View Javadoc

1   /* (c) Copyright 2003 Caleigo AB, All rights reserved. 
2    * 
3    * This library is free software; you can redistribute it and/or
4    * modify it under the terms of the GNU Lesser General Public
5    * License as published by the Free Software Foundation; either
6    * version 2.1 of the License, or (at your option) any later version.
7    * 
8    * This library is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   * Lesser General Public License for more details.
12   * 
13   * You should have received a copy of the GNU Lesser General Public
14   * License along with this library; if not, write to the Free Software
15   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16   *  
17   */
18  package org.caleigo.toolkit.util;
19  
20  import java.io.*;
21  import java.util.jar.*;
22  
23  /*** ClassLoader that can load classes from a jar file.
24   *
25   * @author  mha
26   * @version 1.00
27   *
28   */ /*
29   *
30   * WHEN        WHO               WHY & WHAT
31   * -----------------------------------------------------------------------------
32   * Oct 3, 2003  Mattias Hagstrand    Creation
33   */
34  public class FileClassLoader extends ClassLoader
35  {
36      // Data members ------------------------------------------------------------
37      private JarFile mJarFile;
38      
39      // Constructors ------------------------------------------------------------
40      public FileClassLoader(JarFile jarFile)
41      {
42          mJarFile = jarFile;
43      }
44      
45      // Superclass overrides ----------------------------------------------------
46      
47      /***
48       * Load class data from the jar file and define the class.
49       */
50      protected Class findClass(String name) throws ClassNotFoundException
51      {
52          //Create package and entry name
53          String packageName = name.substring(0, name.lastIndexOf('.'));
54          String entryName = name.replace('.', '/').concat(".class");
55          
56          // Try to find entry
57          JarEntry entry = mJarFile.getJarEntry(entryName);
58          if (entry == null)
59              throw new ClassNotFoundException(name);
60              
61          try
62          {
63              // Read class data from the jar file
64              InputStream inputStream = mJarFile.getInputStream(entry);
65              ByteBuffer byteBuffer = new ByteBuffer();
66              byte[] data = new byte[500];
67              while (inputStream.available() > 0)
68              {
69                  int nbrOfReadBytes = inputStream.read(data);
70                  if (nbrOfReadBytes != -1)
71                      byteBuffer.addBytes(data, nbrOfReadBytes);
72              }
73              inputStream.close();
74              
75              // Check if package exists and define it if it does not exist
76              Package pkg = getPackage(packageName);
77              if (pkg == null)
78                  definePackage(packageName, null, null, null, null, null, null, null);
79                  
80              // Define the class
81              return defineClass(name, byteBuffer.getData(), 0, byteBuffer.getData().length);
82          } catch (IOException e)
83          {
84              throw new ClassNotFoundException(name, e);
85          }
86      }
87      
88      private class ByteBuffer
89      {
90          // Constants -----------------------------------------------------------
91          private final static int SIZE = 1000;
92          
93          // Data members --------------------------------------------------------
94          private byte[] mData = new byte[SIZE];
95          private int mOffset;
96          
97          // Access methods ------------------------------------------------------
98          public void addBytes(byte[] data, int length)
99          {
100             if (mData.length - mOffset < length)
101             {
102                 byte[] tempData = new byte[mData.length + SIZE];
103                 System.arraycopy(mData, 0, tempData, 0, mData.length);
104                 mData = tempData;
105             }
106             
107             System.arraycopy(data, 0, mData, mOffset, length);
108             mOffset += length;
109         }
110         
111         public byte[] getData()
112         {
113             byte[] data = new byte[mOffset];
114             System.arraycopy(mData, 0, data, 0, mOffset);
115             return data;
116         }
117     }
118 }