diff options
Diffstat (limited to 'bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse')
14 files changed, 333 insertions, 417 deletions
diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/ISupplementerRegistry.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/ISupplementerRegistry.java index 4645e7886..82335817d 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/ISupplementerRegistry.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/ISupplementerRegistry.java @@ -31,6 +31,11 @@ public interface ISupplementerRegistry { public void setPackageAdmin(final PackageAdmin packageAdmin); - public void updateInstalledBundle(final Bundle bundle); + /** + * Refreshes the given bundles + * + * @param bundles The bundles to refresh + */ + public void refreshBundles(final Bundle[] bundles); } diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/AspectJAdaptorFactory.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/AspectJAdaptorFactory.java index 96f3716a5..613c7c7ec 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/AspectJAdaptorFactory.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/AspectJAdaptorFactory.java @@ -13,11 +13,13 @@ package org.eclipse.equinox.weaving.adaptors; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -124,6 +126,8 @@ public class AspectJAdaptorFactory { public void serviceChanged(final ServiceEvent event) { if (event.getType() == ServiceEvent.REGISTERED) { + final List<Bundle> bundlesToRefresh = new ArrayList<Bundle>(); + final Iterator bundleEntries = weavingServices.entrySet() .iterator(); synchronized (weavingServices) { @@ -135,18 +139,23 @@ public class AspectJAdaptorFactory { System.err .println("bundle update because of weaving service start: " + bundle.getSymbolicName()); - supplementerRegistry - .updateInstalledBundle(bundle); + bundlesToRefresh.add(bundle); if (Debug.DEBUG_WEAVE) Debug.println("> Updated bundle " + bundle.getSymbolicName()); } } } + + if (bundlesToRefresh.size() > 0) { + supplementerRegistry.refreshBundles(bundlesToRefresh + .toArray(new Bundle[bundlesToRefresh.size()])); + } } if (event.getType() == ServiceEvent.UNREGISTERING && startLevelService != null && startLevelService.getStartLevel() > 0) { + final List<Bundle> bundlesToRefresh = new ArrayList<Bundle>(); final Iterator bundleEntries = weavingServices.entrySet() .iterator(); @@ -159,14 +168,17 @@ public class AspectJAdaptorFactory { System.err .println("bundle update because of weaving service stop: " + bundle.getSymbolicName()); - supplementerRegistry - .updateInstalledBundle(bundle); + bundlesToRefresh.add(bundle); if (Debug.DEBUG_WEAVE) Debug.println("> Updated bundle " + bundle.getSymbolicName()); } } } + if (bundlesToRefresh.size() > 0) { + supplementerRegistry.refreshBundles(bundlesToRefresh + .toArray(new Bundle[bundlesToRefresh.size()])); + } } } }; diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAJBundleFile.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAJBundleFile.java index 45748ba20..07d84c370 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAJBundleFile.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAJBundleFile.java @@ -23,42 +23,48 @@ import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; public abstract class AbstractAJBundleFile extends BundleFile { - protected IAspectJAdaptor adaptor; - protected BundleFile delegate; - public AbstractAJBundleFile(final IAspectJAdaptor aspectjAdaptor, + private final BundleAdaptorProvider adaptorProvider; + + public AbstractAJBundleFile(final BundleAdaptorProvider adaptorProvider, final BundleFile bundleFile) { super(bundleFile.getBaseFile()); - this.adaptor = aspectjAdaptor; + this.adaptorProvider = adaptorProvider; this.delegate = bundleFile; } + @Override public void close() throws IOException { delegate.close(); } + @Override public boolean containsDir(final String dir) { return delegate.containsDir(dir); } public IAspectJAdaptor getAdaptor() { - return adaptor; + return this.adaptorProvider.getAdaptor(); } + @Override public File getBaseFile() { final File baseFile = delegate.getBaseFile(); return baseFile; } + @Override public BundleEntry getEntry(final String path) { return delegate.getEntry(path); } + @Override public Enumeration getEntryPaths(final String path) { return delegate.getEntryPaths(path); } + @Override public File getFile(final String path, final boolean nativeCode) { return delegate.getFile(path, nativeCode); } @@ -66,6 +72,8 @@ public abstract class AbstractAJBundleFile extends BundleFile { /** * @deprecated */ + @Deprecated + @Override public URL getResourceURL(final String path, final long hostBundleID) { return delegate.getResourceURL(path, hostBundleID); } @@ -73,11 +81,14 @@ public abstract class AbstractAJBundleFile extends BundleFile { /** * @deprecated */ + @Deprecated + @Override public URL getResourceURL(final String path, final long hostBundleID, final int index) { return delegate.getResourceURL(path, hostBundleID, index); } + @Override public void open() throws IOException { delegate.open(); } diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAspectJHook.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAspectJHook.java index 2396133aa..7166efd23 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAspectJHook.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAspectJHook.java @@ -48,7 +48,7 @@ import org.osgi.framework.BundleException; */ public abstract class AbstractAspectJHook implements HookConfigurator, AdaptorHook, BundleFileWrapperFactoryHook, ClassLoadingHook, - ClassLoadingStatsHook { + ClassLoadingStatsHook, IAdaptorProvider { /** * flag to indicate whether to print out detailed information or not @@ -79,13 +79,12 @@ public abstract class AbstractAspectJHook implements HookConfigurator, System.err .println("[org.eclipse.equinox.weaving.hook] info adding AspectJ hooks ..."); //$NON-NLS-1$ - supplementerRegistry = new SupplementerRegistry(); + supplementerRegistry = new SupplementerRegistry(this); hooks.addAdaptorHook(this); hooks.addClassLoadingHook(this); hooks.addBundleFileWrapperFactoryHook(this); hooks.addClassLoadingStatsHook(this); - hooks.addStorageHook(new AspectJStorageHook(supplementerRegistry)); hooks.addClassLoaderDelegateHook(new WeavingLoaderDelegateHook( supplementerRegistry)); } diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJBundleFile.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJBundleFile.java index 8a4c8b2f8..873734311 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJBundleFile.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJBundleFile.java @@ -25,12 +25,13 @@ public class AspectJBundleFile extends AbstractAJBundleFile { private final URL url; - public AspectJBundleFile(final IAspectJAdaptor aa, + public AspectJBundleFile(final BundleAdaptorProvider adaptorProvider, final BundleFile bundleFile) throws IOException { - super(aa, bundleFile); + super(adaptorProvider, bundleFile); this.url = delegate.getBaseFile().toURL(); } + @Override public BundleEntry getEntry(final String path) { if (Debug.DEBUG_BUNDLE) Debug.println("> AspectJBundleFile.getEntry() path=" + path @@ -41,6 +42,7 @@ public class AspectJBundleFile extends AbstractAJBundleFile { final int offset = path.lastIndexOf('.'); final String name = path.substring(0, offset).replace('/', '.'); // byte[] bytes = adaptor.findClass(name,url); + final IAspectJAdaptor adaptor = getAdaptor(); final CacheEntry cacheEntry = adaptor.findClass(name, url); if (cacheEntry == null) { if (entry != null) { diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJHook.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJHook.java index 344cdec21..2f47075e4 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJHook.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJHook.java @@ -15,6 +15,8 @@ package org.eclipse.equinox.weaving.hooks; import java.io.IOException; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import org.eclipse.equinox.service.weaving.ISupplementerRegistry; import org.eclipse.equinox.weaving.adaptors.AspectJAdaptor; @@ -37,24 +39,46 @@ public class AspectJHook extends AbstractAspectJHook { private final AspectJAdaptorFactory adaptorFactory; + private final Map<Long, IAspectJAdaptor> adaptors; + private BundleContext bundleContext; public AspectJHook() { if (Debug.DEBUG_GENERAL) Debug.println("- AspectJHook.<init>()"); - adaptorFactory = new AspectJAdaptorFactory(); + this.adaptorFactory = new AspectJAdaptorFactory(); + this.adaptors = new HashMap<Long, IAspectJAdaptor>(); } + @Override public void frameworkStart(final BundleContext context) throws BundleException { // Debug.println("? AspectJHook.frameworkStart() context=" + context + ", fdo=" + FrameworkDebugOptions.getDefault()); initialize(context); } + @Override public void frameworkStop(final BundleContext context) throws BundleException { adaptorFactory.dispose(context); } + public IAspectJAdaptor getAdaptor(final long bundleID) { + return this.adaptors.get(bundleID); + } + + public IAspectJAdaptor getHostBundleAdaptor(final long bundleID) { + final Bundle bundle = this.bundleContext.getBundle(bundleID); + if (bundle != null) { + final Bundle host = adaptorFactory.getHost(bundle); + if (host != null) { + final long hostBundleID = host.getBundleId(); + return this.adaptors.get(hostBundleID); + } + } + return null; + } + + @Override public void initializedClassLoader(final BaseClassLoader baseClassLoader, final BaseData data) { if (Debug.DEBUG_GENERAL) @@ -63,19 +87,17 @@ public class AspectJHook extends AbstractAspectJHook { + data.getSymbolicName() + ", loader=" + baseClassLoader + ", data=" + data + ", bundleFile=" + data.getBundleFile()); - IAspectJAdaptor adaptor = null; - final BundleFile bundleFile = data.getBundleFile(); - if (bundleFile instanceof BaseAjBundleFile) { - final BaseAjBundleFile baseBundleFile = (BaseAjBundleFile) bundleFile; - adaptor = baseBundleFile.getAdaptor(); - adaptor.setBaseClassLoader(baseClassLoader); - } + + final IAspectJAdaptor adaptor = createAspectJAdaptor(data); + adaptor.setBaseClassLoader(baseClassLoader); + this.adaptors.put(data.getBundleID(), adaptor); if (Debug.DEBUG_GENERAL) Debug.println("< AspectJHook.initializedClassLoader() adaptor=" + adaptor); } + @Override public byte[] processClass(final String name, final byte[] classbytes, final ClasspathEntry classpathEntry, final BundleEntry entry, final ClasspathManager manager) { @@ -90,6 +112,7 @@ public class AspectJHook extends AbstractAspectJHook { return newClassytes; } + @Override public void recordClassDefine(final String name, final Class clazz, final byte[] classbytes, final ClasspathEntry classpathEntry, final BundleEntry entry, final ClasspathManager manager) { @@ -103,6 +126,7 @@ public class AspectJHook extends AbstractAspectJHook { } } + @Override public BundleFile wrapBundleFile(final BundleFile bundleFile, final Object content, final BaseData data, final boolean base) throws IOException { @@ -123,23 +147,11 @@ public class AspectJHook extends AbstractAspectJHook { + bundleFile.getBaseFile()); if (base) { - final IAspectJAdaptor adaptor = createAspectJAdaptor(data); - if (adaptor != null) { - wrapped = new BaseAjBundleFile(adaptor, bundleFile); - } + wrapped = new BaseAjBundleFile( + new BundleAdaptorProvider(data, this), bundleFile); } else { - IAspectJAdaptor adaptor = null; - if (bundleContext != null) { - adaptor = getAspectJAdaptor(data); - if (Debug.DEBUG_BUNDLE) - Debug - .println("- AspectJBundleFileWrapperFactoryHook.wrapBundleFile() adaptor=" - + adaptor); - // if (adaptor == null) throw new RuntimeException(data.getSymbolicName()); - } - if (adaptor != null) { - wrapped = new AspectJBundleFile(adaptor, bundleFile); - } + wrapped = new AspectJBundleFile(new BundleAdaptorProvider(data, + this), bundleFile); } if (Debug.DEBUG_BUNDLE) Debug @@ -170,15 +182,7 @@ public class AspectJHook extends AbstractAspectJHook { } private IAspectJAdaptor getAspectJAdaptor(final BaseData data) { - IAspectJAdaptor adaptor = null; - - final BundleFile bundleFile = data.getBundleFile(); - if (bundleFile instanceof BaseAjBundleFile) { - final BaseAjBundleFile baseBundleFile = (BaseAjBundleFile) bundleFile; - adaptor = baseBundleFile.getAdaptor(); - } - - return adaptor; + return getAdaptor(data.getBundleID()); } private void initialize(final BundleContext context) { @@ -213,4 +217,5 @@ public class AspectJHook extends AbstractAspectJHook { Debug.println("< AspectJHook.initialize() adaptorFactory=" + adaptorFactory); } + } diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJStorageHook.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJStorageHook.java deleted file mode 100644 index b7cd0bd74..000000000 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJStorageHook.java +++ /dev/null @@ -1,253 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 IBM Corporation and others. - * 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: - * Matthew Webster initial implementation - * Martin Lippert supplementing mechanism reworked - *******************************************************************************/ - -package org.eclipse.equinox.weaving.hooks; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.Dictionary; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.core.runtime.internal.adaptor.CachedManifest; -import org.eclipse.equinox.service.weaving.ISupplementerRegistry; -import org.eclipse.equinox.weaving.adaptors.Debug; -import org.eclipse.osgi.baseadaptor.BaseData; -import org.eclipse.osgi.baseadaptor.hooks.StorageHook; -import org.eclipse.osgi.framework.util.Headers; -import org.eclipse.osgi.framework.util.KeyedElement; -import org.eclipse.osgi.util.ManifestElement; -import org.osgi.framework.BundleException; -import org.osgi.framework.Constants; - -public class AspectJStorageHook implements StorageHook { - - public static final int HASHCODE; - - public static final String KEY; - - private static Field readOnly; - - static { - KEY = AspectJStorageHook.class.getName(); - HASHCODE = KEY.hashCode(); - try { - readOnly = Headers.class.getDeclaredField("readOnly"); - readOnly.setAccessible(true); - } catch (final Exception ex) { - if (Debug.DEBUG_SUPPLEMENTS) ex.printStackTrace(); - } - } - - private BaseData bundleData; - - private final ISupplementerRegistry supplementerRegistry; - - public AspectJStorageHook(final BaseData bd, - final ISupplementerRegistry supplementerRegistry) { - if (Debug.DEBUG_SUPPLEMENTS) - Debug.println("- AspectJStorageHook.AspectJStorageHook() baseDate=" - + bd); - this.bundleData = bd; - this.supplementerRegistry = supplementerRegistry; - } - - public AspectJStorageHook(final ISupplementerRegistry supplementerRegistry) { - if (Debug.DEBUG_SUPPLEMENTS) - Debug.println("- AspectJStorageHook.AspectJStorageHook()"); - this.supplementerRegistry = supplementerRegistry; - } - - public boolean compare(final KeyedElement other) { - // TODO Auto-generated method stub - return other.getKey() == KEY; - } - - public void copy(final StorageHook storageHook) { - // TODO Auto-generated method stub - } - - public StorageHook create(final BaseData bundledata) throws BundleException { - // System.err.println("? AbstractAspectJHook.create()"); - // TODO Auto-generated method stub - // StorageHook result; - final StorageHook hook = new AspectJStorageHook(bundledata, - supplementerRegistry); - //// if (bundledata.getSymbolicName().equals("demo.hello")) { - // InvocationHandler ih = new InvocationHandler() { - // public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable { - // System.err.println("? " + method.getName()); - // return method.invoke(hook,args); - // } - // }; - // result = (StorageHook)Proxy.newProxyInstance(getClass().getClassLoader(),new Class[] { StorageHook.class }, ih); - //// } - //// else { - //// result = hook; - //// } - // return result; - return hook; - } - - public boolean forgetStartLevelChange(final int startlevel) { - // TODO Auto-generated method stub - return false; - } - - public boolean forgetStatusChange(final int status) { - // TODO Auto-generated method stub - return false; - } - - public Object getKey() { - return KEY; - } - - public int getKeyHashCode() { - return HASHCODE; - } - - public Dictionary getManifest(final boolean firstLoad) - throws BundleException { - // System.err.println("? AspectJStorageHook.getManifest() " + this + " firstLoad=" + firstLoad); - // TODO Auto-generated method stub - return null; - } - - public int getStorageVersion() { - // TODO Auto-generated method stub - return 0; - } - - public void initialize(final Dictionary manifest) throws BundleException { - // System.err.println("? AspectJStorageHook.initialize() " + this + " manifest=" + manifest); - if (Debug.DEBUG_SUPPLEMENTS) - Debug.println("> AspectJStorageHook.initialize() " - + getSymbolicName()); - try { - final ManifestElement[] imports = ManifestElement.parseHeader( - Constants.IMPORT_PACKAGE, (String) manifest - .get(Constants.IMPORT_PACKAGE)); - final ManifestElement[] exports = ManifestElement.parseHeader( - Constants.EXPORT_PACKAGE, (String) manifest - .get(Constants.EXPORT_PACKAGE)); - final List supplementers = supplementerRegistry.getSupplementers( - bundleData.getSymbolicName(), imports, exports); - if (!supplementers.isEmpty()) { - if (Debug.DEBUG_SUPPLEMENTS) - Debug.println("- AspectJStorageHook.initialize() " - + getSymbolicName() + " supplementers=" - + supplementers); - // if (addRequiredBundles(supplementers)) { - // if (AbstractAspectJHook.verbose) - // System.err - // .println("[org.eclipse.equinox.weaving.hook] info supplementing " - // + getSymbolicName() - // + " with " - // + supplementers); - // } else { - // if (AbstractAspectJHook.verbose) - // System.err - // .println("[org.eclipse.equinox.weaving.hook] info not supplementing " - // + getSymbolicName()); - // } - } - } catch (final Exception ex) { - ex.printStackTrace(); - } - if (Debug.DEBUG_SUPPLEMENTS) - Debug.println("< AspectJStorageHook.initialize() "); - } - - public StorageHook load(final BaseData bundledata, final DataInputStream is) - throws IOException { - if (Debug.DEBUG_SUPPLEMENTS) - Debug.println("- AspectJStorageHook.load() " + getSymbolicName() - + " bundleData=" + bundledata); - return new AspectJStorageHook(bundledata, supplementerRegistry); - } - - public boolean matchDNChain(final String pattern) { - // TODO Auto-generated method stub - // System.err.println("? AspectJStorageHook.matchDNChain() " + getSymbolicName() + " pattern=" + pattern); - return false; - } - - public void save(final DataOutputStream os) throws IOException { - // TODO Auto-generated method stub - if (Debug.DEBUG_SUPPLEMENTS) - Debug.println("- AspectJStorageHook.save() " + getSymbolicName()); - } - - public String toString() { - return "AspectJStorageHook[" + getSymbolicName() + "]"; - } - - public void validate() throws IllegalArgumentException { - // TODO Auto-generated method stub - // System.err.println("? AspectJStorageHook.validate()"); - } - - private boolean addRequiredBundles(final List bundles) - throws BundleException { - Dictionary manifest = bundleData.getManifest(); - manifest = ((CachedManifest) manifest).getManifest(); - - if (manifest != null) { - String value = (String) manifest.get(Constants.REQUIRE_BUNDLE); - for (final Iterator i = bundles.iterator(); i.hasNext();) { - final String name = (String) i.next(); - if (value == null) - value = name; - else - value += "," + name; - } - - if (Debug.DEBUG_SUPPLEMENTS) - Debug.println("- AspectJStorageHook.addRequiredBundles() " - + bundleData.getSymbolicName() - + " ,manifest=" - + manifest.getClass().getName() - + "@" - + Integer - .toHexString(System.identityHashCode(manifest)) - + ", value=" + value); - setHeader((Headers) manifest, Constants.REQUIRE_BUNDLE, value, true); - } - - return true; - } - - private String getSymbolicName() { - return (bundleData == null) ? "root" : bundleData.getSymbolicName(); - } - - private Object setHeader(final Headers manifest, final Object key, - final Object value, final boolean replace) throws BundleException { - try { - /* - * In Eclipse 3.3 we must use reflection to allow the manifest to be - * modified - */ - if (readOnly != null) { - readOnly.set(manifest, new Boolean(false)); - } - - return manifest.set(Constants.REQUIRE_BUNDLE, value, true); - } catch (final IllegalAccessException ex) { - throw new BundleException(key + "=" + value, ex); - } - } - -} diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/BaseAjBundleFile.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/BaseAjBundleFile.java index db48a48f1..b5b04e6b2 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/BaseAjBundleFile.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/BaseAjBundleFile.java @@ -14,13 +14,12 @@ package org.eclipse.equinox.weaving.hooks; import java.io.IOException; -import org.eclipse.equinox.weaving.adaptors.IAspectJAdaptor; import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; public class BaseAjBundleFile extends AspectJBundleFile { - public BaseAjBundleFile(final IAspectJAdaptor aspectjAdaptor, + public BaseAjBundleFile(final BundleAdaptorProvider adaptorProvider, final BundleFile bundleFile) throws IOException { - super(aspectjAdaptor, bundleFile); + super(adaptorProvider, bundleFile); } } diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/BundleAdaptorProvider.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/BundleAdaptorProvider.java new file mode 100644 index 000000000..4e8368f5b --- /dev/null +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/BundleAdaptorProvider.java @@ -0,0 +1,29 @@ + +package org.eclipse.equinox.weaving.hooks; + +import org.eclipse.equinox.weaving.adaptors.IAspectJAdaptor; +import org.eclipse.osgi.baseadaptor.BaseData; +import org.eclipse.osgi.framework.internal.core.BundleFragment; + +public class BundleAdaptorProvider { + + private final IAdaptorProvider adaptorProvider; + + private final BaseData baseData; + + public BundleAdaptorProvider(final BaseData data, + final IAdaptorProvider adaptorProvider) { + this.baseData = data; + this.adaptorProvider = adaptorProvider; + } + + public IAspectJAdaptor getAdaptor() { + if (this.baseData.getBundle() instanceof BundleFragment) { + return this.adaptorProvider.getHostBundleAdaptor(this.baseData + .getBundleID()); + } else { + return this.adaptorProvider.getAdaptor(this.baseData.getBundleID()); + } + } + +} diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/IAdaptorProvider.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/IAdaptorProvider.java new file mode 100644 index 000000000..5fa5bc026 --- /dev/null +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/IAdaptorProvider.java @@ -0,0 +1,12 @@ + +package org.eclipse.equinox.weaving.hooks; + +import org.eclipse.equinox.weaving.adaptors.IAspectJAdaptor; + +public interface IAdaptorProvider { + + public IAspectJAdaptor getAdaptor(long bundleID); + + public IAspectJAdaptor getHostBundleAdaptor(long bundleID); + +} diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/SupplementBundleListener.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/SupplementBundleListener.java index ab6a65838..69f40f515 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/SupplementBundleListener.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/SupplementBundleListener.java @@ -27,17 +27,17 @@ public class SupplementBundleListener implements SynchronousBundleListener { public void bundleChanged(final BundleEvent event) { final Bundle bundle = event.getBundle(); - if (event.getType() == BundleEvent.INSTALLED) { + if (event.getType() == BundleEvent.RESOLVED) { supplementerRegistry.addBundle(bundle); - } else if (event.getType() == BundleEvent.UNINSTALLED) { + } else if (event.getType() == BundleEvent.UNRESOLVED) { supplementerRegistry.removeBundle(bundle); - } else if (event.getType() == BundleEvent.UPDATED) { - System.err.println("bundle update: " - + event.getBundle().getBundleId()); - - supplementerRegistry.removeBundle(bundle); - supplementerRegistry.addBundle(bundle); - // supplementerRegistry.getPackageAdmin().refreshPackages(null); + // } else if (event.getType() == BundleEvent.UPDATED) { + // System.err.println("bundle update: " + // + event.getBundle().getBundleId()); + // + // supplementerRegistry.removeBundle(bundle); + // supplementerRegistry.addBundle(bundle); + // // supplementerRegistry.getPackageAdmin().refreshPackages(null); } } diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/Supplementer.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/Supplementer.java index 792909e70..80cafecbc 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/Supplementer.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/Supplementer.java @@ -22,7 +22,7 @@ public class Supplementer { private final ManifestElement[] supplementBundle; - private final List supplementedBundles; // elements of type Bundle + private final List<Bundle> supplementedBundles; // elements of type Bundle private final Bundle supplementer; @@ -38,7 +38,7 @@ public class Supplementer { this.supplementBundle = supplementBundle; this.supplementImporter = supplementImporter; this.supplementExporter = supplementExporter; - this.supplementedBundles = new ArrayList(); + this.supplementedBundles = new ArrayList<Bundle>(); } public void addSupplementedBundle(final Bundle supplementedBundle) { @@ -46,7 +46,7 @@ public class Supplementer { } public Bundle[] getSupplementedBundles() { - return (Bundle[]) supplementedBundles + return supplementedBundles .toArray(new Bundle[supplementedBundles.size()]); } diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/SupplementerRegistry.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/SupplementerRegistry.java index 110e10777..c5419bc8c 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/SupplementerRegistry.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/SupplementerRegistry.java @@ -14,6 +14,7 @@ package org.eclipse.equinox.weaving.hooks; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Dictionary; import java.util.HashMap; @@ -71,17 +72,24 @@ public class SupplementerRegistry implements ISupplementerRegistry { */ public static final String SUPPLEMENT_IMPORTER = "Eclipse-SupplementImporter"; //$NON-NLS-1$ + private final IAdaptorProvider adaptorProvider; + private BundleContext context; - private final Set dontWeaveTheseBundles; // elements of type String (symbolic name of bundle) + private final Set<String> dontWeaveTheseBundles; // elements of type String (symbolic name of bundle) private PackageAdmin packageAdmin; - private final Map supplementers; // keys of type String (symbolic name of supplementer bundle), values of type Supplementer + private final Map<String, Supplementer> supplementers; // keys of type String (symbolic name of supplementer bundle), values of type Supplementer + + private final Map<Long, Bundle[]> supplementersByBundle; + + public SupplementerRegistry(final IAdaptorProvider adaptorProvider) { + this.adaptorProvider = adaptorProvider; - public SupplementerRegistry() { - this.supplementers = new HashMap(); - this.dontWeaveTheseBundles = new HashSet(); + this.supplementers = new HashMap<String, Supplementer>(); + this.supplementersByBundle = new HashMap<Long, Bundle[]>(); + this.dontWeaveTheseBundles = new HashSet<String>(); this.dontWeaveTheseBundles.add("org.eclipse.osgi"); this.dontWeaveTheseBundles.add("org.eclipse.update.configurator"); @@ -114,28 +122,31 @@ public class SupplementerRegistry implements ISupplementerRegistry { */ public void addSupplementedBundle(final Bundle bundle) { try { - final Dictionary manifest = bundle.getHeaders(); + final Dictionary<?, ?> manifest = bundle.getHeaders(); final ManifestElement[] imports = ManifestElement.parseHeader( Constants.IMPORT_PACKAGE, (String) manifest .get(Constants.IMPORT_PACKAGE)); final ManifestElement[] exports = ManifestElement.parseHeader( Constants.EXPORT_PACKAGE, (String) manifest .get(Constants.EXPORT_PACKAGE)); - final List supplementers = getSupplementers(bundle + final List<Bundle> supplementers = getSupplementers(bundle .getSymbolicName(), imports, exports); if (supplementers.size() > 0) { this.addSupplementedBundle(bundle, supplementers); } + this.supplementersByBundle.put(bundle.getBundleId(), supplementers + .toArray(new Bundle[supplementers.size()])); } catch (final BundleException e) { } } /** - * @see org.eclipse.equinox.service.weaving.ISupplementerRegistry#addSupplementer(org.osgi.framework.Bundle, boolean) + * @see org.eclipse.equinox.service.weaving.ISupplementerRegistry#addSupplementer(org.osgi.framework.Bundle, + * boolean) */ public void addSupplementer(final Bundle bundle, final boolean updateBundles) { try { - final Dictionary manifest = bundle.getHeaders(); + final Dictionary<?, ?> manifest = bundle.getHeaders(); final ManifestElement[] supplementBundle = ManifestElement .parseHeader(SUPPLEMENT_BUNDLE, (String) manifest .get(SUPPLEMENT_BUNDLE)); @@ -173,50 +184,38 @@ public class SupplementerRegistry implements ISupplementerRegistry { * @see org.eclipse.equinox.service.weaving.ISupplementerRegistry#getSupplementers(org.osgi.framework.Bundle) */ public Bundle[] getSupplementers(final Bundle bundle) { - List result = Collections.EMPTY_LIST; - - if (supplementers.size() > 0) { - result = new ArrayList(); - for (final Iterator i = supplementers.values().iterator(); i - .hasNext();) { - final Supplementer supplementer = (Supplementer) i.next(); - if (supplementer.isSupplemented(bundle)) { - result.add(supplementer.getSupplementerBundle()); - } - } - } - - return (Bundle[]) result.toArray(new Bundle[result.size()]); + return getSupplementers(bundle.getBundleId()); } /** * @see org.eclipse.equinox.service.weaving.ISupplementerRegistry#getSupplementers(long) */ public Bundle[] getSupplementers(final long bundleID) { - final Bundle bundle = this.context.getBundle(bundleID); - if (bundle != null) { - return getSupplementers(bundle); + if (supplementersByBundle.containsKey(bundleID)) { + return supplementersByBundle.get(bundleID); } else { - return null; + return new Bundle[0]; } } /** - * @see org.eclipse.equinox.service.weaving.ISupplementerRegistry#getSupplementers(java.lang.String, org.eclipse.osgi.util.ManifestElement[], org.eclipse.osgi.util.ManifestElement[]) + * @see org.eclipse.equinox.service.weaving.ISupplementerRegistry#getSupplementers(java.lang.String, + * org.eclipse.osgi.util.ManifestElement[], + * org.eclipse.osgi.util.ManifestElement[]) */ - public List getSupplementers(final String symbolicName, + public List<Bundle> getSupplementers(final String symbolicName, final ManifestElement[] imports, final ManifestElement[] exports) { - List result = Collections.EMPTY_LIST; + List<Bundle> result = Collections.emptyList(); if (supplementers.size() > 0 && !this.dontWeaveTheseBundles.contains(symbolicName)) { - result = new LinkedList(); - for (final Iterator i = supplementers.values().iterator(); i - .hasNext();) { - final Supplementer supplementer = (Supplementer) i.next(); + result = new LinkedList<Bundle>(); + for (final Iterator<Supplementer> i = supplementers.values() + .iterator(); i.hasNext();) { + final Supplementer supplementer = i.next(); if (isSupplementerMatching(symbolicName, imports, exports, supplementer)) { - result.add(supplementer.getSymbolicName()); + result.add(supplementer.getSupplementerBundle()); } } } @@ -225,28 +224,50 @@ public class SupplementerRegistry implements ISupplementerRegistry { } /** + * Refreshes the given bundles + * + * @param bundles The bundles to refresh + */ + public void refreshBundles(final Bundle[] bundles) { + if (this.packageAdmin != null) { + this.packageAdmin.refreshPackages(bundles); + } + } + + /** * @see org.eclipse.equinox.service.weaving.ISupplementerRegistry#removeBundle(org.osgi.framework.Bundle) */ public void removeBundle(final Bundle bundle) { // if this bundle is itself supplemented by others, remove the bundle from those lists removeSupplementedBundle(bundle); + this.supplementersByBundle.remove(bundle.getBundleId()); // if this bundle supplements other bundles, remove this supplementer and update the other bundles if (supplementers.containsKey(bundle.getSymbolicName())) { - final Supplementer supplementer = (Supplementer) supplementers - .get(bundle.getSymbolicName()); + final Supplementer supplementer = supplementers.get(bundle + .getSymbolicName()); supplementers.remove(bundle.getSymbolicName()); if (AbstractAspectJHook.verbose) System.err - .println("[org.eclipse.equinox.weaving.hook] info removing supplementer " + .println("[org.eclipse.equinox.weaving.hook] info removing supplementer " //$NON-NLS-1$ + bundle.getSymbolicName()); final Bundle[] supplementedBundles = supplementer .getSupplementedBundles(); - for (int i = 0; i < supplementedBundles.length; i++) { - final Bundle supplementedBundle = supplementedBundles[i]; - if (supplementedBundle != null) { - updateInstalledBundle(supplementedBundle); + if (supplementedBundles != null && supplementedBundles.length > 0) { + refreshBundles(supplementedBundles); + } + + final Iterator<Long> bundles = this.supplementersByBundle.keySet() + .iterator(); + while (bundles.hasNext()) { + final Long next = bundles.next(); + final List<Bundle> supplementerList = new ArrayList<Bundle>( + Arrays.asList(this.supplementersByBundle.get(next))); + if (supplementerList.contains(bundle)) { + supplementerList.remove(bundle); + this.supplementersByBundle.put(next, supplementerList + .toArray(new Bundle[0])); } } } @@ -266,35 +287,13 @@ public class SupplementerRegistry implements ISupplementerRegistry { this.packageAdmin = packageAdmin; } - /** - * @see org.eclipse.equinox.service.weaving.ISupplementerRegistry#updateInstalledBundle(org.osgi.framework.Bundle) - */ - public void updateInstalledBundle(final Bundle bundle) { - if (AbstractAspectJHook.verbose) - System.err - .println("[org.eclipse.equinox.weaving.hook] info triggering update for re-supplementing " - + bundle.getSymbolicName()); - - try { - final int initialstate = (bundle.getState() & (Bundle.ACTIVE | Bundle.STARTING)); - if (initialstate != 0 - && packageAdmin != null - && packageAdmin.getBundleType(bundle) != PackageAdmin.BUNDLE_TYPE_FRAGMENT) { - bundle.stop(Bundle.STOP_TRANSIENT); - } - bundle.update(); - } catch (final BundleException e) { - e.printStackTrace(); - } - } - private void addSupplementedBundle(final Bundle supplementedBundle, - final List supplementers) { - for (final Iterator iterator = supplementers.iterator(); iterator + final List<Bundle> supplementers) { + for (final Iterator<Bundle> iterator = supplementers.iterator(); iterator .hasNext();) { - final String supplementersName = (String) iterator.next(); + final String supplementersName = iterator.next().getSymbolicName(); if (this.supplementers.containsKey(supplementersName)) { - final Supplementer supplementer = (Supplementer) this.supplementers + final Supplementer supplementer = this.supplementers .get(supplementersName); supplementer.addSupplementedBundle(supplementedBundle); } @@ -328,6 +327,8 @@ public class SupplementerRegistry implements ISupplementerRegistry { private void resupplementInstalledBundles(final Supplementer supplementer) { final Bundle[] installedBundles = context.getBundles(); + final List<Bundle> bundlesToRefresh = new ArrayList<Bundle>(); + for (int i = 0; i < installedBundles.length; i++) { try { final Bundle bundle = installedBundles[i]; @@ -341,7 +342,7 @@ public class SupplementerRegistry implements ISupplementerRegistry { continue; } - final Dictionary manifest = bundle.getHeaders(); + final Dictionary<?, ?> manifest = bundle.getHeaders(); final ManifestElement[] imports = ManifestElement.parseHeader( Constants.IMPORT_PACKAGE, (String) manifest .get(Constants.IMPORT_PACKAGE)); @@ -351,14 +352,47 @@ public class SupplementerRegistry implements ISupplementerRegistry { if (isSupplementerMatching(bundle.getSymbolicName(), imports, exports, supplementer)) { - - updateInstalledBundle(bundle); + if (this.adaptorProvider.getAdaptor(bundle.getBundleId()) != null) { + bundlesToRefresh.add(bundle); + } else { + supplementer.addSupplementedBundle(bundle); + final Bundle[] existingSupplementers = supplementersByBundle + .get(bundle.getBundleId()); + List<Bundle> enhancedSupplementerList = null; + if (existingSupplementers != null) { + enhancedSupplementerList = new ArrayList<Bundle>( + Arrays.asList(existingSupplementers)); + } else { + enhancedSupplementerList = new ArrayList<Bundle>(); + } + if (!enhancedSupplementerList.contains(supplementer + .getSupplementerBundle())) { + enhancedSupplementerList.add(supplementer + .getSupplementerBundle()); + } + + this.supplementersByBundle + .put(bundle.getBundleId(), + enhancedSupplementerList + .toArray(new Bundle[0])); + } } } catch (final BundleException e) { e.printStackTrace(); } } - } + if (bundlesToRefresh.size() > 0) { + final Bundle[] bundles = bundlesToRefresh + .toArray(new Bundle[bundlesToRefresh.size()]); + + for (int i = 0; i < bundles.length; i++) { + System.out.println("refresh bundle: " + + bundles[i].getSymbolicName()); + } + + refreshBundles(bundles); + } + } } diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/WeavingLoaderDelegateHook.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/WeavingLoaderDelegateHook.java index 24f4b6e5b..eb080157d 100644 --- a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/WeavingLoaderDelegateHook.java +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/WeavingLoaderDelegateHook.java @@ -14,6 +14,8 @@ package org.eclipse.equinox.weaving.hooks; import java.io.FileNotFoundException; import java.net.URL; import java.util.Enumeration; +import java.util.HashSet; +import java.util.Set; import org.eclipse.equinox.service.weaving.ISupplementerRegistry; import org.eclipse.osgi.framework.adaptor.BundleClassLoader; @@ -34,6 +36,30 @@ import org.osgi.framework.Bundle; */ public class WeavingLoaderDelegateHook implements ClassLoaderDelegateHook { + private final ThreadLocal<Set<String>> postFindClassCalls = new ThreadLocal<Set<String>>() { + + @Override + protected Set<String> initialValue() { + return new HashSet<String>(); + } + }; + + private final ThreadLocal<Set<String>> postFindResourceCalls = new ThreadLocal<Set<String>>() { + + @Override + protected Set<String> initialValue() { + return new HashSet<String>(); + } + }; + + private final ThreadLocal<Set<String>> postFindResourcesCalls = new ThreadLocal<Set<String>>() { + + @Override + protected Set<String> initialValue() { + return new HashSet<String>(); + } + }; + private final ISupplementerRegistry supplementerRegistry; /** @@ -58,18 +84,29 @@ public class WeavingLoaderDelegateHook implements ClassLoaderDelegateHook { final BundleClassLoader classLoader, final BundleData data) throws ClassNotFoundException { final long bundleID = data.getBundleID(); - final Bundle[] supplementers = supplementerRegistry - .getSupplementers(bundleID); - if (supplementers != null) { - for (int i = 0; i < supplementers.length; i++) { - try { - final Class clazz = supplementers[i].loadClass(name); - if (clazz != null) { - return clazz; + + final String callKey = bundleID + name; + if (postFindClassCalls.get().contains(callKey)) { + return null; + } + + postFindClassCalls.get().add(callKey); + try { + final Bundle[] supplementers = supplementerRegistry + .getSupplementers(bundleID); + if (supplementers != null) { + for (int i = 0; i < supplementers.length; i++) { + try { + final Class clazz = supplementers[i].loadClass(name); + if (clazz != null) { + return clazz; + } + } catch (final ClassNotFoundException e) { } - } catch (final ClassNotFoundException e) { } } + } finally { + postFindClassCalls.get().remove(callKey); } return null; @@ -94,18 +131,30 @@ public class WeavingLoaderDelegateHook implements ClassLoaderDelegateHook { final BundleClassLoader classLoader, final BundleData data) throws FileNotFoundException { final long bundleID = data.getBundleID(); - final Bundle[] supplementers = supplementerRegistry - .getSupplementers(bundleID); - if (supplementers != null) { - for (int i = 0; i < supplementers.length; i++) { - try { - final URL resource = supplementers[i].getResource(name); - if (resource != null) { - return resource; + + final String callKey = bundleID + name; + if (postFindResourceCalls.get().contains(callKey)) { + return null; + } + + postFindResourceCalls.get().add(callKey); + try { + final Bundle[] supplementers = supplementerRegistry + .getSupplementers(bundleID); + if (supplementers != null) { + for (int i = 0; i < supplementers.length; i++) { + try { + final URL resource = supplementers[i].getResource(name); + if (resource != null) { + return resource; + } + } catch (final Exception e) { + e.printStackTrace(); } - } catch (final Exception e) { } } + } finally { + postFindResourceCalls.get().remove(callKey); } return null; @@ -120,20 +169,32 @@ public class WeavingLoaderDelegateHook implements ClassLoaderDelegateHook { final BundleClassLoader classLoader, final BundleData data) throws FileNotFoundException { final long bundleID = data.getBundleID(); - final Bundle[] supplementers = supplementerRegistry - .getSupplementers(bundleID); - if (supplementers != null) { - for (int i = 0; i < supplementers.length; i++) { - try { - final Enumeration resource = supplementers[i] - .getResources(name); - if (resource != null) { - // TODO: if more than one enumeration is found, we should return all items - return resource; + + final String callKey = bundleID + name; + if (postFindResourcesCalls.get().contains(callKey)) { + return null; + } + + postFindResourcesCalls.get().add(callKey); + try { + final Bundle[] supplementers = supplementerRegistry + .getSupplementers(bundleID); + if (supplementers != null) { + for (int i = 0; i < supplementers.length; i++) { + try { + final Enumeration resource = supplementers[i] + .getResources(name); + if (resource != null) { + // TODO: if more than one enumeration is found, we should return all items + return resource; + } + } catch (final Exception e) { + e.printStackTrace(); } - } catch (final Exception e) { } } + } finally { + postFindResourcesCalls.get().remove(callKey); } return null; |