diff options
author | rescobar | 2010-03-12 18:27:25 +0000 |
---|---|---|
committer | rescobar | 2010-03-12 18:27:25 +0000 |
commit | 205aa057fa925d37a3a5375aa8418b9567e99c6d (patch) | |
tree | d33f80b9f727c479b8031aeb352494c38ad9878d /plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader | |
parent | 0e6d2b595cfb4d54eccdf3479e7c5d74d9c736a5 (diff) | |
download | org.eclipse.osee-205aa057fa925d37a3a5375aa8418b9567e99c6d.tar.gz org.eclipse.osee-205aa057fa925d37a3a5375aa8418b9567e99c6d.tar.xz org.eclipse.osee-205aa057fa925d37a3a5375aa8418b9567e99c6d.zip |
Diffstat (limited to 'plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader')
9 files changed, 974 insertions, 0 deletions
diff --git a/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/EarlyStartup.java b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/EarlyStartup.java new file mode 100644 index 00000000000..de9a429873d --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/EarlyStartup.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.workspacebundleloader; + +import java.util.logging.Level; +import org.eclipse.core.runtime.Platform; +import org.eclipse.osee.framework.logging.OseeLog; +import org.eclipse.osee.framework.ui.workspacebundleloader.internal.Activator; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IStartup; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleException; + +/** + * @author Andrew M. Finkbeiner + */ +public class EarlyStartup implements IStartup { + + private SafeWorkspaceTracker workspaceTracker; + + @Override + public void earlyStartup() { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + try { + Bundle bundle = Platform.getBundle("org.eclipse.osee.framework.ui.workspacebundleloader"); + bundle.start(); + workspaceTracker = new SafeWorkspaceTracker(bundle.getBundleContext()); + workspaceTracker.open(true); + } catch (BundleException ex) { + OseeLog.log(Activator.class, Level.SEVERE, ex); + } + } + }); + + } +} diff --git a/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/FileChangeDetector.java b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/FileChangeDetector.java new file mode 100644 index 00000000000..deeac2408c0 --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/FileChangeDetector.java @@ -0,0 +1,85 @@ +/*
+ * Created on Dec 10, 2009
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.framework.ui.workspacebundleloader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+
+import org.eclipse.osee.framework.jdk.core.util.ChecksumUtil;
+import org.eclipse.osee.framework.logging.OseeLog;
+
+/**
+ * @author b1528444
+ *
+ */
+public class FileChangeDetector {
+
+ private ConcurrentHashMap<URL, byte[]> bundleNameToMd5Map;
+
+ public FileChangeDetector(){
+ bundleNameToMd5Map = new ConcurrentHashMap<URL, byte[]>();
+ }
+
+ public boolean isChanged(URL url) {
+ byte[] digest = getMd5Checksum(url);
+ if (bundleNameToMd5Map.containsKey(url)) {
+ // check for bundle binary equality
+ if (!Arrays.equals(bundleNameToMd5Map.get(url), digest)) {
+ bundleNameToMd5Map.put(url, digest);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ bundleNameToMd5Map.put(url, digest);
+ return true;
+ }
+ }
+
+ private byte[] getMd5Checksum(URL url) {
+ InputStream in = null;
+ byte[] digest = new byte[0];
+ try {
+ in = url.openStream();
+ digest = ChecksumUtil.createChecksum(url.openStream(), "MD5");
+ } catch (IOException ex) {
+ OseeLog.log(FileChangeDetector.class, Level.SEVERE, ex);
+ } catch (NoSuchAlgorithmException ex) {
+ OseeLog.log(FileChangeDetector.class, Level.SEVERE, ex);
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException ex) {
+ OseeLog.log(FileChangeDetector.class, Level.SEVERE, ex);
+ }
+ }
+ }
+ return digest;
+ }
+
+ /**
+ * @param url
+ * @return
+ */
+ public boolean remove(URL url) {
+ bundleNameToMd5Map.remove(url);
+ return true;
+ }
+
+ /**
+ *
+ */
+ public void clear() {
+ bundleNameToMd5Map.clear();
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/IJarChangeListener.java b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/IJarChangeListener.java new file mode 100644 index 00000000000..cec9a2e31e5 --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/IJarChangeListener.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.workspacebundleloader;
+
+import java.net.URL;
+
+/**
+ * @author Robert A. Fisher
+ *
+ */
+public interface IJarChangeListener <T extends JarCollectionNature> {
+
+ /**
+ * Called for each addition of bundle
+ *
+ * @param url
+ */
+ public void handleBundleAdded(URL url);
+
+ /**
+ * Called for each change of bundle
+ *
+ * @param url
+ */
+ public void handleBundleChanged(URL url);
+
+ /**
+ * Called for each removal of bundle
+ *
+ * @param url
+ */
+ public void handleBundleRemoved(URL url);
+
+ /**
+ * Called after all add/change/remove methods have been
+ * invoked for a given delta.
+ */
+ public void handlePostChange();
+
+ /**
+ * Called just before a project with the nature is closed
+ * @param nature
+ */
+ public void handleNatureClosed(T nature);
+}
diff --git a/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/JarChangeResourceListener.java b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/JarChangeResourceListener.java new file mode 100644 index 00000000000..785a3d47a26 --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/JarChangeResourceListener.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.workspacebundleloader; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectNature; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.osgi.framework.BundleException; + +/** + * Handler for IResourceChangeEvent.POST_CHANGE and IResourceChangeEvent.PRE_CLOSE events for projects with a given + * nature ID that extends JarCollectionNature. POST_CHANGE events against the jars in projects with the nature, and + * close events on the projects with the nature are detected and offered to an IJarChangeListener. + * + * @author Robert A. Fisher + */ +public class JarChangeResourceListener<T extends JarCollectionNature> implements IResourceChangeListener { + private final String natureId; + private final IJarChangeListener<T> listener; + + /** + * @param natureId + * @param listener + */ + public JarChangeResourceListener(String natureId, IJarChangeListener<T> listener) { + if (natureId == null) { + throw new IllegalArgumentException("natureId must not be null"); + } + if (listener == null) { + throw new IllegalArgumentException("listener must not be null"); + } + this.natureId = natureId; + this.listener = listener; + } + + @SuppressWarnings("unchecked") + @Override + public void resourceChanged(IResourceChangeEvent event) { + try { + if (event.getType() == IResourceChangeEvent.POST_CHANGE) { + handleChangeEvent(event); + } else if (event.getType() == IResourceChangeEvent.PRE_CLOSE) { + IResource resource = event.getResource(); + if (resource != null && resource instanceof IProject) { + IProject project = (IProject) resource; + + IProjectNature nature = project.getNature(natureId); + if (nature != null) { + listener.handleNatureClosed((T) nature); + } + } + } + } catch (CoreException ex) { + } catch (MalformedURLException ex) { + } + } + + /** + * @param event + * @throws CoreException + * @throws MalformedURLException + */ + private void handleChangeEvent(IResourceChangeEvent event) throws CoreException, MalformedURLException { + IResourceDelta rootDelta = event.getDelta(); + if (rootDelta != null) { + boolean triggered = false; + for (IResourceDelta child : rootDelta.getAffectedChildren()) { + IResource resource = child.getResource(); + if (resource != null && resource instanceof IProject) { + IProject project = (IProject) resource; + + IProjectNature nature = project.getNature(natureId); + if (nature != null) { + JarCollectionNature starterNature = (JarCollectionNature) nature; + IPath[] paths = starterNature.getProjectRelativeBundlePaths(); + for (IPath path : paths) { + IResourceDelta pluginDelta = child.findMember(path); + if (pluginDelta != null && isModifyingChange(pluginDelta)) { + handlePluginChanges(project.getLocation().removeLastSegments(1), + pluginDelta.getAffectedChildren()); + triggered = true; + } + } + } + } + } + + if (triggered) { + listener.handlePostChange(); + } + } + } + + /** + * @param pluginDelta + * @return + */ + private boolean isModifyingChange(IResourceDelta pluginDelta) { + boolean synch = (pluginDelta.getFlags() & IResourceDelta.SYNC) != 0; +// boolean content = (pluginDelta.getFlags() & IResourceDelta.CONTENT) != 0; +// boolean REPLACED = (pluginDelta.getFlags() & IResourceDelta.REPLACED) != 0; +// boolean MARKERS = (pluginDelta.getFlags() & IResourceDelta.MARKERS) != 0; +// boolean TYPE = (pluginDelta.getFlags() & IResourceDelta.TYPE) != 0; +// boolean MOVED_FROM = (pluginDelta.getFlags() & IResourceDelta.MOVED_FROM) != 0; +// boolean MOVED_TO = (pluginDelta.getFlags() & IResourceDelta.MOVED_TO) != 0; +// boolean OPEN = (pluginDelta.getFlags() & IResourceDelta.OPEN) != 0; +// boolean ENCODING = (pluginDelta.getFlags() & IResourceDelta.ENCODING) != 0; +// boolean DESCRIPTION = (pluginDelta.getFlags() & IResourceDelta.DESCRIPTION) != 0; + + +// boolean ADDED = (pluginDelta.getKind() & IResourceDelta.ADDED) != 0; +// boolean CHANGED = (pluginDelta.getKind() & IResourceDelta.CHANGED) != 0; +// boolean ADDED_PHANTOM = (pluginDelta.getKind() & IResourceDelta.ADDED_PHANTOM) != 0; +// boolean REMOVED_PHANTOM = (pluginDelta.getKind() & IResourceDelta.REMOVED_PHANTOM) != 0; + return !synch; + } + + /** + * @param projectPath + * @param affectedChildren + * @throws BundleException + * @throws MalformedURLException + */ + protected void handlePluginChanges(IPath workspacePath, IResourceDelta[] affectedChildren) throws MalformedURLException { + for (IResourceDelta affectedPluginDelta : affectedChildren) { + URL url = workspacePath.append(affectedPluginDelta.getFullPath()).toFile().toURI().toURL(); + if (affectedPluginDelta.getFullPath().getFileExtension().equals("jar")) { + try { + switch (affectedPluginDelta.getKind()) { + case IResourceDelta.ADDED: + listener.handleBundleAdded(url); + break; + case IResourceDelta.CHANGED: + listener.handleBundleChanged(url); + break; + case IResourceDelta.REMOVED: + listener.handleBundleRemoved(url); + break; + + default: + System.err.println("Do not expect change kind of " + generateKindString(affectedPluginDelta.getKind())); + } + } catch (RuntimeException ex) { + ex.printStackTrace(); + throw ex; + } + } + } + } + + private String generateKindString(int kind) { + switch (kind) { + case IResourceDelta.ADDED: + return "Added"; + case IResourceDelta.CHANGED: + return "Changed"; + case IResourceDelta.REMOVED: + return "Removed"; + default: + return "Unexpected Kind: " + kind; + } + } + + /** + * @param type + * @return + */ + protected String generateEventString(int type) { + switch (type) { + case IResourceChangeEvent.POST_BUILD: + return "Post Build"; + case IResourceChangeEvent.POST_CHANGE: + return "Post Change"; + case IResourceChangeEvent.PRE_BUILD: + return "Pre Build"; + case IResourceChangeEvent.PRE_CLOSE: + return "Pre Close"; + case IResourceChangeEvent.PRE_DELETE: + return "Pre Delete"; + case IResourceChangeEvent.PRE_REFRESH: + return "Pre Refresh"; + default: + return "Unknown Code: " + type; + } + } +} diff --git a/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/JarCollectionNature.java b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/JarCollectionNature.java new file mode 100644 index 00000000000..75103491487 --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/JarCollectionNature.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.workspacebundleloader;
+
+import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FilenameFilter; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import java.util.jar.Attributes.Name; +import java.util.logging.Level; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectNature; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.osee.framework.logging.OseeLog; +
+/**
+ * @author Robert A. Fisher
+ */
+public class JarCollectionNature implements IProjectNature {
+
+ private final Name BUNDLE_PATH_ATTRIBUTE; + private boolean isClosing;
+
+ protected IProject project;
+
+ /**
+ * @param BUNDLE_PATH_ATTRIBUTE the name of the attribute in the MANIFEST.MF to look at when looking for the path to
+ * the jars being provided.
+ */
+ public JarCollectionNature(String BUNDLE_PATH_ATTRIBUTE) {
+ super();
+ this.BUNDLE_PATH_ATTRIBUTE = new Name(BUNDLE_PATH_ATTRIBUTE); + this.isClosing = false;
+ } + +
+ /** + * @return the isClosing + */ + public boolean isClosing() { + return isClosing; + } + + + /** + * @param isClosing the isClosing to set + */ + public void setClosing(boolean isClosing) { + this.isClosing = isClosing; + } + + + @Override
+ public void configure() throws CoreException {
+ }
+
+ @Override
+ public void deconfigure() throws CoreException {
+ }
+
+ @Override
+ public IProject getProject() {
+ return project;
+ }
+
+ @Override
+ public void setProject(IProject project) {
+ this.project = project;
+ }
+
+ public Collection<URL> getBundles() { + Collection<URL> urls = new ArrayList<URL>();
+ + if( isClosing ) { + return urls; + }
+ + IPath[] paths = getProjectRelativeBundlePaths();
+ for (IPath path : paths) {
+ IPath pluginsPath = project.getLocation().append(path);
+ File pluginDir = pluginsPath.toFile();
+ File[] jars = pluginDir.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }
+ });
+
+ if (jars != null) {
+ for (File jar : jars) {
+ try {
+ urls.add(jar.toURI().toURL());
+ } catch (MalformedURLException ex) {
+ OseeLog.log(JarCollectionNature.class, Level.SEVERE, ex);
+ }
+ }
+ }
+ }
+ return urls;
+ }
+
+ public IPath[] getProjectRelativeBundlePaths() {
+ Manifest manifest = getManifestFile();
+ Path[] paths;
+ Attributes mainAttributes = manifest.getMainAttributes();
+ String pathString;
+ if (mainAttributes.containsKey(BUNDLE_PATH_ATTRIBUTE)) {
+ pathString = mainAttributes.getValue(BUNDLE_PATH_ATTRIBUTE);
+ String[] tempPaths = pathString.split(",");
+ paths = new Path[tempPaths.length];
+ for (int i = 0; i < paths.length; i++) {
+ paths[i] = new Path(tempPaths[i].trim());
+ }
+ } else {
+ paths = new Path[1];
+ paths[0] = new Path("plugins");
+ }
+ return paths;
+ }
+
+ /**
+ * @param manifestFile
+ * @return
+ * @throws IOException
+ * @throws FileNotFoundException
+ */
+ private Manifest getManifestFile() {
+ try {
+ File manifestFile = project.getLocation().append("META-INF").append("MANIFEST.MF").toFile();
+ if (manifestFile.exists()) {
+ return new Manifest(new FileInputStream(manifestFile));
+ } else {
+ return null;
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected static <T extends JarCollectionNature> Collection<T> getWorkspaceProjects(String natureId, Class<T> clazz) throws CoreException {
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IWorkspaceRoot workspaceRoot = workspace.getRoot();
+ IProject[] projects = workspaceRoot.getProjects();
+
+ Collection<T> natures = new LinkedList<T>();
+
+ for (IProject project : projects) {
+ if (project.isOpen()) {
+ IProjectNature nature = project.getNature(natureId);
+ if (nature != null) {
+ JarCollectionNature jarNature = (JarCollectionNature) nature;
+ natures.add((T) jarNature);
+ }
+ }
+ }
+
+ return natures;
+ }
+}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/SafeWorkspaceTracker.java b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/SafeWorkspaceTracker.java new file mode 100644 index 00000000000..bf62898f2bc --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/SafeWorkspaceTracker.java @@ -0,0 +1,327 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.workspacebundleloader; + +import java.net.URL; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.logging.Level; + +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.osee.framework.core.operation.AbstractOperation; +import org.eclipse.osee.framework.logging.OseeLog; +import org.eclipse.osee.framework.plugin.core.util.Jobs; +import org.eclipse.osee.framework.ui.plugin.workspace.SafeWorkspaceAccess; +import org.eclipse.osee.framework.ui.workspacebundleloader.internal.Activator; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.ServiceReference; +import org.osgi.service.packageadmin.PackageAdmin; +import org.osgi.util.tracker.ServiceTracker; + +/** + * @author Andrew M. Finkbeiner + */ +public class SafeWorkspaceTracker extends ServiceTracker implements + IJarChangeListener<WorkspaceStarterNature>, WorkspaceLoader { + + private final Map<String, Bundle> installedBundles; + private final Map<String, Bundle> runningBundles; + private final Collection<Bundle> stoppedBundles; + private JarChangeResourceListener workspaceListener; + private SafeWorkspaceAccess service; + private ServiceTracker packageAdminTracker; + + private FileChangeDetector detector = new FileChangeDetector(); + + /** + * @param context + * @param filter + * @param customizer + */ + public SafeWorkspaceTracker(BundleContext context) { + super(context, SafeWorkspaceAccess.class.getName(), null); + + packageAdminTracker = new ServiceTracker(context, PackageAdmin.class + .getName(), null); + packageAdminTracker.open(true); + + this.installedBundles = new HashMap<String, Bundle>(); + this.runningBundles = new HashMap<String, Bundle>(); + this.stoppedBundles = new LinkedList<Bundle>(); + + context.registerService(WorkspaceLoader.class.getName(), this, null); + } + + @Override + public Object addingService(ServiceReference reference) { + service = (SafeWorkspaceAccess) context.getService(reference); + setupWorkspaceBundleLoadingAfterBenchStartup(); + return super.addingService(reference); + } + + void setupWorkspaceBundleLoadingAfterBenchStartup() { + Jobs.runInJob(new PrecompileStartup("Loading Precompiled Libraries", + Activator.BUNDLE_ID), false); + } + + private class PrecompileStartup extends AbstractOperation { + /** + * @param operationName + * @param pluginId + */ + public PrecompileStartup(String operationName, String pluginId) { + super(operationName, pluginId); + } + + @Override + protected void doWork(IProgressMonitor monitor) throws Exception { + IWorkspace workspace = service.getWorkspace(); + workspaceListener = new JarChangeResourceListener<WorkspaceStarterNature>( + WorkspaceStarterNature.NATURE_ID, SafeWorkspaceTracker.this); + try { + installWorkspacePlugins(); + } catch (CoreException ex) { + OseeLog.log(Activator.class, Level.SEVERE, ex); + } catch (BundleException ex) { + OseeLog.log(Activator.class, Level.SEVERE, ex); + } + workspace.addResourceChangeListener(workspaceListener); + } + } + + @Override + public synchronized void close() { + IWorkspace workspace = service.getWorkspace(); + cleanupHandledBundles(); + workspace.removeResourceChangeListener(workspaceListener); + super.close(); + } + + /** + * + */ + private void cleanupHandledBundles() { + for (Bundle bundle : installedBundles.values()) { + try { + if (bundle.getState() != Bundle.UNINSTALLED) { + bundle.uninstall(); + } + } catch (BundleException ex) { + OseeLog.log(SafeWorkspaceTracker.class, Level.INFO, ex); + } + } + for (Bundle bundle : runningBundles.values()) { + try { + bundle.stop(); + bundle.uninstall(); + } catch (BundleException ex) { + OseeLog.log(SafeWorkspaceTracker.class, Level.INFO, ex); + } + } + for (Bundle bundle : stoppedBundles) { + try { + bundle.uninstall(); + } catch (BundleException ex) { + OseeLog.log(SafeWorkspaceTracker.class, Level.INFO, ex); + } + } + refreshPackages(); + detector.clear(); + stoppedBundles.clear(); + runningBundles.clear(); + installedBundles.clear(); + } + + /** + * @param monitor + * @throws CoreException + * @throws CoreException + * @throws BundleException + * @throws BundleException + */ + private void installWorkspacePlugins() throws CoreException, + BundleException { + + loadBundles(); + } + + /** + * @param url + * @throws BundleException + */ + @Override + public void handleBundleAdded(URL url) { + try { + if (detector.isChanged(url)) { + String urlString = url.toString(); + Bundle bundle = context.installBundle(urlString); + installedBundles.put(urlString, bundle); + } + } catch (BundleException ex) { + OseeLog.log(SafeWorkspaceTracker.class, Level.SEVERE, ex); + } + } + + /** + * @param stoppedBundles + * @param url + * @throws BundleException + */ + @Override + public void handleBundleChanged(URL url) { + try { + if (detector.isChanged(url)) { + String urlString = url.toString(); + + // Check to see if this is the first we've seen this + if (runningBundles.containsKey(urlString)) { + Bundle bundle = runningBundles.get(urlString); + System.out.println("\tUpdating plugin " + + bundle.getSymbolicName()); + + bundle.update(); + } else { + handleBundleAdded(url); + } + } + } catch (BundleException ex) { + } + } + + /** + * @param stoppedBundles + * @param url + * @throws BundleException + */ + @Override + public void handleBundleRemoved(URL url) { + try { + detector.remove(url); + String urlString = url.toString(); + if (runningBundles.containsKey(urlString)) { + Bundle bundle = runningBundles.get(urlString); + System.out.println("\tStopping plugin " + + bundle.getSymbolicName()); + + bundle.stop(); + runningBundles.remove(urlString); + stoppedBundles.add(bundle); + } + } catch (BundleException ex) { + } + } + + /** + * @throws BundleException + */ + private void transitionInstalledPlugins() throws BundleException { + Iterator<String> iter = installedBundles.keySet().iterator(); + while (iter.hasNext()) { + String urlString = iter.next(); + Bundle bundle = installedBundles.get(urlString); + try { + bundle.start(); + iter.remove(); + runningBundles.put(urlString, bundle); + } catch (Throwable th) { + OseeLog.log(Activator.class, Level.SEVERE, th); + } + } + refreshPackages(); + } + + /** + * + */ + private void refreshPackages() { + PackageAdmin packageAdmin = (PackageAdmin) packageAdminTracker + .getService(); + packageAdmin.refreshPackages(null); + // try { + // Thread.sleep(10000); + // } catch (InterruptedException ex) { + // } + } + + /** + * @throws BundleException + */ + private void transitionStoppedBundles() throws BundleException { + Iterator<Bundle> iter = stoppedBundles.iterator(); + while (iter.hasNext()) { + Bundle bundle = iter.next(); + try { + bundle.uninstall(); + + iter.remove(); + } catch (Throwable th) { + OseeLog.log(Activator.class, Level.SEVERE, th); + } + } + refreshPackages(); + } + + @Override + public void handlePostChange() { + try { + transitionInstalledPlugins(); + transitionStoppedBundles(); + } catch (BundleException ex) { + } + } + + @Override + public void handleNatureClosed(WorkspaceStarterNature nature) { + closeAllPlugins(nature); + } + + /** + * @param project + * @throws CoreException + * @throws BundleException + */ + private void closeAllPlugins(WorkspaceStarterNature nature) { + for (URL url : nature.getBundles()) { + handleBundleRemoved(url); + } + + try { + transitionStoppedBundles(); + } catch (BundleException ex) { + } + } + + public void loadBundles() throws CoreException, BundleException { + for (WorkspaceStarterNature starterNature : WorkspaceStarterNature + .getWorkspaceProjects()) { + for (URL url : starterNature.getBundles()) { + try { + handleBundleAdded(url); + } catch (Exception ex) { + OseeLog.log(SafeWorkspaceTracker.class, Level.INFO, ex); + ex.printStackTrace(); + } + } + } + transitionInstalledPlugins(); + } + + public void unloadBundles() { + cleanupHandledBundles(); + } +} diff --git a/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/WorkspaceLoader.java b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/WorkspaceLoader.java new file mode 100644 index 00000000000..c881a62efbb --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/WorkspaceLoader.java @@ -0,0 +1,18 @@ +/*
+ * Created on Dec 8, 2009
+ *
+ * PLACE_YOUR_DISTRIBUTION_STATEMENT_RIGHT_HERE
+ */
+package org.eclipse.osee.framework.ui.workspacebundleloader;
+
+import org.eclipse.core.runtime.CoreException;
+import org.osgi.framework.BundleException;
+
+/**
+ * @author b1528444
+ *
+ */
+public interface WorkspaceLoader {
+ public void loadBundles() throws CoreException, BundleException;
+ public void unloadBundles();
+}
diff --git a/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/WorkspaceStarterNature.java b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/WorkspaceStarterNature.java new file mode 100644 index 00000000000..eeb2cd22012 --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/WorkspaceStarterNature.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 Boeing. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.framework.ui.workspacebundleloader; + +import java.util.Collection; +import org.eclipse.core.runtime.CoreException; + +/** + * @author Robert A. Fisher + * @author Andrew M. Finkbeiner + */ +public class WorkspaceStarterNature extends JarCollectionNature { + public static final String NATURE_ID = "org.eclipse.osee.framework.ui.workspacebundleloader.WorkspaceStarterNature"; + static final String BUNDLE_PATH_ATTRIBUTE = "WorkspaceBundlePath"; + + public WorkspaceStarterNature() { + super(BUNDLE_PATH_ATTRIBUTE); + } + + public static Collection<WorkspaceStarterNature> getWorkspaceProjects() throws CoreException { + return getWorkspaceProjects(NATURE_ID, WorkspaceStarterNature.class); + } +} diff --git a/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/internal/Activator.java b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/internal/Activator.java new file mode 100644 index 00000000000..215d8521b75 --- /dev/null +++ b/plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/internal/Activator.java @@ -0,0 +1,29 @@ +/*******************************************************************************
+ * Copyright (c) 2009 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.ui.workspacebundleloader.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * @author Ryan D. Brooks
+ */
+public class Activator implements BundleActivator {
+
+ public static final String BUNDLE_ID = "org.eclipse.osee.framework.ui.workspacebundleloader";
+
+public void start(BundleContext context) throws Exception {
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ }
+
+}
|