From 17f1988c7649d4239ba675040bf7dc145f3e5423 Mon Sep 17 00:00:00 2001 From: Ivo Hinkelmann Date: Wed, 16 Sep 2009 11:45:54 +0000 Subject: CWS-TOOLING: integrate CWS l10nframework01 --- desktop/prj/build.lst | 6 +- desktop/prj/d.lst | 9 + .../registry/data/org/openoffice/Office/Jobs.xcu | 78 ++ .../data/org/openoffice/Office/makefile.mk | 81 ++ .../source/deployment/registry/help/dp_help.cxx | 2 +- .../com/sun/star/registration/Registration.java | 342 ++++++++ .../com/sun/star/registration/makefile.mk | 59 ++ .../com/sun/star/registration/manifest | 2 + .../com/sun/star/servicetag/BrowserSupport.java | 205 +++++ .../com/sun/star/servicetag/Installer.java | 947 +++++++++++++++++++++ .../star/servicetag/LinuxSystemEnvironment.java | 194 +++++ .../com/sun/star/servicetag/RegistrationData.java | 473 ++++++++++ .../sun/star/servicetag/RegistrationDocument.java | 374 ++++++++ .../com/sun/star/servicetag/Registry.java | 558 ++++++++++++ .../com/sun/star/servicetag/ServiceTag.java | 640 ++++++++++++++ .../com/sun/star/servicetag/SolarisServiceTag.java | 68 ++ .../star/servicetag/SolarisSystemEnvironment.java | 159 ++++ .../com/sun/star/servicetag/SunConnection.java | 296 +++++++ .../sun/star/servicetag/SysnetRegistryHelper.java | 380 +++++++++ .../com/sun/star/servicetag/SystemEnvironment.java | 341 ++++++++ .../servicetag/UnauthorizedAccessException.java | 59 ++ .../registration/com/sun/star/servicetag/Util.java | 297 +++++++ .../star/servicetag/WindowsSystemEnvironment.java | 145 ++++ .../com/sun/star/servicetag/makefile.mk | 83 ++ .../servicetag/resources/product_registration.xsd | 301 +++++++ desktop/util/makefile.mk | 7 + 26 files changed, 6104 insertions(+), 2 deletions(-) create mode 100644 desktop/registry/data/org/openoffice/Office/Jobs.xcu create mode 100644 desktop/registry/data/org/openoffice/Office/makefile.mk create mode 100644 desktop/source/registration/com/sun/star/registration/Registration.java create mode 100644 desktop/source/registration/com/sun/star/registration/makefile.mk create mode 100644 desktop/source/registration/com/sun/star/registration/manifest create mode 100644 desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/Installer.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/RegistrationData.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/Registry.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/ServiceTag.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/SunConnection.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/Util.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java create mode 100644 desktop/source/registration/com/sun/star/servicetag/makefile.mk create mode 100644 desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd (limited to 'desktop') diff --git a/desktop/prj/build.lst b/desktop/prj/build.lst index 3aa56e273ff3..ce2ed07f57e4 100644 --- a/desktop/prj/build.lst +++ b/desktop/prj/build.lst @@ -1,4 +1,4 @@ -dt desktop : l10n sfx2 stoc uui BERKELEYDB:berkeleydb sysui SO:sysui_so BOOST:boost svx xmlhelp NULL +dt desktop : l10n sfx2 stoc uui BERKELEYDB:berkeleydb sysui SO:sysui_so BOOST:boost svx xmlhelp sal unoil officecfg NULL dt desktop usr1 - all dt_mkout NULL dt desktop\inc nmake - all dt_inc NULL dt desktop\prj get - all dt_prj NULL @@ -38,3 +38,7 @@ dt desktop\source\deployment\registry\executable nmake - all dt_dp_registry_exe dt desktop\scripts nmake - u dt_scripts dt_inc NULL dt desktop\util nmake - all dt_util dt_app dt_so_comp dt_spl dt_wrapper.w dt_officeloader.w dt_officeloader_unx.u dt_migr dt_rebase.w NULL dt desktop\zipintro nmake - all dt_zipintro NULL +dt desktop\registry\data\org\openoffice\Office nmake - all sn_regconfig NULL +dt desktop\source\registration\com\sun\star\servicetag\resources get - all sn_svctagres NULL +dt desktop\source\registration\com\sun\star\servicetag nmake - all sn_svctag NULL +dt desktop\source\registration\com\sun\star\registration nmake - all sn_regjob sn_svctag NULL diff --git a/desktop/prj/d.lst b/desktop/prj/d.lst index eb0d93886e8a..fe688e2c4b44 100644 --- a/desktop/prj/d.lst +++ b/desktop/prj/d.lst @@ -134,3 +134,12 @@ mkdir: %COMMON_DEST%\pck%_EXT%\broffice_nologo ..\scripts\basis-link %_DEST%\bin%_EXT%\c08\basis-link ..\scripts\so-basis-link %_DEST%\bin%_EXT%\so\basis-link ..\scripts\odf-basis-link %_DEST%\bin%_EXT%\odf4ms\basis-link + +mkdir: %_DEST%\xml%_EXT%\registry\spool +mkdir: %_DEST%\xml%_EXT%\registry\spool\org +mkdir: %_DEST%\xml%_EXT%\registry\spool\org\openoffice +mkdir: %_DEST%\xml%_EXT%\registry\spool\org\openoffice\Office +mkdir: %_DEST%\xml%_EXT%\registry\spool\org\openoffice\Office\Jobs + +..\%__SRC%\class\*.jar %_DEST%\bin%_EXT%\*.jar +..\%__SRC%\misc\registry\spool\org\openoffice\Office\Jobs\*.xcu %_DEST%\xml%_EXT%\registry\spool\org\openoffice\Office\Jobs diff --git a/desktop/registry/data/org/openoffice/Office/Jobs.xcu b/desktop/registry/data/org/openoffice/Office/Jobs.xcu new file mode 100644 index 000000000000..628e3dcdf70a --- /dev/null +++ b/desktop/registry/data/org/openoffice/Office/Jobs.xcu @@ -0,0 +1,78 @@ + + + + + + + com.sun.star.comp.framework.DoRegistrationJob + + + + ${SERVICETAG_PRODUCTNAME} + + + ${SERVICETAG_PRODUCTVERSION} + + + ${SERVICETAG_URN} + + + ${SERVICETAG_SOURCE} + + + ${SERVICETAG_PARENTNAME} + + + Sun Microsystems, Inc. + + + $(user)/registration.xml + + + ${REGISTRATION_HOST}/register/${registry_urn}?product=${REGISTRATION_PRODUCT}&locale=${locale}&cid=${REGISTRATION_CID} + + + + + + + + + + + + + + + + + diff --git a/desktop/registry/data/org/openoffice/Office/makefile.mk b/desktop/registry/data/org/openoffice/Office/makefile.mk new file mode 100644 index 000000000000..651c731fa4a9 --- /dev/null +++ b/desktop/registry/data/org/openoffice/Office/makefile.mk @@ -0,0 +1,81 @@ +#************************************************************************* +# +# 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: makefile.mk,v $ +# +# $Revision: 1.5 $ +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/..$/..$/.. +PRJNAME=setup_native +TARGET=data_registration +PACKAGE=org.openoffice.Office + +ABSXCSROOT=$(SOLARXMLDIR) +XCSROOT=.. +DTDDIR=$(ABSXCSROOT) +XSLDIR=$(ABSXCSROOT)$/processing +PROCESSOUT=$(MISC)$/$(TARGET) +PROCESSORDIR=$(SOLARBINDIR) + +.INCLUDE : settings.mk +.IF "$(L10N_framework)"=="" + +# --- Files ------------------------------------------------------- + +.IF "$(BUILD_SPECIAL)"!="" + +XCUFILES= \ + Jobs.xcu + +MODULEFILES= + +LOCALIZEDFILES= + +PACKAGEDIR=$(subst,.,$/ $(PACKAGE)) +SPOOLDIR=$(MISC)$/registry$/spool + +MYXCUFILES= \ + $(SPOOLDIR)$/$(PACKAGEDIR)$/Jobs$/Jobs-registration.xcu + +.ELSE # "$(BUILD_SPECIAL)"!="" + +dummy: + @echo "Nothing to build" + +.ENDIF # "$(BUILD_SPECIAL)"!="" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +.ENDIF # L10N_framework +ALLTAR : $(MYXCUFILES) + +$(SPOOLDIR)$/$(PACKAGEDIR)$/Jobs$/Jobs-registration.xcu : $(PROCESSOUT)$/registry$/data$/$/$(PACKAGEDIR)$/Jobs.xcu + @-$(MKDIRHIER) $(@:d) + @$(COPY) $< $@ + diff --git a/desktop/source/deployment/registry/help/dp_help.cxx b/desktop/source/deployment/registry/help/dp_help.cxx index 573c1c639de1..dd9e009e90cc 100644 --- a/desktop/source/deployment/registry/help/dp_help.cxx +++ b/desktop/source/deployment/registry/help/dp_help.cxx @@ -40,7 +40,7 @@ #include "comphelper/servicedecl.hxx" #include "svtools/inettype.hxx" -#include +#include #include #include #include diff --git a/desktop/source/registration/com/sun/star/registration/Registration.java b/desktop/source/registration/com/sun/star/registration/Registration.java new file mode 100644 index 000000000000..afcb1b99660e --- /dev/null +++ b/desktop/source/registration/com/sun/star/registration/Registration.java @@ -0,0 +1,342 @@ +/************************************************************************* + * + * 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: Registration.java,v $ + * $Revision: 1.3 $ + * + * 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.registration; + +import com.sun.star.beans.NamedValue; +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.frame.DispatchResultEvent; +import com.sun.star.frame.DispatchResultState; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.registry.*; +import com.sun.star.servicetag.*; +import com.sun.star.system.*; +import com.sun.star.task.*; +import com.sun.star.uno.*; +import com.sun.star.uri.XExternalUriReferenceTranslator; +import com.sun.star.util.XStringSubstitution; + +import java.io.*; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Locale; +import java.util.Set; +import java.net.HttpURLConnection; + +public class Registration { + + public static XSingleServiceFactory __getServiceFactory(String implName, + XMultiServiceFactory multiFactory, XRegistryKey regKey) { + XSingleServiceFactory xSingleServiceFactory = null; + + if (implName.equals(Registration.class.getName())) { + xSingleServiceFactory = FactoryHelper.getServiceFactory(_Registration.class, _serviceName, multiFactory, regKey); + } + + return xSingleServiceFactory; + } + + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo(Registration.class.getName(), _serviceName, regKey); + } + + static final String _serviceName = "com.sun.star.comp.framework.DoRegistrationJob"; + + static public class _Registration implements XJob { + XComponentContext xComponentContext; + + XStringSubstitution xPathSubstService = null; + XExternalUriReferenceTranslator xUriTranslator = null; + + RegistrationData theRegistrationData = null; + + public _Registration(XComponentContext xComponentContext) { + this.xComponentContext = xComponentContext; + } + + private String resolvePath(String path) { + try { + if( xPathSubstService == null || xUriTranslator == null ) { + XMultiComponentFactory theServiceManager = xComponentContext.getServiceManager(); + if( xPathSubstService == null ) { + Object o = theServiceManager.createInstanceWithContext( + "com.sun.star.util.PathSubstitution", + xComponentContext ); + xPathSubstService = (XStringSubstitution) + UnoRuntime.queryInterface(XStringSubstitution.class, o); + } + + if( xUriTranslator == null ) { + Object o = theServiceManager.createInstanceWithContext( + "com.sun.star.uri.ExternalUriReferenceTranslator", + xComponentContext ); + xUriTranslator = (XExternalUriReferenceTranslator) + UnoRuntime.queryInterface(XExternalUriReferenceTranslator.class, o); + } + } + + String s = xPathSubstService.substituteVariables(path, true); + return xUriTranslator.translateToExternal(s); + } catch (java.lang.Exception e) { + return path; + } + } + + private void openBrowser(String url) { + try { + XMultiComponentFactory theServiceManager = xComponentContext.getServiceManager(); + + Object o = theServiceManager.createInstanceWithContext( + "com.sun.star.system.SystemShellExecute", + xComponentContext ); + + XSystemShellExecute xShellExecuteService = (XSystemShellExecute) + UnoRuntime.queryInterface(XSystemShellExecute.class, o); + + xShellExecuteService.execute( url, "", SystemShellExecuteFlags.DEFAULTS ); + } catch (java.lang.Exception e) { + } + } + + private ServiceTag getServiceTagFromRegistrationData(File xmlFile, String productURN) { + try { + RegistrationData storedRegData = RegistrationData.loadFromXML(new FileInputStream(xmlFile)); + Set storedServiceTags = storedRegData.getServiceTags(); + + Iterator tagIterator = storedServiceTags.iterator(); + while( tagIterator.hasNext() ) { + ServiceTag tag = tagIterator.next(); + if( tag.getProductURN().equals(productURN) ) { + theRegistrationData = storedRegData; + return tag; + } + } + + // product URN has changed, remove registration data file + xmlFile.delete(); + } catch (IOException e) { + // fall through intentionally + } catch (IllegalArgumentException e) { + // file is damaged (or a name clash appeared) + xmlFile.delete(); + } + return null; + } + + /* + * XJob + * + * NOTE: as this Job hets triggered by the the JobExecutor service from first start + * wizard and registration reminder code (because their frames do not implement + * XDispatchProvider), making this an XAsyncJob doesn't make sense as the + * JobExecutor waits for the jobFinished call on the listener passed. + */ + public Object execute(NamedValue[] args) + throws com.sun.star.lang.IllegalArgumentException, com.sun.star.uno.Exception { + + final NamedValue[] f_args = args; + + new Thread( + new Runnable () { + public void run() { + try { + executeImpl(f_args); + } catch(com.sun.star.uno.Exception e) { + } + } + } + ).start(); + + NamedValue ret[] = new NamedValue[1]; + ret[0] = new NamedValue( "Deactivate", new Boolean(false) ); + return ret; + } + + public synchronized void executeImpl(NamedValue[] args) + throws com.sun.star.lang.IllegalArgumentException, com.sun.star.uno.Exception { + + // extract the interesting part of the argument list + NamedValue[] theJobConfig = null; + NamedValue[] theEnvironment = null; + + int c = args.length; + for (int i=0; i +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJNAME = setup_native +PRJ = ..$/..$/..$/..$/..$/.. +TARGET = productregistration +PACKAGE = com$/sun$/star$/registration + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +.IF "$(ENABLE_SVCTAGS)" == "YES" + +JARFILES = jurt.jar unoil.jar ridl.jar +JAVAFILES = \ + Registration.java + +JAVACLASSFILES= $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class) + +JARTARGET = $(TARGET).jar +JARCOMPRESS = TRUE +JARCLASSDIRS = $(PACKAGE) com$/sun$/star$/servicetag +CUSTOMMANIFESTFILE = manifest +.ENDIF # "$(ENABLE_SVCTAGS)" == "YES" + +# --- Targets ------------------------------------------------------ + + +.INCLUDE : target.mk + diff --git a/desktop/source/registration/com/sun/star/registration/manifest b/desktop/source/registration/com/sun/star/registration/manifest new file mode 100644 index 000000000000..952aaa804e96 --- /dev/null +++ b/desktop/source/registration/com/sun/star/registration/manifest @@ -0,0 +1,2 @@ +RegistrationClassName: com.sun.star.registration.Registration +UNO-Type-Path: diff --git a/desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java b/desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java new file mode 100644 index 000000000000..c97d5f2cd4f0 --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/BrowserSupport.java @@ -0,0 +1,205 @@ +/************************************************************************* + * + * 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: BrowserSupport.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.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.io.IOException; +import java.net.URI; + +/** + * BrowserSupport class. + * + * The implementation of the com.sun.servicetag API needs to be + * compiled with JDK 5 as well since the consumer of this API + * may require to support JDK 5 (e.g. NetBeans). + * + * The Desktop.browse() method can be backported in this class + * if needed. The current implementation only supports JDK 6. + */ +class BrowserSupport { + private static boolean isBrowseSupported = false; + private static Method browseMethod = null; + private static Object desktop = null; + private static volatile Boolean result = false; + + + private static void initX() { + if (desktop != null) { + return; + } + boolean supported = false; + Method browseM = null; + Object desktopObj = null; + try { + // Determine if java.awt.Desktop is supported + Class desktopCls = Class.forName("java.awt.Desktop", true, null); + Method getDesktopM = desktopCls.getMethod("getDesktop"); + browseM = desktopCls.getMethod("browse", URI.class); + + Class actionCls = Class.forName("java.awt.Desktop$Action", true, null); + final Method isDesktopSupportedMethod = desktopCls.getMethod("isDesktopSupported"); + Method isSupportedMethod = desktopCls.getMethod("isSupported", actionCls); + Field browseField = actionCls.getField("BROWSE"); + // isDesktopSupported calls getDefaultToolkit which can block + // infinitely, see 6636099 for details, to workaround we call + // in a thread and time it out, noting that the issue is specific + // to X11, it does not hurt for Windows. + Thread xthread = new Thread() { + public void run() { + try { + // support only if Desktop.isDesktopSupported() and + // Desktop.isSupported(Desktop.Action.BROWSE) return true. + result = (Boolean) isDesktopSupportedMethod.invoke(null); + } catch (IllegalAccessException e) { + // should never reach here + InternalError x = + new InternalError("Desktop.getDesktop() method not found"); + x.initCause(e); + } catch (InvocationTargetException e) { + // browser not supported + if (Util.isVerbose()) { + e.printStackTrace(); + } + } + } + }; + // set it to daemon, so that the vm will exit. + xthread.setDaemon(true); + xthread.start(); + try { + xthread.join(5 * 1000); + } catch (InterruptedException ie) { + // ignore the exception + } + if (result.booleanValue()) { + desktopObj = getDesktopM.invoke(null); + result = (Boolean) isSupportedMethod.invoke(desktopObj, browseField.get(null)); + supported = result.booleanValue(); + } + } catch (ClassNotFoundException e) { + // browser not supported + if (Util.isVerbose()) { + e.printStackTrace(); + } + } catch (NoSuchMethodException e) { + // browser not supported + if (Util.isVerbose()) { + e.printStackTrace(); + } + } catch (NoSuchFieldException e) { + // browser not supported + if (Util.isVerbose()) { + e.printStackTrace(); + } + } catch (IllegalAccessException e) { + // should never reach here + InternalError x = + new InternalError("Desktop.getDesktop() method not found"); + x.initCause(e); + throw x; + } catch (InvocationTargetException e) { + // browser not supported + if (Util.isVerbose()) { + e.printStackTrace(); + } + } + isBrowseSupported = supported; + browseMethod = browseM; + desktop = desktopObj; + } + + static boolean isSupported() { + initX(); + return isBrowseSupported; + } + + /** + * Launches the default browser to display a {@code URI}. + * If the default browser is not able to handle the specified + * {@code URI}, the application registered for handling + * {@code URIs} of the specified type is invoked. The application + * is determined from the protocol and path of the {@code URI}, as + * defined by the {@code URI} class. + *

