1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package org.apache.harmony.sql.tests.java.sql;
19 
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.jar.JarEntry;
25 import java.util.jar.JarFile;
26 
27 public class TestHelper_ClassLoader extends ClassLoader {
28 
TestHelper_ClassLoader()29     public TestHelper_ClassLoader() {
30         super(null);
31     }
32 
33     /**
34      * Loads a class specified by its name
35      * <p/>
36      * This classloader makes the assumption that any class it is asked to load
37      * is in the current directory....
38      */
39     @Override
findClass(String className)40     public Class<?> findClass(String className) throws ClassNotFoundException {
41         Class<?> theClass = null;
42 
43         if (!className
44                 .equals("org.apache.harmony.sql.tests.java.sql.TestHelper_DriverManager")) {
45             return null;
46         }
47 
48         String classNameAsFile = className.replace('.', '/') + ".class";
49         // System.out.println("findClass - class filename = " + classNameAsFile
50         // );
51 
52         String classPath = System.getProperty("java.class.path");
53         // System.out.println("Test class loader - classpath = " + classPath );
54 
55         String theSeparator = String.valueOf(File.pathSeparatorChar);
56         String[] theClassPaths = classPath.split(theSeparator);
57         for (int i = 0; (i < theClassPaths.length) && (theClass == null); i++) {
58             // Ignore jar files...
59             if (theClassPaths[i].endsWith(".jar")) {
60                 theClass = loadClassFromJar(theClassPaths[i], className,
61                         classNameAsFile);
62             } else {
63                 theClass = loadClassFromFile(theClassPaths[i], className,
64                         classNameAsFile);
65             } // end if
66         } // end for
67 
68         return theClass;
69     } // end method findClass( String )
70 
71     @Override
loadClass(String className)72     public Class<?> loadClass(String className) throws ClassNotFoundException {
73         // Allowed classes:
74         String[] disallowedClasses = {
75                 "org.apache.harmony.sql.tests.java.sql.TestHelper_Driver1",
76                 "org.apache.harmony.sql.tests.java.sql.TestHelper_Driver2",
77                 "org.apache.harmony.sql.tests.java.sql.TestHelper_Driver4",
78                 "org.apache.harmony.sql.tests.java.sql.TestHelper_Driver5" };
79 
80         Class<?> theClass;
81 
82         theClass = findLoadedClass(className);
83         if (theClass != null) {
84             return theClass;
85         }
86 
87         theClass = this.findClass(className);
88 
89         if (theClass == null) {
90             for (String element : disallowedClasses) {
91                 if (element.equals(className)) {
92                     return null;
93                 } // end if
94             } // end for
95             theClass = Class.forName(className);
96         } // end if
97 
98         return theClass;
99     } // end method loadClass( String )
100 
loadClassFromFile(String pathName, String className, String classNameAsFile)101     private Class<?> loadClassFromFile(String pathName, String className,
102             String classNameAsFile) {
103         Class<?> theClass = null;
104         FileInputStream theInput = null;
105         File theFile = null;
106         try {
107             theFile = new File(pathName, classNameAsFile);
108             if (theFile.exists()) {
109                 int length = (int) theFile.length();
110                 theInput = new FileInputStream(theFile);
111                 byte[] theBytes = new byte[length + 100];
112                 int dataRead = 0;
113                 while (dataRead < length) {
114                     int count = theInput.read(theBytes, dataRead,
115                             theBytes.length - dataRead);
116                     if (count == -1) {
117                         break;
118                     }
119                     dataRead += count;
120                 }
121 
122                 if (dataRead > 0) {
123                     // Create the class from the bytes read in...
124                     theClass = this.defineClass(className, theBytes, 0,
125                             dataRead);
126                     ClassLoader testClassLoader = theClass.getClassLoader();
127                     if (testClassLoader != this) {
128                         System.out.println("findClass - wrong classloader!!");
129                     }
130                 }
131             }
132         } catch (Exception e) {
133             System.out.println("findClass - exception reading class file.");
134             e.printStackTrace();
135         } finally {
136             try {
137                 if (theInput != null) {
138                     theInput.close();
139                 }
140             } catch (Exception e) {
141             }
142         }
143         return theClass;
144     }
145 
146     /*
147      * Loads a named class from a specified JAR file
148      */
loadClassFromJar(String jarfileName, String className, String classNameAsFile)149     private Class<?> loadClassFromJar(String jarfileName, String className,
150             String classNameAsFile) {
151         Class<?> theClass = null;
152 
153         // First, try to open the Jar file
154         JarFile theJar = null;
155         try {
156             theJar = new JarFile(jarfileName);
157             JarEntry theEntry = theJar.getJarEntry(classNameAsFile);
158 
159             if (theEntry == null) {
160                 // System.out.println("TestHelper_Classloader - did not find
161                 // class file in Jar " + jarfileName );
162                 return theClass;
163             } // end if
164 
165             theEntry.getMethod();
166             InputStream theStream = theJar.getInputStream(theEntry);
167 
168             long size = theEntry.getSize();
169             if (size < 0) {
170                 size = 100000;
171             }
172             byte[] theBytes = new byte[(int) size + 100];
173 
174             int dataRead = 0;
175             while (dataRead < size) {
176                 int count = theStream.read(theBytes, dataRead, theBytes.length
177                         - dataRead);
178                 if (count == -1) {
179                     break;
180                 }
181                 dataRead += count;
182             } // end while
183 
184             // System.out.println("loadClassFromJar: read " + dataRead + " bytes
185             // from class file");
186             if (dataRead > 0) {
187                 // Create the class from the bytes read in...
188                 theClass = this.defineClass(className, theBytes, 0, dataRead);
189                 /* System.out.println("findClass: created Class object."); */
190                 ClassLoader testClassLoader = theClass.getClassLoader();
191                 if (testClassLoader != this) {
192                     System.out.println("findClass - wrong classloader!!");
193                 } else {
194                     System.out
195                             .println("Testclassloader loaded class from jar: "
196                                     + className);
197                 } // end if
198             } // end if
199         } catch (IOException ie) {
200             System.out
201                     .println("TestHelper_ClassLoader: IOException opening Jar "
202                             + jarfileName);
203         } catch (Exception e) {
204             System.out
205                     .println("TestHelper_ClassLoader: Exception loading class from Jar ");
206         } catch (ClassFormatError ce) {
207             System.out
208                     .println("TestHelper_ClassLoader: ClassFormatException loading class from Jar ");
209         } finally {
210             try {
211                 if (theJar != null) {
212                     theJar.close();
213                 }
214             } catch (Exception e) {
215             } // end try
216         } // end try
217 
218         return theClass;
219     } // end method loadClassFromJar(
220 
221 } // end class TestHelper_ClassLoader
222 
223