Skip to content
This repository was archived by the owner on May 28, 2018. It is now read-only.

Commit fa6927b

Browse files
Petr Boudapavelbucek
authored andcommitted
Initial commit of CDI SE implementation.
- Registration of internal Jersey components and components registered in Application class - Supports for getting Suppliers from CdiSeInjectionManager - Supports injection of JAX-RS/Jersey components (@*Param, @context annotations) - Creates proxies in Singleton and ApplicationScoped classes during the field injection - Integration tests prove that CDI interceptors, decorators, events are working - CDI 2 SE HelloWorld example Change-Id: I67a491704699cd39ace000d2277bac9c9d7c2020
1 parent 9add7e3 commit fa6927b

File tree

134 files changed

+12153
-393
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

134 files changed

+12153
-393
lines changed

bom/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@
336336
<artifactId>jersey-hk2</artifactId>
337337
<version>${project.version}</version>
338338
</dependency>
339+
<dependency>
340+
<groupId>org.glassfish.jersey.inject</groupId>
341+
<artifactId>jersey-cdi2-se</artifactId>
342+
<version>${project.version}</version>
343+
</dependency>
339344
<dependency>
340345
<groupId>org.glassfish.jersey.test-framework</groupId>
341346
<artifactId>jersey-test-framework-core</artifactId>

