blob: a67deae1b08d3cd92657ebc192833898c19f6e32 [file] [log] [blame]
/*******************************************************************************
* 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.Debug;
import org.eclipse.equinox.weaving.adaptors.IWeavingAdaptor;
import org.eclipse.equinox.weaving.adaptors.WeavingAdaptor;
import org.eclipse.equinox.weaving.adaptors.WeavingAdaptorFactory;
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);
}
}
}
public void resetAdaptor(final long bundleID) {
this.adaptors.remove(bundleID);
}
@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 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);
}
}