]> gerrit.simantics Code Review - simantics/platform.git/blob - 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
1 /*******************************************************************************\r
2  *  Copyright (c) 2007, 2010 IBM Corporation and others.\r
3  *  All rights reserved. This program and the accompanying materials\r
4  *  are made available under the terms of the Eclipse Public License v1.0\r
5  *  which accompanies this distribution, and is available at\r
6  *  http://www.eclipse.org/legal/epl-v10.html\r
7  * \r
8  *  Contributors:\r
9  *     IBM Corporation - initial API and implementation\r
10  *     Code 9 - ongoing development\r
11  *     Sonatype, Inc. - ongoing development\r
12  *******************************************************************************/\r
13 package org.simantics.project.management.install;\r
14 \r
15 import java.io.File;\r
16 import java.io.IOException;\r
17 import java.io.InputStream;\r
18 import java.net.URI;\r
19 import java.net.URISyntaxException;\r
20 import java.util.ArrayList;\r
21 import java.util.HashMap;\r
22 import java.util.List;\r
23 import java.util.Map;\r
24 import java.util.StringTokenizer;\r
25 \r
26 import org.eclipse.core.runtime.IStatus;\r
27 import org.eclipse.core.runtime.Path;\r
28 import org.eclipse.core.runtime.Status;\r
29 import org.eclipse.core.runtime.SubMonitor;\r
30 import org.eclipse.core.runtime.URIUtil;\r
31 import org.eclipse.equinox.internal.p2.core.helpers.CollectionUtils;\r
32 import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;\r
33 import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;\r
34 import org.eclipse.equinox.internal.p2.repository.Transport;\r
35 import org.eclipse.equinox.internal.provisional.p2.installer.InstallDescription;\r
36 import org.eclipse.equinox.p2.core.IProvisioningAgent;\r
37 import org.eclipse.equinox.p2.metadata.IVersionedId;\r
38 import org.eclipse.equinox.p2.metadata.VersionedId;\r
39 import org.simantics.project.internal.Activator;\r
40 \r
41 /**\r
42  * This class is responsible for loading install descriptions from a stream.\r
43  */\r
44 @SuppressWarnings("restriction")\r
45 public class InstallDescriptionParser {\r
46         private static final String PROP_AGENT_LOCATION = "eclipse.p2.agentLocation"; //$NON-NLS-1$\r
47         private static final String PROP_ARTIFACT_REPOSITORY = "eclipse.p2.artifacts";//$NON-NLS-1$\r
48         private static final String PROP_BUNDLE_LOCATION = "eclipse.p2.bundleLocation";//$NON-NLS-1$\r
49         private static final String PROP_INSTALL_LOCATION = "eclipse.p2.installLocation";//$NON-NLS-1$\r
50         private static final String PROP_IS_AUTO_START = "eclipse.p2.autoStart";//$NON-NLS-1$\r
51         private static final String PROP_LAUNCHER_NAME = "eclipse.p2.launcherName";//$NON-NLS-1$\r
52         private static final String PROP_METADATA_REPOSITORY = "eclipse.p2.metadata";//$NON-NLS-1$\r
53         private static final String PROP_PROFILE_NAME = "eclipse.p2.profileName";//$NON-NLS-1$\r
54         private static final String PROP_ROOT_ID = "eclipse.p2.rootId";//$NON-NLS-1$\r
55         private static final String PROP_ROOT_VERSION = "eclipse.p2.rootVersion";//$NON-NLS-1$\r
56         private static final String PROP_ROOTS = "eclipse.p2.roots";//$NON-NLS-1$\r
57 \r
58         /**\r
59          * Loads and returns an install description that is stored in a properties file.\r
60          * @param site The URL of the install properties file.\r
61          */\r
62         public static InstallDescription createDescription(String site, SubMonitor monitor) throws Exception {\r
63                 // if no description URL was given from the outside, look for an "install.properties" file \r
64                 // in relative to where the installer is running.  This allows the installer to be self-contained\r
65                 if (site == null)\r
66                         site = "installer.properties"; //$NON-NLS-1$\r
67 \r
68                 URI propsURI = URIUtil.fromString(site);\r
69                 InputStream in = null;\r
70                 if (!propsURI.isAbsolute()) {\r
71                         String installerInstallArea = System.getProperty("osgi.install.area");\r
72                         if (installerInstallArea == null)\r
73                                 throw new IllegalStateException("Install area is not specified.");\r
74 \r
75                         propsURI = URIUtil.append(URIUtil.fromString(installerInstallArea), site);\r
76                         File installerDescription = URIUtil.toFile(propsURI);\r
77                         if (!installerDescription.exists()) {\r
78                                 throw new IllegalStateException("Can't find install description file: " + installerDescription);\r
79                         }\r
80                 }\r
81                 Map<String, String> properties;\r
82                 try {\r
83                         in = getTransport().stream(propsURI, monitor);\r
84                         properties = CollectionUtils.loadProperties(in);\r
85                 } finally {\r
86                         safeClose(in);\r
87                 }\r
88 \r
89                 URI base = getBase(propsURI);\r
90                 InstallDescription result = new InstallDescription();\r
91                 result = initialize(result, properties, base);\r
92                 initializeProfileProperties(result, properties);\r
93 \r
94                 // now override the properties from anything interesting in system properties\r
95                 result = initialize(result, CollectionUtils.toMap(System.getProperties()), base);\r
96                 return result;\r
97         }\r
98 \r
99         private static IProvisioningAgent getAgent() {\r
100             return (IProvisioningAgent) ServiceHelper.getService(Activator.getDefault().getContext(), IProvisioningAgent.SERVICE_NAME);\r
101         }\r
102 \r
103         private static Transport getTransport() {\r
104                 return (Transport) getAgent().getService(Transport.SERVICE_NAME);\r
105         }\r
106 \r
107         private static URI getBase(URI uri) {\r
108                 if (uri == null)\r
109                         return null;\r
110 \r
111                 String uriString = uri.toString();\r
112                 int slashIndex = uriString.lastIndexOf('/');\r
113                 if (slashIndex == -1 || slashIndex == (uriString.length() - 1))\r
114                         return uri;\r
115 \r
116                 return URI.create(uriString.substring(0, slashIndex + 1));\r
117         }\r
118 \r
119         private static InstallDescription initialize(InstallDescription description, Map<String, String> properties, URI base) {\r
120                 String property = properties.get(PROP_ARTIFACT_REPOSITORY);\r
121                 if (property != null)\r
122                         description.setArtifactRepositories(getURIs(property, base));\r
123 \r
124                 property = properties.get(PROP_METADATA_REPOSITORY);\r
125                 if (property != null)\r
126                         description.setMetadataRepositories(getURIs(property, base));\r
127 \r
128                 property = properties.get(PROP_IS_AUTO_START);\r
129                 if (property != null)\r
130                         description.setAutoStart(Boolean.TRUE.toString().equalsIgnoreCase(property));\r
131 \r
132                 property = properties.get(PROP_LAUNCHER_NAME);\r
133                 if (property != null)\r
134                         description.setLauncherName(property);\r
135 \r
136                 property = properties.get(PROP_INSTALL_LOCATION);\r
137                 if (property != null)\r
138                         description.setInstallLocation(new Path(property));\r
139 \r
140                 property = properties.get(PROP_AGENT_LOCATION);\r
141                 if (property != null)\r
142                         description.setAgentLocation(new Path(property));\r
143 \r
144                 property = properties.get(PROP_BUNDLE_LOCATION);\r
145                 if (property != null)\r
146                         description.setBundleLocation(new Path(property));\r
147 \r
148                 property = properties.get(PROP_PROFILE_NAME);\r
149                 if (property != null)\r
150                         description.setProductName(property);\r
151 \r
152                 // Process the retro root id and rootVersion properties\r
153                 String id = properties.get(PROP_ROOT_ID);\r
154                 if (id != null) {\r
155                         String version = properties.get(PROP_ROOT_VERSION);\r
156                         try {\r
157                                 description.setRoots(new IVersionedId[] {new VersionedId(id, version)});\r
158                         } catch (IllegalArgumentException e) {\r
159                                 LogHelper.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Invalid version in install description: " + version, e)); //$NON-NLS-1$\r
160                         }\r
161                 }\r
162 \r
163                 String rootSpec = properties.get(PROP_ROOTS);\r
164                 if (rootSpec != null) {\r
165                         String[] rootList = getArrayFromString(rootSpec, ","); //$NON-NLS-1$\r
166                         ArrayList<IVersionedId> roots = new ArrayList<IVersionedId>(rootList.length);\r
167                         for (int i = 0; i < rootList.length; i++) {\r
168                                 try {\r
169                                         roots.add(VersionedId.parse(rootList[i]));\r
170                                 } catch (IllegalArgumentException e) {\r
171                                         LogHelper.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Invalid version in install description: " + rootList[i], e)); //$NON-NLS-1$\r
172                                 }\r
173                         }\r
174                         if (!roots.isEmpty())\r
175                                 description.setRoots(roots.toArray(new IVersionedId[roots.size()]));\r
176                 }\r
177                 return description;\r
178         }\r
179 \r
180         /**\r
181          * Add all of the given properties to profile properties of the given description \r
182          * after removing the keys known to be for the installer.  This allows install descriptions \r
183          * to also set random profile properties.\r
184          * @param description\r
185          * @param properties\r
186          */\r
187         private static void initializeProfileProperties(InstallDescription description, Map<String, String> properties) {\r
188                 //any remaining properties are profile properties\r
189                 Map<String, String> profileProperties = new HashMap<String, String>(properties);\r
190                 profileProperties.remove(PROP_PROFILE_NAME);\r
191                 profileProperties.remove(PROP_ARTIFACT_REPOSITORY);\r
192                 profileProperties.remove(PROP_METADATA_REPOSITORY);\r
193                 profileProperties.remove(PROP_IS_AUTO_START);\r
194                 profileProperties.remove(PROP_LAUNCHER_NAME);\r
195                 profileProperties.remove(PROP_AGENT_LOCATION);\r
196                 profileProperties.remove(PROP_BUNDLE_LOCATION);\r
197                 profileProperties.remove(PROP_ROOT_ID);\r
198                 profileProperties.remove(PROP_ROOT_VERSION);\r
199                 profileProperties.remove(PROP_ROOTS);\r
200                 description.setProfileProperties(profileProperties);\r
201         }\r
202 \r
203         /**\r
204          * Returns an array of URIs from the given comma-separated list\r
205          * of URLs. Returns null if the given spec does not contain any URLs.\r
206          * @param base \r
207          * @return An array of URIs in the given spec, or <code>null</code>\r
208          */\r
209         private static URI[] getURIs(String spec, URI base) {\r
210                 String[] urlSpecs = getArrayFromString(spec, ","); //$NON-NLS-1$\r
211                 ArrayList<URI> result = new ArrayList<URI>(urlSpecs.length);\r
212                 for (int i = 0; i < urlSpecs.length; i++) {\r
213                         try {\r
214                                 URI uri = URIUtil.fromString(urlSpecs[i]);\r
215                                 uri = URIUtil.makeAbsolute(uri, base);\r
216                                 result.add(uri);\r
217                         } catch (URISyntaxException e) {\r
218                                 LogHelper.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Invalid URL in install description: " + urlSpecs[i], e)); //$NON-NLS-1$\r
219                         }\r
220                 }\r
221                 if (result.isEmpty())\r
222                         return null;\r
223                 return result.toArray(new URI[result.size()]);\r
224         }\r
225 \r
226         private static void safeClose(InputStream in) {\r
227                 try {\r
228                         if (in != null)\r
229                                 in.close();\r
230                 } catch (IOException e) {\r
231                         //ignore secondary failure during close\r
232                 }\r
233         }\r
234 \r
235         /**\r
236          * Convert a list of tokens into an array. The list separator has to be\r
237          * specified.\r
238          */\r
239         public static String[] getArrayFromString(String list, String separator) {\r
240                 if (list == null || list.trim().equals("")) //$NON-NLS-1$\r
241                         return new String[0];\r
242                 List<String> result = new ArrayList<String>();\r
243                 for (StringTokenizer tokens = new StringTokenizer(list, separator); tokens.hasMoreTokens();) {\r
244                         String token = tokens.nextToken().trim();\r
245                         if (!token.equals("")) //$NON-NLS-1$\r
246                                 result.add(token);\r
247                 }\r
248                 return result.toArray(new String[result.size()]);\r
249         }\r
250 \r
251 }\r