Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / services / reflect / DatabaseClasses.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/services/reflect/DatabaseClasses.java
new file mode 100644 (file)
index 0000000..5d2aab7
--- /dev/null
@@ -0,0 +1,332 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.services.reflect.DatabaseClasses\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.services.reflect;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.services.loader.ClassFactory;\r
+import org.apache.derby.iapi.services.loader.GeneratedClass;\r
+import org.apache.derby.iapi.services.loader.ClassInspector;\r
+\r
+import org.apache.derby.iapi.services.monitor.ModuleControl;\r
+import org.apache.derby.iapi.services.monitor.ModuleSupportable;\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.services.property.PropertyUtil;\r
+\r
+import org.apache.derby.iapi.services.stream.HeaderPrintWriter;\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+\r
+import org.apache.derby.iapi.services.compiler.*;\r
+import java.lang.reflect.Modifier;\r
+import org.apache.derby.iapi.sql.compile.CodeGeneration;\r
+\r
+import org.apache.derby.iapi.util.ByteArray;\r
+import org.apache.derby.iapi.services.io.FileUtil;\r
+import org.apache.derby.iapi.services.i18n.MessageService;\r
+import org.apache.derby.iapi.reference.Property;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.reference.MessageId;\r
+import org.apache.derby.iapi.reference.ClassName;\r
+\r
+import java.util.Properties;\r
+import java.util.Hashtable;\r
+\r
+import java.io.ObjectStreamClass;\r
+import java.io.File;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.Serializable;\r
+\r
+/**\r
+\r
+    An abstract implementation of the ClassFactory. This package can\r
+       be extended to fully implement a ClassFactory. Implementations can\r
+       differ in two areas, how they load a class and how they invoke methods\r
+       of the generated class.\r
+\r
+    <P>\r
+       This class manages a hash table of loaded generated classes and\r
+       their GeneratedClass objects.  A loaded class may be referenced\r
+       multiple times -- each class has a reference count associated\r
+       with it.  When a load request arrives, if the class has already\r
+       been loaded, its ref count is incremented.  For a remove request,\r
+       the ref count is decremented unless it is the last reference,\r
+       in which case the class is removed.  This is transparent to users.\r
+\r
+       @see org.apache.derby.iapi.services.loader.ClassFactory\r
+*/\r
+\r
+abstract class DatabaseClasses\r
+       implements ClassFactory, ModuleControl\r
+{\r
+       /*\r
+       ** Fields\r
+       */\r
+\r
+       private ClassInspector  classInspector;\r
+       private JavaFactory             javaFactory;\r
+\r
+       private UpdateLoader            applicationLoader;\r
+\r
+       /*\r
+       ** Constructor\r
+       */\r
+\r
+       DatabaseClasses() {\r
+       }\r
+\r
+       /*\r
+       ** Public methods of ModuleControl\r
+       */\r
+\r
+       public void boot(boolean create, Properties startParams)\r
+               throws StandardException\r
+       {\r
+\r
+               classInspector = new ClassInspector(this);\r
+\r
+               //\r
+               //The ClassFactory runs per service (database) mode (booted as a service module after AccessFactory).\r
+               //If the code that booted\r
+               //us needs a per-database classpath then they pass in the classpath using\r
+               //the runtime property BOOT_DB_CLASSPATH in startParams\r
+\r
+\r
+               String classpath = null;\r
+               if (startParams != null) {\r
+                       classpath = startParams.getProperty(Property.BOOT_DB_CLASSPATH);\r
+               }\r
+\r
+               if (classpath != null) {\r
+                       applicationLoader = new UpdateLoader(classpath, this, true,\r
+                                                 true);\r
+               }\r
+\r
+               javaFactory = (JavaFactory) org.apache.derby.iapi.services.monitor.Monitor.startSystemModule(org.apache.derby.iapi.reference.Module.JavaFactory);\r
+       }\r
+\r
+\r
+\r
+       public void stop() {\r
+               if (applicationLoader != null)\r
+                       applicationLoader.close();\r
+       }\r
+\r
+       /*\r
+       **      Public methods of ClassFactory\r
+       */\r
+\r
+       /**\r
+               Here we load the newly added class now, rather than waiting for the\r
+               findGeneratedClass(). Thus we are assuming that the class is going\r
+               to be used sometime soon. Delaying the load would mean storing the class\r
+               data in a file, this wastes cycles and compilcates the cleanup.\r
+\r
+               @see ClassFactory#loadGeneratedClass\r
+\r
+               @exception      StandardException Class format is bad.\r
+       */\r
+       public final GeneratedClass loadGeneratedClass(String fullyQualifiedName, ByteArray classDump)\r
+               throws StandardException {\r
+\r
+\r
+                       try {\r
+\r
+\r
+                               return loadGeneratedClassFromData(fullyQualifiedName, classDump);\r
+\r
+                       } catch (LinkageError le) {\r
+\r
+                           WriteClassFile(fullyQualifiedName, classDump, le);\r
+\r
+                               throw StandardException.newException(SQLState.GENERATED_CLASS_LINKAGE_ERROR,\r
+                                                       le, fullyQualifiedName);\r
+\r
+               } catch (VirtualMachineError vme) { // these may be beyond saving, but fwiw\r
+\r
+                           WriteClassFile(fullyQualifiedName, classDump, vme);\r
+\r
+                           throw vme;\r
+                   }\r
+\r
+       }\r
+\r
+    private static void WriteClassFile(String fullyQualifiedName, ByteArray bytecode, Throwable t) {\r
+\r
+               // get the un-qualified name and add the extension\r
+        int lastDot = fullyQualifiedName.lastIndexOf((int)'.');\r
+        String filename = fullyQualifiedName.substring(lastDot+1,fullyQualifiedName.length()).concat(".class");\r
+\r
+               Object env = Monitor.getMonitor().getEnvironment();\r
+               File dir = env instanceof File ? (File) env : null;\r
+\r
+               File classFile = FileUtil.newFile(dir,filename);\r
+\r
+               // find the error stream\r
+               HeaderPrintWriter errorStream = Monitor.getStream();\r
+\r
+               try {\r
+                       FileOutputStream fis = new FileOutputStream(classFile);\r
+                       fis.write(bytecode.getArray(),\r
+                               bytecode.getOffset(), bytecode.getLength());\r
+                       fis.flush();\r
+                       if (t!=null) {                          \r
+                               errorStream.printlnWithHeader(MessageService.getTextMessage(MessageId.CM_WROTE_CLASS_FILE, fullyQualifiedName, classFile, t));\r
+                       }\r
+                       fis.close();\r
+               } catch (IOException e) {\r
+                       if (SanityManager.DEBUG)\r
+                               SanityManager.THROWASSERT("Unable to write .class file");\r
+               }\r
+       }\r
+\r
+       public ClassInspector getClassInspector() {\r
+               return classInspector;\r
+       }\r
+\r
+\r
+       public final Class loadApplicationClass(String className)\r
+               throws ClassNotFoundException {\r
+        \r
+        if (className.startsWith("org.apache.derby.")) {\r
+            // Assume this is an engine class, if so\r
+            // try to load from this class loader,\r
+            // this ensures in strange class loader\r
+            // environments we do not get ClassCastExceptions\r
+            // when an engine class is loaded through a different\r
+            // class loader to the rest of the engine.\r
+            try {\r
+                return Class.forName(className);\r
+                       //Added by Jeff Huang\r
+                       //TODO: FIXIT\r
+            } catch (ClassNotFoundException cnfe)\r
+            {\r
+                // fall through to the code below,\r
+                // could be client or tools class\r
+                // in a different loader.\r
+            }\r
+        }\r
\r
+               Throwable loadError;\r
+               try {\r
+                       try {\r
+                               return loadClassNotInDatabaseJar(className);\r
+                       } catch (ClassNotFoundException cnfe) {\r
+                               if (applicationLoader == null)\r
+                                       throw cnfe;\r
+                               Class c = applicationLoader.loadClass(className, true);\r
+                               if (c == null)\r
+                                       throw cnfe;\r
+                               return c;\r
+                       }\r
+               }\r
+               catch (SecurityException se)\r
+               {\r
+                       // Thrown if the class has been comprimised in some\r
+                       // way, e.g. modified in a signed jar.\r
+                       loadError = se; \r
+               }\r
+               catch (LinkageError le)\r
+               {\r
+                       // some error linking the jar, again could\r
+                       // be malicious code inserted into a jar.\r
+                       loadError = le; \r
+               }\r
+               throw new ClassNotFoundException(className + " : " + loadError.getMessage());\r
+       }\r
+       \r
+       abstract Class loadClassNotInDatabaseJar(String className)\r
+               throws ClassNotFoundException;\r
+\r
+       public final Class loadApplicationClass(ObjectStreamClass classDescriptor)\r
+               throws ClassNotFoundException {\r
+               return loadApplicationClass(classDescriptor.getName());\r
+       }\r
+\r
+       public boolean isApplicationClass(Class theClass) {\r
+\r
+               return theClass.getClassLoader()\r
+                       instanceof JarLoader;\r
+       }\r
+\r
+       public void notifyModifyJar(boolean reload) throws StandardException  {\r
+               if (applicationLoader != null) {\r
+                       applicationLoader.modifyJar(reload);\r
+               }\r
+       }\r
+\r
+       /**\r
+               Notify the class manager that the classpath has been modified.\r
+\r
+               @exception StandardException thrown on error\r
+       */\r
+       public void notifyModifyClasspath(String classpath) throws StandardException {\r
+\r
+               if (applicationLoader != null) {\r
+                       applicationLoader.modifyClasspath(classpath);\r
+               }\r
+       }\r
+\r
+\r
+       public int getClassLoaderVersion() {\r
+               if (applicationLoader != null) {\r
+                       return applicationLoader.getClassLoaderVersion();\r
+               }\r
+\r
+               return -1;\r
+       }\r
+\r
+       public ByteArray buildSpecificFactory(String className, String factoryName)\r
+               throws StandardException {\r
+\r
+               ClassBuilder cb = javaFactory.newClassBuilder(this, CodeGeneration.GENERATED_PACKAGE_PREFIX,\r
+                       Modifier.PUBLIC | Modifier.FINAL, factoryName, "org.apache.derby.impl.services.reflect.GCInstanceFactory");\r
+\r
+               MethodBuilder constructor = cb.newConstructorBuilder(Modifier.PUBLIC);\r
+\r
+               constructor.callSuper();\r
+               constructor.methodReturn();\r
+               constructor.complete();\r
+               constructor = null;\r
+\r
+               MethodBuilder noArg = cb.newMethodBuilder(Modifier.PUBLIC, ClassName.GeneratedByteCode, "getNewInstance");\r
+               noArg.pushNewStart(className);\r
+               noArg.pushNewComplete(0);\r
+               noArg.methodReturn();\r
+               noArg.complete();\r
+               noArg = null;\r
+\r
+               return cb.getClassBytecode();\r
+       }\r
+\r
+       /*\r
+       ** Class specific methods\r
+       */\r
+       \r
+       /*\r
+       ** Keep track of loaded generated classes and their GeneratedClass objects.\r
+       */\r
+\r
+       abstract LoadedGeneratedClass loadGeneratedClassFromData(String fullyQualifiedName, ByteArray classDump); \r
+}\r