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 }