Package org.jboss.virtual.plugins.context.jar

Source Code of org.jboss.virtual.plugins.context.jar.NestedJarFromStream$ZisEnumeration

/*
* Copyright (c) 2005 Your Corporation. All Rights Reserved.
*/
package org.jboss.virtual.plugins.context.jar;

import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
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.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 Ales.Justin@jboss.org
* @author Scott.Stark@jboss.org
* @version $Revision: 44334 $
*/
public class NestedJarFromStream extends AbstractStructuredJarHandler<byte[]>
{
   /**
    * serialVersionUID
    */
   private static final long serialVersionUID = 1L;

   private transient ZipInputStream zis;
   private URL jarURL;
   private URL entryURL;
   private long lastModified;
   private long size;
   private AtomicBoolean inited = new AtomicBoolean(false);

   /**
    * 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<VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException
   {
      init();
      return super.getChildren(ignoreErrors);
   }

   public VirtualFileHandler getChild(String path) throws IOException
   {
      init();
      return super.getChild(path);
   }

   protected void extraWrapperInfo(ZipEntryWrapper<byte[]> wrapper) throws IOException
   {
      byte[] contents;
      int size = (int)wrapper.getSize();
      if (size > 0)
      {
         ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
         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<byte[]> wrapper, String entryName) throws IOException
   {
      try
      {
         String url = toURI().toASCIIString() + "!/" + wrapper.getName();
         URL jecURL = new URL(url);
         VFSContext context = parent.getVFSContext();
         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;
   }

   // Stream accessor
   public InputStream openStream() throws IOException
   {
      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<ZipEntryWrapper<byte[]>>
   {
      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<byte[]> nextElement()
      {
         moved = true;
         return new ZipEntryWrapper<byte[]>(next);
      }
   }
}
TOP

Related Classes of org.jboss.virtual.plugins.context.jar.NestedJarFromStream$ZisEnumeration

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.