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

Commit cdcfaad

Browse files
japodjerseyrobot
authored andcommitted
JERSEY-2526: CDI producer for JAX-RS String parameters clashes with application producers
Change-Id: I1e195d68c0b9b836bb1f1a5a5d87f2e399b2a3f8 Signed-off-by: Jakub Podlesak <[email protected]>
1 parent 46bd842 commit cdcfaad

File tree

6 files changed

+424
-6
lines changed

6 files changed

+424
-6
lines changed

containers/glassfish/jersey-gf-cdi/src/main/java/org/glassfish/jersey/gf/cdi/internal/CdiComponentProvider.java

Lines changed: 204 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
package org.glassfish.jersey.gf.cdi.internal;
4141

4242
import java.lang.annotation.Annotation;
43+
import java.lang.annotation.Target;
44+
import java.lang.annotation.Retention;
45+
4346
import java.lang.reflect.Field;
4447
import java.lang.reflect.Member;
4548
import java.lang.reflect.Method;
@@ -121,6 +124,13 @@
121124
import org.glassfish.jersey.model.internal.RankedComparator;
122125
import org.glassfish.jersey.model.internal.RankedProvider;
123126

127+
import static java.lang.annotation.ElementType.FIELD;
128+
import static java.lang.annotation.ElementType.METHOD;
129+
import static java.lang.annotation.ElementType.PARAMETER;
130+
import static java.lang.annotation.ElementType.TYPE;
131+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
132+
import java.lang.reflect.Constructor;
133+
124134
/**
125135
* Jersey CDI integration implementation.
126136
* Implements {@link ComponentProvider Jersey component provider} to serve CDI beans
@@ -274,6 +284,30 @@ public void initialize(final ServiceLocator locator) {
274284
@ApplicationScoped
275285
public static class JaxRsParamProducer {
276286

287+
@Qualifier
288+
@Retention(RUNTIME)
289+
@Target({METHOD, FIELD, PARAMETER, TYPE})
290+
public static @interface JaxRsParamQualifier {
291+
}
292+
293+
private static final JaxRsParamQualifier JaxRsParamQUALIFIER = new JaxRsParamQualifier() {
294+
295+
@Override
296+
public Class<? extends Annotation> annotationType() {
297+
return JaxRsParamQualifier.class;
298+
}
299+
};
300+
301+
static final Set<Class<? extends Annotation>> JaxRsParamAnnotationTYPES = new HashSet<Class<? extends Annotation>>() {
302+
{
303+
add(javax.ws.rs.PathParam.class);
304+
add(javax.ws.rs.QueryParam.class);
305+
add(javax.ws.rs.CookieParam.class);
306+
add(javax.ws.rs.HeaderParam.class);
307+
add(javax.ws.rs.MatrixParam.class);
308+
}
309+
};
310+
277311
/**
278312
* Internal cache to store CDI {@link InjectionPoint} to Jersey {@link Parameter} mapping.
279313
*/
@@ -304,14 +338,15 @@ public Parameter compute(final InjectionPoint injectionPoint) {
304338
});
305339

