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
18package org.apache.harmony.sql.tests.java.sql;
19
20import java.io.File;
21import java.io.FileInputStream;
22import java.io.IOException;
23import java.io.InputStream;
24import java.util.jar.JarEntry;
25import java.util.jar.JarFile;
26
27public class TestHelper_ClassLoader extends ClassLoader {
28
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
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
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
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     */
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