-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial Build Compatible Extension API proposal
- Loading branch information
Showing
47 changed files
with
2,035 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
package cdi.lite.extension; | ||
|
||
import cdi.lite.extension.model.declarations.ClassInfo; | ||
import cdi.lite.extension.model.declarations.FieldInfo; | ||
import cdi.lite.extension.model.declarations.MethodInfo; | ||
import cdi.lite.extension.model.types.Type; | ||
import java.lang.annotation.Annotation; | ||
import java.util.Collection; | ||
import java.util.stream.Stream; | ||
|
||
public interface AppArchive { | ||
ClassQuery classes(); | ||
|
||
MethodQuery constructors(); // no static initializers | ||
|
||
MethodQuery methods(); // no constructors nor static initializers | ||
|
||
FieldQuery fields(); | ||
|
||
/** | ||
* The {@code exactly}, {@code subtypeOf} and {@code supertypeOf} methods are additive. | ||
* When called multiple times, they form a union of requested classes (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appArchive.classes() | ||
* .exactly(Foo.class) | ||
* .subtypeOf(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns the {@code Foo} class and all subtypes of the {@code Bar} class. | ||
* <p> | ||
* The {@code annotatedWith} methods are additive. | ||
* When called multiple times, they form a union of requested annotations (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appArchive.classes() | ||
* .annotatedWith(Foo.class) | ||
* .annotatedWith(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all classes annotated either with {@code @Foo} or with {@code @Bar} (or both). | ||
*/ | ||
interface ClassQuery { | ||
ClassQuery exactly(Class<?> clazz); | ||
|
||
ClassQuery exactly(ClassInfo<?> clazz); | ||
|
||
ClassQuery subtypeOf(Class<?> clazz); | ||
|
||
ClassQuery subtypeOf(ClassInfo<?> clazz); | ||
|
||
ClassQuery supertypeOf(Class<?> clazz); | ||
|
||
ClassQuery supertypeOf(ClassInfo<?> clazz); | ||
|
||
ClassQuery annotatedWith(Class<? extends Annotation> annotationType); | ||
|
||
ClassQuery annotatedWith(ClassInfo<?> annotationType); | ||
|
||
Collection<ClassInfo<?>> find(); | ||
|
||
Stream<ClassInfo<?>> stream(); | ||
} | ||
|
||
/** | ||
* The {@code declaredOn} method is additive. | ||
* When called multiple times, it forms a union of requested classes (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appArchive.methods() | ||
* .declaredOn(appArchive.classes().exactly(Foo.class)) | ||
* .declaredOn(appArchive.classes().subtypeOf(Bar.class)) | ||
* .find() | ||
* }</pre> | ||
* returns all methods declared on the {@code Foo} class and on all subtypes of the {@code Bar} class. | ||
* Note that this example can be rewritten as | ||
* <pre>{@code | ||
* appArchive.methods() | ||
* .declaredOn(appArchive.classes().exactly(Foo.class).subtypeOf(Bar.class)) | ||
* .find() | ||
* }</pre> | ||
* which is probably easier to understand. | ||
* <p> | ||
* The {@code withReturnType} methods are additive. | ||
* When called multiple times, they form a union of requested return types (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appArchive.methods() | ||
* .withReturnType(Foo.class) | ||
* .withReturnType(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all methods that return either {@code Foo} or {@code Bar}. | ||
* <p> | ||
* The {@code annotatedWith} methods are additive. | ||
* When called multiple times, they form a union of requested annotations (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appArchive.methods() | ||
* .annotatedWith(Foo.class) | ||
* .annotatedWith(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all methods annotated either with {@code @Foo} or with {@code @Bar} (or both). | ||
*/ | ||
interface MethodQuery { | ||
MethodQuery declaredOn(ClassQuery classes); | ||
|
||
/** | ||
* Equivalent to {@code withReturnType(types.of(type))}, where {@code types} is {@link Types}. | ||
*/ | ||
MethodQuery withReturnType(Class<?> type); | ||
|
||
MethodQuery withReturnType(Type type); | ||
|
||
// TODO parameters? | ||
|
||
MethodQuery annotatedWith(Class<? extends Annotation> annotationType); | ||
|
||
MethodQuery annotatedWith(ClassInfo<?> annotationType); | ||
|
||
Collection<MethodInfo<?>> find(); | ||
|
||
Stream<MethodInfo<?>> stream(); | ||
} | ||
|
||
/** | ||
* The {@code declaredOn} method is additive. | ||
* When called multiple times, it forms a union of requested classes (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appArchive.fields() | ||
* .declaredOn(appArchive.classes().exactly(Foo.class)) | ||
* .declaredOn(appArchive.classes().subtypeOf(Bar.class)) | ||
* .find() | ||
* }</pre> | ||
* returns all fields declared on the {@code Foo} class and on all subtypes of the {@code Bar} class. | ||
* Note that this example can be rewritten as | ||
* <pre>{@code | ||
* appArchive.fields() | ||
* .declaredOn(appArchive.classes().exactly(Foo.class).subtypeOf(Bar.class)) | ||
* .find() | ||
* }</pre> | ||
* which is probably easier to understand. | ||
* <p> | ||
* The {@code ofType} methods are additive. | ||
* When called multiple times, they form a union of requested field types (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appArchive.fields() | ||
* .ofType(Foo.class) | ||
* .ofType(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all fields that are of type either {@code Foo} or {@code Bar}. | ||
* <p> | ||
* The {@code annotatedWith} methods are additive. | ||
* When called multiple times, they form a union of requested annotations (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appArchive.fields() | ||
* .annotatedWith(Foo.class) | ||
* .annotatedWith(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all fields annotated either with {@code @Foo} or with {@code @Bar} (or both). | ||
*/ | ||
interface FieldQuery { | ||
FieldQuery declaredOn(ClassQuery classes); | ||
|
||
/** | ||
* Equivalent to {@code ofType(types.of(type))}, where {@code types} is {@link Types}. | ||
*/ | ||
FieldQuery ofType(Class<?> type); | ||
|
||
FieldQuery ofType(Type type); | ||
|
||
FieldQuery annotatedWith(Class<? extends Annotation> annotationType); | ||
|
||
FieldQuery annotatedWith(ClassInfo<?> annotationType); | ||
|
||
Collection<FieldInfo<?>> find(); | ||
|
||
Stream<FieldInfo<?>> stream(); | ||
} | ||
} |
140 changes: 140 additions & 0 deletions
140
api/src/main/java/cdi/lite/extension/AppDeployment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package cdi.lite.extension; | ||
|
||
import cdi.lite.extension.beans.BeanInfo; | ||
import cdi.lite.extension.beans.ObserverInfo; | ||
import cdi.lite.extension.model.declarations.ClassInfo; | ||
import cdi.lite.extension.model.types.Type; | ||
import java.lang.annotation.Annotation; | ||
import java.util.Collection; | ||
import java.util.stream.Stream; | ||
|
||
public interface AppDeployment { | ||
BeanQuery beans(); | ||
|
||
ObserverQuery observers(); | ||
|
||
/** | ||
* The {@code scope} methods are additive. | ||
* When called multiple times, they form a union of requested scope types (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appDeployment.beans() | ||
* .scope(Foo.class) | ||
* .scope(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all beans with the {@code @Foo} scope or the {@code @Bar} scope. | ||
* <p> | ||
* The {@code type} methods are additive. | ||
* When called multiple times, they form a union of requested bean types (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appDeployment.beans() | ||
* .type(Foo.class) | ||
* .type(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all beans with the {@code Foo} type or the {@code Bar} type (or both). | ||
* Note that bean type is not just the class which declares the bean (or return type of a producer method, | ||
* or type of producer field). All superclasses and superinterfaces are also included in the set of bean types. | ||
* <p> | ||
* The {@code qualifier} methods are additive. | ||
* When called multiple times, they form a union of requested qualifiers (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appDeployment.beans() | ||
* .qualifier(Foo.class) | ||
* .qualifier(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all beans with the {@code @Foo} qualifier or the {@code @Bar} qualifier (or both). | ||
* <p> | ||
* The {@code declaringClass} methods are additive. | ||
* When called multiple times, they form a union of requested declaration classes (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appDeployment.beans() | ||
* .declaringClass(Foo.class) | ||
* .declaringClass(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all beans declared on the {@code Foo} class or the {@code Bar} class. | ||
*/ | ||
interface BeanQuery { | ||
BeanQuery scope(Class<? extends Annotation> scopeAnnotation); | ||
|
||
BeanQuery scope(ClassInfo<?> scopeAnnotation); | ||
|
||
BeanQuery type(Class<?> beanType); | ||
|
||
BeanQuery type(ClassInfo<?> beanType); | ||
|
||
BeanQuery type(Type beanType); | ||
|
||
BeanQuery qualifier(Class<? extends Annotation> qualifierAnnotation); | ||
|
||
BeanQuery qualifier(ClassInfo<?> qualifierAnnotation); | ||
|
||
BeanQuery declaringClass(Class<?> declarationClass); | ||
|
||
BeanQuery declaringClass(ClassInfo<?> declarationClass); | ||
|
||
Collection<BeanInfo<?>> find(); | ||
|
||
Stream<BeanInfo<?>> stream(); | ||
} | ||
|
||
/** | ||
* The {@code observedType} methods are additive. | ||
* When called multiple times, they form a union of requested observer types (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appDeployment.observers() | ||
* .observedType(Foo.class) | ||
* .observedType(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all observers that observe the {@code Foo} event type or the {@code Bar} event type. | ||
* <p> | ||
* The {@code qualifier} methods are additive. | ||
* When called multiple times, they form a union of requested qualifiers (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appDeployment.observers() | ||
* .qualifier(Foo.class) | ||
* .qualifier(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all observers with the {@code @Foo} qualifier or the {@code @Bar} qualifier (or both). | ||
* <p> | ||
* The {@code declaringClass} methods are additive. | ||
* When called multiple times, they form a union of requested declaration classes (not an intersection). | ||
* For example, | ||
* <pre>{@code | ||
* appDeployment.observers() | ||
* .declaringClass(Foo.class) | ||
* .declaringClass(Bar.class) | ||
* .find() | ||
* }</pre> | ||
* returns all observers declared on the {@code Foo} class or the {@code Bar} class. | ||
*/ | ||
interface ObserverQuery { | ||
ObserverQuery observedType(Class<?> beanType); | ||
|
||
ObserverQuery observedType(ClassInfo<?> beanType); | ||
|
||
ObserverQuery observedType(Type beanType); | ||
|
||
ObserverQuery qualifier(Class<? extends Annotation> qualifierAnnotation); | ||
|
||
ObserverQuery qualifier(ClassInfo<?> qualifierAnnotation); | ||
|
||
ObserverQuery declaringClass(Class<?> declarationClass); | ||
|
||
ObserverQuery declaringClass(ClassInfo<?> declarationClass); | ||
|
||
Collection<ObserverInfo<?>> find(); | ||
|
||
Stream<ObserverInfo<?>> stream(); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
api/src/main/java/cdi/lite/extension/ExtensionPriority.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package cdi.lite.extension; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Allows specifying priority of extensions. | ||
* <p> | ||
* Extensions with specified priority always precede extensions without any priority. | ||
* Extension with highest priority get invoked first. If two extensions have equal | ||
* priority, the ordering is undefined. | ||
* TODO should really figure out if low number = high priority or otherwise, preferrably | ||
* so that it's consistent with common usages of `@Priority` | ||
*/ | ||
@Target(ElementType.METHOD) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface ExtensionPriority { | ||
/** | ||
* The priority value. | ||
*/ | ||
int value(); | ||
} |
Oops, something went wrong.