--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.tools.sysinfo.Main\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.tools.sysinfo;\r
+\r
+import java.security.AccessController;\r
+import java.security.PrivilegedAction;\r
+import java.util.Locale;\r
+import java.io.IOException;\r
+import java.io.UnsupportedEncodingException;\r
+import java.io.InputStream;\r
+import java.util.Properties;\r
+import java.io.BufferedReader;\r
+import java.io.InputStreamReader;\r
+import java.util.Locale;\r
+import java.util.MissingResourceException;\r
+import java.util.ResourceBundle;\r
+import java.util.StringTokenizer;\r
+import java.io.File;\r
+import java.util.zip.ZipFile;\r
+import java.io.IOException;\r
+import java.util.zip.ZipEntry;\r
+import java.io.FileInputStream;\r
+import java.util.Vector;\r
+import java.io.InputStream;\r
+import java.lang.reflect.Method;\r
+import java.net.URL;\r
+import java.net.URLDecoder;\r
+import java.security.ProtectionDomain;\r
+import java.security.CodeSource;\r
+import java.security.AccessController;\r
+\r
+import org.apache.derby.iapi.services.info.PropertyNames;\r
+import org.apache.derby.iapi.services.info.ProductVersionHolder;\r
+import org.apache.derby.iapi.services.info.ProductGenusNames;\r
+\r
+import org.apache.derby.iapi.tools.i18n.*;\r
+\r
+\r
+/**\r
+ <P>\r
+ Sysinfo reports values relevant to the current Derby configuration.\r
+\r
+ <P>\r
+ Sysinfo looks for properties files in org.apache.derby.info named after\r
+ the genus names in org.apache.derby.tools.sysinfo, and gets their location\r
+ using getResource. It also searches the classpath and attempts to load\r
+ the info properties files from the directory or jar locations on the\r
+ classpath, and eliminates any duplicated information. If no files\r
+ are found, or some other exception occurs, the\r
+ value returned will be that set for the key\r
+ SysInfo.failureTag, or be the value "<info unavailable>".\r
+\r
+ <P>\r
+ This class can be used to print out system information at the\r
+ command line by issuing the command:\r
+ <PRE>\r
+ java org.apache.derby.tools.sysinfo\r
+ </PRE>\r
+ Alternatively, you can use SysInfo within your program to display\r
+ Derby information; a Derby version string is returned by this Java code:\r
+ <PRE>\r
+ new Main().toString();\r
+ </PRE>\r
+\r
+ */\r
+\r
+\r
+public final class Main {\r
+\r
+ /**\r
+ * Name of file which contains messages for sysinfo.\r
+ */\r
+ private final static String MESSAGE_FILE =\r
+ "org.apache.derby.loc.sysinfoMessages";\r
+\r
+ /**\r
+ * Resource for localizing the sysinfo messages.\r
+ *\r
+ * The default LocalizedResource reads messages from the toolsmessages\r
+ * bundle. Create this instance to read messages from sysinfoMessages. Use\r
+ * the locale and codeset specified by derby.ui.locale and derby.ui.codeset\r
+ * if they are set.\r
+ *\r
+ * Note that this variable must be initialized when the class is loaded in\r
+ * order to work correctly for the API methods that don't call\r
+ * <code>main()</code>.\r
+ */\r
+ private final static LocalizedResource LOCALIZED_RESOURCE =\r
+ new LocalizedResource(null, null, MESSAGE_FILE);\r
+\r
+ /**\r
+ Application entry point for SysInfo. This will print out\r
+ the Derby product information as well as a snapshot of\r
+ the System properties.\r
+ */\r
+ public static void main(String args[]) {\r
+ // adjust the application in accordance with derby.ui.locale and derby.ui.codeset\r
+ LocalizedResource.getInstance().init();\r
+\r
+ LocalizedOutput out;\r
+\r
+ //using AppStreamReader(extends InputStreamReader) for conversion into specific codeset\r
+\r
+ out = LocalizedResource.OutputWriter();\r
+\r
+ // because we're in a static method, we need to\r
+ // get our own instance variable\r
+ parseArgs (args);\r
+\r
+ if (cptester == true)\r
+ getClasspathInfo (args, out);\r
+ else\r
+ getMainInfo (out, setPause);\r
+\r
+ } // end of main (String args[])\r
+\r
+public static void getMainInfo (java.io.PrintWriter aw, boolean pause) {\r
+\r
+ aw.println (javaSep);\r
+ reportJavaInfo (aw);\r
+ aw.println (jbmsSep);\r
+ reportDerby (aw);\r
+\r
+ aw.println (sep);\r
+\r
+ // Locales info\r
+ try {\r
+ reportLocales (aw);\r
+ }\r
+ catch (Exception e) {\r
+\r
+ aw.println (Main.getTextMessage ("SIF01.Q"));\r
+ aw.println (Main.getTextMessage ("SIF01.B"));\r
+ }\r
+\r
+\r
+ if (pause) {\r
+ pause();\r
+ }\r
+\r
+ } // end of getMainInfo (AppStreamWriter aw, boolean printLicense, boolean pause)\r
+\r
+\r
+ private static boolean setPause = false;\r
+\r
+ private static boolean setLicense = false;\r
+\r
+ private static boolean cptester = false;\r
+\r
+ private static void parseArgs (String args[]) {\r
+\r
+ if (args == null) {\r
+\r
+ return;\r
+ }\r
+\r
+\r
+ for (int i = 0; i < args.length; i++) {\r
+\r
+ if (args[i].equals ("-pause")) {\r
+\r
+ setPause = true;\r
+ }\r
+\r
+ if (args[i].equals ("-cp")) {\r
+\r
+ cptester=true;\r
+ }\r
+\r
+ } // end for\r
+\r
+ } // end of parseArgs (String args[])\r
+\r
+\r
+ /**\r
+ For the benefit of DOS box users, this method waits for input\r
+ before returning\r
+ */\r
+ private static void pause () {\r
+\r
+ try {\r
+\r
+ System.out.print (Main.getTextMessage ("SIF01.C"));\r
+ BufferedReader br = new BufferedReader (new InputStreamReader (System.in));\r
+ br.readLine ();\r
+ }\r
+ catch (IOException ioe) {\r
+\r
+ //just return\r
+ }\r
+\r
+ } // end of pause ()\r
+\r
+ /**\r
+ prints out the jbms info to the specified AppStreamWriter.\r
+ @param localAW the AppStreamWriter to use. If null, System.out is\r
+ used\r
+ */\r
+\r
+ private static void reportDerby (java.io.PrintWriter localAW) {\r
+\r
+ localAW.println("JRE - JDBC: " + org.apache.derby.iapi.services.info.JVMInfo.derbyVMLevel());\r
+\r
+ String classpath = null;\r
+\r
+ try {\r
+ classpath = (String) AccessController.doPrivileged( new PrivilegedAction()\r
+ {\r
+ public Object run()\r
+ {\r
+ return System.getProperty("java.class.path");\r
+ }\r
+ }\r
+ );\r
+ }\r
+ catch (SecurityException se) {\r
+ localAW.println(\r
+ Main.getTextMessage ("SIF01.U", se.getMessage()));\r
+ classpath = null;\r
+ }\r
+\r
+ ZipInfoProperties zip[]= Main.getAllInfo (classpath);\r
+\r
+ if (zip != null) {\r
+\r
+ for (int i = 0; i < zip.length; i++) {\r
+\r
+ String thisInfo = "[" + zip[i].getLocation () + "] " +\r
+ zip[i].getVersionBuildInfo ();\r
+\r
+ localAW.println (thisInfo);\r
+ }\r
+ }\r
+\r
+ else {\r
+\r
+ localAW.println (Main.getTextMessage ("SIF01.D"));\r
+ }\r
+\r
+\r
+ } // end of reportDerby\r
+\r
+ /**\r
+ Writes out the relevant info about the Java environment to\r
+ the specified AppStreamWriter.\r
+\r
+ @param localAW The AppStreamWriter to write info out to. If this is\r
+ null, the info is written to System.out\r
+ */\r
+\r
+ private static void reportJavaInfo (java.io.PrintWriter localAW) {\r
+\r
+ \r
+\r
+ localAW.println (Main.getTextMessage ("SIF02.A",\r
+ getJavaProperty ("java.version")));\r
+\r
+ localAW.println (Main.getTextMessage ("SIF02.B",\r
+ getJavaProperty ("java.vendor")));\r
+\r
+ localAW.println (Main.getTextMessage ("SIF02.C",\r
+ getJavaProperty ("java.home")));\r
+\r
+ localAW.println (Main.getTextMessage ("SIF02.D",\r
+ getJavaProperty ("java.class.path")));\r
+\r
+ localAW.println (Main.getTextMessage ("SIF02.E",\r
+ getJavaProperty ("os.name")));\r
+\r
+ localAW.println (Main.getTextMessage ("SIF02.F",\r
+ getJavaProperty ("os.arch")));\r
+\r
+ localAW.println (Main.getTextMessage ("SIF02.G",\r
+ getJavaProperty ("os.version")));\r
+\r
+ localAW.println (Main.getTextMessage ("SIF02.H",\r
+ getJavaProperty ("user.name")));\r
+\r
+ localAW.println (Main.getTextMessage ("SIF02.I",\r
+ getJavaProperty ("user.home")));\r
+\r
+ localAW.println (Main.getTextMessage ("SIF02.J",\r
+ getJavaProperty ("user.dir")));\r
+\r
+ localAW.println("java.specification.name: " + getJavaProperty("java.specification.name"));\r
+ localAW.println("java.specification.version: " + getJavaProperty("java.specification.version"));\r
+\r
+\r
+ } // end of reportJavaInfo\r
+\r
+\r
+\r
+ /**\r
+ Return Java properties from java.lang.System. Will catch\r
+ SecurityExceptions and note them for displaying information.\r
+\r
+ @return the Java property value or a string capturing a\r
+ security exception.\r
+ */\r
+\r
+ private static String getJavaProperty (final String whichProperty) {\r
+\r
+ final String unavailable = Main.getTextMessage ("SIF01.H");\r
+\r
+ try {\r
+ String property = (String) AccessController.doPrivileged( new PrivilegedAction()\r
+ {\r
+ public Object run()\r
+ {\r
+ return System.getProperty (whichProperty, unavailable);\r
+ }\r
+ }\r
+ );\r
+ return property;\r
+ }\r
+ catch (SecurityException se) {\r
+\r
+ return Main.getTextMessage ("SIF01.I", se);\r
+ }\r
+\r
+ } // end of getJavaProperty (String whichProperty)\r
+\r
+\r
+\r
+ /**\r
+ for use by the main () method\r
+ */\r
+\r
+ private final static String sep = "------------------------------------------------------";\r
+ private final static String javaSep = Main.getTextMessage ("SIF01.L");\r
+\r
+ private final static String jbmsSep = Main.getTextMessage ("SIF01.M");\r
+\r
+ private final static String licSep = Main.getTextMessage ("SIF01.N");\r
+\r
+ private final static String locSep = Main.getTextMessage ("SIF01.P");\r
+\r
+ private final static String curLoc = Main.getTextMessage ("SIF01.T");\r
+\r
+ /**\r
+ The name of the failure tag in the information file.\r
+ The failure tag's value provides a default value if\r
+ any other properties are missing.\r
+ */\r
+ private final static String failureTag = Main.getTextMessage ("SIF01.J");\r
+\r
+ private static void getClasspathInfo (String args[], java.io.PrintWriter aw) {\r
+\r
+ Main.useMe (args, aw);\r
+ }\r
+\r
+\r
+\r
+\r
+ /**\r
+ Writes out information about the locales with the\r
+ product.\r
+\r
+ @param localAW the AppStreamWriter to which the info is written. If this\r
+ value is null, the info is written to System.out\r
+\r
+ */\r
+ private static void reportLocales (java.io.PrintWriter localAW) {\r
+\r
+ boolean cur_loc = true;\r
+\r
+ localAW.println (locSep);\r
+\r
+ // Read all the possible locales, and test for each one, if it loads.\r
+ // If so, then read the properties, and print them out.\r
+\r
+ Locale[] supportedLocales = Locale.getAvailableLocales();\r
+ String[] stringLocales = new String[supportedLocales.length];\r
+ for (int i = 0; i < supportedLocales.length; i++)\r
+ {\r
+ stringLocales[i] = supportedLocales[i].toString();\r
+ }\r
+ java.util.Arrays.sort(stringLocales);\r
+\r
+ Properties p = new Properties ();\r
+ for (int i = 0; i < stringLocales.length; i++) {\r
+\r
+ String localeResource =\r
+ "/org/apache/derby/info/locale_" + stringLocales[i] + ".properties";\r
+ \r
+ final Properties finalp = p;\r
+ final String finalLocaleResource = localeResource;\r
+ \r
+ try { \r
+ InputStream is = (InputStream) AccessController.doPrivileged\r
+ (new PrivilegedAction() {\r
+ public Object run() {\r
+ InputStream locis =\r
+ finalp.getClass().getResourceAsStream (finalLocaleResource);\r
+ return locis;\r
+ }\r
+ }\r
+ ); \r
+ \r
+ if (is == null) {\r
+// localAW.println("resource is null: " + localeResource);\r
+ }\r
+ else {\r
+\r
+ try {\r
+ p.clear();\r
+ p.load (is);\r
+ //Displaying Current Locale\r
+ if (cur_loc)\r
+ {\r
+ Locale loc = null;\r
+ loc = Locale.getDefault();\r
+ localAW.println(Main.getTextMessage ("SIF01.T") + " [" + loc.getDisplayLanguage() + "/" + loc.getDisplayCountry() + " [" + loc + "]]");\r
+ cur_loc = false;\r
+ }\r
+\r
+ //Beetle 5079: do not print unlocalized locale names to console, only print locale code.\r
+ String localeName = p.getProperty("derby.locale.external.name");\r
+ localeName = localeName.substring(localeName.indexOf("[")+1);\r
+ localeName = localeName.substring(0,localeName.indexOf("]"));\r
+ \r
+ localAW.println (Main.getTextMessage ("SIF01.R",\r
+ localeName));\r
+\r
+\r
+ int major = Integer.valueOf(p.getProperty ("derby.locale.version.major")).intValue();\r
+ int minor = Integer.valueOf(p.getProperty ("derby.locale.version.minor")).intValue();\r
+ int maint = Integer.valueOf(p.getProperty ("derby.locale.version.maint")).intValue();\r
+ String build = p.getProperty ("derby.locale.build.number");\r
+\r
+ String lv = ProductVersionHolder.fullVersionString(major, minor, maint, false, build);\r
+\r
+\r
+ localAW.println (Main.getTextMessage ("SIF01.S", lv));\r
+\r
+\r
+ }\r
+ catch (IOException ioe) {\r
+\r
+ //This case is a bit ugly. If we get an IOException, we return\r
+ //null. Though this correctly reflects that the product is not\r
+ //available for use, it may be confusing to users that we swallow\r
+ //the IO error here.\r
+\r
+ localAW.println("Could not get locale properties from : " + is);\r
+ }\r
+ }\r
+\r
+ }\r
+ catch (Throwable t) {\r
+ localAW.println ("Could not load resource: " + localeResource);\r
+ localAW.println ("Exception: " + t);\r
+ }\r
+\r
+ }\r
+\r
+\r
+ localAW.println (sep);\r
+\r
+ } // end of reportLocales\r
+\r
+ /* for arguments, choose from one of:*/\r
+ private static final String EMBEDDED = "embedded";\r
+\r
+ /* you can add this if you like*/\r
+ private static final String TOOLS = "tools";\r
+\r
+ private static final String NET = "server";\r
+ private static final String CLIENT = "client";\r
+ private static final String DB2DRIVER = "db2driver";\r
+\r
+ /* you can add this if you like */\r
+\r
+ private static final String MAINUSAGESTRING = "java org.apache.derby.tools.sysinfo -cp";\r
+\r
+ private static final String USAGESTRINGPARTA = MAINUSAGESTRING + " [ [ " + EMBEDDED + " ][ " + NET + " ][ " + CLIENT + "] [ " + DB2DRIVER + " ] [ " + TOOLS + " ] [ ";\r
+ private static final String USAGESTRINGPARTB = ".class ] ]";\r
+\r
+ static void useMe(String[] args, java.io.PrintWriter pw) {\r
+ java.io.PrintWriter localPW = pw;\r
+\r
+ if (localPW == null)\r
+ {\r
+ localPW = new java.io.PrintWriter(System.out);\r
+ }\r
+\r
+\r
+ int length = args.length;\r
+ if (length==1) {\r
+\r
+ try {\r
+ tryAllClasspaths(localPW);\r
+\r
+ }\r
+\r
+ catch (Throwable t) {\r
+\r
+ }\r
+ }\r
+ else {\r
+ try {\r
+ trySomeClasspaths(args, localPW);\r
+ }\r
+\r
+ catch (Throwable t) {\r
+\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+\r
+\r
+\r
+\r
+ private static void tryAllClasspaths(java.io.PrintWriter localPW) throws Throwable {\r
+ localPW.println(Main.getTextMessage("SIF08.B"));\r
+ localPW.println(Main.getTextMessage("SIF08.C", MAINUSAGESTRING + " args"));\r
+ StringBuffer successes = new StringBuffer(Main.getTextMessage("SIF08.D")+ crLf());\r
+ StringBuffer failures = new StringBuffer(crLf() + Main.getTextMessage("SIF08.E") + crLf());\r
+ tryCoreClasspath(successes, failures);\r
+ tryNetClasspath(successes, failures);\r
+ tryClientClasspath(successes, failures);\r
+ tryDB2DriverClasspath(successes, failures);\r
+ tryUtilsClasspath(successes, failures);\r
+ localPW.println(successes.toString());\r
+ if (!failures.toString().equals(crLf() + Main.getTextMessage("SIF08.E") + crLf())) {\r
+ localPW.println(failures.toString());\r
+ }\r
+ else {\r
+\r
+ localPW.println(Main.getTextMessage("SIF08.F"));\r
+ }\r
+ localPW.flush();\r
+ }\r
+\r
+ private static void trySomeClasspaths(String[] args, java.io.PrintWriter localPW) throws Throwable {\r
+\r
+ boolean seenArg = false;\r
+ StringBuffer successes = new StringBuffer(Main.getTextMessage("SIF08.D")+ crLf());\r
+ StringBuffer failures = new StringBuffer(crLf() + Main.getTextMessage("SIF08.E") + crLf());\r
+\r
+ if (argumentsContain(args, EMBEDDED))\r
+ {\r
+\r
+ tryCoreClasspath(successes, failures);\r
+ seenArg =true;\r
+\r
+ }\r
+ if (argumentsContain(args,NET)) {\r
+ tryNetClasspath(successes, failures);\r
+ seenArg =true;\r
+\r
+ }\r
+ if (argumentsContain(args,CLIENT)) {\r
+ tryClientClasspath(successes, failures);\r
+ seenArg =true;\r
+\r
+ }\r
+ if (argumentsContain(args,DB2DRIVER)) {\r
+ tryDB2DriverClasspath(successes, failures);\r
+ seenArg =true;\r
+ }\r
+\r
+ if (argumentsContain(args,TOOLS) || argumentsContain(args,"utils")) {\r
+ tryUtilsClasspath(successes, failures);\r
+ seenArg =true;\r
+\r
+ }\r
+\r
+\r
+ String userclass = argumentMatches(args, ".class");\r
+ if (!userclass.equals("")) {\r
+ tryMyClasspath(argumentMatches(args, ".class"), Main.getTextMessage("SIF08.H", userclass), successes, failures);\r
+ seenArg =true;\r
+ }\r
+\r
+ if (seenArg)\r
+ {\r
+\r
+ localPW.println(successes.toString());\r
+ if (!failures.toString().equals(crLf() + Main.getTextMessage("SIF08.E") + crLf())) {\r
+ localPW.println(failures.toString());\r
+ }\r
+ else {\r
+\r
+ localPW.println(Main.getTextMessage("SIF08.F"));\r
+ }\r
+ }\r
+ else\r
+ {\r
+ localPW.println(Main.getTextMessage("SIF08.A", USAGESTRINGPARTA, USAGESTRINGPARTB));\r
+ }\r
+ localPW.flush();\r
+\r
+ }\r
+\r
+ private static void tryCoreClasspath(StringBuffer successes, StringBuffer failures) {\r
+ tryMyClasspath("org.apache.derby.database.Database", Main.getTextMessage("SIF08.J","derby.jar" ), successes, failures);\r
+ }\r
+ private static void tryNetClasspath(StringBuffer successes, StringBuffer failures) {\r
+ tryMyClasspath("org.apache.derby.database.Database", Main.getTextMessage("SIF08.J","derby.jar" ), successes, failures);\r
+ tryMyClasspath("org.apache.derby.drda.NetworkServerControl", Main.getTextMessage("SIF08.I", "derbynet.jar"), successes, failures);\r
+ }\r
+ private static void tryClientClasspath(StringBuffer successes, StringBuffer failures) {\r
+ tryMyClasspath("org.apache.derby.jdbc.ClientDriver", Main.getTextMessage("SIF08.L", "derbyclient.jar"), successes, failures);\r
+ }\r
+ private static void tryDB2DriverClasspath(StringBuffer successes,\r
+ StringBuffer failures)\r
+ {\r
+ tryMyClasspath("com.ibm.db2.jcc.DB2Driver",\r
+ Main.getTextMessage("SIF08.L", "db2jcc.jar"),\r
+ successes, failures);\r
+ }\r
+\r
+ private static void tryUtilsClasspath(StringBuffer successes, StringBuffer failures) {\r
+ tryMyClasspath("org.apache.derby.tools.ij", Main.getTextMessage("SIF08.Q", "derbytools.jar"), successes, failures);\r
+ }\r
+\r
+ private static void tryMyClasspath(String cn, String library, StringBuffer successes, StringBuffer failures) {\r
+\r
+ try {\r
+ Class c = Class.forName(cn);\r
+ //Added by Jeff Huang\r
+ //TODO: FIXIT\r
+ String loc = getFileWhichLoadedClass(c);\r
+ successes.append(found(cn, library, loc));\r
+ \r
+ }\r
+\r
+ catch (Throwable t) {\r
+\r
+ failures.append(notFound(cn, library));\r
+\r
+ }\r
+\r
+\r
+ }\r
+\r
+ private static void tryAsResource(String cn, String library, StringBuffer successes, StringBuffer failures) {\r
+\r
+ try {\r
+ java.io.InputStream in = cn.getClass().getResourceAsStream(cn);\r
+ in.close();\r
+ String loc = getFileWhichLoadedClass(cn.getClass());\r
+ successes.append(found(cn, library, loc));\r
+ }\r
+\r
+ catch (Throwable t) {\r
+ failures.append(notFound(cn, library));\r
+\r
+ }\r
+\r
+ }\r
+\r
+ private static String found(String cn, String library, String loc) {\r
+ StringBuffer temp = new StringBuffer(crLf());\r
+ temp.append(" " + library);\r
+ temp.append(crLf());\r
+ if (loc != null)\r
+ temp.append(" ").append(loc).append(crLf());\r
+ temp.append(crLf());\r
+ return temp.toString();\r
+ }\r
+ private static String notFound(String cn, String library) {\r
+\r
+ StringBuffer temp = new StringBuffer(crLf());\r
+ temp.append(" " + library);\r
+ temp.append(crLf());\r
+ temp.append(" " + Main.getTextMessage("SIF08.U", cn));\r
+ temp.append(crLf());\r
+ temp.append(crLf());\r
+ return temp.toString();\r
+ }\r
+\r
+ private static String crLf() {\r
+ return System.getProperty("line.separator");\r
+ }\r
+\r
+ private static String lookForMainArg(String[] args, java.io.PrintWriter localPW)\r
+ {\r
+ int length=args.length;\r
+ String[] legalargs = new String[1];\r
+ legalargs[0] = EMBEDDED;\r
+\r
+ int argsfound = 0;\r
+ String whichargument="";\r
+\r
+ for (int i = 0; i < length; i++) {\r
+\r
+ for (int j=0; j < legalargs.length; j++) {\r
+ if (args[i].toUpperCase(java.util.Locale.ENGLISH).equals(legalargs[j].toUpperCase(java.util.Locale.ENGLISH))) {\r
+ argsfound++;\r
+ whichargument=legalargs[j];\r
+ }\r
+ }\r
+ }\r
+ if (argsfound > 1 || argsfound < 1) {\r
+ localPW.println(Main.getTextMessage("SIF08.A", USAGESTRINGPARTA, USAGESTRINGPARTB));\r
+ return "";\r
+ }\r
+ return whichargument;\r
+ }\r
+\r
+ private static boolean argumentsContain(String[] args, String s) {\r
+ for (int i = 0; i < args.length; i++) {\r
+ if (args[i].equalsIgnoreCase(s))\r
+ return true;\r
+ }\r
+ return false;\r
+\r
+ }\r
+\r
+ private static String argumentMatches(String[] args, String ss) {\r
+ String userclass = "";\r
+ int length = args.length;\r
+ for (int i = 0; i < length; i++) {\r
+ if (args[i].endsWith(ss)) {\r
+ userclass = args[i].substring(0,args[i].length()-6) ;\r
+\r
+ }\r
+\r
+ }\r
+ return userclass;\r
+ }\r
+\r
+ /*\r
+ ** Code related to loading info fromjar files.\r
+ */\r
+\r
+ private static final String infoNames[] = {\r
+\r
+ "org/apache/derby/info/" +\r
+ org.apache.derby.iapi.services.info.ProductGenusNames.DBMS +\r
+ ".properties",\r
+\r
+\r
+ "org/apache/derby/info/" +\r
+ org.apache.derby.iapi.services.info.ProductGenusNames.TOOLS +\r
+ ".properties",\r
+\r
+ "org/apache/derby/info/" +\r
+ org.apache.derby.iapi.services.info.ProductGenusNames.NET +\r
+ ".properties",\r
+\r
+ "org/apache/derby/info/" +\r
+ org.apache.derby.iapi.services.info.ProductGenusNames.DNC +\r
+ ".properties"\r
+ };\r
+\r
+ /**\r
+ * Get all the info we can obtain from the local execution context\r
+ * as to the availability of the Derby classes by attempting to load\r
+ * the info files with loadZipFromResource() and checking classpath\r
+ * locations with checkForInfo if the classpath is accessible.\r
+ *\r
+ * @param classpath the classpath, or null if not accessible\r
+ * @return an array of ZipInfoProperties with the locations of the located\r
+ * resources\r
+ * @see #loadZipFromResource()\r
+ * @see #checkForInfo(String)\r
+ */\r
+ public static ZipInfoProperties[] getAllInfo(String classpath)\r
+ {\r
+ ZipInfoProperties zips[] = loadZipFromResource();\r
+\r
+ // No info properties files found, but here we are in sysinfo.\r
+ // Avoid an NPE in mergeZips by creating a ZipInfoProperties array\r
+ // with the location of the sysinfo that is currently executing.\r
+ if (zips == null)\r
+ {\r
+ zips = new ZipInfoProperties[1];\r
+ ZipInfoProperties zip = new ZipInfoProperties(ProductVersionHolder.getProductVersionHolderFromMyEnv(org.apache.derby.tools.sysinfo.TOOLS));\r
+ zip.setLocation(getFileWhichLoadedClass(new Main().getClass()));\r
+ zips[0] = zip;\r
+ }\r
+\r
+ try\r
+ {\r
+ if (classpath != null) {\r
+ String cp [] = parseClasspath(classpath);\r
+ Vector v = new Vector();\r
+ for (int i = 0; i < cp.length; i++)\r
+ {\r
+ ZipInfoProperties zip = null;\r
+ try {\r
+ zip = checkForInfo(cp[i]);\r
+ }\r
+ catch (SecurityException se)\r
+ {\r
+ zip = new ZipInfoProperties(null);\r
+ zip.setLocation(\r
+ Main.getTextMessage ("SIF03.C", se.getMessage()));\r
+ }\r
+ if (zip != null)\r
+ {\r
+ v.addElement(zip);\r
+ }\r
+ }\r
+ if (v.size() > 0)\r
+ {\r
+ ZipInfoProperties cpzips[] = new ZipInfoProperties[v.size()];\r
+ v.copyInto(cpzips);\r
+ return mergeZips(zips, cpzips);\r
+ }\r
+ }\r
+ return mergeZips(zips, null);\r
+\r
+ }\r
+ catch (SecurityException se)\r
+ {\r
+ ZipInfoProperties zip[] = new ZipInfoProperties[1];\r
+ zip[0] = new ZipInfoProperties(null);\r
+ zip[0].setLocation(\r
+ Main.getTextMessage ("SIF03.C", se.getMessage()));\r
+ return zip;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Attempt to load the info properties files specified in infoNames[i]\r
+ * using getResourceAsStream(). If none are able to be loaded, return\r
+ * a null array.\r
+ *\r
+ * @return An array of ZipInfoProperties with the locations from which\r
+ * the info properties files were loaded.\r
+ * @see #infoNames\r
+ */\r
+ private static ZipInfoProperties [] loadZipFromResource()\r
+ {\r
+ java.util.ArrayList al = new java.util.ArrayList();\r
+\r
+ for (int i = 0; i < infoNames.length; i++)\r
+ {\r
+ final String resource = "/".concat(infoNames[i]);\r
+\r
+ InputStream is = (InputStream) AccessController.doPrivileged\r
+ (new PrivilegedAction() {\r
+ public Object run() {\r
+ InputStream locis =\r
+ new Main().getClass().getResourceAsStream(resource);\r
+ return locis;\r
+ }\r
+ }\r
+ ); \r
+\r
+ if (is == null)\r
+ continue;\r
+\r
+ ZipInfoProperties ze = new ZipInfoProperties(ProductVersionHolder.getProductVersionHolderFromMyEnv(is));\r
+ \r
+ // get the real location of the info file\r
+ URL locUrl = (URL) AccessController.doPrivileged\r
+ (new PrivilegedAction() {\r
+ public Object run() {\r
+ URL realUrl = new Main().getClass().getResource(resource);\r
+ return realUrl;\r
+ }\r
+ });\r
+\r
+ ze.setLocation(formatURL(locUrl));\r
+\r
+ al.add(ze);\r
+ }\r
+\r
+ if (al.size() == 0)\r
+ {\r
+ return null;\r
+ }\r
+\r
+ ZipInfoProperties[] zip = new ZipInfoProperties[al.size()];\r
+\r
+ al.toArray(zip);\r
+\r
+ return zip;\r
+ }\r
+\r
+ /**\r
+ * Split the classpath into separate elements.\r
+ *\r
+ * @param cp the classpath, if accessible.\r
+ * @return a String array with the individual classpath elements.\r
+ */\r
+ private static String [] parseClasspath(String cp)\r
+ {\r
+ StringTokenizer st = new StringTokenizer(cp, File.pathSeparator);\r
+ int count = st.countTokens();\r
+ if (count == 0)\r
+ {\r
+ return null;\r
+ }\r
+\r
+ String vals[] = new String[count];\r
+ for (int i =0; i < count; i++)\r
+ {\r
+ vals[i] = st.nextToken();\r
+ }\r
+ return vals;\r
+ }\r
+\r
+ /**\r
+ * Given an individual element of the element of the classpath, call\r
+ * checkDirectory() if the element is a directory or checkFile()\r
+ * if the element is a file.\r
+ *\r
+ * @param cpEntry the classpath element\r
+ * @return a ZipInfoProperties if an info properties file is found.\r
+ */\r
+ private static ZipInfoProperties checkForInfo(final String cpEntry)\r
+ {\r
+ return (ZipInfoProperties) AccessController.doPrivileged( new PrivilegedAction()\r
+ {\r
+ public Object run()\r
+ {\r
+ File f = new File(cpEntry);\r
+ if ( ! f.exists())\r
+ {\r
+ return null;\r
+ }\r
+\r
+ if (f.isDirectory())\r
+ {\r
+ ZipInfoProperties zip = checkDirectory(cpEntry);\r
+ return zip;\r
+ }\r
+\r
+ if (f.isFile())\r
+ {\r
+ ZipInfoProperties zip = checkFile(cpEntry);\r
+ return zip;\r
+ }\r
+ return null;\r
+ }\r
+ }\r
+ );\r
+ \r
+ }\r
+\r
+ /**\r
+ * Check a given directory for the presence of an info properties file in\r
+ * org/apache/derby/info inside the directory.\r
+ *\r
+ * @param dirname the directory to check as a String\r
+ * @return a ZipInfoProperties if a file is found, otherwise null.\r
+ */\r
+ private static ZipInfoProperties checkDirectory(String dirname)\r
+ {\r
+ boolean foundOne = false;\r
+ File f = null;\r
+ for (int i = 0; i < infoNames.length; i++)\r
+ {\r
+ String localSysinfo = infoNames[i].replace('/', File.separatorChar);\r
+ f = new File(dirname, localSysinfo);\r
+ if (f.exists())\r
+ {\r
+ foundOne = true;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (!foundOne || (f == null))\r
+ {\r
+ return null;\r
+ }\r
+\r
+ try\r
+ {\r
+ InputStream bis = new FileInputStream(f);\r
+\r
+ ZipInfoProperties zip = new ZipInfoProperties(ProductVersionHolder.getProductVersionHolderFromMyEnv(bis));\r
+ zip.setLocation(new File(dirname).getCanonicalPath().replace('/', File.separatorChar));\r
+ return zip;\r
+ }\r
+ catch (IOException ioe)\r
+ {\r
+ return null;\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Check inside a jar file for the presence of a Derby info properties\r
+ * file. There is a special case for db2jcc, which does not have a Derby\r
+ * info propeties file. If db2jcc is in the filename, acquire DB2Driver\r
+ * via reflection and get the version number from it.\r
+ *\r
+ * @param filename the jar file to check\r
+ * @return ZipInfoProperties with the jar file set as the location\r
+ * or null if not found.\r
+ */\r
+ private static ZipInfoProperties checkFile(String filename)\r
+ {\r
+ // try to create a ZipFile from it\r
+\r
+ // Check to see if it's a version of db2jcc.jar and if so, report the version number. \r
+ if (filename.indexOf("db2jcc") >= 0)\r
+ {\r
+ Class c = null;\r
+ Method m = null;\r
+ Object o = null;\r
+ Integer build = null;\r
+ Integer major = null;\r
+ Integer minor = null;\r
+ try \r
+ {\r
+ try \r
+ {\r
+ c = Class.forName("com.ibm.db2.jcc.DB2Driver");\r
+ m = c.getMethod("getJCCBuildNumber", null);\r
+ o = c.newInstance();\r
+ //Added by Jeff Huang\r
+// (new com.ibm.db2.jcc.DB2Driver()).getJCCBuildNumber();\r
+ \r
+ build = (Integer)m.invoke(o,null);\r
+ } catch (ClassNotFoundException cnfe) {\r
+ c = Class.forName("com.ibm.db2.jcc.DB2Version");\r
+ m = c.getMethod("getBuildNumber", null);\r
+ o = c.newInstance();\r
+ //Added by Jeff Huang\r
+// (new com.ibm.db2.jcc.DB2Driver()).getBuildNumber();\r
+ build = (Integer)m.invoke(o,null);\r
+ } \r
+ m = c.getMethod("getMajorVersion", null);\r
+ major = (Integer)m.invoke(o,null);\r
+ m = c.getMethod("getMinorVersion", null);\r
+ minor = (Integer)m.invoke(o,null);\r
+\r
+ ProductVersionHolder jccVersion = ProductVersionHolder.getProductVersionHolder(\r
+ "IBM Corp.",\r
+ "DB2 Java Common Client",\r
+ "DRDA:jcc",\r
+ major.intValue(),\r
+ minor.intValue(),\r
+ 0,\r
+ 0,\r
+ build.toString(),\r
+ Boolean.FALSE);\r
+\r
+ ZipInfoProperties zip = new ZipInfoProperties(jccVersion);\r
+\r
+ String loc = getFileWhichLoadedClass(c);\r
+ // For db2jcc.jar, report the actual file from which DB2Driver\r
+ // was loaded, if we can determine it. For db2jcc_license_c,\r
+ // report the filename from the classpath, and the version \r
+ // info from the DB2Driver that we loaded. This is slightly\r
+ // misleading, since db2jcc_license_c.jar doesn't really have\r
+ // a "version", but the two jars are usually linked.\r
+ if (loc != null && filename.indexOf("license_c") < 0)\r
+ zip.setLocation(loc);\r
+ else\r
+ zip.setLocation(new File(filename).getCanonicalPath().replace('/', File.separatorChar));\r
+ return zip;\r
+ } catch (Exception e) { return null; }\r
+ }\r
+\r
+ try\r
+ {\r
+ ZipFile zf = new ZipFile(filename);\r
+ // try to get a ZipEntry from the ZipFile\r
+\r
+ ZipEntry thisEntry = null;\r
+\r
+ for (int i =0; i < infoNames.length; i++)\r
+ {\r
+ thisEntry = zf.getEntry(infoNames[i]);\r
+ if (thisEntry != null)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (thisEntry == null)\r
+ {\r
+ return null;\r
+ }\r
+\r
+ InputStream bis = zf.getInputStream(thisEntry);\r
+ if (bis == null)\r
+ {\r
+ return null;\r
+ }\r
+\r
+ ZipInfoProperties zip = new ZipInfoProperties(ProductVersionHolder.getProductVersionHolderFromMyEnv(bis));\r
+ zip.setLocation(new File(filename).getCanonicalPath().replace('/', File.separatorChar));\r
+ return zip;\r
+\r
+ }\r
+ catch (IOException ioe)\r
+ {\r
+ //guess not\r
+ return null;\r
+ }\r
+\r
+ }\r
+\r
+ /*\r
+ ** Message handling\r
+ */\r
+\r
+ public static String getTextMessage(String msgId) {\r
+ return getCompleteMessage(msgId, new Object[0]);\r
+ }\r
+ public static String getTextMessage(String msgId, Object a1) {\r
+\r
+ return getCompleteMessage(msgId, new Object[] {a1});\r
+ }\r
+ public static String getTextMessage(String msgId, Object a1, Object a2) {\r
+ return getCompleteMessage(msgId, new Object[] {a1, a2});\r
+ }\r
+ public static String getTextMessage(String msgId, Object a1, Object a2, Object a3) {\r
+ return getCompleteMessage(msgId, new Object[] {a1, a2, a3});\r
+ }\r
+ public static String getTextMessage(String msgId, Object a1, Object a2, Object a3, Object a4) {\r
+ return getCompleteMessage(msgId, new Object[] {a1, a2, a3, a4});\r
+ }\r
+\r
+ /**\r
+ */\r
+ public static String getCompleteMessage(String msgId, Object[] arguments) {\r
+ return LOCALIZED_RESOURCE.getTextMessage(msgId, arguments);\r
+ }\r
+\r
+ /**\r
+ * Given a loaded class, this\r
+ * routine asks the class's class loader for information about where the\r
+ * class was loaded from. Typically, this is a file, which might be\r
+ * either a class file or a jar file. The routine figures that out, and\r
+ * returns the name of the file. If it can't figure it out, it returns null\r
+ */\r
+ private static String getFileWhichLoadedClass(final Class cls)\r
+ {\r
+ return (String)AccessController.doPrivileged( new PrivilegedAction()\r
+ {\r
+ public Object run()\r
+ {\r
+ CodeSource cs = null;\r
+ try {\r
+ cs = cls.getProtectionDomain().getCodeSource ();\r
+ }\r
+ catch (SecurityException se) {\r
+ return Main.getTextMessage("SIF01.V", cls, se.getMessage());\r
+ }\r
+ \r
+ if ( cs == null )\r
+ return null; \r
+ \r
+ URL result = cs.getLocation ();\r
+ \r
+ return formatURL(result);\r
+ }\r
+ });\r
+ }\r
+\r
+ /**\r
+ * <P>\r
+ * Merge and flatten two arrays of ZipInfoProperties, removing any \r
+ * duplicates. There may be duplicates in the arrays because\r
+ * loadZipFromResource may find all the properties files in the same\r
+ * location, such as when loading from compiled source instead of\r
+ * packaged jars. Also, a poorly constructed classpath may contain\r
+ * duplicate entries that each contain the Derby classes, and we\r
+ * need only report the first of each such instances found.\r
+ * <P>\r
+ * The second array may be null if the classpath was empty, in which\r
+ * case we still remove the duplicates from the first array and return \r
+ * the shortened array.\r
+ *\r
+ * @param zip1 the first array from loadZipWithResource\r
+ * @param zip2 the second array from analyzing the classpath\r
+ * @return the merged array\r
+ */\r
+ private static ZipInfoProperties[] mergeZips(ZipInfoProperties[] zip1,\r
+ ZipInfoProperties[] zip2)\r
+ {\r
+ Vector v = new Vector();\r
+ boolean foundDup = false;\r
+ \r
+ // remove duplicates from first array\r
+ for (int i = 0; i < zip1.length; i++)\r
+ {\r
+ if (zip1[i] != null && zip1.length > 1)\r
+ {\r
+ for (int j = i + 1; j < zip1.length; j++)\r
+ {\r
+ if (zip1[i].getLocation().equals(zip1[j].getLocation()))\r
+ zip1[j] = null;\r
+ }\r
+ }\r
+ if (zip1[i] != null)\r
+ v.addElement(zip1[i]);\r
+ }\r
+ \r
+ // if provided a second array, remove any locations in second array\r
+ // still in first array.\r
+ if (zip2 != null)\r
+ {\r
+ for (int j = 0; j < zip2.length; j++)\r
+ {\r
+ for (int k = 0; k < v.size(); k++)\r
+ {\r
+ ZipInfoProperties z = (ZipInfoProperties)v.get(k);\r
+ if (zip2[j].getLocation().equals(z.getLocation()))\r
+ foundDup = true;\r
+ }\r
+ if (!foundDup)\r
+ {\r
+ v.addElement(zip2[j]);\r
+ }\r
+ foundDup = false;\r
+ }\r
+ }\r
+ \r
+ ZipInfoProperties[] merged = new ZipInfoProperties[v.size()];\r
+ v.copyInto(merged);\r
+ return merged;\r
+ }\r
+\r
+ /**\r
+ * Strip a given URL down to the filename. The URL will be a jarfile or\r
+ * directory containing a Derby info properties file. Return the canonical\r
+ * path for the filename, with the path separators normalized.\r
+ */\r
+ private static String formatURL(URL loc)\r
+ {\r
+ String filename = URLDecoder.decode(loc.toString());\r
+\r
+ if (filename.startsWith("jar:")) { filename = filename.substring(4); }\r
+ if (filename.startsWith("file:")) { filename = filename.substring(5); }\r
+ if (filename.indexOf("!") > -1) { filename = filename.substring(0, filename.indexOf("!")); }\r
+ if (filename.indexOf("/org/apache/derby") > -1) { \r
+ filename = filename.substring(0, filename.indexOf("/org/apache/derby")); \r
+ }\r
+ if (filename.charAt(0) == '/' && \r
+ Character.isLetter(filename.charAt(1)) &&\r
+ filename.charAt(2) == ':' &&\r
+ filename.charAt(2) == '/') { filename = filename.substring(1); }\r
+\r
+ String result = ""; \r
+ try {\r
+ result = new File(filename).getCanonicalPath().replace('/', File.separatorChar);\r
+ } catch (IOException e) {\r
+ result = "IOException";\r
+ }\r
+ return result;\r
+ }\r
+\r
+} // end of class Main\r
+\r