Skip to content

Commit 0c6e55e

Browse files
committed
Polish code
1 parent 9367adb commit 0c6e55e

File tree

7 files changed

+294
-118
lines changed

7 files changed

+294
-118
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.geektimes.enterprise.inject.standard.beans.decorator;
18+
19+
import org.geektimes.enterprise.inject.standard.beans.manager.StandardBeanManager;
20+
21+
import javax.decorator.Decorator;
22+
23+
/**
24+
* {@link Decorator Decorator} Manager
25+
*
26+
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
27+
* @since 1.0.0
28+
*/
29+
public class DecoratorManager {
30+
31+
private final StandardBeanManager standardBeanManager;
32+
33+
public DecoratorManager(StandardBeanManager standardBeanManager) {
34+
this.standardBeanManager = standardBeanManager;
35+
}
36+
}

projects/stage-1/middleware-frameworks/my-cdi/src/main/java/org/geektimes/enterprise/inject/standard/beans/manager/StandardBeanManager.java

+66-46
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
import java.lang.annotation.Annotation;
6060
import java.lang.reflect.Method;
6161
import java.lang.reflect.Type;
62+
import java.lang.reflect.TypeVariable;
63+
import java.lang.reflect.WildcardType;
6264
import java.util.*;
6365
import java.util.function.Function;
6466

