Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrescobar2010-03-12 18:27:25 +0000
committerrescobar2010-03-12 18:27:25 +0000
commit205aa057fa925d37a3a5375aa8418b9567e99c6d (patch)
treed33f80b9f727c479b8031aeb352494c38ad9878d /plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader
parent0e6d2b595cfb4d54eccdf3479e7c5d74d9c736a5 (diff)
downloadorg.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')
-rw-r--r--plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/EarlyStartup.java46
-rw-r--r--plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/FileChangeDetector.java85
-rw-r--r--plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/IJarChangeListener.java53
-rw-r--r--plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/JarChangeResourceListener.java202
-rw-r--r--plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/JarCollectionNature.java183
-rw-r--r--plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/SafeWorkspaceTracker.java327
-rw-r--r--plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/WorkspaceLoader.java18
-rw-r--r--plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/WorkspaceStarterNature.java31
-rw-r--r--plugins/org.eclipse.osee.framework.ui.workspacebundleloader/src/org/eclipse/osee/framework/ui/workspacebundleloader/internal/Activator.java29
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 {
+ }
+
+}

Back to the top