/**
   * Tests the behavior of {@link AcceleoCommonPlugin#log(Exception, boolean)} passing an arbitrary
   * exception other than {@link NullPointerException} and {@link CoreException} to be logged.
   * Expects the exception to be logged with the specified severity. The error message should be the
   * one specified in org.eclipse.acceleo.common.acceleocommonmessages.properties with key
   * "AcceleoCommonPlugin.JavaException".
   */
  public void testLogExceptionArbitraryException() {
    boolean blocker = false;
    for (String message : ERROR_MESSAGES) {
      final PrintStream systemErr = System.err;
      // disables standard error to avoid all logged exception to be displayed in console.
      final Exception exception = new IllegalArgumentException(message);
      System.setErr(temporaryErr);
      AcceleoCommonPlugin.log(exception, blocker);
      System.setErr(systemErr);

      final int expectedSeverity;
      if (blocker) {
        expectedSeverity = IStatus.ERROR;
      } else {
        expectedSeverity = IStatus.WARNING;
      }
      blocker = !blocker;

      assertEquals(
          "Unexpected message of the logged exception.",
          exception.getMessage(),
          loggedStatus.getMessage());
      assertEquals(
          "Unexpected severity of the logged exception.",
          expectedSeverity,
          loggedStatus.getSeverity());
      assertEquals(
          "Exception logged with unexpected plug-in ID.",
          AcceleoCommonPlugin.PLUGIN_ID,
          loggedStatus.getPlugin());
    }
  }
  /**
   * {@inheritDoc}
   *
   * @see junit.framework.TestCase#setUp()
   */
  @Override
  protected void setUp() {
    // Creates a log listener that will update the field loggedStatus as needed
    logListener =
        new ILogListener() {
          public void logging(IStatus status, String message) {
            loggedStatus = status;
          }
        };
    // Then sets it to listen to the log
    AcceleoCommonPlugin.getDefault().getLog().addLogListener(logListener);

    try {
      // Creates temporary error log
      final File dataDir =
          new File(
              FileLocator.toFileURL(
                      AcceleoCommonTestPlugin.getDefault().getBundle().getEntry("/data"))
                  .getFile());
      temporaryLog = new File(dataDir.getAbsolutePath() + "/testLogErrorLog");
      temporaryErr = new PrintStream(temporaryLog);
    } catch (IOException e) {
      fail("Couldn't create temporary error log.");
    }
  }
  /**
   * Tests the behavior of {@link AcceleoCommonPlugin#log(Exception, boolean)} passing a {@link
   * NullPointerException} to be logged. Expects the exception to be logged with the specified
   * severity. The error message should be the one specified in
   * org.eclipse.acceleo.common.acceleocommonmessages.properties with key
   * "AcceleoCommonPlugin.ElementNotFound".
   */
  public void testLogExceptionNullPointerException() {
    boolean blocker = false;
    for (String message : ERROR_MESSAGES) {
      // disables standard error to avoid all logged exception to be displayed in console.
      final PrintStream systemErr = System.err;
      System.setErr(temporaryErr);
      AcceleoCommonPlugin.log(new NullPointerException(message), blocker);
      System.setErr(systemErr);

      final String expectedMessage =
          AcceleoCommonMessages.getString("AcceleoCommonPlugin.ElementNotFound");
      final int expectedSeverity;
      if (blocker) {
        expectedSeverity = IStatus.ERROR;
      } else {
        expectedSeverity = IStatus.WARNING;
      }
      blocker = !blocker;

      assertEquals(
          "Unexpected message of the logged NullPointerException.",
          expectedMessage,
          loggedStatus.getMessage());
      assertEquals(
          "Unexpected severity of the logged NullPointerException.",
          expectedSeverity,
          loggedStatus.getSeverity());
      assertEquals(
          "NullPointerException logged with unexpected plug-in ID.",
          AcceleoCommonPlugin.PLUGIN_ID,
          loggedStatus.getPlugin());
    }
  }
