summaryrefslogtreecommitdiff
path: root/setup_native
diff options
context:
space:
mode:
Diffstat (limited to 'setup_native')
-rw-r--r--setup_native/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java380
-rw-r--r--setup_native/source/registration/com/sun/star/servicetag/SystemEnvironment.java341
-rw-r--r--setup_native/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java59
-rw-r--r--setup_native/source/registration/com/sun/star/servicetag/Util.java297
-rw-r--r--setup_native/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java145
-rw-r--r--setup_native/source/registration/com/sun/star/servicetag/resources/product_registration.xsd301
6 files changed, 1523 insertions, 0 deletions
diff --git a/setup_native/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java b/setup_native/source/registration/com/sun/star/servicetag/SysnetRegistryHelper.java
new file mode 100644
index 000000000000..d50104e827ed
--- /dev/null
+++ b/setup_native/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
+ * <http://www.openoffice.org/license.html>
+ * 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 = "<instance_urn>";
+ private static final String INSTANCE_URN_CLOSE_ELEMENT = "</instance_urn>";
+ private static final String REGISTRY_URN = "<registry urn=\"";
+ 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;
+
+ // System properties for testing
+ private static String SVCTAG_STCLIENT_CMD = "servicetag.stclient.cmd";
+ private static String SVCTAG_STHELPER_SUPPORTED = "servicetag.sthelper.supported";
+
+ 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;
+ }
+
+ private static List<String> getCommandList() {
+ // Set up the arguments to call stclient
+ List<String> command = new ArrayList<String>();
+ 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 <tt>instance_urn</tt>
+ * in this registry.
+ *
+ * @param instanceURN the <tt>instance_urn</tt> of the service tag
+ * @return a {@code ServiceTag} object of the given <tt>instance_urn</tt>
+ * 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<String> 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<String> 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<ServiceTag> getServiceTags() throws IOException {
+ List<String> command = getCommandList();
+ command.add("-x");
+
+ BufferedReader in = null;
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ Process p = pb.start();
+ String output = commandOutput(p);
+
+ Set<ServiceTag> instances = new HashSet<ServiceTag>();
+ 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/setup_native/source/registration/com/sun/star/servicetag/SystemEnvironment.java b/setup_native/source/registration/com/sun/star/servicetag/SystemEnvironment.java
new file mode 100644
index 000000000000..e5b9e0e3b4fe
--- /dev/null
+++ b/setup_native/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
+ * <http://www.openoffice.org/license.html>
+ * 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/setup_native/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java b/setup_native/source/registration/com/sun/star/servicetag/UnauthorizedAccessException.java
new file mode 100644
index 000000000000..785cb35777ae
--- /dev/null
+++ b/setup_native/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
+ * <http://www.openoffice.org/license.html>
+ * 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 <code>UnauthorizedAccessException</code> object
+ * without detail message.
+ */
+ public UnauthorizedAccessException() {
+ }
+
+
+ /**
+ * Constructs an <code>UnauthorizedAccessException</code> object
+ * with the specified detail message.
+ *
+ * @param msg the detail message.
+ */
+ public UnauthorizedAccessException(String msg) {
+ super(msg);
+ }
+}
diff --git a/setup_native/source/registration/com/sun/star/servicetag/Util.java b/setup_native/source/registration/com/sun/star/servicetag/Util.java
new file mode 100644
index 000000000000..55fa097297e6
--- /dev/null
+++ b/setup_native/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
+ * <http://www.openoffice.org/license.html>
+ * 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
+ // <HOME>/jre/lib and <HOME>/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() {
+ // <HOME>/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]][-<identifer>]-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/setup_native/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java b/setup_native/source/registration/com/sun/star/servicetag/WindowsSystemEnvironment.java
new file mode 100644
index 000000000000..cdc374f4a993
--- /dev/null
+++ b/setup_native/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
+ * <http://www.openoffice.org/license.html>
+ * 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.
+ *
+ * <code>
+ * 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."
+ * </code>
+ */
+ 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/setup_native/source/registration/com/sun/star/servicetag/resources/product_registration.xsd b/setup_native/source/registration/com/sun/star/servicetag/resources/product_registration.xsd
new file mode 100644
index 000000000000..e9b34417d9ae
--- /dev/null
+++ b/setup_native/source/registration/com/sun/star/servicetag/resources/product_registration.xsd
@@ -0,0 +1,301 @@
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+<xs:element name="registration_data">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="environment"
+ minOccurs="1"
+ maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="hostname"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="hostId"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="osName"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="osVersion"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="osArchitecture"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="systemModel"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="systemManufacturer"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="cpuManufacturer"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="serialNumber"
+ minOccurs='1'
+ maxOccurs='1'/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="registry"
+ minOccurs="1"
+ maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="service_tag"
+ minOccurs="0"
+ maxOccurs="1024">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="instance_urn"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_name"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_version"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_urn"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_parent_urn"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_parent"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_defined_inst_id"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="product_vendor"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="platform_arch"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="timestamp"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="container"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="source"
+ minOccurs='1'
+ maxOccurs='1'/>
+ <xs:element ref="installer_uid"
+ minOccurs='1'
+ maxOccurs='1'/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="urn"
+ type="xs:string"
+ use="required"/>
+ <xs:attribute name="version"
+ type="xs:string"
+ use="required"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="version"
+ type="xs:string"
+ use="required"/>
+ </xs:complexType>
+</xs:element>
+
+ <!-- definition of simple elements -->
+ <xs:element name="hostname">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="hostId">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="16"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="osName">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="osVersion">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="osArchitecture">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="systemModel">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="systemManufacturer">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="cpuManufacturer">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="50"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="serialNumber">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="256"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="instance_urn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_name">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_version">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_urn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_parent_urn">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_parent">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_defined_inst_id">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="0"/>
+ <xs:maxLength value="255"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="product_vendor">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="platform_arch">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="timestamp">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="24"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="container">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="source">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:maxLength value="63"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+ <xs:element name="installer_uid">
+ <xs:simpleType>
+ <xs:restriction base="xs:integer">
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+
+</xs:schema>