/**
* 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.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import org.apache.log4j.Logger;
import xeus.jcl.exception.JclException;
/**
* JarResources reads jar files and loads the class content/bytes in a HashMap
*
* @author Kamran Zafar
*
*/
public class JarResources {
protected Map<String, byte[]> jarEntryContents;
private static Logger logger = Logger.getLogger( JarResources.class );
/**
* @throws IOException
*/
public JarResources() {
jarEntryContents = new HashMap<String, byte[]>();
}
/**
* @param name
* @return byte[]
*/
public byte[] getResource(String name) {
return jarEntryContents.get( name );
}
/**
* Returns an immutable Map of all jar resources
*
* @return Map
*/
public Map<String, byte[]> getResources() {
return Collections.unmodifiableMap( jarEntryContents );
}
/**
* Reads the specified jar file
*
* @param jarFile
* @throws IOException
*/
public void loadJar(String jarFile) throws IOException {
if( logger.isTraceEnabled() )
logger.trace( "Loading jar: " + jarFile );
FileInputStream fis = new FileInputStream( jarFile );
loadJar( fis );
fis.close();
}
/**
* Reads the jar file from a specified URL
*
* @param url
* @throws IOException
*/
public void loadJar(URL url) throws IOException {
if( logger.isTraceEnabled() )
logger.trace( "Loading jar: " + url.toString() );
InputStream in = url.openStream();
loadJar( in );
in.close();
}
/**
* Load the jar contents from InputStream
*
* @throws IOException
*/
public void loadJar(InputStream jarStream) throws IOException {
BufferedInputStream bis = null;
JarInputStream jis = null;
try {
bis = new BufferedInputStream( jarStream );
jis = new JarInputStream( bis );
JarEntry jarEntry = null;
while(( jarEntry = jis.getNextJarEntry() ) != null) {
if( logger.isTraceEnabled() )
logger.trace( dump( jarEntry ) );
if( jarEntry.isDirectory() ) {
continue;
}
if( jarEntryContents.containsKey( jarEntry.getName() ) ) {
if( !Configuration.supressCollisionException() )
throw new JclException( "Class/Resource " + jarEntry.getName() + " already loaded" );
else {
if( logger.isTraceEnabled() )
logger
.trace( "Class/Resource " + jarEntry.getName()
+ " already loaded; ignoring entry..." );
continue;
}
}
if( logger.isTraceEnabled() )
logger.trace( "Entry Name: " + jarEntry.getName() + ", " + "Entry Size: " + jarEntry.getSize() );
byte[] b = new byte[2048];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len = 0;
while(( len = jis.read( b ) ) > 0) {
out.write( b, 0, len );
}
// add to internal resource HashMap
jarEntryContents.put( jarEntry.getName(), out.toByteArray() );
if( logger.isTraceEnabled() )
logger.trace( jarEntry.getName() + ": size=" + out.size() + " ,csize="
+ jarEntry.getCompressedSize() );
out.close();
}
} catch (NullPointerException e) {
if( logger.isTraceEnabled() )
logger.trace( "Done loading." );
} finally {
jis.close();
bis.close();
}
}
/**
* For debugging
*
* @param je
* @return String
*/
private String dump(JarEntry je) {
StringBuffer sb = new StringBuffer();
if( je.isDirectory() ) {
sb.append( "d " );
} else {
sb.append( "f " );
}
if( je.getMethod() == JarEntry.STORED ) {
sb.append( "stored " );
} else {
sb.append( "defalted " );
}
sb.append( je.getName() );
sb.append( "\t" );
sb.append( "" + je.getSize() );
if( je.getMethod() == JarEntry.DEFLATED ) {
sb.append( "/" + je.getCompressedSize() );
}
return ( sb.toString() );
}
}