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