Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jboss.virtual.plugins.context.jar.NestedJarFromStream Maven / Gradle / Ivy
/*
* Copyright (c) 2005 Your Corporation. All Rights Reserved.
*/
package org.jboss.virtual.plugins.context.jar;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectInputStream.GetField;
import java.io.ObjectOutputStream;
import java.io.ObjectOutputStream.PutField;
import java.io.ObjectStreamField;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.jboss.virtual.spi.VFSContext;
import org.jboss.virtual.spi.VirtualFileHandler;
/**
* A nested jar implementation used to represent a jar within a jar.
*
* @author [email protected]
* @author [email protected]
* @version $Revision: 44334 $
*/
public class NestedJarFromStream extends AbstractStructuredJarHandler
{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 2L;
/** The class serial fields */
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("zisBytes", byte[].class),
new ObjectStreamField("jarURL", URL.class),
new ObjectStreamField("entryURL", String.class),
new ObjectStreamField("lastModified", long.class),
new ObjectStreamField("size", long.class)
};
private transient ZipInputStream zis;
private transient AtomicBoolean inited = new AtomicBoolean(false);
private URL jarURL;
private URL entryURL;
private long lastModified;
private long size;
/**
* Create a nested jar from the parent zip inputstream/zip entry.
*
* @param context - the context containing the jar
* @param parent - the jar handler for this nested jar
* @param zis - the jar zip input stream
* @param jarURL - the URL to use as the jar URL
* @param jar - the parent jar file for the nested jar
* @param entry - the zip entry
* @param entryName - the entry name
* @throws IOException for any error
*/
public NestedJarFromStream(VFSContext context, VirtualFileHandler parent, ZipInputStream zis, URL jarURL, JarFile jar, ZipEntry entry, String entryName) throws IOException
{
super(context, parent, jarURL, jar, entry, entryName);
this.jarURL = jarURL;
this.lastModified = entry.getTime();
this.size = entry.getSize();
this.zis = zis;
try
{
setPathName(getChildPathName(entryName, false));
setVfsUrl(getChildVfsUrl(entryName, false));
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
protected void initCacheLastModified()
{
cachedLastModified = lastModified;
}
/**
* Initialize entries.
*
* @throws IOException for any error
*/
protected void init() throws IOException
{
if (inited.get() == false)
{
inited.set(true);
try
{
initJarFile(new ZisEnumeration());
}
finally
{
close();
}
}
}
public List getChildren(boolean ignoreErrors) throws IOException
{
init();
return super.getChildren(ignoreErrors);
}
public VirtualFileHandler getChild(String path) throws IOException
{
init();
return super.getChild(path);
}
public boolean removeChild(String name) throws IOException
{
return false;
}
public VirtualFileHandler createChildHandler(String name) throws IOException
{
init();
return super.createChildHandler(name);
}
protected void extraWrapperInfo(ZipEntryWrapper wrapper) throws IOException
{
byte[] contents;
int size = (int)wrapper.getSize();
if (size != 0)
{
ByteArrayOutputStream baos = size > 0 ? new ByteArrayOutputStream(size) : new ByteArrayOutputStream();
byte[] tmp = new byte[1024];
while (zis.available() > 0)
{
int length = zis.read(tmp);
if (length > 0)
baos.write(tmp, 0, length);
}
contents = baos.toByteArray();
}
else
contents = new byte[0];
wrapper.setExtra(contents);
}
protected VirtualFileHandler createVirtualFileHandler(VirtualFileHandler parent, ZipEntryWrapper wrapper, String entryName) throws IOException
{
try
{
String url = toURI().toASCIIString() + "!/" + wrapper.getName();
URL jecURL = new URL(url);
VFSContext context = parent.getVFSContext();
if (wrapper.isDirectory())
{
return new SynthenticDirEntryHandler(context, parent, entryName, System.currentTimeMillis(), jecURL);
}
else
{
byte[] contents = wrapper.getExtra();
return new JarEntryContents(context, parent, wrapper.getEntry(), entryName, toURL(), jecURL, contents);
}
}
catch (Throwable t)
{
IOException ioe = new IOException("Exception while reading nested jar entry: " + this);
ioe.initCause(t);
ioe.setStackTrace(t.getStackTrace());
throw ioe;
}
}
/**
* TODO: removing the entry/jar that resulted in this needs
* to be detected.
*/
public boolean exists() throws IOException
{
return true;
}
public boolean isHidden()
{
return false;
}
public long getSize()
{
return size;
}
public long getLastModified() throws IOException
{
return lastModified;
}
public boolean isNested() throws IOException
{
return true;
}
public boolean delete(int gracePeriod)
{
return false;
}
// Stream accessor
public InputStream openStream() throws IOException
{
if(zis == null)
{
// Need to obtain this nested jar input stream from parent
InputStream parentIS = super.getParent().openStream();
if(parentIS == null)
throw new IOException("Failed to open parent stream, "+this);
if(parentIS instanceof ZipInputStream)
{
zis = (ZipInputStream) parentIS;
}
else
{
zis = new ZipInputStream(parentIS);
}
// First find our entry
ZipEntry entry = zis.getNextEntry();
while(entry != null)
{
if(entry.getName().equals(getName()))
break;
entry = zis.getNextEntry();
}
if(entry == null)
throw new IOException("Failed to find nested jar entry: "+this.getName()+" in parent: "+getParent());
}
return zis;
}
public void close()
{
if (zis != null)
{
try
{
zis.close();
}
catch (IOException e)
{
log.error("close error", e);
}
zis = null;
}
}
public URI toURI() throws URISyntaxException
{
try
{
if (entryURL == null)
entryURL = new URL(jarURL, getName());
}
catch (MalformedURLException e)
{
throw new URISyntaxException("Failed to create relative jarURL", e.getMessage());
}
return entryURL.toURI();
}
public String toString()
{
StringBuffer tmp = new StringBuffer(super.toString());
tmp.append('[');
tmp.append("name=");
tmp.append(getName());
tmp.append(",size=");
tmp.append(getSize());
tmp.append(",lastModified=");
tmp.append(lastModified);
tmp.append(",URI=");
try
{
tmp.append(toURI());
}
catch (URISyntaxException e)
{
}
tmp.append(']');
return tmp.toString();
}
protected void initJarFile() throws IOException
{
// todo - deserialize
}
private class ZisEnumeration implements Enumeration>
{
private boolean moved = true;
private ZipEntry next = null;
public boolean hasMoreElements()
{
if (zis == null)
return false;
try
{
if (moved)
{
next = zis.getNextEntry();
moved = false;
}
return next != null;
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
public ZipEntryWrapper nextElement()
{
moved = true;
return new ZipEntryWrapper(next);
}
}
/**
* Write the jar contents and information
* @param out
* @throws IOException
*/
private void writeObject(ObjectOutputStream out)
throws IOException
{
PutField fields = out.putFields();
byte[] zisBytes;
ZipInputStream jarStream = zis;
if(jarStream == null)
{
// Need to obtain this nested jar input stream from parent
InputStream parentIS = super.getParent().openStream();
if(parentIS == null)
throw new IOException("Failed to open parent stream, "+this);
jarStream = new ZipInputStream(parentIS);
// First find our entry
ZipEntry entry = jarStream.getNextEntry();
while(entry != null)
{
if(entry.getName().equals(getName()))
break;
entry = jarStream.getNextEntry();
}
if(entry == null)
throw new IOException("Failed to find nested jar entry: "+this.getName()+" in parent: "+getParent());
}
// Now read zis for this entry
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] tmp = new byte[1024];
int length = jarStream.read(tmp);
while(length > 0)
{
baos.write(tmp, 0, length);
length = jarStream.read(tmp);
}
jarStream.close();
jarStream = null;
zisBytes = baos.toByteArray();
fields.put("zisBytes", zisBytes);
fields.put("jarURL", jarURL);
fields.put("entryURL", entryURL);
fields.put("lastModified", lastModified);
fields.put("size", size);
out.writeFields();
}
/**
* Read the jar contents and reinitialize the entry map
* @param in
* @throws IOException
* @throws ClassNotFoundException
*/
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
// Read in the serialPersistentFields
GetField fields = in.readFields();
byte[] zisBytes = (byte[]) fields.get("zisBytes", null);
this.jarURL = (URL) fields.get("jarURL", null);
this.entryURL = (URL) fields.get("entryURL", null);
this.lastModified = fields.get("lastModified", (long)-1);
this.size = fields.get("size", (long)-1);
// Initialize the jar entry map
inited = new AtomicBoolean(false);
ByteArrayInputStream bais = new ByteArrayInputStream(zisBytes);
zis = new ZipInputStream(bais);
this.init();
}
}