@@ -230,6 +232,7 @@ public <X> Bean<? extends X> resolve(Set<Bean<? extends X>> beans) {
230232
@Override
231233
public void validate(InjectionPoint injectionPoint) {
232234
assertAfterBeanDiscovery();
235+
validateInjectionPointType(injectionPoint);
233236
Annotated annotated = injectionPoint.getAnnotated();
234237
if (annotated instanceof AnnotatedField) { // InjectionPoint on Field
235238
validateFieldInjectionPoint(injectionPoint);
@@ -243,6 +246,22 @@ public void validate(InjectionPoint injectionPoint) {
243246
}
244247
}
245248

249+
/**
250+
* Any legal bean type may be the required type of an injection point.
251+
* Furthermore, the required type of an injection point may contain a wildcard type parameter.
252+
* However, a type variable is not a legal injection point type.
253+
*
254+
* @param injectionPoint {@link InjectionPoint}
255+
* @throws DefinitionException If an injection point type is a type variable, the container automatically
256+
* detects the problem and treats it as a definition error.
257+
*/
258+
private void validateInjectionPointType(InjectionPoint injectionPoint) throws DefinitionException {
259+
Type type = injectionPoint.getType();
260+
if(type instanceof TypeVariable){
261+
throw newDefinitionException("A type variable[%s] is not a legal injection point[%s] type",type,injectionPoint);
262+
}
263+
}
264+
246265
/**
247266
* @param injectionPoint {@link InjectionPoint}
248267
* @throws DefinitionException If an injected field is annotated @Produces, the container automatically detects
@@ -276,52 +295,6 @@ private void validateMethodParameterInjectionPoint(InjectionPoint injectionPoint
276295
validateForbiddenAnnotation(injectionPoint, ObservesAsync.class);
277296
}
278297

279-
/**
280-
* Is defining annotation type or not.
281-
* <p>
282-
* A bean class may have a bean defining annotation, allowing it to be placed anywhere in an application,
283-
* as defined in Bean archives. A bean class with a bean defining annotation is said to be an implicit bean.
284-
* The set of bean defining annotations contains:
285-
* <ul>
286-
* <li>{@link ApplicationScoped @ApplicationScoped}, {@link SessionScoped @SessionScoped},
287-
* {@link ConversationScoped @ConversationScoped} and {@link RequestScoped @RequestScoped} annotations
288-
* </li>
289-
* <li>all other normal scope types</li>
290-
* <li>{@link javax.interceptor.Interceptor @Interceptor} and {@link javax.decorator.Decorator @Decorator} annotations</li>
291-
* <li>all stereotype annotations (i.e. annotations annotated with {@link Stereotype @Stereotype})</li>
292-
* <li>the {@link Dependent @Dependent} scope annotation</li>
293-
* </ul>
294-
*
295-
* @param type
296-
* @param includedInterceptor
297-
* @param includedDecorator
298-
* @return
299-
*/
300-
public boolean isDefiningAnnotationType(Class<?> type, boolean includedInterceptor, boolean includedDecorator) {
301-
302-
if (includedInterceptor && interceptorManager.isInterceptorClass(type)) {
303-
return true;
304-
}
305-
if (includedDecorator && isDecorator(type)) {
306-
return true;
307-
}
308-
309-
boolean hasDefiningAnnotation = false;
310-
311-
Annotation[] annotations = type.getAnnotations();
312-
for (Annotation annotation : annotations) {
313-
Class<? extends Annotation> annotationType = annotation.annotationType();
314-
if (isScope(annotationType) ||
315-
isNormalScope(annotationType) ||
316-
isStereotype(annotationType)) {
317-
hasDefiningAnnotation = true;
318-
break;
319-
}
320-
}
321-
322-
return hasDefiningAnnotation;
323-
}
324-
325298
@Override
326299
@Deprecated
327300
public void fireEvent(Object event, Annotation... qualifiers) {
@@ -566,6 +539,53 @@ public void initialize() {
566539
// TODO
567540
}
568541

542+
543+
/**
544+
* Is defining annotation type or not.
545+
* <p>
546+
* A bean class may have a bean defining annotation, allowing it to be placed anywhere in an application,
547+
* as defined in Bean archives. A bean class with a bean defining annotation is said to be an implicit bean.
548+
* The set of bean defining annotations contains:
549+
* <ul>
550+
* <li>{@link ApplicationScoped @ApplicationScoped}, {@link SessionScoped @SessionScoped},
551+
* {@link ConversationScoped @ConversationScoped} and {@link RequestScoped @RequestScoped} annotations
552+
* </li>
553+
* <li>all other normal scope types</li>
554+
* <li>{@link javax.interceptor.Interceptor @Interceptor} and {@link javax.decorator.Decorator @Decorator} annotations</li>
555+
* <li>all stereotype annotations (i.e. annotations annotated with {@link Stereotype @Stereotype})</li>
556+
* <li>the {@link Dependent @Dependent} scope annotation</li>
557+
* </ul>
558+
*
559+
* @param type
560+
* @param includedInterceptor
561+
* @param includedDecorator
562+
* @return
563+
*/
564+
public boolean isDefiningAnnotationType(Class<?> type, boolean includedInterceptor, boolean includedDecorator) {
565+
566+
if (includedInterceptor && interceptorManager.isInterceptorClass(type)) {
567+
return true;
568+
}
569+
if (includedDecorator && isDecorator(type)) {
570+
return true;
571+
}
572+
573+
boolean hasDefiningAnnotation = false;
574+
575+
Annotation[] annotations = type.getAnnotations();
576+
for (Annotation annotation : annotations) {
577+
Class<? extends Annotation> annotationType = annotation.annotationType();
578+
if (isScope(annotationType) ||
579+
isNormalScope(annotationType) ||
580+
isStereotype(annotationType)) {
581+
hasDefiningAnnotation = true;
582+
break;
583+
}
584+
}
585+
586+
return hasDefiningAnnotation;
587+
}
588+
569589
public void addDefinitionError(Throwable t) {
570590
this.definitionErrors.add(new DefinitionException(t));
571591
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.geektimes.enterprise.inject.standard.producer;
18+
19+
import org.geektimes.enterprise.inject.standard.MethodParameterInjectionPoint;
20+
import org.geektimes.enterprise.inject.standard.beans.manager.StandardBeanManager;
21+
import org.geektimes.enterprise.inject.standard.disposer.DisposerMethodManager;
22+
23+
import javax.enterprise.context.spi.CreationalContext;
24+
import javax.enterprise.inject.spi.AnnotatedParameter;
25+
import javax.enterprise.inject.spi.Bean;
26+
import javax.enterprise.inject.spi.InjectionPoint;
27+
import javax.enterprise.inject.spi.Producer;
28+
import java.util.Set;
29+
30+
import static java.util.Collections.unmodifiableSet;
31+
32+
/**
33+
* Abstract implementation of {@link Producer}
34+
*
35+
* @param <T> The class of object produced by the producer
36+
* @param <X> THe class of {@link Bean}
37+
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
38+
* @since 1.0.0
39+
*/
40+
public abstract class AbstractProducer<T, X> implements Producer<T> {
41+
42+
private final Bean<X> declaringBean;
43+
44+
private final StandardBeanManager standardBeanManager;
45+
46+
private Set<InjectionPoint> injectionPoints;
47+
48+
public AbstractProducer(Bean<X> declaringBean, StandardBeanManager standardBeanManager) {
49+
this.declaringBean = declaringBean;
50+
this.standardBeanManager = standardBeanManager;
51+
}
52+
53+
@Override
54+
public void dispose(T instance) {
55+
DisposerMethodManager disposerMethodManager = standardBeanManager.getDisposerMethodManager();
56+
disposerMethodManager.invokeDisposerMethod(instance);
57+
}
58+
59+
@Override
60+
public final Set<InjectionPoint> getInjectionPoints() {
61+
if (injectionPoints == null) {
62+
injectionPoints = unmodifiableSet(resolveInjectionPoints());
63+
}
64+
return injectionPoints;
65+
}
66+
67+
protected Bean<X> getDeclaringBean() {
68+
return declaringBean;
69+
}
70+
71+
protected StandardBeanManager getStandardBeanManager() {
72+
return standardBeanManager;
73+
}
74+
75+
protected Object[] resolveInjectedArguments(CreationalContext<T> ctx) {
76+
Set<InjectionPoint> injectionPoints = getInjectionPoints();
77+
Object[] injectedArguments = new Object[injectionPoints.size()];
78+
79+
injectionPoints
80+
.stream()
81+
.map(MethodParameterInjectionPoint.class::cast)
82+
.forEach(injectionPoint -> {
83+
AnnotatedParameter parameter = injectionPoint.getAnnotated();
84+
injectedArguments[parameter.getPosition()] = standardBeanManager.getInjectableReference(injectionPoint, ctx);
85+
});
86+
87+
return injectedArguments;
88+
}
89+
90+
protected Object getDeclaringBeanInstance(CreationalContext<T> ctx) {
91+
Bean<X> declaringBean = getDeclaringBean();
92+
return standardBeanManager.getReference(declaringBean, declaringBean.getBeanClass(), ctx);
93+
}
94+
95+
protected abstract Set<InjectionPoint> resolveInjectionPoints();
96+
97+
}

projects/stage-1/middleware-frameworks/my-cdi/src/main/java/org/geektimes/enterprise/inject/standard/producer/AnnotatedFieldProducer.java

+6-16
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.geektimes.enterprise.inject.standard.producer;
1818

1919
import org.geektimes.enterprise.inject.standard.beans.manager.StandardBeanManager;
20-
import org.geektimes.enterprise.inject.standard.disposer.DisposerMethodManager;
2120

2221
import javax.enterprise.context.spi.CreationalContext;
2322
import javax.enterprise.inject.CreationException;
@@ -38,20 +37,13 @@
3837
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
3938
* @since 1.0.0
4039
*/
41-
public class AnnotatedFieldProducer<T, X> implements Producer<T> {
40+
public class AnnotatedFieldProducer<T, X> extends AbstractProducer<T, X> {
4241

4342
private final AnnotatedField<T> producerField;
4443

45-
private final Bean<X> declaringBean;
46-
47-
private final StandardBeanManager standardBeanManager;
48-
49-
private Set<InjectionPoint> injectionPoints;
50-
5144
public AnnotatedFieldProducer(AnnotatedField<T> producerField, Bean<X> declaringBean, StandardBeanManager standardBeanManager) {
45+
super(declaringBean, standardBeanManager);
5246
this.producerField = producerField;
53-
this.declaringBean = declaringBean;
54-
this.standardBeanManager = standardBeanManager;
5547
}
5648

5749
@Override
@@ -63,7 +55,7 @@ public T produce(CreationalContext<T> ctx) {
6355
final T beanInstance;
6456
try {
6557
if (!isStatic(field)) {
66-
instance = standardBeanManager.getReference(declaringBean, declaringBean.getBeanClass(), ctx);
58+
instance = getDeclaringBeanInstance(ctx);
6759
}
6860
beanInstance = (T) field.get(instance);
6961
} catch (Throwable e) {
@@ -72,14 +64,12 @@ public T produce(CreationalContext<T> ctx) {
7264
return beanInstance;
7365
}
7466

75-
@Override
76-
public void dispose(T instance) {
77-
DisposerMethodManager disposerMethodManager = standardBeanManager.getDisposerMethodManager();
78-
disposerMethodManager.invokeDisposerMethod(instance);
67+
public AnnotatedField<T> getProducerField() {
68+
return producerField;
7969
}
8070

8171
@Override
82-
public Set<InjectionPoint> getInjectionPoints() {
72+
protected Set<InjectionPoint> resolveInjectionPoints() {
8373
return emptySet();
8474
}
8575
}

0 commit comments

Comments
 (0)