diff options
Diffstat (limited to 'bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/WeavingHook.java')
-rw-r--r-- | bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/WeavingHook.java | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/WeavingHook.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/WeavingHook.java new file mode 100644 index 000000000..a2e2f7c46 --- /dev/null +++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/WeavingHook.java @@ -0,0 +1,245 @@ +/******************************************************************************* + * 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: + * David Knibb initial implementation + * Matthew Webster Eclipse 3.2 changes + * Martin Lippert supplementing mechanism reworked + *******************************************************************************/ + +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.WeavingAdaptor; +import org.eclipse.equinox.weaving.adaptors.WeavingAdaptorFactory; +import org.eclipse.equinox.weaving.adaptors.Debug; +import org.eclipse.equinox.weaving.adaptors.IWeavingAdaptor; +import org.eclipse.osgi.baseadaptor.BaseData; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; +import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader; +import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry; +import org.eclipse.osgi.baseadaptor.loader.ClasspathManager; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.ServiceReference; +import org.osgi.service.packageadmin.PackageAdmin; + +public class WeavingHook extends AbstractWeavingHook { + + private final WeavingAdaptorFactory adaptorFactory; + + private final Map<Long, IWeavingAdaptor> adaptors; + + private BundleContext bundleContext; + + public WeavingHook() { + if (Debug.DEBUG_GENERAL) Debug.println("- AspectJHook.<init>()"); + this.adaptorFactory = new WeavingAdaptorFactory(); + this.adaptors = new HashMap<Long, IWeavingAdaptor>(); + } + + /** + * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#frameworkStart(org.osgi.framework.BundleContext) + */ + @Override + public void frameworkStart(final BundleContext context) + throws BundleException { + // Debug.println("? AspectJHook.frameworkStart() context=" + context + ", fdo=" + FrameworkDebugOptions.getDefault()); + initialize(context); + } + + /** + * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#frameworkStop(org.osgi.framework.BundleContext) + */ + @Override + public void frameworkStop(final BundleContext context) + throws BundleException { + adaptorFactory.dispose(context); + } + + public IWeavingAdaptor getAdaptor(final long bundleID) { + return this.adaptors.get(bundleID); + } + + public IWeavingAdaptor 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; + } + + /** + * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#initializedClassLoader(org.eclipse.osgi.baseadaptor.loader.BaseClassLoader, + * org.eclipse.osgi.baseadaptor.BaseData) + */ + @Override + public void initializedClassLoader(final BaseClassLoader baseClassLoader, + final BaseData data) { + if (Debug.DEBUG_GENERAL) + Debug + .println("> AspectJHook.initializedClassLoader() bundle=" + + data.getSymbolicName() + ", loader=" + + baseClassLoader + ", data=" + data + + ", bundleFile=" + data.getBundleFile()); + + final IWeavingAdaptor adaptor = createAspectJAdaptor(data); + adaptor.setBaseClassLoader(baseClassLoader); + adaptor.initialize(); + this.adaptors.put(data.getBundleID(), adaptor); + + if (Debug.DEBUG_GENERAL) + Debug.println("< AspectJHook.initializedClassLoader() adaptor=" + + adaptor); + } + + /** + * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#processClass(java.lang.String, + * byte[], org.eclipse.osgi.baseadaptor.loader.ClasspathEntry, + * org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry, + * org.eclipse.osgi.baseadaptor.loader.ClasspathManager) + */ + @Override + public byte[] processClass(final String name, final byte[] classbytes, + final ClasspathEntry classpathEntry, final BundleEntry entry, + final ClasspathManager manager) { + byte[] newClassytes = null; + if (entry instanceof WeavingBundleEntry) { + final WeavingBundleEntry ajBundleEntry = (WeavingBundleEntry) entry; + if (!ajBundleEntry.dontWeave()) { + final IWeavingAdaptor adaptor = ajBundleEntry.getAdaptor(); + newClassytes = adaptor.weaveClass(name, classbytes); + } + } + return newClassytes; + } + + /** + * @see org.eclipse.equinox.weaving.hooks.AbstractWeavingHook#recordClassDefine(java.lang.String, + * java.lang.Class, byte[], + * org.eclipse.osgi.baseadaptor.loader.ClasspathEntry, + * org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry, + * org.eclipse.osgi.baseadaptor.loader.ClasspathManager) + */ + @Override + public void recordClassDefine(final String name, final Class clazz, + final byte[] classbytes, final ClasspathEntry classpathEntry, + final BundleEntry entry, final ClasspathManager manager) { + if (entry instanceof WeavingBundleEntry) { + final WeavingBundleEntry ajBundleEntry = (WeavingBundleEntry) entry; + if (!ajBundleEntry.dontWeave()) { + final IWeavingAdaptor adaptor = ajBundleEntry.getAdaptor(); + final URL sourceFileURL = ajBundleEntry.getBundleFileURL(); + adaptor.storeClass(name, sourceFileURL, clazz, classbytes); + } + } + } + + @Override + public BundleFile wrapBundleFile(final BundleFile bundleFile, + final Object content, final BaseData data, final boolean base) + throws IOException { + BundleFile wrapped = null; + if (Debug.DEBUG_BUNDLE) + Debug + .println("> AspectJBundleFileWrapperFactoryHook.wrapBundleFile() bundle=" + + data.getSymbolicName() + + " bundleFile=" + + bundleFile + + ", content=" + + content + + ", data=" + + data + + ", base=" + + base + + ", baseFile=" + + bundleFile.getBaseFile()); + + if (base) { + wrapped = new BaseWeavingBundleFile( + new BundleAdaptorProvider(data, this), bundleFile); + } else { + wrapped = new WeavingBundleFile(new BundleAdaptorProvider(data, + this), bundleFile); + } + if (Debug.DEBUG_BUNDLE) + Debug + .println("< AspectJBundleFileWrapperFactoryHook.wrapBundleFile() wrapped=" + + wrapped); + return wrapped; + } + + private IWeavingAdaptor createAspectJAdaptor(final BaseData baseData) { + if (Debug.DEBUG_GENERAL) + Debug.println("> AspectJHook.createAspectJAdaptor() location=" + + baseData.getLocation()); + IWeavingAdaptor adaptor = null; + + if (adaptorFactory != null) { + adaptor = new WeavingAdaptor(baseData, adaptorFactory, null, null, + null); + } else { + if (Debug.DEBUG_GENERAL) + Debug.println("- AspectJHook.createAspectJAdaptor() factory=" + + adaptorFactory); + } + + if (Debug.DEBUG_GENERAL) + Debug.println("< AspectJHook.createAspectJAdaptor() adaptor=" + + adaptor); + return adaptor; + } + + private IWeavingAdaptor getAspectJAdaptor(final BaseData data) { + return getAdaptor(data.getBundleID()); + } + + private void initialize(final BundleContext context) { + if (Debug.DEBUG_GENERAL) + Debug.println("> AspectJHook.initialize() context=" + context); + + this.bundleContext = context; + + final ISupplementerRegistry supplementerRegistry = getSupplementerRegistry(); + adaptorFactory.initialize(context, supplementerRegistry); + + final ServiceReference serviceReference = context + .getServiceReference(PackageAdmin.class.getName()); + final PackageAdmin packageAdmin = (PackageAdmin) context + .getService(serviceReference); + + supplementerRegistry.setBundleContext(context); + supplementerRegistry.setPackageAdmin(packageAdmin); + context.addBundleListener(new SupplementBundleListener( + supplementerRegistry)); + + // final re-build supplementer final registry state for final installed bundles + final Bundle[] installedBundles = context.getBundles(); + for (int i = 0; i < installedBundles.length; i++) { + supplementerRegistry.addSupplementer(installedBundles[i], false); + } + for (int i = 0; i < installedBundles.length; i++) { + supplementerRegistry.addSupplementedBundle(installedBundles[i]); + } + + if (Debug.DEBUG_GENERAL) + Debug.println("< AspectJHook.initialize() adaptorFactory=" + + adaptorFactory); + } + +} |