Skip to main content
summaryrefslogblamecommitdiffstats
blob: 02a85e5e504cd9ee1d04c032422e560efe326a4f (plain) (tree)




























                                                                                 

                                                                   
                                                  
                                                        
                                                                          
                                                                                     

                                                  
                                                                           


                                                                                  





                                            
   

                                                                                      








                                                                                    



















                                                                                                              





                                                                                                               
























































                                                                                                                        









































                                                                                                                                 













                                                                                           









                                                                                     














                                                                                                






                                                                                           
                                                    



                                                                            
                                                     


















                                                                                                             
        

                             
 
/*******************************************************************************
 * 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.ote.runtimemanager;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
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.JarChangeResourceListener;
import org.eclipse.osee.ote.core.BundleInfo;
import org.eclipse.osee.ote.core.OteBundleLocator;
import org.eclipse.osee.ote.runtimemanager.container.OteClasspathContainer;
import org.eclipse.osee.ote.runtimemanager.internal.ProjectChangeResourceListener;
import org.eclipse.osee.ote.runtimemanager.internal.RuntimeBundleServer;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;

/**
 * @author Robert A. Fisher
 * @author Andrew M. Finkbeiner
 */
public class SafeWorkspaceTracker extends ServiceTracker implements OteBundleLocator {

   private JarChangeResourceListener<OteSystemLibsNature> systemLibResourceListener;
   private JarChangeResourceListener<OteUserLibsNature> userLibResourceListener;
   private LibJarListener<OteSystemLibsNature> systemLibListener;
   private LibJarListener<OteUserLibsNature> userLibListener;
   private ProjectChangeResourceListener projectChangeResourceListener;
   private RuntimeBundleServer bundleServer;
   private SafeWorkspaceAccess service;
   private final BundleContext context;

   public SafeWorkspaceTracker(BundleContext context) {
      super(context, SafeWorkspaceAccess.class.getName(), null);
      this.context = context;
   }

   @Override
   public Object addingService(ServiceReference reference) {
      this.systemLibListener = new LibJarListener<OteSystemLibsNature>();
      this.userLibListener = new LibJarListener<OteUserLibsNature>();
      this.systemLibResourceListener =
         new JarChangeResourceListener<OteSystemLibsNature>(OteSystemLibsNature.NATURE_ID, systemLibListener);
      this.userLibResourceListener =
         new JarChangeResourceListener<OteUserLibsNature>(OteUserLibsNature.NATURE_ID, userLibListener);
      this.projectChangeResourceListener = new ProjectChangeResourceListener();
      service = (SafeWorkspaceAccess) context.getService(reference);
      slowLoadingJars();

      return super.addingService(reference);
   }

   private void slowLoadingJars() {
      Jobs.runInJob(new LocateWorkspaceBundles("Locating Workspace Bundles", RuntimeManager.BUNDLE_ID), false);

   }

   private class LocateWorkspaceBundles extends AbstractOperation {
      public LocateWorkspaceBundles(String operationName, String pluginId) {
         super(operationName, pluginId);
      }

      @SuppressWarnings("rawtypes")
      @Override
      protected void doWork(IProgressMonitor monitor) throws Exception {
         IWorkspace workspace = service.getWorkspace();
         try {
            scrapeAllLibs();
         } catch (CoreException ex) {
            OseeLog.log(RuntimeManager.class, Level.SEVERE, ex);
         }
         workspace.addResourceChangeListener(systemLibResourceListener);
         workspace.addResourceChangeListener(userLibResourceListener);

         SafeWorkspaceTracker.this.bundleServer = new RuntimeBundleServer(SafeWorkspaceTracker.this);

         context.registerService(OteBundleLocator.class.getName(), SafeWorkspaceTracker.this, new Hashtable());
         OteClasspathContainer.refreshAll();
      }
   }

   private void scrapeAllLibs() throws CoreException {
      for (OteSystemLibsNature nature : OteSystemLibsNature.getWorkspaceProjects()) {
         for (URL url : nature.getBundles()) {
            systemLibListener.handleBundleAdded(url);
         }

         projectChangeResourceListener.addProject(nature.getProject());
      }
      for (OteUserLibsNature nature : OteUserLibsNature.getWorkspaceProjects()) {
         for (URL url : nature.getBundles()) {
            userLibListener.handleBundleAdded(url);
         }

         projectChangeResourceListener.addProject(nature.getProject());
      }
   }

   @Override
   public synchronized void close() {
      IWorkspace workspace = service.getWorkspace();
      if (workspace != null) {
         workspace.removeResourceChangeListener(systemLibResourceListener);
         workspace.removeResourceChangeListener(userLibResourceListener);
      }
      super.close();
   }

