Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Lippert2008-07-04 18:57:06 +0000
committerMartin Lippert2008-07-04 18:57:06 +0000
commit2f425920ab801b833bc8828a053d8adc1e427aa3 (patch)
tree92830ad0186a56d60ad3eb58cb71098ddc8787e6
parenta8ed43f1d037ff5a577f4c36d9876e874964b898 (diff)
downloadrt.equinox.bundles-2f425920ab801b833bc8828a053d8adc1e427aa3.tar.gz
rt.equinox.bundles-2f425920ab801b833bc8828a053d8adc1e427aa3.tar.xz
rt.equinox.bundles-2f425920ab801b833bc8828a053d8adc1e427aa3.zip
Bug 238730 - [aspects] rename bundles and start with new version numbering
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/.options1
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/.project28
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/.settings/org.eclipse.jdt.core.prefs12
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/META-INF/MANIFEST.MF11
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/build.properties6
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingService.java93
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingServiceFactory.java17
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingServicePlugin.java88
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/loadtime/OSGiWeavingAdaptor.java170
-rw-r--r--bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/loadtime/OSGiWeavingContext.java140
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching.j9/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching.j9/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching.j9/.options1
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching.j9/.project28
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching.j9/META-INF/MANIFEST.MF12
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching.j9/build.properties5
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingService.java97
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingServiceFactory.java30
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingServicePlugin.java110
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/.options1
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/.project28
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.jdt.core.prefs78
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.pde.core.prefs4
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.pde.prefs15
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/META-INF/MANIFEST.MF13
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/build.properties4
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/Activator.java108
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/BaseCachingService.java53
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/BundleCachingService.java310
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/IBundleConstants.java26
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/Log.java66
-rw-r--r--bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/SingletonCachingService.java120
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/.options6
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/.project28
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/.settings/org.eclipse.jdt.core.prefs12
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/.settings/org.eclipse.jdt.ui.prefs3
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/All OSGi Tests (AOSGi).launch32
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/META-INF/MANIFEST.MF8
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/build.properties6
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/config.ini12
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/hookconfigurators.properties2
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/patches/org.eclipse.osgi_patch_20060509.txt594
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/readme.txt15
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/ICachingService.java27
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/IWeavingService.java36
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/SupplementerRegistry.java259
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/AspectJAdaptor.java189
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/AspectJAdaptorFactory.java153
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/Debug.java53
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/IAspectJAdaptor.java28
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAJBundleFile.java82
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAspectJHook.java169
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJBundleEntry.java94
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJBundleFile.java60
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJHook.java174
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJStorageHook.java220
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/BaseAjBundleFile.java25
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/SupplementBundleListener.java41
-rw-r--r--bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/Supplementer.java122
65 files changed, 4157 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/.classpath b/bundles/org.eclipse.equinox.weaving.aspectj/.classpath
new file mode 100644
index 000000000..230429d56
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry excluding="org/eclipse/osgi/aspectj/weavingService/WeavingServiceFactory.java" kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.3"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/.cvsignore b/bundles/org.eclipse.equinox.weaving.aspectj/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/.options b/bundles/org.eclipse.equinox.weaving.aspectj/.options
new file mode 100644
index 000000000..a4c746efd
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/.options
@@ -0,0 +1 @@
+org.aspectj.osgi.service.weaving/debug=false
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/.project b/bundles/org.eclipse.equinox.weaving.aspectj/.project
new file mode 100644
index 000000000..3ddde52d0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.weaving.aspectj</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.weaving.aspectj/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..35c2a5b04
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Wed Feb 27 23:06:56 CET 2008
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.compliance=1.3
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.1
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=ignore
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=ignore
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.weaving.aspectj/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..ed836365b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: WeavingService Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.equinox.weaving.aspectj
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.equinox.weaving.aspectj.WeavingServicePlugin
+Require-Bundle: org.aspectj.weaver,
+ system.bundle
+Bundle-ActivationPolicy: lazy
+Import-Package: org.eclipse.equinox.service.weaving, org.eclipse.osgi.service.resolver
+Bundle-RequiredExecutionEnvironment: J2SE-1.3
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/build.properties b/bundles/org.eclipse.equinox.weaving.aspectj/build.properties
new file mode 100644
index 000000000..07bbd6ddc
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ .options
+src.includes = src/
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingService.java b/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingService.java
new file mode 100644
index 000000000..fcb5ef7ed
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingService.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ * Heiko Seeberger AJDT 1.5.1 changes
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.aspectj;
+
+import java.io.IOException;
+
+import org.eclipse.equinox.service.weaving.IWeavingService;
+import org.eclipse.equinox.service.weaving.SupplementerRegistry;
+import org.eclipse.equinox.weaving.aspectj.loadtime.OSGiWeavingAdaptor;
+import org.eclipse.equinox.weaving.aspectj.loadtime.OSGiWeavingContext;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.State;
+import org.osgi.framework.Bundle;
+
+public class WeavingService implements IWeavingService {
+
+ private ClassLoader loader;
+ private BundleDescription bundle;
+ private OSGiWeavingAdaptor adaptor1;
+ private OSGiWeavingContext weavingContext;
+
+ public WeavingService(){
+ if (WeavingServicePlugin.DEBUG) System.out.println("- WeavingService.<init>");
+ }
+
+ public WeavingService (ClassLoader loader, Bundle bundle, State state, BundleDescription bundleDescription, SupplementerRegistry supplementerRegistry) {
+ this.loader=(ClassLoader)loader;
+ this.bundle = bundleDescription;
+ this.weavingContext = new OSGiWeavingContext((ClassLoader)loader, bundle, state, bundleDescription, supplementerRegistry);
+ }
+
+ /**
+ * Return an instance of this service, initalised with the specified classloader
+ */
+ public IWeavingService getInstance(ClassLoader loader, Bundle bundle, State resolverState, BundleDescription bundleDesciption, SupplementerRegistry supplementerRegistry){
+ return new WeavingService(loader, bundle, resolverState, bundleDesciption, supplementerRegistry);
+ }
+
+ /**
+ * See Aj.preProcess
+ */
+ public byte[] preProcess(String name, byte[] classbytes, ClassLoader loader) throws IOException {
+ if (WeavingServicePlugin.DEBUG) System.out.println("> WeavingService.preProcess() bundle=" + bundle.getSymbolicName() + ", name=" + name + ", bytes=" + classbytes.length);
+ byte[] newBytes;
+ ensureAdaptorInit();
+
+ // Bug 215177: Adapt to updated (AJ 1.5.4) signature.
+ newBytes = adaptor1.weaveClass(name,classbytes, false);
+ if (WeavingServicePlugin.DEBUG) System.out.println("< WeavingService.preProcess() bytes=" + newBytes.length);
+ return newBytes;
+ }
+
+ /**
+ * Initialise Aj
+ */
+ private void ensureAdaptorInit(){
+ if (adaptor1 == null){
+ adaptor1 = new OSGiWeavingAdaptor(loader,weavingContext);
+ adaptor1.initialize();
+ }
+ }
+
+ public String getKey () {
+ if (WeavingServicePlugin.DEBUG) System.out.println("> WeavingService.getKey() bundle=" + bundle.getSymbolicName());
+ String key;
+ ensureAdaptorInit();
+ key = adaptor1.getNamespace();
+ if (WeavingServicePlugin.DEBUG)System.out.println("< WeavingService.getKey() key='" + key + "'");
+ return key;
+ }
+
+ public boolean generatedClassesExistFor(ClassLoader loader, String className) {
+ ensureAdaptorInit();
+ return adaptor1.generatedClassesExistFor(className);
+ }
+
+ public void flushGeneratedClasses(ClassLoader loader) {
+ ensureAdaptorInit();
+ adaptor1.flushGeneratedClasses();
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingServiceFactory.java b/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingServiceFactory.java
new file mode 100644
index 000000000..6371c7e46
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingServiceFactory.java
@@ -0,0 +1,17 @@
+package org.eclipse.equinox.weaving.aspectj;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+public class WeavingServiceFactory implements ServiceFactory {
+
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ return (new WeavingService());
+ }
+
+ public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+ //nothing here
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingServicePlugin.java b/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingServicePlugin.java
new file mode 100644
index 000000000..e05d0655a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/WeavingServicePlugin.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.aspectj;
+
+import java.util.Properties;
+
+import org.eclipse.equinox.service.weaving.IWeavingService;
+import org.eclipse.osgi.service.debug.DebugOptions;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class WeavingServicePlugin implements BundleActivator {
+
+ public static boolean verbose = Boolean.getBoolean("org.aspectj.osgi.verbose");
+
+ //The shared instance.
+ private static WeavingServicePlugin plugin;
+
+ /**
+ * The constructor.
+ */
+ public WeavingServicePlugin() {
+ plugin = this;
+// IWeavingContext iwc = new WeavingContext(null,null);//force bundle to be resolved
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ public void start(BundleContext context) throws Exception {
+ loadOptions(context);
+ if (verbose) System.err.println("[org.aspectj.osgi.service.weaving] info Starting AspectJ weaving service ...");
+ String serviceName = IWeavingService.class.getName();
+// ServiceFactory factory = new WeavingServiceFactory();
+ IWeavingService weavingService = new WeavingService();
+ Properties props = new Properties();
+// context.registerService(serviceName, factory, props);
+ context.registerService(serviceName, weavingService, props);
+// System.out.println("WeavingServicePlugin.start() - registered WeavingService");
+ }
+
+ /**
+ * This method is called when the plug-in is stopped
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static WeavingServicePlugin getDefault() {
+ return plugin;
+ }
+
+ private void loadOptions (BundleContext context) {
+ // all this is only to get the application args
+ DebugOptions service = null;
+ ServiceReference reference = context.getServiceReference(DebugOptions.class.getName());
+ if (reference != null)
+ service = (DebugOptions) context.getService(reference);
+ if (service == null)
+ return;
+ try {
+ DEBUG = service.getBooleanOption("org.aspectj.osgi.service.weaving/debug", false);
+ } finally {
+ // we have what we want - release the service
+ context.ungetService(reference);
+ }
+ }
+
+ public static boolean DEBUG;
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/loadtime/OSGiWeavingAdaptor.java b/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/loadtime/OSGiWeavingAdaptor.java
new file mode 100644
index 000000000..f40bc9f14
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/loadtime/OSGiWeavingAdaptor.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ * Heiko Seeberger AJDT 1.5.1 changes
+ * Martin Lippert minor changes and bugfixes
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.aspectj.loadtime;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.aspectj.bridge.Constants;
+import org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor;
+import org.aspectj.weaver.loadtime.definition.DocumentParser;
+import org.eclipse.equinox.weaving.aspectj.WeavingServicePlugin;
+import org.osgi.framework.Bundle;
+
+public class OSGiWeavingAdaptor extends ClassLoaderWeavingAdaptor {
+
+ private final static String AOP_XML = Constants.AOP_USER_XML + ";" + Constants.AOP_AJC_XML + ";" + Constants.AOP_OSGI_XML;
+
+ private static final String AOP_CONTEXT_LOCATION_HEADER = "Eclipse-AspectContext";
+ private static final String DEFAULT_AOP_CONTEXT_LOCATION = "META-INF/aop.xml";
+
+ private boolean initialized;
+ private boolean initializing;
+ private ClassLoader classLoader;
+ private OSGiWeavingContext weavingContext;
+
+ public OSGiWeavingAdaptor (ClassLoader loader, OSGiWeavingContext context) {
+ super();
+ this.classLoader = loader;
+ this.weavingContext = context;
+ }
+
+ // Bug 215177: Adapt to updated (AJ 1.5.4) super class signature:
+ public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IOException {
+
+ /* Avoid recursion during adaptor initialization */
+ if (!initializing) {
+ if (!initialized) {
+ initializing = true;
+ initialize(classLoader,weavingContext);
+ initialized = true;
+ initializing = false;
+ }
+ // Bug 215177: Adapt to updated (AJ 1.5.4) super class signature:
+ bytes = super.weaveClass(name, bytes, mustWeave);
+ }
+ return bytes;
+ }
+
+ public void initialize() {
+ if (!initializing) {
+ if (!initialized) {
+ initializing = true;
+ super.initialize(classLoader,weavingContext);
+ initialized = true;
+ initializing = false;
+ }
+ }
+
+ if (WeavingServicePlugin.verbose) {
+ if (isEnabled()) System.err.println("[org.aspectj.osgi.service.weaving] info weaving bundle '" + weavingContext.getClassLoaderName() + "'");
+ else System.err.println("[org.aspectj.osgi.service.weaving] info not weaving bundle '" + weavingContext.getClassLoaderName() + "'");
+ }
+ }
+
+ /**
+ * Load and cache the aop.xml/properties according to the classloader visibility rules
+ *
+ * @param weaver
+ * @param loader
+ */
+ public List parseDefinitionsForBundle() {
+ List definitions = new ArrayList();
+ Set seenBefore = new HashSet();
+
+ try {
+ parseDefinitionsFromVisibility(definitions, seenBefore);
+ parseDefinitionsFromRequiredBundles(definitions, seenBefore);
+ if (definitions.isEmpty()) {
+ info("no configuration found. Disabling weaver for bundler " + weavingContext.getClassLoaderName());
+ }
+ } catch (Exception e) {
+ definitions.clear();
+ warn("parse definitions failed",e);
+ }
+
+ return definitions;
+ }
+
+ private void parseDefinitionsFromVisibility(List definitions, Set seenBefore) {
+ String resourcePath = System.getProperty("org.aspectj.weaver.loadtime.configuration", AOP_XML);
+ StringTokenizer st = new StringTokenizer(resourcePath,";");
+
+ while(st.hasMoreTokens()){
+ try {
+ Enumeration xmls = weavingContext.getResources(st.nextToken());
+
+ while (xmls.hasMoreElements()) {
+ URL xml = (URL) xmls.nextElement();
+ if (!seenBefore.contains(xml)) {
+ info("using configuration " + weavingContext.getFile(xml));
+ definitions.add(DocumentParser.parse(xml));
+ seenBefore.add(xml);
+ }
+ else {
+ warn("ignoring duplicate definition: " + xml);
+ }
+ }
+ }
+ catch (Exception e) {
+ warn("parse definitions failed",e);
+ }
+ }
+ }
+
+ private void parseDefinitionsFromRequiredBundles(List definitions,
+ Set seenBefore) {
+ Bundle[] bundles = weavingContext.getBundles();
+ for (int i = 0; i < bundles.length; i++) {
+ parseDefinitionFromRequiredBundle(bundles[i], definitions, seenBefore);
+ }
+ }
+
+ private void parseDefinitionFromRequiredBundle(Bundle bundle,
+ List definitions, Set seenBefore) {
+ try {
+ URL aopXmlDef = bundle.getEntry(getDefinitionLocation(bundle));
+ if (aopXmlDef != null) {
+ if (!seenBefore.contains(aopXmlDef)) {
+ definitions.add(DocumentParser.parse(aopXmlDef));
+ seenBefore.add(aopXmlDef);
+ }
+ else {
+ warn("ignoring duplicate definition: " + aopXmlDef);
+ }
+ }
+ }
+ catch (Exception e) {
+ warn("parse definitions failed", e);
+ }
+ }
+
+ private String getDefinitionLocation(Bundle bundle) {
+ String aopContextHeader = (String) bundle.getHeaders().get(AOP_CONTEXT_LOCATION_HEADER);
+ if (aopContextHeader != null) {
+ aopContextHeader = aopContextHeader.trim();
+ return aopContextHeader;
+ }
+
+ return DEFAULT_AOP_CONTEXT_LOCATION;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/loadtime/OSGiWeavingContext.java b/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/loadtime/OSGiWeavingContext.java
new file mode 100644
index 000000000..54adcf3d6
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.aspectj/src/org/eclipse/equinox/weaving/aspectj/loadtime/OSGiWeavingContext.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.aspectj.loadtime;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.aspectj.weaver.loadtime.DefaultWeavingContext;
+import org.aspectj.weaver.tools.WeavingAdaptor;
+import org.eclipse.equinox.service.weaving.SupplementerRegistry;
+import org.eclipse.equinox.weaving.aspectj.WeavingServicePlugin;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.BundleSpecification;
+import org.eclipse.osgi.service.resolver.State;
+import org.osgi.framework.Bundle;
+
+public class OSGiWeavingContext extends DefaultWeavingContext {
+
+ private final State resolverState;
+ private final Bundle bundle;
+ private final BundleDescription bundleDescription;
+ private final SupplementerRegistry supplementerRegistry;
+
+ public OSGiWeavingContext(ClassLoader loader, Bundle bundle, State state, BundleDescription bundleDescription, SupplementerRegistry supplementerRegistry) {
+ super(loader);
+ this.bundle = bundle;
+ this.bundleDescription = bundleDescription;
+ this.resolverState = state;
+ this.supplementerRegistry = supplementerRegistry;
+ if (WeavingServicePlugin.DEBUG) System.out.println("- WeavingContext.WeavingContext() locader=" + loader + ", bundle=" + bundle.getSymbolicName());
+ }
+
+ public String getBundleIdFromURL(URL url) {
+ return resolverState.getBundle(Integer.parseInt(url.getHost())).getSymbolicName();
+ }
+
+ public String toString(){
+ return getClass().getName() + "[" + bundleDescription.getSymbolicName() + "]";
+ }
+
+ public String getClassLoaderName() {
+ return bundleDescription.getSymbolicName();
+ }
+
+ public String getFile(URL url) {
+ return getBundleIdFromURL(url) + url.getFile();
+ }
+
+ public String getId () {
+ return bundleDescription.getSymbolicName();
+ }
+
+ public Enumeration getResources(String name) throws IOException {
+ Enumeration result = super.getResources(name);
+
+ if (name.endsWith("aop.xml")){
+ Vector modified =new Vector();
+ BundleSpecification[] requires = bundleDescription.getRequiredBundles();
+ BundleDescription[] fragments = bundleDescription.getFragments();
+
+ while(result.hasMoreElements()){
+ URL xml = (URL) result.nextElement();
+ String resourceBundleName = getBundleIdFromURL(xml);
+
+ if (bundleDescription.getSymbolicName().equals(resourceBundleName)){
+ modified.add(xml);
+ continue;
+ }
+
+ for (int i=0; i<requires.length; i++){
+ BundleSpecification r = requires[i];
+ if (r.getName().equals(resourceBundleName)){
+ modified.add(xml);
+ continue;
+ }
+ }
+
+ for (int i = 0; i < fragments.length; i++) {
+ BundleSpecification[] fragmentRequires = fragments[i].getRequiredBundles();
+ for (int j=0; j<fragmentRequires.length; j++){
+ BundleSpecification r = fragmentRequires[j];
+ if (r.getName().equals(resourceBundleName)){
+ modified.add(xml);
+ continue;
+ }
+ }
+ }
+ }
+
+ result=modified.elements();
+ }
+ return result;
+ }
+
+ public List getDefinitions(ClassLoader loader, WeavingAdaptor adaptor) {
+ List definitions = ((OSGiWeavingAdaptor)adaptor).parseDefinitionsForBundle();
+ return definitions;
+ }
+
+ public Bundle[] getBundles() {
+ Set bundles = new HashSet();
+
+ // the bundle this context belongs to should be used
+ bundles.add(this.bundle);
+
+ // add required bundles
+ if (this.bundle.getBundleContext() != null) {
+ BundleDescription[] resolvedRequires = this.bundleDescription.getResolvedRequires();
+ for (int i = 0; i < resolvedRequires.length; i++) {
+ Bundle requiredBundle = this.bundle.getBundleContext().getBundle(resolvedRequires[i].getBundleId());
+ if (requiredBundle != null) {
+ bundles.add(requiredBundle);
+ }
+ }
+ }
+
+ // add supplementers
+ Bundle[] supplementers = this.supplementerRegistry.getSupplementers(this.bundle);
+ bundles.addAll(Arrays.asList(supplementers));
+
+ return (Bundle[]) bundles.toArray(new Bundle[bundles.size()]);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.caching.j9/.classpath b/bundles/org.eclipse.equinox.weaving.caching.j9/.classpath
new file mode 100644
index 000000000..304e86186
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching.j9/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.weaving.caching.j9/.cvsignore b/bundles/org.eclipse.equinox.weaving.caching.j9/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching.j9/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.weaving.caching.j9/.options b/bundles/org.eclipse.equinox.weaving.caching.j9/.options
new file mode 100644
index 000000000..7f5c58338
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching.j9/.options
@@ -0,0 +1 @@
+org.aspectj.osgi.service.caching.j9/debug=false
diff --git a/bundles/org.eclipse.equinox.weaving.caching.j9/.project b/bundles/org.eclipse.equinox.weaving.caching.j9/.project
new file mode 100644
index 000000000..3443fe7fc
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching.j9/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.weaving.caching.j9</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.weaving.caching.j9/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.weaving.caching.j9/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..bd21949ab
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching.j9/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: J9 CachingService Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.equinox.weaving.caching.j9
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.equinox.weaving.internal.caching.j9.CachingServicePlugin
+Bundle-ActivationPolicy: lazy
+Import-Package: com.ibm.oti.shared;resolution:=optional,
+ org.eclipse.equinox.service.weaving,
+ org.eclipse.osgi.service.debug;version="1.0.0",
+ org.osgi.framework;version="1.4.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/bundles/org.eclipse.equinox.weaving.caching.j9/build.properties b/bundles/org.eclipse.equinox.weaving.caching.j9/build.properties
new file mode 100644
index 000000000..8951ab621
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching.j9/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ .options
diff --git a/bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingService.java b/bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingService.java
new file mode 100644
index 000000000..109c49a06
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingService.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.internal.caching.j9;
+
+import java.net.URL;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.eclipse.equinox.service.weaving.ICachingService;
+import org.osgi.framework.Bundle;
+
+import com.ibm.oti.shared.HelperAlreadyDefinedException;
+import com.ibm.oti.shared.Shared;
+import com.ibm.oti.shared.SharedClassURLHelper;
+
+public class CachingService implements ICachingService {
+
+ private Bundle bundle;
+ private ClassLoader classLoader;
+ private String partition;
+ SharedClassURLHelper urlhelper;
+
+ public CachingService () {
+ if (CachingServicePlugin.DEBUG) System.out.println("- CachingService.<init>()");
+ }
+
+ public CachingService (ClassLoader loader, Bundle bundle, String key) {
+ if (CachingServicePlugin.DEBUG) System.out.println("> CachingService.<init>() bundle=" + bundle.getSymbolicName() + ", loader=" + loader + ", key='" + key + "'");
+ this.bundle = bundle;
+ this.classLoader = loader;
+ this.partition = hashNamespace(key);
+ try{
+ urlhelper = Shared.getSharedClassHelperFactory().getURLHelper(classLoader);
+ } catch (HelperAlreadyDefinedException e) {
+ e.printStackTrace();
+ }
+ if (CachingServicePlugin.DEBUG) System.out.println("< CachingService.<init>() partition='" + partition + "', urlhelper=" + urlhelper);
+ }
+
+ public ICachingService getInstance(ClassLoader classLoader, Bundle bundle, String key) {
+ return new CachingService(classLoader,bundle, key);
+ }
+
+ public byte[] findStoredClass(String namespace, URL sourceFileURL, String name) {
+ byte[] bytes = urlhelper.findSharedClass(partition, sourceFileURL, name);
+ if (CachingServicePlugin.DEBUG && bytes != null) System.out.println("- CachingService.findStoredClass() bundle=" + bundle.getSymbolicName() + ", name=" + name + ", url=" + sourceFileURL + ", bytes=" + bytes);
+ return bytes;
+ }
+
+ public boolean storeClass(String namespace, URL sourceFileURL, Class clazz, byte[] classbytes) {
+ boolean success = urlhelper.storeSharedClass(partition, sourceFileURL, clazz);
+ if (CachingServicePlugin.DEBUG && success) System.out.println("- CachingService.storeClass() bundle=" + bundle.getSymbolicName() + ", clazz=" + clazz + ", url=" + sourceFileURL);
+ return success;
+ }
+
+ /**
+ * Hash the shared class namespace using MD5
+ * @param keyToHash
+ * @return the MD5 version of the input string
+ */
+ public String hashNamespace(String namespace){
+ MessageDigest md = null;
+ try {
+ md = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ byte[] bytes = md.digest(namespace.getBytes());
+ StringBuffer result = new StringBuffer();
+ for(int i=0; i<bytes.length; i++){
+ byte b = bytes[i];
+ int num;
+ if(b<0) {
+ num = b+256;
+ }else{
+ num=b;
+ }
+ String s = Integer.toHexString(num);
+ while (s.length()<2){
+ s = "0"+s;
+ }
+ result.append(s);
+ }
+ return new String(result);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingServiceFactory.java b/bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingServiceFactory.java
new file mode 100644
index 000000000..c3c86db7d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingServiceFactory.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.internal.caching.j9;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+public class CachingServiceFactory implements ServiceFactory {
+
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ return new CachingService();
+ }
+
+ public void ungetService(Bundle bundle, ServiceRegistration registration,
+ Object service) {
+
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingServicePlugin.java b/bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingServicePlugin.java
new file mode 100644
index 000000000..4009aeb82
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching.j9/src/org/eclipse/equinox/weaving/internal/caching/j9/CachingServicePlugin.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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 minor changes
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.internal.caching.j9;
+
+import org.eclipse.equinox.service.weaving.ICachingService;
+import org.eclipse.osgi.service.debug.DebugOptions;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+import com.ibm.oti.shared.Shared;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class CachingServicePlugin implements BundleActivator {
+
+ public static boolean verbose = Boolean.getBoolean("org.aspectj.osgi.verbose");
+
+ /**
+ * The constructor.
+ */
+ public CachingServicePlugin() {
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ public void start(BundleContext context) throws Exception {
+ if (CachingServicePlugin.DEBUG) System.out.println("> CachingServicePlugin.start() context=" + context);
+
+ loadOptions(context);
+
+ //are we on J9?
+ if(shouldRegister()){
+ if (verbose) System.err.println("[org.aspectj.osgi.service.caching.j9] info starting J9 caching service ...");
+ String name = ICachingService.class.getName();
+// CachingServiceFactory factory = new CachingServiceFactory();
+ CachingService singleCachingService = new CachingService();
+ context.registerService(name,singleCachingService,null);
+// System.out.println("CachingServicePlugin.start() - registered cachingService");
+ }
+ else {
+ if (verbose) System.err.println("[org.aspectj.osgi.service.caching.j9] warning cannot start J9 caching service");
+ }
+
+ if (CachingServicePlugin.DEBUG) System.out.println("< CachingServicePlugin.start()");
+ }
+
+ /**
+ * This method is called when the plug-in is stopped
+ */
+ public void stop(BundleContext context) throws Exception {
+ }
+
+ private boolean shouldRegister(){
+ if (CachingServicePlugin.DEBUG) System.out.println("> CachingServicePlugin.shouldRegister()");
+
+ boolean enabled;
+ try{
+ Class.forName("com.ibm.oti.vm.VM"); //if this fails we are not on J9
+ boolean sharing = Shared.isSharingEnabled(); //if not using shared classes we want a different adaptor
+ if (CachingServicePlugin.DEBUG) System.out.println("- CachingServicePlugin.shouldRegister() sharing=" + sharing);
+
+ if(sharing) {
+ enabled = true;
+ }else{
+ enabled = false;
+ }
+ }
+ catch(ClassNotFoundException ex){
+ if (CachingServicePlugin.DEBUG) System.out.println("E CachingServicePlugin.shouldRegister() ex=" + ex);
+ //not on J9
+ enabled = false;
+ }
+
+ if (CachingServicePlugin.DEBUG) System.out.println("< CachingServicePlugin.shouldRegister() " + enabled);
+ return enabled;
+ }
+
+ private void loadOptions (BundleContext context) {
+ // all this is only to get the application args
+ DebugOptions service = null;
+ ServiceReference reference = context.getServiceReference(DebugOptions.class.getName());
+ if (reference != null)
+ service = (DebugOptions) context.getService(reference);
+ if (service == null)
+ return;
+ try {
+ DEBUG = service.getBooleanOption("org.aspectj.osgi.service.caching.j9/debug", false);
+ } finally {
+ // we have what we want - release the service
+ context.ungetService(reference);
+ }
+ }
+
+ public static boolean DEBUG;
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.caching/.classpath b/bundles/org.eclipse.equinox.weaving.caching/.classpath
new file mode 100644
index 000000000..304e86186
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.weaving.caching/.cvsignore b/bundles/org.eclipse.equinox.weaving.caching/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.weaving.caching/.options b/bundles/org.eclipse.equinox.weaving.caching/.options
new file mode 100644
index 000000000..4a1f02a72
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/.options
@@ -0,0 +1 @@
+org.aspectj.osgi.service.caching/debug=false
diff --git a/bundles/org.eclipse.equinox.weaving.caching/.project b/bundles/org.eclipse.equinox.weaving.caching/.project
new file mode 100644
index 000000000..06b2f9f46
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.weaving.caching</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..e46d604ee
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,78 @@
+#Sun Feb 17 19:55:33 CET 2008
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.pde.core.prefs b/bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 000000000..efde3d153
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Sun Jan 13 21:33:28 CET 2008
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.pde.prefs b/bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.pde.prefs
new file mode 100644
index 000000000..382fc744a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,15 @@
+#Sun Feb 17 19:55:59 CET 2008
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.deprecated=1
+compilers.p.missing-packages=2
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=1
+compilers.p.unknown-class=1
+compilers.p.unknown-element=1
+compilers.p.unknown-resource=1
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/bundles/org.eclipse.equinox.weaving.caching/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.weaving.caching/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..bd51e3b7b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.eclipse.equinox.weaving.caching
+Bundle-Version: 1.0.0.qualifier
+Bundle-Name: Standard Caching Service for Equinox Aspects (Incubation)
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-Activator: org.eclipse.equinox.weaving.internal.caching.Activator
+Import-Package: com.ibm.oti.shared;resolution:=optional,
+ org.eclipse.equinox.service.weaving,
+ org.eclipse.osgi.service.datalocation;version="1.0.0",
+ org.eclipse.osgi.service.debug;version="1.0.0",
+ org.osgi.framework;version="1.4.0"
+Export-Package: org.eclipse.equinox.weaving.internal.caching;x-friends:="org.aspectj.osgi.service.caching.test"
diff --git a/bundles/org.eclipse.equinox.weaving.caching/build.properties b/bundles/org.eclipse.equinox.weaving.caching/build.properties
new file mode 100644
index 000000000..34d2e4d2d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/Activator.java b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/Activator.java
new file mode 100644
index 000000000..06e3af0ef
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/Activator.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Heiko Seeberger 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:
+ * Heiko Seeberger - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.internal.caching;
+
+import org.eclipse.equinox.service.weaving.ICachingService;
+import org.eclipse.osgi.service.debug.DebugOptions;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+import com.ibm.oti.shared.Shared;
+
+/**
+ * {@link BundleActivator} for "org.aspectj.osgi.service.caching".
+ *
+ * @author Heiko Seeberger
+ */
+public class Activator implements BundleActivator {
+
+ public static boolean verbose = Boolean.getBoolean("org.aspectj.osgi.verbose");
+
+ private SingletonCachingService singletonCachingService;
+ private ServiceRegistration singletonCachingServiceRegistration;
+
+ /**
+ * Registers a new {@link SingletonCachingService} instance as OSGi service
+ * under the interface {@link ICachingService}.
+ *
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(final BundleContext bundleContext) {
+ setDebugEnabled(bundleContext);
+
+ if (shouldRegister()) {
+ if (verbose) System.err.println("[org.aspectj.osgi.service.caching] info starting standard caching service ...");
+ registerSingletonCachingService(bundleContext);
+ }
+ else {
+ if (verbose) System.err.println("[org.aspectj.osgi.service.caching] warning cannot start standard caching service on J9 VM");
+ }
+ }
+
+ private boolean shouldRegister() {
+ boolean enabled = true;
+ try {
+ Class.forName("com.ibm.oti.vm.VM"); // if this fails we are not on J9
+ boolean sharing = Shared.isSharingEnabled(); // if not using shared classes we want a different adaptor
+
+ if (sharing) {
+ enabled = false;
+ }
+ } catch (ClassNotFoundException ex) {
+ }
+
+ return enabled;
+ }
+
+ /**
+ * Shuts down the {@link SingletonCachingService}.
+ *
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(final BundleContext context) {
+ singletonCachingService.stop();
+ singletonCachingServiceRegistration.unregister();
+ if (Log.isDebugEnabled()) {
+ Log.debug("Shut down and unregistered SingletonCachingService.");
+ }
+ }
+
+ private void registerSingletonCachingService(
+ final BundleContext bundleContext) {
+ singletonCachingService = new SingletonCachingService(bundleContext);
+ singletonCachingServiceRegistration =
+ bundleContext.registerService(ICachingService.class.getName(),
+ singletonCachingService, null);
+ if (Log.isDebugEnabled()) {
+ Log.debug("Created and registered SingletonCachingService.");
+ }
+ }
+
+ private void setDebugEnabled(final BundleContext bundleContext) {
+ final ServiceReference debugOptionsReference =
+ bundleContext.getServiceReference(DebugOptions.class.getName());
+ if (debugOptionsReference != null) {
+ final DebugOptions debugOptions =
+ (DebugOptions) bundleContext.getService(debugOptionsReference);
+ if (debugOptions != null) {
+ Log.debugEnabled =
+ debugOptions.getBooleanOption(
+ "org.aspectj.osgi.service.caching/debug", true); //$NON-NLS-1$
+ }
+ }
+ if (debugOptionsReference != null) {
+ bundleContext.ungetService(debugOptionsReference);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/BaseCachingService.java b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/BaseCachingService.java
new file mode 100644
index 000000000..848308e6a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/BaseCachingService.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Heiko Seeberger 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:
+ * Heiko Seeberger - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.internal.caching;
+
+import java.net.URL;
+
+import org.eclipse.equinox.service.weaving.ICachingService;
+import org.osgi.framework.Bundle;
+
+/**
+ * Abstract superclass for {@link ICachingService}. Throws
+ * {@link UnsupportedOperationException}s for every method.
+ *
+ * @author Heiko Seeberger
+ */
+public abstract class BaseCachingService implements ICachingService {
+
+ /**
+ * @see org.eclipse.equinox.service.weaving.ICachingService#findStoredClass(java.lang.String,
+ * java.net.URL, java.lang.String)
+ */
+ public byte[] findStoredClass(final String namespace,
+ final URL sourceFileURL, final String name) {
+ throw new UnsupportedOperationException("Illegal call semantics!");
+ }
+
+ /**
+ * @see org.eclipse.equinox.service.weaving.ICachingService#getInstance(java.lang.ClassLoader,
+ * org.osgi.framework.Bundle, java.lang.String)
+ */
+ public ICachingService getInstance(final ClassLoader classLoader,
+ final Bundle bundle, final String key) {
+ throw new UnsupportedOperationException("Illegal call semantics!");
+ }
+
+ /**
+ * @see org.eclipse.equinox.service.weaving.ICachingService#storeClass(java.lang.String,
+ * java.net.URL, java.lang.Class, byte[])
+ */
+ public boolean storeClass(final String namespace, final URL sourceFileURL,
+ final Class clazz, final byte[] classbytes) {
+ throw new UnsupportedOperationException("Illegal call semantics!");
+ }
+}
diff --git a/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/BundleCachingService.java b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/BundleCachingService.java
new file mode 100644
index 000000000..81e58a734
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/BundleCachingService.java
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Heiko Seeberger 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:
+ * Heiko Seeberger - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.internal.caching;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.equinox.service.weaving.ICachingService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * <p>
+ * {@link ICachingService} instantiated by {@link SingletonCachingService} for
+ * each bundle.
+ * </p>
+ * <p>
+ * The maximum number of classes cached in memory before writing to disk is
+ * definded via the system property
+ * <code>org.aspectj.osgi.service.caching.maxCachedClasses</code>. The
+ * default is 20.
+ * </p>
+ *
+ * @author Heiko Seeberger
+ */
+public class BundleCachingService extends BaseCachingService {
+
+ private static final int BUFFER_SIZE = 8 * 1024;
+ private static final Integer MAX_CACHED_CLASSES =
+ Integer.getInteger("org.aspectj.osgi.service.caching.maxCachedClasses",
+ 20);
+
+ private final Bundle bundle;
+ private final BundleContext bundleContext;
+
+ private File cache;
+ private final String cacheKey;
+
+ private final Map<String, byte[]> cachedClasses =
+ new HashMap<String, byte[]>(MAX_CACHED_CLASSES + 10);
+
+
+ /**
+ * @param bundleContext
+ * Must not be null!
+ * @param bundle
+ * Must not be null!
+ * @param key
+ * Must not be null!
+ * @throws IllegalArgumentException
+ * if given bundleContext or bundle is null.
+ */
+ public BundleCachingService(final BundleContext bundleContext,
+ final Bundle bundle, final String key) {
+
+ if (bundleContext == null) {
+ throw new IllegalArgumentException(
+ "Argument \"bundleContext\" must not be null!");
+ }
+ if (bundle == null) {
+ throw new IllegalArgumentException(
+ "Argument \"bundle\" must not be null!");
+ }
+ if (key == null) {
+ throw new IllegalArgumentException(
+ "Argument \"key\" must not be null!");
+ }
+
+ this.bundleContext = bundleContext;
+ this.bundle = bundle;
+ this.cacheKey = hashNamespace(key);
+
+ initCache();
+ }
+
+ /**
+ * @see org.eclipse.equinox.service.weaving.ICachingService#findStoredClass(java.lang.String,
+ * java.net.URL, java.lang.String)
+ */
+ @Override
+ public byte[] findStoredClass(final String namespace,
+ final URL sourceFileURL, final String name) {
+
+ if (name == null) {
+ throw new IllegalArgumentException(
+ "Argument \"name\" must not be null!");
+ }
+
+ byte[] storedClass = null;
+ if (cache != null) {
+ File cachedBytecodeFile = new File(cache, name);
+ if (cachedBytecodeFile.exists()) {
+ storedClass = read(name, cachedBytecodeFile);
+ }
+ }
+
+ if (Log.isDebugEnabled()) {
+ Log.debug(MessageFormat.format("for [{0}]: {1} {2}", bundle
+ .getSymbolicName(), ((storedClass != null) ? "Found"
+ : "Found NOT"), name));
+ }
+ return storedClass;
+ }
+
+ /**
+ * Writes the remaining cache to disk.
+ */
+ public void stop() {
+ if (cache != null) {
+ for (final String name : cachedClasses.keySet()) {
+ write(name);
+ }
+ }
+ }
+
+ /**
+ * @see org.eclipse.equinox.service.weaving.ICachingService#storeClass(java.lang.String,
+ * java.net.URL, java.lang.Class, byte[])
+ */
+ @Override
+ public boolean storeClass(final String namespace, final URL sourceFileURL,
+ final Class clazz, final byte[] classbytes) {
+
+ if (clazz == null) {
+ throw new IllegalArgumentException(
+ "Argument \"clazz\" must not be null!");
+ }
+ if (classbytes == null) {
+ throw new IllegalArgumentException(
+ "Argument \"classbytes\" must not be null!");
+ }
+
+ if (cache == null) {
+ return false;
+ }
+
+ cachedClasses.put(clazz.getName(), classbytes);
+ if (cachedClasses.size() > MAX_CACHED_CLASSES) {
+
+ final Iterator<String> names = cachedClasses.keySet().iterator();
+ while (names.hasNext()) {
+ write(names.next());
+ names.remove();
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Hash the shared class namespace using MD5
+ *
+ * @param keyToHash
+ * @return the MD5 version of the input string
+ */
+ private String hashNamespace(final String namespace) {
+ MessageDigest md = null;
+ try {
+ md = MessageDigest.getInstance("MD5");
+ }
+ catch (final NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ final byte[] bytes = md.digest(namespace.getBytes());
+ final StringBuffer result = new StringBuffer();
+ for (final byte b : bytes) {
+ int num;
+ if (b < 0) {
+ num = b + 256;
+ }
+ else {
+ num = b;
+ }
+ String s = Integer.toHexString(num);
+ while (s.length() < 2) {
+ s = "0" + s;
+ }
+ result.append(s);
+ }
+ return new String(result);
+ }
+
+ private void initCache() {
+ boolean isInitialized = false;
+ final File dataFile = bundleContext.getDataFile("");
+ if (dataFile != null) {
+ cache =
+ new File(new File(dataFile, cacheKey), bundle.getSymbolicName());
+ if (!cache.exists()) {
+ isInitialized = cache.mkdirs();
+ }
+ else {
+ isInitialized = true;
+ }
+ }
+ if (!isInitialized) {
+ Log.error("Cannot initialize cache!", null);
+ }
+ }
+
+ private byte[] read(final String name, final File file) {
+ int length = (int) file.length();
+
+ InputStream in = null;
+ try {
+ byte[] classbytes = new byte[length];
+ int bytesread = 0;
+ int readcount;
+
+ in = new FileInputStream(file);
+
+ if (length > 0) {
+ classbytes = new byte[length];
+ for (; bytesread < length; bytesread += readcount) {
+ readcount = in.read(classbytes, bytesread, length - bytesread);
+ if (readcount <= 0) /* if we didn't read anything */
+ break; /* leave the loop */
+ }
+ } else /* BundleEntry does not know its own length! */{
+ length = BUFFER_SIZE;
+ classbytes = new byte[length];
+ readloop: while (true) {
+ for (; bytesread < length; bytesread += readcount) {
+ readcount = in.read(classbytes, bytesread, length - bytesread);
+ if (readcount <= 0) /* if we didn't read anything */
+ break readloop; /* leave the loop */
+ }
+ byte[] oldbytes = classbytes;
+ length += BUFFER_SIZE;
+ classbytes = new byte[length];
+ System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
+ }
+ }
+ if (classbytes.length > bytesread) {
+ byte[] oldbytes = classbytes;
+ classbytes = new byte[bytesread];
+ System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
+ }
+ return classbytes;
+ }
+ catch (final IOException e) {
+ Log.error(MessageFormat.format(
+ "for [{0}]: Cannot read [1] from cache!", bundle
+ .getSymbolicName(), name), e);
+ return null;
+ }
+ finally {
+ if (in != null) {
+ try {
+ in.close();
+ }
+ catch (final IOException e) {
+ Log.error(MessageFormat.format(
+ "for [{0}]: Cannot close cache file for [1]!", bundle
+ .getSymbolicName(), name), e);
+ }
+ }
+ }
+ }
+
+ private void write(final String name) {
+ // TODO Think about synchronization !!!
+ FileOutputStream out = null;
+ try {
+ out = new FileOutputStream(new File(cache, name));
+ out.write(cachedClasses.get(name));
+ out.close();
+ if (Log.isDebugEnabled()) {
+ Log.debug(MessageFormat.format(
+ "for [{0}]: Written {1} to cache.", bundle
+ .getSymbolicName(), name));
+ }
+ }
+ catch (final IOException e) {
+ Log.error(MessageFormat.format(
+ "for [{0}]: Cannot write [1] to cache!", bundle
+ .getSymbolicName(), name), e);
+ }
+ finally {
+ if (out != null) {
+ try {
+ out.close();
+ }
+ catch (final IOException e) {
+ Log.error(MessageFormat.format(
+ "for [{0}]: Cannot close cache file for [1]!", bundle
+ .getSymbolicName(), name), e);
+ }
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/IBundleConstants.java b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/IBundleConstants.java
new file mode 100644
index 000000000..14476ceae
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/IBundleConstants.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Heiko Seeberger 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:
+ * Heiko Seeberger - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.internal.caching;
+
+/**
+ * Constants for org.aspectj.osgi.service.caching".
+ *
+ * @author Heiko Seeberger
+ */
+public interface IBundleConstants {
+
+ /**
+ * The symbolic name for this bundle: "org.aspectj.osgi.service.caching".
+ */
+ public static final String BUNDLE_SYMBOLIC_NAME =
+ "org.aspectj.osgi.service.caching"; //$NON-NLS-1$
+}
diff --git a/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/Log.java b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/Log.java
new file mode 100644
index 000000000..7a9e2f60d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/Log.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Heiko Seeberger 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:
+ * Heiko Seeberger - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.internal.caching;
+
+import static org.eclipse.equinox.weaving.internal.caching.IBundleConstants.BUNDLE_SYMBOLIC_NAME;
+
+/**
+ * Logging utility.
+ *
+ * @author Heiko Seeberger
+ */
+public class Log {
+
+ static boolean debugEnabled = false;
+
+ private static final String PREFIX = "[" + BUNDLE_SYMBOLIC_NAME + "] "; //$NON-NLS-1$ //$NON-NLS-2$
+
+ /**
+ * Logging debug information.
+ *
+ * @param message
+ * The tracing message, optional.
+ */
+ public static void debug(final String message) {
+ if (debugEnabled) {
+ if (message != null) {
+ System.out.println(PREFIX + message);
+ }
+ }
+ }
+
+ /**
+ * Logging an error.
+ *
+ * @param message
+ * The error message, optional.
+ * @param t
+ * The Throwable for this error, optional.
+ */
+ public static void error(final String message, final Throwable t) {
+ if (message != null) {
+ System.err.println(PREFIX + message);
+ }
+ if (t != null) {
+ t.printStackTrace(System.err);
+ }
+ }
+
+ /**
+ * Shows debug toggle state.
+ *
+ * @return true, if debug is enabled, else false.
+ */
+ public static boolean isDebugEnabled() {
+ return debugEnabled;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/SingletonCachingService.java b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/SingletonCachingService.java
new file mode 100644
index 000000000..764af442c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.caching/src/org/eclipse/equinox/weaving/internal/caching/SingletonCachingService.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Heiko Seeberger 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:
+ * Heiko Seeberger - initial implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.internal.caching;
+
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.equinox.service.weaving.ICachingService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+
+/**
+ * {@link ICachingService} used as "singleton" OSGi service by
+ * "org.aspectj.osgi".
+ *
+ * @author Heiko Seeberger
+ */
+public class SingletonCachingService extends BaseCachingService {
+
+ private final Map<String, BundleCachingService> bundleCachingServices =
+ new HashMap<String, BundleCachingService>();
+
+ private final BundleContext bundleContext;
+
+ /**
+ * @param bundleContext
+ * Must not be null!
+ * @throws IllegalArgumentException
+ * if given bundleContext is null.
+ */
+ public SingletonCachingService(final BundleContext bundleContext) {
+ if (bundleContext == null) {
+ throw new IllegalArgumentException(
+ "Argument \"bundleContext\" must not be null!");
+ }
+ this.bundleContext = bundleContext;
+
+ this.bundleContext.addBundleListener(new SynchronousBundleListener() {
+ public void bundleChanged(BundleEvent event) {
+ if (event.getType() == BundleEvent.UNINSTALLED) {
+ stopBundleCachingService(event);
+ }
+ }
+ });
+ }
+
+ /**
+ * Looks for a stored {@link BaseCachingService} for the given bundle. If
+ * this exits it is returned, else created and stored.
+ *
+ * @see org.eclipse.equinox.service.weaving.ICachingService#getInstance(java.lang.ClassLoader,
+ * org.osgi.framework.Bundle, java.lang.String)
+ */
+ @Override
+ public synchronized ICachingService getInstance(
+ final ClassLoader classLoader, final Bundle bundle, String key) {
+
+ if (bundle == null) {
+ throw new IllegalArgumentException(
+ "Argument \"bundle\" must not be null!");
+ }
+
+ BundleCachingService bundleCachingService =
+ bundleCachingServices.get(bundle.getSymbolicName());
+
+ key = key == null || key.length() == 0 ? "defaultCache" : key;
+
+ if (bundleCachingService == null) {
+
+ bundleCachingService =
+ new BundleCachingService(bundleContext, bundle, key);
+ bundleCachingServices.put(bundle.getSymbolicName(),
+ bundleCachingService);
+
+ if (Log.isDebugEnabled()) {
+ Log.debug(MessageFormat.format(
+ "Created BundleCachingService for [{0}].", bundle
+ .getSymbolicName()));
+ }
+ }
+
+ return bundleCachingService;
+ }
+
+ /**
+ * Stops all individual bundle services.
+ */
+ public synchronized void stop() {
+ for (final BundleCachingService bundleCachingService : bundleCachingServices
+ .values()) {
+ bundleCachingService.stop();
+ }
+ bundleCachingServices.clear();
+ }
+
+ /**
+ * Stops individual bundle caching service if the bundle is uninstalled
+ */
+ protected void stopBundleCachingService(BundleEvent event) {
+ String symbolicName = event.getBundle().getSymbolicName();
+ BundleCachingService bundleCachingService = bundleCachingServices.get(symbolicName);
+ if (bundleCachingService != null) {
+ bundleCachingService.stop();
+ bundleCachingServices.remove(symbolicName);
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.hook/.classpath b/bundles/org.eclipse.equinox.weaving.hook/.classpath
new file mode 100644
index 000000000..a9648dd85
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry excluding="org/aspectj/weaver/osgi/hooks/AspectJBundleWatcherHook.java|org/aspectj/weaver/osgi/hooks/AspectJBundleFileWrapperFactoryHook.java|org/aspectj/weaver/osgi/hooks/AspectJHookConfigurator.java|org/aspectj/weaver/osgi/hooks/AspectJClassLoadingHook.java|org/aspectj/weaver/osgi/hooks/AspectJClassLoadingStatsHook.java|org/aspectj/osgi/hooks/AspectJHookConfigurator.java|org/aspectj/osgi/hooks/AspectJClassLoadingHook.java|org/aspectj/osgi/hooks/AspectJBundleFileWrapperFactoryHook.java|org/aspectj/osgi/hooks/AspectJBundleWatcherHook.java|org/aspectj/osgi/hooks/AspectJClassLoadingStatsHook.java" kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.3"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.weaving.hook/.cvsignore b/bundles/org.eclipse.equinox.weaving.hook/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.weaving.hook/.options b/bundles/org.eclipse.equinox.weaving.hook/.options
new file mode 100644
index 000000000..1b6f040ff
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/.options
@@ -0,0 +1,6 @@
+org.aspectj.osgi/debug=false
+org.aspectj.osgi/debug/bundle=false
+org.aspectj.osgi/debug/weave=false
+org.aspectj.osgi/debug/cache=false
+org.aspectj.osgi/debug/supplements=false
+org.aspectj.osgi/debug/bundleName=
diff --git a/bundles/org.eclipse.equinox.weaving.hook/.project b/bundles/org.eclipse.equinox.weaving.hook/.project
new file mode 100644
index 000000000..ccdd43984
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.weaving.hook</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.weaving.hook/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.weaving.hook/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..3121c2dbc
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Fri Oct 13 09:40:18 BST 2006
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.1
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.3
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=ignore
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/bundles/org.eclipse.equinox.weaving.hook/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.equinox.weaving.hook/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..320731eb0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,3 @@
+#Fri Oct 13 09:40:18 BST 2006
+eclipse.preferences.version=1
+internal.default.compliance=default
diff --git a/bundles/org.eclipse.equinox.weaving.hook/All OSGi Tests (AOSGi).launch b/bundles/org.eclipse.equinox.weaving.hook/All OSGi Tests (AOSGi).launch
new file mode 100644
index 000000000..86e1c8e6a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/All OSGi Tests (AOSGi).launch
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?><launchConfiguration type="org.eclipse.pde.ui.JunitLaunchConfig">
+<stringAttribute key="application" value="org.eclipse.pde.junit.runtime.coretestapplication"/>
+<booleanAttribute key="askclear" value="false"/>
+<booleanAttribute key="automaticAdd" value="true"/>
+<booleanAttribute key="automaticValidate" value="false"/>
+<stringAttribute key="bootstrap" value=""/>
+<stringAttribute key="checked" value="[NONE]"/>
+<booleanAttribute key="clearConfig" value="true"/>
+<booleanAttribute key="clearws" value="true"/>
+<stringAttribute key="configLocation" value=""/>
+<booleanAttribute key="default" value="true"/>
+<booleanAttribute key="includeFragments" value="false"/>
+<booleanAttribute key="includeOptional" value="true"/>
+<stringAttribute key="location" value="c:\temp\test-workspaces"/>
+<stringAttribute key="location1" value="c:\temp\test-workspaces"/>
+<stringAttribute key="location2" value="d:\work\workspaces\runtime-test-workspace"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
+<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
+<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
+<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.osgi.tests.AutomatedTests"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.osgi.tests"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
+<stringAttribute key="pde.version" value="3.3"/>
+<stringAttribute key="product" value="org.eclipse.platform.ide"/>
+<stringAttribute key="templateConfig" value="C:\workspaces\aspects-equinox-incubator\org.aspectj.osgi\config.ini"/>
+<booleanAttribute key="tracing" value="false"/>
+<booleanAttribute key="useDefaultConfig" value="false"/>
+<booleanAttribute key="useDefaultConfigArea" value="true"/>
+<booleanAttribute key="useProduct" value="false"/>
+</launchConfiguration> \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.weaving.hook/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.weaving.hook/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..f2ade9230
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Aspect Weaving Hooks Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.equinox.weaving.hook
+Bundle-Version: 1.0.0.qualifier
+Fragment-Host: org.eclipse.osgi;bundle-version="[3.2.0,4.0.0)"
+Export-Package: org.eclipse.equinox.service.weaving
+Bundle-RequiredExecutionEnvironment: J2SE-1.3
diff --git a/bundles/org.eclipse.equinox.weaving.hook/build.properties b/bundles/org.eclipse.equinox.weaving.hook/build.properties
new file mode 100644
index 000000000..a42e7f7fc
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ hookconfigurators.properties,\
+ .options
diff --git a/bundles/org.eclipse.equinox.weaving.hook/config.ini b/bundles/org.eclipse.equinox.weaving.hook/config.ini
new file mode 100644
index 000000000..a2b878aa7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/config.ini
@@ -0,0 +1,12 @@
+osgi.bundles=org.eclipse.equinox.common@2\:start,org.eclipse.update.configurator@3\:start,org.eclipse.core.runtime@start, org.aspectj.osgi.service.weaving@:start
+osgi.bundles.defaultStartLevel=4
+osgi.framework=org.eclipse.osgi
+osgi.configuration.cascaded=false
+osgi.splashPath=platform:/base/plugins/org.eclipse.platform
+
+# AOSGi
+osgi.framework.extensions=org.aspectj.osgi
+org.aspectj.weaver.loadtime.configuration=META-INF/aop.xml;org/aspectj/aop.xml;META-INF/aop-ajc.xml
+#aj.weaving.verbose=true
+#org.aspectj.weaver.showWeaveInfo=true
+org.aspectj.osgi.verbose=true \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.weaving.hook/hookconfigurators.properties b/bundles/org.eclipse.equinox.weaving.hook/hookconfigurators.properties
new file mode 100644
index 000000000..8ade8522d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/hookconfigurators.properties
@@ -0,0 +1,2 @@
+hook.configurators= \
+ org.eclipse.equinox.weaving.hooks.AspectJHook
diff --git a/bundles/org.eclipse.equinox.weaving.hook/patches/org.eclipse.osgi_patch_20060509.txt b/bundles/org.eclipse.equinox.weaving.hook/patches/org.eclipse.osgi_patch_20060509.txt
new file mode 100644
index 000000000..d03b0424b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/patches/org.eclipse.osgi_patch_20060509.txt
@@ -0,0 +1,594 @@
+### Eclipse Workspace Patch 1.0
+#P org.eclipse.osgi
+Index: core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java,v
+retrieving revision 1.11
+diff -u -r1.11 BundleDescription.java
+--- core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java 17 Mar 2006 14:46:43 -0000 1.11
++++ core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java 9 May 2006 21:27:12 -0000
+@@ -227,4 +227,27 @@
+ * @return the list of execution environments that are required.
+ */
+ public String[] getExecutionEnvironments();
++
++ // AMC
++ /**
++ * Returns the supplemented import packages defined by the Supplement-Importer
++ * clause.
++ */
++ public ImportPackageSpecification[] getSupplementedImportPackages();
++
++ /**
++ * Returns the supplemented export packages defined by the Supplement-Exporter
++ * clause.
++ */
++ public ImportPackageSpecification[] getSupplementedExportPackages();
++
++ //end AMC
++
++ //knibb
++ /**
++ * Returns the supplemented bundles defined by the Supplement-Bundle clause
++ */
++ public BundleDescription[] getSupplementedBundles();
++ //end knibb
++
+ }
+Index: core/framework/org/eclipse/osgi/framework/internal/core/Constants.java
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Constants.java,v
+retrieving revision 1.29
+diff -u -r1.29 Constants.java
+--- core/framework/org/eclipse/osgi/framework/internal/core/Constants.java 26 Oct 2005 17:58:14 -0000 1.29
++++ core/framework/org/eclipse/osgi/framework/internal/core/Constants.java 9 May 2006 21:27:12 -0000
+@@ -268,4 +268,44 @@
+ * @deprecated use {@link #ECLIPSE_LAZYSTART_EXCEPTIONS}
+ */
+ public static final String ECLIPSE_AUTOSTART_EXCEPTIONS = ECLIPSE_LAZYSTART_EXCEPTIONS;
++
++
++ // Added by AMC
++
++ /**
++ * Manifest header (named &quot;Supplement-Importer&quot;) identifying the names
++ * (and optionally, version numbers) of the packages that the bundle supplements.
++ * All importers of one of these packages will have the exported packages of this
++ * bundle added to their imports in addition.
++ *
++ * <p>
++ * The attribute value may be retrieved from the <code>Dictionary</code>
++ * object returned by the <code>Bundle.getHeaders</code> method.
++ */
++ public static final String SUPPLEMENT_IMPORTER = "Eclipse-SupplementImporter"; //$NON-NLS-1$
++
++ /**
++ * Manifest header (named &quot;Supplement-Exporter&quot;) identifying the names
++ * (and optionally, version numbers) of the packages that the bundle supplements.
++ * All exporters of one of these packages will have the exported packages of this bundle
++ * added to their imports list.
++ *
++ * <p>
++ * The attribute value may be retrieved from the <code>Dictionary</code>
++ * object returned by the <code>Bundle.getHeaders</code> method.
++ */
++ public static final String SUPPLEMENT_EXPORTER = "Eclipse-SupplementExporter"; //$NON-NLS-1$
++
++ //knibb
++ /**
++ * Manifest header (named &quot;Supplement-Bundle&quot;) identifying the names
++ * (and optionally, version numbers) of any bundles supplemented by this bundle.
++ * All supplemented bundles will have all the exported packages of this bundle
++ * added to their imports list
++ *
++ * <p>
++ * The attribute value may be retrieved from the <code>Dictionary</code>
++ * object returned by the <code>Bundle.getHeaders</code> method.
++ */
++ public static final String SUPPLEMENT_BUNDLE = "Eclipse-SupplementBundle"; //$NON-NLS-1$
+ }
+Index: resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java,v
+retrieving revision 1.46
+diff -u -r1.46 StateBuilder.java
+--- resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java 24 Apr 2006 16:23:48 -0000 1.46
++++ resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java 9 May 2006 21:27:18 -0000
+@@ -101,6 +101,23 @@
+ result.setGenericRequires(createGenericRequires(genericRequires));
+ ManifestElement[] genericCapabilities = getGenericCapabilities(manifest, genericAliases);
+ result.setGenericCapabilities(createGenericCapabilities(genericCapabilities));
++
++ // AMC addition
++ ManifestElement[] supplementImporter = ManifestElement.parseHeader(Constants.SUPPLEMENT_IMPORTER, (String) manifest.get(Constants.SUPPLEMENT_IMPORTER));
++ if (supplementImporter != null)
++ result.setSupplementedImportPackages(createPackageSpecification(supplementImporter,manifestVersion));
++ ManifestElement[] supplementExporter = ManifestElement.parseHeader(Constants.SUPPLEMENT_EXPORTER, (String) manifest.get(Constants.SUPPLEMENT_EXPORTER));
++ if (supplementExporter != null)
++ result.setSupplementedExportPackages(createPackageSpecification(supplementExporter,manifestVersion));
++ // end AMC
++
++ //knibb
++
++ ManifestElement[] supplementBundle = ManifestElement.parseHeader(Constants.SUPPLEMENT_BUNDLE, (String) manifest.get(Constants.SUPPLEMENT_BUNDLE));
++ if (supplementBundle != null)
++ result.setSupplementedBundles(createBundleSpecification(supplementBundle,manifestVersion));
++
++ //end knibb
+ return result;
+ }
+
+@@ -544,4 +561,46 @@
+ if (!hostName.equals(Constants.SYSTEM_BUNDLE_SYMBOLICNAME) && !hostName.equals(Constants.getInternalSymbolicName()))
+ throw new BundleException(NLS.bind(StateMsg.HEADER_EXTENSION_ERROR, hostName));
+ }
+-}
++
++ // AMC
++
++ private static ImportPackageSpecification[] createPackageSpecification(ManifestElement[] packages, int manifestVersion) {
++ ImportPackageSpecificationImpl[] result = new ImportPackageSpecificationImpl[packages.length];
++ for (int p = 0; p < packages.length; p++) {
++ String[] packagesNames = packages[p].getValueComponents();
++ for (int i = 0; i < packagesNames.length; i++) {
++ ImportPackageSpecificationImpl spec = new ImportPackageSpecificationImpl();
++ spec.setName(packagesNames[i]);
++ // set common attributes for both dynamic and static imports
++ spec.setVersionRange(getVersionRange(manifestVersion < 2 ? packages[p].getAttribute(Constants.PACKAGE_SPECIFICATION_VERSION) : packages[p].getAttribute(Constants.VERSION_ATTRIBUTE)));
++ spec.setBundleSymbolicName(packages[p].getAttribute(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE));
++ spec.setBundleVersionRange(getVersionRange(packages[p].getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE)));
++ spec.setAttributes(getAttributes(packages[p],DEFINED_MATCHING_ATTRS));
++ //spec.setPropagate(ManifestElement.getArrayFromList(packages[p].getDirective(Constants.GROUPING_DIRECTIVE)));
++ spec.setDirective(Constants.RESOLUTION_DIRECTIVE,getResolution(packages[p].getDirective(Constants.RESOLUTION_DIRECTIVE)));
++ result[p] = spec;
++ }
++ }
++ return result;
++ }
++ //End AMC
++
++ //knibb
++
++ private static BundleDescription[] createBundleSpecification(ManifestElement[] bundles, int manifestVersion) {
++ BundleDescriptionImpl[] result = new BundleDescriptionImpl[bundles.length];
++ for (int b=0; b<bundles.length; b++) {
++ String[] bundleNames = bundles[b].getValueComponents();
++ for(int i=0; i<bundleNames.length; i++) {
++ BundleDescriptionImpl spec = new BundleDescriptionImpl();
++ spec.setName(bundleNames[i]);
++ //TODO incomplete - only matches bundle name at this time
++ result[b] = spec;
++ }
++ }
++ return result;
++ }
++
++
++ //end knibb
++}
+\ No newline at end of file
+Index: resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java,v
+retrieving revision 1.6
+diff -u -r1.6 BundleSpecificationImpl.java
+--- resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java 12 Sep 2005 16:44:01 -0000 1.6
++++ resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java 9 May 2006 21:27:17 -0000
+@@ -18,6 +18,14 @@
+ private boolean exported;
+ private boolean optional;
+
++ // AMC
++ public BundleSpecificationImpl() { /* empty */ }
++
++ public BundleSpecificationImpl(String name) {
++ setName(name);
++ }
++ // End AMC
++
+ protected void setExported(boolean exported) {
+ this.exported = exported;
+ }
+Index: resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java,v
+retrieving revision 1.35
+diff -u -r1.35 BundleDescriptionImpl.java
+--- resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java 17 Mar 2006 14:46:42 -0000 1.35
++++ resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java 9 May 2006 21:27:17 -0000
+@@ -91,6 +91,35 @@
+ return EMPTY_IMPORTS;
+ return lazyData.importPackages;
+ }
++
++ // AMC
++
++ public ImportPackageSpecification[] getSupplementedImportPackages() {
++ fullyLoad();
++ if (lazyData.supplementedImports == null)
++ return new ImportPackageSpecification[0];
++ return lazyData.supplementedImports;
++ }
++
++ public ImportPackageSpecification[] getSupplementedExportPackages() {
++ fullyLoad();
++ if (lazyData.supplementedExports == null)
++ return new ImportPackageSpecification[0];
++ return lazyData.supplementedExports;
++ }
++
++ // END AMC
++
++ //knibb
++
++ public BundleDescription[] getSupplementedBundles() {
++ fullyLoad();
++ if (lazyData.SupplementedBundles == null)
++ return new BundleDescription[0];
++ return lazyData.SupplementedBundles;
++ }
++
++ //end knibb
+
+ public BundleSpecification[] getRequiredBundles() {
+ fullyLoad();
+@@ -224,6 +253,31 @@
+ }
+ }
+
++ // AMC
++
++ protected void setSupplementedImportPackages(ImportPackageSpecification[] supplementedImports) {
++ checkLazyData();
++ lazyData.supplementedImports = supplementedImports;
++ }
++
++
++ protected void setSupplementedExportPackages(ImportPackageSpecification[] supplementedExports) {
++ checkLazyData();
++ lazyData.supplementedExports = supplementedExports;
++ }
++
++ // END AMC
++
++ //knibb
++
++ protected void setSupplementedBundles(BundleDescription[] supplementedBundles) {
++ checkLazyData();
++ lazyData.SupplementedBundles = supplementedBundles;
++ }
++
++ //end knibb
++
++
+ protected void setRequiredBundles(BundleSpecification[] requiredBundles) {
+ checkLazyData();
+ lazyData.requiredBundles = requiredBundles;
+@@ -543,5 +597,11 @@
+ String[] executionEnvironments;
+
+ HashMap dynamicStamps;
++
++ // AMC
++ ImportPackageSpecification[] supplementedImports;
++ ImportPackageSpecification[] supplementedExports;
++ //knibb
++ BundleDescription[] SupplementedBundles;
+ }
+ }
+Index: resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java,v
+retrieving revision 1.20
+diff -u -r1.20 ResolverBundle.java
+--- resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java 3 May 2006 13:35:59 -0000 1.20
++++ resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java 9 May 2006 21:27:14 -0000
+@@ -252,6 +252,16 @@
+ return allRequires[i];
+ return null;
+ }
++
++ // AMC
++ void addRequired(BundleConstraint required) {
++ BundleConstraint[] newRequires = new BundleConstraint[requires.length + 1];
++ System.arraycopy(requires,0,newRequires,0,requires.length);
++ newRequires[requires.length] = required;
++ requires = newRequires;
++ }
++
++ // End AMC
+
+ public BundleDescription getBundle() {
+ return (BundleDescription) getBaseDescription();
+@@ -494,4 +504,4 @@
+ int getRefs() {
+ return refs == null ? 0 : refs.size();
+ }
+-}
++}
+\ No newline at end of file
+Index: resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java,v
+retrieving revision 1.35
+diff -u -r1.35 ResolverImpl.java
+--- resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java 17 Apr 2006 20:22:58 -0000 1.35
++++ resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java 9 May 2006 21:27:16 -0000
+@@ -15,6 +15,7 @@
+ import org.eclipse.osgi.framework.debug.Debug;
+ import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
+ import org.eclipse.osgi.internal.resolver.BundleDescriptionImpl;
++import org.eclipse.osgi.internal.resolver.BundleSpecificationImpl;
+ import org.eclipse.osgi.service.resolver.*;
+ import org.eclipse.osgi.util.ManifestElement;
+ import org.osgi.framework.*;
+@@ -29,6 +30,7 @@
+ private static final String OPTION_GENERICS = RESOLVER + "/generics"; //$NON-NLS-1$
+ private static final String OPTION_GROUPING = RESOLVER + "/grouping"; //$NON-NLS-1$
+ private static final String OPTION_CYCLES = RESOLVER + "/cycles"; //$NON-NLS-1$
++ private static final String OPTION_SUPPLEMENTS = RESOLVER + "/supplements"; //$NON-NLS-1$
+ public static boolean DEBUG = false;
+ public static boolean DEBUG_WIRING = false;
+ public static boolean DEBUG_IMPORTS = false;
+@@ -571,6 +573,7 @@
+
+ // This method will attempt to resolve the supplied bundle and any bundles that it is dependent on
+ private boolean resolveBundle(ResolverBundle bundle, ArrayList cycle) {
++// System.out.println("ResolverImpl.resolveBundle() bundle=" + bundle.getName());
+ if (bundle.isFragment())
+ return false;
+ if (!bundle.isResolvable()) {
+@@ -646,6 +649,100 @@
+ }
+ }
+ }
++
++ // AMC
++// System.err.println("? ResolverImpl.resolveBundle() bundle=" + bundle); //$NON-NLS-1$
++ if (!failed) {
++ // XXX this feels horribly inefficient...
++ // Iterate thru resolver bundles looking for any supplementors of packages that this
++ // bundle imports or exports. If we find a match, resolve it as a required bundle of
++ // this bundle
++ // Exports first
++ ResolverExport[] exports = bundle.getExportPackages();
++ outerExport: for (Iterator iter = resolverBundles.iterator(); iter.hasNext(); ) {
++ Object[] suppliers = (Object[]) iter.next();
++ //suppliers is an array of ResolverBundle objects. ResolverBundle is a subclass of VersionSupplier
++ //so suppliers has type VersionSupplier[]
++ //unfortunately this results in a ClassCastException so that is why this is an Object[] and not VersionSupplier[]
++ for (int s = 0; s < suppliers.length; s++) {
++ //the cast from Object to VersionSupplier is made here
++ VersionSupplier supplier = (VersionSupplier) suppliers[s];
++ BundleDescription desc = supplier.getBundle();
++ ImportPackageSpecification[] supplements = desc.getSupplementedExportPackages();
++ for (int i = 0; i < supplements.length; i++) {
++ for (int e = 0; e < exports.length; e++) {
++ if (supplements[i].getName().equals(exports[e].getName())) {
++ // it's a match
++ if(Debug.DEBUG_SUPPLEMENTS)
++ System.out.println("export " + exports[i] + " supplemented by " + desc); //$NON-NLS-1$//$NON-NLS-2$
++ // add suppliers[s].getBundle as a required bundle for me...
++ addRequired(bundle,supplier.getBundle(), cycle);
++ continue outerExport;
++ }
++ }
++ }
++ }
++ }
++ // Then imports
++ ResolverImport[] imports = bundle.getImportPackages();
++ outer: for (Iterator iter = resolverBundles.iterator(); iter.hasNext();) {
++ Object[] suppliers = (Object[]) iter.next();
++ for (int s = 0; s < suppliers.length; s++) {
++ VersionSupplier supplier = (VersionSupplier) suppliers[s];
++ BundleDescription desc = supplier.getBundle();
++ ImportPackageSpecification[] supplements = desc.getSupplementedImportPackages();
++ for (int i = 0; i < supplements.length; i++) {
++ for (int j = 0; j < imports.length; j++) {
++ ImportPackageSpecification possibleMatch = (ImportPackageSpecification) imports[j].getVersionConstraint();
++ if (possibleMatch.getName().equals(supplements[i].getName())) {
++ // we have a match
++ if(Debug.DEBUG_SUPPLEMENTS)
++ System.out.println("import " + imports[j] + " supplemented by " + desc); //$NON-NLS-1$ //$NON-NLS-2$
++ addRequired(bundle,supplier.getBundle(), cycle);
++ continue outer;
++ }
++ }
++ }
++ }
++ }
++ }
++ // END AMC
++
++ //knibb
++ //now check for any other bundles which supplement this bundle
++ //TODO - would be usefull to have an exclusion mechanism here (e.g. you could then say someting like "supplement all bundles, except....")
++ if(!failed) {
++ String myName = bundle.getName();
++ for (Iterator iter = resolverBundles.iterator(); iter.hasNext();) {
++ Object[] suppliers = (Object[]) iter.next();
++ outerBundles: for(int s=0; s < suppliers.length; s++){
++ VersionSupplier supplier = (VersionSupplier) suppliers[s];
++ BundleDescription desc = supplier.getBundle();
++ //don't want to supplement ourselves so break if desc and bundle are the same
++ if(bundle.getBundle().equals(desc)){
++ continue outerBundles;
++ }
++ //supplemtor should not supplement any bundle on which it depends
++ BundleSpecification[] bundlesRequiredBySupplementor = desc.getRequiredBundles();
++ for(int i=0; i<bundlesRequiredBySupplementor.length; i++){
++ if(bundlesRequiredBySupplementor[i].getName().equals( myName ))
++ continue outerBundles; //avoid circular dependacy - do not allow a bundle to supplement any bundle on which it depends
++ }
++ BundleDescription[] supplemented = desc.getSupplementedBundles(); //the list of bundles it (desc) supplements
++ for(int i=0; i<supplemented.length; i++){
++// if ( myName.equals(supplemented[i].getName())){
++ if ( equals_wild(supplemented[i].getName(), myName)){
++ addRequired(bundle, desc, cycle);
++ if(Debug.DEBUG_SUPPLEMENTS)
++ System.out.println("bundle Supplement-Bundle: " + bundle + " supplemeted by [" + desc +"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
++ }
++ }
++ }
++ }
++ }
++
++ //end knibb
++
+ // Need to check that all mandatory imports are wired. If they are then
+ // set the bundle RESOLVED, otherwise set it back to UNRESOLVED
+ if (failed) {
+@@ -666,6 +763,16 @@
+ return bundle.getState() != ResolverBundle.UNRESOLVED;
+ }
+
++ // AMC
++ private void addRequired(ResolverBundle toBundle, BundleDescription toBeAdded, ArrayList cycle) {
++ // TODO
++ BundleSpecification spec = new BundleSpecificationImpl(toBeAdded.getName());
++ BundleConstraint constraint = new BundleConstraint(toBundle,spec);
++ if (resolveRequire(constraint, cycle)) {
++ toBundle.addRequired(constraint);
++ }
++ }
++
+ private boolean resolveGenericReq(GenericConstraint constraint, ArrayList cycle) {
+ if (DEBUG_REQUIRES)
+ ResolverImpl.log("Trying to resolve: " + constraint.getBundle() + ", " + constraint.getVersionConstraint()); //$NON-NLS-1$ //$NON-NLS-2$
+@@ -1328,6 +1435,25 @@
+ VersionHashMap getResolverExports() {
+ return resolverExports;
+ }
++
++ //knibb
++ //test if two Strings are equal
++ //with wild card support - only supports strings ending in *
++ private boolean equals_wild(String input, String match){
++ if(input.equals(match)){
++ //its a match so just return true
++ return true;
++ }
++ if(input.endsWith("*")==false){
++ //no wildcards are being used here
++ return false;
++ }
++ String wild_in = input.substring(0, input.length()-1);
++ if(match.startsWith(wild_in))
++ return true;
++
++ return false;
++ }
+
+ public void setSelectionPolicy(Comparator selectionPolicy) {
+ this.selectionPolicy = selectionPolicy;
+Index: resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java,v
+retrieving revision 1.5
+diff -u -r1.5 VersionHashMap.java
+--- resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java 23 Jan 2006 19:13:00 -0000 1.5
++++ resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java 9 May 2006 21:27:16 -0000
+@@ -28,6 +28,14 @@
+ for (int i = 0; i < versionSuppliers.length; i++)
+ put(versionSuppliers[i].getName(), versionSuppliers[i]);
+ }
++
++ // AMC
++
++ Iterator iterator() {
++ return internal.values().iterator();
++ }
++
++ // END AMC
+
+ public void put(Object key, Object value) {
+ super.put(key, value);
+Index: .options
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/.options,v
+retrieving revision 1.14
+diff -u -r1.14 .options
+--- .options 1 May 2006 17:08:49 -0000 1.14
++++ .options 9 May 2006 21:27:12 -0000
+@@ -23,6 +23,9 @@
+ # Debug the loading of message bundles
+ org.eclipse.osgi/debug/messageBundles=false
+
++# Debug supplements mechanism
++org.eclipse.osgi/debug/supplements=false
++
+ # Eclipse adaptor options
+ org.eclipse.osgi/eclipseadaptor/debug = false
+ org.eclipse.osgi/eclipseadaptor/debug/location = false
+Index: core/framework/org/eclipse/osgi/framework/debug/Debug.java
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/debug/Debug.java,v
+retrieving revision 1.17
+diff -u -r1.17 Debug.java
+--- core/framework/org/eclipse/osgi/framework/debug/Debug.java 1 May 2006 15:37:20 -0000 1.17
++++ core/framework/org/eclipse/osgi/framework/debug/Debug.java 9 May 2006 21:27:12 -0000
+@@ -90,6 +90,12 @@
+ public static boolean MONITOR_ACTIVATION = false; // "monitor/bundles"
+
+ /**
++ * Show info about the supplements mechanism
++ */
++// public static boolean DEBUG_SUPPLEMENTS = Boolean.getBoolean("org.eclipse.osgi.showSupplementsInfo"); //$NON-NLS-1$ //$NON-NLS-2$
++ public static boolean DEBUG_SUPPLEMENTS = false; // "debug/supplements"
++
++ /**
+ * Base debug option key (org.eclispe.osgi).
+ */
+ public static final String ECLIPSE_OSGI = "org.eclipse.osgi"; //$NON-NLS-1$
+@@ -150,6 +156,10 @@
+ * Message bundles Debug option key.
+ */
+ public static final String OPTION_DEBUG_MESSAGE_BUNDLES = ECLIPSE_OSGI + "/debug/messageBundles"; //$NON-NLS-1$
++ /**
++ * Supplements mechansism Debug option key.
++ */
++ public static final String OPTION_DEBUG_SUPPLEMENTS = ECLIPSE_OSGI + "/debug/supplements"; //$NON-NLS-1$
+
+ static {
+ FrameworkDebugOptions dbgOptions = FrameworkDebugOptions.getDefault();
+@@ -168,6 +178,7 @@
+ DEBUG_PACKAGEADMIN = dbgOptions.getBooleanOption(OPTION_DEBUG_PACKAGEADMIN, false);
+ DEBUG_PACKAGEADMIN_TIMING = dbgOptions.getBooleanOption(OPTION_DEBUG_PACKAGEADMIN_TIMING, false) || dbgOptions.getBooleanOption("org.eclipse.core.runtime/debug", false); //$NON-NLS-1$
+ DEBUG_MESSAGE_BUNDLES = dbgOptions.getBooleanOption(OPTION_DEBUG_MESSAGE_BUNDLES, false);
++ DEBUG_SUPPLEMENTS = dbgOptions.getBooleanOption(OPTION_DEBUG_SUPPLEMENTS, false);
+ MONITOR_ACTIVATION = dbgOptions.getBooleanOption(OPTION_MONITOR_ACTIVATION, false);
+ }
+ }
+@@ -351,4 +362,4 @@
+ }
+ }
+
+-}
++}
+\ No newline at end of file
+Index: defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathManager.java
+===================================================================
+RCS file: /home/eclipse/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathManager.java,v
+retrieving revision 1.6
+diff -u -r1.6 ClasspathManager.java
+--- defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathManager.java 1 May 2006 14:14:24 -0000 1.6
++++ defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathManager.java 9 May 2006 21:27:14 -0000
+@@ -68,6 +68,10 @@
+ * </p>
+ */
+ public void initialize() {
++// String bundleName = data.getSymbolicName();
++// if (bundleName.equals("org.eclipse.osgi.aspectj.tests")) {
++// System.out.println("? ClasspathManager.initialize() bundle=" + bundleName);
++// }
+ entries = buildClasspath(classpath, this, data, classloader.getDomain());
+ ClassLoadingHook[] hooks = data.getAdaptor().getHookRegistry().getClassLoadingHooks();
+ for (int i = 0; i < hooks.length; i++)
+@@ -530,4 +534,4 @@
+ return classloader;
+ }
+
+-}
++}
+\ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.weaving.hook/readme.txt b/bundles/org.eclipse.equinox.weaving.hook/readme.txt
new file mode 100644
index 000000000..a5fcf7b48
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/readme.txt
@@ -0,0 +1,15 @@
+This version works with Eclipse 3.2 Final only. Checkout projects org.aspectj.osgi,
+org.aspectj.osgi.service.weaving and org.eclipse.osgi_3.2.0. The OSGi bundle is
+needed to run the org.aspectj.osgi Framework Extension bundle fragment as a
+source project (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143696).
+
+To run the accompanying tests checkout all the projects in aspects/tests and
+open the WeavingTest.lauch configuration.
+
+To run the demos checkout the projects in aspects/demos.
+- HelloWorld: run HelloWorldTest in the demo.hello bundle as a JUnit Plug-in
+test with the config.ini in the org.aspectj.osgi project.
+- Tooltip: run "Tooltip Demo.launch" in demo.eclipse.tooltip as an
+Eclipse Application using the config.ini in the same project.
+- Tracing: run "Eclipse Tracing Demo.launch" in demo.eclipse.tooltip as an
+Eclipse Application using the config.ini in the same project. \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/ICachingService.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/ICachingService.java
new file mode 100644
index 000000000..df251b4be
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/ICachingService.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.service.weaving;
+
+import java.net.URL;
+
+import org.osgi.framework.Bundle;
+
+public interface ICachingService {
+
+ public ICachingService getInstance(ClassLoader classLoader, Bundle bundle, String key);
+
+ public byte[] findStoredClass(String namespace, URL sourceFileURL, String name);
+
+ public boolean storeClass(String namespace, URL sourceFileURL, Class clazz, byte[] classbytes);
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/IWeavingService.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/IWeavingService.java
new file mode 100644
index 000000000..72f568168
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/IWeavingService.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.service.weaving;
+
+import java.io.IOException;
+
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.State;
+import org.osgi.framework.Bundle;
+
+public interface IWeavingService {
+
+ public IWeavingService getInstance(ClassLoader loader, Bundle bundle,
+ State resolverState, BundleDescription bundleDesciption,
+ SupplementerRegistry supplementerRegistry);
+
+ public byte[] preProcess(String name, byte[] classbytes, ClassLoader loader)
+ throws IOException;
+
+ public String getKey();
+
+ public boolean generatedClassesExistFor(ClassLoader loader, String className);
+
+ public void flushGeneratedClasses(ClassLoader loader);
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/SupplementerRegistry.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/SupplementerRegistry.java
new file mode 100644
index 000000000..d0fdea180
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/service/weaving/SupplementerRegistry.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Martin Lippert 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.service.weaving;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.equinox.weaving.hooks.AbstractAspectJHook;
+import org.eclipse.equinox.weaving.hooks.Supplementer;
+import org.eclipse.osgi.util.ManifestElement;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+public class SupplementerRegistry {
+
+ /**
+ * Manifest header (named &quot;Supplement-Importer&quot;) identifying the names
+ * (and optionally, version numbers) of the packages that the bundle supplements.
+ * All importers of one of these packages will have the exported packages of this
+ * bundle added to their imports in addition.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String SUPPLEMENT_IMPORTER = "Eclipse-SupplementImporter"; //$NON-NLS-1$
+
+ /**
+ * Manifest header (named &quot;Supplement-Exporter&quot;) identifying the names
+ * (and optionally, version numbers) of the packages that the bundle supplements.
+ * All exporters of one of these packages will have the exported packages of this bundle
+ * added to their imports list.
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String SUPPLEMENT_EXPORTER = "Eclipse-SupplementExporter"; //$NON-NLS-1$
+
+ //knibb
+ /**
+ * Manifest header (named &quot;Supplement-Bundle&quot;) identifying the names
+ * (and optionally, version numbers) of any bundles supplemented by this bundle.
+ * All supplemented bundles will have all the exported packages of this bundle
+ * added to their imports list
+ *
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String SUPPLEMENT_BUNDLE = "Eclipse-SupplementBundle"; //$NON-NLS-1$
+
+ private final Map supplementers; // keys of type String (symbolic name of supplementer bundle), values of type Supplementer
+ private BundleContext context;
+ private PackageAdmin packageAdmin;
+
+ public SupplementerRegistry() {
+ this.supplementers = new HashMap();
+ }
+
+ public void setBundleContext(BundleContext context) {
+ this.context = context;
+ }
+
+ public void setPackageAdmin(PackageAdmin packageAdmin) {
+ this.packageAdmin = packageAdmin;
+ }
+
+ public void addSupplementer(Bundle bundle) {
+ Dictionary manifest = bundle.getHeaders();
+ try {
+ // First analyze which supplementers already exists for this bundle
+ ManifestElement[] imports = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, (String) manifest.get(Constants.IMPORT_PACKAGE));
+ ManifestElement[] exports = ManifestElement.parseHeader(Constants.EXPORT_PACKAGE, (String) manifest.get(Constants.EXPORT_PACKAGE));
+ List supplementers = getSupplementers(bundle.getSymbolicName(), imports, exports);
+ if (supplementers.size() > 0) {
+ this.addSupplementedBundle(bundle, supplementers);
+ }
+
+ // Second analyze if this bundle itself is a supplementer
+ ManifestElement[] supplementBundle = ManifestElement.parseHeader(SUPPLEMENT_BUNDLE, (String) manifest.get(SUPPLEMENT_BUNDLE));
+ ManifestElement[] supplementImporter = ManifestElement.parseHeader(SUPPLEMENT_IMPORTER, (String) manifest.get(SUPPLEMENT_IMPORTER));
+ ManifestElement[] supplementExporter = ManifestElement.parseHeader(SUPPLEMENT_EXPORTER, (String) manifest.get(SUPPLEMENT_EXPORTER));
+
+ if (supplementBundle != null || supplementImporter != null || supplementExporter != null) {
+ Supplementer newSupplementer = new Supplementer(bundle, supplementBundle, supplementImporter, supplementExporter);
+
+ this.supplementers.put(bundle.getSymbolicName(), newSupplementer);
+ resupplementInstalledBundles(newSupplementer);
+ }
+ }
+ catch (BundleException e) {
+ }
+ }
+
+ public void removeSupplementer(Bundle bundle) {
+ // if this bundle is itself supplemented by others, remove the bundle from those lists
+ removeSupplementedBundle(bundle);
+
+ // if this bundle supplements other bundles, remove this supplementer and update the other bundles
+ if (supplementers.containsKey(bundle.getSymbolicName())) {
+ Supplementer supplementer = (Supplementer) supplementers.get(bundle.getSymbolicName());
+ supplementers.remove(bundle.getSymbolicName());
+ if (AbstractAspectJHook.verbose) System.err.println("[org.aspectj.osgi] info removing supplementer " + bundle.getSymbolicName());
+
+ Bundle[] supplementedBundles = supplementer.getSupplementedBundles();
+ for (int i = 0; i < supplementedBundles.length; i++) {
+ Bundle supplementedBundle = supplementedBundles[i];
+ if (supplementedBundle != null) {
+ updateInstalledBundle(supplementedBundle);
+ }
+ }
+ }
+ }
+
+ public List getSupplementers (String symbolicName, ManifestElement[] imports, ManifestElement[] exports) {
+ List result = Collections.EMPTY_LIST;
+
+ if (supplementers.size() > 0) {
+ result = new LinkedList();
+ for (Iterator i = supplementers.values().iterator(); i.hasNext();) {
+ Supplementer supplementer = (Supplementer) i.next();
+ if (isSupplementerMatching(symbolicName, imports, exports, supplementer)) {
+ result.add(supplementer.getSymbolicName());
+ }
+ }
+ }
+
+ return result;
+ }
+
+ public Bundle[] getSupplementers(Bundle bundle) {
+ List result = Collections.EMPTY_LIST;
+
+ if (supplementers.size() > 0) {
+ result = new ArrayList();
+ for (Iterator i = supplementers.values().iterator(); i.hasNext();) {
+ Supplementer supplementer = (Supplementer) i.next();
+ if (supplementer.isSupplemented(bundle)) {
+ result.add(supplementer.getSupplementerBundle());
+ }
+ }
+ }
+
+ return (Bundle[]) result.toArray(new Bundle[result.size()]);
+ }
+
+ public void addSupplementedBundle(Bundle supplementedBundle, List supplementers) {
+ for (Iterator iterator = supplementers.iterator(); iterator.hasNext();) {
+ String supplementersName = (String) iterator.next();
+ if (this.supplementers.containsKey(supplementersName)) {
+ Supplementer supplementer = (Supplementer) this.supplementers.get(supplementersName);
+ supplementer.addSupplementedBundle(supplementedBundle);
+ }
+ }
+ }
+
+ public void removeSupplementedBundle(Bundle bundle) {
+ for (Iterator iterator = this.supplementers.values().iterator(); iterator.hasNext();) {
+ Supplementer supplementer = (Supplementer) iterator.next();
+ supplementer.removeSupplementedBundle(bundle);
+ }
+ }
+
+ private boolean isSupplementerMatching(String symbolicName,
+ ManifestElement[] imports, ManifestElement[] exports, Supplementer supplementer) {
+ String supplementerName = supplementer.getSymbolicName();
+ if (!supplementerName.equals(symbolicName)) {
+ if (supplementer.matchSupplementer(symbolicName)
+ || (imports != null && supplementer.matchesSupplementImporter(imports))
+ || (exports != null && supplementer.matchesSupplementExporter(exports))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void resupplementInstalledBundles(Supplementer supplementer) {
+ Bundle[] installedBundles = context.getBundles();
+
+ for (int i = 0; i < installedBundles.length; i++) {
+ try {
+ Bundle bundle = installedBundles[i];
+
+ if (bundle.getSymbolicName().equals(supplementer.getSymbolicName())) {
+ continue;
+ }
+
+ Dictionary manifest = bundle.getHeaders();
+ ManifestElement[] imports = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, (String) manifest.get(Constants.IMPORT_PACKAGE));
+ ManifestElement[] exports = ManifestElement.parseHeader(Constants.EXPORT_PACKAGE, (String) manifest.get(Constants.EXPORT_PACKAGE));
+
+ if (isSupplementerMatching(bundle.getSymbolicName(), imports, exports, supplementer)) {
+ boolean alreadyRequired = false;
+ ManifestElement[] requires = ManifestElement.parseHeader(Constants.REQUIRE_BUNDLE, (String) manifest.get(Constants.REQUIRE_BUNDLE));
+ if (requires != null) {
+ for (int j = 0; j < requires.length; j++) {
+ if (requires[j].getValue().equals(supplementer.getSymbolicName())) {
+ alreadyRequired = true;
+ }
+ }
+ }
+
+ if (!alreadyRequired) {
+ updateInstalledBundle(bundle);
+ }
+ }
+
+ } catch (BundleException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void updateInstalledBundle(Bundle bundle) {
+
+ String symbolicName = bundle.getSymbolicName();
+
+ if (symbolicName.equals("org.eclipse.osgi")) return;
+ if (symbolicName.equals("org.aspectj.osgi")) return;
+ if (symbolicName.startsWith("org.eclipse.update")) return;
+ if (symbolicName.startsWith("org.eclipse.core.runtime")) return;
+ if (symbolicName.startsWith("org.aspectj.osgi.service")) return;
+ if (symbolicName.startsWith("org.eclipse.equinox")) return;
+
+ if (AbstractAspectJHook.verbose) System.err.println("[org.aspectj.osgi] info triggering update for re-supplementing " + symbolicName);
+
+ try {
+ 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 (BundleException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/AspectJAdaptor.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/AspectJAdaptor.java
new file mode 100644
index 000000000..fefc30956
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/AspectJAdaptor.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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 minor changes and bugfixes
+ *******************************************************************************/
+package org.eclipse.equinox.weaving.adaptors;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.equinox.service.weaving.ICachingService;
+import org.eclipse.equinox.service.weaving.IWeavingService;
+import org.eclipse.equinox.weaving.hooks.AspectJBundleFile;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
+import org.eclipse.osgi.framework.internal.core.BundleFragment;
+import org.eclipse.osgi.framework.internal.core.BundleHost;
+import org.osgi.framework.Bundle;
+
+public class AspectJAdaptor implements IAspectJAdaptor {
+
+ private boolean initialized = false;
+ private BaseData data;
+ private AspectJAdaptorFactory factory;
+ private BaseClassLoader baseLoader;
+ private Bundle bundle;
+ private String symbolicName;
+ private IWeavingService weavingService;
+ private ICachingService cachingService;
+
+ private static ThreadLocalSet identifyRecursionSet = new ThreadLocalSet();
+
+ private static class ThreadLocalSet extends ThreadLocal {
+
+ public void put(Object obj) {
+ Set set = (Set) get();
+ if (set.contains(obj)) {
+ throw new RuntimeException(obj.toString());
+ }
+ set.add(obj);
+ }
+
+ public void remove(Object obj) {
+ Set set = (Set) get();
+ if (!set.contains(obj)) {
+ throw new RuntimeException(obj.toString());
+ }
+ set.remove(obj);
+ }
+
+ public boolean contains(Object obj) {
+ Set set = (Set) get();
+ return set.contains(obj);
+ }
+
+ protected Object initialValue() {
+ return new HashSet();
+ }
+ }
+
+ public AspectJAdaptor (BaseData baseData, AspectJAdaptorFactory serviceFactory, BaseClassLoader baseClassLoader, IWeavingService weavingService, ICachingService cachingService) {
+ this.data = baseData;
+ this.factory = serviceFactory;
+ this.symbolicName = baseData.getLocation();
+ if (Debug.DEBUG_GENERAL) Debug.println("- AspectJAdaptor.AspectJAdaptor() bundle=" + symbolicName);
+ }
+
+ private void initialize () {
+ synchronized(this) {
+ if (initialized) return;
+
+ this.bundle = data.getBundle();
+ this.symbolicName = data.getSymbolicName();
+ if (!identifyRecursionSet.contains(this)) {
+ identifyRecursionSet.put(this);
+
+ if (Debug.DEBUG_GENERAL) Debug.println("> AspectJAdaptor.initialize() bundle=" + symbolicName + ", baseLoader=" + baseLoader);
+
+ if (symbolicName.startsWith("org.aspectj")) {
+ if (Debug.DEBUG_GENERAL) Debug.println("- AspectJAdaptor.initialize() symbolicName=" + symbolicName + ", baseLoader=" + baseLoader);
+ }
+ else if (baseLoader != null) {
+ weavingService = factory.getWeavingService(baseLoader);
+ cachingService = factory.getCachingService(baseLoader,bundle,weavingService);
+ }
+ else if (bundle instanceof BundleFragment) {
+ BundleFragment fragment = (BundleFragment)bundle;
+ BundleHost host = (BundleHost)factory.getHost(fragment);
+ if (Debug.DEBUG_GENERAL) Debug.println("- AspectJAdaptor.initialize() symbolicName=" + symbolicName + ", host=" + host);
+
+ BaseData hostData = (BaseData)host.getBundleData();
+ // System.err.println("? AspectJAdaptor.initialize() bundleData=" + hostData);
+ BundleFile bundleFile = hostData.getBundleFile();
+ if (bundleFile instanceof AspectJBundleFile) {
+ AspectJBundleFile hostFile = (AspectJBundleFile)bundleFile;
+ // System.err.println("? AspectJAdaptor.initialize() bundleFile=" + hostFile);
+ AspectJAdaptor hostAdaptor = (AspectJAdaptor)hostFile.getAdaptor();
+ // System.err.println("? AspectJAdaptor.initialize() bundleFile=" + hostAdaptor);
+ weavingService = hostAdaptor.weavingService;
+ cachingService = factory.getCachingService(hostAdaptor.baseLoader,bundle,weavingService);
+ }
+ }
+ else {
+ if (Debug.DEBUG_GENERAL) Debug.println("W AspectJAdaptor.initialize() symbolicName=" + symbolicName + ", baseLoader=" + baseLoader);
+ }
+ initialized = true;
+ identifyRecursionSet.remove(this);
+ }
+
+ if (Debug.DEBUG_GENERAL) Debug.println("< AspectJAdaptor.initialize() weavingService=" + (weavingService != null) + ", cachingService=" + (cachingService != null));
+ }
+ }
+
+ public void setBaseClassLoader (BaseClassLoader baseClassLoader) {
+ this.baseLoader = baseClassLoader;
+
+ if (Debug.DEBUG_GENERAL) Debug.println("- AspectJAdaptor.setBaseClassLoader() bundle=" + symbolicName + ", baseLoader=" + baseLoader);
+ }
+
+ public byte[] findClass (String name, URL sourceFileURL) {
+ if (Debug.DEBUG_CACHE) Debug.println("> AspectJAdaptor.findClass() bundle=" + symbolicName + ", url=" + sourceFileURL + ", name=" + name);
+ byte[] bytes = null;
+
+ initialize();
+ if (cachingService != null) {
+ bytes = cachingService.findStoredClass("",sourceFileURL,name);
+ }
+
+ if (Debug.DEBUG_CACHE) Debug.println("< AspectJAdaptor.findClass() bytes=" + bytes);
+ return bytes;
+ }
+
+ public byte[] weaveClass (String name, byte[] bytes) {
+ if (Debug.DEBUG_WEAVE) Debug.println("> AspectJAdaptor.weaveClass() bundle=" + symbolicName + ", name=" + name + ", bytes=" + bytes.length);
+ byte[] newBytes = null;
+
+ initialize();
+ if (/*shouldWeave(bytes) && */ weavingService != null){
+ try {
+ newBytes = weavingService.preProcess(name,bytes,(ClassLoader)baseLoader);
+ }
+ catch (IOException ex) {
+ throw new ClassFormatError(ex.toString());
+ }
+ }
+
+ if (Debug.DEBUG_WEAVE) Debug.println("< AspectJAdaptor.weaveClass() newBytes=" + newBytes);
+ return newBytes;
+ }
+
+ public boolean storeClass (String name, URL sourceFileURL, Class clazz, byte[] classbytes) {
+ if (Debug.DEBUG_CACHE) Debug.println("> AspectJAdaptor.storeClass() bundle=" + symbolicName + ", url=" + sourceFileURL + ", name=" + name + ", clazz=" + clazz);
+ boolean stored = false;
+
+ initialize();
+ if (cachingService != null) {
+ //have we generated a closure?
+ //If so we cannot store in shared cache (as closure will be lost for future runs)
+ if (weavingService != null && weavingService.generatedClassesExistFor((ClassLoader)baseLoader,name)) {
+ weavingService.flushGeneratedClasses((ClassLoader)baseLoader);
+ if (Debug.DEBUG_CACHE) Debug.println("- AspectJAdaptor.storeClass() generatedClassesExistFor=true");
+// return clazz;
+ }
+ else{
+ stored = cachingService.storeClass("",sourceFileURL,clazz,classbytes);
+ if(!stored){
+ if (Debug.DEBUG_CACHE) Debug.println("E AspectJHook.storeClass() bundle=" + symbolicName + ", name=" + name);
+ }
+ }
+ }
+ if (Debug.DEBUG_CACHE) Debug.println("< AspectJAdaptor.storeClass() stored=" + stored);
+ return stored;
+ }
+
+ public String toString () {
+ return "AspectJAdaptor[" + symbolicName + "]";
+ }
+
+} \ No newline at end of file
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
new file mode 100644
index 000000000..a9535a916
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/AspectJAdaptorFactory.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.equinox.weaving.adaptors;
+
+import org.eclipse.equinox.service.weaving.ICachingService;
+import org.eclipse.equinox.service.weaving.IWeavingService;
+import org.eclipse.equinox.service.weaving.SupplementerRegistry;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.State;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+public class AspectJAdaptorFactory {
+
+ private BundleContext bundleContext;
+ private IWeavingService singletonWeavingService;
+ private ICachingService singletonCachingService;
+ private PackageAdmin packageAdminService;
+ private SupplementerRegistry supplementerRegistry;
+
+ public AspectJAdaptorFactory () {
+ }
+
+ public void initialize (BundleContext context, SupplementerRegistry supplementerRegistry) {
+ if (Debug.DEBUG_GENERAL) Debug.println("> AspectJAdaptorFactory.initialize() context=" + context);
+ this.bundleContext = context;
+ this.supplementerRegistry = supplementerRegistry;
+
+ String weavingFilter = "(objectclass="+IWeavingService.class.getName()+")";
+ String cachingFilter = "(objectclass="+ICachingService.class.getName()+")";
+ /*
+ * Add listeners to listen for the
+ * registration of the weaving and caching services
+ */
+ ServiceListener weavingListener = new ServiceListener() {
+
+ public void serviceChanged(ServiceEvent event) {
+ if(event.getType() == ServiceEvent.REGISTERED) {
+// System.err.println("ServiceListener.serviceChanged() event=" + event);
+ initializeWeavingService();
+ }
+ }
+
+ };
+
+ ServiceListener cachingListener = new ServiceListener(){
+
+ public void serviceChanged(ServiceEvent event) {
+ if(event.getType() == ServiceEvent.REGISTERED) {
+// System.err.println("ServiceListener.serviceChanged() event=" + event);
+ initializeCachingService();
+ }
+ }
+
+ };
+
+ try {
+ bundleContext.addServiceListener(weavingListener,weavingFilter);
+ bundleContext.addServiceListener(cachingListener,cachingFilter);
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ initializePackageAdminService(context);
+
+ if (Debug.DEBUG_GENERAL) Debug.println("< AspectJAdaptorFactory.initialize() weavingListener=" + weavingListener + ", cachingListener=" + cachingListener);
+ }
+
+ protected void initializeWeavingService () {
+ if (Debug.DEBUG_GENERAL) Debug.println("> AspectJAdaptorFactory.initializeWeavingService()");
+ ServiceReference ref = bundleContext.getServiceReference(IWeavingService.class.getName());
+ if (ref!=null){
+ singletonWeavingService = (IWeavingService)bundleContext.getService(ref);
+ }
+ if (Debug.DEBUG_GENERAL) Debug.println("< AspectJAdaptorFactory.initializeWeavingService() weavingService=" + singletonWeavingService);
+ }
+
+ protected IWeavingService getWeavingService (BaseClassLoader loader) {
+ if (Debug.DEBUG_WEAVE) Debug.println("> AspectJAdaptorFactory.getWeavingService() baseClassLoader=" + loader);
+ IWeavingService weavingService = null;
+
+ if (singletonWeavingService != null) {
+ BaseData baseData = loader.getClasspathManager().getBaseData();
+ State state = baseData.getAdaptor().getState();
+ Bundle bundle = baseData.getBundle();
+ BundleDescription bundleDescription = state.getBundle(bundle.getBundleId());
+ weavingService = singletonWeavingService.getInstance((ClassLoader)loader, bundle, state, bundleDescription, supplementerRegistry);
+ }
+ if (Debug.DEBUG_WEAVE) Debug.println("< AspectJAdaptorFactory.getWeavingService() service=" + weavingService);
+ return weavingService;
+ }
+
+ protected void initializeCachingService () {
+ if (Debug.DEBUG_CACHE) Debug.println("> AspectJAdaptorFactory.initializeCachingService()");
+ ServiceReference ref = bundleContext.getServiceReference(ICachingService.class.getName());
+ if (ref != null){
+ singletonCachingService = (ICachingService)bundleContext.getService(ref);
+ }
+ if (Debug.DEBUG_CACHE) Debug.println("< AspectJAdaptorFactory.initializeCachingService() singletonCachingService=" + singletonCachingService);
+ }
+
+ protected ICachingService getCachingService (BaseClassLoader loader, Bundle bundle, IWeavingService weavingService) {
+ if (Debug.DEBUG_CACHE) Debug.println("> AspectJAdaptorFactory.getCachingService() bundle=" + bundle + ", weavingService=" + weavingService);
+ ICachingService service = null;
+ String key = "";
+
+ if (weavingService != null) {
+ key = weavingService.getKey();
+ }
+ if (singletonCachingService != null) {
+ service = singletonCachingService.getInstance((ClassLoader)loader,bundle,key);
+ }
+ if (Debug.DEBUG_CACHE) Debug.println("< AspectJAdaptorFactory.getCachingService() service=" + service + ", key='" + key + "'");
+ return service;
+ }
+
+ private void initializePackageAdminService (BundleContext context) {
+ if (Debug.DEBUG_GENERAL) Debug.println("> AspectJAdaptorFactory.initializePackageAdminService() context=" + context);
+
+ ServiceReference ref = context.getServiceReference(PackageAdmin.class.getName());
+ if (ref != null) {
+ packageAdminService = (PackageAdmin)context.getService(ref);
+ }
+
+ if (Debug.DEBUG_GENERAL) Debug.println("< AspectJAdaptorFactory.initializePackageAdminService() " + packageAdminService);
+ }
+
+ public Bundle getHost (Bundle fragment) {
+ if (Debug.DEBUG_GENERAL) Debug.println("> AspectJAdaptorFactory.getHost() fragment=" + fragment);
+
+ Bundle host = null;
+ if (packageAdminService != null) host = packageAdminService.getHosts(fragment)[0];
+
+ if (Debug.DEBUG_GENERAL) Debug.println("< AspectJAdaptorFactory.getHost() " + host);
+ return host;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/Debug.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/Debug.java
new file mode 100644
index 000000000..d045a5c9f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/Debug.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.adaptors;
+
+import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
+
+public class Debug {
+
+ public static boolean DEBUG_GENERAL;
+ public static boolean DEBUG_BUNDLE;
+ public static boolean DEBUG_WEAVE;
+ public static boolean DEBUG_CACHE;
+ public static boolean DEBUG_SUPPLEMENTS;
+
+ private static String bundleName;
+
+ public static boolean bundleNameMatches (String name) {
+ return name.equals(bundleName);
+ }
+
+ public static final String ASPECTJ_OSGI = "org.aspectj.osgi";
+ public static final String OPTION_DEBUG_GENERAL = ASPECTJ_OSGI + "/debug";
+ public static final String OPTION_DEBUG_BUNDLE = ASPECTJ_OSGI + "/debug/bundle";
+ public static final String OPTION_DEBUG_WEAVE = ASPECTJ_OSGI + "/debug/weave";
+ public static final String OPTION_DEBUG_CACHE = ASPECTJ_OSGI + "/debug/cache";
+ public static final String OPTION_DEBUG_BUNDLENAME = ASPECTJ_OSGI + "/debug/bundleName";
+ public static final String OPTION_DEBUG_SUPPLEMENTS = ASPECTJ_OSGI + "/debug/supplements";
+
+ static {
+ FrameworkDebugOptions fdo = FrameworkDebugOptions.getDefault();
+ if (fdo != null) {
+ DEBUG_GENERAL = fdo.getBooleanOption(OPTION_DEBUG_GENERAL,false);
+ DEBUG_BUNDLE = fdo.getBooleanOption(OPTION_DEBUG_BUNDLE,false);
+ DEBUG_WEAVE = fdo.getBooleanOption(OPTION_DEBUG_WEAVE,false);
+ DEBUG_CACHE = fdo.getBooleanOption(OPTION_DEBUG_CACHE,false);
+ bundleName = fdo.getOption(OPTION_DEBUG_BUNDLENAME,"");
+ DEBUG_SUPPLEMENTS = fdo.getBooleanOption(OPTION_DEBUG_SUPPLEMENTS,false);
+ }
+ }
+
+ public static void println (String s) {
+ /*if (s.indexOf("org.eclipse.osgi.tests") != -1)*/ System.err.println(s);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/IAspectJAdaptor.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/IAspectJAdaptor.java
new file mode 100644
index 000000000..c6acb5af2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/adaptors/IAspectJAdaptor.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.equinox.weaving.adaptors;
+
+import java.net.URL;
+
+import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
+
+public interface IAspectJAdaptor {
+
+ public void setBaseClassLoader (BaseClassLoader baseClassLoader);
+
+ public byte[] findClass (String name, URL sourceFileURL);
+
+ public byte[] weaveClass (String name, byte[] bytes);
+
+ public boolean storeClass (String name, URL sourceFileURL, Class clazz, byte[] classbytes);
+
+}
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
new file mode 100644
index 000000000..b2d0fe4c2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAJBundleFile.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.hooks;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.eclipse.equinox.weaving.adaptors.IAspectJAdaptor;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+
+public abstract class AbstractAJBundleFile extends BundleFile {
+
+ protected IAspectJAdaptor adaptor;
+ protected BundleFile delegate;
+
+ public AbstractAJBundleFile (IAspectJAdaptor aspectjAdaptor, BundleFile bundleFile) {
+ super(bundleFile.getBaseFile());
+ this.adaptor = aspectjAdaptor;
+ this.delegate = bundleFile;
+ }
+
+ public File getBaseFile() {
+ File baseFile = delegate.getBaseFile();
+ return baseFile;
+ }
+
+ /**
+ * @deprecated
+ */
+ public URL getResourceURL(String path, long hostBundleID, int index) {
+ return delegate.getResourceURL(path, hostBundleID, index);
+ }
+
+ /**
+ * @deprecated
+ */
+ public URL getResourceURL(String path, long hostBundleID) {
+ return delegate.getResourceURL(path, hostBundleID);
+ }
+
+ public void close() throws IOException {
+ delegate.close();
+ }
+
+ public boolean containsDir(String dir) {
+ return delegate.containsDir(dir);
+ }
+
+ public BundleEntry getEntry(String path) {
+ return delegate.getEntry(path);
+ }
+
+ public Enumeration getEntryPaths(String path) {
+ return delegate.getEntryPaths(path);
+ }
+
+ public File getFile(String path, boolean nativeCode) {
+ return delegate.getFile(path, nativeCode);
+ }
+
+ public void open() throws IOException {
+ delegate.open();
+ }
+
+ public IAspectJAdaptor getAdaptor() {
+ return adaptor;
+ }
+
+}
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
new file mode 100644
index 000000000..89f1465ef
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AbstractAspectJHook.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * 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.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Properties;
+
+import org.eclipse.equinox.service.weaving.SupplementerRegistry;
+import org.eclipse.osgi.baseadaptor.BaseAdaptor;
+import org.eclipse.osgi.baseadaptor.BaseData;
+import org.eclipse.osgi.baseadaptor.HookConfigurator;
+import org.eclipse.osgi.baseadaptor.HookRegistry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook;
+import org.eclipse.osgi.baseadaptor.hooks.BundleFileWrapperFactoryHook;
+import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook;
+import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingStatsHook;
+import org.eclipse.osgi.baseadaptor.loader.BaseClassLoader;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry;
+import org.eclipse.osgi.baseadaptor.loader.ClasspathManager;
+import org.eclipse.osgi.framework.adaptor.BundleProtectionDomain;
+import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
+import org.eclipse.osgi.framework.log.FrameworkLog;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+public abstract class AbstractAspectJHook implements HookConfigurator, AdaptorHook, BundleFileWrapperFactoryHook , ClassLoadingHook, ClassLoadingStatsHook {
+
+ public static boolean verbose = Boolean.getBoolean("org.aspectj.osgi.verbose");
+
+ private SupplementerRegistry supplementerRegistry;
+
+ public void addHooks (HookRegistry hooks) {
+ if (verbose) System.err.println("[org.aspectj.osgi] info adding AspectJ hooks ...");
+
+ supplementerRegistry = new SupplementerRegistry();
+
+ hooks.addAdaptorHook(this);
+ hooks.addClassLoadingHook(this);
+ hooks.addBundleFileWrapperFactoryHook(this);
+ hooks.addClassLoadingStatsHook(this);
+ hooks.addStorageHook(new AspectJStorageHook(supplementerRegistry));
+ }
+
+ public SupplementerRegistry getSupplementerRegistry() {
+ return this.supplementerRegistry;
+ }
+
+ public BundleFile wrapBundleFile(BundleFile bundleFile, Object content, BaseData data, boolean base) throws IOException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean addClassPathEntry(ArrayList cpEntries, String cp, ClasspathManager hostmanager, BaseData sourcedata, ProtectionDomain sourcedomain) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public BaseClassLoader createClassLoader(ClassLoader parent, ClassLoaderDelegate delegate, BundleProtectionDomain domain, BaseData data, String[] bundleclasspath) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String findLibrary(BaseData data, String libName) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public ClassLoader getBundleClassLoaderParent() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void initializedClassLoader(BaseClassLoader baseClassLoader, BaseData data) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public byte[] processClass(String name, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void addProperties(Properties properties) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public FrameworkLog createFrameworkLog() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void frameworkStart(BundleContext context) throws BundleException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void frameworkStop(BundleContext context) throws BundleException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void frameworkStopping(BundleContext context) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void handleRuntimeError(Throwable error) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void initialize(BaseAdaptor adaptor) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public URLConnection mapLocationToURLConnection(String location) throws IOException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean matchDNChain(String pattern, String[] dnChain) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void postFindLocalClass(String name, Class clazz, ClasspathManager manager) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void postFindLocalResource(String name, URL resource, ClasspathManager manager) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void preFindLocalClass(String name, ClasspathManager manager) throws ClassNotFoundException {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void preFindLocalResource(String name, ClasspathManager manager) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void recordClassDefine(String name, Class clazz, byte[] classbytes, ClasspathEntry classpathEntry, BundleEntry entry, ClasspathManager manager) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJBundleEntry.java b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJBundleEntry.java
new file mode 100644
index 000000000..96320eee9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJBundleEntry.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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 minor changes and bugfixes
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.hooks;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.eclipse.equinox.weaving.adaptors.IAspectJAdaptor;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+
+public class AspectJBundleEntry extends BundleEntry {
+
+ private IAspectJAdaptor adaptor;
+ private String name;
+ private byte[] bytes;
+ private URL bundleFileURL;
+ private BundleEntry delegate;
+
+ public AspectJBundleEntry (IAspectJAdaptor aspectjAdaptor, BundleEntry delegate, URL url) {
+ this.adaptor = aspectjAdaptor;
+ this.bundleFileURL = url;
+ this.delegate = delegate;
+ }
+
+ public AspectJBundleEntry (IAspectJAdaptor aspectjAdaptor, BundleEntry delegate, String name, byte[] bytes, URL url) {
+ this(aspectjAdaptor, delegate, url);
+ this.name = name;
+ this.bytes = bytes;
+ }
+
+ public URL getBundleFileURL () {
+ return bundleFileURL;
+ }
+
+ public IAspectJAdaptor getAdaptor() {
+ return adaptor;
+ }
+
+ public URL getFileURL() {
+ if (bytes == null) return delegate.getFileURL();
+ else return null;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ // this always returns the original stream of the delegate to
+ // allow getResourceAsStream to be used even in the context of
+ // caching with J9 class sharing
+ //
+ // class loading uses getBytes instead (where the caching is considered)
+ return delegate.getInputStream();
+ }
+
+ public byte[] getBytes() throws IOException {
+ if (bytes == null) return delegate.getBytes();
+ return bytes;
+ }
+
+ public URL getLocalURL() {
+ if (bytes == null) return delegate.getLocalURL();
+ else return null;
+ }
+
+ public String getName() {
+ if (bytes == null) return delegate.getName();
+ else return name;
+ }
+
+ public long getSize() {
+ if (delegate != null) return delegate.getSize();
+ else return bytes.length;
+ }
+
+ public long getTime() {
+ if (delegate != null) return delegate.getTime();
+ else return 0;
+ }
+
+ public boolean isCached() {
+ return bytes != null;
+ }
+
+}
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
new file mode 100644
index 000000000..78ca3a5a8
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJBundleFile.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.hooks;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.equinox.weaving.adaptors.Debug;
+import org.eclipse.equinox.weaving.adaptors.IAspectJAdaptor;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile;
+
+public class AspectJBundleFile extends AbstractAJBundleFile {
+
+ private URL url;
+
+ public AspectJBundleFile (IAspectJAdaptor aa, BundleFile bundleFile) throws IOException {
+ super(aa,bundleFile);
+ this.url = delegate.getBaseFile().toURL();
+ }
+
+ public URL getURL () {
+ return url;
+ }
+
+ public BundleEntry getEntry(String path) {
+ if (Debug.DEBUG_BUNDLE) Debug.println("> AspectJBundleFile.getEntry() path=" + path + ", url=" + url);
+ BundleEntry entry;
+ if (path.endsWith(".class")) {
+ int offset = path.lastIndexOf('.');
+ String name = path.substring(0,offset).replace('/','.');
+ byte[] bytes = adaptor.findClass(name,url);
+ if (bytes == null) {
+ entry = delegate.getEntry(path);
+ if (entry != null) {
+ entry = new AspectJBundleEntry(adaptor,entry, url);
+ if (Debug.DEBUG_BUNDLE) Debug.println("- AspectJBundleFile.getEntry() path=" + path + ", entry=" + entry);
+ }
+ }
+ else entry = new AspectJBundleEntry(adaptor,delegate.getEntry(path), path,bytes, url);
+ }
+ else {
+ entry = delegate.getEntry(path);
+ }
+
+ if (Debug.DEBUG_BUNDLE) Debug.println("< AspectJBundleFile.getEntry() entry=" + entry);
+ return entry;
+ }
+
+}
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
new file mode 100644
index 000000000..e6f65b3c5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJHook.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * 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 org.eclipse.equinox.weaving.adaptors.AspectJAdaptor;
+import org.eclipse.equinox.weaving.adaptors.AspectJAdaptorFactory;
+import org.eclipse.equinox.weaving.adaptors.Debug;
+import org.eclipse.equinox.weaving.adaptors.IAspectJAdaptor;
+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.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+public class AspectJHook extends AbstractAspectJHook {
+
+ private BundleContext bundleContext;
+ private AspectJAdaptorFactory adaptorFactory;
+
+ public AspectJHook () {
+ if (Debug.DEBUG_GENERAL) Debug.println("- AspectJHook.<init>()");
+ adaptorFactory = new AspectJAdaptorFactory();
+ }
+
+ private void initialize (BundleContext context) {
+ if (Debug.DEBUG_GENERAL) Debug.println("> AspectJHook.initialize() context=" + context);
+
+ this.bundleContext = context;
+ adaptorFactory.initialize(context, getSupplementerRegistry());
+
+ ServiceReference serviceReference = context.getServiceReference(PackageAdmin.class.getName());
+ PackageAdmin packageAdmin = (PackageAdmin) context.getService(serviceReference);
+
+ getSupplementerRegistry().setBundleContext(context);
+ getSupplementerRegistry().setPackageAdmin(packageAdmin);
+ context.addBundleListener(new SupplementBundleListener(getSupplementerRegistry()));
+
+ if (Debug.DEBUG_GENERAL) Debug.println("< AspectJHook.initialize() adaptorFactory=" + adaptorFactory);
+ }
+
+ public void frameworkStart(BundleContext context) throws BundleException {
+// Debug.println("? AspectJHook.frameworkStart() context=" + context + ", fdo=" + FrameworkDebugOptions.getDefault());
+ initialize(context);
+ }
+
+ public void recordClassDefine(String name, Class clazz, byte[] classbytes,
+ ClasspathEntry classpathEntry, BundleEntry entry,
+ ClasspathManager manager) {
+ if (entry instanceof AspectJBundleEntry) {
+ AspectJBundleEntry ajBundleEntry = (AspectJBundleEntry)entry;
+ IAspectJAdaptor adaptor = ajBundleEntry.getAdaptor();
+ URL sourceFileURL = ajBundleEntry.getBundleFileURL();
+ adaptor.storeClass(name,sourceFileURL,clazz,classbytes);
+ }
+ }
+
+ public void initializedClassLoader(BaseClassLoader baseClassLoader,
+ BaseData data) {
+ if (Debug.DEBUG_GENERAL) Debug.println("> AspectJHook.initializedClassLoader() bundle=" + data.getSymbolicName() + ", loader=" + baseClassLoader + ", data=" + data + ", bundleFile=" + data.getBundleFile());
+ IAspectJAdaptor adaptor = null;
+ BundleFile bundleFile = data.getBundleFile();
+ if (bundleFile instanceof BaseAjBundleFile) {
+ BaseAjBundleFile baseBundleFile = (BaseAjBundleFile)bundleFile;
+ adaptor = baseBundleFile.getAdaptor();
+ adaptor.setBaseClassLoader(baseClassLoader);
+ }
+
+ if (Debug.DEBUG_GENERAL) Debug.println("< AspectJHook.initializedClassLoader() adaptor=" + adaptor);
+ }
+
+ public byte[] processClass(String name, byte[] classbytes,
+ ClasspathEntry classpathEntry, BundleEntry entry,
+ ClasspathManager manager) {
+ byte[] newClassytes = null;
+ if (entry instanceof AspectJBundleEntry) {
+ AspectJBundleEntry ajBundleEntry = (AspectJBundleEntry)entry;
+ if (!ajBundleEntry.isCached()) {
+ IAspectJAdaptor adaptor = ajBundleEntry.getAdaptor();
+ newClassytes = adaptor.weaveClass(name,classbytes);
+ }
+ }
+ return newClassytes;
+ }
+
+ public BundleFile wrapBundleFile(BundleFile bundleFile, Object content,
+ BaseData data, 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());
+
+// IAspectJAdaptor adaptor = null;
+// if (base) {
+// adaptor = createAspectJAdaptor(data);
+// }
+// else if (bundleContext != null) {
+// adaptor = getAspectJAdaptor(data);
+// }
+//
+// if (adaptor != null) {
+// if (bundleFile instanceof DirBundleFile) {
+// wrapped = new BaseAjBundleFile(adaptor,bundleFile);
+// }
+// else {
+// wrapped = new AspectJBundleFile(adaptor,bundleFile);
+// }
+// }
+// if (Debug.DEBUG_BUNDLE) Debug.println("< AspectJBundleFileWrapperFactoryHook.wrapBundleFile() wrapped=" + wrapped + ", adaptor=" + adaptor);
+
+ if (base) {
+ IAspectJAdaptor adaptor = createAspectJAdaptor(data);
+ if (adaptor != null) {
+ wrapped = new BaseAjBundleFile(adaptor, 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);
+ }
+ }
+ if (Debug.DEBUG_BUNDLE) Debug.println("< AspectJBundleFileWrapperFactoryHook.wrapBundleFile() wrapped=" + wrapped);
+ return wrapped;
+ }
+
+ private IAspectJAdaptor createAspectJAdaptor (BaseData baseData) {
+ if (Debug.DEBUG_GENERAL) Debug.println("> AspectJHook.createAspectJAdaptor() location=" + baseData.getLocation());
+ IAspectJAdaptor adaptor = null;
+
+ if (adaptorFactory != null) {
+ adaptor = new AspectJAdaptor(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 IAspectJAdaptor getAspectJAdaptor (BaseData data) {
+ IAspectJAdaptor adaptor = null;
+
+ BundleFile bundleFile = data.getBundleFile();
+ if (bundleFile instanceof BaseAjBundleFile) {
+ BaseAjBundleFile baseBundleFile = (BaseAjBundleFile)bundleFile;
+ adaptor = baseBundleFile.getAdaptor();
+ }
+
+ return adaptor;
+ }
+
+}
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
new file mode 100644
index 000000000..3e59880f4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/AspectJStorageHook.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * 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.SupplementerRegistry;
+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 String KEY = AspectJStorageHook.class.getName();
+ public static final int HASHCODE = KEY.hashCode();
+
+ private BaseData bundleData;
+ private final SupplementerRegistry supplementerRegistry;
+
+
+ public AspectJStorageHook(SupplementerRegistry supplementerRegistry) {
+ if (Debug.DEBUG_SUPPLEMENTS) Debug.println("- AspectJStorageHook.AspectJStorageHook()");
+ this.supplementerRegistry = supplementerRegistry;
+ }
+
+ public AspectJStorageHook(BaseData bd, SupplementerRegistry supplementerRegistry) {
+ if (Debug.DEBUG_SUPPLEMENTS) Debug.println("- AspectJStorageHook.AspectJStorageHook() baseDate=" + bd);
+ this.bundleData = bd;
+ this.supplementerRegistry = supplementerRegistry;
+ }
+
+ private String getSymbolicName () {
+ return (bundleData == null)? "root" : bundleData.getSymbolicName();
+ }
+
+ public void copy(StorageHook storageHook) {
+ // TODO Auto-generated method stub
+ }
+
+ public StorageHook create(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(int startlevel) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean forgetStatusChange(int status) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public Dictionary getManifest(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(Dictionary manifest) throws BundleException {
+// System.err.println("? AspectJStorageHook.initialize() " + this + " manifest=" + manifest);
+ if (Debug.DEBUG_SUPPLEMENTS) Debug.println("> AspectJStorageHook.initialize() " + getSymbolicName());
+ try {
+ ManifestElement[] imports = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, (String) manifest.get(Constants.IMPORT_PACKAGE));
+ ManifestElement[] exports = ManifestElement.parseHeader(Constants.EXPORT_PACKAGE, (String) manifest.get(Constants.EXPORT_PACKAGE));
+ List supplementers = supplementerRegistry.getSupplementers(bundleData.getSymbolicName(), imports, exports);
+ if (!supplementers.isEmpty()) {
+ if (Debug.DEBUG_SUPPLEMENTS) Debug.println("- AspectJStorageHook.initialize() " + getSymbolicName() + " supplementers=" + supplementers);
+ if (!getSymbolicName().equals("org.eclipse.osgi")
+// && !getSymbolicName().startsWith("org.eclipse.core")
+// && !getSymbolicName().startsWith("org.eclipse.equinox")
+ && !getSymbolicName().startsWith("org.eclipse.team.ui")
+ && !getSymbolicName().startsWith("org.eclipse.update")
+ ) {
+ if (addRequiredBundles(supplementers)) {
+ if (AbstractAspectJHook.verbose) System.err.println("[org.aspectj.osgi] info supplementing " + getSymbolicName() + " with " + supplementers);
+ }
+ else {
+ if (AbstractAspectJHook.verbose) System.err.println("[org.aspectj.osgi] info not supplementing " + getSymbolicName());
+ }
+ }
+ else {
+ if (AbstractAspectJHook.verbose) System.err.println("[org.aspectj.osgi] info cannot supplement " + getSymbolicName());
+ }
+ }
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ if (Debug.DEBUG_SUPPLEMENTS) Debug.println("< AspectJStorageHook.initialize() ");
+ }
+
+ private boolean addRequiredBundles (List bundles) throws BundleException {
+ Dictionary manifest = bundleData.getManifest();
+ manifest = ((CachedManifest)manifest).getManifest();
+
+ if (manifest != null) {
+ String value = (String)manifest.get(Constants.REQUIRE_BUNDLE);
+ for (Iterator i = bundles.iterator(); i.hasNext();) {
+ 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 Object setHeader(Headers manifest, Object key, Object value, 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 (IllegalAccessException ex) {
+ throw new BundleException(key + "=" + value,ex);
+ }
+ }
+
+ private static Field readOnly;
+
+ static {
+ try {
+ readOnly = Headers.class.getDeclaredField("readOnly");
+ readOnly.setAccessible(true);
+ }
+ catch (Exception ex) {
+ if (Debug.DEBUG_SUPPLEMENTS) ex.printStackTrace();
+ }
+ }
+
+ public StorageHook load(BaseData bundledata, DataInputStream is) throws IOException {
+ if (Debug.DEBUG_SUPPLEMENTS) Debug.println("- AspectJStorageHook.load() " + getSymbolicName() + " bundleData=" + bundledata);
+ return new AspectJStorageHook(bundledata, supplementerRegistry);
+ }
+
+ public boolean matchDNChain(String pattern) {
+ // TODO Auto-generated method stub
+// System.err.println("? AspectJStorageHook.matchDNChain() " + getSymbolicName() + " pattern=" + pattern);
+ return false;
+ }
+
+ public void save(DataOutputStream os) throws IOException {
+ // TODO Auto-generated method stub
+ if (Debug.DEBUG_SUPPLEMENTS) Debug.println("- AspectJStorageHook.save() " + getSymbolicName());
+ }
+
+ public void validate() throws IllegalArgumentException {
+ // TODO Auto-generated method stub
+// System.err.println("? AspectJStorageHook.validate()");
+ }
+
+ public boolean compare(KeyedElement other) {
+ // TODO Auto-generated method stub
+ return other.getKey() == KEY;
+ }
+
+ public Object getKey() {
+ return KEY;
+ }
+
+ public int getKeyHashCode() {
+ return HASHCODE;
+ }
+
+ public String toString () {
+ return "AspectJStorageHook[" + getSymbolicName() + "]";
+ }
+
+}
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
new file mode 100644
index 000000000..df674d8aa
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/BaseAjBundleFile.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+
+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 (IAspectJAdaptor aspectjAdaptor, BundleFile bundleFile) throws IOException {
+ super(aspectjAdaptor,bundleFile);
+ }
+}
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
new file mode 100644
index 000000000..a5ed6a481
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/SupplementBundleListener.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Martin Lippert 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:
+ * Martin Lippert initial implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.hooks;
+
+import org.eclipse.equinox.service.weaving.SupplementerRegistry;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+
+public class SupplementBundleListener implements SynchronousBundleListener {
+
+ private final SupplementerRegistry supplementerRegistry;
+
+ public SupplementBundleListener(SupplementerRegistry supplementerRegistry) {
+ this.supplementerRegistry = supplementerRegistry;
+ }
+
+ public void bundleChanged(BundleEvent event) {
+ Bundle bundle = event.getBundle();
+ if (event.getType() == BundleEvent.INSTALLED) {
+ supplementerRegistry.addSupplementer(bundle);
+ }
+ else if (event.getType() == BundleEvent.UNINSTALLED) {
+ supplementerRegistry.removeSupplementer(bundle);
+ }
+ else if (event.getType() == BundleEvent.UPDATED) {
+ supplementerRegistry.removeSupplementer(bundle);
+ supplementerRegistry.addSupplementer(bundle);
+ }
+ }
+
+}
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
new file mode 100644
index 000000000..005d88b1a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.weaving.hook/src/org/eclipse/equinox/weaving/hooks/Supplementer.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Martin Lippert 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
+ * Martin Lippert supplementing mechanism reworked
+ *******************************************************************************/
+
+package org.eclipse.equinox.weaving.hooks;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.osgi.util.ManifestElement;
+import org.osgi.framework.Bundle;
+
+public class Supplementer {
+
+ private ManifestElement[] supplementBundle;
+ private ManifestElement[] supplementImporter;
+ private ManifestElement[] supplementExporter;
+ private Bundle supplementer;
+ private List supplementedBundles; // elements of type Bundle
+
+ public Supplementer(Bundle bundle,
+ ManifestElement[] supplementBundle,
+ ManifestElement[] supplementImporter,
+ ManifestElement[] supplementExporter) {
+ this.supplementer = bundle;
+ this.supplementBundle = supplementBundle;
+ this.supplementImporter = supplementImporter;
+ this.supplementExporter = supplementExporter;
+ this.supplementedBundles = new ArrayList();
+ }
+
+ public Bundle getSupplementerBundle() {
+ return supplementer;
+ }
+
+ public String getSymbolicName() {
+ return supplementer.getSymbolicName();
+ }
+
+ public void addSupplementedBundle(Bundle supplementedBundle) {
+ this.supplementedBundles.add(supplementedBundle);
+ }
+
+ public void removeSupplementedBundle(Bundle supplementedBundle) {
+ this.supplementedBundles.remove(supplementedBundle);
+ }
+
+ public Bundle[] getSupplementedBundles() {
+ return (Bundle[]) supplementedBundles.toArray(new Bundle[supplementedBundles.size()]);
+ }
+
+ public boolean isSupplemented(Bundle bundle) {
+ return supplementedBundles.contains(bundle);
+ }
+
+ public boolean matchSupplementer(String symbolicName) {
+ boolean matches = false;
+
+ if (supplementBundle != null) for (int i = 0; !matches && i < supplementBundle.length; i++) {
+ ManifestElement bundle = supplementBundle[i];
+ if (equals_wild(bundle.getValue(),symbolicName)) matches = true;
+ }
+
+ return matches;
+ }
+
+ public boolean matchesSupplementImporter(ManifestElement[] imports) {
+ boolean matches = false;
+
+ if (supplementImporter != null) for (int i = 0; !matches && i < supplementImporter.length; i++) {
+ ManifestElement supplementImport = supplementImporter[i];
+ for (int j = 0; !matches && j < imports.length; j++) {
+ ManifestElement importPackage = imports[j];
+ if (supplementImport.getValue().equals(importPackage.getValue())) matches = true;
+ }
+ }
+
+ return matches;
+ }
+
+ public boolean matchesSupplementExporter(ManifestElement[] exports) {
+ boolean matches = false;
+
+ if (supplementExporter != null) for (int i = 0; !matches && i < supplementExporter.length; i++) {
+ ManifestElement supplementExport = supplementExporter[i];
+ for (int j = 0; !matches && j < exports.length; j++) {
+ ManifestElement exportPackage = exports[j];
+ if (supplementExport.getValue().equals(exportPackage.getValue())) matches = true;
+ }
+ }
+
+ return matches;
+ }
+
+ //knibb
+ //test if two Strings are equal
+ //with wild card support - only supports strings ending in *
+ private boolean equals_wild(String input, String match){
+ if(input.equals(match)){
+ //its a match so just return true
+ return true;
+ }
+ if(input.endsWith("*")==false){
+ //no wildcards are being used here
+ return false;
+ }
+ String wild_in = input.substring(0, input.length()-1);
+ if(match.startsWith(wild_in))
+ return true;
+
+ return false;
+ }
+
+}

Back to the top