View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.slc.client.ui.dist.commands;
17  
18  import java.io.File;
19  import java.io.FileWriter;
20  import java.io.InputStream;
21  import java.io.OutputStream;
22  import java.io.Writer;
23  import java.net.URL;
24  
25  import javax.jcr.Node;
26  import javax.jcr.NodeIterator;
27  import javax.jcr.Repository;
28  import javax.jcr.Session;
29  
30  import org.apache.commons.io.FileUtils;
31  import org.apache.commons.io.IOUtils;
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
35  import org.argeo.jcr.JcrUtils;
36  import org.argeo.slc.SlcException;
37  import org.argeo.slc.SlcNames;
38  import org.argeo.slc.client.ui.dist.DistPlugin;
39  import org.argeo.slc.core.execution.tasks.JvmProcess;
40  import org.argeo.slc.repo.RepoUtils;
41  import org.argeo.slc.repo.maven.MavenConventionsUtils;
42  import org.eclipse.aether.artifact.Artifact;
43  import org.eclipse.core.commands.AbstractHandler;
44  import org.eclipse.core.commands.ExecutionEvent;
45  import org.eclipse.core.commands.ExecutionException;
46  import org.eclipse.core.runtime.IProgressMonitor;
47  import org.eclipse.core.runtime.IStatus;
48  import org.eclipse.core.runtime.Status;
49  import org.eclipse.core.runtime.jobs.Job;
50  import org.eclipse.jface.resource.ImageDescriptor;
51  
52  /** <b>UNDER DEVELOPMENT</b>. Download and prepare an OSGi runtime */
53  public class RunInOsgi extends AbstractHandler implements SlcNames {
54  	private final static Log log = LogFactory.getLog(RunInOsgi.class);
55  
56  	public final static String ID = DistPlugin.PLUGIN_ID + ".runInOsgi";
57  	public final static String DEFAULT_LABEL = "Run in OSGi";
58  	public final static ImageDescriptor DEFAULT_ICON = DistPlugin
59  			.getImageDescriptor("icons/runInOsgi.gif");
60  
61  	public final static String PARAM_WORKSPACE_NAME = "workspaceName";
62  	public final static String PARAM_MODULE_PATH = "modulePath";
63  
64  	/* DEPENDENCY INJECTION */
65  	private Repository repository;
66  
67  	public Object execute(ExecutionEvent event) throws ExecutionException {
68  
69  		String workspace = event.getParameter(PARAM_WORKSPACE_NAME);
70  		String modulePath = event.getParameter(PARAM_MODULE_PATH);
71  		String port = System.getProperty("argeo.server.port.http");
72  		// String localMavenBase = System.getProperty("user.home")
73  		// + "/.m2/repository";
74  
75  		InputStream jarStream = null;
76  		OutputStream out = null;
77  		Writer writer = null;
78  		Session session = null;
79  		try {
80  			// Bundle distPluginBundle = DistPlugin.getDefault().getBundle();
81  			// File baseDir = distPluginBundle.getBundleContext().getDataFile(
82  			// "runInOSGi");
83  			File baseDir = new File(System.getProperty("java.io.tmpdir")
84  					+ "/runInOSGi-" + System.getProperty("user.name"));
85  			if (baseDir.exists())
86  				FileUtils.deleteDirectory(baseDir);
87  			File libDir = new File(baseDir, "lib");
88  			libDir.mkdirs();
89  			File confDir = new File(baseDir, "configuration");
90  			confDir.mkdirs();
91  			File dataDir = new File(baseDir, "data");
92  			dataDir.mkdirs();
93  
94  			session = repository.login(workspace);
95  
96  			// NodeIterator bundles = listBundleArtifacts(session);
97  			// if (log.isDebugEnabled())
98  			// log.debug("## Copying to " + libDir);
99  			//
100 			// File equinoxJar = null;
101 			// List<File> files = new ArrayList<File>();
102 			// bundles: while (bundles.hasNext()) {
103 			// Node bundleNode = bundles.nextNode();
104 			// String symbolicName = JcrUtils.get(bundleNode,
105 			// SLC_SYMBOLIC_NAME);
106 			//
107 			// // skip sources
108 			// if (symbolicName.endsWith(".source"))
109 			// continue bundles;
110 			// // skip eclipse
111 			// if (symbolicName.startsWith("org.eclipse")
112 			// && !symbolicName.equals("org.eclipse.osgi"))
113 			// continue bundles;
114 			// if (symbolicName.equals("org.polymap.openlayers.rap.widget"))
115 			// continue bundles;
116 			//
117 			// File targetFile = new File(libDir, bundleNode.getName());
118 			// out = new FileOutputStream(targetFile);
119 			// jarStream = bundleNode.getNode(Node.JCR_CONTENT)
120 			// .getProperty(Property.JCR_DATA).getBinary().getStream();
121 			// IOUtils.copy(jarStream, out);
122 			// if (symbolicName.equals("org.eclipse.osgi"))
123 			// equinoxJar = targetFile;
124 			// else
125 			// files.add(targetFile);
126 			// if (log.isDebugEnabled())
127 			// log.debug("Copied " + targetFile.getName());
128 			//
129 			// IOUtils.closeQuietly(out);
130 			// IOUtils.closeQuietly(jarStream);
131 			// }
132 			//
133 			// StringBuffer osgiBundles = new StringBuffer("osgi.bundles=");
134 			// for (int i = 0; i < files.size(); i++) {
135 			// if (i != 0)
136 			// osgiBundles.append(',');
137 			// osgiBundles.append(files.get(i).getName());
138 			// }
139 
140 			String equinoxJar = null;
141 
142 			Node distModule = session.getNode(modulePath);
143 			NodeIterator coordinates = distModule.getNode(SLC_MODULES)
144 					.getNodes();
145 			StringBuilder conf = new StringBuilder(1024 * 1024);
146 			conf.append("osgi.clean=true\n");
147 			conf.append("osgi.console=7777\n");
148 			// conf.append("osgi.console.enable.builtin=true\n");
149 
150 			conf.append("osgi.bundles=");
151 			coords: while (coordinates.hasNext()) {
152 				Node coord = coordinates.nextNode();
153 				// String category =
154 				// coord.getProperty(SLC_CATEGORY).getString();
155 				String name = coord.getProperty(SLC_NAME).getString();
156 				String version = coord.getProperty(SLC_VERSION).getString();
157 				Artifact artifact = RepoUtils.asArtifact(coord);
158 				String path = MavenConventionsUtils.artifactPath("", artifact);
159 				String url = "http://localhost:" + port + "/data/public/java/"
160 						+ workspace + path;
161 				if (log.isDebugEnabled())
162 					log.debug(url);
163 				File f = new File(libDir, name + "-" + version + ".jar");
164 				FileUtils.copyURLToFile(new URL(url), f);
165 				if (name.equals("org.eclipse.osgi")) {
166 					// File f = new File(localMavenBase + path);
167 					// if (!f.exists())
168 					// FileUtils.copyURLToFile(new URL(url), f);
169 					equinoxJar = f.getCanonicalPath();
170 					continue coords;
171 				}
172 				conf.append(f.getName());
173 				if (coordinates.hasNext())
174 					conf.append(",\\\n");
175 			}
176 
177 			File confIni = new File(confDir, "config.ini");
178 			writer = new FileWriter(confIni);
179 			writer.write(conf.toString());
180 			IOUtils.closeQuietly(writer);
181 
182 			// Map<String, String> configuration = new HashMap<String,
183 			// String>();
184 			// configuration.put("osgi.configuration.area",
185 			// confDir.getCanonicalPath());
186 			// configuration.put("osgi.instance.area",
187 			// dataDir.getCanonicalPath());
188 			// // Do clean
189 			// configuration.put("osgi.clean", "true");
190 
191 			JvmProcess osgiRuntime = new JvmProcess();
192 			osgiRuntime.setExecDir(baseDir.getCanonicalPath());
193 			if (equinoxJar == null)
194 				throw new SlcException("Cannot find OSGi runtime.");
195 			osgiRuntime.setMainJar(equinoxJar);
196 			osgiRuntime.arg("-configuration", confDir.getCanonicalPath()).arg(
197 					"-data", dataDir.getCanonicalPath());
198 			// .arg("-console", "7777").arg("-clean");
199 			osgiRuntime.setLogCommand(true);
200 			osgiRuntime.afterPropertiesSet();
201 			Job job = new RunInOsgiJob(osgiRuntime);
202 			job.schedule();
203 			// osgiRuntime.run();
204 
205 			// Map<String, String> configuration = new HashMap<String,
206 			// String>();
207 			// configuration.put("osgi.configuration.area",
208 			// confDir.getCanonicalPath());
209 			// configuration.put("osgi.instance.area",
210 			// dataDir.getCanonicalPath());
211 			// // Do clean
212 			// configuration.put("osgi.clean", "true");
213 			// ServiceLoader<FrameworkFactory> ff = ServiceLoader
214 			// .load(FrameworkFactory.class);
215 			// FrameworkFactory frameworkFactory = ff.iterator().next();
216 			// Framework framework =
217 			// frameworkFactory.newFramework(configuration);
218 			// framework.start();
219 			// BundleContext testBundleContext = framework.getBundleContext();
220 
221 			// for (int i = 0; i < files.size(); i++) {
222 			// testBundleContext.installBundle("file://"
223 			// + files.get(i).getCanonicalPath());
224 			// }
225 			//
226 			// Bundle[] testBundles = testBundleContext.getBundles();
227 			// for (Bundle bundle : testBundles) {
228 			// if (log.isDebugEnabled())
229 			// log.debug(bundle.getSymbolicName() + " "
230 			// + bundle.getVersion());
231 			// }
232 
233 		} catch (Exception e) {
234 			ErrorFeedback.show("Cannot run in OSGi", e);
235 		} finally {
236 			IOUtils.closeQuietly(jarStream);
237 			IOUtils.closeQuietly(out);
238 			IOUtils.closeQuietly(writer);
239 			JcrUtils.logoutQuietly(session);
240 		}
241 
242 		return null;
243 	}
244 
245 	// private NodeIterator listBundleArtifacts(Session session)
246 	// throws RepositoryException {
247 
248 	// QueryManager queryManager = session.getWorkspace().getQueryManager();
249 	// QueryObjectModelFactory factory = queryManager.getQOMFactory();
250 	//
251 	// final String bundleArtifactsSelector = "bundleArtifacts";
252 	// Selector source = factory.selector(SlcTypes.SLC_BUNDLE_ARTIFACT,
253 	// bundleArtifactsSelector);
254 	//
255 	// Ordering order = factory.ascending(factory.propertyValue(
256 	// bundleArtifactsSelector, SlcNames.SLC_SYMBOLIC_NAME));
257 	// Ordering[] orderings = { order };
258 	//
259 	// QueryObjectModel query = factory.createQuery(source, null, orderings,
260 	// null);
261 	//
262 	// QueryResult result = query.execute();
263 	// return result.getNodes();
264 	// }
265 
266 	private class RunInOsgiJob extends Job {
267 		final JvmProcess osgiRuntime;
268 
269 		public RunInOsgiJob(JvmProcess osgiRuntime) {
270 			super("OSGi Test");
271 			this.osgiRuntime = osgiRuntime;
272 		}
273 
274 		@Override
275 		protected IStatus run(IProgressMonitor monitor) {
276 			osgiRuntime.setSynchronous(false);
277 			osgiRuntime.run();
278 			while (!monitor.isCanceled()) {
279 				try {
280 					Thread.sleep(500);
281 				} catch (InterruptedException e) {
282 					// silent
283 				}
284 
285 				if (monitor.isCanceled()) {
286 					osgiRuntime.kill();
287 					return Status.CANCEL_STATUS;
288 				}
289 				if (!osgiRuntime.isRunning())
290 					break;
291 			}
292 			return Status.OK_STATUS;
293 		}
294 
295 	}
296 
297 	public void setRepository(Repository repository) {
298 		this.repository = repository;
299 	}
300 }