diff options
author | Stephan Herrmann | 2013-04-25 11:30:30 +0000 |
---|---|---|
committer | Stephan Herrmann | 2013-04-25 11:30:30 +0000 |
commit | 5a7ecb34d166516d548f8a32b0a82ebb020b7a6b (patch) | |
tree | 0e94fc24d0908957b5cfab8873bc0e7bf3c277cd /plugins | |
parent | 81fd5dcf044c587591d9d354a058919526bb15bb (diff) | |
download | org.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
Diffstat (limited to 'plugins')
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. +<p> +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. +<ul> +<li>As soon as any extension DENYs a given request this aspect plugin is blocked.</li> +<li>If no extension GRANTs the request the aspect plugin is blocked, too.</li> +<li>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.</li> +</ul> +</p> + </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 <code>negotiator</code>:<pre> +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.2"?> +<plugin> + <extension + point="org.eclipse.objectteams.otequinox.aspectBindingNegotiators"> + <negotiator + class="yesser.AspectRequestGranter"> + </negotiator> + </extension> +</plugin> +</pre> + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiInfo"/> + </appInfo> + <documentation> + The class named in the <code>class</code> property must implement the <code>org.eclipse.objectteams.otequinox.IAspectRequestNegotiator</code> interface. + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="copyright"/> + </appInfo> + <documentation> + <em> +<p> +This file is part of "Object Teams Development Tooling"-Software +</p><p> +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 +<a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a> +</p><p> +Please visit <a href="http://www.objectteams.org">www.objectteams.org</a> for updates and contact. +</p><p> +Contributors:<br> +Technical University Berlin - Initial API and implementation +</p> +</em> + </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 <strong>relationship</strong> between plug-ins +called <strong>"aspectBinding"</strong>. +By an aspectBinding an aspect plug-in declares which <strong>base plug-ins</strong> it wishes to adapt +and which <strong>team classes</strong> 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 <strong>instantiated</strong> +before the corresponding base plug-in is fully activated. +In addition extensions may specify that a given team is also <strong>activated</strong> +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> + <i>Default value to provide an icon for this element kind. No need to edit</i> + </documentation> + <appInfo> + <meta.attribute kind="resource"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="basePlugin"> + <annotation> + <appInfo> + <meta.element icon="icon"/> + </appInfo> + <documentation> + <p> +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 <b>fragment</b> should be adapted the aspect binding must refer to the fragment's host bundle +and additionally a <code>requiredFragment</code> should be added. +</p> +<p> +By specifying <code>SELF</code> as the basePlugin, a team may adapt classes from its own bundle. +</p> + </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> + <i>Default value to provide an icon for this element kind. No need to edit</i> + </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.<br/> +If a nested team shall be used it can be specified using either its source name (using '.' as the separator) or its binary name (using a '$' 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'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'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> + <i>Default value to provide an icon for this element kind. No need to edit</i> + </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 <code>class</code> named in the class property must be a team class thus implementing the <code>org.objectteams.ITeam</code> interface. + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + None. + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="copyright"/> + </appInfo> + <documentation> + <em> +<p> +This file is part of "Object Teams Development Tooling"-Software +</p><p> +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 +<a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a> +</p><p> +Please visit <a href="http://www.objectteams.org">www.objectteams.org</a> for updates and contact. +</p><p> +Contributors:<br> +Technical University Berlin - Initial API and implementation +</p> +</em> + </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 <code>org.objectteams.ILiftingParticipant</code>
+ </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 "lifting participants" 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 <code>class</code> named in the class property must implement the <code>org.objectteams.ILiftingParticipant</code> 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>
+ <em>
+<p>
+This file is part of "Object Teams Development Tooling"-Software
+</p>
+<p>
+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
+<a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>
+</p>
+<p>
+Please visit <a href="http://www.eclipse.org/objectteams">www.eclipse.org/objectteams</a> for updates and contact.
+</p>
+<p>
+Contributors:<br>
+Fraunhofer FIRST - Initial API and implementation
+</p>
+</em>
+ </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"; +} |