]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.project/src/org/simantics/project/management/install/InstallDescriptionParser.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.project / src / org / simantics / project / management / install / InstallDescriptionParser.java
diff --git a/bundles/org.simantics.project/src/org/simantics/project/management/install/InstallDescriptionParser.java b/bundles/org.simantics.project/src/org/simantics/project/management/install/InstallDescriptionParser.java
new file mode 100644 (file)
index 0000000..567f48a
--- /dev/null
@@ -0,0 +1,251 @@
+/*******************************************************************************\r
+ *  Copyright (c) 2007, 2010 IBM Corporation and others.\r
+ *  All rights reserved. This program and the accompanying materials\r
+ *  are made available under the terms of the Eclipse Public License v1.0\r
+ *  which accompanies this distribution, and is available at\r
+ *  http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ *  Contributors:\r
+ *     IBM Corporation - initial API and implementation\r
+ *     Code 9 - ongoing development\r
+ *     Sonatype, Inc. - ongoing development\r
+ *******************************************************************************/\r
+package org.simantics.project.management.install;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.StringTokenizer;\r
+\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.SubMonitor;\r
+import org.eclipse.core.runtime.URIUtil;\r
+import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;\r
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;\r
+import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;\r
+import org.eclipse.equinox.internal.p2.repository.Transport;\r
+import org.eclipse.equinox.internal.provisional.p2.installer.InstallDescription;\r
+import org.eclipse.equinox.p2.core.IProvisioningAgent;\r
+import org.eclipse.equinox.p2.metadata.IVersionedId;\r
+import org.eclipse.equinox.p2.metadata.VersionedId;\r
+import org.simantics.project.internal.Activator;\r
+\r
+/**\r
+ * This class is responsible for loading install descriptions from a stream.\r
+ */\r
+@SuppressWarnings("restriction")\r
+public class InstallDescriptionParser {\r
+       private static final String PROP_AGENT_LOCATION = "eclipse.p2.agentLocation"; //$NON-NLS-1$\r
+       private static final String PROP_ARTIFACT_REPOSITORY = "eclipse.p2.artifacts";//$NON-NLS-1$\r
+       private static final String PROP_BUNDLE_LOCATION = "eclipse.p2.bundleLocation";//$NON-NLS-1$\r
+       private static final String PROP_INSTALL_LOCATION = "eclipse.p2.installLocation";//$NON-NLS-1$\r
+       private static final String PROP_IS_AUTO_START = "eclipse.p2.autoStart";//$NON-NLS-1$\r
+       private static final String PROP_LAUNCHER_NAME = "eclipse.p2.launcherName";//$NON-NLS-1$\r
+       private static final String PROP_METADATA_REPOSITORY = "eclipse.p2.metadata";//$NON-NLS-1$\r
+       private static final String PROP_PROFILE_NAME = "eclipse.p2.profileName";//$NON-NLS-1$\r
+       private static final String PROP_ROOT_ID = "eclipse.p2.rootId";//$NON-NLS-1$\r
+       private static final String PROP_ROOT_VERSION = "eclipse.p2.rootVersion";//$NON-NLS-1$\r
+       private static final String PROP_ROOTS = "eclipse.p2.roots";//$NON-NLS-1$\r
+\r
+       /**\r
+        * Loads and returns an install description that is stored in a properties file.\r
+        * @param site The URL of the install properties file.\r
+        */\r
+       public static InstallDescription createDescription(String site, SubMonitor monitor) throws Exception {\r
+               // if no description URL was given from the outside, look for an "install.properties" file \r
+               // in relative to where the installer is running.  This allows the installer to be self-contained\r
+               if (site == null)\r
+                       site = "installer.properties"; //$NON-NLS-1$\r
+\r
+               URI propsURI = URIUtil.fromString(site);\r
+               InputStream in = null;\r
+               if (!propsURI.isAbsolute()) {\r
+                       String installerInstallArea = System.getProperty("osgi.install.area");\r
+                       if (installerInstallArea == null)\r
+                               throw new IllegalStateException("Install area is not specified.");\r
+\r
+                       propsURI = URIUtil.append(URIUtil.fromString(installerInstallArea), site);\r
+                       File installerDescription = URIUtil.toFile(propsURI);\r
+                       if (!installerDescription.exists()) {\r
+                               throw new IllegalStateException("Can't find install description file: " + installerDescription);\r
+                       }\r
+               }\r
+               Map<String, String> properties;\r
+               try {\r
+                       in = getTransport().stream(propsURI, monitor);\r
+                       properties = CollectionUtils.loadProperties(in);\r
+               } finally {\r
+                       safeClose(in);\r
+               }\r
+\r
+               URI base = getBase(propsURI);\r
+               InstallDescription result = new InstallDescription();\r
+               result = initialize(result, properties, base);\r
+               initializeProfileProperties(result, properties);\r
+\r
+               // now override the properties from anything interesting in system properties\r
+               result = initialize(result, CollectionUtils.toMap(System.getProperties()), base);\r
+               return result;\r
+       }\r
+\r
+       private static IProvisioningAgent getAgent() {\r
+           return (IProvisioningAgent) ServiceHelper.getService(Activator.getDefault().getContext(), IProvisioningAgent.SERVICE_NAME);\r
+       }\r
+\r
+       private static Transport getTransport() {\r
+               return (Transport) getAgent().getService(Transport.SERVICE_NAME);\r
+       }\r
+\r
+       private static URI getBase(URI uri) {\r
+               if (uri == null)\r
+                       return null;\r
+\r
+               String uriString = uri.toString();\r
+               int slashIndex = uriString.lastIndexOf('/');\r
+               if (slashIndex == -1 || slashIndex == (uriString.length() - 1))\r
+                       return uri;\r
+\r
+               return URI.create(uriString.substring(0, slashIndex + 1));\r
+       }\r
+\r
+       private static InstallDescription initialize(InstallDescription description, Map<String, String> properties, URI base) {\r
+               String property = properties.get(PROP_ARTIFACT_REPOSITORY);\r
+               if (property != null)\r
+                       description.setArtifactRepositories(getURIs(property, base));\r
+\r
+               property = properties.get(PROP_METADATA_REPOSITORY);\r
+               if (property != null)\r
+                       description.setMetadataRepositories(getURIs(property, base));\r
+\r
+               property = properties.get(PROP_IS_AUTO_START);\r
+               if (property != null)\r
+                       description.setAutoStart(Boolean.TRUE.toString().equalsIgnoreCase(property));\r
+\r
+               property = properties.get(PROP_LAUNCHER_NAME);\r
+               if (property != null)\r
+                       description.setLauncherName(property);\r
+\r
+               property = properties.get(PROP_INSTALL_LOCATION);\r
+               if (property != null)\r
+                       description.setInstallLocation(new Path(property));\r
+\r
+               property = properties.get(PROP_AGENT_LOCATION);\r
+               if (property != null)\r
+                       description.setAgentLocation(new Path(property));\r
+\r
+               property = properties.get(PROP_BUNDLE_LOCATION);\r
+               if (property != null)\r
+                       description.setBundleLocation(new Path(property));\r
+\r
+               property = properties.get(PROP_PROFILE_NAME);\r
+               if (property != null)\r
+                       description.setProductName(property);\r
+\r
+               // Process the retro root id and rootVersion properties\r
+               String id = properties.get(PROP_ROOT_ID);\r
+               if (id != null) {\r
+                       String version = properties.get(PROP_ROOT_VERSION);\r
+                       try {\r
+                               description.setRoots(new IVersionedId[] {new VersionedId(id, version)});\r
+                       } catch (IllegalArgumentException e) {\r
+                               LogHelper.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Invalid version in install description: " + version, e)); //$NON-NLS-1$\r
+                       }\r
+               }\r
+\r
+               String rootSpec = properties.get(PROP_ROOTS);\r
+               if (rootSpec != null) {\r
+                       String[] rootList = getArrayFromString(rootSpec, ","); //$NON-NLS-1$\r
+                       ArrayList<IVersionedId> roots = new ArrayList<IVersionedId>(rootList.length);\r
+                       for (int i = 0; i < rootList.length; i++) {\r
+                               try {\r
+                                       roots.add(VersionedId.parse(rootList[i]));\r
+                               } catch (IllegalArgumentException e) {\r
+                                       LogHelper.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Invalid version in install description: " + rootList[i], e)); //$NON-NLS-1$\r
+                               }\r
+                       }\r
+                       if (!roots.isEmpty())\r
+                               description.setRoots(roots.toArray(new IVersionedId[roots.size()]));\r
+               }\r
+               return description;\r
+       }\r
+\r
+       /**\r
+        * Add all of the given properties to profile properties of the given description \r
+        * after removing the keys known to be for the installer.  This allows install descriptions \r
+        * to also set random profile properties.\r
+        * @param description\r
+        * @param properties\r
+        */\r
+       private static void initializeProfileProperties(InstallDescription description, Map<String, String> properties) {\r
+               //any remaining properties are profile properties\r
+               Map<String, String> profileProperties = new HashMap<String, String>(properties);\r
+               profileProperties.remove(PROP_PROFILE_NAME);\r
+               profileProperties.remove(PROP_ARTIFACT_REPOSITORY);\r
+               profileProperties.remove(PROP_METADATA_REPOSITORY);\r
+               profileProperties.remove(PROP_IS_AUTO_START);\r
+               profileProperties.remove(PROP_LAUNCHER_NAME);\r
+               profileProperties.remove(PROP_AGENT_LOCATION);\r
+               profileProperties.remove(PROP_BUNDLE_LOCATION);\r
+               profileProperties.remove(PROP_ROOT_ID);\r
+               profileProperties.remove(PROP_ROOT_VERSION);\r
+               profileProperties.remove(PROP_ROOTS);\r
+               description.setProfileProperties(profileProperties);\r
+       }\r
+\r
+       /**\r
+        * Returns an array of URIs from the given comma-separated list\r
+        * of URLs. Returns null if the given spec does not contain any URLs.\r
+        * @param base \r
+        * @return An array of URIs in the given spec, or <code>null</code>\r
+        */\r
+       private static URI[] getURIs(String spec, URI base) {\r
+               String[] urlSpecs = getArrayFromString(spec, ","); //$NON-NLS-1$\r
+               ArrayList<URI> result = new ArrayList<URI>(urlSpecs.length);\r
+               for (int i = 0; i < urlSpecs.length; i++) {\r
+                       try {\r
+                               URI uri = URIUtil.fromString(urlSpecs[i]);\r
+                               uri = URIUtil.makeAbsolute(uri, base);\r
+                               result.add(uri);\r
+                       } catch (URISyntaxException e) {\r
+                               LogHelper.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Invalid URL in install description: " + urlSpecs[i], e)); //$NON-NLS-1$\r
+                       }\r
+               }\r
+               if (result.isEmpty())\r
+                       return null;\r
+               return result.toArray(new URI[result.size()]);\r
+       }\r
+\r
+       private static void safeClose(InputStream in) {\r
+               try {\r
+                       if (in != null)\r
+                               in.close();\r
+               } catch (IOException e) {\r
+                       //ignore secondary failure during close\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Convert a list of tokens into an array. The list separator has to be\r
+        * specified.\r
+        */\r
+       public static String[] getArrayFromString(String list, String separator) {\r
+               if (list == null || list.trim().equals("")) //$NON-NLS-1$\r
+                       return new String[0];\r
+               List<String> result = new ArrayList<String>();\r
+               for (StringTokenizer tokens = new StringTokenizer(list, separator); tokens.hasMoreTokens();) {\r
+                       String token = tokens.nextToken().trim();\r
+                       if (!token.equals("")) //$NON-NLS-1$\r
+                               result.add(token);\r
+               }\r
+               return result.toArray(new String[result.size()]);\r
+       }\r
+\r
+}\r