   /**
    * Returns a list of URL's to workspace jars to be used for the test server. The collection returned is a combination
    * of all the user libraries and any system libraries that weren't already supplied in the user libraries. The
    * workspace is considered to have runtime libraries only if there are system libraries present. Subsequently, if no
    * system libraries are in the workspace then this method will return an empty collection.
    * 
    * @return runtime library bundle infos
    */
   @Override
   public Collection<BundleInfo> getRuntimeLibs() throws IOException, CoreException {
      Collection<URL> userLibUrls = getUserLibUrls();
      Collection<URL> systemLibUrls = getSystemLibUrls();
      // If there are no system libs, then claim no runtime libs
      if (!systemLibUrls.isEmpty()) {
         return getRuntimeLibs(systemLibUrls, userLibUrls);
      } else {
         return Collections.emptyList();
      }
   }

   private Collection<BundleInfo> getRuntimeLibs(Collection<URL> systemLibUrls, Collection<URL> userLibUrls) throws IOException {
      Map<String, BundleInfo> runtimeMap = new HashMap<String, BundleInfo>();
      Collection<BundleInfo> runtimeInfos = new LinkedList<BundleInfo>();

      // First add all of the system libraries to the map
      for (URL url : systemLibUrls) {
         String symbolicName = getBundleNameFromJar(url);

         runtimeMap.put(symbolicName, new BundleInfo(url, bundleServer.getClassServerPath(), true));
      }

      // Now add the user libraries so any system library with the same name
      // gets replaced
      for (URL url : userLibUrls) {
         String symbolicName = getBundleNameFromJar(url);

         runtimeMap.put(symbolicName, new BundleInfo(url, bundleServer.getClassServerPath(), false));
      }

      runtimeInfos.addAll(runtimeMap.values());

      return runtimeInfos;
   }

   /**
    * Returns a list of URL's to all system libraries in the workspace regardless of ones that are supplied in user
    * libraries.
    * 
    * @return system library URL's
    */
   public Collection<URL> getSystemLibUrls() throws CoreException {
      Collection<URL> libs = new LinkedList<URL>();
      for (OteSystemLibsNature systemNature : OteSystemLibsNature.getWorkspaceProjects()) {
         libs.addAll(systemNature.getBundles());
      }

      return libs;
   }

   /**
    * Returns a list of URL's to all user libraries in the workspace.
    * 
    * @return user library URL's
    */
   public Collection<URL> getUserLibUrls() throws CoreException {
      Collection<URL> libs = new LinkedList<URL>();
      for (OteUserLibsNature userNature : OteUserLibsNature.getWorkspaceProjects()) {
         libs.addAll(userNature.getBundles());
      }

      return libs;
   }

   private String getBundleNameFromJar(URL url) throws IOException {
      File file;
      try {
         file = new File(url.toURI());
      } catch (URISyntaxException ex) {
         file = new File(url.getPath());
      }

      JarFile jarFile = new JarFile(file);
      Manifest jarManifest = jarFile.getManifest();
      return BundleInfo.generateBundleName(jarManifest);
   }

   /**
    * Returns a list of all bundles that have been modified since the last time this was called.
    */
   @Override
   public Collection<BundleInfo> consumeModifiedLibs() throws IOException {
      //		Collection<BundleInfo> modifiedLibs = new LinkedList<BundleInfo>();

      Set<URL> sysNewBundles = systemLibListener.consumeNewBundles();
      Set<URL> sysChangedBundles = systemLibListener.consumeChangedBundles();
      //		Set<URL> sysRemovedBundles =
      systemLibListener.consumeRemovedBundles();

      Set<URL> userNewBundles = userLibListener.consumeNewBundles();
      Set<URL> userChangedBundles = userLibListener.consumeChangedBundles();
      //		Set<URL> userRemovedBundles =
      userLibListener.consumeRemovedBundles();

      Collection<URL> sysNewModLibs = new ArrayList<URL>(sysNewBundles.size() + sysChangedBundles.size());
      sysNewModLibs.addAll(sysNewBundles);
      sysNewModLibs.addAll(sysChangedBundles);

      Collection<URL> userNewModLibs = new ArrayList<URL>(userNewBundles.size() + userChangedBundles.size());
      userNewModLibs.addAll(userNewBundles);
      userNewModLibs.addAll(userChangedBundles);

      // TODO what about removed libs?
      return getRuntimeLibs(sysNewModLibs, userNewModLibs);

      // // For now, return all user libs
      // for (BundleInfo info : getRuntimeLibs()) {
      // if (!info.isSystemLibrary()) {
      // modifiedLibs.add(info);
      // }
      // }
      //
      // return modifiedLibs;
   }
}

Back to the top