Example #4
0
  /**
   * Loads the class <code>qualifiedName</code> from the specified <code>bundle</code> if possible.
   *
   * @param bundle The bundle from which to load the sought class.
   * @param qualifiedName Qualified name of the class that is to be loaded.
   * @return An instance of the class if it could be loaded, <code>null</code> otherwise.
   */
  private Class<?> internalLoadClass(Bundle bundle, String qualifiedName) {
    try {
      WorkspaceClassInstance workspaceInstance = workspaceLoadedClasses.get(qualifiedName);
      final Class<?> clazz;
      if (workspaceInstance == null) {
        clazz = bundle.loadClass(qualifiedName);
        workspaceLoadedClasses.put(
            qualifiedName, new WorkspaceClassInstance(clazz, bundle.getSymbolicName()));
      } else if (workspaceInstance.isStale()) {
        clazz = bundle.loadClass(qualifiedName);
        workspaceInstance.setStale(false);
        workspaceInstance.setClass(clazz);
      } else {
        clazz = workspaceInstance.getClassInstance();
      }

      return clazz;
    } catch (ClassNotFoundException e) {
      e.fillInStackTrace();
      AcceleoCommonPlugin.log(
          AcceleoCommonMessages.getString(
              "BundleClassLookupFailure", //$NON-NLS-1$
              qualifiedName,
              bundle.getSymbolicName()),
          e,
          false);
    }
    return null;
  }
  /**
   * Tests the behavior of {@link AcceleoCommonPlugin#log(String, boolean)} with <code>null</code>
   * as the message to be logged. Expects a new entry to be logged with the given severity and the
   * message specified in org.eclipse.acceleo.common.acceleocommonmessages.properties with key
   * &quot;AcceleoCommonPlugin.UnexpectedException&quot;.
   */
  public void testLogMessageNullMessage() {
    boolean blocker = false;
    for (int i = 0; i < ERROR_MESSAGES.length; i++) {
      final PrintStream systemErr = System.err;
      // disables standard error to avoid all logged exception to be displayed in console.
      System.setErr(temporaryErr);
      AcceleoCommonPlugin.log((String) null, blocker);
      System.setErr(systemErr);

      final String expectedMessage =
          AcceleoCommonMessages.getString("AcceleoCommonPlugin.UnexpectedException");
      final int expectedSeverity;
      if (blocker) {
        expectedSeverity = IStatus.ERROR;
      } else {
        expectedSeverity = IStatus.WARNING;
      }
      blocker = !blocker;

      assertEquals(
          "Unexpected message of the logged message.", expectedMessage, loggedStatus.getMessage());
      assertEquals(
          "Unexpected severity of the logged message.",
          expectedSeverity,
          loggedStatus.getSeverity());
      assertEquals(
          "Message logged with unexpected plug-in ID.",
          AcceleoCommonPlugin.PLUGIN_ID,
          loggedStatus.getPlugin());
    }
  }
