/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <http://www.gnu.org/licenses/>. */ package icy.plugin.classloader; import icy.file.FileUtil; import icy.network.NetworkUtil; import icy.plugin.classloader.exception.JclException; import icy.plugin.classloader.exception.ResourceNotFoundException; import icy.system.IcyExceptionHandler; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; /** * Class that builds a local classpath by loading resources from different * files/paths * * @author Kamran Zafar * @author Stephane Dallongeville */ public class ClasspathResources extends JarResources { private static Logger logger = Logger.getLogger(ClasspathResources.class.getName()); private boolean ignoreMissingResources; public ClasspathResources() { super(); ignoreMissingResources = Configuration.suppressMissingResourceException(); } /** * Attempts to load a remote resource (jars, properties files, etc) * * @param url */ protected void loadRemoteResource(URL url) { if (logger.isLoggable(Level.FINEST)) logger.finest("Attempting to load a remote resource."); if (url.toString().toLowerCase().endsWith(".jar")) { try { loadJar(url); } catch (IOException e) { System.err.println("JarResources.loadJar(" + url + ") error:"); IcyExceptionHandler.showErrorMessage(e, false, true); } return; } if (entryUrls.containsKey(url.toString())) { if (!collisionAllowed) throw new JclException("Resource " + url.toString() + " already loaded"); if (logger.isLoggable(Level.FINEST)) logger.finest("Resource " + url.toString() + " already loaded; ignoring entry..."); return; } if (logger.isLoggable(Level.FINEST)) logger.finest("Loading remote resource."); entryUrls.put(url.toString(), url); } /** * Loads and returns content the remote resource (jars, properties files, etc) * * @throws IOException */ protected byte[] loadRemoteResourceContent(URL url) throws IOException { final byte[] result = NetworkUtil.download(url.openStream()); if (result != null) loadedSize += result.length; return result; } /** * Reads local and remote resources * * @param url */ protected void loadResource(URL url) { try { final File file = new File(url.toURI()); // Is Local loadResource(file, FileUtil.getGenericPath(file.getAbsolutePath())); } catch (IllegalArgumentException iae) { // Is Remote loadRemoteResource(url); } catch (URISyntaxException e) { throw new JclException("URISyntaxException", e); } } /** * Reads local resources from - Jar files - Class folders - Jar Library * folders * * @param path */ protected void loadResource(String path) { if (logger.isLoggable(Level.FINEST)) logger.finest("Resource: " + path); File fp = new File(path); if (!fp.exists() && !ignoreMissingResources) throw new JclException("File/Path does not exist"); loadResource(fp, FileUtil.getGenericPath(path)); } /** * Reads local resources from - Jar files - Class folders - Jar Library * folders * * @param fol * @param packName */ protected void loadResource(File fol, String packName) { // FILE if (fol.isFile()) { if (fol.getName().toLowerCase().endsWith(".jar")) { try { loadJar(fol.toURI().toURL()); } catch (IOException e) { System.err.println("JarResources.loadJar(" + fol.getAbsolutePath() + ") error:"); IcyExceptionHandler.showErrorMessage(e, false, true); } } else loadResourceInternal(fol, packName); } // DIRECTORY else { if (fol.list() != null) { for (String f : fol.list()) { File fl = new File(fol.getAbsolutePath() + "/" + f); String pn = packName; if (fl.isDirectory()) { if (!pn.equals("")) pn = pn + "/"; pn = pn + fl.getName(); } loadResource(fl, pn); } } } } /** * Loads the local resource. */ protected void loadResourceInternal(File file, String pack) { String entryName = ""; if (pack.length() > 0) entryName = pack + "/"; entryName += file.getName(); if (entryUrls.containsKey(entryName)) { if (!collisionAllowed) throw new JclException("Resource " + entryName + " already loaded"); if (logger.isLoggable(Level.WARNING)) logger.finest("Resource " + entryName + " already loaded; ignoring entry..."); return; } if (logger.isLoggable(Level.FINEST)) logger.finest("Loading resource: " + entryName); try { entryUrls.put(entryName, file.toURI().toURL()); } catch (Exception e) { if (logger.isLoggable(Level.SEVERE)) logger.finest("Error while loading: " + entryName); System.err.println("JarResources.loadResourceInternal(" + file.getAbsolutePath() + ") error:"); IcyExceptionHandler.showErrorMessage(e, false, true); } } @Override protected void loadContent(String name, URL url) throws IOException { // JAR protocol if (url.getProtocol().equalsIgnoreCase(("jar"))) super.loadContent(name, url); // FILE protocol else if (url.getProtocol().equalsIgnoreCase(("file"))) { final byte[] content = loadResourceContent(url); setResourceContent(name, content); } // try remote loading else { final byte content[] = loadRemoteResourceContent(url); setResourceContent(name, content); } } /** * Loads and returns the local resource content. * * @throws IOException */ protected byte[] loadResourceContent(URL url) throws IOException { final byte[] result = NetworkUtil.download(url.openStream()); if (result != null) loadedSize += result.length; return result; } /** * Removes the loaded resource * * @param resource */ public void unload(String resource) { if (entryContents.containsKey(resource)) { if (logger.isLoggable(Level.FINEST)) logger.finest("Removing resource " + resource); entryContents.remove(resource); } else throw new ResourceNotFoundException(resource, "Resource not found in local ClasspathResources"); } public boolean isCollisionAllowed() { return collisionAllowed; } public void setCollisionAllowed(boolean collisionAllowed) { this.collisionAllowed = collisionAllowed; } public boolean isIgnoreMissingResources() { return ignoreMissingResources; } public void setIgnoreMissingResources(boolean ignoreMissingResources) { this.ignoreMissingResources = ignoreMissingResources; } }