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 }