+ * This method calls the Desktop.getDesktop().browse() method. + *

+ * @param uri the URI to be displayed in the user default browser + * + * @throws NullPointerException if {@code uri} is {@code null} + * @throws UnsupportedOperationException if the current platform + * does not support the {@link Desktop.Action#BROWSE} action + * @throws IOException if the user default browser is not found, + * or it fails to be launched, or the default handler application + * failed to be launched + * @throws IllegalArgumentException if the necessary permissions + * are not available and the URI can not be converted to a {@code URL} + */ + static void browse(URI uri) throws IOException { + if (uri == null) { + throw new NullPointerException("null uri"); + } + if (!isSupported()) { + throw new UnsupportedOperationException("Browse operation is not supported"); + } + + // Call Desktop.browse() method + try { + if (Util.isVerbose()) { + System.out.println("desktop: " + desktop + ":browsing..." + uri); + } + browseMethod.invoke(desktop, uri); + } catch (IllegalAccessException e) { + // should never reach here + InternalError x = + new InternalError("Desktop.getDesktop() method not found"); + x.initCause(e); + throw x; + } catch (InvocationTargetException e) { + Throwable x = e.getCause(); + if (x != null) { + if (x instanceof UnsupportedOperationException) { + throw (UnsupportedOperationException) x; + } else if (x instanceof IllegalArgumentException) { + throw (IllegalArgumentException) x; + } else if (x instanceof IOException) { + throw (IOException) x; + } else if (x instanceof SecurityException) { + throw (SecurityException) x; + } else { + // ignore + } + } + } + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/Installer.java b/desktop/source/registration/com/sun/star/servicetag/Installer.java new file mode 100644 index 000000000000..02825dfec69d --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/Installer.java @@ -0,0 +1,947 @@ +/************************************************************************* + * + * 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: Installer.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.HashSet; +import java.util.Locale; +import java.util.Properties; +import java.util.Set; +import java.util.List; +import java.util.ArrayList; +import static com.sun.star.servicetag.Util.*; + +/** + * Service Tag Installer for Java SE. + */ +public class Installer { + // System properties for testing + private static String SVCTAG_DIR_PATH = + "servicetag.dir.path"; + private static String SVCTAG_ENABLE_REGISTRATION = + "servicetag.registration.enabled"; + private final static String SUN_VENDOR = "Sun Microsystems"; + private final static String REGISTRATION_XML = "registration.xml"; + private final static String SERVICE_TAG_FILE = "servicetag"; + private final static String REGISTRATION_HTML_NAME = "register"; + + private final static Locale[] knownSupportedLocales = + new Locale[] { Locale.ENGLISH, + Locale.JAPANESE, + Locale.SIMPLIFIED_CHINESE}; + + private final static String javaHome = System.getProperty("java.home"); + private static File svcTagDir; + private static File serviceTagFile; + private static File regXmlFile; + private static RegistrationData registration; + private static boolean supportRegistration; + private static String registerHtmlParent; + private static Set supportedLocales = new HashSet(); + private static Properties swordfishProps = null; + private static String[] jreArchs = null; + static { + String dir = System.getProperty(SVCTAG_DIR_PATH); + if (dir == null) { + svcTagDir = new File(getJrePath(), "lib" + File.separator + SERVICE_TAG_FILE); + } else { + svcTagDir = new File(dir); + } + serviceTagFile = new File(svcTagDir, SERVICE_TAG_FILE); + regXmlFile = new File(svcTagDir, REGISTRATION_XML); + if (System.getProperty(SVCTAG_ENABLE_REGISTRATION) == null) { + supportRegistration = isJdk(); + } else { + supportRegistration = true; + } + } + + private Installer() { + } + + // Implementation of ServiceTag.getJavaServiceTag(String) method + static ServiceTag getJavaServiceTag(String source) throws IOException { + if (!System.getProperty("java.vendor").startsWith(SUN_VENDOR)) { + // Products bundling this implementation may run on + // Mac OS which is not a Sun JDK + return null; + } + boolean cleanup = false; + try { + // Check if we have the swordfish entries for this JRE version + if (loadSwordfishEntries() == null) { + return null; + } + + ServiceTag st = getJavaServiceTag(); + // Check if the service tag created by this bundle owner + if (st != null && st.getSource().equals(source)) { + // Install the system service tag if supported + // stclient may be installed after the service tag creation + if (Registry.isSupported()) { + installSystemServiceTag(); + } + return st; + } + + // in case any exception thrown during the cleanup + cleanup = true; + + // re-create a new one for this bundle owner + // first delete the registration data + deleteRegistrationData(); + cleanup = false; + + // create service tag and generate new register.html pages + return createServiceTag(source); + } finally { + if (cleanup) { + if (regXmlFile.exists()) { + regXmlFile.delete(); + } + if (serviceTagFile.exists()) { + serviceTagFile.delete(); + } + } + } + } + + /** + * Returns the Java SE registration data located in + * the /lib/servicetag/registration.xml by default. + * + * @throws IllegalArgumentException if the registration data + * is of invalid format. + */ + private static synchronized RegistrationData getRegistrationData() + throws IOException { + if (registration != null) { + return registration; + } + if (regXmlFile.exists()) { + BufferedInputStream in = null; + try { + in = new BufferedInputStream(new FileInputStream(regXmlFile)); + registration = RegistrationData.loadFromXML(in); + } catch (IllegalArgumentException ex) { + System.err.println("Error: Bad registration data \"" + + regXmlFile + "\":" + ex.getMessage()); + throw ex; + } finally { + if (in != null) { + in.close(); + } + } + } else { + registration = new RegistrationData(); + } + return registration; + } + + /** + * Write the registration data to the registration.xml file. + * + * The offline registration page has to be regenerated with + * the new registration data. + * + * @throws java.io.IOException + */ + private static synchronized void writeRegistrationXml() + throws IOException { + if (!svcTagDir.exists()) { + // This check is for NetBeans or other products that + // bundles this com.sun.servicetag implementation for + // pre-6u5 release. + if (!svcTagDir.mkdir()) { + throw new IOException("Failed to create directory: " + svcTagDir); + } + } + + // regenerate the new offline registration page + deleteRegistrationHtmlPage(); + getRegistrationHtmlPage(); + + BufferedOutputStream out = null; + try { + out = new BufferedOutputStream(new FileOutputStream(regXmlFile)); + getRegistrationData().storeToXML(out); + } catch (IllegalArgumentException ex) { + System.err.println("Error: Bad registration data \"" + + regXmlFile + "\":" + ex.getMessage()); + throw ex; + } finally { + if (out != null) { + out.close(); + } + } + } + + /** + * Returns the instance urn(s) stored in the servicetag file + * or empty set if file not exists. + */ + private static Set getInstalledURNs() throws IOException { + Set urnSet = new HashSet(); + if (serviceTagFile.exists()) { + BufferedReader in = null; + try { + in = new BufferedReader(new FileReader(serviceTagFile)); + String urn; + while ((urn = in.readLine()) != null) { + urn = urn.trim(); + if (urn.length() > 0) { + urnSet.add(urn); + } + } + } finally { + if (in != null) { + in.close(); + } + } + } + return urnSet; + } + + /** + * Return the Java SE service tag(s) if it exists. + * Typically only one Java SE service tag but it could have two for + * Solaris 32-bit and 64-bit on the same install directory. + * + * @return the service tag(s) for Java SE + */ + private static ServiceTag[] getJavaServiceTagArray() throws IOException { + RegistrationData regData = getRegistrationData(); + Set svcTags = regData.getServiceTags(); + Set result = new HashSet(); + + Properties props = loadSwordfishEntries(); + String jdkUrn = props.getProperty("servicetag.jdk.urn"); + String jreUrn = props.getProperty("servicetag.jre.urn"); + for (ServiceTag st : svcTags) { + if (st.getProductURN().equals(jdkUrn) || + st.getProductURN().equals(jreUrn)) { + result.add(st); + } + } + return result.toArray(new ServiceTag[0]); + } + + /** + * Returns the Java SE service tag for this running platform; + * or null if not exist. + * This method will return the 64-bit service tag if the JDK + * supports both 32-bit and 64-bit if already created. + */ + private static ServiceTag getJavaServiceTag() throws IOException { + String definedId = getProductDefinedId(); + for (ServiceTag st : getJavaServiceTagArray()) { + if (st.getProductDefinedInstanceID().equals(definedId)) { + return st; + } + } + return null; + } + + /** + * Create a service tag for Java SE and install in the system + * service tag registry if supported. + * + * A registration data /lib/servicetag/registration.xml + * will be created to storeToXML the XML entry for Java SE service tag. + * If the system supports service tags, this method will install + * the Java SE service tag in the system service tag registry and + * its instance_urn will be stored to /lib/servicetag/servicetag. + * + * If /lib/servicetag/registration.xml exists but is not installed + * in the system service tag registry (i.e. servicetag doesn't exist), + * this method will install it as described above. + * + * If the system supports service tag, stclient will be used + * to create the Java SE service tag. + * + * A Solaris 32-bit and 64-bit JDK will be installed in the same + * directory but the registration.xml will have 2 service tags. + * The servicetag file will also contain 2 instance_urns for that case. + */ + private static ServiceTag createServiceTag(String svcTagSource) + throws IOException { + // determine if a new service tag is needed to be created + ServiceTag newSvcTag = null; + if (getJavaServiceTag() == null) { + newSvcTag = newServiceTag(svcTagSource); + } + + // Add the new service tag in the registration data + if (newSvcTag != null) { + RegistrationData regData = getRegistrationData(); + + // Add the service tag to the registration data in JDK/JRE + newSvcTag = regData.addServiceTag(newSvcTag); + + // add if there is a service tag for the OS + ServiceTag osTag = SolarisServiceTag.getServiceTag(); + if (osTag != null && regData.getServiceTag(osTag.getInstanceURN()) == null) { + regData.addServiceTag(osTag); + } + // write to the registration.xml + writeRegistrationXml(); + } + + // Install the system service tag if supported + if (Registry.isSupported()) { + installSystemServiceTag(); + } + return newSvcTag; + } + + private static void installSystemServiceTag() throws IOException { + // only install the service tag in the registry if + // it has permission to write the servicetag file. + if ((!serviceTagFile.exists() && !svcTagDir.canWrite()) || + (serviceTagFile.exists() && !serviceTagFile.canWrite())) { + return; + } + + Set urns = getInstalledURNs(); + ServiceTag[] javaSvcTags = getJavaServiceTagArray(); + if (urns.size() < javaSvcTags.length) { + for (ServiceTag st : javaSvcTags) { + // Add the service tag in the system service tag registry + // if not installed + String instanceURN = st.getInstanceURN(); + if (!urns.contains(instanceURN)) { + Registry.getSystemRegistry().addServiceTag(st); + } + } + } + writeInstalledUrns(); + } + + private static ServiceTag newServiceTag(String svcTagSource) throws IOException { + // Load the swoRDFish information for the service tag creation + Properties props = loadSwordfishEntries(); + + // Determine the product URN and name + String productURN; + String productName; + + if (isJdk()) { + // /jre exists which implies it's a JDK + productURN = props.getProperty("servicetag.jdk.urn"); + productName = props.getProperty("servicetag.jdk.name"); + } else { + // Otherwise, it's a JRE + productURN = props.getProperty("servicetag.jre.urn"); + productName = props.getProperty("servicetag.jre.name"); + } + + return ServiceTag.newInstance(ServiceTag.generateInstanceURN(), + productName, + System.getProperty("java.version"), + productURN, + props.getProperty("servicetag.parent.name"), + props.getProperty("servicetag.parent.urn"), + getProductDefinedId(), + SUN_VENDOR, + System.getProperty("os.arch"), + getZoneName(), + svcTagSource); + } + + /** + * Delete the registration data, the offline registration pages and + * the service tags in the system service tag registry if installed. + * + * The registration.xml and servicetag file will be removed. + */ + private static synchronized void deleteRegistrationData() + throws IOException { + try { + // delete the offline registration page + deleteRegistrationHtmlPage(); + + // Remove the service tag from the system ST registry if exists + Set urns = getInstalledURNs(); + if (urns.size() > 0 && Registry.isSupported()) { + for (String u : urns) { + Registry.getSystemRegistry().removeServiceTag(u); + } + } + registration = null; + } finally { + // Delete the registration.xml and servicetag files if exists + if (regXmlFile.exists()) { + if (!regXmlFile.delete()) { + throw new IOException("Failed to delete " + regXmlFile); + } + } + if (serviceTagFile.exists()) { + if (!serviceTagFile.delete()) { + throw new IOException("Failed to delete " + serviceTagFile); + } + } + } + } + + /** + * Updates the registration data to contain one single service tag + * for the running Java runtime. + */ + private static synchronized void updateRegistrationData(String svcTagSource) + throws IOException { + RegistrationData regData = getRegistrationData(); + ServiceTag curSvcTag = newServiceTag(svcTagSource); + + ServiceTag[] javaSvcTags = getJavaServiceTagArray(); + Set urns = getInstalledURNs(); + for (ServiceTag st : javaSvcTags) { + if (!st.getProductDefinedInstanceID().equals(curSvcTag.getProductDefinedInstanceID())) { + String instanceURN = st.getInstanceURN(); + regData.removeServiceTag(instanceURN); + + // remove it from the system service tag registry if exists + if (urns.contains(instanceURN) && Registry.isSupported()) { + Registry.getSystemRegistry().removeServiceTag(instanceURN); + } + } + } + writeRegistrationXml(); + writeInstalledUrns(); + } + + private static void writeInstalledUrns() throws IOException { + // if the Registry is not supported, + // remove the servicetag file + if (!Registry.isSupported() && serviceTagFile.exists()) { + serviceTagFile.delete(); + return; + } + + PrintWriter out = null; + try { + out = new PrintWriter(serviceTagFile); + + ServiceTag[] javaSvcTags = getJavaServiceTagArray(); + for (ServiceTag st : javaSvcTags) { + // Write the instance_run to the servicetag file + String instanceURN = st.getInstanceURN(); + out.println(instanceURN); + } + } finally { + if (out != null) { + out.close(); + } + } + } + + /** + * Load the values associated with the swoRDFish metadata entries + * for Java SE. The swoRDFish metadata entries are different for + * different release. + * + * @param version Version of Java SE + */ + private static synchronized Properties loadSwordfishEntries() throws IOException { + if (swordfishProps != null) { + return swordfishProps; + } + + // The version string for Java SE 6 is 1.6.0 + // We just need the minor number in the version string + int version = Util.getJdkVersion(); + + String filename = "/com/sun/servicetag/resources/javase_" + + version + "_swordfish.properties"; + InputStream in = Installer.class.getClass().getResourceAsStream(filename); + if (in == null) { + return null; + } + swordfishProps = new Properties(); + try { + swordfishProps.load(in); + } finally { + in.close(); + } + return swordfishProps; + } + + /** + * Returns the product defined instance ID for Java SE. + * It is a list of comma-separated name/value pairs: + * "id= []*" + * "dir=" + * + * where is the full version string of the JRE, + * is the architecture that the runtime supports + * (i.e. "sparc", "sparcv9", "i386", "amd64" (ISA list)) + * + * For Solaris, it can be dual mode that can support both + * 32-bit and 64-bit. the "id" will be set to + * "1.6.0_03-b02 sparc sparcv9" + * + * The "dir" property is included in the service tag to enable + * the Service Tag software to determine if a service tag for + * Java SE is invalid and perform appropriate service tag + * cleanup if necessary. See RFE# 6574781 Service Tags Enhancement. + * + */ + private static String getProductDefinedId() { + StringBuilder definedId = new StringBuilder(); + definedId.append("id="); + definedId.append(System.getProperty("java.runtime.version")); + + String[] archs = getJreArchs(); + for (String name : archs) { + definedId.append(" " + name); + } + + String location = ",dir=" + javaHome; + if ((definedId.length() + location.length()) < 256) { + definedId.append(",dir="); + definedId.append(javaHome); + } else { + // if it exceeds the limit, we will not include the location + if (isVerbose()) { + System.err.println("Warning: Product defined instance ID exceeds the field limit:"); + } + } + + return definedId.toString(); + } + + /** + * Returns the architectures that the runtime supports + * (i.e. "sparc", "sparcv9", "i386", "amd64" (ISA list)) + * The directory name where libjava.so is located. + * + * On Windows, returns the "os.arch" system property value. + */ + private synchronized static String[] getJreArchs() { + if (jreArchs != null) { + return jreArchs; + } + + Set archs = new HashSet(); + + String os = System.getProperty("os.name"); + if (os.equals("SunOS") || os.equals("Linux")) { + // Traverse the directories under /lib. + // If /lib//libjava.so exists, add + // to the product defined ID + File dir = new File(getJrePath() + File.separator + "lib"); + if (dir.isDirectory()) { + String[] children = dir.list(); + for (String name : children) { + File f = new File(dir, name + File.separator + "libjava.so"); + if (f.exists()) { + archs.add(name); + } + } + } + } else { + // Windows - append the os.arch + archs.add(System.getProperty("os.arch")); + } + jreArchs = archs.toArray(new String[0]); + return jreArchs; + } + + /** + * Return the zonename if zone is supported; otherwise, return + * "global". + */ + public static String getZoneName() throws IOException { + String zonename = "global"; + + String command = "/usr/bin/zonename"; + File f = new File(command); + // com.sun.servicetag package has to be compiled with JDK 5 as well + // JDK 5 doesn't support the File.canExecute() method. + // Risk not checking isExecute() for the zonename command is very low. + if (f.exists()) { + ProcessBuilder pb = new ProcessBuilder(command); + Process p = pb.start(); + String output = commandOutput(p); + if (p.exitValue() == 0) { + zonename = output.trim(); + } + + } + return zonename; + } + + private synchronized static String getRegisterHtmlParent() throws IOException { + if (registerHtmlParent == null) { + File htmlDir; // register.html is put under the JDK directory + if (getJrePath().endsWith(File.separator + "jre")) { + htmlDir = new File(getJrePath(), ".."); + } else { + // j2se non-image build + htmlDir = new File(getJrePath()); + } + + // initialize the supported locales + initSupportedLocales(htmlDir); + + // Determine the location of the offline registration page + String path = System.getProperty(SVCTAG_DIR_PATH); + if (path == null) { + // Default is /register.html + registerHtmlParent = htmlDir.getCanonicalPath(); + } else { + File f = new File(path); + registerHtmlParent = f.getCanonicalPath(); + if (!f.isDirectory()) { + throw new InternalError("Path " + path + " set in \"" + + SVCTAG_DIR_PATH + "\" property is not a directory"); + } + } + } + return registerHtmlParent; + } + + /** + * Returns the File object of the offline registration page localized + * for the default locale in the JDK directory. + */ + static synchronized File getRegistrationHtmlPage() throws IOException { + if (!supportRegistration) { + // No register.html page generated if JRE + return null; + } + + String parent = getRegisterHtmlParent(); + + // check if the offline registration page is already generated + File f = new File(parent, REGISTRATION_HTML_NAME + ".html"); + if (!f.exists()) { + // Generate the localized version of the offline registration Page + generateRegisterHtml(parent); + } + + String name = REGISTRATION_HTML_NAME; + List candidateLocales = getCandidateLocales(Locale.getDefault()); + for (Locale l : candidateLocales) { + if (supportedLocales.contains(l)) { + name = REGISTRATION_HTML_NAME + "_" + l.toString(); + break; + } + } + File htmlFile = new File(parent, name + ".html"); + if (isVerbose()) { + System.out.print("Offline registration page: " + htmlFile); + System.out.println((htmlFile.exists() ? + "" : " not exist. Use register.html")); + } + if (htmlFile.exists()) { + return htmlFile; + } else { + return new File(parent, + REGISTRATION_HTML_NAME + ".html"); + } + } + + private static List getCandidateLocales(Locale locale) { + String language = locale.getLanguage(); + String country = locale.getCountry(); + String variant = locale.getVariant(); + + List locales = new ArrayList(3); + if (variant.length() > 0) { + locales.add(locale); + } + if (country.length() > 0) { + locales.add((locales.size() == 0) ? + locale : new Locale(language, country, "")); + } + if (language.length() > 0) { + locales.add((locales.size() == 0) ? + locale : new Locale(language, "", "")); + } + return locales; + } + + // Remove the offline registration pages + private static void deleteRegistrationHtmlPage() throws IOException { + String parent = getRegisterHtmlParent(); + if (parent == null) { + return; + } + + for (Locale locale : supportedLocales) { + String name = REGISTRATION_HTML_NAME; + if (!locale.equals(Locale.ENGLISH)) { + name += "_" + locale.toString(); + } + File f = new File(parent, name + ".html"); + if (f.exists()) { + if (!f.delete()) { + throw new IOException("Failed to delete " + f); + } + } + } + } + + private static void initSupportedLocales(File jdkDir) { + if (supportedLocales.isEmpty()) { + // initialize with the known supported locales + for (Locale l : knownSupportedLocales) { + supportedLocales.add(l); + } + } + + // Determine unknown supported locales if any + // by finding the localized version of README.html + // This prepares if a new locale in JDK is supported in + // e.g. in the OpenSource world + FilenameFilter ff = new FilenameFilter() { + public boolean accept(File dir, String name) { + String fname = name.toLowerCase(); + if (fname.startsWith("readme") && fname.endsWith(".html")) { + return true; + } + return false; + } + }; + + String[] readmes = jdkDir.list(ff); + for (String name : readmes) { + String basename = name.substring(0, name.length() - ".html".length()); + String[] ss = basename.split("_"); + switch (ss.length) { + case 1: + // English version + break; + case 2: + supportedLocales.add(new Locale(ss[1])); + break; + case 3: + supportedLocales.add(new Locale(ss[1], ss[2])); + break; + default: + // ignore + break; + } + } + if (isVerbose()) { + System.out.println("Supported locales: "); + for (Locale l : supportedLocales) { + System.out.println(l); + } + } + } + + private static final String JDK_HEADER_PNG_KEY = "@@JDK_HEADER_PNG@@"; + private static final String JDK_VERSION_KEY = "@@JDK_VERSION@@"; + private static final String REGISTRATION_URL_KEY = "@@REGISTRATION_URL@@"; + private static final String REGISTRATION_PAYLOAD_KEY = "@@REGISTRATION_PAYLOAD@@"; + + @SuppressWarnings("unchecked") + private static void generateRegisterHtml(String parent) throws IOException { + int version = Util.getJdkVersion(); + int update = Util.getUpdateVersion(); + String jdkVersion = "Version " + version; + if (update > 0) { + // product name is not translated + jdkVersion += " Update " + update; + } + RegistrationData regData = getRegistrationData(); + String registerURL = SunConnection.getRegistrationURL( + regData.getRegistrationURN()).toString(); + // Make sure it uses the canonical path before getting the URI. + File img = new File(svcTagDir.getCanonicalPath(), "jdk_header.png"); + String headerImageSrc = img.toURI().toString(); + + // Format the registration data in one single line + StringBuilder payload = new StringBuilder(); + String xml = regData.toString().replaceAll("\"", "%22"); + BufferedReader reader = new BufferedReader(new StringReader(xml)); + try { + String line = null; + while ((line = reader.readLine()) != null) { + payload.append(line.trim()); + } + } finally { + reader.close(); + } + + String resourceFilename = "/com/sun/star/servicetag/resources/register"; + for (Locale locale : supportedLocales) { + String name = REGISTRATION_HTML_NAME; + String resource = resourceFilename; + if (!locale.equals(Locale.ENGLISH)) { + name += "_" + locale.toString(); + resource += "_" + locale.toString(); + } + File f = new File(parent, name + ".html"); + InputStream in = null; + BufferedReader br = null; + PrintWriter pw = null; + try { + in = Installer.class.getClass().getResourceAsStream(resource + ".html"); + if (in == null) { + // if the resource file is missing + if (isVerbose()) { + System.out.println("Missing resouce file: " + resource + ".html"); + } + continue; + } + if (isVerbose()) { + System.out.println("Generating " + f + " from " + resource + ".html"); + } + + br = new BufferedReader(new InputStreamReader(in, "UTF-8")); + pw = new PrintWriter(f, "UTF-8"); + String line = null; + while ((line = br.readLine()) != null) { + String output = line; + if (line.contains(JDK_VERSION_KEY)) { + output = line.replace(JDK_VERSION_KEY, jdkVersion); + } else if (line.contains(JDK_HEADER_PNG_KEY)) { + output = line.replace(JDK_HEADER_PNG_KEY, headerImageSrc); + } else if (line.contains(REGISTRATION_URL_KEY)) { + output = line.replace(REGISTRATION_URL_KEY, registerURL); + } else if (line.contains(REGISTRATION_PAYLOAD_KEY)) { + output = line.replace(REGISTRATION_PAYLOAD_KEY, payload.toString()); + } + pw.println(output); + } + f.setReadOnly(); + pw.flush(); + } finally { + if (pw != null) { + pw.close(); + } + if (in != null) { + in.close(); + } + if (br!= null) { + br.close(); + } + } + } + } + + /** + * A utility class to create a service tag for Java SE. + *

+ * Usage:
+ *

+ * <JAVA_HOME>/bin/java com.sun.servicetag.Installer + *
+ *

+ */ + public static void main(String[] args) { + String source = "Manual"; + + // Parse the options (arguments starting with "-" ) + boolean delete = false; + boolean update = false; + boolean register = false; + int count = 0; + while (count < args.length) { + String arg = args[count]; + if (arg.trim().length() == 0) { + // skip empty arguments + count++; + continue; + } + + if (arg.equals("-source")) { + source = args[++count]; + } else if (arg.equals("-delete")) { + delete = true; + } else if (arg.equals("-register")) { + register = true; + } else { + usage(); + return; + } + count++; + } + try { + if (delete) { + deleteRegistrationData(); + } else { + ServiceTag[] javaSvcTags = getJavaServiceTagArray(); + String[] archs = getJreArchs(); + if (javaSvcTags.length > archs.length) { + // 64-bit has been uninstalled + // so remove the service tag + updateRegistrationData(source); + } else { + // create the service tag + createServiceTag(source); + } + } + + if (register) { + // Registration is only supported by JDK + // For testing purpose, override with a "servicetag.enable.registration" property + + RegistrationData regData = getRegistrationData(); + if (supportRegistration && !regData.getServiceTags().isEmpty()) { + SunConnection.register(regData); + } + } + System.exit(0); + } catch (IOException e) { + System.err.println("I/O Error: " + e.getMessage()); + if (isVerbose()) { + e.printStackTrace(); + } + } catch (IllegalArgumentException ex) { + if (isVerbose()) { + ex.printStackTrace(); + } + } catch (Exception e) { + System.err.println("Error: " + e.getMessage()); + if (isVerbose()) { + e.printStackTrace(); + } + } + System.exit(1); + } + + private static void usage() { + System.out.println("Usage:"); + System.out.print(" " + Installer.class.getName()); + System.out.println(" [-delete|-source |-register]"); + System.out.println(" to create a service tag for the Java platform"); + System.out.println(""); + System.out.println("Internal Options:"); + System.out.println(" -source: to specify the source of the service tag to be created"); + System.out.println(" -delete: to delete the service tag "); + System.out.println(" -register: to register the JDK"); + System.out.println(" -help: to print this help message"); + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java new file mode 100644 index 000000000000..90e38021c103 --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/LinuxSystemEnvironment.java @@ -0,0 +1,194 @@ +/************************************************************************* + * + * 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: LinuxSystemEnvironment.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; + +// The Service Tags team maintains the latest version of the implementation +// for system environment data collection. JDK will include a copy of +// the most recent released version for a JDK release. We rename +// the package to com.sun.servicetag so that the Sun Connection +// product always uses the latest version from the com.sun.scn.servicetags +// package. JDK and users of the com.sun.servicetag API +// (e.g. NetBeans and SunStudio) will use the version in JDK. + +import java.io.*; + +/** + * Linux implementation of the SystemEnvironment class. + */ +class LinuxSystemEnvironment extends SystemEnvironment { + LinuxSystemEnvironment() { + setHostId(getLinuxHostId()); + setSystemModel(getCommandOutput("/bin/uname", "-i")); + setSystemManufacturer(getLinuxSystemManufacturer()); + setCpuManufacturer(getLinuxCpuManufacturer()); + setSerialNumber(getLinuxSN()); + } + private String dmiInfo = null; + + private static final int SN = 1; + private static final int SYS = 2; + private static final int CPU = 3; + + private String getLinuxHostId() { + String output = getCommandOutput("/usr/bin/hostid"); + // trim off the leading 0x + if (output.startsWith("0x")) { + output = output.substring(2); + } + return output; + } + + /** + * Tries to obtain and return the cpu manufacturer. + * @return The cpu manufacturer (an empty string if not found or an error occurred) + */ + private String getLinuxCpuManufacturer() { + String tmp = getLinuxPSNInfo(CPU); + if (tmp.length() > 0) { + return tmp; + } + + String contents = getFileContent("/proc/cpuinfo"); + for (String line : contents.split("\n")) { + if (line.contains("vendor_id")) { + String[] ss = line.split(":", 2); + if (ss.length > 1) { + return ss[1].trim(); + } + } + } + + // returns an empty string if it can't be found or an error happened + return getLinuxDMIInfo("dmi type 4", "manufacturer"); + } + + + /** + * Tries to obtain and return the system manufacturer. + * @return The system manufacturer (an empty string if not found or an error occurred) + */ + private String getLinuxSystemManufacturer() { + String tmp = getLinuxPSNInfo(SYS); + if (tmp.length() > 0) { + return tmp; + } + + // returns an empty string if it can't be found or an error happened + return getLinuxDMIInfo("dmi type 1", "manufacturer"); + } + + /** + * Tries to obtain and return the serial number of the system. + * @return The serial number (an empty string if not found or an error occurred) + */ + private String getLinuxSN() { + String tmp = getLinuxPSNInfo(SN); + if (tmp.length() > 0) { + return tmp; + } + + // returns an empty string if it can't be found or an error happened + return getLinuxDMIInfo("dmi type 1", "serial number"); + } + + private String getLinuxPSNInfo(int target) { + // try to read from the psn file if it exists + String contents = getFileContent("/var/run/psn"); + String[] ss = contents.split("\n"); + if (target <= ss.length) { + return ss[target-1]; + } + + // default case is to return "" + return ""; + } + + // reads from dmidecode with the given type and target + // returns an empty string if nothing was found or an error occurred + // + // Sample output segment: + // Handle 0x0001 + // DMI type 1, 25 bytes. + // System Information + // Manufacturer: System manufacturer + // Product Name: System Product Name + // Version: System Version + // Serial Number: System Serial Number + // UUID: 3091D719-B25B-D911-959D-6D1B12C7686E + // Wake-up Type: Power Switch + + private synchronized String getLinuxDMIInfo(String dmiType, String target) { + // only try to get dmidecode information once, after that, we can + // reuse the output + if (dmiInfo == null) { + Thread dmidecodeThread = new Thread() { + public void run() { + dmiInfo = getCommandOutput("/usr/sbin/dmidecode"); + } + }; + dmidecodeThread.start(); + + try { + dmidecodeThread.join(2000); + if (dmidecodeThread.isAlive()) { + dmidecodeThread.interrupt(); + dmiInfo = ""; + } + } catch (InterruptedException ie) { + dmidecodeThread.interrupt(); + } + } + + if (dmiInfo.length() == 0) { + return ""; + } + boolean dmiFlag = false; + for (String s : dmiInfo.split("\n")) { + String line = s.toLowerCase(); + if (dmiFlag) { + if (line.contains(target)) { + String key = target + ":"; + int indx = line.indexOf(key) + key.length(); + if (line.contains(key) && indx < line.length()) { + return line.substring(indx).trim(); + } + String[] ss = line.split(":"); + return ss[ss.length-1]; + } + } else if (line.contains(dmiType)) { + dmiFlag = true; + } + } + return ""; + } + +} diff --git a/desktop/source/registration/com/sun/star/servicetag/RegistrationData.java b/desktop/source/registration/com/sun/star/servicetag/RegistrationData.java new file mode 100644 index 000000000000..57be724a78a3 --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/RegistrationData.java @@ -0,0 +1,473 @@ +/************************************************************************* + * + * 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: RegistrationData.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.net.UnknownHostException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import static com.sun.star.servicetag.RegistrationDocument.*; + +/** + * A {@code RegistrationData} object is a container of one or more + * {@link #getServiceTags service tags} that identify the + * components for product registration. + * Each {@code RegistrationData} object has a {@link #getRegistrationURN + * uniform resource name} (URN) as its identifier. + * + * It also has an environment map with + * the following elements: + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
hostnameHostname of the systeme.g. woody
hostIdHost ID of the systeme.g. 83abc1ab
osNameOperating system name e.g. SunOS
osVersionOperating system version e.g. 5.10
osArchitectureOperating system architecture e.g. sparc
systemModelSystem model e.g. SUNW,Sun-Fire-V440
systemManufacturerSystem manufacturer e.g. Sun Microsystems
cpuManufacturerCPU manufacturer e.g. Sun Microsystems
serialNumberSystem serial number e.g. BEL078932
+ *
+ * The hostname and osName element must have a non-empty value. + * If an element is not available on a system and their value will be + * empty. + *

+ * + * Registration XML Schema + *

+ * A {@code RegistrationData} object can be {@link #loadFromXML loaded} from + * and {@link #storeToXML stored} into an XML file in the format described + * by the + * + * registration data schema. The registration data schema is defined by the + * Service Tags Technology. + *

+ * Typically the registration data is constructed at installation time + * and stored in an XML file for later service tag lookup or registration. + * + *

+ * Example Usage + *

+ * The examples below show how the {@code RegistrationData} can be + * used for product registration. + * Exception handling is not shown in these examples for clarity. + *

    + *
  1. This example shows how the JDK creates a JDK service tag, installs it + * in the system service tag registry and adds it to the registration data. + *
    + *
    + *   // create a service tag object with an instance_urn
    + *   ServiceTag st = ServiceTag.newInstance(ServiceTag.generateInstanceURN(),
    + *                                          ....);
    + *   // Adds to the system service tag registry if supported
    + *   if (Registry.isSupported()) {
    + *       Registry.getSystemRegistry().addServiceTag(st);
    + *   }
    + *
    + *   // add to the registration data
    + *   RegistrationData registration  = new RegistrationData();
    + *   registration.addServiceTag(st);
    + * 
    + *
  2. + *
  3. At this point, the registration data is ready to + * send to Sun Connection for registration. This example shows how to register + * the JDK via the Registration Relay Service. + *

    + * There are several registration services for Sun Connection. For example, + * the + * Registration Relay Service is a web application interface that + * processes the registration data payload sent via HTTP post + * and hosts the registration user interface for a specified + * registration URL. Refer to the + * Registration Relay Service Specification for details. + *

    + *

    + *   // Open the connection to the URL of the registration service
    + *   HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
    + *   con.setDoInput(true);
    + *   con.setDoOutput(true);
    + *   con.setUseCaches(false);
    + *   con.setAllowUserInteraction(false);
    + *   con.setRequestMethod("POST");
    + *   con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\"");
    + *   con.connect();
    + *
    + *   // send the registration data to the registration service
    + *   OutputStream out = con.getOutputStream();
    + *   registration.storeToXML(out);
    + *   out.close();
    + * 
    + *
  4. + *
  5. This example shows how to store the registration data in an XML file. + * for later service tag lookup or registration. + *
    + *
    + *   BufferedOutputStream out = new BufferedOutputStream(
    + *       new FileOutputStream(""<JAVA_HOME>/lib/servicetag/registration.xml"));
    + *   registration.storeToXML(out);
    + *   out.close();
    + * 
    + *
  6. + *
  7. This example shows how to install service tags that are in the + * registration data in the system service tag registry when determined + * to be available. The system service tag registry might not have existed + * when the registration data was constructed. + *
    + *
    + *   if (Registry.isSupported()) {
    + *       Set<ServiceTag> svctags = registration.getServiceTags();
    + *       for (ServiceTag st : svctags) {
    + *           Registry.getSystemRegistry().addServiceTag(st);
    + *       }
    + *   }
    + * 
    + *
  8. + *
+ * + * @see Sun Connection Inventory Channel + */ +public class RegistrationData { + private final Map environment; + private final Map svcTagMap; + private final String urn; + + /** + * Creates a {@code RegistrationData} object with a generated + * {@link #getRegistrationURN registration URN}. + * The following keys in the {@link #getEnvironmentMap environment map} + * will be initialized for the configuration of the + * running system: + *
+ * hostname, osName, osVersion and + * osArchitecture + *
+ * and the value of other keys may be empty. + */ + public RegistrationData() { + this(Util.generateURN()); + } + + // package private + RegistrationData(String urn) { + this.urn = urn; + this.environment = initEnvironment(); + this.svcTagMap = new LinkedHashMap(); + } + + private Map initEnvironment() { + Map map = new LinkedHashMap(); + SystemEnvironment sysEnv = SystemEnvironment.getSystemEnvironment(); + map.put(ST_NODE_HOSTNAME, sysEnv.getHostname()); + map.put(ST_NODE_HOST_ID, sysEnv.getHostId()); + map.put(ST_NODE_OS_NAME, sysEnv.getOsName()); + map.put(ST_NODE_OS_VERSION, sysEnv.getOsVersion()); + map.put(ST_NODE_OS_ARCH, sysEnv.getOsArchitecture()); + map.put(ST_NODE_SYSTEM_MODEL, sysEnv.getSystemModel()); + map.put(ST_NODE_SYSTEM_MANUFACTURER, sysEnv.getSystemManufacturer()); + map.put(ST_NODE_CPU_MANUFACTURER, sysEnv.getCpuManufacturer()); + map.put(ST_NODE_SERIAL_NUMBER, sysEnv.getSerialNumber()); + return map; + } + + /** + * Returns the uniform resource name of this registration data + * in this format: + * urn:st:<32-char {@link java.util.UUID uuid}> + * + * @return the URN of this registration data. + */ + public String getRegistrationURN() { + return urn; + } + + /** + * Returns a map containing the environment information for this + * registration data. See the set of keys + * in the environment map. Subsequent update to the environment + * map via the {@link #setEnvironment setEnvironment} method will not be reflected + * in the returned map. + * + * @return an environment map for this registration data. + */ + public Map getEnvironmentMap() { + return new LinkedHashMap(environment); + } + + /** + * Sets an element of the specified {@code name} in the environment map + * with the given {@code value}. + * + * @throws IllegalArgumentException if {@code name} is not a valid key + * in the environment map, or {@code value} is not valid. + */ + public void setEnvironment(String name, String value) { + if (name == null) { + throw new NullPointerException("name is null"); + } + if (value == null) { + throw new NullPointerException("value is null"); + } + if (environment.containsKey(name)) { + if (name.equals(ST_NODE_HOSTNAME) || name.equals(ST_NODE_OS_NAME)) { + if (value.length() == 0) { + throw new IllegalArgumentException("\"" + + name + "\" requires non-empty value."); + } + } + environment.put(name, value); + } else { + throw new IllegalArgumentException("\"" + + name + "\" is not an environment element."); + } + } + + /** + * Returns all service tags in this registration data. + * + * @return a {@link Set Set} of the service tags + * in this registration data. + */ + public Set getServiceTags() { + return new HashSet(svcTagMap.values()); + } + + /** + * Adds a service tag to this registration data. + * If the given service tag has an empty instance_urn, + * this method will generate a URN and place it in the copy + * of the service tag in this registration data. + * This method will return the {@code ServiceTag} object + * added to this registration data. + * + * @param st {@code ServiceTag} object to be added. + * @return a {@code ServiceTag} object added to this registration data. + * + * @throws IllegalArgumentException if + * a service tag of the same {@link ServiceTag#getInstanceURN + * instance_urn} already exists in the registry. + */ + public synchronized ServiceTag addServiceTag(ServiceTag st) { + ServiceTag svcTag = ServiceTag.newInstanceWithUrnTimestamp(st); + + String instanceURN = svcTag.getInstanceURN(); + if (svcTagMap.containsKey(instanceURN)) { + throw new IllegalArgumentException("Instance_urn = " + instanceURN + + " already exists in the registration data."); + } else { + svcTagMap.put(instanceURN, svcTag); + } + return svcTag; + } + + /** + * Returns a service tag of the given instance_urn in this registration + * data. + * + * @param instanceURN the instance_urn of the service tag + * @return the {@code ServiceTag} object of the given instance_urn + * if exists; otherwise return {@code null}. + */ + public synchronized ServiceTag getServiceTag(String instanceURN) { + if (instanceURN == null) { + throw new NullPointerException("instanceURN is null"); + } + return svcTagMap.get(instanceURN); + } + + /** + * Removes a service tag of the given instance_urn from this + * registration data. + * + * @param instanceURN the instance_urn of + * the service tag to be removed. + * + * @return the removed {@code ServiceTag} object; + * or {@code null} if the service tag does not exist in this + * registration data. + */ + public synchronized ServiceTag removeServiceTag(String instanceURN) { + if (instanceURN == null) { + throw new NullPointerException("instanceURN is null"); + } + + ServiceTag svcTag = null; + if (svcTagMap.containsKey(instanceURN)) { + svcTag = svcTagMap.remove(instanceURN); + } + return svcTag; + } + + /** + * Updates the product_defined_instance_id in the service tag + * of the given instance_urn in this registration data. + * + * @param instanceURN the instance_urn of the service tag to be updated. + * @param productDefinedInstanceID the value of the + * product_defined_instance_id to be set. + * + * @return the updated {@code ServiceTag} object; + * or {@code null} if the service tag does not exist in this + * registration data. + */ + public synchronized ServiceTag updateServiceTag(String instanceURN, + String productDefinedInstanceID) { + ServiceTag svcTag = getServiceTag(instanceURN); + if (svcTag == null) { + return null; + } + + svcTag = ServiceTag.newInstanceWithUrnTimestamp(svcTag); + // update the product defined instance ID field + svcTag.setProductDefinedInstanceID(productDefinedInstanceID); + svcTagMap.put(instanceURN, svcTag); + return svcTag; + } + + /** + * Reads the registration data from the XML document on the + * specified input stream. The XML document must be + * in the format described by the + * registration data schema. + * The specified stream is closed after this method returns. + * + * @param in the input stream from which to read the XML document. + * @return a {@code RegistrationData} object read from the input + * stream. + * + * @throws IllegalArgumentException if the input stream + * contains an invalid registration data. + * + * @throws IOException if an error occurred when reading from the input stream. + */ + public static RegistrationData loadFromXML(InputStream in) throws IOException { + try { + return RegistrationDocument.load(in); + } finally { + in.close(); + } + } + + /** + * Writes the registration data to the specified output stream + * in the format described by the + * registration data schema with "UTF-8" encoding. + * The specified stream remains open after this method returns. + * + * @param os the output stream on which to write the XML document. + * + * @throws IOException if an error occurred when writing to the output stream. + */ + public void storeToXML(OutputStream os) throws IOException { + RegistrationDocument.store(os, this); + os.flush(); + } + + /** + * Returns a newly allocated byte array containing the registration + * data in XML format. + * + * @return a newly allocated byte array containing the registration + * data in XML format. + */ + public byte[] toXML() { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + storeToXML(out); + return out.toByteArray(); + } catch (IOException e) { + // should not reach here + return new byte[0]; + } + } + + /** + * Returns a string representation of this registration data in XML + * format. + * + * @return a string representation of this registration data in XML + * format. + */ + @Override + public String toString() { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + storeToXML(out); + return out.toString("UTF-8"); + } catch (IOException e) { + // should not reach here + return "Error creating the return string."; + } + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java b/desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java new file mode 100644 index 000000000000..240eebf4e65c --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/RegistrationDocument.java @@ -0,0 +1,374 @@ +/************************************************************************* + * + * 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: RegistrationDocument.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.net.URL; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import org.xml.sax.InputSource; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + +// For write operation +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +/** + * XML Support Class for Product Registration. + */ +class RegistrationDocument { + + private static final String REGISTRATION_DATA_SCHEMA = + "/com/sun/star/servicetag/resources/product_registration.xsd"; + private static final String REGISTRATION_DATA_VERSION = "1.0"; + private static final String SERVICE_TAG_VERSION = "1.0"; + final static String ST_NODE_REGISTRATION_DATA = "registration_data"; + final static String ST_ATTR_REGISTRATION_VERSION = "version"; + final static String ST_NODE_ENVIRONMENT = "environment"; + final static String ST_NODE_HOSTNAME = "hostname"; + final static String ST_NODE_HOST_ID = "hostId"; + final static String ST_NODE_OS_NAME = "osName"; + final static String ST_NODE_OS_VERSION = "osVersion"; + final static String ST_NODE_OS_ARCH = "osArchitecture"; + final static String ST_NODE_SYSTEM_MODEL = "systemModel"; + final static String ST_NODE_SYSTEM_MANUFACTURER = "systemManufacturer"; + final static String ST_NODE_CPU_MANUFACTURER = "cpuManufacturer"; + final static String ST_NODE_SERIAL_NUMBER = "serialNumber"; + final static String ST_NODE_REGISTRY = "registry"; + final static String ST_ATTR_REGISTRY_URN = "urn"; + final static String ST_ATTR_REGISTRY_VERSION = "version"; + final static String ST_NODE_SERVICE_TAG = "service_tag"; + final static String ST_NODE_INSTANCE_URN = "instance_urn"; + final static String ST_NODE_PRODUCT_NAME = "product_name"; + final static String ST_NODE_PRODUCT_VERSION = "product_version"; + final static String ST_NODE_PRODUCT_URN = "product_urn"; + final static String ST_NODE_PRODUCT_PARENT_URN = "product_parent_urn"; + final static String ST_NODE_PRODUCT_PARENT = "product_parent"; + final static String ST_NODE_PRODUCT_DEFINED_INST_ID = "product_defined_inst_id"; + final static String ST_NODE_PRODUCT_VENDOR = "product_vendor"; + final static String ST_NODE_PLATFORM_ARCH = "platform_arch"; + final static String ST_NODE_TIMESTAMP = "timestamp"; + final static String ST_NODE_CONTAINER = "container"; + final static String ST_NODE_SOURCE = "source"; + final static String ST_NODE_INSTALLER_UID = "installer_uid"; + + static RegistrationData load(InputStream in) throws IOException { + Document document = initializeDocument(in); + + // Gets the registration URN + Element root = getRegistrationDataRoot(document); + Element registryRoot = + getSingletonElementFromRoot(root, ST_NODE_REGISTRY); + String urn = registryRoot.getAttribute(ST_ATTR_REGISTRY_URN); + + // Construct a new RegistrationData object from the DOM tree + // Initialize the environment map and service tags + RegistrationData regData = new RegistrationData(urn); + addServiceTags(registryRoot, regData); + + Element envRoot = getSingletonElementFromRoot(root, ST_NODE_ENVIRONMENT); + buildEnvironmentMap(envRoot, regData); + return regData; + } + + static void store(OutputStream os, RegistrationData registration) + throws IOException { + // create a new document with the root node + Document document = initializeDocument(); + + // create the nodes for the environment map and the service tags + // in the registration data + addEnvironmentNodes(document, + registration.getEnvironmentMap()); + addServiceTagRegistry(document, + registration.getRegistrationURN(), + registration.getServiceTags()); + transform(document, os); + } + + // initialize a document from an input stream + private static Document initializeDocument(InputStream in) throws IOException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + try { + // XML schema for validation + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + URL xsdUrl = RegistrationDocument.class.getResource(REGISTRATION_DATA_SCHEMA); + Schema schema = sf.newSchema(xsdUrl); + Validator validator = schema.newValidator(); + + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new InputSource(in)); + validator.validate(new DOMSource(doc)); + return doc; + } catch (SAXException sxe) { + IllegalArgumentException e = new IllegalArgumentException("Error generated in parsing"); + e.initCause(sxe); + throw e; + } catch (ParserConfigurationException pce) { + // Parser with specific options can't be built + // should not reach here + InternalError x = new InternalError("Error in creating the new document"); + x.initCause(pce); + throw x; + } + } + + // initialize a new document for the registration data + private static Document initializeDocument() throws IOException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + try { + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.newDocument(); + + // initialize the document with the registration_data root + Element root = doc.createElement(ST_NODE_REGISTRATION_DATA); + doc.appendChild(root); + root.setAttribute(ST_ATTR_REGISTRATION_VERSION, REGISTRATION_DATA_VERSION); + + return doc; + } catch (ParserConfigurationException pce) { + // Parser with specified options can't be built + // should not reach here + InternalError x = new InternalError("Error in creating the new document"); + x.initCause(pce); + throw x; + } + } + + // Transform the current DOM tree with the given output stream. + private static void transform(Document document, OutputStream os) { + try { + // Use a Transformer for output + TransformerFactory tFactory = TransformerFactory.newInstance(); + tFactory.setAttribute("indent-number", new Integer(3)); + + Transformer transformer = tFactory.newTransformer(); + + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OutputKeys.STANDALONE, "yes"); + transformer.transform(new DOMSource(document), + new StreamResult(new BufferedWriter(new OutputStreamWriter(os, "UTF-8")))); + } catch (UnsupportedEncodingException ue) { + // Should not reach here + InternalError x = new InternalError("Error generated during transformation"); + x.initCause(ue); + throw x; + } catch (TransformerConfigurationException tce) { + // Error generated by the parser + // Should not reach here + InternalError x = new InternalError("Error in creating the new document"); + x.initCause(tce); + throw x; + } catch (TransformerException te) { + // Error generated by the transformer + InternalError x = new InternalError("Error generated during transformation"); + x.initCause(te); + throw x; + } + } + + private static void addServiceTagRegistry(Document document, + String registryURN, + Set svcTags) { + // add service tag registry node and its attributes + Element reg = document.createElement(ST_NODE_REGISTRY); + reg.setAttribute(ST_ATTR_REGISTRY_URN, registryURN); + reg.setAttribute(ST_ATTR_REGISTRY_VERSION, SERVICE_TAG_VERSION); + + Element root = getRegistrationDataRoot(document); + root.appendChild(reg); + + // adds the elements for the service tags + for (ServiceTag st : svcTags) { + addServiceTagElement(document, reg, st); + } + } + + private static void addServiceTagElement(Document document, + Element registryRoot, + ServiceTag st) { + Element svcTag = document.createElement(ST_NODE_SERVICE_TAG); + registryRoot.appendChild(svcTag); + addChildElement(document, svcTag, + ST_NODE_INSTANCE_URN, st.getInstanceURN()); + addChildElement(document, svcTag, + ST_NODE_PRODUCT_NAME, st.getProductName()); + addChildElement(document, svcTag, + ST_NODE_PRODUCT_VERSION, st.getProductVersion()); + addChildElement(document, svcTag, + ST_NODE_PRODUCT_URN, st.getProductURN()); + addChildElement(document, svcTag, + ST_NODE_PRODUCT_PARENT_URN, st.getProductParentURN()); + addChildElement(document, svcTag, + ST_NODE_PRODUCT_PARENT, st.getProductParent()); + addChildElement(document, svcTag, + ST_NODE_PRODUCT_DEFINED_INST_ID, + st.getProductDefinedInstanceID()); + addChildElement(document, svcTag, + ST_NODE_PRODUCT_VENDOR, st.getProductVendor()); + addChildElement(document, svcTag, + ST_NODE_PLATFORM_ARCH, st.getPlatformArch()); + addChildElement(document, svcTag, + ST_NODE_TIMESTAMP, Util.formatTimestamp(st.getTimestamp())); + addChildElement(document, svcTag, + ST_NODE_CONTAINER, st.getContainer()); + addChildElement(document, svcTag, + ST_NODE_SOURCE, st.getSource()); + addChildElement(document, svcTag, + ST_NODE_INSTALLER_UID, + String.valueOf(st.getInstallerUID())); + } + + private static void addChildElement(Document document, Element root, + String element, String text) { + Element node = document.createElement(element); + node.appendChild(document.createTextNode(text)); + root.appendChild(node); + } + + // Constructs service tags from the document + private static void addServiceTags(Element registryRoot, + RegistrationData registration) { + NodeList children = registryRoot.getElementsByTagName(ST_NODE_SERVICE_TAG); + int length = (children == null ? 0 : children.getLength()); + for (int i = 0; i < length; i++) { + Element svcTagElement = (Element) children.item(i); + ServiceTag st = getServiceTag(svcTagElement); + registration.addServiceTag(st); + } + } + + // build environment map from the document + private static void buildEnvironmentMap(Element envRoot, + RegistrationData registration) { + registration.setEnvironment(ST_NODE_HOSTNAME, getTextValue(envRoot, ST_NODE_HOSTNAME)); + registration.setEnvironment(ST_NODE_HOST_ID, getTextValue(envRoot, ST_NODE_HOST_ID)); + registration.setEnvironment(ST_NODE_OS_NAME, getTextValue(envRoot, ST_NODE_OS_NAME)); + registration.setEnvironment(ST_NODE_OS_VERSION, getTextValue(envRoot, ST_NODE_OS_VERSION)); + registration.setEnvironment(ST_NODE_OS_ARCH, getTextValue(envRoot, ST_NODE_OS_ARCH)); + registration.setEnvironment(ST_NODE_SYSTEM_MODEL, getTextValue(envRoot, ST_NODE_SYSTEM_MODEL)); + registration.setEnvironment(ST_NODE_SYSTEM_MANUFACTURER, getTextValue(envRoot, ST_NODE_SYSTEM_MANUFACTURER)); + registration.setEnvironment(ST_NODE_CPU_MANUFACTURER, getTextValue(envRoot, ST_NODE_CPU_MANUFACTURER)); + registration.setEnvironment(ST_NODE_SERIAL_NUMBER, getTextValue(envRoot, ST_NODE_SERIAL_NUMBER)); + } + + // add the nodes representing the environment map in the document + private static void addEnvironmentNodes(Document document, + Map envMap) { + Element root = getRegistrationDataRoot(document); + Element env = document.createElement(ST_NODE_ENVIRONMENT); + root.appendChild(env); + Set> keys = envMap.entrySet(); + for (Map.Entry entry : keys) { + addChildElement(document, env, entry.getKey(), entry.getValue()); + } + } + + private static Element getRegistrationDataRoot(Document doc) { + Element root = doc.getDocumentElement(); + if (!root.getNodeName().equals(ST_NODE_REGISTRATION_DATA)) { + throw new IllegalArgumentException("Not a " + + ST_NODE_REGISTRATION_DATA + + " node \"" + root.getNodeName() + "\""); + } + return root; + } + + private static Element getSingletonElementFromRoot(Element root, String name) { + NodeList children = root.getElementsByTagName(name); + int length = (children == null ? 0 : children.getLength()); + if (length != 1) { + throw new IllegalArgumentException("Invalid number of " + name + + " nodes = " + length); + } + Element e = (Element) children.item(0); + if (!e.getNodeName().equals(name)) { + throw new IllegalArgumentException("Not a " + name + + " node \"" + e.getNodeName() + "\""); + } + return e; + } + + // Constructs one ServiceTag instance from a service tag element root + private static ServiceTag getServiceTag(Element svcTagElement) { + return new ServiceTag( + getTextValue(svcTagElement, ST_NODE_INSTANCE_URN), + getTextValue(svcTagElement, ST_NODE_PRODUCT_NAME), + getTextValue(svcTagElement, ST_NODE_PRODUCT_VERSION), + getTextValue(svcTagElement, ST_NODE_PRODUCT_URN), + getTextValue(svcTagElement, ST_NODE_PRODUCT_PARENT), + getTextValue(svcTagElement, ST_NODE_PRODUCT_PARENT_URN), + getTextValue(svcTagElement, ST_NODE_PRODUCT_DEFINED_INST_ID), + getTextValue(svcTagElement, ST_NODE_PRODUCT_VENDOR), + getTextValue(svcTagElement, ST_NODE_PLATFORM_ARCH), + getTextValue(svcTagElement, ST_NODE_CONTAINER), + getTextValue(svcTagElement, ST_NODE_SOURCE), + Util.getIntValue(getTextValue(svcTagElement, ST_NODE_INSTALLER_UID)), + Util.parseTimestamp(getTextValue(svcTagElement, ST_NODE_TIMESTAMP)) + ); + } + + private static String getTextValue(Element e, String tagName) { + String value = ""; + NodeList nl = e.getElementsByTagName(tagName); + if (nl != null && nl.getLength() > 0) { + Element el = (Element) nl.item(0); + Node node = el.getFirstChild(); + if (node != null) { + value = node.getNodeValue(); + } + } + return value; + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/Registry.java b/desktop/source/registration/com/sun/star/servicetag/Registry.java new file mode 100644 index 000000000000..c118dc2e2575 --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/Registry.java @@ -0,0 +1,558 @@ +/************************************************************************* + * + * 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: Registry.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.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import static com.sun.star.servicetag.Util.*; +import static com.sun.star.servicetag.RegistrationDocument.*; + +/** + * A service tag registry is a XML-based registry containing + * the list of {@link ServiceTag service tags} installed in the system. + * The {@code Registry} class provides interfaces + * to add, remove, update, and get a service tag from a service tag + * registry. + * This {@code Registry} class may not be supported + * on all systems. The {@link #isSupported} method + * can be called to determine if it is supported. + *

+ * A registry may implement restrictions to only allow certain users + * to {@link #updateServiceTag update} and + * to {@link #removeServiceTag remove} a service tag record. Typically, + * only the owner of the service tag, the owner of the registry + * and superuser are authorized to update or remove a service tag in + * the registry. + * + * @see + * Service Tag User Guide + */ +public class Registry { + + private static final String STCLIENT_SOLARIS = "/usr/bin/stclient"; + private static final String STCLIENT_LINUX = "/opt/sun/servicetag/bin/stclient"; + // stclient exit value (see sthelper.h) + private static final int ST_ERR_NOT_AUTH = 245; + private static final int ST_ERR_REC_NOT_FOUND = 225; + + // The stclient output has to be an exported interface + private static final String INSTANCE_URN_DESC = "Product instance URN="; + private static boolean initialized = false; + private static boolean supportsHelperClass = true; // default + private static File stclient = null; + private static String stclientPath = null; + private static Registry registry = new Registry(); + + // System properties for testing + private static String SVCTAG_STCLIENT_CMD = "servicetag.stclient.cmd"; + private static String SVCTAG_STHELPER_SUPPORTED = "servicetag.sthelper.supported"; + + private Registry() { + } + + private synchronized static String getSTclient() { + if (!initialized) { + // the system property always overrides the default setting + if (System.getProperty(SVCTAG_STHELPER_SUPPORTED) != null) { + supportsHelperClass = Boolean.getBoolean(SVCTAG_STHELPER_SUPPORTED); + } + + // This is only used for testing + stclientPath = System.getProperty(SVCTAG_STCLIENT_CMD); + if (stclientPath != null) { + return stclientPath; + } + + // Initialization to determine the platform's stclient pathname + String os = System.getProperty("os.name"); + if (os.equals("SunOS")) { + stclient = new File(STCLIENT_SOLARIS); + } else if (os.equals("Linux")) { + stclient = new File(STCLIENT_LINUX); + } else if (os.startsWith("Windows")) { + stclient = getWindowsStClientFile(); + } else { + if (isVerbose()) { + System.out.println("Running on non-Sun JDK"); + } + } + initialized = true; + } + + // com.sun.servicetag package has to be compiled with JDK 5 as well + // JDK 5 doesn't support the File.canExecute() method. + // Risk not checking isExecute() for the stclient command is very low. + + if (stclientPath == null && stclient != null && stclient.exists()) { + stclientPath = stclient.getAbsolutePath(); + } + return stclientPath; + } + + /** + * Returns the system service tag registry. The {@code Registry} class + * may not be supported on some platforms; use the {@link #isSupported} + * method to determine if it is supported. + * + * @return the {@code Registry} object for the system service tag registry. + * + * @throws UnsupportedOperationException if the {@code Registry} class is + * not supported. + */ + public static Registry getSystemRegistry() { + if (isSupported()) { + return registry; + } else { + throw new UnsupportedOperationException("Registry class is not supported"); + } + } + + /** + * Returns {@code true} if the {@code Registry} class is supported on this system. + * + * @return {@code true} if the {@code Registry} class is supported; + * otherwise, return {@code false}. + */ + public static boolean isSupported() { + return (getSTclient() != null && supportsHelperClass); + } + + private static List getCommandList() { + // Set up the arguments to call stclient + List command = new ArrayList(); + if (System.getProperty(SVCTAG_STCLIENT_CMD) != null) { + // This is for jtreg testing use. This will be set to something + // like: + // $JAVA_HOME/bin/java -cp $TEST_DIR \ + // -Dstclient.registry.path=$TEST_DIR/registry.xml \ + // SvcTagClient + // + // On Windows, the JAVA_HOME and TEST_DIR path could contain + // space e.g. c:\Program Files\Java\jdk1.6.0_05\bin\java. + // The SVCTAG_STCLIENT_CMD must be set with a list of + // space-separated parameters. If a parameter contains spaces, + // it must be quoted with '"'. + + String cmd = getSTclient(); + int len = cmd.length(); + int i = 0; + while (i < len) { + char separator = ' '; + if (cmd.charAt(i) == '"') { + separator = '"'; + i++; + } + // look for the separator or matched the closing '"' + int j; + for (j = i+1; j < len; j++) { + if (cmd.charAt(j) == separator) { + break; + } + } + + if (i == j-1) { + // add an empty parameter + command.add("\"\""); + } else { + // double quotes and space are not included + command.add(cmd.substring(i,j)); + } + + // skip spaces + for (i = j+1; i < len; i++) { + if (!Character.isSpaceChar(cmd.charAt(i))) { + break; + } + } + } + if (isVerbose()) { + System.out.println("Command list:"); + for (String s : command) { + System.out.println(s); + } + } + } else { + command.add(getSTclient()); + } + return command; + } + + // Returns null if the service tag record not found; + // or throw UnauthorizedAccessException or IOException + // based on the exitValue. + private static ServiceTag checkReturnError(int exitValue, + String output, + ServiceTag st) throws IOException { + switch (exitValue) { + case ST_ERR_REC_NOT_FOUND: + return null; + case ST_ERR_NOT_AUTH: + if (st != null) { + throw new UnauthorizedAccessException( + "Not authorized to access " + st.getInstanceURN() + + " installer_uid=" + st.getInstallerUID()); + } else { + throw new UnauthorizedAccessException( + "Not authorized:" + output); + } + default: + throw new IOException("stclient exits with error" + + " (" + exitValue + ")\n" + output); + } + } + + /** + * Adds a service tag to this registry. + * If the given service tag has an empty instance_urn, + * this helper class will generate a URN and place it in the + * copy of the service tag in this registry. + * This method will return the {@code ServiceTag} representing + * the service tag entry to this registry. + * + * @param st {@code ServiceTag} object + * @return a {@code ServiceTag} object representing the service tag + * entry to this registry. + * + * @throws IllegalArgumentException if a service tag of the same + * instance_urn already exists in this registry. + * + * @throws java.io.IOException if an I/O error occurs in this operation. + */ + public ServiceTag addServiceTag(ServiceTag st) throws IOException { + List command = getCommandList(); + command.add("-a"); + if (st.getInstanceURN().length() > 0) { + ServiceTag sysSvcTag = getServiceTag(st.getInstanceURN()); + if (sysSvcTag != null) { + throw new IllegalArgumentException("Instance_urn = " + + st.getInstanceURN() + " already exists"); + } + command.add("-i"); + command.add(st.getInstanceURN()); + } + command.add("-p"); + command.add(st.getProductName()); + command.add("-e"); + command.add(st.getProductVersion()); + command.add("-t"); + command.add(st.getProductURN()); + if (st.getProductParentURN().length() > 0) { + command.add("-F"); + command.add(st.getProductParentURN()); + } + command.add("-P"); + command.add(st.getProductParent()); + if (st.getProductDefinedInstanceID().length() > 0) { + command.add("-I"); + command.add(st.getProductDefinedInstanceID()); + } + command.add("-m"); + command.add(st.getProductVendor()); + command.add("-A"); + command.add(st.getPlatformArch()); + command.add("-z"); + command.add(st.getContainer()); + command.add("-S"); + command.add(st.getSource()); + + BufferedReader in = null; + try { + ProcessBuilder pb = new ProcessBuilder(command); + Process p = pb.start(); + String output = commandOutput(p); + if (isVerbose()) { + System.out.println("Output from stclient -a command:"); + System.out.println(output); + } + String urn = ""; + if (p.exitValue() == 0) { + // Obtain the instance urn from the stclient output + in = new BufferedReader(new StringReader(output)); + String line = null; + while ((line = in.readLine()) != null) { + line = line.trim(); + if (line.startsWith(INSTANCE_URN_DESC)) { + urn = line.substring(INSTANCE_URN_DESC.length()); + break; + } + } + if (urn.length() == 0) { + throw new IOException("Error in creating service tag:\n" + + output); + } + return getServiceTag(urn); + } else { + return checkReturnError(p.exitValue(), output, st); + } + } finally { + if (in != null) { + in.close(); + } + } + } + + /** + * Removes a service tag of the given instance_urn from this + * registry. + * + * @param instanceURN the instance_urn of the service tag + * to be removed. + * + * @return the {@code ServiceTag} object removed from this registry; + * or {@code null} if the service tag does not exist in this registry. + * + * @throws UnauthorizedAccessException if the user is not authorized to + * remove the service tag of the given instance_urn + * from this registry. + * + * @throws java.io.IOException if an I/O error occurs in this operation. + */ + public ServiceTag removeServiceTag(String instanceURN) throws IOException { + ServiceTag st = getServiceTag(instanceURN); + if (st == null) { + return null; + } + + List command = getCommandList(); + command.add("-d"); + command.add("-i"); + command.add(instanceURN); + + ProcessBuilder pb = new ProcessBuilder(command); + Process p = pb.start(); + String output = commandOutput(p); + if (isVerbose()) { + System.out.println("Output from stclient -d command:"); + System.out.println(output); + } + if (p.exitValue() == 0) { + return st; + } else { + return checkReturnError(p.exitValue(), output, st); + } + } + + /** + * Updates the product_defined_instance_id in the service tag + * of the specified instance_urn in this registry. + * + * @param instanceURN the instance_urn of the service tag to be updated. + * @param productDefinedInstanceID the value of the + * product_defined_instance_id to be set. + * + * @return the updated {@code ServiceTag} object; + * or {@code null} if the service tag does not exist in this + * registry. + * + * @throws UnauthorizedAccessException if the user is not authorized to + * update the service tag from this registry. + * + * @throws IOException if an I/O error occurs in this operation. + */ + public ServiceTag updateServiceTag(String instanceURN, + String productDefinedInstanceID) + throws IOException { + ServiceTag svcTag = getServiceTag(instanceURN); + if (svcTag == null) { + return null; + } + + List command = getCommandList(); + command.add("-u"); + command.add("-i"); + command.add(instanceURN); + command.add("-I"); + if (productDefinedInstanceID.length() > 0) { + command.add(productDefinedInstanceID); + } else { + command.add("\"\""); + } + + ProcessBuilder pb = new ProcessBuilder(command); + Process p = pb.start(); + String output = commandOutput(p); + if (isVerbose()) { + System.out.println("Output from stclient -u command:"); + System.out.println(output); + } + + if (p.exitValue() == 0) { + return getServiceTag(instanceURN); + } else { + return checkReturnError(p.exitValue(), output, svcTag); + } + } + + /** + * Returns a {@code ServiceTag} object of the given instance_urn + * in this registry. + * + * @param instanceURN the instance_urn of the service tag + * @return a {@code ServiceTag} object of the given instance_urn + * in this registry; or {@code null} if not found. + * + * @throws java.io.IOException if an I/O error occurs in this operation. + */ + public ServiceTag getServiceTag(String instanceURN) throws IOException { + if (instanceURN == null) { + throw new NullPointerException("instanceURN is null"); + } + + List command = getCommandList(); + command.add("-g"); + command.add("-i"); + command.add(instanceURN); + + ProcessBuilder pb = new ProcessBuilder(command); + Process p = pb.start(); + String output = commandOutput(p); + if (isVerbose()) { + System.out.println("Output from stclient -g command:"); + System.out.println(output); + } + if (p.exitValue() == 0) { + return parseServiceTag(output); + } else { + return checkReturnError(p.exitValue(), output, null); + } + } + + private ServiceTag parseServiceTag(String output) throws IOException { + BufferedReader in = null; + try { + Properties props = new Properties(); + // parse the service tag output from stclient + in = new BufferedReader(new StringReader(output)); + String line = null; + while ((line = in.readLine()) != null) { + if ((line = line.trim()).length() > 0) { + String[] ss = line.trim().split("=", 2); + if (ss.length == 2) { + props.setProperty(ss[0].trim(), ss[1].trim()); + } else { + props.setProperty(ss[0].trim(), ""); + } + } + } + + String urn = props.getProperty(ST_NODE_INSTANCE_URN); + String productName = props.getProperty(ST_NODE_PRODUCT_NAME); + String productVersion = props.getProperty(ST_NODE_PRODUCT_VERSION); + String productURN = props.getProperty(ST_NODE_PRODUCT_URN); + String productParent = props.getProperty(ST_NODE_PRODUCT_PARENT); + String productParentURN = props.getProperty(ST_NODE_PRODUCT_PARENT_URN); + String productDefinedInstanceID = + props.getProperty(ST_NODE_PRODUCT_DEFINED_INST_ID); + String productVendor = props.getProperty(ST_NODE_PRODUCT_VENDOR); + String platformArch = props.getProperty(ST_NODE_PLATFORM_ARCH); + String container = props.getProperty(ST_NODE_CONTAINER); + String source = props.getProperty(ST_NODE_SOURCE); + int installerUID = + Util.getIntValue(props.getProperty(ST_NODE_INSTALLER_UID)); + Date timestamp = + Util.parseTimestamp(props.getProperty(ST_NODE_TIMESTAMP)); + + return new ServiceTag(urn, + productName, + productVersion, + productURN, + productParent, + productParentURN, + productDefinedInstanceID, + productVendor, + platformArch, + container, + source, + installerUID, + timestamp); + } finally { + if (in != null) { + in.close(); + } + } + + } + + /** + * Returns the service tags of the specified + * product_urn in this registry. + * + * @param productURN the product_urn to look up + * @return a {@code Set} of {@code ServiceTag} objects + * of the specified product_urn in this registry. + * + * @throws java.io.IOException if an I/O error occurs in this operation. + */ + public Set findServiceTags(String productURN) throws IOException { + if (productURN == null) { + throw new NullPointerException("productURN is null"); + } + + List command = getCommandList(); + command.add("-f"); + command.add("-t"); + command.add(productURN); + + BufferedReader in = null; + try { + ProcessBuilder pb = new ProcessBuilder(command); + Process p = pb.start(); + String output = commandOutput(p); + + Set instances = new HashSet(); + if (p.exitValue() == 0) { + // parse the service tag output from stclient + in = new BufferedReader(new StringReader(output)); + String line = null; + while ((line = in.readLine()) != null) { + String s = line.trim(); + if (s.startsWith("urn:st:")) { + instances.add(getServiceTag(s)); + } + } + } else { + checkReturnError(p.exitValue(), output, null); + } + return instances; + } finally { + if (in != null) { + in.close(); + } + } + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/ServiceTag.java b/desktop/source/registration/com/sun/star/servicetag/ServiceTag.java new file mode 100644 index 000000000000..4b2be9ff8cc2 --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/ServiceTag.java @@ -0,0 +1,640 @@ +/************************************************************************* + * + * 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: ServiceTag.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.util.Date; +import java.io.IOException; +import static com.sun.star.servicetag.RegistrationDocument.*; + +/** + * A service tag is an XML-based data structure that identifies a product or + * a component on a system. The service tag schema is defined by the + * Service Tags Technology. The location of the DTD file is platform dependent. + * On Solaris, see /usr/share/lib/xml/dtd/servicetag.dtd. + *

+ * A valid {@code ServiceTag} instance must comply to the service tag schema + * and contain the following fields: + *

    + *
  • {@link #getInstanceURN instance_urn}
  • + *
  • {@link #getProductName product_name}
  • + *
  • {@link #getProductVersion product_version}
  • + *
  • {@link #getProductURN product_urn}
  • + *
  • {@link #getProductParent product_parent}
  • + *
  • {@link #getProductParentURN product_parent_urn}
  • + *
  • {@link #getProductDefinedInstanceID product_defined_inst_id}
  • + *
  • {@link #getProductVendor product_vendor}
  • + *
  • {@link #getPlatformArch platform_arch}
  • + *
  • {@link #getContainer container}
  • + *
  • {@link #getSource source}
  • + *
  • {@link #getInstallerUID installer_uid}
  • + *
  • {@link #getTimestamp timestamp}
  • + *
+ * + * The instance_urn can be specified when a {@code ServiceTag} + * object is created, or it can be generated when it is added to + * a {@link RegistrationData} object, or {@link Registry + * system service tag registry}. The installer_uid and + * timestamp are set when a {@code ServiceTag} object + * is added to a {@link RegistrationData} object, or {@link Registry + * system service tag registry}. + * + * @see Service Tags FAQ + */ +public class ServiceTag { + + private String instanceURN; + private String productName; + private String productVersion; + private String productURN; + private String productParent; + private String productParentURN; + private String productDefinedInstanceID; + private String productVendor; + private String platformArch; + private String container; + private String source; + private int installerUID; + private Date timestamp; + + // Service Tag Field Lengths (defined in sthelper.h) + // Since the constants defined in sthelper.h includes the null-terminated + // character, so minus 1 from the sthelper.h defined values. + private final int MAX_URN_LEN = 256 - 1; + private final int MAX_PRODUCT_NAME_LEN = 256 - 1; + private final int MAX_PRODUCT_VERSION_LEN = 64 - 1; + private final int MAX_PRODUCT_PARENT_LEN = 256 - 1; + private final int MAX_PRODUCT_VENDOR_LEN = 64 - 1; + private final int MAX_PLATFORM_ARCH_LEN = 64 - 1; + private final int MAX_CONTAINER_LEN = 64 - 1; + private final int MAX_SOURCE_LEN = 64 - 1; + + // private constructors + private ServiceTag() { + } + // package private + ServiceTag(String instanceURN, + String productName, + String productVersion, + String productURN, + String productParent, + String productParentURN, + String productDefinedInstanceID, + String productVendor, + String platformArch, + String container, + String source, + int installerUID, + Date timestamp) { + setInstanceURN(instanceURN); + setProductName(productName); + setProductVersion(productVersion); + setProductURN(productURN); + setProductParentURN(productParentURN); + setProductParent(productParent); + setProductDefinedInstanceID(productDefinedInstanceID); + setProductVendor(productVendor); + setPlatformArch(platformArch); + setContainer(container); + setSource(source); + setInstallerUID(installerUID); + setTimestamp(timestamp); + } + + /** + * Creates a service tag object with no instance_urn. + * + * @param productName the name of the product. + * @param productVersion the version of the product. + * @param productURN the uniform resource name of the product + * @param productParent the name of the product's parent. + * @param productParentURN the uniform resource name of the product's parent. + * @param productDefinedInstanceID the instance identifier. + * @param productVendor the vendor of the product. + * @param platformArch the operating system architecture. + * @param container the container of the product. + * @param source the source of the product. + * + * @throws IllegalArgumentException if any value of the input fields + * does not conform to the service tag XML schema. + */ + public static ServiceTag newInstance(String productName, + String productVersion, + String productURN, + String productParent, + String productParentURN, + String productDefinedInstanceID, + String productVendor, + String platformArch, + String container, + String source) { + return new ServiceTag("", /* empty instance_urn */ + productName, + productVersion, + productURN, + productParent, + productParentURN, + productDefinedInstanceID, + productVendor, + platformArch, + container, + source, + -1, + null); + } + + /** + * Creates a service tag object with a specified instance_urn. + * + * @param instanceURN the uniform resource name of this instance. + * @param productName the name of the product. + * @param productVersion the version of the product. + * @param productURN the uniform resource name of the product + * @param productParent the name of the product's parent. + * @param productParentURN the uniform resource name of the product's parent. + * @param productDefinedInstanceID the instance identifier. + * @param productVendor the vendor of the product. + * @param platformArch the operating system architecture. + * @param container the container of the product. + * @param source the source of the product. + * + * @throws IllegalArgumentException if any value of the input fields + * does not conform to the service tag XML schema. + */ + public static ServiceTag newInstance(String instanceURN, + String productName, + String productVersion, + String productURN, + String productParent, + String productParentURN, + String productDefinedInstanceID, + String productVendor, + String platformArch, + String container, + String source) { + return new ServiceTag(instanceURN, + productName, + productVersion, + productURN, + productParent, + productParentURN, + productDefinedInstanceID, + productVendor, + platformArch, + container, + source, + -1, + null); + } + + // Creates a copy of the ServiceTag instance + // with instance_urn and timestamp initialized + static ServiceTag newInstanceWithUrnTimestamp(ServiceTag st) { + String instanceURN = + (st.getInstanceURN().length() == 0 ? Util.generateURN() : + st.getInstanceURN()); + ServiceTag svcTag = new ServiceTag(instanceURN, + st.getProductName(), + st.getProductVersion(), + st.getProductURN(), + st.getProductParent(), + st.getProductParentURN(), + st.getProductDefinedInstanceID(), + st.getProductVendor(), + st.getPlatformArch(), + st.getContainer(), + st.getSource(), + st.getInstallerUID(), + new Date()); + return svcTag; + } + + /** + * Returns a uniform resource name (URN) in this format: + *
+ * "urn:st:<32-char {@link java.util.UUID uuid}>" + *
+ * @return a URN. + */ + public static String generateInstanceURN() { + return Util.generateURN(); + } + + /** + * Returns the uniform resource name of this service tag instance. + * + * @return the instance_urn of this service tag. + */ + public String getInstanceURN() { + return instanceURN; + } + + /** + * Returns the name of the product. + * + * @return the product name. + */ + public String getProductName() { + return productName; + } + + /** + * Returns the version of the product. + * + * @return the product version. + */ + public String getProductVersion() { + return productVersion; + } + + /** + * Returns the uniform resource name of the product. + * + * @return the product URN. + */ + public String getProductURN() { + return productURN; + } + + /** + * Returns the uniform resource name of the product's parent. + * + * @return the product's parent URN. + */ + public String getProductParentURN() { + return productParentURN; + } + + /** + * Returns the name of the product's parent. + * + * @return the product's parent name. + */ + public String getProductParent() { + return productParent; + } + + /** + * Returns the identifier defined for this product instance. + * + * @return the identifier defined for this product instance. + */ + public String getProductDefinedInstanceID() { + return productDefinedInstanceID; + } + + /** + * Returns the vendor of the product. + * + * @return the product vendor. + */ + public String getProductVendor() { + return productVendor; + } + + /** + * Returns the platform architecture on which the product + * is running on. + * + * @return the platform architecture on which the product is running on. + */ + public String getPlatformArch() { + return platformArch; + } + + /** + * Returns the timestamp. This timestamp is set when this service tag + * is added to or updated in a {@code RegistrationData} object or + * the system service tag registry. + * This method may return {@code null}. + * + * @return timestamp when this service tag + * is added to or updated in a {@code RegistrationData} object or + * the system service tag registry, or {@code null}. + */ + public Date getTimestamp() { + if (timestamp != null) { + return (Date) timestamp.clone(); + } else { + return null; + } + } + + + /** + * Returns the container of the product. + * + * @return the container of the product. + */ + public String getContainer() { + return container; + } + + /** + * Returns the source of this service tag. + * + * @return source of this service tag. + */ + public String getSource() { + return source; + } + + /** + * Returns the UID. The UID is set when this service tag + * is added to or updated in the system service tag registry. + * This is platform dependent whose default value is {@code -1}. + * When this service tag is added to a {@code RegistrationData}, + * the UID is not set. + * + * @return the UID of whom this service tag + * is added to or updated in the system service tag registry, + * or {@code -1}. + */ + public int getInstallerUID() { + return installerUID; + } + + // The following setter methods are used to validate the + // input field when constructing a ServiceTag instance + + private void setInstanceURN(String instanceURN) { + if (instanceURN == null) { + throw new NullPointerException("Parameter instanceURN cannot be null"); + } + if (instanceURN.length() > MAX_URN_LEN) { + throw new IllegalArgumentException("instanceURN \"" + instanceURN + + "\" exceeds maximum length " + MAX_URN_LEN); + } + this.instanceURN = instanceURN; + } + + private void setProductName(String productName) { + if (productName == null) { + throw new NullPointerException("Parameter productName cannot be null"); + } + if (productName.length() == 0) { + throw new IllegalArgumentException("product name cannot be empty"); + } + if (productName.length() > MAX_PRODUCT_NAME_LEN) { + throw new IllegalArgumentException("productName \"" + productName + + "\" exceeds maximum length " + MAX_PRODUCT_NAME_LEN); + } + this.productName = productName; + } + + private void setProductVersion(String productVersion) { + if (productVersion == null) { + throw new NullPointerException("Parameter productVersion cannot be null"); + } + + if (productVersion.length() == 0) { + throw new IllegalArgumentException("product version cannot be empty"); + } + if (productVersion.length() > MAX_PRODUCT_VERSION_LEN) { + throw new IllegalArgumentException("productVersion \"" + + productVersion + "\" exceeds maximum length " + + MAX_PRODUCT_VERSION_LEN); + } + this.productVersion = productVersion; + } + + private void setProductURN(String productURN) { + if (productURN == null) { + throw new NullPointerException("Parameter productURN cannot be null"); + } + if (productURN.length() == 0) { + throw new IllegalArgumentException("product URN cannot be empty"); + } + if (productURN.length() > MAX_URN_LEN) { + throw new IllegalArgumentException("productURN \"" + productURN + + "\" exceeds maximum length " + MAX_URN_LEN); + } + this.productURN = productURN; + } + + private void setProductParentURN(String productParentURN) { + if (productParentURN == null) { + throw new NullPointerException("Parameter productParentURN cannot be null"); + } + // optional field - can be empty + if (productParentURN.length() > MAX_URN_LEN) { + throw new IllegalArgumentException("productParentURN \"" + + productParentURN + "\" exceeds maximum length " + + MAX_URN_LEN); + } + this.productParentURN = productParentURN; + } + + private void setProductParent(String productParent) { + if (productParent == null) { + throw new NullPointerException("Parameter productParent cannot be null"); + } + if (productParent.length() == 0) { + throw new IllegalArgumentException("product parent cannot be empty"); + } + if (productParent.length() > MAX_PRODUCT_PARENT_LEN) { + throw new IllegalArgumentException("productParent \"" + + productParent + "\" exceeds maximum length " + + MAX_PRODUCT_PARENT_LEN); + } + this.productParent = productParent; + } + + void setProductDefinedInstanceID(String productDefinedInstanceID) { + if (productDefinedInstanceID == null) { + throw new NullPointerException("Parameter productDefinedInstanceID cannot be null"); + } + if (productDefinedInstanceID.length() > MAX_URN_LEN) { + throw new IllegalArgumentException("productDefinedInstanceID \"" + + productDefinedInstanceID + "\" exceeds maximum length " + + MAX_URN_LEN); + } + // optional field - can be empty + this.productDefinedInstanceID = productDefinedInstanceID; + } + + private void setProductVendor(String productVendor) { + if (productVendor == null) { + throw new NullPointerException("Parameter productVendor cannot be null"); + } + if (productVendor.length() == 0) { + throw new IllegalArgumentException("product vendor cannot be empty"); + } + if (productVendor.length() > MAX_PRODUCT_VENDOR_LEN) { + throw new IllegalArgumentException("productVendor \"" + + productVendor + "\" exceeds maximum length " + + MAX_PRODUCT_VENDOR_LEN); + } + this.productVendor = productVendor; + } + + private void setPlatformArch(String platformArch) { + if (platformArch == null) { + throw new NullPointerException("Parameter platformArch cannot be null"); + } + if (platformArch.length() == 0) { + throw new IllegalArgumentException("platform architecture cannot be empty"); + } + if (platformArch.length() > MAX_PLATFORM_ARCH_LEN) { + throw new IllegalArgumentException("platformArch \"" + + platformArch + "\" exceeds maximum length " + + MAX_PLATFORM_ARCH_LEN); + } + this.platformArch = platformArch; + } + + private void setTimestamp(Date timestamp) { + // can be null + this.timestamp = timestamp; + } + + private void setContainer(String container) { + if (container == null) { + throw new NullPointerException("Parameter container cannot be null"); + } + if (container.length() == 0) { + throw new IllegalArgumentException("container cannot be empty"); + } + if (container.length() > MAX_CONTAINER_LEN) { + throw new IllegalArgumentException("container \"" + + container + "\" exceeds maximum length " + + MAX_CONTAINER_LEN); + } + this.container = container; + } + + private void setSource(String source) { + if (source == null) { + throw new NullPointerException("Parameter source cannot be null"); + } + if (source.length() == 0) { + throw new IllegalArgumentException("source cannot be empty"); + } + if (source.length() > MAX_SOURCE_LEN) { + throw new IllegalArgumentException("source \"" + source + + "\" exceeds maximum length " + MAX_SOURCE_LEN); + } + this.source = source; + } + + private void setInstallerUID(int installerUID) { + this.installerUID = installerUID; + } + + /** + * Compares this service tag to the specified object. + * The result is {@code true} if and only if the argument is + * not {@code null} and is a {@code ServiceTag} object whose + * instance_urn is the same as the + * instance_urn of this service tag. + * + * @return {@code true} if this service tag is the same as + * the specified object. + */ + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof ServiceTag)) { + return false; + } + ServiceTag st = (ServiceTag) obj; + if (st == this) { + return true; + } + return st.getInstanceURN().equals(getInstanceURN()); + } + + /** + * Returns the hash code value for this service tag. + * @return the hash code value for this service tag. + */ + @Override + public int hashCode() { + int hash = 7; + hash = 19 * hash + (this.instanceURN != null ? this.instanceURN.hashCode() : 0); + return hash; + } + + /** + * Returns the string representation of this service tag. + * The format is implementation specific. + * + * @return the string representation of this service tag. + */ + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(ST_NODE_INSTANCE_URN).append("=").append(instanceURN).append("\n"); + sb.append(ST_NODE_PRODUCT_NAME).append("=").append(productName).append("\n"); + sb.append(ST_NODE_PRODUCT_VERSION).append("=").append(productVersion).append("\n"); + sb.append(ST_NODE_PRODUCT_URN).append("=").append(productURN).append("\n"); + sb.append(ST_NODE_PRODUCT_PARENT_URN).append("=").append(productParentURN).append("\n"); + sb.append(ST_NODE_PRODUCT_PARENT).append("=").append(productParent).append("\n"); + sb.append(ST_NODE_PRODUCT_DEFINED_INST_ID).append("=").append(productDefinedInstanceID).append("\n"); + sb.append(ST_NODE_PRODUCT_VENDOR).append("=").append(productVendor).append("\n"); + sb.append(ST_NODE_PLATFORM_ARCH).append("=").append(platformArch).append("\n"); + sb.append(ST_NODE_TIMESTAMP).append("=").append(Util.formatTimestamp(timestamp)).append("\n"); + sb.append(ST_NODE_CONTAINER).append("=").append(container).append("\n"); + sb.append(ST_NODE_SOURCE).append("=").append(source).append("\n"); + sb.append(ST_NODE_INSTALLER_UID).append("=").append(String.valueOf(installerUID)).append("\n"); + return sb.toString(); + } + + + /** + * Returns the {@link ServiceTag} instance for the running Java + * platform. The {@link ServiceTag#setSource source} field + * of the {@code ServiceTag} will be set to the given {@code source}. + * This method will return {@code null} if there is no service tag + * for the running Java platform. + *

+ * This method is designed for Sun software that bundles the JDK + * or the JRE to use. It is recommended that the {@code source} + * string contains information about the bundling software + * such as the name and the version of the software bundle, + * for example, + *

+ * NetBeans IDE 6.0 with JDK 6 Update 5 Bundle + *
+ * in a NetBeans/JDK bundle. + *

+ * At the first time to call this method the application + * is required to have the write permission to the installed + * directory of this running JDK or JRE instance. + * + * @param source the source that bundles the JDK or the JRE. + * @return a {@code ServiceTag} object for the Java platform, + * or {@code null} if not supported. + * @throws IOException if an error occurs in this operation. + */ + public static ServiceTag getJavaServiceTag(String source) throws IOException { + return Installer.getJavaServiceTag(source); + } + +} diff --git a/desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java b/desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java new file mode 100644 index 000000000000..245b993b086e --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/SolarisServiceTag.java @@ -0,0 +1,68 @@ +/************************************************************************* + * + * 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: SolarisServiceTag.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.IOException; +import java.util.Set; + +/** + * Utility class to obtain the service tag for the Solaris Operating System. + */ +class SolarisServiceTag { + private final static String[] SolarisProductURNs = new String[] { + "urn:uuid:a7a38948-2bd5-11d6-98ce-9d3ac1c0cfd7", /* Solaris 8 */ + "urn:uuid:4f82caac-36f3-11d6-866b-85f428ef944e", /* Solaris 9 */ + "urn:uuid:a19de03b-48bc-11d9-9607-080020a9ed93", /* Solaris 9 sparc */ + "urn:uuid:4c35c45b-4955-11d9-9607-080020a9ed93", /* Solaris 9 x86 */ + "urn:uuid:5005588c-36f3-11d6-9cec-fc96f718e113", /* Solaris 10 */ + "urn:uuid:6df19e63-7ef5-11db-a4bd-080020a9ed93" /* Solaris 11 */ + }; + + /** + * Returns null if not found. + * + * There is only one service tag for the operating system. + */ + static ServiceTag getServiceTag() throws IOException { + if (Registry.isSupported()) { + Registry streg = Registry.getSystemRegistry(); + for (String parentURN : SolarisProductURNs) { + Set instances = streg.findServiceTags(parentURN); + for (ServiceTag st : instances) { + // there should have only one service tag for the OS + return st; + } + } + } + return null; + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java new file mode 100644 index 000000000000..1ce5f5697bcb --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/SolarisSystemEnvironment.java @@ -0,0 +1,159 @@ +/************************************************************************* + * + * 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: SolarisSystemEnvironment.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; + +// The Service Tags team maintains the latest version of the implementation +// for system environment data collection. JDK will include a copy of +// the most recent released version for a JDK release. We rename +// the package to com.sun.servicetag so that the Sun Connection +// product always uses the latest version from the com.sun.scn.servicetags +// package. JDK and users of the com.sun.servicetag API +// (e.g. NetBeans and SunStudio) will use the version in JDK. + +import java.io.*; + +/** + * Solaris implementation of the SystemEnvironment class. + */ +class SolarisSystemEnvironment extends SystemEnvironment { + SolarisSystemEnvironment() { + setHostId(getCommandOutput("/usr/bin/hostid")); + setSystemModel(getCommandOutput("/usr/bin/uname", "-i")); + setSystemManufacturer(getSolarisSystemManufacturer()); + setCpuManufacturer(getSolarisCpuManufacturer()); + setSerialNumber(getSolarisSN()); + } + + /** + * Tries to obtain the cpu manufacturer. + * @return The cpu manufacturer (an empty string if not found or an error occurred) + */ + private String getSolarisCpuManufacturer() { + // not fully accurate, this could be another manufacturer (fujitsu for example) + if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) { + return "Sun Microsystems, Inc"; + } + + // if we're here, then we'll try smbios (type 3) + return getSmbiosData("3", "Manufacturer: "); + } + + /** + * Tries to obtain the system manufacturer. + * @return The system manufacturer (an empty string if not found or an error occurred) + */ + private String getSolarisSystemManufacturer() { + // not fully accurate, this could be another manufacturer (fujitsu for example) + if ("sparc".equalsIgnoreCase(System.getProperty("os.arch"))) { + return "Sun Microsystems, Inc"; + } + + // if we're here, then we'll try smbios (type 1) + return getSmbiosData("1", "Manufacturer: "); + } + + /** + * Tries to obtain the serial number. + * @return The serial number (empty string if not found or an error occurred) + */ + private String getSolarisSN() { + // try to read from the psn file if it exists + String tmp = getFileContent("/var/run/psn"); + if (tmp.length() > 0) { + return tmp.trim(); + } + + // if we're here, then we'll try sneep + String tmpSN = getSneepSN(); + if (tmpSN.length() > 0) { + return tmpSN; + } + + // if we're here, then we'll try smbios (type 1) + tmpSN = getSmbiosData("1", "Serial Number: "); + if (tmpSN.length() > 0) { + return tmpSN; + } + + // if we're here, then we'll try smbios (type 3) + tmpSN = getSmbiosData("3", "Serial Number: "); + if (tmpSN.length() > 0) { + return tmpSN; + } + + // give up and return + return ""; + } + + // Sample smbios output segment: + // ID SIZE TYPE + // 1 150 SMB_TYPE_SYSTEM (system information) + // + // Manufacturer: Sun Microsystems + // Product: Sun Fire X4600 + // Version: To Be Filled By O.E.M. + // Serial Number: 00:14:4F:45:0C:2A + private String getSmbiosData(String type, String target) { + String output = getCommandOutput("/usr/sbin/smbios", "-t", type); + for (String s : output.split("\n")) { + if (s.contains(target)) { + int indx = s.indexOf(target) + target.length(); + if (indx < s.length()) { + String tmp = s.substring(indx).trim(); + String lowerCaseStr = tmp.toLowerCase(); + if (!lowerCaseStr.startsWith("not available") + && !lowerCaseStr.startsWith("to be filled by o.e.m")) { + return tmp; + } + } + } + } + + return ""; + } + + private String getSneepSN() { + String basedir = getCommandOutput("pkgparam","SUNWsneep","BASEDIR"); + File f = new File(basedir + "/bin/sneep"); + if (f.exists()) { + String sneepSN = getCommandOutput(basedir + "/bin/sneep"); + if (sneepSN.equalsIgnoreCase("unknown")) { + return ""; + } else { + return sneepSN; + } + } else { + return ""; + } + } + +} diff --git a/desktop/source/registration/com/sun/star/servicetag/SunConnection.java b/desktop/source/registration/com/sun/star/servicetag/SunConnection.java new file mode 100644 index 000000000000..4a3d2ee9722f --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/SunConnection.java @@ -0,0 +1,296 @@ +/************************************************************************* + * + * 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: SunConnection.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.net.URISyntaxException; +import java.net.URL; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.io.OutputStreamWriter; +import java.util.Locale; +import javax.net.ssl.HttpsURLConnection; + +/** + * Sun Connection Class for Product Registration. + * + * Registration Web Application Interface + * 1) POST the product registry to the output stream of the registration + * relay service. + * 2) Open the webapp URL from a browser with the following parameters: + * registry-urn + * product=jdk + * locale= + * + * @see https://sn-tools.central.sun.com/twiki/pub/ServiceTags/RegistrationRelayService/ + * + */ +class SunConnection { + + private static String JDK_REGISTRATION_URL = + "https://inventory.sun.com/RegistrationWeb/register"; + private static String SANDBOX_TESTING_URL = + "https://connection-tst.sun.com/RegistrationWeb/register"; + + // System properties for testing + private static String SVCTAG_REGISTER_TESTING = "servicetag.register.testing"; + private static String SVCTAG_REGISTRATION_URL = "servicetag.registration.url"; + private static String SVCTAG_CONNECTION_TIMEOUT = "servicetag.connection.timeout"; + + private SunConnection() { + } + + /** + * Returns a URL for JDK registration interfacing with the Sun Connection + * registration relay service in this form: + * /?product=jdk&locale= + * + * The can be overridden by an environment + * variable or a system property. + * + * 1) "servicetag.register.testing" system property to switch to the + * Sun Connection registration sandbox testing. + * 2) "servicetag.registration.url" system property to override + * the URL + * 3) Default production URL + * + */ + static URL getRegistrationURL(String registrationURN) { + String url = System.getProperty(SVCTAG_REGISTRATION_URL); + if (url == null) { + if (System.getProperty(SVCTAG_REGISTER_TESTING) != null) { + url = SANDBOX_TESTING_URL; + } else { + url = JDK_REGISTRATION_URL; + } + } + + // trim whitespaces + url = url.trim(); + if (url.length() == 0) { + throw new InternalError("Empty registration url set"); + } + + // Add the registry_urn in the URL's query + String registerURL = rewriteURL(url, registrationURN); + try { + return new URL(registerURL); + } catch (MalformedURLException ex) { + // should never reach here + InternalError x = + new InternalError(ex.getMessage()); + x.initCause(ex); + throw x; + } + } + + private static String rewriteURL(String url, String registryURN) { + StringBuilder sb = new StringBuilder(url.trim()); + int len = sb.length(); + if (sb.charAt(len-1) != '/') { + sb.append('/'); + } + sb.append(registryURN); + sb.append("?"); + sb.append("product=jdk"); + sb.append("&"); + sb.append("locale=").append(Locale.getDefault().getLanguage()); + return sb.toString(); + } + + /** + * Registers all products in the given product registry. If it fails + * to post the service tag registry, open the browser with the offline + * registration page. + * + * @param regData registration data to be posted to the Sun Connection + * for registration. + * + * @throws IOException if I/O error occurs in this operation + */ + public static void register(RegistrationData regData) throws IOException { + // Gets the URL for SunConnection registration relay service + URL url = getRegistrationURL(regData.getRegistrationURN()); + + // Post the Product Registry to Sun Connection + boolean succeed = postRegistrationData(url, regData); + if (succeed) { + // service tags posted successfully + // now prompt for registration + openBrowser(url); + } else { + // open browser with the offline registration page + openOfflineRegisterPage(); + } + } + + /** + * Opens a browser for JDK product registration. + * @param url Registration Webapp URL + */ + private static void openBrowser(URL url) throws IOException { + if (!BrowserSupport.isSupported()) { + if (Util.isVerbose()) { + System.out.println("Browser is not supported"); + } + return; + } + + try { + BrowserSupport.browse(url.toURI()); + } catch (URISyntaxException ex) { + InternalError x = new InternalError("Error in registering: " + ex.getMessage()); + x.initCause(ex); + throw x; + } catch (IllegalArgumentException ex) { + if (Util.isVerbose()) { + ex.printStackTrace(); + } + } catch (UnsupportedOperationException ex) { + // ignore if not supported + if (Util.isVerbose()) { + ex.printStackTrace(); + } + } + } + + /** + * POST service tag registry to Sun Connection + * @param loc the URL of the webapp to handle the POST request + * @param streg the Service Tag registry + * @return true if posting succeeds; otherwise, false. + */ + private static boolean postRegistrationData(URL url, + RegistrationData registration) { + try { + HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); + con.setDoInput(true); + con.setDoOutput(true); + con.setUseCaches(false); + con.setAllowUserInteraction(false); + + // default 10 seconds timeout + String timeout = System.getProperty(SVCTAG_CONNECTION_TIMEOUT, "10"); + con.setConnectTimeout(Util.getIntValue(timeout) * 1000); + + if (Util.isVerbose()) { + System.out.println("Connecting to post registration data at " + url); + } + + con.setRequestMethod("POST"); + con.setRequestProperty("Content-Type", "text/xml;charset=\"utf-8\""); + con.connect(); + + OutputStream out = con.getOutputStream(); + registration.storeToXML(out); + out.flush(); + out.close(); + + int returnCode = con.getResponseCode(); + if (Util.isVerbose()) { + System.out.println("POST return status = " + returnCode); + printReturnData(con, returnCode); + } + return (returnCode == HttpURLConnection.HTTP_OK); + } catch (MalformedURLException me) { + // should never reach here + InternalError x = new InternalError("Error in registering: " + me.getMessage()); + x.initCause(me); + throw x; + } catch (Exception ioe) { + // SocketTimeoutException, IOException or UnknownHostException + if (Util.isVerbose()) { + ioe.printStackTrace(); + } + return false; + } + } + + /** + * Opens the offline registratioin page in the browser. + * + */ + private static void openOfflineRegisterPage() + throws IOException { + if (!BrowserSupport.isSupported()) { + if (Util.isVerbose()) { + System.out.println("Browser is not supported"); + } + return; + } + + File registerPage = Installer.getRegistrationHtmlPage(); + try { + BrowserSupport.browse(registerPage.toURI()); + } catch (FileNotFoundException ex) { + // should never reach here + InternalError x = + new InternalError("Error in launching " + registerPage + ": " + ex.getMessage()); + x.initCause(ex); + throw x; + } catch (IllegalArgumentException ex) { + if (Util.isVerbose()) { + ex.printStackTrace(); + } + } catch (UnsupportedOperationException ex) { + // ignore if not supported + if (Util.isVerbose()) { + ex.printStackTrace(); + } + } + } + + private static void printReturnData(HttpURLConnection con, int returnCode) + throws IOException { + BufferedReader reader = null; + try { + if (returnCode < 400) { + reader = new BufferedReader( + new InputStreamReader(con.getInputStream())); + } else { + reader = new BufferedReader( + new InputStreamReader(con.getErrorStream())); + } + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line).append("\n"); + } + System.out.println("Response is : "); + System.out.println(sb.toString()); + } finally { + if (reader != null) { + reader.close(); + } + } + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java b/desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java new file mode 100644 index 000000000000..d50104e827ed --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java @@ -0,0 +1,380 @@ +/************************************************************************* + * + * 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: SysnetRegistryHelper.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.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import static com.sun.star.servicetag.Util.*; +import static com.sun.star.servicetag.RegistrationDocument.*; + +/** + * Class containing additional methods that are not yet + * in the JDK Registry class. Note that all methods in this class + * will be superceeded by the JDK classes. + */ +public class SysnetRegistryHelper { + + private static final String STCLIENT_SOLARIS = "/usr/bin/stclient"; + private static final String STCLIENT_LINUX = "/opt/sun/servicetag/bin/stclient"; + // stclient exit value (see sthelper.h) + private static final int ST_ERR_NOT_AUTH = 245; + private static final int ST_ERR_REC_NOT_FOUND = 225; + + // The stclient output has to be an exported interface + private static final String INSTANCE_URN_OPEN_ELEMENT = ""; + private static final String INSTANCE_URN_CLOSE_ELEMENT = ""; + private static final String REGISTRY_URN = " getCommandList() { + // Set up the arguments to call stclient + List command = new ArrayList(); + if (System.getProperty(SVCTAG_STCLIENT_CMD) != null) { + // This is for jtreg testing use. This will be set to something + // like: + // $JAVA_HOME/bin/java -cp $TEST_DIR \ + // -Dstclient.registry.path=$TEST_DIR/registry.xml \ + // SvcTagClient + // + // On Windows, the JAVA_HOME and TEST_DIR path could contain + // space e.g. c:\Program Files\Java\jdk1.6.0_05\bin\java. + // The SVCTAG_STCLIENT_CMD must be set with a list of + // space-separated parameters. If a parameter contains spaces, + // it must be quoted with '"'. + + String cmd = getSTclient(); + int len = cmd.length(); + int i = 0; + while (i < len) { + char separator = ' '; + if (cmd.charAt(i) == '"') { + separator = '"'; + i++; + } + // look for the separator or matched the closing '"' + int j; + for (j = i+1; j < len; j++) { + if (cmd.charAt(j) == separator) { + break; + } + } + + if (i == j-1) { + // add an empty parameter + command.add("\"\""); + } else { + // double quotes and space are not included + command.add(cmd.substring(i,j)); + } + + // skip spaces + for (i = j+1; i < len; i++) { + if (!Character.isSpaceChar(cmd.charAt(i))) { + break; + } + } + } + if (isVerbose()) { + System.out.println("Command list:"); + for (String s : command) { + System.out.println(s); + } + } + } else { + command.add(getSTclient()); + } + return command; + } + + // Returns null if the service tag record not found; + // or throw UnauthorizedAccessException or IOException + // based on the exitValue. + private static ServiceTag checkReturnError(int exitValue, + String output, + ServiceTag st) throws IOException { + switch (exitValue) { + case ST_ERR_REC_NOT_FOUND: + return null; + case ST_ERR_NOT_AUTH: + if (st != null) { + throw new UnauthorizedAccessException( + "Not authorized to access " + st.getInstanceURN() + + " installer_uid=" + st.getInstallerUID()); + } else { + throw new UnauthorizedAccessException( + "Not authorized:" + output); + } + default: + throw new IOException("stclient exits with error" + + " (" + exitValue + ")\n" + output); + } + } + + /** + * Returns a {@code ServiceTag} object of the given instance_urn + * in this registry. + * + * @param instanceURN the instance_urn of the service tag + * @return a {@code ServiceTag} object of the given instance_urn + * in this registry; or {@code null} if not found. + * + * @throws java.io.IOException if an I/O error occurs in this operation. + */ + private static ServiceTag getServiceTag(String instanceURN) throws IOException { + if (instanceURN == null) { + throw new NullPointerException("instanceURN is null"); + } + + List command = getCommandList(); + command.add("-g"); + command.add("-i"); + command.add(instanceURN); + + ProcessBuilder pb = new ProcessBuilder(command); + Process p = pb.start(); + String output = commandOutput(p); + if (isVerbose()) { + System.out.println("Output from stclient -g command:"); + System.out.println(output); + } + if (p.exitValue() == 0) { + return parseServiceTag(output); + } else { + return checkReturnError(p.exitValue(), output, null); + } + } + + private static ServiceTag parseServiceTag(String output) throws IOException { + BufferedReader in = null; + try { + Properties props = new Properties(); + // parse the service tag output from stclient + in = new BufferedReader(new StringReader(output)); + String line = null; + while ((line = in.readLine()) != null) { + if ((line = line.trim()).length() > 0) { + String[] ss = line.trim().split("=", 2); + if (ss.length == 2) { + props.setProperty(ss[0].trim(), ss[1].trim()); + } else { + props.setProperty(ss[0].trim(), ""); + } + } + } + + String urn = props.getProperty(ST_NODE_INSTANCE_URN); + String productName = props.getProperty(ST_NODE_PRODUCT_NAME); + String productVersion = props.getProperty(ST_NODE_PRODUCT_VERSION); + String productURN = props.getProperty(ST_NODE_PRODUCT_URN); + String productParent = props.getProperty(ST_NODE_PRODUCT_PARENT); + String productParentURN = props.getProperty(ST_NODE_PRODUCT_PARENT_URN); + String productDefinedInstanceID = + props.getProperty(ST_NODE_PRODUCT_DEFINED_INST_ID); + String productVendor = props.getProperty(ST_NODE_PRODUCT_VENDOR); + String platformArch = props.getProperty(ST_NODE_PLATFORM_ARCH); + String container = props.getProperty(ST_NODE_CONTAINER); + String source = props.getProperty(ST_NODE_SOURCE); + int installerUID = + Util.getIntValue(props.getProperty(ST_NODE_INSTALLER_UID)); + Date timestamp = + Util.parseTimestamp(props.getProperty(ST_NODE_TIMESTAMP)); + + return new ServiceTag(urn, + productName, + productVersion, + productURN, + productParent, + productParentURN, + productDefinedInstanceID, + productVendor, + platformArch, + container, + source, + installerUID, + timestamp); + } finally { + if (in != null) { + in.close(); + } + } + + } + + /** + * Returns the urn of this registry. + * + * @return a {@code String} for the urn of this registry. + * + * @throws java.io.IOException if an I/O error occurs in this operation. + */ + // Once JDK makes this method available, we'll deprecate this method + // @deprecated Use the JDK version when available. + public static String getRegistryURN() throws IOException { + List command = getCommandList(); + command.add("-x"); + + BufferedReader in = null; + try { + ProcessBuilder pb = new ProcessBuilder(command); + Process p = pb.start(); + String output = commandOutput(p); + + String registryURN = null; + if (p.exitValue() == 0) { + // parse the service tag output from stclient + in = new BufferedReader(new StringReader(output)); + String line = null; + while ((line = in.readLine()) != null) { + String s = line.trim(); + if (s.indexOf(REGISTRY_URN) != -1) { + s = s.substring(s.indexOf(REGISTRY_URN) + + REGISTRY_URN.length()); + if (s.indexOf("\"") != -1) { + s = s.substring(0, s.indexOf("\"")); + registryURN = s; + break; + } + } + } + } else { + checkReturnError(p.exitValue(), output, null); + } + return registryURN; + } finally { + if (in != null) { + in.close(); + } + } + } + + /** + * Returns all the service tags in this registry. + * + * @return a {@code Set} of {@code ServiceTag} objects + * in this registry. + * + * @throws java.io.IOException if an I/O error occurs in this operation. + */ + // Once JDK makes this method available, we'll deprecate this method + // @deprecated Use the JDK version when available. + public static Set getServiceTags() throws IOException { + List command = getCommandList(); + command.add("-x"); + + BufferedReader in = null; + try { + ProcessBuilder pb = new ProcessBuilder(command); + Process p = pb.start(); + String output = commandOutput(p); + + Set instances = new HashSet(); + if (p.exitValue() == 0) { + // parse the service tag output from stclient + in = new BufferedReader(new StringReader(output)); + String line = null; + while ((line = in.readLine()) != null) { + String s = line.trim(); + if (s.indexOf(INSTANCE_URN_OPEN_ELEMENT) != -1 + && s.indexOf(INSTANCE_URN_CLOSE_ELEMENT) != -1) { + s = s.substring(s.indexOf(INSTANCE_URN_OPEN_ELEMENT) + + INSTANCE_URN_OPEN_ELEMENT.length(), + s.indexOf(INSTANCE_URN_CLOSE_ELEMENT)); + try { + instances.add(getServiceTag(s)); + } catch (Exception e) { + } + } + } + } else { + checkReturnError(p.exitValue(), output, null); + } + return instances; + } finally { + if (in != null) { + in.close(); + } + } + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java new file mode 100644 index 000000000000..e5b9e0e3b4fe --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/SystemEnvironment.java @@ -0,0 +1,341 @@ +/************************************************************************* + * + * 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: SystemEnvironment.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; + +// The Service Tags team maintains the latest version of the implementation +// for system environment data collection. JDK will include a copy of +// the most recent released version for a JDK release. We rename +// the package to com.sun.servicetag so that the Sun Connection +// product always uses the latest version from the com.sun.scn.servicetags +// package. JDK and users of the com.sun.servicetag API +// (e.g. NetBeans and SunStudio) will use the version in JDK. + +import java.io.*; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * SystemEnvironment class collects the environment data with the + * best effort from the underlying platform. + */ +public class SystemEnvironment { + private String hostname; + private String hostId; + private String osName; + private String osVersion; + private String osArchitecture; + private String systemModel; + private String systemManufacturer; + private String cpuManufacturer; + private String serialNumber; + private static SystemEnvironment sysEnv = null; + + public static synchronized SystemEnvironment getSystemEnvironment() { + if (sysEnv == null) { + String os = System.getProperty("os.name"); + if (os.equals("SunOS")) { + sysEnv = new SolarisSystemEnvironment(); + } else if (os.equals("Linux")) { + sysEnv = new LinuxSystemEnvironment(); + } else if (os.startsWith("Windows")) { + sysEnv = new WindowsSystemEnvironment(); + } else { + sysEnv = new SystemEnvironment(); + } + } + return sysEnv; + } + + // package-private + SystemEnvironment() { + try { + this.hostname = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException ex) { + this.hostname = "Unknown host"; + } + this.hostId = ""; + this.osName = System.getProperty("os.name"); + this.osVersion = System.getProperty("os.version"); + this.osArchitecture = System.getProperty("os.arch"); + this.systemModel = ""; + this.systemManufacturer = ""; + this.cpuManufacturer = ""; + this.serialNumber = ""; + } + + + /** + * Sets the hostname. + * @param hostname The hostname to set. + */ + public void setHostname(String hostname) { + this.hostname = hostname; + } + + /** + * Sets the OS name. + * @param osName The osName to set. + */ + public void setOsName(String osName) { + this.osName = osName; + } + + /** + * Sets the OS version. + * @param osVersion The osVersion to set. + */ + public void setOsVersion(String osVersion) { + this.osVersion = osVersion; + } + + /** + * Sets the OS architecture. + * @param osArchitecture The osArchitecture to set. + */ + public void setOsArchitecture(String osArchitecture) { + this.osArchitecture = osArchitecture; + } + + /** + * Sets the system model. + * @param systemModel The systemModel to set. + */ + public void setSystemModel(String systemModel) { + this.systemModel = systemModel; + } + + /** + * Sets the system manufacturer. + * @param systemManufacturer The systemManufacturer to set. + */ + public void setSystemManufacturer(String systemManufacturer) { + this.systemManufacturer = systemManufacturer; + } + + /** + * Sets the cpu manufacturer. + * @param cpuManufacturer The cpuManufacturer to set. + */ + public void setCpuManufacturer(String cpuManufacturer) { + this.cpuManufacturer = cpuManufacturer; + } + + /** + * Sets the serial number. + * @param serialNumber The serialNumber to set. + */ + public void setSerialNumber(String serialNumber) { + this.serialNumber = serialNumber; + } + + /** + * Sets the hostid. Truncates to a max length of 16 chars. + * @param hostId The hostid to set. + */ + public void setHostId(String hostId) { + if (hostId == null || hostId.equals("null")) { + hostId = ""; + } + if (hostId.length() > 16) { + hostId = hostId.substring(0,16); + } + this.hostId = hostId; + } + + /** + * Returns the hostname. + * @return The hostname. + */ + public String getHostname() { + return hostname; + } + + /** + * Returns the osName. + * @return The osName. + */ + public String getOsName() { + return osName; + } + + /** + * Returns the osVersion. + * @return The osVersion. + */ + public String getOsVersion() { + return osVersion; + } + + /** + * Returns the osArchitecture. + * @return The osArchitecture. + */ + public String getOsArchitecture() { + return osArchitecture; + } + + /** + * Returns the systemModel. + * @return The systemModel. + */ + public String getSystemModel() { + return systemModel; + } + + /** + * Returns the systemManufacturer. + * @return The systemManufacturer. + */ + public String getSystemManufacturer() { + return systemManufacturer; + } + + /** + * Returns the serialNumber. + * @return The serialNumber. + */ + public String getSerialNumber() { + return serialNumber; + } + + /** + * Returns the hostId. + * @return The hostId. + */ + public String getHostId() { + return hostId; + } + + /** + * Returns the cpuManufacturer. + * @return The cpuManufacturer. + */ + public String getCpuManufacturer() { + return cpuManufacturer; + } + + protected String getCommandOutput(String... command) { + StringBuilder sb = new StringBuilder(); + BufferedReader br = null; + Process p = null; + try { + ProcessBuilder pb = new ProcessBuilder(command); + p = pb.start(); + p.waitFor(); + + if (p.exitValue() == 0) { + br = new BufferedReader(new InputStreamReader(p.getInputStream())); + String line = null; + while ((line = br.readLine()) != null) { + line = line.trim(); + if (line.length() > 0) { + if (sb.length() > 0) { + sb.append("\n"); + } + sb.append(line); + } + } + } + return sb.toString(); + } catch (InterruptedException ie) { + // in case the command hangs + if (p != null) { + p.destroy(); + } + return ""; + } catch (Exception e) { + // ignore exception + return ""; + } finally { + if (p != null) { + try { + p.getErrorStream().close(); + } catch (IOException e) { + // ignore + } + try { + p.getInputStream().close(); + } catch (IOException e) { + // ignore + } + try { + p.getOutputStream().close(); + } catch (IOException e) { + // ignore + } + p = null; + } + if (br != null) { + try { + br.close(); + } catch (IOException e) { + // ignore + } + } + } + } + + protected String getFileContent(String filename) { + File f = new File(filename); + if (!f.exists()) { + return ""; + } + + StringBuilder sb = new StringBuilder(); + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(f)); + String line = null; + while ((line = br.readLine()) != null) { + line = line.trim(); + if (line.length() > 0) { + if (sb.length() > 0) { + sb.append("\n"); + } + sb.append(line); + } + } + return sb.toString(); + } catch (Exception e) { + // ignore exception + return ""; + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + // ignore + } + } + } + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java b/desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java new file mode 100644 index 000000000000..785cb35777ae --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java @@ -0,0 +1,59 @@ +/************************************************************************* + * + * 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: UnauthorizedAccessException.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; + +/** + * Thrown if the user is not authorized to + * {@link Registry#updateServiceTag update} or + * {@link Registry#removeServiceTag remove} + * a service tag from a {@link Registry}. + */ +public class UnauthorizedAccessException extends RuntimeException { + + /** + * Constructs an UnauthorizedAccessException object + * without detail message. + */ + public UnauthorizedAccessException() { + } + + + /** + * Constructs an UnauthorizedAccessException object + * with the specified detail message. + * + * @param msg the detail message. + */ + public UnauthorizedAccessException(String msg) { + super(msg); + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/Util.java b/desktop/source/registration/com/sun/star/servicetag/Util.java new file mode 100644 index 000000000000..55fa097297e6 --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/Util.java @@ -0,0 +1,297 @@ +/************************************************************************* + * + * 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); + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java b/desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java new file mode 100644 index 000000000000..cdc374f4a993 --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java @@ -0,0 +1,145 @@ +/************************************************************************* + * + * 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: WindowsSystemEnvironment.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; + +// The Service Tags team maintains the latest version of the implementation +// for system environment data collection. JDK will include a copy of +// the most recent released version for a JDK release. We rename +// the package to com.sun.servicetag so that the Sun Connection +// product always uses the latest version from the com.sun.scn.servicetags +// package. JDK and users of the com.sun.servicetag API +// (e.g. NetBeans and SunStudio) will use the version in JDK. + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +/** + * Windows implementation of the SystemEnvironment class. + */ +class WindowsSystemEnvironment extends SystemEnvironment { + WindowsSystemEnvironment() { + super(); + + // run a call to make sure things are initialized + // ignore the first call result as the system may + // give inconsistent data on the first invocation ever + getWmicResult("computersystem", "get", "model"); + + setSystemModel(getWmicResult("computersystem", "get", "model")); + setSystemManufacturer(getWmicResult("computersystem", "get", "manufacturer")); + setSerialNumber(getWmicResult("bios", "get", "serialnumber")); + + String cpuMfr = getWmicResult("cpu", "get", "manufacturer"); + // this isn't as good an option, but if we couldn't get anything + // from wmic, try the processor_identifier + if (cpuMfr.length() == 0) { + String procId = System.getenv("processor_identifer"); + if (procId != null) { + String[] s = procId.split(","); + cpuMfr = s[s.length - 1].trim(); + } + } + setCpuManufacturer(cpuMfr); + + // try to remove the temp file that gets created from running wmic cmds + try { + // look in the current working directory + File f = new File("TempWmicBatchFile.bat"); + if (f.exists()) { + f.delete(); + } + } catch (Exception e) { + // ignore the exception + } + } + + + /** + * This method invokes wmic outside of the normal environment + * collection routines. + * + * An initial call to wmic can be costly in terms of time. + * + * + * Details of why the first call is costly can be found at: + * + * http://support.microsoft.com/kb/290216/en-us + * + * "When you run the Wmic.exe utility for the first time, the utility + * compiles its .mof files into the repository. To save time during + * Windows installation, this operation takes place as necessary." + * + */ + private String getWmicResult(String alias, String verb, String property) { + String res = ""; + BufferedReader in = null; + try { + ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "WMIC", alias, verb, property); + Process p = pb.start(); + // need this for executing windows commands (at least + // needed for executing wmic command) + BufferedWriter bw = new BufferedWriter( + new OutputStreamWriter(p.getOutputStream())); + bw.write(13); + bw.flush(); + bw.close(); + + p.waitFor(); + if (p.exitValue() == 0) { + in = new BufferedReader(new InputStreamReader(p.getInputStream())); + String line = null; + while ((line = in.readLine()) != null) { + line = line.trim(); + if (line.length() == 0) { + continue; + } + res = line; + } + // return the *last* line read + return res; + } + + } catch (Exception e) { + // ignore the exception + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + // ignore + } + } + } + return res.trim(); + } +} diff --git a/desktop/source/registration/com/sun/star/servicetag/makefile.mk b/desktop/source/registration/com/sun/star/servicetag/makefile.mk new file mode 100644 index 000000000000..d4ebbed2f0c4 --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/makefile.mk @@ -0,0 +1,83 @@ +#************************************************************************* +# +# 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: makefile.mk,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. +# +#************************************************************************* + +PRJNAME = setup_native +PRJ = ..$/..$/..$/..$/..$/.. +TARGET = servicetag +PACKAGE = com$/sun$/star$/servicetag + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +.IF "$(ENABLE_SVCTAGS)" == "YES" + +JARFILES = jurt.jar unoil.jar ridl.jar +JAVAFILES = \ + BrowserSupport.java \ + Installer.java \ + LinuxSystemEnvironment.java \ + RegistrationData.java \ + RegistrationDocument.java \ + Registry.java \ + ServiceTag.java \ + SolarisServiceTag.java \ + SolarisSystemEnvironment.java \ + SunConnection.java \ + SysnetRegistryHelper.java \ + SystemEnvironment.java \ + UnauthorizedAccessException.java \ + Util.java \ + WindowsSystemEnvironment.java + +JAVACLASSFILES= $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class) + +JARTARGET = $(TARGET).jar +JARCOMPRESS = TRUE +JARCLASSDIRS = $(PACKAGE) + +JAVARES= $(CLASSDIR)$/$(PACKAGE)$/resources$/product_registration.xsd + +.ENDIF # "$(ENABLE_SVCTAGS)" == "YES" + +# --- Targets ------------------------------------------------------ + + +.INCLUDE : target.mk + +.IF "$(ENABLE_SVCTAGS)" == "YES" +ALLTAR: $(JAVARES) + +$(JAVARES) : $$(@:d:d:f)$/$$(@:f) + $(MKDIRHIER) $(@:d) + $(COPY) $< $@ + +.ENDIF # "$(ENABLE_SVCTAGS)" == "YES" diff --git a/desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd b/desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd new file mode 100644 index 000000000000..e9b34417d9ae --- /dev/null +++ b/desktop/source/registration/com/sun/star/servicetag/resources/product_registration.xsd @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/desktop/util/makefile.mk b/desktop/util/makefile.mk index b04162cf0ad1..69b9c2254fe5 100644 --- a/desktop/util/makefile.mk +++ b/desktop/util/makefile.mk @@ -78,6 +78,7 @@ RESLIB1IMAGES= $(PRJ)$/res RESLIB1SRSFILES= $(SRS)$/desktop.srs \ $(SRS)$/wizard.srs +.IF "$(L10N_framework)"=="" .IF "$(GUI)" != "OS2" APP1TARGET=so$/$(TARGET) APP1NOSAL=TRUE @@ -241,10 +242,14 @@ APP5DEPN= $(APP1TARGETN) $(APP5RES) ooverinfo.rc APP5DEF= $(MISCX)$/$(TARGET).def .ENDIF # WNT +.ENDIF + # --- Targets ------------------------------------------------------------- .INCLUDE : target.mk +.IF "$(L10N_framework)"=="" + .IF "$(APP1TARGETN)"!="" $(APP1TARGETN) : $(MISC)$/binso_created.flg .ENDIF # "$(APP1TARGETN)"!="" @@ -333,3 +338,5 @@ $(BIN)$/$(TARGET).bin: $(BIN)$/$(TARGET)$(EXECPOST) $(MISC)$/binso_created.flg : @@-$(MKDIRHIER) $(BIN)$/so && $(TOUCH) $@ + +.ENDIF -- cgit