Bug 462968 - [otdre] callback needed to determine superclass weavability
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java
index 27ba96a..f5c4a08 100644
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java
@@ -1,7 +1,7 @@
 /**********************************************************************
  * This file is part of "Object Teams Development Tooling"-Software
  * 
- * Copyright 2013, 2014 GK Software AG
+ * Copyright 2013, 2015 GK Software AG
  *  
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -97,7 +97,7 @@
 				}
 				// (2) scan all teams in affecting aspect bindings:
 				if (!aspectBinding.hasScannedTeams)
-					aspectBinding.scanTeamClasses(aspectBundle, DelegatingTransformer.newTransformer(useDynamicWeaver));
+					aspectBinding.scanTeamClasses(aspectBundle, DelegatingTransformer.newTransformer(useDynamicWeaver, hook, baseClass.getBundleWiring()));
 					// TODO: record adapted base classes?
 				
 				// (3) add dependencies to the base bundle:
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java
index b0c11d2..dde7653 100644
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java
@@ -1,7 +1,7 @@
 /**********************************************************************
  * This file is part of "Object Teams Development Tooling"-Software
  * 
- * Copyright 2014 GK Software AG
+ * Copyright 2015 GK Software AG
  *  
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -21,13 +21,18 @@
 import java.lang.instrument.IllegalClassFormatException;
 import java.lang.instrument.UnmodifiableClassException;
 import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
 import java.security.ProtectionDomain;
 import java.util.Collection;
+import java.util.List;
 
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.objectteams.internal.osgi.weaving.OTWeavingHook.WeavingReason;
 import org.eclipse.objectteams.otredyn.bytecode.IRedefineStrategy;
 import org.eclipse.objectteams.otredyn.bytecode.RedefineStrategyFactory;
+import org.eclipse.objectteams.otredyn.transformer.IWeavingContext;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleWiring;
 
 /**
  * Generalization over the transformers of OTRE and OTDRE.
@@ -35,9 +40,9 @@
 public abstract class DelegatingTransformer {
 
 	/** Factory method for a fresh transformer. */
-	static @NonNull DelegatingTransformer newTransformer(boolean useDynamicWeaver) {
+	static @NonNull DelegatingTransformer newTransformer(boolean useDynamicWeaver, OTWeavingHook hook, BundleWiring wiring) {
 		if (useDynamicWeaver)
-			return new OTDRETransformer();
+			return new OTDRETransformer(getWeavingContext(hook, wiring));
 		else
 			return new OTRETransformer();
 	}
@@ -59,10 +64,10 @@
 	}
 	
 	private static class OTDRETransformer extends DelegatingTransformer {
-		org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer transformer =
-				new org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer();
-		public OTDRETransformer() {
+		org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer transformer;
+		public OTDRETransformer(IWeavingContext weavingContext) {
 			RedefineStrategyFactory.setRedefineStrategy(new OTEquinoxRedefineStrategy());
+			transformer = new org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer(weavingContext);
 		}
 		@Override
 		public void readOTAttributes(String className, InputStream inputStream, String fileName, Bundle bundle) throws ClassFormatError, IOException {
@@ -120,6 +125,23 @@
 			}
 		};
 	}
+
+	static IWeavingContext getWeavingContext(final OTWeavingHook hook, final BundleWiring bundleWiring) {
+		return new IWeavingContext() {
+			@Override
+			public boolean isWeavable(String className) {
+				// currently, we don't support implicit crossing of bundle boundaries,
+				// so check if the requested class is provided by the current bundle:
+				int lastDot = className.lastIndexOf('.');
+				String path = className.substring(0, lastDot).replace('.', '/');
+				String filePattern = className.substring(lastDot+1)+".class";
+				List<URL> entry = bundleWiring.findEntries(path, filePattern, 0);
+				if (entry == null || entry.isEmpty())
+					return false;
+				return hook.requiresWeaving(bundleWiring, className, null) != WeavingReason.None;
+			}
+		};
+	}
 	
 	public abstract void readOTAttributes(String className, InputStream inputStream, String fileName, Bundle bundle) throws ClassFormatError, IOException;
 	
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
index b973667..d5e67bb 100644
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
@@ -1,7 +1,7 @@
 /**********************************************************************
  * This file is part of "Object Teams Development Tooling"-Software
  * 
- * Copyright 2013, 2014 GK Software AG
+ * Copyright 2013, 2015 GK Software AG
  *  
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -236,7 +236,7 @@
 
 				long time = 0;
 
-				DelegatingTransformer transformer = DelegatingTransformer.newTransformer(useDynamicWeaver);
+				DelegatingTransformer transformer = DelegatingTransformer.newTransformer(useDynamicWeaver, this, bundleWiring);
 				Class<?> classBeingRedefined = null; // TODO prepare for otre-dyn
 				try {
 					log(IStatus.OK, "About to transform class "+className);
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
index 5d461e9..5bf069b 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
@@ -31,6 +31,7 @@
 import org.eclipse.objectteams.otredyn.runtime.IMethod;
 import org.eclipse.objectteams.otredyn.runtime.TeamManager;
 import org.eclipse.objectteams.otredyn.runtime.ISubclassWiringTask;
+import org.eclipse.objectteams.otredyn.transformer.IWeavingContext;
 import org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer;
 import org.objectweb.asm.Opcodes;
 
@@ -175,6 +176,8 @@
 
 	protected ClassLoader loader;
 
+	// callback
+	protected IWeavingContext weavingContext;
 
 
 
@@ -331,7 +334,8 @@
 	 * Add the empty method accessStatic
 	 * Add the empty method callAllBindings
 	 */
