1 16 package org.apache.cocoon.util; 17 18 import org.apache.cocoon.environment.Request; 19 import org.apache.commons.lang.StringUtils; 20 import org.apache.commons.lang.SystemUtils; 21 import org.apache.excalibur.source.SourceParameters; 22 23 import java.io.ByteArrayOutputStream ; 24 import java.io.IOException ; 25 import java.io.OutputStreamWriter ; 26 import java.io.UnsupportedEncodingException ; 27 import java.lang.reflect.InvocationTargetException ; 28 import java.lang.reflect.Method ; 29 import java.net.URLDecoder ; 30 import java.net.URLEncoder ; 31 import java.util.BitSet ; 32 import java.util.Enumeration ; 33 import java.util.Iterator ; 34 import java.util.LinkedList ; 35 import java.util.Map ; 36 import java.util.StringTokenizer ; 37 38 45 public class NetUtils { 46 47 50 private static BitSet safeCharacters; 51 52 private static final char[] hexadecimal = 53 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 54 'A', 'B', 'C', 'D', 'E', 'F'}; 55 56 static { 57 safeCharacters = new BitSet (256); 58 int i; 59 for (i = 'a'; i <= 'z'; i++) { 61 safeCharacters.set(i); 62 } 63 for (i = 'A'; i <= 'Z'; i++) { 65 safeCharacters.set(i); 66 } 67 for (i = '0'; i <= '9'; i++) { 69 safeCharacters.set(i); 70 } 71 72 safeCharacters.set('$'); 74 safeCharacters.set('-'); 75 safeCharacters.set('_'); 76 safeCharacters.set('.'); 77 safeCharacters.set('+'); 78 79 safeCharacters.set('!'); 81 safeCharacters.set('*'); 82 safeCharacters.set('\''); 83 safeCharacters.set('('); 84 safeCharacters.set(')'); 85 safeCharacters.set(','); 86 87 safeCharacters.set('/'); 89 safeCharacters.set(':'); 90 safeCharacters.set('@'); 91 safeCharacters.set('&'); 92 safeCharacters.set('='); 93 } 94 95 107 public static String decodePath(String path) { 108 StringBuffer translatedPath = new StringBuffer (path.length()); 109 byte[] encodedchars = new byte[path.length() / 3]; 110 int i = 0; 111 int length = path.length(); 112 int encodedcharsLength = 0; 113 while (i < length) { 114 if (path.charAt(i) == '%') { 115 while (i < length && path.charAt(i) == '%') { 118 if (i + 2 < length) { 119 try { 120 byte x = (byte)Integer.parseInt(path.substring(i + 1, i + 3), 16); 121 encodedchars[encodedcharsLength] = x; 122 } catch (NumberFormatException e) { 123 throw new IllegalArgumentException ("NetUtils.decodePath: " + 124 "Illegal hex characters in pattern %" + path.substring(i + 1, i + 3)); 125 } 126 encodedcharsLength++; 127 i += 3; 128 } else { 129 throw new IllegalArgumentException ("NetUtils.decodePath: " + 130 "% character should be followed by 2 hexadecimal characters."); 131 } 132 } 133 try { 134 String translatedPart = new String (encodedchars, 0, encodedcharsLength, "UTF-8"); 135 translatedPath.append(translatedPart); 136 } catch (UnsupportedEncodingException e) { 137 throw new RuntimeException ("Problem in decodePath: UTF-8 encoding not supported."); 139 } 140 encodedcharsLength = 0; 141 } else { 142 translatedPath.append(path.charAt(i)); 144 i++; 145 } 146 } 147 return translatedPath.toString(); 148 } 149 150 158 public static String encodePath(String path) { 159 161 167 168 int maxBytesPerChar = 10; 169 StringBuffer rewrittenPath = new StringBuffer (path.length()); 170 ByteArrayOutputStream buf = new ByteArrayOutputStream (maxBytesPerChar); 171 OutputStreamWriter writer = null; 172 try { 173 writer = new OutputStreamWriter (buf, "UTF8"); 174 } catch (Exception e) { 175 e.printStackTrace(); 176 writer = new OutputStreamWriter (buf); 177 } 178 179 for (int i = 0; i < path.length(); i++) { 180 int c = path.charAt(i); 181 if (safeCharacters.get(c)) { 182 rewrittenPath.append((char)c); 183 } else { 184 try { 186 writer.write(c); 187 writer.flush(); 188 } catch(IOException e) { 189 buf.reset(); 190 continue; 191 } 192 byte[] ba = buf.toByteArray(); 193 for (int j = 0; j < ba.length; j++) { 194 byte toEncode = ba[j]; 196 rewrittenPath.append('%'); 197 int low = (toEncode & 0x0f); 198 int high = ((toEncode & 0xf0) >> 4); 199 rewrittenPath.append(hexadecimal[high]); 200 rewrittenPath.append(hexadecimal[low]); 201 } 202 buf.reset(); 203 } 204 } 205 return rewrittenPath.toString(); 206 } 207 208 214 public static String getPath(String uri) { 215 int i = uri.lastIndexOf('/'); 216 if (i > -1) { 217 return uri.substring(0, i); 218 } 219 i = uri.indexOf(':'); 220 return (i > -1) ? uri.substring(i + 1, uri.length()) : ""; 221 } 222 223 230 public static String getExtension(String uri) { 231 int dot = uri.lastIndexOf('.'); 232 if (dot > -1) { 233 uri = uri.substring(dot); 234 int slash = uri.lastIndexOf('/'); 235 if (slash > -1) { 236 return null; 237 } else { 238 int sharp = uri.lastIndexOf('#'); 239 if (sharp > -1) { 240 return uri.substring(0, sharp); 242 } else { 243 int mark = uri.lastIndexOf('?'); 244 if (mark > -1) { 245 return uri.substring(0, mark); 247 } else { 248 return uri; 249 } 250 } 251 } 252 } else { 253 return null; 254 } 255 } 256 257 264 public static String absolutize(String path, String resource) { 265 if (StringUtils.isEmpty(path)) { 266 return resource; 267 } else if (StringUtils.isEmpty(resource)) { 268 return path; 269 } else if (resource.charAt(0) == '/') { 270 return resource; 272 } 273 274 boolean slash = (path.charAt(path.length() - 1) == '/'); 275 276 StringBuffer b = new StringBuffer (path.length() + 1 + resource.length()); 277 b.append(path); 278 if (!slash) { 279 b.append('/'); 280 } 281 b.append(resource); 282 return b.toString(); 283 } 284 285 292 public static String relativize(String path, String absoluteResource) { 293 if (StringUtils.isEmpty(path)) { 294 return absoluteResource; 295 } 296 297 if (path.charAt(path.length() - 1) != '/') { 298 path += "/"; 299 } 300 301 if (absoluteResource.startsWith(path)) { 302 return absoluteResource.substring(path.length()); 304 } else { 305 int index = StringUtils.indexOfDifference(path, absoluteResource); 307 if (index > 0 && path.charAt(index-1) != '/') { 308 index = path.substring(0, index).lastIndexOf('/'); 309 index++; 310 } 311 String pathDiff = path.substring(index); 312 String resource = absoluteResource.substring(index); 313 int levels = StringUtils.countMatches(pathDiff, "/"); 314 StringBuffer b = new StringBuffer (levels * 3 + resource.length()); 315 for (int i = 0; i < levels; i++) { 316 b.append("../"); 317 } 318 b.append(resource); 319 return b.toString(); 320 } 321 } 322 323 329 public static String normalize(String uri) { 330 if ("".equals(uri)) { 331 return uri; 332 } 333 int leadingSlashes = 0; 334 for (leadingSlashes = 0 ; leadingSlashes < uri.length() 335 && uri.charAt(leadingSlashes) == '/' ; ++leadingSlashes) {} 336 boolean isDir = (uri.charAt(uri.length() - 1) == '/'); 337 StringTokenizer st = new StringTokenizer (uri, "/"); 338 LinkedList clean = new LinkedList (); 339 while (st.hasMoreTokens()) { 340 String token = st.nextToken(); 341 if ("..".equals(token)) { 342 if (! clean.isEmpty() && ! "..".equals(clean.getLast())) { 343 clean.removeLast(); 344 if (! st.hasMoreTokens()) { 345 isDir = true; 346 } 347 } else { 348 clean.add(".."); 349 } 350 } else if (! ".".equals(token) && ! "".equals(token)) { 351 clean.add(token); 352 } 353 } 354 StringBuffer sb = new StringBuffer (); 355 while (leadingSlashes-- > 0) { 356 sb.append('/'); 357 } 358 for (Iterator it = clean.iterator() ; it.hasNext() ; ) { 359 sb.append(it.next()); 360 if (it.hasNext()) { 361 sb.append('/'); 362 } 363 } 364 if (isDir && sb.length() > 0 && sb.charAt(sb.length() - 1) != '/') { 365 sb.append('/'); 366 } 367 return sb.toString(); 368 } 369 370 379 public static String deparameterize(String uri, Map parameters) { 380 int i = uri.lastIndexOf('?'); 381 if (i == -1) { 382 return uri; 383 } 384 385 String [] params = StringUtils.split(uri.substring(i + 1), '&'); 386 for (int j = 0; j < params.length; j++) { 387 String p = params[j]; 388 int k = p.indexOf('='); 389 if (k == -1) { 390 break; 391 } 392 String name = p.substring(0, k); 393 String value = p.substring(k + 1); 394 Object values = parameters.get(name); 395 if (values == null) { 396 parameters.put(name, value); 397 } else if (values.getClass().isArray()) { 398 String [] v1 = (String [])values; 399 String [] v2 = new String [v1.length + 1]; 400 System.arraycopy(v1, 0, v2, 0, v1.length); 401 v2[v1.length] = value; 402 parameters.put(name, v2); 403 } else { 404 parameters.put(name, new String []{values.toString(), value}); 405 } 406 } 407 return uri.substring(0, i); 408 } 409 410 419 public static String parameterize(String uri, Map parameters) { 420 if (parameters.size() == 0) { 421 return uri; 422 } 423 424 StringBuffer buffer = new StringBuffer (uri); 425 if (uri.indexOf('?') == -1) { 426 buffer.append('?'); 427 } else { 428 buffer.append('&'); 429 } 430 431 for (Iterator i = parameters.entrySet().iterator(); i.hasNext();) { 432 Map.Entry entry = (Map.Entry )i.next(); 433 if (entry.getValue().getClass().isArray()) { 434 Object [] value = (Object [])entry.getValue(); 435 for (int j = 0; j < value.length; j++) { 436 if (j > 0) { 437 buffer.append('&'); 438 } 439 buffer.append(entry.getKey()); 440 buffer.append('='); 441 buffer.append(value[j]); 442 } 443 } else { 444 buffer.append(entry.getKey()); 445 buffer.append('='); 446 buffer.append(entry.getValue()); 447 } 448 if (i.hasNext()) { 449 buffer.append('&'); 450 } 451 } 452 return buffer.toString(); 453 } 454 455 459 public static SourceParameters createParameters(Request request) { 460 final SourceParameters pars = new SourceParameters(); 461 462 if (null != request) { 463 final Enumeration names = request.getParameterNames(); 464 while (names.hasMoreElements()) { 465 final String current = (String )names.nextElement(); 466 final String [] values = request.getParameterValues(current); 467 if (null != values) { 468 for(int i=0; i < values.length; i++) { 469 pars.setParameter(current, values[i]); 470 } 471 } 472 } 473 } 474 475 return pars; 476 } 477 478 481 public static String removeAuthorisation(String uri) { 482 if (uri.indexOf("@")!=-1 && (uri.startsWith("ftp://") || uri.startsWith("http://"))) { 483 return uri.substring(0, uri.indexOf(":")+2)+uri.substring(uri.indexOf("@")+1); 484 } 485 return uri; 486 } 487 488 private static Method urlEncode; 490 private static Method urlDecode; 491 492 static { 493 if (SystemUtils.isJavaVersionAtLeast(140)) { 494 try { 495 urlEncode = URLEncoder .class.getMethod("encode", new Class []{String .class, String .class}); 496 urlDecode = URLDecoder .class.getMethod("decode", new Class []{String .class, String .class}); 497 } catch (NoSuchMethodException e) { 498 } 500 } else { 501 urlEncode = null; 502 urlDecode = null; 503 } 504 } 505 506 510 public static String encode(String s, String enc) throws UnsupportedEncodingException { 511 if (urlEncode != null) { 512 try { 513 return (String )urlEncode.invoke(s, new Object []{ s, enc } ); 514 } catch (IllegalAccessException e) { 515 } catch (InvocationTargetException e) { 517 if (e.getTargetException() instanceof UnsupportedEncodingException ) { 518 throw (UnsupportedEncodingException )e.getTargetException(); 519 } else if (e.getTargetException() instanceof RuntimeException ) { 520 throw (RuntimeException )e.getTargetException(); 521 } 522 } 523 } 524 return URLEncoder.encode(s); 525 } 526 527 531 public static String decode(String s, String enc) throws UnsupportedEncodingException { 532 if (urlDecode != null) { 533 try { 534 return (String )urlDecode.invoke(s, new Object []{ s, enc } ); 535 } catch (IllegalAccessException e) { 536 } catch (InvocationTargetException e) { 538 if (e.getTargetException() instanceof UnsupportedEncodingException ) { 539 throw (UnsupportedEncodingException )e.getTargetException(); 540 } else if (e.getTargetException() instanceof RuntimeException ) { 541 throw (RuntimeException )e.getTargetException(); 542 } 543 } 544 } 545 return URLDecoder.decode(s); 546 } 547 } 548 | Popular Tags |