]> git.argeo.org Git - gpl/argeo-slc.git/blob - eclipse/plugins/org.argeo.slc.ide.ui/src/main/java/org/argeo/slc/ide/ui/launch/osgi/OsgiLaunchHelper.java
Start working on serialized JMS
[gpl/argeo-slc.git] / eclipse / plugins / org.argeo.slc.ide.ui / src / main / java / org / argeo / slc / ide / ui / launch / osgi / OsgiLaunchHelper.java
1 package org.argeo.slc.ide.ui.launch.osgi;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.ArrayList;
7 import java.util.HashMap;
8 import java.util.Iterator;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Properties;
12 import java.util.StringTokenizer;
13
14 import org.argeo.slc.ide.ui.SlcIdeUiPlugin;
15 import org.eclipse.core.resources.IFile;
16 import org.eclipse.core.resources.IProject;
17 import org.eclipse.core.resources.IResource;
18 import org.eclipse.core.runtime.Assert;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IStatus;
21 import org.eclipse.core.runtime.Status;
22 import org.eclipse.core.variables.IStringVariableManager;
23 import org.eclipse.core.variables.VariablesPlugin;
24 import org.eclipse.debug.core.ILaunchConfiguration;
25 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
26 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
27 import org.eclipse.jdt.launching.IVMInstall;
28 import org.eclipse.jdt.launching.IVMInstall2;
29 import org.eclipse.jdt.launching.IVMInstallType;
30 import org.eclipse.jdt.launching.JavaRuntime;
31 import org.eclipse.jface.dialogs.ErrorDialog;
32 import org.eclipse.jface.viewers.ISelection;
33 import org.eclipse.jface.viewers.IStructuredSelection;
34 import org.eclipse.osgi.service.resolver.BundleDescription;
35 import org.eclipse.pde.core.plugin.IPluginModelBase;
36 import org.eclipse.pde.core.plugin.PluginRegistry;
37 import org.eclipse.pde.ui.launcher.IPDELauncherConstants;
38 import org.eclipse.swt.widgets.Shell;
39
40 public class OsgiLaunchHelper implements OsgiLauncherConstants {
41 private static Boolean debug = false;
42
43 /** Expects properties file to be set as mapped resources */
44 public static void updateLaunchConfiguration(
45 ILaunchConfigurationWorkingCopy configuration) {
46 try {
47 // Finds the properties file and load it
48 IFile propertiesFile = (IFile) configuration.getMappedResources()[0];
49 propertiesFile.refreshLocal(IResource.DEPTH_ONE, null);
50 Properties properties = readProperties(propertiesFile);
51
52 // Extract information from the properties file
53 List<String> bundlesToStart = new ArrayList<String>();
54 Map<String, String> systemPropertiesToAppend = new HashMap<String, String>();
55 interpretProperties(properties, bundlesToStart,
56 systemPropertiesToAppend);
57
58 // Define directories
59 File workingDir = getWorkingDirectory(configuration);
60 File dataDir = new File(workingDir, "data");
61
62 // Update the launch configuration accordingly
63 updateLaunchConfiguration(configuration, bundlesToStart,
64 systemPropertiesToAppend, dataDir.getAbsolutePath());
65 } catch (Exception e) {
66 e.printStackTrace();
67 Shell shell = SlcIdeUiPlugin.getDefault().getWorkbench()
68 .getActiveWorkbenchWindow().getShell();
69 // Shell shell= Display.getCurrent().getActiveShell();
70 ErrorDialog.openError(shell, "Error", "Cannot read properties",
71 new Status(IStatus.ERROR, SlcIdeUiPlugin.ID,
72 e.getMessage(), e));
73 return;
74 }
75 }
76
77 /**
78 * Actually modifies the launch configuration in order to reflect the
79 * current state read from the properties file and the launch configuration
80 * UI.
81 */
82 protected static void updateLaunchConfiguration(
83 ILaunchConfigurationWorkingCopy configuration,
84 List<String> bundlesToStart,
85 Map<String, String> systemPropertiesToAppend, String dataDir)
86 throws CoreException {
87 // Convert bundle lists
88 final String targetBundles;
89 final String wkSpaceBundles;
90 if (configuration.getAttribute(ATTR_SYNC_BUNDLES, true)) {
91 StringBuffer tBuf = new StringBuffer();
92 for (IPluginModelBase model : PluginRegistry.getExternalModels()) {
93 tBuf.append(model.getBundleDescription().getSymbolicName());
94 tBuf.append(',');
95 }
96 targetBundles = tBuf.toString();
97 StringBuffer wBuf = new StringBuffer();
98 models: for (IPluginModelBase model : PluginRegistry
99 .getWorkspaceModels()) {
100 if (model.getBundleDescription() == null) {
101 System.err.println("No bundle description for " + model);
102 continue models;
103 }
104 wBuf.append(model.getBundleDescription().getSymbolicName());
105 wBuf.append(',');
106 }
107 wkSpaceBundles = wBuf.toString();
108 } else {
109 targetBundles = configuration.getAttribute(
110 IPDELauncherConstants.TARGET_BUNDLES, "");
111 wkSpaceBundles = configuration.getAttribute(
112 IPDELauncherConstants.WORKSPACE_BUNDLES, "");
113 }
114 configuration.setAttribute(IPDELauncherConstants.TARGET_BUNDLES,
115 convertBundleList(bundlesToStart, targetBundles));
116
117 configuration.setAttribute(IPDELauncherConstants.WORKSPACE_BUNDLES,
118 convertBundleList(bundlesToStart, wkSpaceBundles));
119
120 // Update other default information
121 configuration.setAttribute(IPDELauncherConstants.DEFAULT_AUTO_START,
122 false);
123
124 // VM arguments (system properties)
125 String defaultVmArgs = configuration.getAttribute(
126 OsgiLauncherConstants.ATTR_DEFAULT_VM_ARGS, "");
127 StringBuffer vmArgs = new StringBuffer(defaultVmArgs);
128
129 // Data dir system property
130 if (dataDir != null)
131 addSysProperty(vmArgs, OsgiLauncherConstants.ARGEO_OSGI_DATA_DIR,
132 dataDir);
133 // Add locations of JVMs
134 if (configuration.getAttribute(ATTR_ADD_JVM_PATHS, false))
135 addVms(vmArgs);
136
137 // Add other system properties
138 for (String key : systemPropertiesToAppend.keySet())
139 addSysProperty(vmArgs, key, systemPropertiesToAppend.get(key));
140
141 vmArgs.append(" ").append(
142 configuration.getAttribute(ATTR_ADDITIONAL_VM_ARGS, ""));
143
144 configuration.setAttribute(
145 IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs
146 .toString());
147
148 // Program arguments
149 StringBuffer progArgs = new StringBuffer("");
150 if (dataDir != null) {
151 progArgs.append("-data ");
152 progArgs.append(surroundSpaces(dataDir));
153
154 if (configuration.getAttribute(ATTR_CLEAR_DATA_DIRECTORY, false)) {
155 File dataDirFile = new File(dataDir);
156 deleteDir(dataDirFile);
157 dataDirFile.mkdirs();
158 }
159 }
160 String additionalProgramArgs = configuration.getAttribute(
161 OsgiLauncherConstants.ATTR_ADDITIONAL_PROGRAM_ARGS, "");
162 progArgs.append(' ').append(additionalProgramArgs);
163 configuration.setAttribute(
164 IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,
165 progArgs.toString());
166 }
167
168 /**
169 * Interprets special properties and register the others as system
170 * properties to append.
171 */
172 protected static void interpretProperties(Properties properties,
173 List<String> bundlesToStart,
174 Map<String, String> systemPropertiesToAppend) {
175 String argeoOsgiStart = properties
176 .getProperty(OsgiLauncherConstants.ARGEO_OSGI_START);
177 if (argeoOsgiStart != null) {
178 StringTokenizer st = new StringTokenizer(argeoOsgiStart, ",");
179 while (st.hasMoreTokens())
180 bundlesToStart.add(st.nextToken());
181 }
182
183 propKeys: for (Object keyObj : properties.keySet()) {
184 String key = keyObj.toString();
185 if (OsgiLauncherConstants.ARGEO_OSGI_START.equals(key))
186 continue propKeys;
187 else if (OsgiLauncherConstants.ARGEO_OSGI_BUNDLES.equals(key))
188 continue propKeys;
189 else if (OsgiLauncherConstants.ARGEO_OSGI_LOCATIONS.equals(key))
190 continue propKeys;
191 else if (OsgiLauncherConstants.OSGI_BUNDLES.equals(key))
192 continue propKeys;
193 else
194 systemPropertiesToAppend.put(key, properties.getProperty(key));
195 }
196
197 }
198
199 /** Adds a regular system property. */
200 protected static void addSysProperty(StringBuffer vmArgs, String key,
201 String value) {
202 surroundSpaces(value);
203 String str = "-D" + key + "=" + value;
204 // surroundSpaces(str);
205 vmArgs.append(' ').append(str);
206 }
207
208 /** Adds JVMS registered in the workspace as special system properties. */
209 protected static void addVms(StringBuffer vmArgs) {
210 addVmSysProperty(vmArgs, "default", JavaRuntime.getDefaultVMInstall());
211 IVMInstallType[] vmTypes = JavaRuntime.getVMInstallTypes();
212 for (IVMInstallType vmType : vmTypes) {
213 for (IVMInstall vmInstall : vmType.getVMInstalls()) {
214 // printVm("", vmInstall);
215 // properties based on name
216 addVmSysProperty(vmArgs, vmInstall.getName(), vmInstall);
217 if (vmInstall instanceof IVMInstall2) {
218 // properties based on version
219 IVMInstall2 vmInstall2 = (IVMInstall2) vmInstall;
220 String version = vmInstall2.getJavaVersion();
221 addVmSysProperty(vmArgs, version, vmInstall);
222
223 List<String> tokens = new ArrayList<String>();
224 StringTokenizer st = new StringTokenizer(version, ".");
225 while (st.hasMoreTokens())
226 tokens.add(st.nextToken());
227 if (tokens.size() >= 2)
228 addVmSysProperty(vmArgs, tokens.get(0) + "."
229 + tokens.get(1), vmInstall);
230 }
231 }
232 }
233
234 }
235
236 /** Adds a special system property pointing to one of the registered JVMs. */
237 protected static void addVmSysProperty(StringBuffer vmArgs, String suffix,
238 IVMInstall vmInstall) {
239 addSysProperty(vmArgs, OsgiLauncherConstants.VMS_PROPERTY_PREFIX + "."
240 + suffix, vmInstall.getInstallLocation().getPath());
241 }
242
243 /** Surround the string with quotes if it contains spaces. */
244 protected static String surroundSpaces(String str) {
245 if (str.indexOf(' ') >= 0)
246 return '\"' + str + '\"';
247 else
248 return str;
249 }
250
251 /**
252 * Reformat the bundle list in order to reflect which bundles have to be
253 * started.
254 */
255 protected static String convertBundleList(List<String> bundlesToStart,
256 String original) {
257 if (debug)
258 System.out.println("Original bundle list: " + original);
259
260 StringBuffer bufBundles = new StringBuffer(1024);
261 StringTokenizer stComa = new StringTokenizer(original, ",");
262 boolean first = true;
263 bundles: while (stComa.hasMoreTokens()) {
264 if (first)
265 first = false;
266 else
267 bufBundles.append(',');
268
269 String bundleId = stComa.nextToken();
270 if (bundleId.indexOf('*') >= 0)
271 throw new RuntimeException(
272 "Bundle id "
273 + bundleId
274 + " not properly formatted, clean your workspace projects");
275
276 int indexAt = bundleId.indexOf('@');
277 boolean modified = false;
278 if (indexAt >= 0) {
279 bundleId = bundleId.substring(0, indexAt);
280 }
281
282 if (bundleId.endsWith(".source")) {
283 if (debug)
284 System.out.println("Skip source bundle " + bundleId);
285 continue bundles;
286 }
287
288 if (bundlesToStart.contains(bundleId)) {
289 bufBundles.append(bundleId).append('@').append("default:true");
290 modified = true;
291 if (debug)
292 System.out.println("Will start " + bundleId);
293 }
294
295 if (!modified)
296 bufBundles.append(bundleId);
297 }
298 String output = bufBundles.toString();
299 return output;
300 }
301
302 // UTILITIES
303 /** Recursively deletes a directory tree. */
304 private static void deleteDir(File dir) {
305 File[] files = dir.listFiles();
306 for (File file : files) {
307 if (file.isDirectory())
308 deleteDir(file);
309 else
310 file.delete();
311 }
312 dir.delete();
313 }
314
315 /** Loads a properties file. */
316 private static Properties readProperties(IFile file) throws CoreException {
317 Properties props = new Properties();
318
319 InputStream in = null;
320 try {
321 in = file.getContents();
322 props.load(in);
323 } catch (IOException e) {
324 throw new CoreException(new Status(IStatus.ERROR,
325 SlcIdeUiPlugin.ID, "Cannot read properties file", e));
326 } finally {
327 if (in != null)
328 try {
329 in.close();
330 } catch (IOException e) {
331 // silent
332 }
333 }
334 return props;
335 }
336
337 // Hacked from
338 // org.eclipse.pde.internal.ui.launcher.LaunchArgumentsHelper.getWorkingDirectory(ILaunchConfiguration)
339 private static File getWorkingDirectory(ILaunchConfiguration configuration)
340 throws CoreException {
341 String working;
342 try {
343 working = configuration.getAttribute(
344 IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
345 new File(".").getCanonicalPath()); //$NON-NLS-1$
346 } catch (IOException e) {
347 working = "${workspace_loc}/../"; //$NON-NLS-1$
348 }
349 File dir = new File(getSubstitutedString(working));
350 if (!dir.exists())
351 dir.mkdirs();
352 return dir;
353 }
354
355 // Hacked from
356 // org.eclipse.pde.internal.ui.launcher.LaunchArgumentsHelper.getSubstitutedString(String)
357 private static String getSubstitutedString(String text)
358 throws CoreException {
359 if (text == null)
360 return ""; //$NON-NLS-1$
361 IStringVariableManager mgr = VariablesPlugin.getDefault()
362 .getStringVariableManager();
363 return mgr.performStringSubstitution(text);
364 }
365
366 /**
367 * Not used anymore, but kept because this routine may be useful in the
368 * future.
369 */
370 protected void addSelectedProjects(StringBuffer name, ISelection selection,
371 List<String> bundlesToStart) {
372 Assert.isNotNull(selection);
373
374 Map<String, IPluginModelBase> bundleProjects = new HashMap<String, IPluginModelBase>();
375 for (IPluginModelBase modelBase : PluginRegistry.getWorkspaceModels()) {
376 IProject bundleProject = modelBase.getUnderlyingResource()
377 .getProject();
378 bundleProjects.put(bundleProject.getName(), modelBase);
379 }
380
381 IStructuredSelection sSelection = (IStructuredSelection) selection;
382 for (Iterator<?> it = sSelection.iterator(); it.hasNext();) {
383 Object obj = it.next();
384 if (obj instanceof IProject) {
385 IProject project = (IProject) obj;
386 if (bundleProjects.containsKey(project.getName())) {
387 IPluginModelBase modelBase = bundleProjects.get(project
388 .getName());
389
390 BundleDescription bundleDescription = null;
391 if (modelBase.isFragmentModel()) {
392 BundleDescription[] hosts = modelBase
393 .getBundleDescription().getHost().getHosts();
394 for (BundleDescription bd : hosts) {
395 if (debug)
396 System.out.println("Host for "
397 + modelBase.getBundleDescription()
398 .getSymbolicName() + ": "
399 + bd.getSymbolicName());
400 bundleDescription = bd;
401 }
402 } else {
403 bundleDescription = modelBase.getBundleDescription();
404 }
405
406 if (bundleDescription != null) {
407 String symbolicName = bundleDescription
408 .getSymbolicName();
409 String bundleName = bundleDescription.getName();
410
411 bundlesToStart.add(symbolicName);
412
413 if (name.length() > 0)
414 name.append(" ");
415 if (bundleName != null)
416 name.append(bundleName);
417 else
418 name.append(symbolicName);
419 }
420 }
421 }
422 }
423 }
424
425 }