/** * */ package org.eclipse.iee.web.server.store; import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; import static java.nio.file.StandardWatchEventKinds.OVERFLOW; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.nio.file.attribute.BasicFileAttributes; import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; import org.eclipse.iee.core.document.Document; import org.eclipse.iee.core.document.parser.IDocumentParser; import org.eclipse.iee.core.store.IDocumentStore; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; import org.osgi.framework.launch.Framework; import org.osgi.framework.launch.FrameworkFactory; import com.google.common.base.Throwables; /** * @author Toxin * */ public class OSGIContainerDocumentStore implements IDocumentStore { private Framework framework; private IDocumentParser documentParser; private Thread watchThread; public OSGIContainerDocumentStore(String folder, IDocumentParser documentParser) { this.documentParser = documentParser; FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next(); Map<String, String> config = new HashMap<String, String>(); config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "org.eclipse.iee.core, com.ieecloud.ui.viewer, org.apache.commons.codec.binary; version=\"1.4.0\", org.apache.commons.io"); config.put(Constants.FRAMEWORK_STORAGE, folder + "/osgi-area"); config.put(Constants.FRAMEWORK_STORAGE_CLEAN, "true"); framework = frameworkFactory.newFramework(config); try { framework.start(); System.out.println(framework.getBundleContext().getProperty(Constants.FRAMEWORK_STORAGE)); Bundle[] bundles = framework.getBundleContext().getBundles(); for (Bundle bundle : bundles) { if (bundle.getBundleId() != 0) { Path path = Paths.get(new URI(bundle.getLocation())); if (!Files.exists(path)) { bundle.uninstall(); } else { System.out.println(bundle.getLocation()); } } } Path start = Paths.get(folder + "/doc"); if (!Files.exists(start)) { Files.createDirectory(start); } final WatchService watcher = FileSystems.getDefault().newWatchService(); watchThread = new Thread(new Runnable() { @Override public void run() { for (;;) { WatchKey key; try { key = watcher.take(); } catch (InterruptedException x) { return; } for (WatchEvent<?> event: key.pollEvents()) { WatchEvent.Kind<?> kind = event.kind(); if (kind == OVERFLOW) { continue; } Path dir = (Path) key.watchable(); Path fullPath = dir.resolve((Path) event.context()); if (fullPath.toUri().getPath().endsWith(".jar")) { if (kind == ENTRY_CREATE) { try { installJar(fullPath); } catch (Exception e) { e.printStackTrace(); } } else if (kind == ENTRY_MODIFY) { Bundle bundle = framework.getBundleContext().getBundle(fullPath.toAbsolutePath().toUri().toString()); if (bundle != null) { try { bundle.update(); } catch (BundleException e) { e.printStackTrace(); } } } else if (kind == ENTRY_DELETE) { Bundle bundle = framework.getBundleContext().getBundle(fullPath.toAbsolutePath().toUri().toString()); if (bundle != null) { try { bundle.uninstall(); } catch (BundleException e) { e.printStackTrace(); } } } } boolean valid = key.reset(); if (!valid) { break; } } } } }); watchThread.start(); Files.walkFileTree(start, new SimpleFileVisitor<Path>() { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { dir.register(watcher, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (file.toUri().getPath().endsWith(".jar")) { installJar(file); } return FileVisitResult.CONTINUE; } }); } catch (BundleException | IOException | URISyntaxException e) { Throwables.propagate(e); } } private void installJar(Path file) { try { String location = file.toAbsolutePath().toUri().toString(); Bundle bundle = framework.getBundleContext().getBundle(location); System.out.println(location); if (bundle != null) { return; } bundle = framework.getBundleContext().installBundle(location); bundle.start(); } catch (BundleException e) { Throwables.propagate(e); } } @Override public Document getDocument(String bundle, String document) throws IOException { Bundle bundle2 = getBundle(framework.getBundleContext(), bundle); if (bundle2 == null) { return null; } URL resource = bundle2.getEntry("/src/" + document + ".java"); Document parsedDocument; try (InputStream stream = resource.openStream()) { parsedDocument = documentParser.parseDocument(stream); } return parsedDocument; } private Bundle getBundle(BundleContext bundleContext, String symbolicName) { Bundle result = null; for (Bundle candidate : bundleContext.getBundles()) { if (symbolicName.equals(candidate.getSymbolicName())) { if (result == null || result.getVersion().compareTo(candidate.getVersion()) < 0) { result = candidate; } } } return result; } @Override public Class<?> getDocumentClass(String bundle, String document) throws IOException, ClassNotFoundException { return getBundle(framework.getBundleContext(), bundle).loadClass(document); } @Override public InputStream getResourceAsStream(String bundle, String document, String resource) throws IOException { return getBundle(framework.getBundleContext(), bundle).getResource(resource).openStream(); } public void stop() { watchThread.interrupt(); } }