Example #6
0
  /**
   * This will try and find a resource of the given name using the bundle from which was originally
   * loaded the given class so as to try and detect if it is jarred. If <code>clazz</code> hasn't
   * been loaded from a bundle class loader, we'll resort to the default class loader mechanism.
   * This will only return <code>null</code> in the case where the resource at <code>resourcePath
   * </code> cannot be located at all.
   *
   * @param clazz Class which class loader will be used to try and locate the resource.
   * @param resourcePath Path of the resource we seek, relative to the class.
   * @return The URL of the resource as we could locate it.
   * @throws IOException This will be thrown if we fail to convert bundle-scheme URIs into
   *     file-scheme URIs.
   */
  public static URL getResourceURL(Class<?> clazz, String resourcePath) throws IOException {
    BundleContext context = AcceleoCommonPlugin.getDefault().getContext();
    ServiceReference packageAdminReference =
        context.getServiceReference(PackageAdmin.class.getName());
    PackageAdmin packageAdmin = null;
    if (packageAdminReference != null) {
      packageAdmin = (PackageAdmin) context.getService(packageAdminReference);
    }

    URL resourceURL = null;
    if (packageAdmin != null) {
      Bundle bundle = packageAdmin.getBundle(clazz);
      if (bundle != null) {
        final String pathSeparator = "/"; // $NON-NLS-1$
        // We found the appropriate bundle. We'll now try and determine whether the emtl is jarred
        resourceURL = getBundleResourceURL(bundle, pathSeparator, resourcePath);
      }
    }
    /*
     * We couldn't locate either the bundle which loaded the class or the resource. Resort to the class
     * loader and return null if it cannot locate the resource either.
     */
    if (resourceURL == null) {
      resourceURL = clazz.getResource(resourcePath);
    }

    if (packageAdminReference != null) {
      context.ungetService(packageAdminReference);
    }
    return resourceURL;
  }
  /** Initializes the non-standard library package along with its content. */
  public AcceleoNonStandardLibrary() {
    final ResourceSet resourceSet = new ResourceSetImpl();
    /*
     * Crude workaround : We try not to reload the std lib for no reason, but that means the OCL standard
     * lib used for our references must be the sole instance used by OCL. FIXME : For now, use internals
     * ... try and find a way to use it without restricted access.
     */
    resourceSet.getResources().add(OCLStandardLibraryImpl.INSTANCE.getString().eResource());

    try {
      if (nonStdLibPackage == null) {
        nonStdLibPackage = (EPackage) ModelUtils.load(URI.createURI(NS_URI), resourceSet);
        collectionType = (EClass) nonStdLibPackage.getEClassifier(TYPE_COLLECTION_NAME);
        eObjectType = (EClass) nonStdLibPackage.getEClassifier(TYPE_EOBJECT_NAME);
        oclAnyType = (EClass) nonStdLibPackage.getEClassifier(TYPE_OCLANY_NAME);
        orderedSetType = (EClass) nonStdLibPackage.getEClassifier(TYPE_ORDEREDSET_NAME);
        sequenceType = (EClass) nonStdLibPackage.getEClassifier(TYPE_SEQUENCE_NAME);
        stringType = (EClass) nonStdLibPackage.getEClassifier(PRIMITIVE_STRING_NAME);
      }
    } catch (IOException e) {
      AcceleoCommonPlugin.log(
          AcceleoCommonMessages.getString("AcceleoNonStandardLibrary.LoadFailure"),
          false); //$NON-NLS-1$
    }
  }
 /**
  * Tests the behavior of {@link AcceleoCommonPlugin#log(IStatus)} with <code>null</code> as the
  * status to be logged. Expects a {@link NullPointerException} to be thrown with the given status'
  * error message.
  */
 public void testLogStatusNullStatus() {
   try {
     AcceleoCommonPlugin.log(null);
     fail("Logging null status didn't throw expected NullPointerException.");
   } catch (NullPointerException e) {
     // This ws expected behavior
   }
 }
 /**
  * Tests the behavior of {@link AcceleoCommonPlugin#log(Exception, boolean)} with <code>null
  * </code> as the exception argument. Expects a {@link NullPointerException} to be thrown.
  */
 public void testLogExceptionNullException() {
   try {
     AcceleoCommonPlugin.log((Exception) null, true);
     fail("Logging null didn't throw expected NullPointerException.");
   } catch (NullPointerException e) {
     // This was expected behavior
   }
 }
Example #10
0
 /**
  * Returns the bundle corresponding to the given location if any.
  *
  * @param pluginLocation The location of the bundle we seek.
  * @return The bundle corresponding to the given location if any, <code>null</code> otherwise.
  */
 private static Bundle getBundle(String pluginLocation) {
   Bundle[] bundles = AcceleoCommonPlugin.getDefault().getContext().getBundles();
   for (int i = 0; i < bundles.length; i++) {
     if (pluginLocation.equals(bundles[i].getLocation())) {
       return bundles[i];
     }
   }
   return null;
 }
