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