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 }