-	public void transformAtLoadTime() {
+	public void transformAtLoadTime(IWeavingContext weavingContext) {
+		this.weavingContext = weavingContext;
 		handleTaskList();
 	}
 
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
index 7762e40..45374f0 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
@@ -1,7 +1,7 @@
 /**********************************************************************

  * This file is part of "Object Teams Dynamic Runtime Environment"

  * 

- * Copyright 2009, 2014 Oliver Frank and others.

+ * Copyright 2009, 2015 Oliver Frank and others.

  * 

  * All rights reserved. This program and the accompanying materials

  * are made available under the terms of the Eclipse Public License v1.0

@@ -229,7 +229,7 @@
 	protected void moveCodeToCallOrig(Method boundMethod, int boundMethodId) {

 		if (boundMethod.getName().equals("<init>")) return; // don't move constructor code

 		assert (isTransformationActive) : "No transformation active";

-		nodes.add(new MoveCodeToCallOrigAdapter(this, boundMethod, boundMethodId));

+		nodes.add(new MoveCodeToCallOrigAdapter(this, boundMethod, boundMethodId, this.weavingContext));

 	}

 	

 	/**

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java
index 409d51b..1c51220 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java
@@ -21,6 +21,7 @@
 import java.util.ListIterator;

 

 import org.eclipse.objectteams.otredyn.bytecode.Method;

+import org.eclipse.objectteams.otredyn.transformer.IWeavingContext;

 import org.eclipse.objectteams.otredyn.transformer.names.ConstantMembers;

 import org.objectweb.asm.Opcodes;

 import org.objectweb.asm.Type;

@@ -44,8 +45,9 @@
 	private int firstArgIndex; // slot index of the first argument (0 (static) or 1 (non-static))

 	private int argOffset; // used to skip synth args if the callOrig method itself is a statid role method

 	private Method callOrig;

+	private boolean superIsWeavable = true;

 	

-	public MoveCodeToCallOrigAdapter(AsmWritableBoundClass clazz, Method method, int boundMethodId) {

+	public MoveCodeToCallOrigAdapter(AsmWritableBoundClass clazz, Method method, int boundMethodId, IWeavingContext weavingContext) {

 		this.method = method;

 		this.boundMethodId = boundMethodId;

 		if (method.isStatic()) {

@@ -56,6 +58,8 @@
 			firstArgIndex = 1;

 			callOrig = ConstantMembers.callOrig;

 		}

+		if (weavingContext != null)

+			superIsWeavable = weavingContext.isWeavable(clazz.getSuperClassName());

 	}

 	

 	public boolean transform() {

@@ -105,7 +109,8 @@
 			}

 		}

 

-		adjustSuperCalls(orgMethod.instructions, orgMethod.name, args, returnType, boundMethodIdSlot);

+		if (superIsWeavable)

+			adjustSuperCalls(orgMethod.instructions, orgMethod.name, args, returnType, boundMethodIdSlot);

 		

 		// replace return of the original method with areturn and box the result value if needed

 		replaceReturn(orgMethod.instructions, returnType);

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/IWeavingContext.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/IWeavingContext.java
new file mode 100644
index 0000000..3057580
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/IWeavingContext.java
@@ -0,0 +1,32 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ * 
+ * Copyright 2015 GK Software AG
+ * 
+ * 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
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 	  Stephan Herrmann - Initial API and implementation
+ */
+package org.eclipse.objectteams.otredyn.transformer;
+
+/**
+ * Callback protocol to let the transformer query its context.
+ * @since 1.1.0
+ */
+public interface IWeavingContext {
+	/**
+	 * Is the given class included in load-time weaving, i.e., will
+	 * the weaving context pass the class to the transformer during
+	 * initial loading?
+	 * @param className full qualified classname, dot-separated for packages 
+	 * 		and dollar-separated for nested classes. 
+	 * @return true if the given class is included in load-time weaving.
+	 */
+	boolean isWeavable(String className);
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java
index bb57d19..cd5a5d8 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java
@@ -1,7 +1,7 @@
 /**********************************************************************
  * This file is part of "Object Teams Dynamic Runtime Environment"
  * 
- * Copyright 2002, 2014 Berlin Institute of Technology, Germany, and others.
+ * Copyright 2002, 2015 Berlin Institute of Technology, Germany, and others.
  * 
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -25,6 +25,7 @@
 
 import org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass;
 import org.eclipse.objectteams.otredyn.bytecode.ClassRepository;
+import org.eclipse.objectteams.otredyn.transformer.IWeavingContext;
 
 
 /**
@@ -33,8 +34,16 @@
  */
 public class ObjectTeamsTransformer implements ClassFileTransformer {
 
+	private IWeavingContext weavingContext;
+	
 	private Set<String> boundBaseClassNames = new HashSet<String>();
 
+	public ObjectTeamsTransformer() { }
+
+	public ObjectTeamsTransformer(IWeavingContext weavingContext) {
+		this.weavingContext = weavingContext;
+	}
+	
 	/* (non-Javadoc)
 	 * @see java.lang.instrument.ClassFileTransformer#transform(java.lang.ClassLoader, java.lang.String, java.lang.Class, java.security.ProtectionDomain, byte[])
 	 */
@@ -63,7 +72,7 @@
 			if (!clazz.isInterface())
 				ClassRepository.getInstance().linkClassWithSuperclass(clazz);
 			if (!clazz.isInterface() || clazz.isRole())
-				clazz.transformAtLoadTime();
+				clazz.transformAtLoadTime(this.weavingContext);
 			
 			classfileBuffer = clazz.getBytecode();
 			clazz.dump(classfileBuffer, "initial");