예제 #1
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;
  }
예제 #2
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;
  }
예제 #3
0
 /**
  * Retrieves the singleton instance of the given service class after refreshing it if needed.
  *
  * @param serviceClass The service class we need an instance of.
  * @return The singleton instance of the given service class if any.
  */
 public synchronized Object getServiceInstance(Class<?> serviceClass) {
   String qualifiedName = serviceClass.getName();
   for (Map.Entry<String, WorkspaceClassInstance> workspaceClass :
       workspaceLoadedClasses.entrySet()) {
     if (workspaceClass.getKey().equals(qualifiedName)) {
       WorkspaceClassInstance workspaceInstance = workspaceClass.getValue();
       if (workspaceInstance.isStale()) {
         for (Map.Entry<IPluginModelBase, Bundle> entry : workspaceInstalledBundles.entrySet()) {
           final IPluginModelBase model = entry.getKey();
           if (workspaceInstance
               .getBundle()
               .equals(model.getBundleDescription().getSymbolicName())) {
             Class<?> clazz = internalLoadClass(entry.getValue(), qualifiedName);
             workspaceInstance.setStale(false);
             workspaceInstance.setClass(clazz);
             break;
           }
         }
       }
       return workspaceInstance.getInstance();
     }
   }
   return null;
 }
예제 #4
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
      }
    }