Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2013-01-22 20:08:43 +0000
committerStephan Herrmann2013-01-22 20:08:43 +0000
commitead38387931ff9a1de5d89c97948e54b6ca0c72b (patch)
tree79edd1076044f81e639fe4a8d0dc6d09a67d4c6f
parentd3be838278c26528c9a13b7d11e9d90d4629b8ca (diff)
downloadorg.eclipse.objectteams-ead38387931ff9a1de5d89c97948e54b6ca0c72b.tar.gz
org.eclipse.objectteams-ead38387931ff9a1de5d89c97948e54b6ca0c72b.tar.xz
org.eclipse.objectteams-ead38387931ff9a1de5d89c97948e54b6ca0c72b.zip
Added existing classes from old OTRE plus my own additions.
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddAfterClassLoadingHook.java103
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddGlobalTeamActivationAdapter.java165
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddImplicitActivationAdapter.java144
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateAddRemoveRoleMethod.java105
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBinding.java53
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBoundClass.java86
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBoundTeam.java45
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IClassRepository.java73
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IMember.java27
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IMethod.java30
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/ISubclassWiringTask.java28
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/OTREInternalError.java61
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java105
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/otreAgent.java40
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/util/ListValueHashMap.java97
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/DoublyWeakHashMap.java105
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/DuplicateRoleException.java46
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IBaseMigratable.java34
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IConfined.java23
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ILiftingParticipant.java39
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ITeam.java219
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ITeamMigratable.java35
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IllegalRoleCreationException.java34
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ImplicitTeamActivation.java44
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/Instantiation.java36
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/InstantiationPolicy.java56
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/LiftingFailedException.java46
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/LiftingVetoException.java45
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/NoSuchMethodError.java30
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ResultNotProvidedException.java60
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/RoleCastException.java39
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/SneakyException.java61
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/SoftLiftingFailedException.java48
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/TeamThreadManager.java121
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/UnsupportedFeatureException.java59
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/WrongRoleException.java57
36 files changed, 2399 insertions, 0 deletions
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddAfterClassLoadingHook.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddAfterClassLoadingHook.java
new file mode 100644
index 000000000..9398b2642
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddAfterClassLoadingHook.java
@@ -0,0 +1,103 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2009, 2012 Stephan Herrmann.
+ *
+ * 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.bytecode.asm;
+
+import org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass;
+import org.eclipse.objectteams.otredyn.transformer.names.ClassNames;
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.AdviceAdapter;
+
+import org.objectweb.asm.Opcodes;
+
+import static org.eclipse.objectteams.otredyn.bytecode.Types.ACCESS_STATIC;
+import static org.objectweb.asm.Opcodes.INVOKESTATIC;
+import static org.objectweb.asm.Opcodes.RETURN;
+
+
+/**
+ * This adapter adds static initialization that gives the TeamManager
+ * a chance to trigger class redefinition after the class has been defined successfully.
+ * This is needed if a weaving task is recorded after load-time weaving has been performed
+ * and before defining the class has finished.
+ *
+ * Also the per-team-class mapping of accessIds is initialized at that point.
+ *
+ * @author stephan
+ *
+ */
+public class AddAfterClassLoadingHook extends ClassAdapter {
+
+ // the method to look for or add:
+ private static final String CLINIT_NAME = "<clinit>";
+ private static final String CLINIT_DESC = "()V";
+
+ // the method to invoke:
+ private static final String TARGET_CLASS_NAME = ClassNames.TEAM_MANAGER_SLASH;
+ private static final String TARGET_METHOD_NAME = "handleTeamLoaded";
+ private static final String TARGET_METHOD_DESC = "(Ljava/lang/Class;)V";
+
+ boolean needToAdd = true;
+ AbstractBoundClass clazz;
+
+ public AddAfterClassLoadingHook(ClassVisitor arg0, AbstractBoundClass clazz) {
+ super(arg0);
+ this.clazz = clazz;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ if (CLINIT_NAME.equals(name)) {
+ // clinit already exists, add our statement to the front:
+ this.needToAdd = false;
+ final MethodVisitor clinit = cv.visitMethod(access, name, desc, null, null);
+ return new AdviceAdapter(clinit, access, name, desc) {
+ @Override
+ protected void onMethodEnter() {
+ createHookCall(clinit);
+ }
+ @Override
+ public void visitMaxs(int maxStack, int maxLocals) {
+ super.visitMaxs(Math.max(1,maxStack), maxLocals);
+ }
+ };
+ }
+ return null;
+ }
+
+ @Override
+ public void visitEnd() {
+ if (needToAdd) {
+ // no clinit found, add one now:
+ MethodVisitor mv = cv.visitMethod(ACCESS_STATIC, CLINIT_NAME, CLINIT_DESC, null, null);
+ mv.visitCode();
+ createHookCall(mv);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 0);
+ mv.visitEnd();
+ }
+ }
+
+ void createHookCall(MethodVisitor clinit) {
+ if (clazz.isTeam())
+ clinit.visitLdcInsn(Type.getObjectType(clazz.getName().replace('.', '/')));
+ else
+ clinit.visitInsn(Opcodes.ACONST_NULL);
+ clinit.visitMethodInsn(INVOKESTATIC, TARGET_CLASS_NAME, TARGET_METHOD_NAME, TARGET_METHOD_DESC);
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddGlobalTeamActivationAdapter.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddGlobalTeamActivationAdapter.java
new file mode 100644
index 000000000..711047aa4
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddGlobalTeamActivationAdapter.java
@@ -0,0 +1,165 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2011, 2012 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.bytecode.asm;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.objectteams.otredyn.transformer.names.ClassNames;
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.commons.AdviceAdapter;
+
+/**
+ * This adapter adds some instructions to the front of the main-method.
+ * These instructions will instantiate and globally activate all teams
+ * that are listed in the team config file.
+ * The team config file is specified via the <code>ot.teamconfig</code> property.
+ */
+public class AddGlobalTeamActivationAdapter extends ClassAdapter {
+
+ /** Initialized from property <tt>ot.teamconfig</tt>. */
+ private final static String TEAM_CONFIG_FILE = System.getProperty("ot.teamconfig");
+ /** Marker for comment lines in the team config file. */
+ private final static String COMMENT_MARKER = "#";
+
+ private static boolean done = false;
+
+ private AddGlobalTeamActivationAdapter(ClassVisitor cv) {
+ super(cv);
+ }
+
+ /**
+ * Adds the one and only {@link AddGlobalTeamActivationAdapter} to the given multiAdaptor,
+ * if needed and if not already done.
+ * @param multiAdapter
+ * @param writer
+ */
+ synchronized public static void checkAddVisitor(MultiClassAdapter multiAdapter, ClassWriter writer) {
+ if (done || TEAM_CONFIG_FILE == null)
+ return;
+ multiAdapter.addVisitor(new AddGlobalTeamActivationAdapter(writer));
+ }
+
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ synchronized (AddGlobalTeamActivationAdapter.class) {
+ if (!done && isMainMethod(name, desc, access)) {
+ done = true;
+ final MethodVisitor methodVisitor = cv.visitMethod(access, name, desc, null, null);
+ return new AdviceAdapter(methodVisitor, access, name, desc) {
+ @Override
+ protected void onMethodEnter() {
+ List<String> teams = getTeamsFromConfigFile();
+ for (String aTeam : teams) {
+ Label start, end, typeHandler, ctorHandler, after;
+
+ String aTeamSlash = aTeam.replace('.', '/');
+
+ // new SomeTeam():
+ methodVisitor.visitLabel(start=new Label());
+ methodVisitor.visitTypeInsn(Opcodes.NEW, aTeamSlash);
+ // .activate(Team.ALL_THREADS):
+ methodVisitor.visitInsn(Opcodes.DUP);
+ methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, aTeamSlash, "<init>", "()V");
+ methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, ClassNames.TEAM_SLASH, "ALL_THREADS", "Ljava/lang/Thread;");
+ methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, aTeamSlash, "activate", "(Ljava/lang/Thread;)V");
+
+ methodVisitor.visitLabel(end=new Label());
+ methodVisitor.visitJumpInsn(Opcodes.GOTO, after=new Label());
+
+ // catch (ClassNotFoundException, NoClassDefFoundError):
+ // System.err.println(...)
+ methodVisitor.visitLabel(typeHandler=new Label());
+ methodVisitor.visitInsn(Opcodes.POP); // discard the exception
+ methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("Config error: Team class '"+aTeam+ "' in config file '"+ TEAM_CONFIG_FILE+"' can not be found!");
+ methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
+ methodVisitor.visitJumpInsn(Opcodes.GOTO, after);
+ methodVisitor.visitTryCatchBlock(start, end, typeHandler, "java/lang/ClassNotFoundException");
+ methodVisitor.visitTryCatchBlock(start, end, typeHandler, "java/lang/NoClassDefFoundError");
+
+ // catch (NoSuchMethodError):
+ // System.err.println(...)
+ methodVisitor.visitLabel(ctorHandler=new Label());
+ methodVisitor.visitInsn(Opcodes.POP); // discard the exception
+ methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;");
+ methodVisitor.visitLdcInsn("Activation failed: Team class '"+aTeam+ "' has no default constuctor!");
+ methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
+ methodVisitor.visitTryCatchBlock(start, end, ctorHandler, "java/lang/NoSuchMethodError");
+
+ methodVisitor.visitLabel(after);
+ }
+ }
+ @Override
+ public void visitMaxs(int maxStack, int maxLocals) {
+ super.visitMaxs(Math.max(maxStack,3), maxLocals);
+ }
+ };
+ }
+ return null;
+ }
+ }
+
+ private boolean isMainMethod(String name, String desc, int access) {
+ if (access != (Opcodes.ACC_STATIC|Opcodes.ACC_PUBLIC))
+ return false;
+ if (!"main".equals(name))
+ return false;
+ if (!"([Ljava/lang/String;)V".equals(desc))
+ return false;
+ return true;
+ }
+
+ /**
+ * @return a list of teams in the team initialization config file
+ */
+ private static List<String> getTeamsFromConfigFile() {
+ List<String> result = new ArrayList<String>();
+ BufferedReader in = null;
+ try {
+ FileInputStream fstream = new FileInputStream(TEAM_CONFIG_FILE);
+ in = new BufferedReader(new InputStreamReader(fstream));
+ while (in.ready()) {
+ String nextLine = in.readLine();
+ String nextTeam = nextLine.trim();
+ if (nextTeam.startsWith(COMMENT_MARKER))
+ continue; // this is a comment line
+ if (!nextTeam.equals("")) {
+ result.add(nextTeam.trim());
+ }
+ }
+ } catch (Exception e) {
+ System.err.println("File input error: config file '" + TEAM_CONFIG_FILE + "' can not be found!");
+ } finally {
+ if (in != null)
+ try {
+ in.close();
+ } catch (IOException e) {
+ // nothing
+ }
+ }
+ return result;
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddImplicitActivationAdapter.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddImplicitActivationAdapter.java
new file mode 100644
index 000000000..6b7ea8084
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AddImplicitActivationAdapter.java
@@ -0,0 +1,144 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2011, 2012 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.bytecode.asm;
+
+import org.eclipse.objectteams.otredyn.transformer.names.ClassNames;
+import org.eclipse.objectteams.otredyn.transformer.names.ConstantMembers;
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.commons.AdviceAdapter;
+
+import org.objectweb.asm.Opcodes;
+
+/**
+ * This visitor adds calls to _OT$implicitlyActivate and _OT$implicitlyDeactivate
+ * into all relevant methods as configured by
+ * <ul>
+ * <li>system property <code>ot.implicit.team.activation</code>
+ * <li>annotation {@link org.objectteams.ImplicitTeamActivation}.
+ * </ul>
+ */
+public class AddImplicitActivationAdapter extends ClassAdapter {
+
+ public static final Object ANNOTATION_IMPLICIT_ACTIVATION = 'L'+ClassNames.IMPLICIT_ACTIVATION+';';
+
+ protected static final String TARGET_CLASS_NAME = ClassNames.ITEAM_SLASH;
+ protected static final String IMPLICIT_ACTIVATE_METHOD_NAME = "_OT$implicitlyActivate";
+ protected static final String IMPLICIT_DEACTIVATE_METHOD_NAME = "_OT$implicitlyDeactivate";
+ protected static final String METHOD_DESC = "()V";
+
+ // -------------------------------------------------------
+ // ---------- Modes for implicit team activation --------
+ // -------------------------------------------------------
+ private enum ImplicitActivationMode { NEVER, ANNOTATED, ALWAYS }
+ private static ImplicitActivationMode implicitActivationMode = ImplicitActivationMode.ANNOTATED;
+ static {
+ String prop = System.getProperty("ot.implicit.team.activation");
+ for (ImplicitActivationMode mode : ImplicitActivationMode.values()) {
+ if (mode.name().equals(prop)) {
+ implicitActivationMode = mode;
+ break;
+ }
+ }
+ }
+
+
+ private AsmBoundClass clazz;
+
+ public AddImplicitActivationAdapter(ClassVisitor cv, AsmBoundClass clazz) {
+ super(cv);
+ this.clazz = clazz;
+ }
+
+
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ if (isCandidateForImplicitActivation(name, desc, access)) {
+ final MethodVisitor methodVisitor = cv.visitMethod(access, name, desc, null, null);
+ final String enclTeamDesc = clazz.isRole() ? 'L'+clazz.getEnclosingClass().getName().replace('.', '/')+';' : null;
+ return new AdviceAdapter(methodVisitor, access, name, desc) {
+ @Override
+ protected void onMethodEnter() {
+ if (clazz.isTeam()) {
+ methodVisitor.visitIntInsn(Opcodes.ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKEINTERFACE, TARGET_CLASS_NAME, IMPLICIT_ACTIVATE_METHOD_NAME, METHOD_DESC);
+ }
+ if (clazz.isRole()) {
+ // TODO(SH): respect nesting depth (this$n)
+ methodVisitor.visitIntInsn(Opcodes.ALOAD, 0);
+ methodVisitor.visitFieldInsn(Opcodes.GETFIELD, clazz.getName().replace('.', '/'), "this$0", enclTeamDesc);
+ methodVisitor.visitMethodInsn(INVOKEINTERFACE, TARGET_CLASS_NAME, IMPLICIT_ACTIVATE_METHOD_NAME, METHOD_DESC);
+ }
+ }
+ @Override
+ protected void onMethodExit(int opcode) {
+ if (clazz.isTeam()) {
+ methodVisitor.visitIntInsn(Opcodes.ALOAD, 0);
+ methodVisitor.visitMethodInsn(INVOKEINTERFACE, TARGET_CLASS_NAME, IMPLICIT_DEACTIVATE_METHOD_NAME, METHOD_DESC);
+ }
+ if (clazz.isRole()) {
+ // TODO(SH): respect nesting depth (this$n)
+ methodVisitor.visitIntInsn(Opcodes.ALOAD, 0);
+ methodVisitor.visitFieldInsn(Opcodes.GETFIELD, clazz.getName().replace('.', '/'), "this$0", enclTeamDesc);
+ methodVisitor.visitMethodInsn(INVOKEINTERFACE, TARGET_CLASS_NAME, IMPLICIT_DEACTIVATE_METHOD_NAME, METHOD_DESC);
+ }
+ if (clazz.isTeam() || clazz.isRole())
+ methodVisitor.visitMaxs(0, 0);
+ }
+ };
+ }
+ return null;
+ }
+
+
+ private boolean isCandidateForImplicitActivation(String methName, String methDesc, int accessFlags) {
+ if (clazz.isTeam()) {
+ if ((accessFlags & Opcodes.ACC_PRIVATE) != 0)
+ return false;
+ } else if (clazz.isRole()) {
+ if ( clazz.isProtected()
+ || (accessFlags & Opcodes.ACC_PUBLIC) == 0)
+ return false;
+ } else {
+ return false;
+ }
+ switch (implicitActivationMode) {
+ case NEVER:
+ return false;
+ case ANNOTATED:
+ if (!clazz.hasMethodImplicitActivation(methName+methDesc))
+ return false;
+ //$FALL-THROUGH$
+ case ALWAYS:
+ // TODO: respect RoleClassMethodModifiers attribute
+ return canImplicitlyActivate(accessFlags, methName, methDesc);
+ }
+ return false;
+ }
+
+ private static boolean canImplicitlyActivate(int methFlags, String methName, String methDesc) {
+ boolean isCandidate =
+ ((methFlags & (Opcodes.ACC_ABSTRACT|Opcodes.ACC_STATIC)) == 0) &&
+ (!methName.startsWith("_OT$")) &&
+ (!methName.equals("<init>")) &&
+ (!(methName.equals("activate") && methDesc.equals("()V"))) &&
+ (!(methName.equals("deactivate") && methDesc.equals("()V"))) &&
+ (!ConstantMembers.isReflectiveOTMethod(methName, methDesc));
+ return isCandidate;
+ }
+
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateAddRemoveRoleMethod.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateAddRemoveRoleMethod.java
new file mode 100644
index 000000000..4080b8264
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateAddRemoveRoleMethod.java
@@ -0,0 +1,105 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2009, 2012 Stephan Herrmann.
+ *
+ * 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.bytecode.asm;
+
+import org.eclipse.objectteams.otredyn.transformer.names.ClassNames;
+import org.eclipse.objectteams.otredyn.transformer.names.ConstantMembers;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.InsnNode;
+import org.objectweb.asm.tree.IntInsnNode;
+import org.objectweb.asm.tree.JumpInsnNode;
+import org.objectweb.asm.tree.LabelNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TypeInsnNode;
+
+/**
+ * Implements the method <code>void _OT$addOrRemoveRole(Object role, boolean isAdding)</code>
+ * from <code>org.objectteams.IBoundBase</code>
+ *
+ * @author stephan
+ */
+public class CreateAddRemoveRoleMethod extends AbstractTransformableClassNode {
+
+
+ @Override
+ protected void transform() {
+ // void _OT$addRemoveRole(Object role, boolean isAdding) {
+ MethodNode method = getMethod(ConstantMembers.addOrRemoveRole);
+ method.instructions.clear();
+
+ // set = <initialized _OT$roleSet;>
+ genGetInitializedRoleSet(method.instructions, 3);
+
+ // if (isAdding) {
+ method.instructions.add(new IntInsnNode(Opcodes.ILOAD, 2));
+ LabelNode jumpToRemove = new LabelNode();
+ method.instructions.add(new JumpInsnNode(Opcodes.IFEQ, jumpToRemove));
+
+ // set.add(role);
+ method.instructions.add(new IntInsnNode(Opcodes.ALOAD, 3));
+ method.instructions.add(new IntInsnNode(Opcodes.ALOAD, 1));
+ method.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, ClassNames.HASH_SET_SLASH, "add", "(Ljava/lang/Object;)Z"));
+ method.instructions.add(new InsnNode(Opcodes.POP));
+
+ LabelNode jumpToEnd = new LabelNode();
+ method.instructions.add(new JumpInsnNode(Opcodes.GOTO, jumpToEnd));
+ // } else {
+ method.instructions.add(jumpToRemove);
+ // set.remove(role);
+ method.instructions.add(new IntInsnNode(Opcodes.ALOAD, 3));
+ method.instructions.add(new IntInsnNode(Opcodes.ALOAD, 1));
+ method.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, ClassNames.HASH_SET_SLASH, "remove", "(Ljava/lang/Object;)Z"));
+ method.instructions.add(new InsnNode(Opcodes.POP));
+
+ method.instructions.add(jumpToEnd);
+ // }
+
+ method.instructions.add(new InsnNode(Opcodes.RETURN));
+ // }
+ method.maxStack = 3;
+ method.maxLocals = 4; // this + 2 args + 1 local ("set")
+
+ }
+
+ void genGetInitializedRoleSet(InsnList instructions, int targetLocal) {
+ // x = this._OT$roleSet
+ instructions.add(new IntInsnNode(Opcodes.ALOAD, 0));
+ instructions.add(new FieldInsnNode(Opcodes.GETFIELD, name, ConstantMembers.OT_ROLE_SET, ConstantMembers.HASH_SET_FIELD_TYPE));
+
+ instructions.add(new IntInsnNode(Opcodes.ASTORE, targetLocal));
+ instructions.add(new IntInsnNode(Opcodes.ALOAD, targetLocal));
+
+ // if (x == null) {
+ LabelNode skipInstantiation = new LabelNode();
+ instructions.add(new JumpInsnNode(Opcodes.IFNONNULL, skipInstantiation));
+
+ // this._OT$roleSet = new HashSet();
+ instructions.add(new IntInsnNode(Opcodes.ALOAD, 0));
+ instructions.add(new TypeInsnNode(Opcodes.NEW, ClassNames.HASH_SET_SLASH));
+ instructions.add(new InsnNode(Opcodes.DUP));
+ instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, ClassNames.HASH_SET_SLASH, "<init>", "()V"));
+
+ instructions.add(new IntInsnNode(Opcodes.ASTORE, targetLocal));
+ instructions.add(new IntInsnNode(Opcodes.ALOAD, targetLocal));
+ instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, name, ConstantMembers.OT_ROLE_SET, ConstantMembers.HASH_SET_FIELD_TYPE));
+
+ instructions.add(skipInstantiation);
+ // }
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBinding.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBinding.java
new file mode 100644
index 000000000..13b02c406
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBinding.java
@@ -0,0 +1,53 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2011, 2012 GK Software AG 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
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otredyn.runtime;
+
+/**
+ * Interface through which the {@link TeamManager} reaches into the OTREDyn.
+ * Representation of a callin binding or a callout decapsulation binding.
+ *
+ * @author stephan
+ */
+public interface IBinding {
+
+ public static enum BindingType {
+ CALLIN_BINDING,
+ FIELD_ACCESS,
+ METHOD_ACCESS
+ }
+
+ BindingType getType();
+
+ /** The base class as declared in the source level playedBy clause. */
+ String getBoundClass();
+
+ /** The base class actually declaring the referenced member. */
+ String getDeclaringBaseClassName();
+
+ /** Name of the bound base member. */
+ String getMemberName();
+
+ /** Signature (JVM encoding) of the bound base member. */
+ String getMemberSignature();
+
+ /** Answer the callin ID (also used for callout decapsulation bindings) */
+ int getCallinId();
+
+ /** Does base method matching include overrides with covariant return type?. */
+ boolean isHandleCovariantReturn();
+
+
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBoundClass.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBoundClass.java
new file mode 100644
index 000000000..21f7066ee
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBoundClass.java
@@ -0,0 +1,86 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2011, 2012 GK Software AG 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
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otredyn.runtime;
+
+import org.eclipse.objectteams.otredyn.bytecode.Field;
+import org.eclipse.objectteams.otredyn.bytecode.Method;
+
+/**
+ * Interface through which the {@link TeamManager} reaches into the OTREDyn.
+ * Representation of a class that participates in a binding.
+ *
+ * @author stephan
+ */
+public interface IBoundClass {
+
+ /**
+ * Returns the identifier of the class
+ * @return
+ */
+ String getId();
+
+ /** Answer whether this class is an anonymous subclass. */
+ boolean isAnonymous();
+
+ /**
+ * Returns the method of this class, with the specified name
+ * and signature. If the class is not already loaded yet, the method
+ * is created.
+ * This method ensures, that it returns the same instance
+ * of {@link Method} for the same tuple of name and desc. More formally:
+ * if (name1 + desc1).equals(name2 + desc2) then
+ * getMethod(name1, desc1) == getMethod(name2, desc2)
+ * @param name the name of the method
+ * @param desc the signature of the method (JVM encoding)
+ * @param handleCovariantReturn whether or not methods with covariant return type should be considered
+ * @return
+ */
+ IMethod getMethod(String memberName, String memberSignature, boolean handleCovariantReturn);
+
+ /**
+ * This method creates a globally unique identifier for the method
+ * @param method
+ * @return
+ */
+ String getMethodIdentifier(IMethod method);
+
+ /**
+ * Returns the field of this class, with the specified name
+ * and signature. If the class is not already loaded yet, the field
+ * is created.
+ * This method ensures, that it returns the same instance
+ * of {@link Field} for the same tupel of name and desc. More formally:
+ * if (name1 + desc1).equals(name2 + desc2) then
+ * getField(name1, desc1) == getField(name2, desc2)
+ * @param name the name of the method
+ * @param desc the siganture of the method
+ * @return
+ */
+ IMember getField(String memberName, String memberSignature);
+
+ /**
+ * Handle a new binding a decides, weather weaving is neede or not
+ * @param binding the new binding
+ */
+ void handleAddingOfBinding(IBinding binding);
+
+ /**
+ * Add a {@link ISubclassWiringTask wiring task} to be performed when a
+ * newly loaded class is linked to this class as its super class.
+ */
+ void addWiringTask(ISubclassWiringTask subclassWiringTask);
+
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBoundTeam.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBoundTeam.java
new file mode 100644
index 000000000..ad42d641c
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IBoundTeam.java
@@ -0,0 +1,45 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2011, 2012 GK Software AG 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
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otredyn.runtime;
+
+import java.util.Collection;
+
+import org.eclipse.objectteams.otredyn.bytecode.Binding;
+
+/**
+ * Interface through which the {@link TeamManager} reaches into the OTREDyn.
+ * Representation of a team class.
+ *
+ * @author stephan
+ */
+public interface IBoundTeam {
+
+ /**
+ * Returns all bindings this team have got.
+ * Parses the bytecode, if thats needed
+ * @return
+ */
+ Collection<Binding> getBindings();
+
+ /**
+ * Returns the highest access defined by this team.
+ * The access id is a unique identifier for a base member
+ * in the team
+ * @return
+ */
+ int getHighestAccessId();
+
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IClassRepository.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IClassRepository.java
new file mode 100644
index 000000000..fd231b8b8
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IClassRepository.java
@@ -0,0 +1,73 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2011, 2012 GK Software AG 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
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otredyn.runtime;
+
+import org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass;
+import org.eclipse.objectteams.otredyn.bytecode.AbstractTeam;
+
+/**
+ * Interface through which the {@link TeamManager} reaches into the OTREDyn.
+ * Representation of a repository of {@link IBoundClass}es.
+ *
+ * @author stephan
+ */
+public interface IClassRepository {
+
+ /**
+ * Returns a instance of AbstractBoundClass for the
+ * given FQN and id. If there is no instance it
+ * is created. The class have not to be loaded to get
+ * an instance of AbstractBoundClass representing this class.
+ * It guarantees, that it returns always the same
+ * instance for the same id. More formally:
+ * if id1.equals(id2) then getBoundClass(..., id1) == getBoundClass(id2)
+ * @param className the name of the class
+ * @param id a globally unique identifier for the class
+ * @return
+ */
+ public AbstractBoundClass getBoundClass(String className, String id, ClassLoader loader);
+
+ /**
+ * Returns a instance of AbstractBoundClass for the
+ * given FQN and id and sets the bytecode for this class.
+ * If there is no instance it is created.
+ * This class should be called while loading the class.
+ * It guarantees, that it returns always the same
+ * instance for the same id. More formally:
+ * if id1.equals(id2) then getBoundClass(..., id1) == getBoundClass(..., id2)
+ * @param className the name of the class
+ * @param id a globally unique identifier for the class
+ * @return
+ */
+ public AbstractBoundClass getBoundClass(String className, String id, byte[] classBytes, ClassLoader loader);
+
+ /**
+ * Returns a instance of AbstractTeam for the
+ * given FQN and id. If there is no instance it
+ * is created.
+ * It guarantees, that it returns always the same
+ * instance for the same id. More formally:
+ * if id1.equals(id2) then getTeam(..., id1) == getTeam(..., id2).
+ * This method should only be called, if it is known
+ * that the name identifies a team and not a class.
+ * Otherwise call getBoundClass().isTeam() to check this.
+ * @param teamName the name of the team
+ * @param id a globally unique identifier for the team
+ * @return
+ */
+ public AbstractTeam getTeam(String teamName, String id, ClassLoader loader);
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IMember.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IMember.java
new file mode 100644
index 000000000..d0cbd4755
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IMember.java
@@ -0,0 +1,27 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2011, 2012 GK Software AG 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
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otredyn.runtime;
+
+/**
+ * Interface through which the {@link TeamManager} reaches into the OTREDyn.
+ * Representation of a member (method or field).
+ *
+ * @author stephan
+ */
+public interface IMember {
+
+ int getId(IBoundClass boundClass);
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IMethod.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IMethod.java
new file mode 100644
index 000000000..243752fd2
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/IMethod.java
@@ -0,0 +1,30 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2011, 2012 GK Software AG 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
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otredyn.runtime;
+
+/**
+ * Interface through which the {@link TeamManager} reaches into the OTREDyn.
+ * Representation of a method.
+ *
+ * @author stephan
+ */
+public interface IMethod extends IMember {
+
+ String getName();
+
+ String getSignature();
+
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/ISubclassWiringTask.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/ISubclassWiringTask.java
new file mode 100644
index 000000000..83ce651a8
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/runtime/ISubclassWiringTask.java
@@ -0,0 +1,28 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2011, 2012 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.runtime;
+
+
+/**
+ * Interface for tasks that need to be performed when wiring a class to one of its subclasses.
+ * @author stephan
+ */
+public interface ISubclassWiringTask {
+
+ /** Perform necessary action for the given pair of classes. */
+ public void wire(IBoundClass superClass, IBoundClass subClass);
+
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/OTREInternalError.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/OTREInternalError.java
new file mode 100644
index 000000000..cf129bca4
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/OTREInternalError.java
@@ -0,0 +1,61 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2003, 2010 Berlin Institute of Technology, Germany.
+ *
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otredyn.transformer;
+
+/**
+ * @author stephan
+ */
+public class OTREInternalError extends Error {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private static final String _bugmsg =
+ "An error occurred in the Object Teams runtime environment.\n"+
+ "We would appreciate if you send a bug report to support@ObjectTeams.org.\n"+
+ "Please include your program (if possible) and the following diagnostic\n"+
+ "in your report. -- Thank you. The ObjectTeams/Java developers\n";
+ /**
+ *
+ */
+ public OTREInternalError() {
+ super(_bugmsg);
+ }
+
+ /**
+ * @param message
+ */
+ public OTREInternalError(String message) {
+ super(_bugmsg+message);
+ }
+
+ /**
+ * @param cause
+ */
+ public OTREInternalError(Throwable cause) {
+ super(_bugmsg+cause.toString());
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public OTREInternalError(String message, Throwable cause) {
+ super(_bugmsg+message+cause.toString());
+ }
+
+}
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
new file mode 100644
index 000000000..097ba4ce4
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java
@@ -0,0 +1,105 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2002, 2012 Berlin Institute of Technology, Germany.
+ *
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otredyn.transformer.jplis;
+
+import java.lang.instrument.ClassFileTransformer;
+import java.security.ProtectionDomain;
+
+import org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass;
+import org.eclipse.objectteams.otredyn.bytecode.ClassRepository;
+
+
+/**
+ * This class does all needed transformations at load time.
+ * @author Christine Hundt
+ */
+
+public class ObjectTeamsTransformer implements ClassFileTransformer {
+ /* (non-Javadoc)
+ * @see java.lang.instrument.ClassFileTransformer#transform(java.lang.ClassLoader, java.lang.String, java.lang.Class, java.security.ProtectionDomain, byte[])
+ */
+
+ public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
+ ProtectionDomain protectionDomain, byte[] classfileBuffer) {
+
+
+ return transform(loader, className, className, classBeingRedefined, classfileBuffer);
+ }
+
+ public byte[] transform(ClassLoader loader, String className, String classId, Class<?> classBeingRedefined,
+ byte[] classfileBuffer) {
+ if (!ObjectTeamsTransformer.isWeavable(className))
+ return null;
+
+ AbstractBoundClass clazz = ClassRepository.getInstance().getBoundClass(
+ className.replace('/','.'), classId, loader);
+ try {
+ if (clazz.isTransformationActive()) {
+ return null;
+ }
+ clazz = ClassRepository.getInstance().getBoundClass(
+ className, classId, classfileBuffer, loader);
+ if (!clazz.isInterface())
+ ClassRepository.getInstance().linkClassWithSuperclass(clazz);
+ if (!clazz.isInterface() || clazz.isRole())
+ clazz.transformAtLoadTime();
+
+ classfileBuffer = clazz.getBytecode();
+ clazz.dump(classfileBuffer, "initial");
+ } catch(Throwable t) {
+ t.printStackTrace();
+ }
+
+ return classfileBuffer;
+ }
+
+ public static boolean isWeavable(String className) {
+ switch(className.charAt(0)) {
+ case 'o':
+ if ( className.startsWith("org/eclipse/objectteams/otre") // incl. otredyn
+ || className.startsWith("org/objectteams/") // Team etc.
+ || className.startsWith("org/objectweb/asm"))
+ // skip OTRE and ASM classes
+ return false;
+ break;
+ case 's':
+ // skip, I saw a mysterious deadlock involving sun.misc.Cleaner
+ if (className.startsWith("sun/misc"))
+ return false;
+ break;
+ case 'j':
+ // skip, I saw class loading circularity caused by accessing this class:
+ if ( className.equals("java/util/LinkedHashMap$KeyIterator")
+ || className.startsWith("java/lang")
+ || className.startsWith("java/util")
+ || className.startsWith("java/io")
+ )
+ return false;
+ break;
+ case '$':
+ // funny case, motivated by the following stack trace:
+ // java.lang.NoClassDefFoundError: org/eclipse/objectteams/otredyn/runtime/TeamManager
+ // at $Proxy0.<clinit>(Unknown Source)
+ // at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
+ // at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
+ // at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
+ // at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
+ // at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:605)
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/otreAgent.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/otreAgent.java
new file mode 100644
index 000000000..48ec34d85
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/otreAgent.java
@@ -0,0 +1,40 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2002, 2010 Berlin Institute of Technology, Germany.
+ *
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otredyn.transformer.jplis;
+
+import java.lang.instrument.Instrumentation;
+
+
+/**
+ * @author Christine Hundt
+ */
+public class otreAgent {
+ private static Instrumentation instCopy;
+
+
+ private static ObjectTeamsTransformer otTransformer;
+
+ public static void premain(String options, Instrumentation inst) {
+ instCopy = inst;
+
+ otTransformer = new ObjectTeamsTransformer();
+ instCopy.addTransformer(otTransformer);
+ }
+
+ public static Instrumentation getInstrumentation() {
+ return instCopy;
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/util/ListValueHashMap.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/util/ListValueHashMap.java
new file mode 100644
index 000000000..d30c24a1a
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/util/ListValueHashMap.java
@@ -0,0 +1,97 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2004-2009 Berlin Institute of Technology, Germany.
+ *
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otredyn.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * @author resix
+ */
+public class ListValueHashMap<ValueType> {
+ private HashMap<String, LinkedList<ValueType>> hashMap = new HashMap<String, LinkedList<ValueType>>();
+ //redundant structure for faster access:
+ private LinkedList<ValueType> flattenValues = new LinkedList<ValueType>();
+
+ /**
+ * @param key
+ * @param value
+ */
+ public void put(String key, ValueType value) {
+ LinkedList<ValueType> list;
+ if (!hashMap.containsKey(key)) {
+ list = new LinkedList<ValueType>();
+ } else {
+ list = hashMap.get(key);
+ }
+ list.add(value);
+ hashMap.put(key, list);
+ flattenValues.add(value);
+ }
+
+ /**
+ * @return
+ */
+ public List<ValueType> getFlattenValues() {
+ return flattenValues;
+ }
+
+ /**
+ * @param key
+ * @return
+ */
+ public LinkedList<ValueType> get(String key) {
+ if (!hashMap.containsKey(key)) {
+ return null;
+ }
+ return hashMap.get(key);
+ }
+
+ public boolean containsKey(Object o) {
+ return hashMap.containsKey(o);
+ }
+
+ public Set<String> keySet() {
+ return hashMap.keySet();
+ }
+
+ public Set<Entry<String, LinkedList<ValueType>>> entrySet() {
+ return hashMap.entrySet();
+ }
+
+ public int size() {
+ return hashMap.size();
+ }
+
+ public String toString() {
+ StringBuilder result = new StringBuilder(32);
+ Iterator<Entry<String, LinkedList<ValueType>>> it = hashMap.entrySet().iterator();
+ while (it.hasNext()) {
+ Entry<String, LinkedList<ValueType>> entry = (Entry<String, LinkedList<ValueType>>) it.next();
+ result.append(entry.getKey());
+ result.append(": ");
+ result.append(entry.getValue().toString());
+ result.append("\n");
+ }
+ if (result.length() == 0)
+ return super.toString();
+ return result.toString();
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/DoublyWeakHashMap.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/DoublyWeakHashMap.java
new file mode 100644
index 000000000..faa3da8f1
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/DoublyWeakHashMap.java
@@ -0,0 +1,105 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2010 Stephan Herrmann.
+ *
+ * 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.objectteams;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+/**
+ * This class defines hash maps where both key and value are weak references.
+ * It is implemented by delegating to a WeakHashMap and additionally
+ * wrapping the value in a WeakReference.
+ *
+ * @author stephan
+ * @since 0.7.0
+ * @param <K> type of keys: a base class
+ * @param <V> type of values: a role class
+ */
+public class DoublyWeakHashMap<K,V> implements Map<K,V> {
+
+ private WeakHashMap<K, WeakReference<V>> map;
+
+ public DoublyWeakHashMap() {
+ this.map = new WeakHashMap<K, WeakReference<V>>();
+ }
+
+ public int size() {
+ return this.map.size();
+ }
+
+ public boolean isEmpty() {
+ return this.map.isEmpty();
+ }
+
+ // used from hasRole() and lifting (duplicate role check)
+ public boolean containsKey(Object key) {
+ return this.map.containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ throw new UnsupportedFeatureException("Method containsValue is not implemented for internal class DoublyWeakHashMap.");
+ }
+
+ // used from getRole()
+ public V get(Object key) {
+ WeakReference<V> valRef = this.map.get(key);
+ return valRef == null ? null : valRef.get();
+ }
+
+ // used from migrateToBase() and lifting constructor
+ public synchronized V put(K key, V value) {
+ this.map.put(key, new WeakReference<V>(value));
+ return value;
+ }
+
+ // used from unregisterRole(), migrateToBase()
+ public synchronized V remove(Object key) {
+ WeakReference<V> value = this.map.remove(key);
+ return (value == null) ? null : value.get();
+ }
+
+ public void putAll(Map<? extends K, ? extends V> t) {
+ for (Entry<? extends K, ? extends V> entry : t.entrySet())
+ this.map.put(entry.getKey(), new WeakReference<V>(entry.getValue()));
+ }
+
+ public void clear() {
+ this.map.clear();
+ }
+
+ public Set<K> keySet() {
+ return this.map.keySet();
+ }
+
+ // used from getAllRoles() et al.
+ public synchronized Collection<V> values() {
+ ArrayList<V> result = new ArrayList<V>(this.map.size());
+ for (WeakReference<V> valRef : this.map.values()) {
+ V value = valRef.get();
+ if (value != null)
+ result.add(value);
+ }
+ return result;
+ }
+
+ public Set<java.util.Map.Entry<K, V>> entrySet() {
+ throw new UnsupportedFeatureException("Method entrySet is not implemented for internal class DoublyWeakHashMap.");
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/DuplicateRoleException.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/DuplicateRoleException.java
new file mode 100644
index 000000000..9d5c069f6
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/DuplicateRoleException.java
@@ -0,0 +1,46 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2004, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Signal a violation of OTJLD 2.4.1(c).
+ * Also Team.getRole(Object) may throw a DuplicateRoleException if
+ * more than one role is found for the given base object
+ * (in that case those roles are found in different role-caches).
+ *
+ *
+ * @author stephan
+ */
+public class DuplicateRoleException extends RuntimeException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * @param message
+ */
+ public DuplicateRoleException(String roleClassName) {
+ super("Failed to create a role instance of type "+roleClassName+"\n"+
+ "A role for the given base object already exists (OTJLD 2.4.1(c)).");
+ }
+
+ public DuplicateRoleException(String roleName1, String roleName2) {
+ super("Ambiguous role instances: found a role in hierarchies "+
+ roleName1+" and "+roleName2);
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IBaseMigratable.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IBaseMigratable.java
new file mode 100644
index 000000000..fa49611a2
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IBaseMigratable.java
@@ -0,0 +1,34 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2008, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Marker interface: if a role declares to implement this interface
+ * the compiler will generate the method defined herein, and prepare
+ * the role so that the migration will indeed be possible.
+ *
+ * @author stephan
+ * @since 1.2.5
+ */
+public interface IBaseMigratable {
+ /**
+ * Migrate the current role to the otherBase.
+ *
+ * @param otherBase new base that this role should adapt, must
+ * be of a valid base type for the current role.
+ */
+ <B> void migrateToBase(B otherBase);
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IConfined.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IConfined.java
new file mode 100644
index 000000000..ca13bbcec
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IConfined.java
@@ -0,0 +1,23 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2004, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Special interface that does not extend Object
+ *
+ * @author stephan
+ */
+public interface IConfined {} \ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ILiftingParticipant.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ILiftingParticipant.java
new file mode 100644
index 000000000..725cd19a9
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ILiftingParticipant.java
@@ -0,0 +1,39 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2009 Stephan Herrmann
+ *
+ * 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.objectteams;
+
+/**
+ * A lifting participant hooks into the lifting process.
+ *
+ * @author stephan
+ * @since 1.3.1
+ */
+public interface ILiftingParticipant {
+ /**
+ * This method is called when lifting does not find a suitable role within the
+ * team's internal role cache. If this method returns a non-null value,
+ * this value is considered by the runtime as being the desired role
+ * (i.e., it must be castable to that role type), and no new role is created.
+ * If this method returns null, lifting proceeds as normal, i.e.,
+ * a fresh role is created using the default lifting constructor.
+ *
+ * @param teamInstance
+ * @param baseInstance
+ * @param roleClassName
+ * @return either null or an instance of the class specified by roleClassName
+ */
+ Object createRole(ITeam teamInstance, Object baseInstance, String roleClassName);
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ITeam.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ITeam.java
new file mode 100644
index 000000000..ba6083c33
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ITeam.java
@@ -0,0 +1,219 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2010, 2012 Stephan Herrmann.
+ *
+ * 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.objectteams;
+
+/**
+ * Public interface of all team classes.
+ */
+public interface ITeam {
+
+ /**
+ * Interface for all role classes that should allow explicit lowering.
+ * The interface provides a phantom method <pre>&lt;B&gt; B lower()</pre>
+ * where B is the bound base class of the implementing role class.
+ * There is no need to implement the method lower, since this is done by the compiler.
+ */
+ public interface ILowerable {
+ // internal method needed for cast and instanceof
+ ITeam _OT$getTeam();
+ }
+
+ /**
+ * This role interface has no properties not even those of java.lang.Object.
+ */
+ public interface IConfined extends org.objectteams.IConfined {
+ // internal method needed for cast and instanceof
+ ITeam _OT$getTeam();
+ }
+
+
+ /**
+ * Activates the team and therefore all of its callin bindings.
+ * This activation applies to the current thread only.
+ */
+ public abstract void activate();
+
+ /**
+ * Deactivates the team and therefore all of its callin bindings.
+ * This deactivation applies to the current thread only.
+ */
+ public abstract void deactivate();
+
+ /**
+ * Activates the team and therefore all of its callin bindings for passed thread.
+ * If the constant 'Team.ALL_THREADS' is passed, this activation globally applies to all threads.
+ */
+ public abstract void activate(Thread thread);
+
+ /**
+ * Deactivates the team and therefore all of its callin bindings for passed thread.
+ * If the constant 'Team.ALL_THREADS' is passed, this deactivation globally applies to all threads.
+ */
+ public abstract void deactivate(Thread thread);
+
+ /**
+ * Checks, if the team instance is active for the current thread.
+ * @return true, if the team is active, false else.
+ */
+ public abstract boolean isActive();
+
+ /**
+ * Checks, if the team instance is active for the 'thread'.
+ * @param thread The thread for which to check activity.
+ * @return true, if the team is active for 'thread', false else.
+ */
+ public abstract boolean isActive(Thread thread);
+
+ /** NOT API */
+ public void _OT$implicitlyActivate();
+ /** NOT API */
+ public void _OT$implicitlyDeactivate();
+
+ /**
+ * Does given base object have a role in this team?
+ * This method will consider roles of any type.
+ *
+ * @param aBase any object, i.e., no checks are performed whether the base object's
+ * class is bound by any role class in this team.
+ * @return
+ */
+ public abstract boolean hasRole(Object aBase);
+
+ /**
+ * Does given base object have a role in this team?
+ * The role must be an instance of the specified role type.
+ *
+ * @param aBase any object, i.e., no checks are performed whether the base object's
+ * class is bound by any role class in this team.
+ * @param roleType Class instance specifying the required role type.
+ * TODO (SH): is it legal to pass an unbound role class?
+ * @throws IllegalArgumentException if <code>roleType</code> does not represent a member type of this team.
+ * @return
+ */
+ public abstract boolean hasRole(Object aBase, Class<?> roleType) throws IllegalArgumentException;
+
+ /**
+ * Retrieve a role for a given base object.
+ * If more than one role exists, a DuplicateRoleException is thrown.
+ *
+ * @param aBase
+ * @return
+ */
+ public abstract Object getRole(Object aBase);
+
+ /**
+ * Retrieve a role for a given base object.
+ * The role must be an instance of the specified role type.
+ *
+ * @param aBase any object, i.e., no checks are performed whether the base object's
+ * class is bound by any role class in this team.
+ * @param roleType Class instance specifying the required role type.
+ * @return
+ * @throws IllegalArgumentException if <code>roleType</code> does not represent a member type of this team.
+ */
+ public abstract <T> T getRole(Object aBase, Class<T> roleType) throws IllegalArgumentException;
+
+ /**
+ * Retrieve all bound roles registered in the current team.
+ *
+ * This method uses internal structures of weak references.
+ * For that reason it may return role instances which were about to be reclaimed
+ * by the garbage collector.
+ * If performance permits, it is thus advisable to always call System.gc()
+ * prior to calling getAllRoles() in order to achieve deterministic results
+ *
+ * @return a non-null array.
+ */
+ public abstract Object[] getAllRoles();
+
+ /**
+ * Retrieve all bound roles registered in the current team that
+ * are instance of roleType or a subtype thereof.
+ *
+ * This method uses internal structures of weak references.
+ * For that reason it may return role instances which were about to be reclaimed
+ * by the garbage collector.
+ * If performance permits, it is thus advisable to always call System.gc()
+ * prior to calling getAllRoles() in order to achieve deterministic results
+ *
+ * @param roleType must be a top-most bound role of this team.
+ * @return a non-null array.
+ * @throws IllegalArgumentException if <code>roleType</code> does not represent a member type of this team.
+ */
+ public abstract <T> T[] getAllRoles(Class<T> roleType) throws IllegalArgumentException;
+
+ /**
+ * Query whether any role instance of this team instance is currently executing a
+ * method due to a callin binding.
+ * @return
+ */
+ public abstract boolean isExecutingCallin();
+
+ /**
+ * Remove a role from the internal registry, which means that the role will no longer be
+ * considered during lifting.
+ *
+ * @param aRole
+ */
+ public abstract void unregisterRole(Object aRole);
+
+ /**
+ * Remove a role from the internal registry, which means that the role will no longer be
+ * considered during lifting.
+ *
+ * @param aRole
+ * @param roleType
+ * @throws IllegalArgumentException if <code>roleType</code> does not represent a member type of this team.
+ */
+ public abstract void unregisterRole(Object aRole, Class<?> roleType) throws IllegalArgumentException;
+
+ /**
+ * Not API.
+ * This method saves the activation state of the team for the current thread.
+ * If active, it also saves, if the activation was explicit or implicit.
+ * This method has to be called by the generated code when entering a within block,
+ * before the activation.
+ */
+ public int _OT$saveActivationState();
+
+ /**
+ * Not API.
+ * This method restores the former saved activation state of the team for the current thread.
+ * If active, it also restores, if the activation was explicit or implicit.
+ * This method has to be called by the generated code when leaving a within block
+ * (in the finally block).
+ */
+ public void _OT$restoreActivationState(int old_state);
+
+ /**
+ * Not API, for use by TeamThreadManager, only.
+ */
+ public boolean internalIsActiveSpecificallyFor(Thread t);
+
+ /**
+ * Not API, for use by TeamThreadManager, only.
+ */
+ public void deactivateForEndedThread(Thread thread);
+
+ /** NOT API */
+ public Object _OT$callAllBindings(IBoundBase baze, ITeam[] teams,int idx,int[] callinIds, int boundMethodId, Object[] args);
+
+ /** NOT API */
+ public Object _OT$callOrigStatic(int callinId, int boundMethodId, Object[] args);
+
+ /** NOT API */
+ public Object _OT$callNext(IBoundBase baze, ITeam[] teams, int idx, int[] callinIds, int boundMethodId, Object[] args, Object[] baseCallArgs);
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ITeamMigratable.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ITeamMigratable.java
new file mode 100644
index 000000000..e14750edb
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ITeamMigratable.java
@@ -0,0 +1,35 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2008, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Marker interface: if a role declares to implement this interface
+ * the compiler will generate the method defined herein, and prepare
+ * the role so that the migration will indeed be possible.
+ * Note, that a migratable role does not obey the family guarantee.
+ *
+ * @author stephan
+ * @since 1.2.5
+ */
+public interface ITeamMigratable {
+ /**
+ * Migrate the current role to the otherTeam.
+ *
+ * @param otherTeam new team that should adopt this role
+ * @return the migrated (and re-typed) role (actually of type R<@otherTeam>). FIXME(SH)
+ */
+ <R> R migrateToTeam(final ITeam otherTeam);
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IllegalRoleCreationException.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IllegalRoleCreationException.java
new file mode 100644
index 000000000..08422684b
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/IllegalRoleCreationException.java
@@ -0,0 +1,34 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2007, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * Exception to be thrown when a bound role is being instantiated but
+ * the constructor does not assign a base object.
+ *
+ * @author stephan
+ */
+@SuppressWarnings("serial")
+public class IllegalRoleCreationException extends RuntimeException {
+ public IllegalRoleCreationException() {
+ super();
+ }
+
+ @Override
+ public String getMessage() {
+ return "Cannot instantiate a bound role using a default constructor of its tsuper class";
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ImplicitTeamActivation.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ImplicitTeamActivation.java
new file mode 100644
index 000000000..0415e4dae
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ImplicitTeamActivation.java
@@ -0,0 +1,44 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2009 Stephan Herrmann
+ *
+ * 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.objectteams;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This marker annotation enables implicit team activation for the annotated element:
+ * <ul>
+ * <li>If attached to a method the effect is that each call to this method implicitly
+ * activates the enclosing team.</li>
+ * <li>If attached to a class it has the same effect as annotating all contained methods.</li>
+ * </ul>
+ * See <a href="http://www.objectteams.org/def/1.3/s5.html#s5.3">OTJLD ยง 5.3</a>.
+ * <p>
+ * This annotation is only evaluated if the property <code>ot.implicit.team.activation</code>
+ * is set to the string <code>ANNOTATED</code>.
+ * </p>
+ * @author stephan
+ * @since 1.4.0
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface ImplicitTeamActivation {
+ /* no members, pure marker annotation. */
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/Instantiation.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/Instantiation.java
new file mode 100644
index 000000000..4392adc86
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/Instantiation.java
@@ -0,0 +1,36 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2011 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.objectteams;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation influences the semantics of lifting in OT/J.
+ * See {@link InstantiationPolicy} for possible values and their effects.
+ * This annotation is valid only when applied to a role type.
+ *
+ * @author stephan
+ */
+@Documented
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+public @interface Instantiation {
+ InstantiationPolicy value();
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/InstantiationPolicy.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/InstantiationPolicy.java
new file mode 100644
index 000000000..9cc189e34
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/InstantiationPolicy.java
@@ -0,0 +1,56 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2011 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.objectteams;
+
+/**
+ * Possible values for the {@link Instantiation} annotation for role types:
+ * {@link #NEVER}, {@link #ONDEMAND} (default), {@link #SINGLETON} and {@link #ALWAYS}.
+ *
+ * @author stephan
+ */
+public enum InstantiationPolicy {
+ /**
+ * Roles with the instantiation policy NEVER are not instantiated by lifting.
+ * Such roles cannot have state.
+ * The compiler still has to ensure that access to base instances still behaves
+ * as if a role instance would exist.
+ * Note: this is not yet supported by the OT/J compiler.
+ */
+ NEVER,
+ /**
+ * The constant ONDEMAND corresponds to the default behavior in OT/J
+ * where lifting will create a role for a given base instance upon first access,
+ * i.e., if no matching role is found in the team's internal cache.
+ * Otherwise the existing role from the cache is re-used.
+ */
+ ONDEMAND,
+ /**
+ * For a role with instantiation policy SINGLETON at most one instance per team
+ * will be created by lifting. Subsequent lifting operations will always return
+ * the same role instance.
+ * The compiler still has to ensure that access to base instances still behaves
+ * as if a role instance would exist.
+ * Note: this is not yet supported by the OT/J compiler.
+ */
+ SINGLETON,
+ /**
+ * The instantiation policy ALWAYS advises the compiler to omit generating an
+ * internal cache for the given role type. Instead of first consulting the
+ * cache (as it is done in the default ONDEMAND policy) each lifting operation
+ * creates a new role instance.
+ */
+ ALWAYS;
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/LiftingFailedException.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/LiftingFailedException.java
new file mode 100644
index 000000000..cc771056f
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/LiftingFailedException.java
@@ -0,0 +1,46 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2003, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * This exception signals that lifting failed due to unresolved
+ * binding ambiguity.
+ */
+public class LiftingFailedException extends Exception {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private Object base;
+ private String roleType;
+
+ /**
+ * @param base the object that should be lifted
+ * @param roleType the name of the role type for which
+ * lifting was attempted.
+ */
+ public LiftingFailedException(Object base, String roleType) {
+ this.base = base;
+ this.roleType = roleType;
+ }
+
+ @Override
+ public String getMessage() {
+ return "\nFailed to lift '" + base + "' of " + base.getClass()
+ + " to type '" + roleType
+ + "'\n(See OT/J definition para. 2.3.4(c)).";
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/LiftingVetoException.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/LiftingVetoException.java
new file mode 100644
index 000000000..2d1315df6
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/LiftingVetoException.java
@@ -0,0 +1,45 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2003, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * This exception is used by the language implementation
+ * to signal a failed lifting due to a guard predicate that evaluated to false.
+ * @author Stephan Herrmann
+ */
+public class LiftingVetoException extends RuntimeException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ ITeam aTeam = null;
+ Object base = null;
+
+ public LiftingVetoException(ITeam aTeam, Object base) {
+ this.aTeam = aTeam;
+ this.base = base;
+ }
+
+ public LiftingVetoException() {
+ super("");
+ }
+
+ @Override
+ public String toString() {
+ return "Team " + aTeam + " refuses to lift " + base
+ + "\n(this exception should not be seen in applications).";
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/NoSuchMethodError.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/NoSuchMethodError.java
new file mode 100644
index 000000000..fbc2800b9
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/NoSuchMethodError.java
@@ -0,0 +1,30 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2011 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.objectteams;
+
+/**
+ * This error is thrown when some generated code falls through a switch
+ * without finding a requested target method.
+ *
+ * @author stephan
+ */
+public class NoSuchMethodError extends java.lang.NoSuchMethodError {
+ private static final long serialVersionUID = 8166812526610195056L;
+
+ public NoSuchMethodError(int accessId, String className, String accessReason) {
+ super("Method with internal id "+accessId+" cannot be found in "+className+" for "+accessReason);
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ResultNotProvidedException.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ResultNotProvidedException.java
new file mode 100644
index 000000000..b36870d63
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/ResultNotProvidedException.java
@@ -0,0 +1,60 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2004, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * @author resix
+ */
+public class ResultNotProvidedException extends RuntimeException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private static final String _bugmsg =
+ "\nNo base call executed! Result value was uninitialized!\n(see OT/J language definition para. 4.3(e)).";
+
+ /**
+ *
+ */
+ public ResultNotProvidedException() {
+ super(_bugmsg);
+ }
+
+ /**
+ * @param message
+ */
+ public ResultNotProvidedException(String message) {
+ super(_bugmsg + "\n" + message);
+ StackTraceElement[] ste = new StackTraceElement[0];
+ setStackTrace(ste);
+ }
+
+ /**
+ * @param cause
+ */
+ public ResultNotProvidedException(Throwable cause) {
+ super(_bugmsg + cause.toString());
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public ResultNotProvidedException(String message, Throwable cause) {
+ super(_bugmsg + message/* +cause.toString() */);
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/RoleCastException.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/RoleCastException.java
new file mode 100644
index 000000000..da0338554
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/RoleCastException.java
@@ -0,0 +1,39 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2004, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * This exception is thrown if a cast to a role class fails due to
+ * different enclosing team instances.
+ * @author Stephan Herrmann
+ */
+public class RoleCastException extends ClassCastException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private static final String MSG =
+ "Different enclosing team instances (see OT/J language definition para. 1.2.4(b)).";
+
+ /* (non-Javadoc)
+ * @see java.lang.Throwable#getMessage()
+ */
+ @Override
+ public String getMessage() {
+ return MSG;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/SneakyException.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/SneakyException.java
new file mode 100644
index 000000000..28fad1a44
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/SneakyException.java
@@ -0,0 +1,61 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2012 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.objectteams;
+
+import java.io.PrintStream;
+
+/**
+ * Exception class used for tunneling checked exception through generic dispatch
+ * code without matching throws declaration.
+ *
+ * An original exception raised in a role method is wrapped during any of
+ * <code>_OT$callReplace</code>, <code>_OT$callBefore</code> and <code>_OT$callAfter</code>
+ * and unwrapped in the initial wrapper of any base method.
+ *
+ * Note that the opposite direction needs no wrapping: exceptions raised in
+ * the base method are thrown as normal, because this happens inside _OT$callOrig
+ * of the base class, which is created dynamically by OTREDyn and never checked
+ * by any compiler.
+ */
+@SuppressWarnings("serial")
+public class SneakyException extends RuntimeException {
+ private Exception cause;
+
+ /** Wrap a given exception in an unchecked SneakyException. */
+ public SneakyException(Exception cause) {
+ this.cause = cause;
+ }
+
+ /** Re-throw the nested exception but hide it from the compiler. */
+ public void rethrow() {
+ SneakyException.<RuntimeException>sneakyThrow0(this.cause);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T extends Exception> void sneakyThrow0(Exception t) throws T {
+ throw (T)t;
+ }
+
+ @Override
+ public String getMessage() {
+ return this.cause.getMessage();
+ }
+
+ @Override
+ public void printStackTrace(PrintStream s) {
+ this.cause.printStackTrace(s);
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/SoftLiftingFailedException.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/SoftLiftingFailedException.java
new file mode 100644
index 000000000..0458cc7b6
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/SoftLiftingFailedException.java
@@ -0,0 +1,48 @@
+/**********************************************************************
+ * This file is part of the "Object Teams Runtime Environment"
+ *
+ * Copyright 2011 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.objectteams;
+
+/**
+ * This exception signals that lifting failed due to unresolved
+ * binding ambiguity. This variant is used when static analysis
+ * could not find reason for such failure just in case the class
+ * files have changed since.
+ */
+public class SoftLiftingFailedException extends RuntimeException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private Object base;
+ private String roleType;
+
+ /**
+ * @param base the object that should be lifted
+ * @param roleType the name of the role type for which
+ * lifting was attempted.
+ */
+ public SoftLiftingFailedException(Object base, String roleType) {
+ this.base = base;
+ this.roleType = roleType;
+ }
+
+ @Override
+ public String getMessage() {
+ return "\nFailed to lift '" + base + "' of " + base.getClass()
+ + " to type '" + roleType
+ + "'\nPerhaps some class files have changed since the enclosing team has been compiler? (See OT/J definition para. 2.3.4(c)).";
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/TeamThreadManager.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/TeamThreadManager.java
new file mode 100644
index 000000000..e6bc9db92
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/TeamThreadManager.java
@@ -0,0 +1,121 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2006-2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+import java.util.HashSet;
+import java.util.WeakHashMap;
+
+
+/**
+ * This class is for internal use, only.
+ *
+ * Maintain information about existing threads as to manage
+ * team activation per thread vs. globally.
+ *
+ * @author Chistine Hundt
+ * @author Stephan Herrmann
+ */
+public class TeamThreadManager {
+
+ private static Object token = new Object();
+
+ private static HashSet<ITeam> globalActiveTeams = new HashSet<ITeam>();
+ private static WeakHashMap<ITeam,Object> teamsWithActivationInheritance = new WeakHashMap<ITeam,Object>();
+ private static HashSet<Thread> existingThreads = new HashSet<Thread>();
+
+ public static boolean newThreadStarted(boolean isMain, Thread parent) {
+ Thread currentThread = Thread.currentThread();
+ // already registered?
+ if (existingThreads.contains(currentThread))
+ return false;
+ // workaround for application hang on Mac OS with Apple JVM:
+ if (System.getProperty("os.name").startsWith("Mac"))
+ if (currentThread.getName().equals("AWT-Shutdown"))
+ return false;
+
+ ITeam[] globalTeams;
+ ITeam[] inheritableTeams;
+ synchronized (TeamThreadManager.class) {
+ boolean isFirst = existingThreads.isEmpty();
+ existingThreads.add(currentThread);
+ if (isMain || isFirst) {
+ for (Thread thread : fetchSystemThreads(currentThread))
+ if (thread != null)
+ existingThreads.add(thread);
+ }
+
+ globalTeams = globalActiveTeams.toArray(new ITeam[globalActiveTeams.size()]);
+ inheritableTeams = teamsWithActivationInheritance.keySet().toArray(new ITeam[teamsWithActivationInheritance.size()]);
+ }
+ // activate teams outside synchronized block:
+ for (ITeam t : globalTeams)
+ t.activate(currentThread); // small version? global -> already registered...!
+ if (parent != null)
+ for (ITeam t : inheritableTeams)
+ if (t.internalIsActiveSpecificallyFor(parent))
+ t.activate(currentThread); // pass activation from parent to child thread
+ return true;
+ }
+
+ /* Fetch all existing threads existing at this point in time. Result array is padded with nulls. */
+ private static Thread[] fetchSystemThreads(Thread currentThread) {
+ ThreadGroup group = currentThread.getThreadGroup();
+ {
+ ThreadGroup parentGroup;
+ while ((parentGroup= group.getParent()) != null)
+ group = parentGroup;
+ }
+ int size = group.activeCount();
+ Thread[] allThreads;
+ do {
+ size += 2;
+ allThreads = new Thread[size];
+ } while (group.enumerate(allThreads) == size);
+ return allThreads;
+ }
+
+ public static void threadEnded() {
+ ITeam[] teamsToDeactivate = internalThreadEnded();
+ // + remove per thread activation:
+ for (ITeam t : teamsToDeactivate)
+ //t.deactivate(Thread.currentThread()); // small version?
+ t.deactivateForEndedThread(Thread.currentThread());
+ }
+ private synchronized static ITeam[] internalThreadEnded() {
+ existingThreads.remove(Thread.currentThread());
+ // fetch all global active teams for deactivation:
+ return globalActiveTeams.toArray(new ITeam[globalActiveTeams.size()]);
+ }
+
+ public synchronized static void addGlobalActiveTeam(ITeam t) {
+ globalActiveTeams.add(t);
+ }
+
+ public synchronized static void removeGlobalActiveTeam(ITeam t) {
+ globalActiveTeams.remove(t);
+ }
+
+ public static HashSet<Thread> getExistingThreads() {
+ return existingThreads;
+ }
+ public static void registerTeamForActivationInheritance(ITeam aTeam) {
+ teamsWithActivationInheritance.put(aTeam,token);
+ }
+ public static void unRegisterTeamForActivationInheritance(ITeam aTeam) {
+ teamsWithActivationInheritance.remove(aTeam);
+ }
+
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/UnsupportedFeatureException.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/UnsupportedFeatureException.java
new file mode 100644
index 000000000..24dd1bf01
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/UnsupportedFeatureException.java
@@ -0,0 +1,59 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2004, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * @author resix
+ */
+public class UnsupportedFeatureException extends RuntimeException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private static final String _bugmsg = "\nThe program encountered an unsupported situation! ";
+
+ /**
+ *
+ */
+ public UnsupportedFeatureException() {
+ super(_bugmsg);
+ }
+
+ /**
+ * @param message
+ */
+ public UnsupportedFeatureException(String message) {
+ super(_bugmsg + "\n" + message);
+ StackTraceElement[] ste = new StackTraceElement[0];
+ setStackTrace(ste);
+ }
+
+ /**
+ * @param cause
+ */
+ public UnsupportedFeatureException(Throwable cause) {
+ super(_bugmsg + cause.toString());
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public UnsupportedFeatureException(String message, Throwable cause) {
+ super(_bugmsg + message/*+cause.toString()*/);
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/WrongRoleException.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/WrongRoleException.java
new file mode 100644
index 000000000..467c4a043
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/WrongRoleException.java
@@ -0,0 +1,57 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2003, 2010 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
+ * 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:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+/**
+ * This exception is thrown by the OT/J infra structure if a role for a given base object
+ * was requested during lifting, but a role with an incompatible type was already
+ * registered for that base object. Can only happen if a compile time warning occurred.
+ * @author Stephan Herrmann
+ */
+public class WrongRoleException extends RuntimeException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private Class<?> clazz;
+ private Object base;
+ private Object role;
+
+ /**
+ * @param clazz
+ * @param base
+ * @param role
+ */
+ public WrongRoleException (Class<?> clazz, Object base, Object role) {
+ this.clazz = clazz;
+ this.base = base;
+ this.role = role;
+ }
+
+ @Override
+ public String getMessage() {
+ String baseClazz = base.getClass().getName();
+ String roleClazz = role.getClass().getName();
+ return "The compiler has warned you about ambiguous role bindings.\n"
+ + "Now lifting to " + clazz
+ + " fails with the following objects\n"
+ + "(see OT/J language definition para. 2.3.4(d)):\n"
+ + "Provided:\n Base object: " + base + "\n" + " Base type: "
+ + baseClazz + "\n"
+ + "Found in cache:\n Role object: " + role + "\n"
+ + " Role type: " + roleClazz;
+ }
+}

Back to the top