306340
/**
307-
* Provide a String value for given injection point. If the injection point does not refer
341+
* Provide a value for given injection point. If the injection point does not refer
308342
* to a CDI bean constructor parameter, or the value could not be found, the method will return null.
309343
*
310344
* @param injectionPoint actual injection point.
311345
* @param beanManager current application bean manager.
312-
* @return String value for given injection point.
346+
* @return concrete JAX-RS parameter value for given injection point.
313347
*/
314348
@javax.enterprise.inject.Produces
349+
@JaxRsParamQualifier
315350
public String getParameterValue(final InjectionPoint injectionPoint, final BeanManager beanManager) {
316351

317352
final Parameter parameter = parameterCache.compute(injectionPoint);
@@ -325,7 +360,7 @@ public String getParameterValue(final InjectionPoint injectionPoint, final BeanM
325360
for (final ValueFactoryProvider vfp : providers) {
326361
final Factory<?> valueFactory = vfp.getValueFactory(parameter);
327362
if (valueFactory != null) {
328-
return (String) valueFactory.provide();
363+
return (String)valueFactory.provide();
329364
}
330365
}
331366
}
@@ -405,15 +440,180 @@ private boolean isManagedBean(final Class<?> component) {
405440
return component.isAnnotationPresent(ManagedBean.class);
406441
}
407442

443+
private static AnnotatedConstructor<?> enrichedConstructor(final AnnotatedConstructor<?> ctor) {
444+
return new AnnotatedConstructor(){
445+
446+
@Override
447+
public Constructor getJavaMember() {
448+
return ctor.getJavaMember();
449+
}
450+
451+
@Override
452+
public List<AnnotatedParameter> getParameters() {
453+
final List<AnnotatedParameter> parameters = new ArrayList<AnnotatedParameter>(ctor.getParameters().size());
454+
455+
for (final AnnotatedParameter<?> ap : ctor.getParameters()) {
456+
parameters.add(new AnnotatedParameter(){
457+
458+
@Override
459+
public int getPosition() {
460+
return ap.getPosition();
461+
}
462+
463+
@Override
464+
public AnnotatedCallable getDeclaringCallable() {
465+
return ap.getDeclaringCallable();
466+
}
467+
468+
@Override
469+
public Type getBaseType() {
470+
return ap.getBaseType();
471+
}
472+
473+
@Override
474+
public Set<Type> getTypeClosure() {
475+
return ap.getTypeClosure();
476+
}
477+
478+
@Override
479+
public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
480+
if (annotationType == JaxRsParamProducer.JaxRsParamQualifier.class) {
481+
return isJaxRsParamAnnotationPresent() ? (T)JaxRsParamProducer.JaxRsParamQUALIFIER : null;
482+
} else {
483+
return ap.getAnnotation(annotationType);
484+
}
485+
}
486+
487+
@Override
488+
public Set<Annotation> getAnnotations() {
489+
final Set<Annotation> result = new HashSet<Annotation>();
490+
for (Annotation a : ap.getAnnotations()) {
491+
result.add(a);
492+
final Class<? extends Annotation> annotationType = a.annotationType();
493+
if (JaxRsParamProducer.JaxRsParamAnnotationTYPES.contains(annotationType)) {
494+
result.add(JaxRsParamProducer.JaxRsParamQUALIFIER);
495+
}
496+
}
497+
return result;
498+
}
499+
500+
@Override
501+
public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
502+
return (annotationType == JaxRsParamProducer.JaxRsParamQualifier.class && isJaxRsParamAnnotationPresent())
503+
|| ap.isAnnotationPresent(annotationType);
504+
}
505+
506+
private boolean isJaxRsParamAnnotationPresent() {
507+
for (Class<? extends Annotation> a : JaxRsParamProducer.JaxRsParamAnnotationTYPES) {
508+
if(ap.isAnnotationPresent(a)) {
509+
return true;
510+
}
511+
}
512+
return false;
513+
}
514+
});
515+
}
516+
return parameters;
517+
}
518+
519+
@Override
520+
public boolean isStatic() {
521+
return ctor.isStatic();
522+
}
523+
524+
@Override
525+
public AnnotatedType getDeclaringType() {
526+
return ctor.getDeclaringType();
527+
}
528+
529+
@Override
530+
public Type getBaseType() {
531+
return ctor.getBaseType();
532+
}
533+
534+
@Override
535+
public Set<Type> getTypeClosure() {
536+
return ctor.getTypeClosure();
537+
}
538+
539+
@Override
540+
public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
541+
return ctor.getAnnotation(annotationType);
542+
}
543+
544+
@Override
545+
public Set<Annotation> getAnnotations() {
546+
return ctor.getAnnotations();
547+
}
548+
549+
@Override
550+
public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
551+
return ctor.isAnnotationPresent(annotationType);
552+
}
553+
};
554+
}
555+
408556
@SuppressWarnings("unused")
409557
private void processAnnotatedType(@Observes final ProcessAnnotatedType processAnnotatedType) {
558+
final AnnotatedType annotatedType = processAnnotatedType.getAnnotatedType();
410559
if (customHk2TypesProvider != null) {
411-
final Type baseType = processAnnotatedType.getAnnotatedType().getBaseType();
560+
final Type baseType = annotatedType.getBaseType();
412561
if (customHk2TypesProvider.getHk2Types().contains(baseType)) {
413562
processAnnotatedType.veto();
414563
jerseyVetoedTypes.add(baseType);
415564
}
416565
}
566+
processAnnotatedType.setAnnotatedType(new AnnotatedType(){
567+
568+
@Override
569+
public Class getJavaClass() {
570+
return annotatedType.getJavaClass();
571+
}
572+
573+
@Override
574+
public Set<AnnotatedConstructor> getConstructors() {
575+
Set<AnnotatedConstructor> result = new HashSet<AnnotatedConstructor>();
576+
for (AnnotatedConstructor c : (Set<AnnotatedConstructor>)annotatedType.getConstructors()) {
577+
result.add(enrichedConstructor(c));
578+
}
579+
return result;
580+
}
581+
582+
@Override
583+
public Set getMethods() {
584+
return annotatedType.getMethods();
585+
}
586+
587+
@Override
588+
public Set getFields() {
589+
return annotatedType.getFields();
590+
}
591+
592+
@Override
593+
public Type getBaseType() {
594+
return annotatedType.getBaseType();
595+
}
596+
597+
@Override
598+
public Set<Type> getTypeClosure() {
599+
return annotatedType.getTypeClosure();
600+
}
601+
602+
@Override
603+
public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
604+
return annotatedType.getAnnotation(annotationType);
605+
}
606+
607+
@Override
608+
public Set<Annotation> getAnnotations() {
609+
return annotatedType.getAnnotations();
610+
}
611+
612+
@Override
613+
public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
614+
return annotatedType.isAnnotationPresent(annotationType);
615+
}
616+
});
417617
}
418618

419619
@SuppressWarnings("unused")

examples/cdi-webapp/src/main/java/org/glassfish/jersey/examples/cdi/resources/EchoParamConstructorResource.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33
*
4-
* Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved.
55
*
66
* The contents of this file are subject to the terms of either the GNU
77
* General Public License Version 2 only ("GPL") or the Common Development
@@ -86,4 +86,4 @@ private void postConstruct() {
8686
public String get() {
8787
return "ECHO " + a;
8888
}
89-
}
89+
}

0 commit comments

Comments
 (0)