Example #11
0
  /**
   * This will refresh the workspace contributions if needed, then search through the workspace
   * loaded bundles for a class corresponding to <code>qualifiedName</code>.
   *
   * @param qualifiedName The qualified name of the class we seek to load.
   * @param honorOSGiVisibility If <code>true</code>, this will only search through exported
   *     packages for the class <code>qualifiedName</code>. Otherwise we'll search through all
   *     bundles by simply trying to load the class and catching the {@link ClassNotFoundException}
   *     if it isn't loadable.
   * @return The class <code>qualifiedName</code> if it could be found in the workspace bundles,
   *     <code>null</code> otherwise.
   */
  public synchronized Class<?> getClass(String qualifiedName, boolean honorOSGiVisibility) {
    if (changedContributions.size() > 0) {
      refreshContributions();
    }

    // Has an instance of this class already been loaded?
    Class<?> clazz = null;
    final WorkspaceClassInstance workspaceInstance = workspaceLoadedClasses.get(qualifiedName);
    if (workspaceInstance != null) {
      if (workspaceInstance.isStale()) {
        for (Map.Entry<IPluginModelBase, Bundle> entry : workspaceInstalledBundles.entrySet()) {
          final IPluginModelBase model = entry.getKey();
          if (workspaceInstance
              .getBundle()
              .equals(model.getBundleDescription().getSymbolicName())) {
            clazz = internalLoadClass(entry.getValue(), qualifiedName);
            workspaceInstance.setStale(false);
            workspaceInstance.setClass(clazz);
            break;
          }
        }
      } else {
        clazz = workspaceInstance.getInstance().getClass();
      }
    }
    if (clazz != null) {
      return clazz;
    }

    // The class hasn't been instantiated yet ; search for the class without instantiating it
    Iterator<Map.Entry<IPluginModelBase, Bundle>> iterator =
        workspaceInstalledBundles.entrySet().iterator();
    while (clazz == null && iterator.hasNext()) {
      Map.Entry<IPluginModelBase, Bundle> entry = iterator.next();
      /*
       * If we're asked to honor OSGi package visibility, we'll first check the "Export-Package" header
       * of this bundle's MANIFEST.
       */
      if (!honorOSGiVisibility || hasCorrespondingExportPackage(entry.getKey(), qualifiedName)) {
        try {
          clazz = entry.getValue().loadClass(qualifiedName);
        } catch (ClassNotFoundException e) {
          // Swallow this ; we'll log the issue later on if we cannot find the class at all
        }
      }
    }

    if (clazz == null) {
      AcceleoCommonPlugin.log(
          AcceleoCommonMessages.getString(
              "BundleClassLookupFailure", //$NON-NLS-1$
              qualifiedName),
          false);
    }

    return clazz;
  }
 /**
  * {@inheritDoc}
  *
  * @see junit.framework.TestCase#tearDown()
  */
 @Override
 protected void tearDown() {
   AcceleoCommonPlugin.getDefault().getLog().removeLogListener(logListener);
   if (temporaryErr != null) {
     temporaryErr.close();
   }
   if (temporaryLog.exists()) {
     temporaryLog.delete();
   }
 }
Example #13
0
 /**
  * Installs the bundle corresponding to the given location. This will fail if the location doesn't
  * point to a valid bundle.
  *
  * @param pluginLocation Location of the bundle to be installed.
  * @return The installed bundle.
  * @throws BundleException Thrown if the Bundle isn't valid.
  * @throws IllegalStateException Thrown if the bundle couldn't be installed properly.
  */
 private Bundle installBundle(String pluginLocation)
     throws BundleException, IllegalStateException {
   Bundle target = AcceleoCommonPlugin.getDefault().getContext().installBundle(pluginLocation);
   int state = target.getState();
   if (state != Bundle.INSTALLED) {
     throw new IllegalStateException(
         AcceleoCommonMessages.getString(
             "WorkspaceUtil.IllegalBundleState", target, Integer.valueOf(state))); // $NON-NLS-1$
   }
   return target;
 }
Example #14
0
  /**
   * Returns the bundles with the given name.
   *
   * @param bundleName The bundle name.
   * @return The bundles with the given name.
   */
  public static Bundle[] getBundles(String bundleName) {
    Bundle[] bundle = null;
    BundleContext context = AcceleoCommonPlugin.getDefault().getContext();
    ServiceReference packageAdminReference =
        context.getServiceReference(PackageAdmin.class.getName());
    PackageAdmin packageAdmin = null;
    if (packageAdminReference != null) {
      packageAdmin = (PackageAdmin) context.getService(packageAdminReference);
    }

    if (packageAdmin != null) {
      bundle = packageAdmin.getBundles(bundleName, null);
    }
    if (packageAdminReference != null) {
      context.ungetService(packageAdminReference);
    }
    return bundle;
  }
  /**
   * Tests the behavior of {@link AcceleoCommonPlugin#log(IStatus)} with a valid status to be
   * logged. Expects the status to be logged with the specified severity, error message and source
   * plugin.
   */
  public void testLogStatusValidStatus() {
    for (int severity : ERROR_SEVERITIES) {
      for (String message : ERROR_MESSAGES) {
        final Status status = new Status(severity, AcceleoCommonTestPlugin.PLUGIN_ID, message);
        final PrintStream systemErr = System.err;
        // disables standard error to avoid all logged exception to be displayed in console.
        System.setErr(temporaryErr);
        AcceleoCommonPlugin.log(status);
        System.setErr(systemErr);

        assertEquals(
            "Unexpected message of the logged exception.", message, loggedStatus.getMessage());
        assertEquals(
            "Unexpected severity of the logged exception.", severity, loggedStatus.getSeverity());
        assertEquals(
            "Exception logged with unexpected plug-in ID.",
            AcceleoCommonTestPlugin.PLUGIN_ID,
            loggedStatus.getPlugin());
      }
    }
  }
