1 19 20 package org.openide.filesystems; 21 22 import java.io.File ; 23 import java.io.FileNotFoundException ; 24 import java.io.UnsupportedEncodingException ; 25 import java.net.MalformedURLException ; 26 import java.net.URI ; 27 import java.net.URISyntaxException ; 28 import java.net.URL ; 29 import java.net.URLDecoder ; 30 import java.util.ArrayList ; 31 import java.util.Arrays ; 32 import java.util.Enumeration ; 33 import java.util.Iterator ; 34 import java.util.LinkedHashSet ; 35 import java.util.LinkedList ; 36 import java.util.List ; 37 import java.util.Set ; 38 import org.netbeans.modules.openide.filesystems.DefaultURLMapperProxy; 39 import org.openide.util.Lookup; 40 import org.openide.util.LookupEvent; 41 import org.openide.util.LookupListener; 42 43 54 public abstract class URLMapper { 55 59 public static final int INTERNAL = 0; 60 61 69 public static final int EXTERNAL = 1; 70 71 72 public static final int NETWORK = 2; 73 74 75 private static Lookup.Result<URLMapper> result; 76 private static final List <URLMapper> CACHE_JUST_COMPUTING = new ArrayList <URLMapper>(); 77 private static final ThreadLocal <List <URLMapper>> threadCache = new ThreadLocal <List <URLMapper>>(); 78 79 static { 80 DefaultURLMapperProxy.setDefault(new DefaultURLMapper()); 81 result = Lookup.getDefault().lookupResult(URLMapper.class); 82 result.addLookupListener( 83 new LookupListener() { 84 public void resultChanged(LookupEvent ev) { 85 synchronized (URLMapper.class) { 86 cache = null; 87 } 88 } 89 } 90 ); 91 } 92 93 94 private static URLMapper defMapper; 95 96 97 private static List <URLMapper> cache; 98 99 107 public static URL findURL(FileObject fo, int type) { 108 109 110 for (URLMapper mapper : getInstances()) { 111 URL retVal = mapper.getURL(fo, type); 112 113 if (retVal != null) { 114 return retVal; 115 } 116 } 117 118 if (type == INTERNAL) { 121 try { 122 return FileURL.encodeFileObject(fo); 123 } catch (FileStateInvalidException iex) { 124 } 126 } 127 128 return null; 129 } 130 131 141 public abstract URL getURL(FileObject fo, int type); 142 143 154 @Deprecated 155 public static FileObject[] findFileObjects(URL url) { 156 Set <FileObject> retSet = new LinkedHashSet <FileObject>(); 157 158 for (URLMapper mapper: getInstances()) { 159 FileObject[] retVal = mapper.getFileObjects(url); 160 161 if (retVal != null) { 162 retSet.addAll(Arrays.asList(retVal)); 163 } 164 } 165 166 return retSet.toArray(new FileObject[retSet.size()]); 167 } 168 169 175 public static FileObject findFileObject(URL url) { 176 if (url == null) { 177 throw new NullPointerException ("Cannot pass null URL to URLMapper.findFileObject"); } 179 180 181 FileObject[] results = null; 182 183 Iterator <URLMapper> instances = getInstances().iterator(); 184 185 while (instances.hasNext() && ((results == null) || (results.length == 0))) { 186 URLMapper mapper = instances.next(); 187 188 results = mapper.getFileObjects(url); 189 } 190 191 return ((results != null) && (results.length > 0)) ? results[0] : null; 192 } 193 194 207 public abstract FileObject[] getFileObjects(URL url); 208 209 212 private static List <URLMapper> getInstances() { 213 synchronized (URLMapper.class) { 214 if (cache != null) { 215 if ((cache != CACHE_JUST_COMPUTING) || (threadCache.get() == CACHE_JUST_COMPUTING)) { 216 return cache; 217 } 218 } 219 220 cache = CACHE_JUST_COMPUTING; 223 threadCache.set(CACHE_JUST_COMPUTING); 224 } 225 226 ArrayList <URLMapper> res = null; 227 228 try { 229 res = new ArrayList <URLMapper>(result.allInstances()); 230 { 231 URLMapper def = null; 234 Iterator <URLMapper> it = res.iterator(); 235 while (it.hasNext()) { 236 URLMapper m = it.next(); 237 if (m instanceof DefaultURLMapperProxy) { 238 def = m; 239 it.remove(); 240 break; 241 } 242 } 243 if (def != null) { 244 res.add(def); 245 } 246 } 247 return res; 248 } finally { 249 synchronized (URLMapper.class) { 250 if (cache == CACHE_JUST_COMPUTING) { 251 cache = res; 252 } 253 254 threadCache.set(null); 255 } 256 } 257 } 258 259 260 private static class DefaultURLMapper extends URLMapper { 261 DefaultURLMapper() { 262 } 263 264 public FileObject[] getFileObjects(URL url) { 266 String prot = url.getProtocol(); 267 268 if (prot.equals("nbfs")) { 270 FileObject retVal = FileURL.decodeURL(url); 271 272 return (retVal == null) ? null : new FileObject[] { retVal }; 273 } 274 275 if (prot.equals("jar")) { 277 return getFileObjectsForJarProtocol(url); 278 } 279 280 if (prot.equals("file")) { 282 File f = toFile(url); 283 284 if (f != null) { 285 FileObject[] foRes = findFileObjectsInRepository(f); 286 287 if ((foRes != null) && (foRes.length > 0)) { 288 return foRes; 289 } 290 } 291 } 292 293 return null; 294 } 295 296 private FileObject[] findFileObjectsInRepository(File f) { 297 if (!f.equals(FileUtil.normalizeFile(f))) { 298 throw new IllegalArgumentException ( 299 "Parameter file was not " + "normalized. Was " + f + " instead of " + FileUtil.normalizeFile(f) 301 ); } 303 304 @SuppressWarnings ("deprecation") Enumeration <? extends FileSystem> en = Repository.getDefault().getFileSystems(); 306 LinkedList <FileObject> list = new LinkedList <FileObject>(); 307 String fileName = f.getAbsolutePath(); 308 309 while (en.hasMoreElements()) { 310 FileSystem fs = en.nextElement(); 311 String rootName = null; 312 FileObject fsRoot = fs.getRoot(); 313 File root = findFileInRepository(fsRoot); 314 315 if (root == null) { 316 Object rootPath = fsRoot.getAttribute("FileSystem.rootPath"); 318 if ((rootPath != null) && (rootPath instanceof String )) { 319 rootName = (String ) rootPath; 320 } else { 321 continue; 322 } 323 } 324 325 if (rootName == null) { 326 rootName = root.getAbsolutePath(); 327 } 328 329 330 if (fileName.indexOf(rootName) == 0) { 331 String res = fileName.substring(rootName.length()).replace(File.separatorChar, '/'); 332 FileObject fo = fs.findResource(res); 333 File file2Fo = (fo != null) ? findFileInRepository(fo) : null; 334 335 if ((fo != null) && (file2Fo != null) && f.equals(file2Fo)) { 336 if (fo.getClass().toString().indexOf("org.netbeans.modules.masterfs.MasterFileObject") != -1) { list.addFirst(fo); 338 } else { 339 list.addLast(fo); 340 } 341 } 342 } 343 } 344 345 FileObject[] results = new FileObject[list.size()]; 346 list.toArray(results); 347 348 return results; 349 } 350 351 public URL getURL(FileObject fo, int type) { 353 if (fo == null) { 354 return null; 355 } 356 357 if (type == NETWORK) { 358 return null; 359 } 360 361 if (fo instanceof MultiFileObject && (type == INTERNAL)) { 362 return null; 365 } 366 367 File fFile = findFileInRepository(fo); 368 369 if (fFile != null) { 370 try { 371 return toURL(fFile, fo); 372 } catch (MalformedURLException mfx) { 373 assert false : mfx; 374 375 return null; 376 } 377 } 378 379 URL retURL = null; 380 FileSystem fs = null; 381 382 try { 383 fs = fo.getFileSystem(); 384 } catch (FileStateInvalidException fsex) { 385 return null; 386 } 387 388 if (fs instanceof JarFileSystem) { 389 JarFileSystem jfs = (JarFileSystem) fs; 390 File f = jfs.getJarFile(); 391 392 if (f == null) { 393 return null; 394 } 395 396 try { 397 String toReplace = "__EXCLAMATION_REPLACEMENT__"; retURL = new URL ( 399 "jar:" + new File (f,toReplace + fo.getPath()).toURI().toString().replaceFirst("/"+toReplace,"!/") + ((fo.isFolder() && !fo.isRoot()) ? "/" : "") 401 ); } catch (MalformedURLException mfx) { 403 mfx.printStackTrace(); 404 405 return null; 406 } 407 } else if (fs instanceof XMLFileSystem) { 408 URL retVal = null; 409 410 try { 411 retVal = ((XMLFileSystem) fs).getURL(fo.getPath()); 412 413 if (retVal == null) { 414 return null; 415 } 416 417 if (type == INTERNAL) { 418 return retVal; 419 } 420 421 boolean isInternal = retVal.getProtocol().startsWith("nbres"); 423 if ((type == EXTERNAL) && !isInternal) { 424 return retVal; 425 } 426 427 return null; 428 } catch (FileNotFoundException fnx) { 429 return null; 430 } 431 } 432 433 return retURL; 434 } 435 436 private static URL toURL(File fFile, FileObject fo) 437 throws MalformedURLException { 438 URL retVal = null; 439 440 if (fo.isFolder() && !fo.isValid()) { 441 String urlDef = fFile.toURI().toURL().toExternalForm(); 442 String pathSeparator = "/"; 444 if (!urlDef.endsWith(pathSeparator)) { 445 retVal = new URL (urlDef + pathSeparator); 446 } 447 } 448 449 return (retVal == null) ? fFile.toURI().toURL() : retVal; 450 } 451 452 private static File findFileInRepository(FileObject fo) { 453 File f = (File ) fo.getAttribute("java.io.File"); 455 return (f != null) ? FileUtil.normalizeFile(f) : null; 456 } 457 458 private static FileObject[] getFileObjectsForJarProtocol(URL url) { 459 FileObject retVal = null; 460 JarURLParser jarUrlParser = new JarURLParser(url); 461 File file = jarUrlParser.getJarFile(); 462 String entryName = jarUrlParser.getEntryName(); 463 464 if (file != null) { 465 JarFileSystem fs = findJarFileSystem(file); 466 467 if (fs != null) { 468 if (entryName == null) { 469 entryName = ""; } 471 472 retVal = fs.findResource(entryName); 473 } 474 } 475 476 return (retVal == null) ? null : new FileObject[] { retVal }; 477 } 478 479 private static JarFileSystem findJarFileSystem(File jarFile) { 480 JarFileSystem retVal = null; 481 @SuppressWarnings ("deprecation") Enumeration <? extends FileSystem> en = Repository.getDefault().getFileSystems(); 483 484 while (en.hasMoreElements()) { 485 FileSystem fs = en.nextElement(); 486 487 if (fs instanceof JarFileSystem) { 488 File fsJarFile = ((JarFileSystem) fs).getJarFile(); 489 490 if (fsJarFile.equals(jarFile)) { 491 retVal = (JarFileSystem) fs; 492 493 break; 494 } 495 } 496 } 497 498 return retVal; 499 } 500 501 private static File toFile(URL u) { 502 if (u == null) { 503 throw new NullPointerException (); 504 } 505 506 try { 507 URI uri = new URI (u.toExternalForm()); 508 509 return FileUtil.normalizeFile(new File (uri)); 510 } catch (URISyntaxException use) { 511 return null; 513 } catch (IllegalArgumentException iae) { 514 return null; 516 } 517 } 518 519 private static class JarURLParser { 520 private File jarFile; 521 private String entryName; 522 523 JarURLParser(URL originalURL) { 524 parse(originalURL); 525 } 526 527 528 void parse(URL originalURL) { 529 String spec = originalURL.getFile(); 530 531 int separator = spec.indexOf('!'); 532 533 if (separator != -1) { 534 try { 535 jarFile = toFile(new URL (spec.substring(0, separator++))); 536 entryName = null; 537 } catch (MalformedURLException e) { 538 return; 539 } 540 541 542 if (++separator != spec.length()) { 543 try { 544 entryName = URLDecoder.decode(spec.substring(separator, spec.length()),"UTF-8"); 545 } catch (UnsupportedEncodingException ex) { 546 return; 547 } 548 } 549 } 550 } 551 552 File getJarFile() { 553 return jarFile; 554 } 555 556 String getEntryName() { 557 return entryName; 558 } 559 } 560 } 561 } 562 | Popular Tags |