Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2013-04-25 11:30:30 +0000
committerStephan Herrmann2013-04-25 11:30:30 +0000
commit5a7ecb34d166516d548f8a32b0a82ebb020b7a6b (patch)
tree0e94fc24d0908957b5cfab8873bc0e7bf3c277cd
parent81fd5dcf044c587591d9d354a058919526bb15bb (diff)
downloadorg.eclipse.objectteams-5a7ecb34d166516d548f8a32b0a82ebb020b7a6b.tar.gz
org.eclipse.objectteams-5a7ecb34d166516d548f8a32b0a82ebb020b7a6b.tar.xz
org.eclipse.objectteams-5a7ecb34d166516d548f8a32b0a82ebb020b7a6b.zip
Bug 406518 - migrate OT/Equinox to the standard OSGi WeavingHook
- initial draft implementation
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/.classpath7
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/.project28
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/.settings/org.eclipse.jdt.core.prefs100
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF12
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/build.properties6
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/plugin.xml7
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindingNegotiators.exsd145
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindings.exsd279
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/schema/liftingParticipant.exsd133
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java100
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java348
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleActivation.java174
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/ClassScanner.java143
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java68
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/ActivationKind.java31
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java126
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Constants.java62
17 files changed, 1769 insertions, 0 deletions
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/.classpath b/plugins/org.eclipse.objectteams.osgi.weaving/.classpath
new file mode 100644
index 000000000..098194ca4
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/.project b/plugins/org.eclipse.objectteams.osgi.weaving/.project
new file mode 100644
index 000000000..028edf216
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.objectteams.osgi.weaving</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.objectteams.osgi.weaving/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..2e0f7166e
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,100 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.objectteams.otdt.compiler.option.pure_java=enabled
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..9abb55569
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: OT/J Weaving for OSGi
+Bundle-SymbolicName: org.eclipse.objectteams.osgi.weaving;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.objectteams.osgi.weaving.Activator
+Bundle-Vendor: Eclipse.org - Object Teams
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.objectteams.runtime;bundle-version="2.1.0",
+ org.eclipse.osgi
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/build.properties b/plugins/org.eclipse.objectteams.osgi.weaving/build.properties
new file mode 100644
index 000000000..6ac8fd16c
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
+additional.bundles=org.eclipse.jdt.annotation
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/plugin.xml b/plugins/org.eclipse.objectteams.osgi.weaving/plugin.xml
new file mode 100644
index 000000000..0be0f5793
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/plugin.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+ <extension-point id="aspectBindings" name="OT/J Aspect Bindings" schema="schema/aspectBindings.exsd"/>
+ <extension-point id="aspectBindingNegotiators" name="OT/Equinox negotiators for aspect binding requests" schema="schema/aspectBindingNegotiators.exsd"/>
+ <extension-point id="liftingParticipant" name="OT/J Lifting Participant" schema="schema/liftingParticipant.exsd"/>
+</plugin>
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindingNegotiators.exsd b/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindingNegotiators.exsd
new file mode 100644
index 000000000..9d5418813
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindingNegotiators.exsd
@@ -0,0 +1,145 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.objectteams.otequinox" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.objectteams.otequinox" id="aspectBindingNegotiators" name="OT/Equinox negotiators for aspect binding requests"/>
+ </appInfo>
+ <documentation>
+ Allow client plugins to participate in negotiation whether aspect binding requests
+(incl. forced exports) should be denied or granted.
+&lt;p&gt;
+All extensions will be asked whenever an aspect plugin requests an aspect binding
+or a forced export for which no permission could be found in persistent storage
+of neither the eclipse installation nor the workspace.
+&lt;ul&gt;
+&lt;li&gt;As soon as any extension DENYs a given request this aspect plugin is blocked.&lt;/li&gt;
+&lt;li&gt;If no extension GRANTs the request the aspect plugin is blocked, too.&lt;/li&gt;
+&lt;li&gt;Only if at least one extension GRANTs the request and no extension DENYs
+the aspect may proceed and will be woven into its base entities.&lt;/li&gt;
+&lt;/ul&gt;
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="negotiator" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="negotiator">
+ <annotation>
+ <documentation>
+ A participant in the protocol for aspect binding negotiation,
+which is able to grant or deny a request by an aspect bundle.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ Fully qualified name of the class that shall participate in the negotiation protocol.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.objectteams.otequinox.IAspectRequestNegotiator"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ OTDT 1.2.6
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ Example of a declaration of a &lt;code&gt;negotiator&lt;/code&gt;:&lt;pre&gt;
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;?eclipse version=&quot;3.2&quot;?&gt;
+&lt;plugin&gt;
+ &lt;extension
+ point=&quot;org.eclipse.objectteams.otequinox.aspectBindingNegotiators&quot;&gt;
+ &lt;negotiator
+ class=&quot;yesser.AspectRequestGranter&quot;&gt;
+ &lt;/negotiator&gt;
+ &lt;/extension&gt;
+&lt;/plugin&gt;
+&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ The class named in the &lt;code&gt;class&lt;/code&gt; property must implement the &lt;code&gt;org.eclipse.objectteams.otequinox.IAspectRequestNegotiator&lt;/code&gt; interface.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ &lt;em&gt;
+&lt;p&gt;
+This file is part of &quot;Object Teams Development Tooling&quot;-Software
+&lt;/p&gt;&lt;p&gt;
+Copyright 2009 Technical University Berlin, 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
+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+&lt;/p&gt;&lt;p&gt;
+Please visit &lt;a href=&quot;http://www.objectteams.org&quot;&gt;www.objectteams.org&lt;/a&gt; for updates and contact.
+&lt;/p&gt;&lt;p&gt;
+Contributors:&lt;br&gt;
+Technical University Berlin - Initial API and implementation
+&lt;/p&gt;
+&lt;/em&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindings.exsd b/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindings.exsd
new file mode 100644
index 000000000..7ed4fb7fe
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/schema/aspectBindings.exsd
@@ -0,0 +1,279 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.objectteams.otequinox" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.objectteams.otequinox" id="aspectBindings" name="OT/J Aspect Bindings"/>
+ </appInfo>
+ <documentation>
+ This extension point allows to define a new &lt;strong&gt;relationship&lt;/strong&gt; between plug-ins
+called &lt;strong&gt;&quot;aspectBinding&quot;&lt;/strong&gt;.
+By an aspectBinding an aspect plug-in declares which &lt;strong&gt;base plug-ins&lt;/strong&gt; it wishes to adapt
+and which &lt;strong&gt;team classes&lt;/strong&gt; are used for that purpose.
+Only teams in this list are allowed to adapt classes from another plug-in, and such
+adaptation is restricted to classes residing in the specified base plug-in.
+
+Each team class mentioned in an aspectBinding is automatically &lt;strong&gt;instantiated&lt;/strong&gt;
+before the corresponding base plug-in is fully activated.
+In addition extensions may specify that a given team is also &lt;strong&gt;activated&lt;/strong&gt;
+after instantiation.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="aspectBinding" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="aspectBinding">
+ <annotation>
+ <appInfo>
+ <meta.element icon="icon"/>
+ </appInfo>
+ <documentation>
+ Specifies an individual aspect binding by which a given team class adapts classes from a given base plugin.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="basePlugin"/>
+ <element ref="team" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="icon" type="string" use="default" value="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/calloutbinding_obj.gif">
+ <annotation>
+ <documentation>
+ &lt;i&gt;Default value to provide an icon for this element kind. No need to edit&lt;/i&gt;
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="basePlugin">
+ <annotation>
+ <appInfo>
+ <meta.element icon="icon"/>
+ </appInfo>
+ <documentation>
+ &lt;p&gt;
+The base plug-in whose classes may be adapted by the given team(s).
+The base bundle must be a regular bundle, not a fragment.
+If a bundle &lt;b&gt;fragment&lt;/b&gt; should be adapted the aspect binding must refer to the fragment&apos;s host bundle
+and additionally a &lt;code&gt;requiredFragment&lt;/code&gt; should be added.
+&lt;/p&gt;
+&lt;p&gt;
+By specifying &lt;code&gt;SELF&lt;/code&gt; as the basePlugin, a team may adapt classes from its own bundle.
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="forcedExports" minOccurs="0" maxOccurs="1"/>
+ <element ref="requiredFragment" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ Qualified identifier of the base plug-in.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string" use="default" value="platform:/plugin/org.eclipse.pde.ui/icons/obj16/plugin_obj.gif">
+ <annotation>
+ <documentation>
+ &lt;i&gt;Default value to provide an icon for this element kind. No need to edit&lt;/i&gt;
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="team">
+ <annotation>
+ <appInfo>
+ <meta.element labelAttribute="class" icon="icon"/>
+ </appInfo>
+ <documentation>
+ The team class of this plug-in which is allowed to adapt classes of the given base plug-in.&lt;br/&gt;
+If a nested team shall be used it can be specified using either its source name (using &apos;.&apos; as the separator) or its binary name (using a &apos;$&apos; separator).
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ Fully qualified name of a team class.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.objectteams.ITeam"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="superclass" type="string">
+ <annotation>
+ <documentation>
+ Fully qualified name of the team&apos;s super-class if that is not org.objectteams.Team but another team of the same plugin.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.objectteams.ITeam"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="activation">
+ <annotation>
+ <documentation>
+ Request activation of this team class:
+NONE: don&apos;t automatically activate (default)
+THREAD: activate for one thread (discouraged)
+ALL_THREADS: activate for all threads
+ </documentation>
+ </annotation>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="NONE">
+ </enumeration>
+ <enumeration value="THREAD">
+ </enumeration>
+ <enumeration value="ALL_THREADS">
+ </enumeration>
+ </restriction>
+ </simpleType>
+ </attribute>
+ <attribute name="icon" type="string" use="default" value="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+ <annotation>
+ <documentation>
+ &lt;i&gt;Default value to provide an icon for this element kind. No need to edit&lt;/i&gt;
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="forcedExports" type="string">
+ <annotation>
+ <documentation>
+ Declare any requests to access packages from the base plugin which are not exported.
+Provide comma separated list of package names (as in the OSGi Export-Package: header).
+ </documentation>
+ </annotation>
+ </element>
+
+ <element name="requiredFragment">
+ <annotation>
+ <documentation>
+ Name of a fragment of the base bundle that is required by the aspect.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ Symbolic name of the fragment.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ OTDT 0.9.1 based on Eclipse 3.2.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ See example plugin org.eclipse.objectteams.otequinox.branding.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ The &lt;code&gt;class&lt;/code&gt; named in the class property must be a team class thus implementing the &lt;code&gt;org.objectteams.ITeam&lt;/code&gt; interface.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ None.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ &lt;em&gt;
+&lt;p&gt;
+This file is part of &quot;Object Teams Development Tooling&quot;-Software
+&lt;/p&gt;&lt;p&gt;
+Copyright 2006, 2010 Technical University Berlin, 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
+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+&lt;/p&gt;&lt;p&gt;
+Please visit &lt;a href=&quot;http://www.objectteams.org&quot;&gt;www.objectteams.org&lt;/a&gt; for updates and contact.
+&lt;/p&gt;&lt;p&gt;
+Contributors:&lt;br&gt;
+Technical University Berlin - Initial API and implementation
+&lt;/p&gt;
+&lt;/em&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/schema/liftingParticipant.exsd b/plugins/org.eclipse.objectteams.osgi.weaving/schema/liftingParticipant.exsd
new file mode 100644
index 000000000..b41e21a65
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/schema/liftingParticipant.exsd
@@ -0,0 +1,133 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.objectteams.otequinox" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.objectteams.otequinox" id="liftingParticipant" name="OT/J Lifting Participant"/>
+ </appInfo>
+ <documentation>
+ Allow a client plug-in to install a lifting participant in order to hook into the OT/J lifting process.
+This can be used to avoid default on-demand role creation, such that an application specific strategy
+can be used for creating and initializing role objects on behalf of the lifting operation.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="liftingParticipant"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="liftingParticipant">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ Fully qualified name of a class implementing &lt;code&gt;org.objectteams.ILiftingParticipant&lt;/code&gt;
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.objectteams.ILiftingParticipant"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ OTDT 0.7.0 (from Eclipse.org) based on Eclipse 3.6.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ The concept of &quot;lifting participants&quot; was initially requested for the OT/JPA integration
+where roles may need to be retrieved from persistent storage instead of the default on-demand creation.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ The &lt;code&gt;class&lt;/code&gt; named in the class property must implement the &lt;code&gt;org.objectteams.ILiftingParticipant&lt;/code&gt; interface
+of the Object Teams Runtime Environment.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ None.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ &lt;em&gt;
+&lt;p&gt;
+This file is part of &quot;Object Teams Development Tooling&quot;-Software
+&lt;/p&gt;
+&lt;p&gt;
+Copyright 2010 Fraunhofer Gesellschaft, Munich, Germany,
+for its Fraunhofer Institute for Computer Architecture and Software Technology (FIRST), Berlin, 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
+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+&lt;/p&gt;
+&lt;p&gt;
+Please visit &lt;a href=&quot;http://www.eclipse.org/objectteams&quot;&gt;www.eclipse.org/objectteams&lt;/a&gt; for updates and contact.
+&lt;/p&gt;
+&lt;p&gt;
+Contributors:&lt;br&gt;
+Fraunhofer FIRST - Initial API and implementation
+&lt;/p&gt;
+&lt;/em&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java
new file mode 100644
index 000000000..9836ec337
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java
@@ -0,0 +1,100 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2009 Germany and Technical University Berlin, 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:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.objectteams.osgi.weaving.ActivationKind;
+
+/**
+ * A simple record representing the information read from an extension to org.eclipse.objectteams.otequinox.aspectBindings.
+ * @author stephan
+ * @since 1.3.0 (was a nested class before that)
+ */
+public class AspectBinding {
+ public String aspectPlugin;
+ public String basePlugin;
+ public IConfigurationElement[] forcedExports;
+ public ActivationKind[] activations = null;
+ public String[] teamClasses;
+ public List<String>[] subTeamClasses;
+ public boolean activated= false; // FIXME: consistently set?
+ private HashMap<String, Set<String>> teamsPerBase = new HashMap<>();
+
+ public AspectBinding(String aspectId, String baseId, IConfigurationElement[] forcedExportsConfs) {
+ this.aspectPlugin= aspectId;
+ this.basePlugin= baseId;
+ this.forcedExports= forcedExportsConfs;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void initTeams(int count) {
+ this.teamClasses = new String[count];
+ this.subTeamClasses = new List[count]; // new List<String>[count] is illegal!
+ this.activations = new ActivationKind[count];
+ }
+
+ public void setActivation(int i, String specifier) {
+ if (specifier == null)
+ this.activations[i] = ActivationKind.NONE;
+ else
+ this.activations[i] = ActivationKind.valueOf(specifier);
+ }
+ public String toString() {
+ String result = "\tbase plugin "+basePlugin+"\n\tadapted by aspect pluging "+aspectPlugin;
+ for (String teamClass : teamClasses) {
+ result += "\n\t\t + team "+teamClass;
+ }
+ return result;
+ }
+
+ public List<String> getAllTeams() {
+ List<String> all = Arrays.asList(this.teamClasses);
+ if (subTeamClasses != null)
+ for (int i = 0; i < subTeamClasses.length; i++)
+ if (subTeamClasses[i] != null)
+ all.addAll(subTeamClasses[i]);
+ return all;
+ }
+
+ public void addBaseClassNames(String teamName, Collection<String> baseClassNames) {
+ for (String baseClassName : baseClassNames) {
+ Set<String> teams = teamsPerBase.get(baseClassName);
+ if (teams == null)
+ teamsPerBase.put(baseClassName, teams = new HashSet<>());
+ teams.add(teamName);
+ }
+ }
+
+ /** Destructively read the names of teams to load for a given base class. */
+ public Collection<String> getTeamsForBase(String baseClassName) {
+ return teamsPerBase.remove(baseClassName);
+ }
+
+ public ActivationKind getActivation(String teamClassName) {
+ for (int i=0; i<teamClasses.length; i++) {
+ if (teamClasses[i].equals(teamClassName))
+ return activations[i];
+ }
+ return ActivationKind.NONE;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java
new file mode 100644
index 000000000..bc366f90c
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java
@@ -0,0 +1,348 @@
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.osgi.weaving.Activator.log;
+import static org.eclipse.objectteams.osgi.weaving.Constants.ACTIVATION;
+import static org.eclipse.objectteams.osgi.weaving.Constants.ASPECT_BINDING_EXTPOINT_ID;
+import static org.eclipse.objectteams.osgi.weaving.Constants.BASE_PLUGIN;
+import static org.eclipse.objectteams.osgi.weaving.Constants.CLASS;
+import static org.eclipse.objectteams.osgi.weaving.Constants.ID;
+import static org.eclipse.objectteams.osgi.weaving.Constants.SELF;
+import static org.eclipse.objectteams.osgi.weaving.Constants.SUPERCLASS;
+import static org.eclipse.objectteams.osgi.weaving.Constants.TEAM;
+import static org.eclipse.objectteams.osgi.weaving.Constants.TRANSFORMER_PLUGIN_ID;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.RegistryFactory;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.objectteams.osgi.weaving.Constants;
+import org.eclipse.objectteams.otequinox.hook.IAspectRegistry;
+import org.eclipse.objectteams.otequinox.hook.ILogger;
+import org.objectteams.ITeam;
+import org.osgi.framework.Bundle;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+@NonNullByDefault
+public class AspectBindingRegistry {
+
+ private static List<String> KNOWN_OTDT_ASPECTS = new ArrayList<String>();
+ static {
+ KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.jdt.ui");
+ KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.compiler.adaptor");
+ KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.refactoring");
+ KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.pde.ui");
+ KNOWN_OTDT_ASPECTS.add("org.eclipse.objectteams.otdt.samples");
+ }
+ /** main internal registry of aspect bindings. */
+ private static HashMap<String, ArrayList<AspectBinding>> aspectBindingsByBasePlugin =
+ new HashMap<String, ArrayList<AspectBinding>>();
+ private static HashMap<String, ArrayList<AspectBinding>> aspectBindingsByAspectPlugin =
+ new HashMap<String, ArrayList<AspectBinding>>();
+ // map base bundle name to list of adapted base class names
+ private static HashMap<String, ArrayList<String>> adaptedBaseClassNames =
+ new HashMap<String, ArrayList<String>>();
+ // set of aspect plug-ins which have internal teams:
+ private Set<String> selfAdaptingAspects= new HashSet<String>();
+
+ private HashMap<String, BaseBundleActivation> baseTripWires = new HashMap<>();
+
+ static class WaitingTeamRecord {
+ @Nullable Class<? extends ITeam> teamClass;
+ @Nullable ITeam teamInstance;
+ AspectBinding aspectBinding;
+ String notFoundClass;
+
+ public WaitingTeamRecord(Class<? extends ITeam> teamClass, AspectBinding aspectBinding, String notFoundClass) {
+ this.teamClass = teamClass;
+ this.aspectBinding = aspectBinding;
+ this.notFoundClass = notFoundClass;
+ }
+ public WaitingTeamRecord(ITeam teamInstance, AspectBinding aspectBinding, String notFoundClass) {
+ this.teamInstance = teamInstance;
+ this.aspectBinding = aspectBinding;
+ this.notFoundClass = notFoundClass;
+ }
+ public WaitingTeamRecord(WaitingTeamRecord record, String notFoundClass) {
+ this.teamClass = record.teamClass;
+ this.teamInstance = record.teamInstance;
+ this.aspectBinding = record.aspectBinding;
+ this.notFoundClass = notFoundClass;
+ }
+ public @Nullable String getTeamName() {
+ final Class<? extends ITeam> clazz = teamClass;
+ if (clazz != null) {
+ return clazz.getName();
+ } else {
+ final ITeam instance = teamInstance;
+ if (instance != null)
+ return instance.getClass().getName();
+ }
+ return "<unknown team>";
+ }
+ }
+ // records of teams that have been deferred due to unresolved class dependencies:
+ private List<WaitingTeamRecord> deferredTeams = new ArrayList<>();
+ // records of teams whose class dependencies should/could be unblocked by now:
+ private List<WaitingTeamRecord> scheduledTeams = new ArrayList<>();
+
+ public static boolean IS_OTDT = false;
+
+ public boolean isOTDT() {
+ return IS_OTDT;
+ }
+
+ /* Load extensions for org.eclipse.objectteams.otequinox.aspectBindings and check aspect permissions. */
+ public void loadAspectBindings(@Nullable PackageAdmin packageAdmin) {
+ IConfigurationElement[] aspectBindingConfigs = RegistryFactory.getRegistry().getConfigurationElementsFor(
+ TRANSFORMER_PLUGIN_ID, ASPECT_BINDING_EXTPOINT_ID);
+
+ for (int i = 0; i < aspectBindingConfigs.length; i++) {
+ IConfigurationElement currentBindingConfig = aspectBindingConfigs[i];
+
+ //aspect:
+ @SuppressWarnings("null")@NonNull String aspectBundleId= currentBindingConfig.getContributor().getName();
+ IS_OTDT |= KNOWN_OTDT_ASPECTS.contains(aspectBundleId);
+ if (packageAdmin != null) {
+ Bundle[] aspectBundles = packageAdmin.getBundles(aspectBundleId, null);
+ if (aspectBundles == null || aspectBundles.length == 0 || (aspectBundles[0].getState() < Bundle.RESOLVED)) {
+ log(ILogger.ERROR, "aspect bundle "+aspectBundleId+" is not resolved - not loading aspectBindings.");
+ continue;
+ }
+ }
+
+ //base:
+ IConfigurationElement[] basePlugins = currentBindingConfig.getChildren(BASE_PLUGIN);
+ if (basePlugins.length != 1) {
+ log(ILogger.ERROR, "aspectBinding of "+aspectBundleId+" must declare exactly one basePlugin");
+ continue;
+ }
+ String baseBundleId = basePlugins[0].getAttribute(ID);
+
+// FIXME(SH):
+// //base fragments?
+// IConfigurationElement[] fragments = basePlugins[0].getChildren(REQUIRED_FRAGMENT);
+// if (fragments != null && !checkRequiredFragments(aspectBundleId, baseBundleId, fragments)) // reported inside
+// continue;
+
+ AspectBinding binding = new AspectBinding(aspectBundleId, baseBundleId, basePlugins[0].getChildren(Constants.FORCED_EXPORTS_ELEMENT));
+ // TODO(SH): maybe enforce that every bundle id is given only once?
+
+ //teams:
+ IConfigurationElement[] teams = currentBindingConfig.getChildren(TEAM);
+ binding.initTeams(teams.length);
+ try {
+ for (int j = 0; j < teams.length; j++) {
+ String teamClass = teams[j].getAttribute(CLASS);
+ binding.teamClasses[j] = teamClass;
+ String activation = teams[j].getAttribute(ACTIVATION);
+ binding.setActivation(j, activation);
+ }
+
+ @NonNull String realBaseBundleId = baseBundleId.toUpperCase().equals(SELF) ? aspectBundleId : baseBundleId;
+ addBindingForBaseBundle(realBaseBundleId, binding);
+ addBindingForAspectBundle(aspectBundleId, binding);
+ if (!baseTripWires.containsKey(realBaseBundleId))
+ baseTripWires.put(realBaseBundleId, new BaseBundleActivation(realBaseBundleId, this, packageAdmin));
+
+
+ // now that binding.teamClasses is filled connect to super team, if requested:
+ for (int j = 0; j < teams.length; j++) {
+ String superTeamName = teams[j].getAttribute(SUPERCLASS);
+ if (superTeamName != null)
+ addSubTeam(aspectBundleId, binding.teamClasses[j], superTeamName);
+ }
+ log(ILogger.INFO, "registered:\n"+binding);
+ } catch (Throwable t) {
+ log(t, "Invalid aspectBinding extension");
+ }
+ }
+ }
+
+
+ private static void addBindingForBaseBundle(String baseBundleId, AspectBinding binding) {
+ ArrayList<AspectBinding> bindingList = aspectBindingsByBasePlugin.get(baseBundleId);
+ if (bindingList == null) {
+ bindingList = new ArrayList<AspectBinding>();
+ aspectBindingsByBasePlugin.put(baseBundleId, bindingList);
+ }
+ bindingList.add(binding);
+ }
+
+ private void addBindingForAspectBundle(String aspectBundleId, AspectBinding binding) {
+ ArrayList<AspectBinding> bindingList = aspectBindingsByAspectPlugin.get(aspectBundleId);
+ if (bindingList == null) {
+ bindingList = new ArrayList<AspectBinding>();
+ aspectBindingsByAspectPlugin.put(aspectBundleId, bindingList);
+ }
+ bindingList.add(binding);
+ if (binding.basePlugin.toUpperCase().equals(SELF))
+ selfAdaptingAspects.add(aspectBundleId);
+ }
+
+ /**
+ * Record a sub-class relationship of two teams within the same aspect bundle.
+ *
+ * @param aspectBundleId
+ * @param subTeamName (nullable only until we have JSR 308)
+ * @param teamName
+ */
+ private void addSubTeam(String aspectBundleId, @Nullable String subTeamName, String teamName) {
+ ArrayList<AspectBinding> bindingList = aspectBindingsByAspectPlugin.get(aspectBundleId);
+ if (bindingList == null) {
+ Exception e = new Exception("No such aspect binding");
+ log(e, "Class "+teamName+" not registered (declared to be superclass of team "+subTeamName);
+ } else {
+ for (AspectBinding binding : bindingList)
+ if (binding.teamClasses != null)
+ for (int i=0; i < binding.teamClasses.length; i++)
+ if (binding.teamClasses[i].equals(teamName)) {
+ if (binding.subTeamClasses[i] == null)
+ binding.subTeamClasses[i] = new ArrayList<String>();
+ binding.subTeamClasses[i].add(subTeamName);
+ return;
+ }
+ Exception e = new Exception("No such aspect binding");
+ log(e, "Class "+teamName+" not registered(2) (declared to be superclass of team "+subTeamName);
+ }
+ }
+
+
+ /**
+ * Internal API for TransformerHook:
+ * see {@link IAspectRegistry#getAdaptedBasePlugins(Bundle)}
+ */
+ public @Nullable String[] getAdaptedBasePlugins(Bundle aspectBundle) {
+ ArrayList<AspectBinding> bindings = aspectBindingsByAspectPlugin.get(aspectBundle.getSymbolicName());
+ if (bindings == null) return null;
+ String[] basePlugins = new String[bindings.size()];
+ for (int i=0; i<basePlugins.length; i++) {
+ basePlugins[i] = bindings.get(i).basePlugin;
+ }
+ return basePlugins;
+ }
+
+ /** Is `symbolicName' the name of a base plugin for which an adapting team is registered? */
+ public boolean isAdaptedBasePlugin(@Nullable String symbolicName) {
+ ArrayList<AspectBinding> list = aspectBindingsByBasePlugin.get(symbolicName);
+ return list != null && !list.isEmpty();
+ }
+
+ /**
+ * public API:
+ * {@link IAspectRegistry#getAdaptingAspectPlugins(Bundle)}
+ */
+ public String[] getAdaptingAspectPlugins(Bundle basePlugin) {
+ return getAdaptingAspectPlugins(basePlugin.getSymbolicName());
+ }
+ /**
+ * public API:
+ * Get the names of aspect plugins adapting a given base plugin.
+ * @param basePluginName symbolic name of a base plugin.
+ * @return non-null array of symbolic names of aspect plugins.
+ */
+ public String[] getAdaptingAspectPlugins(@Nullable String basePluginName) {
+ ArrayList<AspectBinding> list = aspectBindingsByBasePlugin.get(basePluginName);
+
+ if (list == null)
+ return new String[0];
+
+ String[] aspects = new String[list.size()];
+ for (int i=0; i< list.size(); i++)
+ aspects[i] = list.get(i).aspectPlugin;
+
+ return aspects;
+ }
+
+ /**
+ * Get the list of aspect bindings affecting the given base plugin.
+ */
+ public @Nullable List<AspectBinding> getAdaptingAspectBindings(@Nullable String basePluginName) {
+ return aspectBindingsByBasePlugin.get(basePluginName);
+ }
+
+ /**
+ * Recored the names of base classes adapted by a given team from a given aspect bundle.
+ */
+ public void storeAdaptedBaseClassNames(String aspectBundleName, String teamName, Collection<String> baseClassNames)
+ {
+ // search the base plugin being adapted by the given team:
+ String basePlugin = null;
+ bindings:
+ for (AspectBinding aspectBinding : aspectBindingsByAspectPlugin.get(aspectBundleName)) {
+ for (String aspectTeamClass : aspectBinding.teamClasses)
+ if (aspectTeamClass.equals(teamName)) {
+ basePlugin = aspectBinding.basePlugin;
+ break bindings;
+ }
+ }
+ if (basePlugin == null && selfAdaptingAspects.contains(aspectBundleName))
+ basePlugin = aspectBundleName;
+ if (basePlugin == null) {
+ log(ILogger.ERROR, "Base plugin for team "+teamName+" from "+aspectBundleName+" not found!");
+ return;
+ }
+ // merge base class names into existing:
+ synchronized (adaptedBaseClassNames) {
+ ArrayList<String> baseBundleClassNames = adaptedBaseClassNames.get(basePlugin);
+ if (baseBundleClassNames == null) {
+ baseBundleClassNames = new ArrayList<String>();
+ adaptedBaseClassNames.put(basePlugin, baseBundleClassNames);
+ }
+ baseBundleClassNames.addAll(baseClassNames);
+ }
+ }
+
+ /** Check if the given base bundle / base class mandate any loading/instantiation/activation of teams. */
+ public void triggerLoadingHooks(@Nullable String bundleName, @Nullable String className) {
+ BaseBundleActivation activation = baseTripWires.get(bundleName);
+ if (activation != null)
+ activation.fire(className);
+ }
+
+ /** Record the given team classes as waiting for instantiation/activation. */
+ public synchronized void addDeferredTeamClasses(List<WaitingTeamRecord> teamClasses) {
+ deferredTeams.addAll(teamClasses);
+ }
+
+ /**
+ * Check if the given class has been recorded as not-found before,
+ * If so, unblock the team class(es) that depend on this class
+ */
+ public synchronized void scheduleTeamClassesFor(@Nullable String className) {
+ List<WaitingTeamRecord> currentList = deferredTeams;
+ deferredTeams = new ArrayList<>();
+ for (WaitingTeamRecord record : currentList) {
+ if (record.notFoundClass.equals(className))
+ scheduledTeams.add(record);
+ else
+ deferredTeams.add(record);
+ }
+ }
+
+ /**
+ * Try to instantiate/activate any deferred teams that have been unblocked by now.
+ */
+ public void instantiateScheduledTeams() {
+ List<WaitingTeamRecord> currentList;
+ synchronized (this) {
+ currentList = scheduledTeams;
+ scheduledTeams = new ArrayList<>();
+ }
+ for(WaitingTeamRecord record : currentList) {
+ try {
+ BaseBundleActivation.instantiateWaitingTeam(record, deferredTeams);
+ } catch (Exception e) {
+ log(e, "Failed to instantiate team "+record.getTeamName());
+ continue;
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleActivation.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleActivation.java
new file mode 100644
index 000000000..c35d734aa
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleActivation.java
@@ -0,0 +1,174 @@
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.osgi.weaving.Activator.log;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBindingRegistry.WaitingTeamRecord;
+import org.eclipse.objectteams.osgi.weaving.ActivationKind;
+import org.eclipse.objectteams.otequinox.hook.ILogger;
+import org.objectteams.ITeam;
+import org.objectteams.Team;
+import org.osgi.framework.Bundle;
+
+/**
+ * Each instance of this class represents the fact that a given base bundle has aspect bindings,
+ * which require to load / instantiate / activate one or more teams at a suitable point in time.
+ */
+public class BaseBundleActivation {
+
+ private AspectBindingRegistry aspectBindingRegistry;
+ @SuppressWarnings("deprecation")
+ private org.osgi.service.packageadmin.PackageAdmin admin;
+
+ private String baseBundleName;
+
+ private boolean teamsScanned = false;
+
+
+ public BaseBundleActivation(String bundleSymbolicName, AspectBindingRegistry aspectBindingRegistry,
+ @SuppressWarnings("deprecation") org.osgi.service.packageadmin.PackageAdmin admin)
+ {
+ this.baseBundleName = bundleSymbolicName;
+ this.aspectBindingRegistry = aspectBindingRegistry;
+ this.admin = admin;
+ }
+
+ /** Signal that the given class is being loaded and trigger any necessary loading/instantiation/activation. */
+ public void fire(String className) {
+ List<AspectBindingRegistry.WaitingTeamRecord> deferredTeamClasses = new ArrayList<>();
+ List<AspectBinding> aspectBindings = aspectBindingRegistry.getAdaptingAspectBindings(baseBundleName);
+ if (aspectBindings != null) {
+ for (AspectBinding aspectBinding : aspectBindings) {
+ if (aspectBinding.activated)
+ continue;
+ Bundle[] aspectBundles = admin.getBundles(aspectBinding.aspectPlugin, null);
+ if (aspectBundles == null || aspectBundles.length == 0) {
+ log(IStatus.ERROR, "Cannot find aspect bundle "+aspectBinding.aspectPlugin);
+ continue;
+ }
+ Bundle aspectBundle = aspectBundles[0];
+ if (shouldScan())
+ scanTeamClasses(aspectBundle, aspectBinding);
+ if (loadTeams(aspectBundle, aspectBinding, className, deferredTeamClasses))
+// aspectBinding.activated = true; // FIXME(SH): this still spoils team activation, the given class may not be the trigger
+ ;
+ }
+ if (!deferredTeamClasses.isEmpty())
+ aspectBindingRegistry.addDeferredTeamClasses(deferredTeamClasses);
+ }
+ }
+
+ private synchronized boolean shouldScan() {
+ boolean shouldScan = !teamsScanned;
+ teamsScanned = true;
+ return shouldScan;
+ }
+
+ /** Read OT attributes of all teams in aspectBinding and collect affected base classes. */
+ private void scanTeamClasses(Bundle bundle, AspectBinding aspectBinding) {
+ List<String> allTeams = aspectBinding.getAllTeams();
+ ClassScanner scanner = new ClassScanner();
+ for (String teamName : allTeams) {
+ try {
+ scanner.readOTAttributes(bundle, teamName);
+ aspectBinding.addBaseClassNames(teamName, scanner.getCollectedBaseClassNames());
+ } catch (Exception e) {
+ log(e, "Failed to load team class "+teamName);
+ }
+ }
+ }
+
+ /** Team loading, 1st attempt (trying to do all three phases load/instantiate/activate). */
+ private boolean loadTeams(Bundle aspectBundle, AspectBinding aspectBinding, String className, List<WaitingTeamRecord> deferredTeamClasses) {
+ Collection<String> teamsForBase = aspectBinding.getTeamsForBase(className);
+ if (teamsForBase == null) return true;
+ TeamLoading delegate = new TeamLoading(deferredTeamClasses);
+ for (String teamForBase : teamsForBase) {
+ // Load:
+ Class<? extends ITeam> teamClass;
+ try {
+ teamClass = (Class<? extends ITeam>) aspectBundle.loadClass(teamForBase);
+ } catch (ClassNotFoundException e) {
+ log(e, "Failed to load team "+teamForBase);
+ continue;
+ }
+ // Instantiate?
+ ActivationKind activationKind = aspectBinding.getActivation(teamForBase);
+ if (activationKind == ActivationKind.NONE)
+ continue;
+ ITeam teamInstance = delegate.instantiateTeam(aspectBinding, teamClass, teamForBase);
+ if (teamInstance == null)
+ continue;
+ // Activate?
+ delegate.activateTeam(aspectBinding, teamForBase, teamInstance, activationKind);
+ }
+ return !delegate.needDeferring; // TODO, need to figure out whether we're done with aspectBinding.
+ }
+
+ /** Team loading, subsequent attempts. */
+ public static void instantiateWaitingTeam(WaitingTeamRecord record, List<WaitingTeamRecord> deferredTeams)
+ throws InstantiationException, IllegalAccessException
+ {
+ ITeam teamInstance = record.teamInstance;
+ String teamName = record.getTeamName();
+ TeamLoading delegate = new TeamLoading(deferredTeams);
+ if (teamInstance == null) {
+ // Instantiate (we only get here if activationKind != NONE)
+ teamInstance = delegate.instantiateTeam(record.aspectBinding, record.teamClass, teamName);
+ if (teamInstance == null)
+ return;
+ }
+ // Activate?
+ ActivationKind activationKind = record.aspectBinding.getActivation(teamName);
+ delegate.activateTeam(record.aspectBinding, teamName, teamInstance, activationKind);
+ }
+
+ /* Common parts for both first and subsequent loading attempts. */
+ private static class TeamLoading {
+ List<WaitingTeamRecord> deferredTeams;
+ boolean needDeferring; // did we record the fact that a team needs deferring?
+
+ public TeamLoading(List<WaitingTeamRecord> deferredTeams) {
+ this.deferredTeams = deferredTeams;
+ }
+
+ @Nullable ITeam instantiateTeam(AspectBinding aspectBinding, Class<? extends ITeam> teamClass, String teamName) {
+ try {
+ ITeam instance = teamClass.newInstance();
+ log(ILogger.INFO, "Instantiated team "+teamName);
+ return instance;
+ } catch (NoClassDefFoundError ncdfe) {
+ needDeferring = true;
+ deferredTeams.add(new WaitingTeamRecord(teamClass, aspectBinding, ncdfe.getMessage().replace('/','.')));
+ } catch (Throwable e) {
+ // application error during constructor execution?
+ log(e, "Failed to instantiate team "+teamName);
+ }
+ return null;
+ }
+ void activateTeam(AspectBinding aspectBinding, String teamName, ITeam teamInstance, ActivationKind activationKind)
+ {
+ try {
+ switch (activationKind) {
+ case ALL_THREADS:
+ teamInstance.activate(Team.ALL_THREADS);
+ break;
+ case THREAD:
+ teamInstance.activate();
+ break;
+ //$CASES-OMITTED$
+ }
+ } catch (NoClassDefFoundError e) {
+ deferredTeams.add(new WaitingTeamRecord(teamInstance, aspectBinding, e.getMessage().replace('/','.'))); // TODO(SH): synchronization
+ } catch (Throwable t) {
+ // application errors during activation
+ log(t, "Failed to activate team "+teamName);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/ClassScanner.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/ClassScanner.java
new file mode 100644
index 000000000..377fe1d6e
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/ClassScanner.java
@@ -0,0 +1,143 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2008, 2010 Technical University Berlin, 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
+ * $Id: ClassScanner.java 23461 2010-02-04 22:10:39Z stephan $
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.osgi.weaving.Activator.log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.objectteams.otequinox.hook.ILogger;
+import org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer;
+import org.eclipse.objectteams.otre.util.CallinBindingManager;
+import org.osgi.framework.Bundle;
+
+/**
+ * Bridge for the TransformerPlugin by which it can access the ObjectTeamsTransformer
+ * without accessing that OTRE class.
+ *
+ * @author stephan
+ * @since 1.2.0
+ */
+@SuppressWarnings("nls")
+public class ClassScanner
+{
+ // default is "on", leave this switch for trouble shooting and profiling:
+ public static final boolean REPOSITORY_USE_RESOURCE_LOADER = !"off".equals(System.getProperty("otequinox.repository.hook"));
+
+ // collect class names recorded by readOTAttributes:
+
+ // * this version used by the MasterTeamLoader.loadTeams:
+ HashMap<String,ArrayList<String>> baseClassNamesByTeam = new HashMap<String, ArrayList<String>>();
+ // * these fields used by TransformerHook.processClass (collected over multiple readOTAttributes):
+ ArrayList<String> allBaseClassNames = new ArrayList<String>();
+ ArrayList<String> roleClassNames = new ArrayList<String>();
+
+
+ /**
+ * Read all OT byte code attributes for the specified class.
+ * While doing so the names of roles and adapted base classes are collected.
+ *
+ * @param bundle where to look
+ * @param className the class to investigate (team or role)
+ * @param loader the loader (could be null) to use for further classFile lookup
+ * @throws ClassFormatError
+ * @throws IOException
+ * @throws ClassNotFoundException the team or role class was not found
+ */
+ public void readOTAttributes(Bundle bundle, String className)
+ throws ClassFormatError, IOException, ClassNotFoundException
+ {
+ Object loader = REPOSITORY_USE_RESOURCE_LOADER ? bundle : null;
+ URL classFile = bundle.getResource(className.replace('.', '/')+".class");
+ if (classFile == null)
+ throw new ClassNotFoundException(className);
+ ObjectTeamsTransformer transformer = new ObjectTeamsTransformer();
+ try (InputStream inputStream = classFile.openStream()) {
+ transformer.readOTAttributes(inputStream, classFile.getFile(), loader);
+ }
+ Collection<String> currentBaseNames = transformer.fetchAdaptedBases(); // destructive read
+ if (currentBaseNames != null) {
+ // store per team:
+ ArrayList<String> basesPerTeam = this.baseClassNamesByTeam.get(className);
+ if (basesPerTeam == null) {
+ basesPerTeam = new ArrayList<String>();
+ this.baseClassNamesByTeam.put(className, basesPerTeam);
+ }
+ basesPerTeam.addAll(currentBaseNames);
+ // accumulated store:
+ allBaseClassNames.addAll(currentBaseNames);
+ }
+ readMemberTypeAttributes(bundle, className, transformer);
+ }
+
+ /**
+ * Get the names of the base classes adapted by the given team and
+ * encountered while reading the byte code attributes.
+ * (Destructive read).
+ */
+ public Collection<String> getCollectedBaseClassNames(String teamName) {
+ return this.baseClassNamesByTeam.remove(teamName);
+ }
+
+ /**
+ * Get the names of all adapted base classes encountered while reading the byte code attributes.
+ * (Destructive read).
+ */
+ public Collection<String> getCollectedBaseClassNames() {
+ try {
+ return this.allBaseClassNames;
+ } finally {
+ this.allBaseClassNames = new ArrayList<String>();
+ }
+ }
+
+ /**
+ * Get the names of all member roles encountered while reading the byte code attributes.
+ * (Destructive read).
+ */
+ public Collection<String> getCollectedRoleClassNames() {
+ return this.roleClassNames;
+ }
+
+ /*
+ * Recurse into member types scanning OT attributes.
+ */
+ private void readMemberTypeAttributes(Bundle bundle,
+ String className,
+ ObjectTeamsTransformer transformer)
+ {
+ List<String> roles = CallinBindingManager.getRolePerTeam(className);
+ if (roles != null) {
+ for (String roleName: roles) {
+ log(ILogger.OK, "scanning role "+roleName);
+ try {
+ this.roleClassNames.add(roleName);
+ readOTAttributes(bundle, roleName);
+ } catch (Throwable t) {
+ log(t, "Failed to read OT-Attributes of role "+roleName);
+ }
+ readMemberTypeAttributes(bundle, roleName, transformer);
+ }
+ }
+ }
+}; \ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
new file mode 100644
index 000000000..8eeb123dc
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
@@ -0,0 +1,68 @@
+package org.eclipse.objectteams.internal.osgi.weaving;
+
+import static org.eclipse.objectteams.osgi.weaving.Activator.log;
+
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.hooks.weaving.WeavingHook;
+import org.osgi.framework.hooks.weaving.WovenClass;
+import org.osgi.framework.wiring.BundleWiring;
+
+public class OTWeavingHook implements WeavingHook {
+
+ private AspectBindingRegistry aspectBindingRegistry;
+ private ObjectTeamsTransformer objectTeamsTransformer;
+
+ public OTWeavingHook(AspectBindingRegistry aspectBindingRegistry) {
+ this.aspectBindingRegistry = aspectBindingRegistry;
+ this.objectTeamsTransformer = new ObjectTeamsTransformer();
+ }
+
+ @Override
+ public void weave(WovenClass wovenClass) {
+ try {
+ // TODO(SH): ideally this trigger would be inserted into the previous woven class
+ // do whatever left-overs we find from previous invocations:
+ aspectBindingRegistry.instantiateScheduledTeams();
+
+ BundleWiring bundleWiring = wovenClass.getBundleWiring();
+ String bundleName = bundleWiring.getBundle().getSymbolicName();
+ String className = wovenClass.getClassName();
+
+ // do whatever is needed *before* loading this class:
+ aspectBindingRegistry.triggerLoadingHooks(bundleName, className);
+
+ if (requiresWeaving(bundleWiring)) {
+ Class<?> classBeingRedefined = null; // TODO
+ ProtectionDomain protectionDomain = null; // TODO
+ byte[] bytes = wovenClass.getBytes();
+ try {
+ log(IStatus.INFO, "About to transform class "+wovenClass);
+ byte[] newBytes = objectTeamsTransformer.transform(bundleWiring.getClassLoader(),
+ className, classBeingRedefined, protectionDomain, bytes);
+ if (newBytes != bytes)
+ wovenClass.setBytes(newBytes);
+ } catch (IllegalClassFormatException e) {
+ log(e, "Failed to transform class "+className);
+ }
+ }
+ // unblock any waiting teams depending on this class:
+ aspectBindingRegistry.scheduleTeamClassesFor(className);
+ } catch (ClassCircularityError cce) {
+ log(cce, "Weaver encountered a circular class dependency");
+ }
+ }
+
+ private boolean requiresWeaving(BundleWiring bundleWiring) {
+ @SuppressWarnings("null")@NonNull
+ Bundle bundle = bundleWiring.getBundle();
+ return aspectBindingRegistry.getAdaptedBasePlugins(bundle) != null
+ || aspectBindingRegistry.isAdaptedBasePlugin(bundle.getSymbolicName());
+ }
+
+}
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/ActivationKind.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/ActivationKind.java
new file mode 100644
index 000000000..57d154609
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/ActivationKind.java
@@ -0,0 +1,31 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2009 Technical University Berlin, 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:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.osgi.weaving;
+
+/**
+ * Possible values for the "activation" attribute of a "team" element within an "aspectBinding" extension.
+ *
+ * @author stephan
+ * @since 1.2.7 (was inline previously)
+ */
+public enum ActivationKind {
+ /** Don't activate team by default. */
+ NONE,
+ /** Activate team for current thread. */
+ THREAD,
+ /** Globally activate team. */
+ ALL_THREADS;
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java
new file mode 100644
index 000000000..ac7605fa4
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java
@@ -0,0 +1,126 @@
+package org.eclipse.objectteams.osgi.weaving;
+
+import static org.eclipse.objectteams.osgi.weaving.Constants.TRANSFORMER_PLUGIN_ID;
+
+import java.util.Hashtable;
+
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.objectteams.internal.osgi.weaving.AspectBindingRegistry;
+import org.eclipse.objectteams.internal.osgi.weaving.OTWeavingHook;
+import org.eclipse.objectteams.otequinox.hook.ILogger;
+import org.eclipse.objectteams.otre.ClassLoaderAccess;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.hooks.weaving.WeavingHook;
+
+public class Activator implements BundleActivator {
+
+ private static BundleContext context;
+
+ static BundleContext getContext() {
+ return context;
+ }
+
+ private ServiceRegistration<WeavingHook> serviceRegistration;
+ private AspectBindingRegistry aspectBindingRegistry;
+
+ @SuppressWarnings("deprecation")
+ private org.osgi.service.packageadmin.PackageAdmin packageAdmin;
+
+ private static ILog log;
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bundleContext) throws Exception {
+ Activator.context = bundleContext;
+
+ frameworkInit(bundleContext);
+
+ this.aspectBindingRegistry = new AspectBindingRegistry();
+ this.aspectBindingRegistry.loadAspectBindings(this.packageAdmin);
+
+ OTWeavingHook otWeavingHook = new OTWeavingHook(this.aspectBindingRegistry);
+ this.serviceRegistration = context.registerService(WeavingHook.class, otWeavingHook, new Hashtable<String, Object>());
+
+ OTREInit();
+ }
+
+ @SuppressWarnings({ "restriction", "deprecation" })
+ private void frameworkInit(BundleContext bundleContext) {
+ try {
+ Activator.log = org.eclipse.core.internal.runtime.InternalPlatform.getDefault().getLog(bundleContext.getBundle());
+ } catch (NullPointerException npe) {
+ // WTF?
+ }
+
+ ServiceReference<?> ref= context.getServiceReference(org.osgi.service.packageadmin.PackageAdmin.class.getName());
+ if (ref!=null)
+ this.packageAdmin = (org.osgi.service.packageadmin.PackageAdmin)context.getService(ref);
+ else
+ log(ILogger.ERROR, "Failed to load PackageAdmin service. Will not be able to handle fragments.");
+ }
+
+ private void OTREInit() {
+ try {
+ ClassLoaderAccess.setLoadClass(Bundle.class.getMethod("loadClass", String.class));
+ ClassLoaderAccess.setGetResource(Bundle.class.getMethod("getResource", String.class));
+ } catch (NoSuchMethodException | SecurityException e) {
+ log(e, "Failed to wire an OSGi class into the OTRE");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bundleContext) throws Exception {
+ Activator.context = null;
+ this.serviceRegistration.unregister();
+ }
+
+ // configure OT/Equinox debugging:
+ public static int WARN_LEVEL = ILogger.ERROR;
+ static {
+ String level = System.getProperty("otequinox.debug");
+ if (level != null) {
+ level = level.toUpperCase();
+ if (level.equals("OK"))
+ WARN_LEVEL = ILogger.OK;
+ else if (level.equals("INFO"))
+ WARN_LEVEL = ILogger.INFO;
+ else if (level.startsWith("WARN"))
+ WARN_LEVEL = ILogger.WARNING;
+ else if (level.startsWith("ERR"))
+ WARN_LEVEL = ILogger.ERROR;
+ else
+ WARN_LEVEL = ILogger.OK;
+ }
+ }
+
+ public static void log (Throwable ex, String msg) {
+ msg = "OT/Equinox: "+msg;
+ System.err.println(msg);
+ ex.printStackTrace();
+ log.log(new Status(IStatus.ERROR, TRANSFORMER_PLUGIN_ID, msg, ex));
+ }
+
+ public static void log(int status, String msg) {
+ if (status >= WARN_LEVEL)
+ doLog(status, msg);
+ }
+
+ private static void doLog(int status, String msg) {
+ msg = "OT/Equinox: "+msg;
+ if (log != null)
+ log.log(new Status(status, TRANSFORMER_PLUGIN_ID, msg));
+ else
+ System.err.println(msg);
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Constants.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Constants.java
new file mode 100644
index 000000000..e3dfc5864
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Constants.java
@@ -0,0 +1,62 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2009 Technical University Berlin, 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:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.osgi.weaving;
+
+/**
+ * Constants used for OT/Equinox.
+ *
+ * @author stephan
+ * @since 1.2.7
+ */
+public interface Constants {
+
+ /** ID of this plugin. */
+ public static final String TRANSFORMER_PLUGIN_ID = "org.eclipse.objectteams.osgi.weaving" ; //$NON-NLS-1$
+
+ // === Extension point elements: ===
+
+ /** Simple name of the extension point org.eclipse.objectteams.otequinox.aspectBindings. */
+ static final String ASPECT_BINDING_EXTPOINT_ID = "aspectBindings";
+ static final String ASPECT_BINDING_FQEXTPOINT_ID = TRANSFORMER_PLUGIN_ID+'.'+ASPECT_BINDING_EXTPOINT_ID;
+
+ /** Simple name of the extension point org.eclipse.objectteams.otequinox.liftingParticipant. */
+ static final String LIFTING_PARTICIPANT_EXTPOINT_ID = "liftingParticipant";
+
+ /** Attribute of "team" and "basePlugin" elements. */
+ static final String ID = "id";
+
+ /** Element of EP aspectBindings denoting a team class. */
+ static final String TEAM = "team";
+ /** Attribute of a "team" element denoting the fully qualified class name. */
+ static final String CLASS = "class";
+ /** Attribute of a "team" element denoting the team's superclass. */
+ static final String SUPERCLASS = "superclass";
+ /** Attribute of a "team" element denoting the requested activation: one of "NONE", "THREAD", "ALL_THREADS". */
+ static final String ACTIVATION = "activation";
+
+ /** Element of EP aspectBindings denoting an adapted base plugin. */
+ static final String BASE_PLUGIN = "basePlugin";
+ /** Subelement of a "basePlugin" denoting a framgment of the base plugin that is required by the aspect. */
+ static final String REQUIRED_FRAGMENT = "requiredFragment";
+ /** Pseudo ID of a basePlugin specifying that the team(s) adapt base classes from their own plugin. */
+ static final String SELF = "SELF";
+
+ /** Element of EP aspectBinding - child of basePlugin node - requesting exports forced on the given base plug-in. */
+ public static final String FORCED_EXPORTS_ELEMENT = "forcedExports";
+
+ /** Simple name of the extension point org.eclipse.objectteams.otequinox.aspectBindingNegotiators. */
+ public static final String ASPECT_NEGOTIATOR_EXTPOINT_ID = "aspectBindingNegotiators";
+}

Back to the top