1+ /*
2+ * Copyright (c) 2012, 2013, Werner Keil, Credit Suisse (Anatole Tresch).
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+ * use this file except in compliance with the License. You may obtain a copy of
6+ * the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+ * License for the specific language governing permissions and limitations under
14+ * the License.
15+ *
16+ *
17+ * Contributors: Anatole Tresch - initial version.
18+ */
19+ package org .javamoney .cdi .bootstrap ;
20+
21+ import org .slf4j .Logger ;
22+ import org .slf4j .LoggerFactory ;
23+
24+ import java .lang .annotation .Annotation ;
25+ import java .util .*;
26+
27+ import javax .enterprise .context .spi .CreationalContext ;
28+ import javax .enterprise .inject .Instance ;
29+ import javax .enterprise .inject .Vetoed ;
30+ import javax .enterprise .inject .spi .Bean ;
31+ import javax .enterprise .inject .spi .BeanManager ;
32+ import javax .enterprise .inject .spi .CDI ;
33+ import javax .enterprise .util .TypeLiteral ;
34+ import javax .inject .Named ;
35+ import javax .naming .InitialContext ;
36+
37+ /**
38+ * Small utility class that glues together service loading and CDI, including support for different CDI version.
39+ */
40+ final class CDIAccessor {
41+
42+ private static final Logger LOG = LoggerFactory .getLogger (CDIAccessor .class );
43+
44+ private static final Instance <?> EMPTY_INSTANCE = new EmptyInstance <>();
45+
46+ private CDIAccessor () {
47+ }
48+
49+ private static <T > Instance <T > emptyInstance () {
50+ return Instance .class .cast (EMPTY_INSTANCE );
51+ }
52+
53+ public static <T > Optional <T > getInstance (Class <T > instanceType ,
54+ Annotation ... qualifiers ) {
55+ BeanManager man = getBeanManager ();
56+ if (man != null ) {
57+ return Optional .ofNullable (getInstanceByType (man , instanceType , qualifiers ));
58+ }
59+ return Optional .empty ();
60+ }
61+
62+ private static BeanManager getBeanManager () {
63+ // 1 try JNDI
64+ try {
65+ InitialContext ctx = new InitialContext ();
66+ BeanManager man = (BeanManager ) ctx .lookup ("comp:/env/BeanManager" );
67+ if (man != null ) {
68+ return man ;
69+ }
70+ } catch (Exception e ) {
71+ LoggerFactory .getLogger (CDIAccessor .class ).debug ("Unable to locate BeanManager from JNDI..." , e );
72+ }
73+ try {
74+ Class .forName ("javax.enterprise.inject.spi.CDI" );
75+ // OK CDI 1.1 is loaded
76+ return CDI .current ().getBeanManager ();
77+ } catch (ClassNotFoundException e ) {
78+ LoggerFactory .getLogger (CDIAccessor .class ).debug ("CDI accessor not available (CDI 1.0)." );
79+ } catch (Exception e ) {
80+ LoggerFactory .getLogger (CDIAccessor .class ).debug ("Unable to locate BeanManager from CDI providers..." , e );
81+ }
82+ // 3 error, CDI not loaded...
83+ throw new IllegalStateException ("CDI is not available." );
84+ }
85+
86+ /**
87+ * Utility method allowing managed instances of beans to provide entry points
88+ * for non-managed beans (such as {@link org.jboss.weld.environment.se.WeldContainer}). Should only called
89+ * once Weld has finished booting.
90+ *
91+ * @param manager the BeanManager to use to access the managed instance
92+ * @param type the type of the Bean
93+ * @param bindings the bean's qualifiers
94+ * @return a managed instance of the bean
95+ * @throws IllegalArgumentException if the given type represents a type
96+ * variable
97+ * @throws IllegalArgumentException if two instances of the same qualifier
98+ * type are given
99+ * @throws IllegalArgumentException if an instance of an annotation that is
100+ * not a qualifier type is given
101+ * @throws javax.enterprise.inject.UnsatisfiedResolutionException if no beans can be resolved * @throws
102+ * AmbiguousResolutionException if the ambiguous dependency
103+ * resolution rules fail
104+ * @throws IllegalArgumentException if the given type is not a bean type of
105+ * the given bean
106+ */
107+ private static <T > T getInstanceByType (BeanManager manager , Class <T > type , Annotation ... bindings ) {
108+ final Bean <?> bean = manager .resolve (manager .getBeans (type ));
109+ if (bean == null ) {
110+ return null ;
111+ }
112+ CreationalContext <?> cc = manager .createCreationalContext (bean );
113+ return type .cast (manager .getReference (bean , type , cc ));
114+ }
115+
116+ public static <T > Instance <T > getInstances (Class <T > instanceType ,
117+ Annotation ... qualifiers ) {
118+ try {
119+ return getInstance (Instance .class ).get ().select (instanceType , qualifiers );
120+ } catch (Exception e ) {
121+ LOG .info ("Failed to load instances from CDI." , e );
122+ return emptyInstance ();
123+ }
124+ }
125+
126+ public static Set <?> getInstances (String name ) {
127+ try {
128+ return getBeanManager ().getBeans (name );
129+ } catch (Exception e ) {
130+ LOG .info ("Failed to load instances from CDI." , e );
131+ return Collections .emptySet ();
132+ }
133+
134+ }
135+
136+ public static void fireEvent (Object evt , Annotation ... qualifiers ) {
137+ try {
138+ getBeanManager ().fireEvent (evt , qualifiers );
139+ } catch (Exception e ) {
140+ LOG .info ("Failed to fire event from CDI." , e );
141+ }
142+ }
143+
144+ @ SuppressWarnings ("unchecked" )
145+ public static <T > T getNamedInstance (Class <T > type , String id ) {
146+ try {
147+ Set <?> found = getBeanManager ().getBeans (id );
148+ if (found .isEmpty ()) {
149+ return null ;
150+ }
151+ for (Object object : found ) {
152+ if (type .isAssignableFrom (object .getClass ())) {
153+ return (T ) object ;
154+ }
155+ }
156+ return null ;
157+ } catch (Exception e ) {
158+ LOG .info ("Failed to load instances from CDI." , e );
159+ return null ;
160+ }
161+
162+ }
163+
164+ public static String getName (Object o ) {
165+ if (o == null ) {
166+ return "<null>" ;
167+ }
168+ Named named = o .getClass ().getAnnotation (Named .class );
169+ if (named != null ) {
170+ return named .value ();
171+ }
172+ return o .getClass ().getSimpleName ();
173+ }
174+
175+ @ Vetoed
176+ private static final class EmptyInstance <T > implements Instance <T > {
177+ @ Override
178+ public Instance <T > select (Annotation ... annotations ) {
179+ return this ;
180+ }
181+
182+ @ Override
183+ public <U extends T > Instance <U > select (Class <U > uClass , Annotation ... annotations ) {
184+ return new EmptyInstance <>();
185+ }
186+
187+ @ Override
188+ public <U extends T > Instance <U > select (TypeLiteral <U > uTypeLiteral , Annotation ... annotations ) {
189+ return new EmptyInstance <>();
190+ }
191+
192+ @ Override
193+ public boolean isUnsatisfied () {
194+ return true ;
195+ }
196+
197+ @ Override
198+ public boolean isAmbiguous () {
199+ return false ;
200+ }
201+
202+ @ Override
203+ public void destroy (T t ) {
204+ }
205+
206+ @ Override
207+ public Iterator <T > iterator () {
208+ return Collections .emptyIterator ();
209+ }
210+
211+ @ Override
212+ public T get () {
213+ throw new NoSuchElementException ();
214+ }
215+ }
216+ }
0 commit comments