private void fetchNext() { if (iterator == null) { return; } if (next != null) { return; } try { while (iterator.hasNext()) { ResourceLocation resourceLocation = (ResourceLocation) iterator.next(); ResourceHandle resourceHandle = resourceLocation.getResourceHandle(resourceName); if (resourceHandle != null) { next = resourceHandle.getUrl(); return; } } // no more elements // clear the iterator so it can be GCed iterator = null; } catch (IllegalStateException e) { // Jar file was closed... this means the resource finder was destroyed // clear the iterator so it can be GCed iterator = null; throw e; } }
public void destroy() { synchronized (lock) { if (destroyed) { return; } destroyed = true; uris.clear(); for (ResourceLocation resourceLocation : classPath.values()) { resourceLocation.close(); } classPath.clear(); } }
public NBTTagCompound b(NBTTagCompound nbttagcompound) { ResourceLocation resourcelocation = (ResourceLocation) Item.e.c(this.d); nbttagcompound.a( "id", resourcelocation == null ? "minecraft:air" : resourcelocation.toString()); nbttagcompound.a("Count", (byte) this.b); nbttagcompound.a("Damage", (short) this.f); if (this.e != null) { nbttagcompound.a("tag", (NBTBase) this.e); } return nbttagcompound; }
public URL findResource(String resourceName) { synchronized (lock) { if (destroyed) { return null; } for (Map.Entry<URI, ResourceLocation> entry : getClassPath().entrySet()) { ResourceLocation resourceLocation = entry.getValue(); ResourceHandle resourceHandle = resourceLocation.getResourceHandle(resourceName); if (resourceHandle != null) { return resourceHandle.getUrl(); } } } return null; }
/** * Get a resource * * @param ref The reference to the resource to retrieve * @return A stream from which the resource can be read */ public InputStream getResourceAsStream(String ref) { InputStream in = null; for (int i = 0; i < locations.size(); i++) { ResourceLocation location = (ResourceLocation) locations.get(i); in = location.getResourceAsStream(ref); if (in != null) { break; } } if (in == null) { throw new RuntimeException("Resource not found: " + ref); } return new BufferedInputStream(in); }
/** * Get a resource as a URL * * @param ref The reference to the resource to retrieve * @return A stream from which the resource can be read */ public URL getResource(String ref) { URL url = null; for (int i = 0; i < locations.size(); i++) { ResourceLocation location = (ResourceLocation) locations.get(i); url = location.getResource(ref); if (url != null) { break; } } if (url == null) { throw new RuntimeException("Resource not found: " + ref); } return url; }
private List<URI> getManifestClassPath(ResourceLocation resourceLocation) { try { // get the manifest, if possible Manifest manifest = resourceLocation.getManifest(); if (manifest == null) { // some locations don't have a manifest return Collections.EMPTY_LIST; } // get the class-path attribute, if possible String manifestClassPath = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH); if (manifestClassPath == null) { return Collections.EMPTY_LIST; } // build the uris... // the class-path attribute is space delimited URL codeSource = resourceLocation.getCodeSource(); LinkedList<URI> classPathUrls = new LinkedList<URI>(); for (StringTokenizer tokenizer = new StringTokenizer(manifestClassPath, " "); tokenizer.hasMoreTokens(); ) { String entry = tokenizer.nextToken(); try { // the class path entry is relative to the resource location code source URL entryUrl = new URL(codeSource, entry); classPathUrls.addLast(entryUrl.toURI()); } catch (MalformedURLException ignored) { // most likely a poorly named entry } catch (URISyntaxException ignored) { // most likely a poorly named entry } } return classPathUrls; } catch (IOException ignored) { // error opening the manifest return Collections.EMPTY_LIST; } }
/** * Rebuilds the entire class path. This class is called when new URIs are added or one of the * watched files becomes readable. This method will not open jar files again, but will add any new * entries not alredy open to the class path. If any file based uri is does not exist, we will * watch for that file to appear. */ private void rebuildClassPath() { assert Thread.holdsLock(lock) : "This method can only be called while holding the lock"; // copy all of the existing locations into a temp map and clear the class path Map<URI, ResourceLocation> existingJarFiles = new LinkedHashMap<URI, ResourceLocation>(classPath); classPath.clear(); LinkedList<URI> locationStack = new LinkedList<URI>(uris); try { while (!locationStack.isEmpty()) { URI uri = locationStack.removeFirst(); // Skip any duplicate uris in the classpath if (classPath.containsKey(uri)) { continue; } // Check is this URL has already been opened ResourceLocation resourceLocation = existingJarFiles.remove(uri); // If not opened, cache the uri and wrap it with a resource location if (resourceLocation == null) { try { File file = cacheUri(uri); resourceLocation = createResourceLocation(uri.toURL(), file); } catch (FileNotFoundException e) { // if this is a file URL, the file doesn't exist yet... watch to see if it appears later if ("file".equals(uri.getScheme())) { File file = new File(uri.getPath()); watchedFiles.add(file); continue; } } catch (IOException ignored) { // can't seem to open the file... this is most likely a bad jar file // so don't keep a watch out for it because that would require lots of checking // Dain: We may want to review this decision later continue; } catch (UnsupportedOperationException ex) { // the protocol for the JAR file's URL is not supported. This can occur when // the jar file is embedded in an EAR or CAR file. continue; } } try { // add the jar to our class path classPath.put(resourceLocation.getCodeSource().toURI(), resourceLocation); } catch (URISyntaxException ex) { } // push the manifest classpath on the stack (make sure to maintain the order) List<URI> manifestClassPath = getManifestClassPath(resourceLocation); locationStack.addAll(0, manifestClassPath); } } catch (Error e) { destroy(); throw e; } for (ResourceLocation resourceLocation : existingJarFiles.values()) { resourceLocation.close(); } }