/** * JCL (Jar Class Loader) * * Copyright (C) 2009 Xeus Technologies * * This file is part of Jar Class Loader (JCL). * Jar Class Loader (JCL) is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * JarClassLoader 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with JCL. If not, see <http://www.gnu.org/licenses/>. * * @author Kamran Zafar * * Contact Info: * Email: xeus.man@gmail.com * Web: http://xeustech.blogspot.com */ package xeus.jcl; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; import java.net.URL; import org.apache.log4j.Logger; import xeus.jcl.exception.JclException; import xeus.jcl.exception.ResourceNotFoundException; /** * Class that builds a local classpath by loading resources from different * files/paths * * @author Kamran Zafar * */ public class ClasspathResources extends JarResources { private static Logger logger = Logger.getLogger( ClasspathResources.class ); /** * Reads the resource content * * @param resource * @throws IOException */ private void loadResourceContent(String resource) throws IOException { File resourceFile = new File( resource ); FileInputStream fis = new FileInputStream( resourceFile ); byte[] content = new byte[(int) resourceFile.length()]; fis.read( content ); if( jarEntryContents.containsKey( resourceFile.getName() ) ) { if( !Configuration.supressCollisionException() ) throw new JclException( "Resource " + resourceFile.getName() + " already loaded" ); else { if( logger.isTraceEnabled() ) logger.trace( "Resource " + resourceFile.getName() + " already loaded; ignoring entry..." ); return; } } fis.close(); if( logger.isTraceEnabled() ) logger.trace( "Loading resource: " + resourceFile.getName() ); jarEntryContents.put( resourceFile.getName(), content ); } /** * Attempts to load a remote resource (jars, properties files, etc) * * @param url * @throws IOException */ private void loadRemoteResource(URL url) throws IOException { if( logger.isTraceEnabled() ) logger.trace( "Attempting to load a remote resource." ); if( url.toString().toLowerCase().endsWith( ".jar" ) ) { loadJar( url ); return; } InputStream stream = url.openStream(); ByteArrayOutputStream out = new ByteArrayOutputStream(); int byt; while(( ( byt = stream.read() ) != -1 )) { out.write( byt ); } byte[] content = out.toByteArray(); if( jarEntryContents.containsKey( url.toString() ) ) { if( !Configuration.supressCollisionException() ) throw new JclException( "Resource " + url.toString() + " already loaded" ); else { if( logger.isTraceEnabled() ) logger.trace( "Resource " + url.toString() + " already loaded; ignoring entry..." ); return; } } if( logger.isTraceEnabled() ) logger.trace( "Loading remote resource." ); jarEntryContents.put( url.toString(), content ); out.close(); stream.close(); } /** * Reads the class content * * @param clazz * @param pack * @throws IOException */ private void loadClassContent(String clazz, String pack) throws IOException { File cf = new File( clazz ); FileInputStream fis = new FileInputStream( cf ); byte[] content = new byte[(int) cf.length()]; fis.read( content ); String entryName = pack + "/" + cf.getName(); if( jarEntryContents.containsKey( entryName ) ) { if( !Configuration.supressCollisionException() ) throw new JclException( "Class " + entryName + " already loaded" ); else { if( logger.isTraceEnabled() ) logger.trace( "Class " + entryName + " already loaded; ignoring entry..." ); return; } } fis.close(); if( logger.isTraceEnabled() ) logger.trace( "Loading class: " + entryName ); jarEntryContents.put( entryName, content ); } /** * Reads local and remote resources * * @param url * @throws IOException */ public void loadResource(URL url) throws IOException { try { // Is Local loadResource( new File( url.toURI() ), "" ); } 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 * @throws IOException */ public void loadResource(String path) throws IOException { if( logger.isTraceEnabled() ) logger.trace( "Resource: " + path ); loadResource( new File( path ), "" ); } /** * Reads local resources from - Jar files - Class folders - Jar Library * folders * * @param fol * @param packName * @throws IOException */ private void loadResource(File fol, String packName) throws IOException { if( fol.isFile() ) { if( fol.getName().toLowerCase().endsWith( ".class" ) ) { loadClassContent( fol.getAbsolutePath(), packName ); } else { if( fol.getName().toLowerCase().endsWith( ".jar" ) ) { loadJar( fol.getAbsolutePath() ); } else { loadResourceContent( fol.getAbsolutePath() ); } } return; } 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 ); } } } /** * Removes the loaded resource * * @param resource * @throws ResourceNotFoundException */ public void unload(String resource) throws ResourceNotFoundException { if( jarEntryContents.containsKey( resource ) ) { if( logger.isTraceEnabled() ) logger.trace( "Removing resource " + resource ); jarEntryContents.remove( resource ); } else { throw new ResourceNotFoundException( resource, "Resource not found in local ClasspathResources" ); } } }