/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: Util.java,v $ * * $Revision: 1.2 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ package com.sun.star.servicetag; import java.io.*; import java.util.Date; import java.text.SimpleDateFormat; import java.text.ParseException; import java.util.TimeZone; import java.util.UUID; import java.lang.reflect.Field; import java.lang.reflect.Method; // Utility class for com.sun.star.servicetag package class Util { private static boolean verbose = (System.getProperty("servicetag.verbose") != null); private static String jrepath = null; // for debugging and tracing static boolean isVerbose() { return verbose; } /** * Gets the pathname of JRE in the running platform * This can be a JDK or JRE. */ static synchronized String getJrePath() { if (jrepath == null) { // Determine the JRE path by checking the existence of // /jre/lib and /lib. String javaHome = System.getProperty("java.home"); jrepath = javaHome + File.separator + "jre"; File f = new File(jrepath, "lib"); if (!f.exists()) { // java.home usually points to the JRE path jrepath = javaHome; } } return jrepath; } /** * Tests if the running platform is a JDK. */ static boolean isJdk() { // /jre exists which implies it's a JDK return getJrePath().endsWith(File.separator + "jre"); } /** * Generates the URN string of "urn:st" namespace */ static String generateURN() { return "urn:st:" + UUID.randomUUID().toString(); } static int getIntValue(String value) { try { return Integer.parseInt(value); } catch (NumberFormatException e) { throw new IllegalArgumentException("\"" + value + "\"" + " expected to be an integer"); } } /** * Formats the Date into a timestamp string in YYYY-MM-dd HH:mm:ss GMT. * @param timestamp Date * @return a string representation of the timestamp * in the YYYY-MM-dd HH:mm:ss GMT format. */ static String formatTimestamp(Date timestamp) { if (timestamp == null) { return "[No timestamp]"; } SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); df.setTimeZone(TimeZone.getTimeZone("GMT")); return df.format(timestamp); } /** * Parses a timestamp string in YYYY-MM-dd HH:mm:ss GMT format. * @param timestamp Timestamp in the YYYY-MM-dd HH:mm:ss GMT format. * @return Date */ static Date parseTimestamp(String timestamp) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); df.setTimeZone(TimeZone.getTimeZone("GMT")); try { return df.parse(timestamp); } catch (ParseException e) { // should not reach here e.printStackTrace(); return new Date(); } } static String commandOutput(Process p) throws IOException { Reader r = null; Reader err = null; try { r = new InputStreamReader(p.getInputStream()); err = new InputStreamReader(p.getErrorStream()); String output = commandOutput(r); String errorMsg = commandOutput(err); p.waitFor(); return output + errorMsg.trim(); } catch (InterruptedException e) { if (isVerbose()) { e.printStackTrace(); } return e.getMessage(); } finally { if (r != null) { r.close(); } if (err != null) { err.close(); } } } static String commandOutput(Reader r) throws IOException { StringBuilder sb = new StringBuilder(); int c; while ((c = r.read()) > 0) { if (c != '\r') { sb.append((char) c); } } return sb.toString(); } static int getJdkVersion() { parseVersion(); return jdkVersion; } static int getUpdateVersion() { parseVersion(); return jdkUpdate; } private static int jdkVersion = 0; private static int jdkUpdate = 0; private static synchronized void parseVersion() { if (jdkVersion > 0) { return; } // parse java.runtime.version // valid format of the version string is: // n.n.n[_uu[c]][-]-bxx String cs = System.getProperty("java.runtime.version"); if (cs.length() >= 5 && Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' && Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' && Character.isDigit(cs.charAt(4))) { jdkVersion = Character.digit(cs.charAt(2), 10); cs = cs.substring(5, cs.length()); if (cs.charAt(0) == '_' && cs.length() >= 3 && Character.isDigit(cs.charAt(1)) && Character.isDigit(cs.charAt(2))) { int nextChar = 3; try { String uu = cs.substring(1, 3); jdkUpdate = Integer.valueOf(uu).intValue(); } catch (NumberFormatException e) { // not conforming to the naming convention return; } } } else { throw new InternalError("Invalid java.runtime.version" + cs); } } /** * Returns this java string as a null-terminated byte array */ private static byte[] stringToByteArray(String str) { return (str + "\u0000").getBytes(); } /** * Converts a null-terminated byte array to java string */ private static String byteArrayToString(byte[] array) { return new String(array, 0, array.length -1); } /** * Gets the stclient path using a well known location from * the Windows platform Registry, otherwise it will return null. */ static File getWindowsStClientFile() { File out = null; String regKey = "software\\microsoft\\windows\\currentversion\\app paths\\stclient.exe"; String keyName = "" ; // use the default key String path = getRegistryKey(regKey, keyName); if (path != null && (new File(path)).exists()) { out = new File(path); } if (isVerbose()) { System.out.println("stclient=" + out); } return out; } /** * This uses reflection to access a private java windows registry * interface, any changes to that Class must be appropriately adjusted. * Returns a null if unsuccessful. */ private static String getRegistryKey(String regKey, String keyName) { String out = null; try { Class clazz = Class.forName("java.util.prefs.WindowsPreferences"); // Get the registry methods Method winRegOpenKeyM = clazz.getDeclaredMethod("WindowsRegOpenKey", int.class, byte[].class, int.class); winRegOpenKeyM.setAccessible(true); Method winRegCloseKeyM = clazz.getDeclaredMethod("WindowsRegCloseKey", int.class); winRegCloseKeyM.setAccessible(true); Method winRegQueryValueM = clazz.getDeclaredMethod("WindowsRegQueryValueEx", int.class, byte[].class); winRegQueryValueM.setAccessible(true); // Get all the constants we need int HKLM = getValueFromStaticField("HKEY_LOCAL_MACHINE", clazz); int KEY_READ = getValueFromStaticField("KEY_READ", clazz); int ERROR_CODE = getValueFromStaticField("ERROR_CODE", clazz); int NATIVE_HANDLE = getValueFromStaticField("NATIVE_HANDLE", clazz); int ERROR_SUCCESS = getValueFromStaticField("ERROR_SUCCESS", clazz); // Convert keys byte[] reg = stringToByteArray(regKey); byte[] key = stringToByteArray(keyName); // Open the registry int[] result = (int[]) winRegOpenKeyM.invoke(null, HKLM, reg, KEY_READ); if (result[ERROR_CODE] == ERROR_SUCCESS) { byte[] stvalue = (byte[]) winRegQueryValueM.invoke(null, result[NATIVE_HANDLE], key); out = byteArrayToString(stvalue); winRegCloseKeyM.invoke(null, result[NATIVE_HANDLE]); } } catch (Exception ex) { if (isVerbose()) { ex.printStackTrace(); } } return out; } private static int getValueFromStaticField(String fldName, Class klass) throws Exception { Field f = klass.getDeclaredField(fldName); f.setAccessible(true); return f.getInt(null); } }