예제 #1
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;
  }
예제 #2
0
  /**
   * {@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.");
    }
  }
예제 #3
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;
 }
예제 #4
0
 /**
  * {@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();
   }
 }
예제 #5
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;
 }
예제 #6
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;
  }
예제 #7
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;
  }
예제 #8
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);
      }
    }
  }