package oracle.jaccelerator.server; import java.io.*; import java.util.Hashtable; import java.util.Enumeration; import java.util.Date; import java.util.Stack; import java.sql.*; import oracle.jdbc.*; import oracle.sql.CHAR; import oracle.sql.BLOB; import oracle.aurora.rdbms.Handle; import oracle.aurora.rdbms.ClassHandle; import oracle.aurora.rdbms.Schema; public class MinimizeNcompListAndDumpTC extends TransitiveClosureDumper { String libPrefix; String DLLExtension; public MinimizeNcompListAndDumpTC (BLOB classListBlob, String libPrefix, String DLLExtension) throws SQLException, IOException { super(classListBlob); this.libPrefix = libPrefix; this.DLLExtension = DLLExtension; } public MinimizeNcompListAndDumpTC (String libPrefix, String DLLExtension) throws IOException { super(); this.libPrefix = libPrefix; this.DLLExtension = DLLExtension; } public void validate (String prefix, String[] roots, Schema schema) throws SQLException, IOException { for (int i = 0; i < roots.length; i++) { String name = roots[i]; if (prefix != null) name = prefix + name; ClassHandle h = Handle.lookupClass(name, schema); if (h == null) { classNotFound(name, schema); } else if (h.status() == Handle.INVALID) { // warning("class to translate is invalid: " + name + " in " + schema); try { h.resolve(); } catch (Exception e) { warning("-- MinimizeNcompListAndDumpTC.validate: " + e); } } } } public static boolean classNotFoundMustThrowError = false; private static void classNotFound (String name, Schema schema) throws SQLException { String message = "MinimizeNcompListAndDumpTC: class to translate not found: " + name + " in " + schema; warning(message); if (classNotFoundMustThrowError) throw new SQLException(message); } Hashtable probedDLLs = new Hashtable(); String o_home = (String)System.getProperty("oracle.aurora.rdbms.oracle_home"); String oracle_home = (o_home.endsWith(File.separator)) ? o_home : o_home + File.separator; String adminPath = oracle_home + "javavm" + File.separator + "admin" + File.separator; public boolean DLLExists (ClassHandle h) { String libraryLogicalName = h.getNcompLibNameAsCHAR().toString(); if (libraryLogicalName == null) return false; if (probedDLLs.get(libraryLogicalName) != null) return true; String so_name = libPrefix + "jtc" + libraryLogicalName.replace('-','_') + "." + DLLExtension; System.out.println("-- so_name: " + so_name); File file = new File(adminPath, so_name); boolean exists = file.exists(); System.out.println("-- exists: " + exists); if (exists) probedDLLs.put(libraryLogicalName, libraryLogicalName); return exists; } private static String[] stackToStringArray (Stack stack) { if (stack == null) return null; String[] result = new String[stack.size()]; stack.copyInto(result); return result; } Stack validClasses = new Stack(); Stack invalidClasses = new Stack(); Stack ncompedClasses = new Stack(); Stack notNcompedClasses = new Stack(); Stack notFoundClasses = new Stack(); Stack notNcompedModules = new Stack(); Stack ncompedModules = new Stack(); public String[] getValidClasses () { return stackToStringArray(validClasses); } public String[] getInvalidClasses () { return stackToStringArray(invalidClasses); } public String[] getNcompedClasses () { return stackToStringArray(ncompedClasses); } public String[] getNotNcompedClasses () { return stackToStringArray(notNcompedClasses); } public String[] getNotFoundClasses () { return stackToStringArray(notFoundClasses); } public String[] getNotNcompedModules () { return stackToStringArray(notNcompedModules); } public String[] getNcompedModules () { return stackToStringArray(ncompedModules); } public boolean appearsNcomped (ClassHandle h) throws SQLException, IOException { return (h.getNcompIsEnabled() && h.getNcompIsAllowed() && DLLExists(h)); } public void gatherClassesThatNeedNcomp (String module, String[] classes, Schema schema, boolean forceAll) throws SQLException, IOException { boolean everythingInThisModuleIsNcomped = (forceAll ? false : true); String[] validOrNull = new String[classes.length]; for (int i = 0; i < classes.length; i++) { String name = module + classes[i]; ClassHandle h = Handle.lookupClass(name, schema); if (h == null) { classNotFound(name, schema); notFoundClasses.push(name); } else if (h.status() == Handle.VALID) { validOrNull[i] = classes[i]; boolean appearsNcomped = appearsNcomped(h); if (appearsNcomped) ncompedClasses.push(name); else notNcompedClasses.push(name); everythingInThisModuleIsNcomped = everythingInThisModuleIsNcomped && appearsNcomped; } else invalidClasses.push(name); } if (everythingInThisModuleIsNcomped) { if (module.equals("") == false) ncompedModules.push(module); } else { if (module.equals("") == false) notNcompedModules.push(module); for (int i = 0; i < classes.length; i++) { String validClass = validOrNull[i]; if (validClass != null) validClasses.push(module + validClass); } } } public String[] computeEffectiveClassList (String[] roots) { Hashtable bag = new Hashtable(); Enumeration e = validClasses.elements(); while (e.hasMoreElements()) { String elt = (String)e.nextElement(); String pkg = classToPackageName(elt); for (int i = 0; i < roots.length; i++) { if (inPackage(roots[i], pkg)) bag.put(elt, pkg); } } String[] result = new String[bag.size()]; int idx = 0; e = bag.keys(); while (e.hasMoreElements()) { result[idx] = (String)e.nextElement(); idx++; } return result; } String classToPackageName (String className) { return className.substring(0, className.lastIndexOf('/')); } boolean inPackage (String className, String packageName) { if (className.length() < 2 + packageName.length()) return false; if (className.startsWith(packageName) == false) return false; className = className.substring(packageName.length()); if (className.indexOf('/') != 0) return false; if (className.lastIndexOf('/') > 0) return false; return true; } public String listClassesAndDumpTC (String[][] modules, String[] moduleNames, String schemaName, boolean forceAll) throws SQLException, IOException { schemaName = schemaName.toUpperCase(); if (schemaName.equals("INTERNAL")) schemaName = "SYS"; try { Schema schema = Schema.lookup(schemaName); System.out.println("-- schema: " + schema); for (int i = 0; i < modules.length; i++) validate(moduleNames[i], modules[i], schema); for (int i = 0; i < modules.length; i++) gatherClassesThatNeedNcomp(moduleNames[i], modules[i], schema, forceAll); String[] roots = new String[validClasses.size()]; validClasses.copyInto(roots); return super.traverseReferences(roots, schemaName); } catch (Exception e) { System.out.println("-- MinimizeNcompListAndDumpTC.minimizeListAndDump(): " + e); e.printStackTrace(System.out); throw new SQLException("" +e); } } private Messages messages; private Date stamp = new Date(); private void emitInfo(String name, String status) throws SQLException, IOException { // classAttributesWriter.println(name + " " + status + " _ _ _"); classAttributesWriter.println("# " + status + " " + name); messages.makeStatusRecord(name, status, stamp, false); } private void emitInfo(Stack list, String status, String comment) throws SQLException, IOException { if (list.size() > 0) { classAttributesWriter.println(); classAttributesWriter.println("# " + comment); classAttributesWriter.println(); Enumeration e = list.elements(); while(e.hasMoreElements()) { String name = (String)e.nextElement(); emitInfo(name, status); } } } protected void dumpClasses_before () throws SQLException, IOException { try { OracleDriver driver = new OracleDriver(); Connection connection = driver.defaultConnection(); messages = new Messages(connection, "prepare status"); messages.prepareInfoTables(); messages.clearStatusRecords(); String jtc_h_checksum = Dumper.parseKeywordValuePair(oracle_home + "javavm" + File.separator + "jahome" + File.separator + "jtc.h", "JTC_CHECKSUM_NCOMP_H"); if (jtc_h_checksum == null) jtc_h_checksum = "UNKNOWN_CHECKSUM"; classAttributesWriter.println("# " + System.getProperty("os.name") + " " + System.getProperty("os.arch") + " " + jtc_h_checksum); emitInfo(invalidClasses, "INVALID", "Classes detected as invalid"); emitInfo(ncompedClasses, "ALREADY_NCOMPED", "Classes that are already ncomped"); emitInfo(notNcompedClasses, "NEED_NCOMPING", "Classes that need ncomping"); emitInfo(notFoundClasses, "NOT_FOUND_IN_SCHEMA", "Classes that are not found on the server"); emitInfo(notNcompedModules, "NEED_NCOMPING", "Ncomp libraries that need ncomping"); //emitInfo(ncompedModules, "ALREADY_NCOMPED", "Ncomp libraries are ncomped"); messages.finishInfoTables(); } catch (Exception e) { throw new SQLException("failed to produce status report because of: " + e); } finally { } } }