Example #16
0
  /**
   * This can be used to check whether the given class is located in a dynamically installed bundle.
   *
   * @param clazz The class of which we need to determine the originating bundle.
   * @return <code>true</code> if the given class has been loaded from a dynamic bundle, <code>false
   *     </code> otherwise.
   */
  public boolean isInDynamicBundle(Class<?> clazz) {
    BundleContext context = AcceleoCommonPlugin.getDefault().getContext();
    ServiceReference packageAdminReference =
        context.getServiceReference(PackageAdmin.class.getName());
    PackageAdmin packageAdmin = null;
    if (packageAdminReference != null) {
      packageAdmin = (PackageAdmin) context.getService(packageAdminReference);
    }

    if (packageAdmin != null) {
      Bundle bundle = packageAdmin.getBundle(clazz);
      if (workspaceInstalledBundles.values().contains(bundle)) {
        return true;
      }
    }

    if (packageAdminReference != null) {
      context.ungetService(packageAdminReference);
    }

    return false;
  }
Example #17
0
  /**
   * This can be used to uninstall all manually loaded bundles from the registry and remove all
   * listeners. It will be called on plugin stopping and is not intended to be called by clients.
   *
   * @noreference This method is not intended to be referenced by clients.
   */
  public synchronized void dispose() {
    changedContributions.clear();
    workspaceLoadedClasses.clear();
    ResourcesPlugin.getWorkspace().removeResourceChangeListener(workspaceListener);

    for (Map.Entry<IPluginModelBase, Bundle> entry : workspaceInstalledBundles.entrySet()) {
      final Bundle bundle = entry.getValue();

      try {
        uninstallBundle(bundle);
      } catch (BundleException e) {
        AcceleoCommonPlugin.log(
            new Status(
                IStatus.ERROR,
                AcceleoCommonPlugin.PLUGIN_ID,
                AcceleoCommonMessages.getString(
                    UNINSTALLATION_FAILURE_KEY, bundle.getSymbolicName()),
                e));
      }
    }
    workspaceInstalledBundles.clear();
  }
Example #18
0
 /**
  * {@inheritDoc}
  *
  * @see
  *     org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
  */
 public void resourceChanged(IResourceChangeEvent event) {
   switch (event.getType()) {
       /*
        * Closing and deleting projects trigger the same actions : we must remove the model listener and
        * uninstall the bundle.
        */
     case IResourceChangeEvent.PRE_CLOSE:
     case IResourceChangeEvent.PRE_DELETE:
       if (event.getResource() instanceof IProject) {
         final IProject project = (IProject) event.getResource();
         final IPluginModelBase model = PluginRegistry.findModel(project);
         if (model != null) {
           final Bundle bundle = workspaceInstalledBundles.remove(model);
           changedContributions.remove(model);
           if (bundle != null) {
             try {
               uninstallBundle(bundle);
             } catch (BundleException e) {
               AcceleoCommonPlugin.log(
                   new Status(
                       IStatus.ERROR,
                       AcceleoCommonPlugin.PLUGIN_ID,
                       AcceleoCommonMessages.getString(
                           UNINSTALLATION_FAILURE_KEY, bundle.getSymbolicName()),
                       e));
             }
           }
         }
       }
       break;
     case IResourceChangeEvent.POST_BUILD:
       processBuildEvent(event);
       break;
     case IResourceChangeEvent.POST_CHANGE:
     default:
       // no default action
   }
 }
Example #19
0
 /**
  * This will return the set of output folders name for the given (java) project.
  *
  * <p>For example, if a project has a source folder "src" with its output folder set as "bin" and
  * a source folder "src-gen" with its output folder set as "bin-gen", this will return a
  * LinkedHashSet containing both "bin" and "bin-gen".
  *
  * @param project The project we seek the output folders of.
  * @return The set of output folders name for the given (java) project.
  */
 private static Set<String> getOutputFolders(IProject project) {
   final Set<String> classpathEntries = new CompactLinkedHashSet<String>();
   final IJavaProject javaProject = JavaCore.create(project);
   try {
     for (IClasspathEntry entry : javaProject.getResolvedClasspath(true)) {
       if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
         final IPath output = entry.getOutputLocation();
         if (output != null) {
           classpathEntries.add(output.removeFirstSegments(1).toString());
         }
       }
     }
     /*
      * Add the default output location to the classpath anyway since source folders are not required
      * to have their own
      */
     final IPath output = javaProject.getOutputLocation();
     classpathEntries.add(output.removeFirstSegments(1).toString());
   } catch (JavaModelException e) {
     AcceleoCommonPlugin.log(e, false);
   }
   return classpathEntries;
 }
