001 package org.deegree.portal.standard.security.control;
002
003 import java.io.File;
004 import java.text.ParseException;
005 import java.util.Collection;
006 import java.util.Iterator;
007 import java.util.Vector;
008
009 /**
010 * TODO add documentation here
011 *
012 * @author <a href="mailto:elmasry@lat-lon.de">Moataz Elmasry</a>
013 * @author last edited by: $Author: elmasri$
014 *
015 * @version $Revision: $, $Date: 08-Mar-2007 16:46:12$
016 */
017 public class RelativePath {
018
019 /**
020 * get the first match from the many delimiters give as input
021 *
022 * @param source
023 * @param delimiters
024 * @return String
025 */
026 public static String getFirstMatch( String source, String[] delimiters ) {
027
028 Vector<Delimiter> indices = new Vector<Delimiter>();
029
030 for ( int i = 0; i < delimiters.length; i++ ) {
031 // we added the indices of all matches to the vector
032 indices.add( new Delimiter( i, source.indexOf( delimiters[i] ), delimiters[i] ) );
033 }
034
035 Delimiter delimiter = getFirstIndex( indices );
036 if ( delimiter.getValue() == null ) {
037 return null;
038 }
039
040 return source.substring( 0, delimiter.getFoundAt() + 1 );
041 }
042
043 /**
044 * Gets the first index of a match from the many delimiters given as input Takes many delimiters
045 * returns the delimiter that occured first
046 *
047 * @param collection
048 * @return instance of Delimiter class
049 */
050 private static Delimiter getFirstIndex( Collection<Delimiter> collection ) {
051
052 Delimiter delimiter = new Delimiter( -1, 999, null );
053 Iterator it = collection.iterator();
054 // comparing the matches to see which match occured first
055 while ( it.hasNext() ) {
056 Delimiter temp = (Delimiter) it.next();
057 int indexOf = temp.foundAt;
058 if ( indexOf < delimiter.getFoundAt() && indexOf > -1 ) {
059 delimiter = temp;
060 }
061 }
062
063 if ( delimiter == null ) {
064 return null;
065 }
066 return delimiter;
067
068 }
069
070 /**
071 * Split a string based on the given delimiters and return an array of strings(tokens)
072 *
073 * @param source
074 * @param delimiters
075 * @return tokens from a given string
076 */
077 public static String[] splitString( String source, String[] delimiters ) {
078
079 if ( source == null || delimiters == null )
080 return null;
081
082 Vector<String> returnedStrings = new Vector<String>();
083 String tempSource = source;
084
085 while ( tempSource.length() != 0 ) {
086
087 int delimiterLength = 0;
088 String match = getFirstMatch( tempSource, delimiters );
089 // if this is the last token in the String
090 if ( match == null ) {
091 returnedStrings.add( tempSource );
092 break;
093 } else {
094
095 // removing any delimiters that could exist
096 for ( int i = 0; i < delimiters.length; i++ ) {
097 if ( match.contains( delimiters[i] ) ) {
098 match = match.replace( delimiters[i], "" );
099 delimiterLength = delimiters[i].length();
100 break;
101 }
102
103 }
104 // Ignore the ./ and don't add it to the array
105 if ( match.compareTo( "./" ) != 0 ) {
106 returnedStrings.add( match );
107 }
108 tempSource = tempSource.substring( match.length() + delimiterLength, tempSource.length() );
109 }
110
111 }
112
113 String[] strings = new String[returnedStrings.size()];
114 for ( int i = 0; i < returnedStrings.size(); i++ ) {
115 strings[i] = returnedStrings.elementAt( i );
116 }
117 return strings;
118 }
119
120 /**
121 * Maps from a source sTring to a target String, based on the delimiters given the delimiters
122 * are basically "\\" or "/", but it also could be anything else Two absolute pathes should be
123 * given here Don't give relative or non existing pathes
124 *
125 * @param source
126 * @param target
127 * @param delimiters
128 * @return the mapped path
129 * @throws ParseException
130 */
131 public static String mapRelativePath( String source, String target, String[] delimiters )
132 throws ParseException {
133
134 if ( !new File( source ).isAbsolute() ) {
135 throw new ParseException( "The source path is not absolute", 0 );
136 }
137 if ( !new File( target ).isAbsolute() ) {
138 throw new ParseException( "The target path is not absolute", 0 );
139 }
140
141 String[] sourceTokens = splitString( source, delimiters );
142 String[] targetTokens = splitString( target, delimiters );
143 if ( sourceTokens == null || targetTokens == null )
144 return null;
145 if ( sourceTokens.length == 0 || targetTokens.length == 0 )
146 return null;
147
148 int lessTokens = 0;
149 if ( sourceTokens.length < targetTokens.length ) {
150 lessTokens = sourceTokens.length;
151 } else {
152 lessTokens = targetTokens.length;
153 }
154
155 int counter = 0;
156 for ( counter = 0; counter < lessTokens; counter++ ) {
157 if ( !sourceTokens[counter].equals( targetTokens[counter] ) )
158 break;
159 }
160
161 StringBuffer buffer = new StringBuffer();
162 for ( int i = counter; i < sourceTokens.length; i++ ) {
163 if ( i != sourceTokens.length - 1 ) {
164 buffer.append( "../" );
165 } else {
166 // We are checking if the last token in the source String is a file or a directory
167 // if its a file we don'tn write it
168 File sourceFile = new File( source );
169 if ( sourceFile.isDirectory() ) {
170 buffer.append( "../" );
171 }
172 }
173
174 }
175
176 // This is used when the target is only one token different/larger than the source, so we
177 // just take
178 // the last token in the target
179 if ( ( counter == sourceTokens.length ) && ( sourceTokens.length == targetTokens.length + 1 )
180 && ( sourceTokens[counter - 1].equals( targetTokens[counter - 1] ) ) ) {
181 return targetTokens[targetTokens.length - 1];
182 }
183 for ( int i = counter; i < targetTokens.length; i++ ) {
184 if ( buffer.length() == 0 ) {
185 // This is the first token in the path
186 buffer.append( "./" );
187 }
188 buffer.append( targetTokens[i] );
189 if ( i != targetTokens.length - 1 ) {
190 buffer.append( "/" );
191 }
192
193 }
194
195 return buffer.toString();
196 }
197
198 static class Delimiter {
199 int index;
200
201 String value;
202
203 int foundAt;
204
205 /**
206 * @param index
207 * @param foundAt
208 * @param value
209 */
210 public Delimiter( int index, int foundAt, String value ) {
211 this.index = index;
212 this.value = value;
213 this.foundAt = foundAt;
214 }
215
216 /**
217 * @return int
218 */
219 public int getIndex() {
220 return index;
221 }
222
223 /**
224 * @param index
225 */
226 public void setIndex( int index ) {
227 this.index = index;
228 }
229
230 /**
231 * @return String
232 */
233 public String getValue() {
234 return value;
235 }
236
237 /**
238 * @param value
239 */
240 public void setValue( String value ) {
241 this.value = value;
242 }
243
244 /**
245 * @return int
246 */
247 public int getFoundAt() {
248 return foundAt;
249 }
250
251 /**
252 * @param foundAt
253 */
254 public void setFoundAt( int foundAt ) {
255 this.foundAt = foundAt;
256 }
257 }
258
259 }