001 /*---------------- FILE HEADER ------------------------------------------
002
003 This file is part of deegree.
004 Copyright (C) 2001-2008 by:
005 EXSE, Department of Geography, University of Bonn
006 http://www.giub.uni-bonn.de/deegree/
007 lat/lon GmbH
008 http://www.lat-lon.de
009
010 This library is free software; you can redistribute it and/or
011 modify it under the terms of the GNU Lesser General Public
012 License as published by the Free Software Foundation; either
013 version 2.1 of the License, or (at your option) any later version.
014
015 This library is distributed in the hope that it will be useful,
016 but WITHOUT ANY WARRANTY; without even the implied warranty of
017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
018 Lesser General Public License for more details.
019
020 You should have received a copy of the GNU Lesser General Public
021 License along with this library; if not, write to the Free Software
022 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
023
024 Contact:
025
026 Andreas Poth
027 lat/lon GmbH
028 Aennchenstr. 19
029 53115 Bonn
030 Germany
031 E-Mail: poth@lat-lon.de
032
033 Prof. Dr. Klaus Greve
034 Department of Geography
035 University of Bonn
036 Meckenheimer Allee 166
037 53115 Bonn
038 Germany
039 E-Mail: greve@giub.uni-bonn.de
040
041
042 ---------------------------------------------------------------------------*/
043 package org.deegree.portal.standard.security.control;
044
045 import java.io.File;
046 import java.text.ParseException;
047 import java.util.Collection;
048 import java.util.Iterator;
049 import java.util.Vector;
050
051 /**
052 * TODO add documentation here
053 *
054 * @author <a href="mailto:elmasry@lat-lon.de">Moataz Elmasry</a>
055 * @author last edited by: $Author: elmasri$
056 *
057 * @version $Revision: $, $Date: 08-Mar-2007 16:46:12$
058 */
059 public class RelativePath {
060
061 /**
062 * get the first match from the many delimiters give as input
063 *
064 * @param source
065 * @param delimiters
066 * @return String
067 */
068 public static String getFirstMatch( String source, String[] delimiters ) {
069
070 Vector<Delimiter> indices = new Vector<Delimiter>();
071
072 for ( int i = 0; i < delimiters.length; i++ ) {
073 // we added the indices of all matches to the vector
074 indices.add( new Delimiter( i, source.indexOf( delimiters[i] ), delimiters[i] ) );
075 }
076
077 Delimiter delimiter = getFirstIndex( indices );
078 if ( delimiter.getValue() == null ) {
079 return null;
080 }
081
082 return source.substring( 0, delimiter.getFoundAt() + 1 );
083 }
084
085 /**
086 * Gets the first index of a match from the many delimiters given as input Takes many delimiters
087 * returns the delimiter that occured first
088 *
089 * @param collection
090 * @return instance of Delimiter class
091 */
092 private static Delimiter getFirstIndex( Collection<Delimiter> collection ) {
093
094 Delimiter delimiter = new Delimiter( -1, 999, null );
095 Iterator it = collection.iterator();
096 // comparing the matches to see which match occured first
097 while ( it.hasNext() ) {
098 Delimiter temp = (Delimiter) it.next();
099 int indexOf = temp.foundAt;
100 if ( indexOf < delimiter.getFoundAt() && indexOf > -1 ) {
101 delimiter = temp;
102 }
103 }
104
105 if ( delimiter == null ) {
106 return null;
107 }
108 return delimiter;
109
110 }
111
112 /**
113 * Split a string based on the given delimiters and return an array of strings(tokens)
114 *
115 * @param source
116 * @param delimiters
117 * @return tokens from a given string
118 */
119 public static String[] splitString( String source, String[] delimiters ) {
120
121 if ( source == null || delimiters == null )
122 return null;
123
124 Vector<String> returnedStrings = new Vector<String>();
125 String tempSource = source;
126
127 while ( tempSource.length() != 0 ) {
128
129 int delimiterLength = 0;
130 String match = getFirstMatch( tempSource, delimiters );
131 // if this is the last token in the String
132 if ( match == null ) {
133 returnedStrings.add( tempSource );
134 break;
135 } else {
136
137 // removing any delimiters that could exist
138 for ( int i = 0; i < delimiters.length; i++ ) {
139 if ( match.contains( delimiters[i] ) ) {
140 match = match.replace( delimiters[i], "" );
141 delimiterLength = delimiters[i].length();
142 break;
143 }
144
145 }
146 // Ignore the ./ and don't add it to the array
147 if ( match.compareTo( "./" ) != 0 ) {
148 returnedStrings.add( match );
149 }
150 tempSource = tempSource.substring( match.length() + delimiterLength, tempSource.length() );
151 }
152
153 }
154
155 String[] strings = new String[returnedStrings.size()];
156 for ( int i = 0; i < returnedStrings.size(); i++ ) {
157 strings[i] = returnedStrings.elementAt( i );
158 }
159 return strings;
160 }
161
162 /**
163 * Maps from a source sTring to a target String, based on the delimiters given the delimiters
164 * are basically "\\" or "/", but it also could be anything else Two absolute pathes should be
165 * given here Don't give relative or non existing pathes
166 *
167 * @param source
168 * @param target
169 * @param delimiters
170 * @return the mapped path
171 * @throws ParseException
172 */
173 public static String mapRelativePath( String source, String target, String[] delimiters )
174 throws ParseException {
175
176 if ( !new File( source ).isAbsolute() ) {
177 throw new ParseException( "The source path is not absolute", 0 );
178 }
179 if ( !new File( target ).isAbsolute() ) {
180 throw new ParseException( "The target path is not absolute", 0 );
181 }
182
183 String[] sourceTokens = splitString( source, delimiters );
184 String[] targetTokens = splitString( target, delimiters );
185 if ( sourceTokens == null || targetTokens == null )
186 return null;
187 if ( sourceTokens.length == 0 || targetTokens.length == 0 )
188 return null;
189
190 int lessTokens = 0;
191 if ( sourceTokens.length < targetTokens.length ) {
192 lessTokens = sourceTokens.length;
193 } else {
194 lessTokens = targetTokens.length;
195 }
196
197 int counter = 0;
198 for ( counter = 0; counter < lessTokens; counter++ ) {
199 if ( !sourceTokens[counter].equals( targetTokens[counter] ) )
200 break;
201 }
202
203 StringBuffer buffer = new StringBuffer();
204 for ( int i = counter; i < sourceTokens.length; i++ ) {
205 if ( i != sourceTokens.length - 1 ) {
206 buffer.append( "../" );
207 } else {
208 // We are checking if the last token in the source String is a file or a directory
209 // if its a file we don'tn write it
210 File sourceFile = new File( source );
211 if ( sourceFile.isDirectory() ) {
212 buffer.append( "../" );
213 }
214 }
215
216 }
217
218 // This is used when the target is only one token different/larger than the source, so we
219 // just take
220 // the last token in the target
221 if ( ( counter == sourceTokens.length ) && ( sourceTokens.length == targetTokens.length + 1 )
222 && ( sourceTokens[counter - 1].equals( targetTokens[counter - 1] ) ) ) {
223 return targetTokens[targetTokens.length - 1];
224 }
225 for ( int i = counter; i < targetTokens.length; i++ ) {
226 if ( buffer.length() == 0 ) {
227 // This is the first token in the path
228 buffer.append( "./" );
229 }
230 buffer.append( targetTokens[i] );
231 if ( i != targetTokens.length - 1 ) {
232 buffer.append( "/" );
233 }
234
235 }
236
237 return buffer.toString();
238 }
239
240 static class Delimiter {
241 int index;
242
243 String value;
244
245 int foundAt;
246
247 /**
248 * @param index
249 * @param foundAt
250 * @param value
251 */
252 public Delimiter( int index, int foundAt, String value ) {
253 this.index = index;
254 this.value = value;
255 this.foundAt = foundAt;
256 }
257
258 /**
259 * @return int
260 */
261 public int getIndex() {
262 return index;
263 }
264
265 /**
266 * @param index
267 */
268 public void setIndex( int index ) {
269 this.index = index;
270 }
271
272 /**
273 * @return String
274 */
275 public String getValue() {
276 return value;
277 }
278
279 /**
280 * @param value
281 */
282 public void setValue( String value ) {
283 this.value = value;
284 }
285
286 /**
287 * @return int
288 */
289 public int getFoundAt() {
290 return foundAt;
291 }
292
293 /**
294 * @param foundAt
295 */
296 public void setFoundAt( int foundAt ) {
297 this.foundAt = foundAt;
298 }
299 }
300
301 }