Example #20
0
  /**
   * Installs the bundle corresponding to the model.
   *
   * @param model Model of the bundle to be installed.
   */
  private void installBundle(IPluginModelBase model) {
    try {
      final IResource candidateManifest = model.getUnderlyingResource();
      final IProject project = candidateManifest.getProject();

      URL url = null;
      try {
        url = project.getLocationURI().toURL();
      } catch (MalformedURLException e) {
        // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=354360
        try {
          URI uri = project.getLocationURI();
          IFileStore store = EFS.getStore(uri);
          File file = store.toLocalFile(0, null);
          if (file != null) {
            url = file.toURI().toURL();
          }
        } catch (CoreException ex) {
          // Logging both exceptions just to be sure
          AcceleoCommonPlugin.log(e, false);
          AcceleoCommonPlugin.log(ex, false);
        }
      }

      if (url != null) {
        final String candidateLocationReference =
            REFERENCE_URI_PREFIX
                + URLDecoder.decode(
                    url.toExternalForm(), System.getProperty("file.encoding")); // $NON-NLS-1$

        Bundle bundle = getBundle(candidateLocationReference);

        /*
         * Install the bundle if needed. Note that we'll check bundle dependencies in two phases as
         * even if there cannot be cyclic dependencies through the "require-bundle" header, there
         * could be through the "import package" header.
         */
        if (bundle == null) {
          checkRequireBundleDependencies(model);
          bundle = installBundle(candidateLocationReference);
          setBundleClasspath(project, bundle);
          workspaceInstalledBundles.put(model, bundle);
          checkImportPackagesDependencies(model);
        }
        refreshPackages(
            new Bundle[] {
              bundle,
            });
      }
    } catch (BundleException e) {
      String bundleName = model.getBundleDescription().getName();
      if (!logOnceProjectLoad.contains(bundleName)) {
        logOnceProjectLoad.add(bundleName);
        AcceleoCommonPlugin.log(
            new Status(
                IStatus.WARNING,
                AcceleoCommonPlugin.PLUGIN_ID,
                AcceleoCommonMessages.getString(
                    "WorkspaceUtil.InstallationFailure", //$NON-NLS-1$
                    bundleName,
                    e.getMessage()),
                e));
      }
    } catch (MalformedURLException e) {
      AcceleoCommonPlugin.log(e, false);
    } catch (UnsupportedEncodingException e) {
      AcceleoCommonPlugin.log(e, false);
    }
  }
Example #21
0
  /**
   * Refreshes all exported packages of the given bundles. This must be called after installing the
   * bundle.
   *
   * @param bundles Bundles which exported packages are to be refreshed.
   */
  @SuppressWarnings("restriction")
  void refreshPackages(Bundle[] bundles) {
    BundleContext context = AcceleoCommonPlugin.getDefault().getContext();
    ServiceReference packageAdminReference =
        context.getServiceReference(PackageAdmin.class.getName());
    PackageAdmin packageAdmin = null;
    if (packageAdminReference != null) {
      packageAdmin = (PackageAdmin) context.getService(packageAdminReference);
    }

    if (packageAdmin != null) {
      final boolean[] flag =
          new boolean[] {
            false,
          };
      FrameworkListener listener =
          new FrameworkListener() {
            public void frameworkEvent(FrameworkEvent event) {
              if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
                synchronized (flag) {
                  flag[0] = true;
                  flag.notifyAll();
                }
              }
            }
          };

      /*
       * Hack-ish : Make sure the contributions from this bundle won't be parsed. When installing a
       * bundle, the EclipseBundleListener will _always_ parse the plugin.xml and notify the extension
       * registry (and its listeners) of the new contributions. Problem is : some bundles listen to new
       * contributions, but ignore the event of contribution removals (when we uninstall the bundle). We
       * would thus end with "invalid registry object" exceptions thrown ... with no way to prevent or
       * fix them whatsoever. Equinox does not provide us with an API to disable the contributions from
       * the bundle we're installing, temporarily disable the extension listeners... or any other way to
       * workaround this registry issue. We'll then make use of the fact that the EclipseBundleListener
       * does not add contributions from a contributor which has already been added: we'll add the
       * contributor beforehand with an empty plugin.xml, disabling all potential contributions this
       * bundle would have made otherwise.
       */

      if (bundles != null && Platform.getExtensionRegistry() instanceof IDynamicExtensionRegistry) {
        IExtensionRegistry registry = Platform.getExtensionRegistry();
        for (Bundle bundle : bundles) {
          IContributor contributor = ContributorFactoryOSGi.createContributor(bundle);
          if (!((IDynamicExtensionRegistry) registry).hasContributor(contributor)) {
            registry.addContribution(
                new ByteArrayInputStream(EMPTY_PLUGIN_XML.getBytes()),
                contributor,
                false,
                null,
                null,
                ((ExtensionRegistry) registry).getTemporaryUserToken());
          }
        }
      }

      context.addFrameworkListener(listener);
      packageAdmin.refreshPackages(bundles);
      synchronized (flag) {
        while (!flag[0]) {
          try {
            flag.wait(OSGI_TIMEOUT);
          } catch (InterruptedException e) {
            // discard
            break;
          }
        }
      }
      context.removeFrameworkListener(listener);
      if (packageAdminReference != null) {
        context.ungetService(packageAdminReference);
      }
    }
  }