core-client/src/main/java/org/glassfish/jersey/client/ClientRuntime.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import org.glassfish.jersey.message.MessageBodyWorkers;
7373
import org.glassfish.jersey.model.internal.ManagedObjectsFinalizer;
7474
import org.glassfish.jersey.process.internal.ChainableStage;
75+
import org.glassfish.jersey.process.internal.RequestContext;
7576
import org.glassfish.jersey.process.internal.RequestScope;
7677
import org.glassfish.jersey.process.internal.Stage;
7778
import org.glassfish.jersey.process.internal.Stages;
@@ -111,7 +112,7 @@ class ClientRuntime implements JerseyClient.ShutdownHook, ClientExecutor {
111112
public ClientRuntime(final ClientConfig config, final Connector connector, final InjectionManager injectionManager,
112113
final BootstrapBag bootstrapBag) {
113114
Provider<Ref<ClientRequest>> clientRequest =
114-
injectionManager.getInstance(new GenericType<Provider<Ref<ClientRequest>>>() {}.getType());
115+
() -> injectionManager.getInstance(new GenericType<Ref<ClientRequest>>() {}.getType());
115116

116117
RequestProcessingInitializationStage requestProcessingInitializationStage =
117118
new RequestProcessingInitializationStage(clientRequest, bootstrapBag.getMessageBodyWorkers(), injectionManager);
@@ -257,7 +258,7 @@ private ClientRequest addUserAgent(final ClientRequest clientRequest, final Stri
257258
* <p>
258259
* NOTE: the method does not explicitly start a new request scope context. Instead
259260
* it is assumed that the method is invoked from within a context of a proper, running
260-
* {@link RequestScope.Instance request scope instance}. A caller may use the
261+
* {@link RequestContext request context}. A caller may use the
261262
* {@link #getRequestScope()} method to retrieve the request scope instance and use it to
262263
* initialize the proper request scope context prior the method invocation.
263264
* </p>

core-client/src/main/java/org/glassfish/jersey/client/InboundJaxrsResponse.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import javax.ws.rs.core.Response;
5858

5959
import org.glassfish.jersey.internal.util.Producer;
60+
import org.glassfish.jersey.process.internal.RequestContext;
6061
import org.glassfish.jersey.process.internal.RequestScope;
6162

6263
/**
@@ -73,7 +74,7 @@ class InboundJaxrsResponse extends Response {
7374

7475
private final ClientResponse context;
7576
private final RequestScope scope;
76-
private final RequestScope.Instance scopeInstance;
77+
private final RequestContext requestContext;
7778

7879
/**
7980
* Create new scoped client response.
@@ -85,9 +86,9 @@ public InboundJaxrsResponse(final ClientResponse context, final RequestScope sco
8586
this.context = context;
8687
this.scope = scope;
8788
if (this.scope != null) {
88-
this.scopeInstance = scope.referenceCurrent();
89+
this.requestContext = scope.referenceCurrent();
8990
} else {
90-
this.scopeInstance = null;
91+
this.requestContext = null;
9192
}
9293
}
9394

@@ -165,8 +166,8 @@ public void close() throws ProcessingException {
165166
try {
166167
context.close();
167168
} finally {
168-
if (scopeInstance != null) {
169-
scopeInstance.release();
169+
if (requestContext != null) {
170+
requestContext.release();
170171
}
171172
}
172173
}
@@ -259,8 +260,8 @@ public String toString() {
259260
}
260261

261262
private <T> T runInScopeIfPossible(Producer<T> producer) {
262-
if (scope != null && scopeInstance != null) {
263-
return scope.runInScope(scopeInstance, producer);
263+
if (scope != null && requestContext != null) {
264+
return scope.runInScope(requestContext, producer);
264265
} else {
265266
return producer.call();
266267
}

core-common/src/main/java/org/glassfish/jersey/internal/inject/AliasBinding.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
*/
5454
public class AliasBinding {
5555

56-
private final String contract;
56+
private final Class<?> contract;
5757
private final Set<Annotation> qualifiers = new LinkedHashSet<>();
5858
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
5959
private Optional<String> scope = Optional.empty();
@@ -65,7 +65,7 @@ public class AliasBinding {
6565
*
6666
* @param contract contract of the alias.
6767
*/
68-
/* package */ AliasBinding(String contract) {
68+
/* package */ AliasBinding(Class<?> contract) {
6969
this.contract = contract;
7070
}
7171

@@ -74,7 +74,7 @@ public class AliasBinding {
7474
*
7575
* @return binding's contract.
7676
*/
77-
public String getContract() {
77+
public Class<?> getContract() {
7878
return contract;
7979
}
8080

core-common/src/main/java/org/glassfish/jersey/internal/inject/Binding.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public abstract class Binding<T, D extends Binding> {
6565
private final Set<AliasBinding> aliases = new HashSet<>();
6666
private Class<? extends Annotation> scope = null;
6767
private String name = null;
68-
private Type implementationType = null;
68+
private Class<T> implementationType = null;
6969
private String analyzer = null;
7070
private Boolean proxiable = null;
7171
private Boolean proxyForSameScope = null;
@@ -139,7 +139,7 @@ public String getName() {
139139
*
140140
* @return service's type.
141141
*/
142-
public Type getImplementationType() {
142+
public Class<T> getImplementationType() {
143143
return implementationType;
144144
}
145145

@@ -166,6 +166,7 @@ public Set<AliasBinding> getAliases() {
166166
*
167167
* @return current instance.
168168
*/
169+
// TODO: Candidate to remove, used only in legacy CDI integration.
169170
public D analyzeWith(String analyzer) {
170171
this.analyzer = analyzer;
171172
return (D) this;
@@ -252,10 +253,9 @@ public D named(String name) {
252253
* @param contract contract of the alias.
253254
* @return instance of a new alias for this binding descriptor that can be further specified.
254255
*/
255-
public AliasBinding addAlias(String contract) {
256+
public AliasBinding addAlias(Class<?> contract) {
256257
AliasBinding alias = new AliasBinding(contract);
257258
aliases.add(alias);
258-
259259
return alias;
260260
}
261261

@@ -293,8 +293,8 @@ public void ranked(int rank) {
293293
*
294294
* @return current instance.
295295
*/
296-
D asType(Type t) {
297-
this.implementationType = t;
296+
D asType(Class type) {
297+
this.implementationType = type;
298298
return (D) this;
299299
}
300300
}

core-common/src/main/java/org/glassfish/jersey/internal/inject/Bindings.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ public static <T> ClassBinding<T> serviceAsContract(Class<T> serviceType) {
105105
*/
106106
@SuppressWarnings("unchecked")
107107
public static <T> ClassBinding<T> service(GenericType<T> serviceType) {
108-
return (ClassBinding<T>) new ClassBinding<>(serviceType.getRawType()).asType(serviceType.getType());
108+
return (ClassBinding<T>) new ClassBinding<>(serviceType.getRawType())
109+
.asType((Class<T>) serviceType.getType());
109110
}
110111

111112
/**
@@ -120,7 +121,7 @@ public static <T> ClassBinding<T> service(GenericType<T> serviceType) {
120121
@SuppressWarnings("unchecked")
121122
public static <T> ClassBinding<T> serviceAsContract(GenericType<T> serviceType) {
122123
return (ClassBinding<T>) new ClassBinding<>(serviceType.getRawType())
123-
.asType(serviceType.getType())
124+
.asType((Class<T>) serviceType.getType())
124125
.to(serviceType.getType());
125126
}
126127

@@ -136,7 +137,7 @@ public static <T> ClassBinding<T> serviceAsContract(GenericType<T> serviceType)
136137
@SuppressWarnings("unchecked")
137138
public static <T> ClassBinding<T> serviceAsContract(Type serviceType) {
138139
return new ClassBinding<>((Class<T>) ReflectionHelper.getRawClass(serviceType))
139-
.asType(serviceType)
140+
.asType((Class<T>) serviceType)
140141
.to(serviceType);
141142
}
142143

core-common/src/main/java/org/glassfish/jersey/internal/inject/ClassBinding.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public class ClassBinding<T> extends Binding<T, ClassBinding<T>> {
5757
*/
5858
ClassBinding(Class<T> service) {
5959
this.service = service;
60+
asType(service);
6061
}
6162

6263
/**

core-common/src/main/java/org/glassfish/jersey/internal/inject/Injectee.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,23 @@ public interface Injectee {
110110
ForeignDescriptor getInjecteeDescriptor();
111111

112112
/**
113-
* This method returns {@code true} if the injectee value is provided using factory class.
113+
* This method returns scope in which the parent class is registered.
114+
*
115+
* @return scope annotation.
116+
*/
117+
Class<? extends Annotation> getParentClassScope();
118+
119+
/**
120+
* This method returns {@code true} if the injectee value is provided using {@link java.util.function.Supplier}.
114121
*
115122
* @return {@code true} if the injectee is a factory.
116123
*/
117124
boolean isFactory();
125+
126+
/**
127+
* This method returns {@code true} if the injectee value is provided using {@link javax.inject.Provider}.
128+
*
129+
* @return {@code true} if the injectee is a provider.
130+
*/
131+
boolean isProvider();
118132
}

core-common/src/main/java/org/glassfish/jersey/internal/inject/InjecteeImpl.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,11 @@
4747
import java.lang.reflect.Method;
4848
import java.lang.reflect.Type;
4949
import java.util.Collections;
50+
import java.util.Objects;
5051
import java.util.Set;
5152

53+
import org.glassfish.jersey.internal.util.Pretty;
54+
5255
/**
5356
* An Injectee represents the point of injection. It can be used by injection resolvers to discover all of the information
5457
* available about the entity being injected into.
@@ -57,11 +60,13 @@ public class InjecteeImpl implements Injectee {
5760

5861
private Type requiredType;
5962
private Set<Annotation> qualifiers;
63+
private Class<? extends Annotation> parentClassScope;
6064
private int position = -1;
6165
private Class<?> injecteeClass;
6266
private AnnotatedElement parent;
6367
private boolean isOptional = false;
6468
private boolean isFactory = false;
69+
private boolean isProvider = false;
6570
private ForeignDescriptor injecteeDescriptor;
6671

6772
@Override
@@ -96,6 +101,21 @@ public void setRequiredQualifiers(Set<Annotation> requiredQualifiers) {
96101

97102
}
98103

104+
@Override
105+
public Class<? extends Annotation> getParentClassScope() {
106+
return parentClassScope;
107+
}
108+
109+
110+
/**
111+
* Sets the scope in which the parent class is registered.
112+
*
113+
* @return parent class scope.
114+
*/
115+
public void setParentClassScope(Class<? extends Annotation> parentClassScope) {
116+
this.parentClassScope = parentClassScope;
117+
}
118+
99119
@Override
100120
public boolean isFactory() {
101121
return isFactory;
@@ -110,6 +130,20 @@ public void setFactory(boolean factory) {
110130
isFactory = factory;
111131
}
112132

133+
@Override
134+
public boolean isProvider() {
135+
return isProvider;
136+
}
137+
138+
/**
139+
* Sets a flag whether the injectee is a provider.
140+
*
141+
* @param provider {@code true} flag whether the injectee is provider.
142+
*/
143+
public void setProvider(boolean provider) {
144+
isProvider = provider;
145+
}
146+
113147
@Override
114148
public int getPosition() {
115149
return position;
@@ -188,4 +222,40 @@ public ForeignDescriptor getInjecteeDescriptor() {
188222
public void setInjecteeDescriptor(ForeignDescriptor injecteeDescriptor) {
189223
this.injecteeDescriptor = injecteeDescriptor;
190224
}
225+
226+
@Override
227+
public String toString() {
228+
return "InjecteeImpl(requiredType=" + Pretty.type(requiredType)
229+
+ ",parent=" + Pretty.clazz(parent.getClass())
230+
+ ",qualifiers=" + Pretty.collection(qualifiers)
231+
+ ",position=" + position
232+
+ ",factory=" + isFactory
233+
+ ",provider=" + isProvider
234+
+ ",optional=" + isOptional
235+
+ "," + System.identityHashCode(this) + ")";
236+
}
237+
238+
@Override
239+
public boolean equals(Object o) {
240+
if (this == o) {
241+
return true;
242+
}
243+
if (!(o instanceof InjecteeImpl)) {
244+
return false;
245+
}
246+
InjecteeImpl injectee = (InjecteeImpl) o;
247+
return position == injectee.position
248+
&& isOptional == injectee.isOptional
249+
&& isFactory == injectee.isFactory
250+
&& isProvider == injectee.isProvider
251+
&& Objects.equals(requiredType, injectee.requiredType)
252+
&& Objects.equals(qualifiers, injectee.qualifiers)
253+
&& Objects.equals(injecteeClass, injectee.injecteeClass)
254+
&& Objects.equals(parent, injectee.parent);
255+
}
256+
257+
@Override
258+
public int hashCode() {
259+
return Objects.hash(requiredType, qualifiers, position, injecteeClass, parent, isOptional, isFactory);
260+
}
191261
}

core-common/src/main/java/org/glassfish/jersey/internal/inject/Injections.java

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,16 @@
4040

4141
package org.glassfish.jersey.internal.inject;
4242

43-
import java.util.Iterator;
43+
import java.util.LinkedList;
44+
import java.util.List;
45+
import java.util.Optional;
4446

4547
import javax.ws.rs.WebApplicationException;
4648

4749
import org.glassfish.jersey.internal.LocalizationMessages;
4850
import org.glassfish.jersey.internal.ServiceFinder;
51+
import org.glassfish.jersey.model.internal.RankedComparator;
52+
import org.glassfish.jersey.model.internal.RankedProvider;
4953

5054
/**
5155
* Injection binding utility methods.
@@ -81,21 +85,35 @@ public static InjectionManager createInjectionManager(Binder binder) {
8185
* Creates an unnamed, parented {@link InjectionManager}. In case the {@code parent} injection manager is not specified, the
8286
* locator will not be parented.
8387
*
84-
* @param parent The parent of this injection manager. Services can be found in the parent (and all grand-parents). May be
85-
* {@code null}. An underlying DI provider checks whether the parent is in a proper type.
88+
* @param parent The parent of this injection manager. Services can be found in the parent (and all grand-parents). May be
89+
* {@code null}. An underlying DI provider checks whether the parent is in a proper type.
8690
* @return an injection manager with all the bindings.
8791
*/
8892
public static InjectionManager createInjectionManager(Object parent) {
8993
return lookupInjectionManagerFactory().create(parent);
9094
}
9195

9296
private static InjectionManagerFactory lookupInjectionManagerFactory() {
93-
Iterator<InjectionManagerFactory> iterator = ServiceFinder.find(InjectionManagerFactory.class).iterator();
94-
if (iterator.hasNext()) {
95-
return iterator.next();
96-
} else {
97-
throw new IllegalStateException(LocalizationMessages.INJECTION_MANAGER_FACTORY_NOT_FOUND());
97+
return lookupService(InjectionManagerFactory.class)
98+
.orElseThrow(() -> new IllegalStateException(LocalizationMessages.INJECTION_MANAGER_FACTORY_NOT_FOUND()));
99+
}
100+
101+
/**
102+
* Look for a service of given type. If more then one service is found the method sorts them are returns the one with highest
103+
* priority.
104+
*
105+
* @param clazz type of service to look for.
106+
* @param <T> type of service to look for.
107+
* @return instance of service with highest priority or {@code null} if service of given type cannot be found.
108+
* @see javax.annotation.Priority
109+
*/
110+
private static <T> Optional<T> lookupService(final Class<T> clazz) {
111+
List<RankedProvider<T>> providers = new LinkedList<>();
112+
for (T provider : ServiceFinder.find(clazz)) {
113+
providers.add(new RankedProvider<>(provider));
98114
}
115+
providers.sort(new RankedComparator<>(RankedComparator.Order.DESCENDING));
116+
return providers.isEmpty() ? Optional.empty() : Optional.ofNullable(providers.get(0).getProvider());
99117
}
100118

101119
/**

0 commit comments

Comments
 (0)