1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.config.annotation;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.commons.discovery.resource.ClassLoaders;
24 import org.apache.commons.discovery.resource.names.DiscoverServiceNames;
25 import org.apache.commons.discovery.ResourceNameIterator;
26 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
27 import org.apache.myfaces.shared_impl.util.ClassUtils;
28
29 import javax.faces.context.ExternalContext;
30 import javax.naming.Context;
31 import javax.naming.InitialContext;
32 import javax.naming.NamingException;
33 import java.lang.reflect.InvocationTargetException;
34 import java.lang.reflect.Constructor;
35
36
37
38
39
40 public class DefaultLifecycleProviderFactory extends LifecycleProviderFactory {
41 private static Log log = LogFactory.getLog(DefaultLifecycleProviderFactory.class);
42 public static final String LIFECYCLE_PROVIDER_INSTANCE_KEY = LifecycleProvider.class.getName() + ".LIFECYCLE_PROVIDER_INSTANCE";
43
44 @JSFWebConfigParam(name="org.apache.myfaces.config.annotation.LifecycleProvider", since="1.1")
45 public static final String LIFECYCLE_PROVIDER = LifecycleProvider.class.getName();
46
47
48 public DefaultLifecycleProviderFactory()
49 {
50 }
51
52 @Override
53 public LifecycleProvider getLifecycleProvider(ExternalContext externalContext)
54 {
55 LifecycleProvider lifecycleProvider = null;
56 if (externalContext == null)
57 {
58 log.info("No ExternalContext using fallback LifecycleProvider.");
59 lifecycleProvider = resolveFallbackLifecycleProvider();
60 }
61 else
62 {
63 lifecycleProvider = (LifecycleProvider) externalContext.getApplicationMap().get(LIFECYCLE_PROVIDER_INSTANCE_KEY);
64 }
65 if (lifecycleProvider == null)
66 {
67 if (!resolveLifecycleProviderFromExternalContext(externalContext))
68 {
69 if (!resolveLifecycleProviderFromService(externalContext))
70 {
71 lifecycleProvider = resolveFallbackLifecycleProvider();
72 externalContext.getApplicationMap().put(LIFECYCLE_PROVIDER_INSTANCE_KEY, lifecycleProvider);
73 }
74 else
75 {
76
77 lifecycleProvider = (LifecycleProvider) externalContext.getApplicationMap().get(LIFECYCLE_PROVIDER_INSTANCE_KEY);
78 }
79 }
80 else
81 {
82
83 lifecycleProvider = (LifecycleProvider) externalContext.getApplicationMap().get(LIFECYCLE_PROVIDER_INSTANCE_KEY);
84 }
85 log.info("Using LifecycleProvider "+ lifecycleProvider.getClass().getName());
86 }
87 return lifecycleProvider;
88 }
89
90 @Override
91 public void release() {
92
93 }
94
95
96
97 private boolean resolveLifecycleProviderFromExternalContext(ExternalContext externalContext)
98 {
99 try
100 {
101 String lifecycleProvider = externalContext.getInitParameter(LIFECYCLE_PROVIDER);
102 if (lifecycleProvider != null)
103 {
104
105 Object obj = createClass(lifecycleProvider, externalContext);
106
107 if (obj instanceof LifecycleProvider) {
108 externalContext.getApplicationMap().put(LIFECYCLE_PROVIDER_INSTANCE_KEY, (LifecycleProvider) obj);
109 return true;
110 }
111 }
112 }
113 catch (ClassNotFoundException e)
114 {
115 log.error("", e);
116 }
117 catch (InstantiationException e)
118 {
119 log.error("", e);
120 }
121 catch (IllegalAccessException e)
122 {
123 log.error("", e);
124 }
125 catch (InvocationTargetException e)
126 {
127 log.error("", e);
128 }
129 return false;
130 }
131
132
133 private boolean resolveLifecycleProviderFromService(ExternalContext externalContext) {
134 ClassLoader classLoader = ClassUtils.getContextClassLoader();
135 ClassLoaders loaders = new ClassLoaders();
136 loaders.put(classLoader);
137 loaders.put(this.getClass().getClassLoader());
138 DiscoverServiceNames dsn = new DiscoverServiceNames(loaders);
139 ResourceNameIterator iter = dsn.findResourceNames(LIFECYCLE_PROVIDER);
140 while (iter.hasNext()) {
141 String className = iter.nextResourceName();
142 try
143 {
144 Object obj = createClass(className, externalContext);
145 if (DiscoverableLifecycleProvider.class.isAssignableFrom(obj.getClass())) {
146 DiscoverableLifecycleProvider discoverableLifecycleProvider =
147 (DiscoverableLifecycleProvider) obj;
148 if (discoverableLifecycleProvider.isAvailable()) {
149 externalContext.getApplicationMap().put(LIFECYCLE_PROVIDER_INSTANCE_KEY, discoverableLifecycleProvider);
150 return true;
151 }
152 }
153 }
154 catch (ClassNotFoundException e)
155 {
156
157 }
158 catch (NoClassDefFoundError e)
159 {
160
161 }
162 catch (InstantiationException e)
163 {
164 log.error("", e);
165 }
166 catch (IllegalAccessException e)
167 {
168 log.error("", e);
169 }
170 catch (InvocationTargetException e)
171 {
172 log.error("", e);
173 }
174 }
175 return false;
176 }
177
178 private Object createClass(String className, ExternalContext externalContext)
179 throws InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException
180 {
181 Class clazz = ClassUtils.classForName(className);
182
183 Object obj;
184 try
185 {
186 Constructor constructor = clazz.getConstructor(ExternalContext.class);
187 obj = constructor.newInstance(externalContext);
188 }
189 catch (NoSuchMethodException e)
190 {
191 obj = clazz.newInstance();
192 }
193 return obj;
194 }
195
196
197 private LifecycleProvider resolveFallbackLifecycleProvider()
198 {
199 try
200 {
201 ClassUtils.classForName("javax.annotation.PreDestroy");
202 }
203 catch (ClassNotFoundException e)
204 {
205
206 return new NoAnnotationLifecyleProvider();
207 }
208 Context context;
209 try
210 {
211 context = new InitialContext();
212 try
213 {
214 ClassUtils.classForName("javax.ejb.EJB");
215
216 return new AllAnnotationLifecycleProvider(context);
217 }
218 catch (ClassNotFoundException e)
219 {
220
221 return new ResourceAnnotationLifecycleProvider(context);
222 }
223 }
224 catch (NamingException e)
225 {
226
227 log.error("No InitialContext found. Using NoInjectionAnnotationProcessor.", e);
228 return new NoInjectionAnnotationLifecycleProvider();
229 }
230 }
231 }