Example #22
0
    /**
     * This will process IResourceChangeEvent.POST_BUILD events so that we can react to builds of
     * our workspace loaded services.
     *
     * @param event The event that is to be processed. Assumes that <code>
     *     event.getType() == IResourceChangeEvent.POST_BUILD</code>.
     */
    private void processBuildEvent(IResourceChangeEvent event) {
      final IResourceDelta delta = event.getDelta();
      switch (event.getBuildKind()) {
        case IncrementalProjectBuilder.AUTO_BUILD:
          // Nothing built in such cases
          if (!ResourcesPlugin.getWorkspace().isAutoBuilding()) {
            break;
          }
          // Fall through to the incremental build handling otherwise
          // $FALL-THROUGH$
        case IncrementalProjectBuilder.INCREMENTAL_BUILD:
          final AcceleoDeltaVisitor visitor = new AcceleoDeltaVisitor();
          try {
            delta.accept(visitor);
          } catch (CoreException e) {
            AcceleoCommonPlugin.log(e, false);
          }
          for (IProject changed : visitor.getChangedProjects()) {
            IPluginModelBase model = PluginRegistry.findModel(changed);
            if (model != null) {
              changedContributions.add(model);
            }
          }
          for (String changedClass : visitor.getChangedClasses()) {
            final WorkspaceClassInstance workspaceInstance =
                workspaceLoadedClasses.get(changedClass);
            if (workspaceInstance != null) {
              workspaceInstance.setStale(true);
            }
          }
          break;
        case IncrementalProjectBuilder.FULL_BUILD:
          for (Map.Entry<IPluginModelBase, Bundle> entry : workspaceInstalledBundles.entrySet()) {
            IPluginModelBase model = entry.getKey();
            if (model != null) {
              changedContributions.add(model);
            }
          }
          for (WorkspaceClassInstance workspaceInstance : workspaceLoadedClasses.values()) {
            workspaceInstance.setStale(true);
          }
          break;
        case IncrementalProjectBuilder.CLEAN_BUILD:
          // workspace has been cleaned. Unload every service until next they're built
          final Iterator<Map.Entry<IPluginModelBase, Bundle>> workspaceBundleIterator =
              workspaceInstalledBundles.entrySet().iterator();
          while (workspaceBundleIterator.hasNext()) {
            Map.Entry<IPluginModelBase, Bundle> entry = workspaceBundleIterator.next();
            final Bundle bundle = entry.getValue();

            try {
              uninstallBundle(bundle);
            } catch (BundleException e) {
              AcceleoCommonPlugin.log(
                  new Status(
                      IStatus.ERROR,
                      AcceleoCommonPlugin.PLUGIN_ID,
                      AcceleoCommonMessages.getString(
                          UNINSTALLATION_FAILURE_KEY, bundle.getSymbolicName()),
                      e));
            }

            workspaceBundleIterator.remove();
          }
          for (WorkspaceClassInstance workspaceInstance : workspaceLoadedClasses.values()) {
            workspaceInstance.setStale(true);
          }
          break;
        default:
          // no default action
      }
    }