1
2
3
4 package org.rcfaces.core.internal.config;
5
6 import java.io.IOException;
7 import java.io.Serializable;
8 import java.util.HashMap;
9 import java.util.Map;
10
11 import javax.faces.FacesException;
12 import javax.faces.context.FacesContext;
13 import javax.faces.event.PhaseEvent;
14 import javax.faces.event.PhaseId;
15 import javax.faces.event.PhaseListener;
16
17 import org.apache.commons.digester.Digester;
18 import org.apache.commons.digester.Rule;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.rcfaces.core.internal.service.IService;
22 import org.rcfaces.core.internal.service.IServicesRegistry;
23 import org.rcfaces.core.internal.util.ClassLocator;
24 import org.xml.sax.Attributes;
25
26
27
28
29
30
31 public class ServicesRegistryImpl extends AbstractRenderKitRegistryImpl
32 implements Serializable, PhaseListener, IServicesRegistry {
33 private static final String REVISION = "$Revision: 1.18 $";
34
35 private static final long serialVersionUID = -2873554843764179473L;
36
37 private static final Log LOG = LogFactory
38 .getLog(ServicesRegistryImpl.class);
39
40 private static final boolean TEST_SERVICE_WAIT = true;
41
42 protected static final String CAMELIA_HEADER = "X-Camelia";
43
44 private static final String SERVICE_WAIT_PROPERTY = "org.rcfaces.core.services.WAIT";
45
46 private static final String SERVICE_PROPERTY = "org.rcfaces.core.config.SERVICE_REGISTRY";
47
48 public ServicesRegistryImpl() {
49 }
50
51 protected String getApplicationPropertyId() {
52 return SERVICE_PROPERTY;
53 }
54
55 public IService getService(FacesContext facesContext, String renderKitId,
56 String serviceId) {
57
58 RenderKit renderKit = (RenderKit) getRenderKit(facesContext,
59 renderKitId);
60 if (renderKit == null) {
61 throw new FacesException(
62 "Can not get the service repository associated to the renderKit '"
63 + facesContext.getViewRoot().getRenderKitId()
64 + "' !");
65 }
66
67 ServiceFacade service = renderKit.getServiceById(serviceId);
68 if (service == null) {
69 throw new FacesException("Service '" + serviceId
70 + "' is not defined !");
71 }
72
73 return service.getService(facesContext);
74 }
75
76 public void beforePhase(PhaseEvent event) {
77
78 if (LOG.isDebugEnabled()) {
79 FacesContext facesContext = event.getFacesContext();
80
81 Map headers = facesContext.getExternalContext()
82 .getRequestHeaderMap();
83 String commandId = (String) headers.get(CAMELIA_HEADER);
84
85 LOG.debug("Before phase '" + event.getPhaseId() + "' viewId="
86 + facesContext.getViewRoot() + " commandId=" + commandId);
87 }
88 }
89
90 public final PhaseId getPhaseId() {
91 return PhaseId.RESTORE_VIEW;
92 }
93
94 public void afterPhase(PhaseEvent event) {
95 FacesContext facesContext = event.getFacesContext();
96
97 Map headers = facesContext.getExternalContext().getRequestHeaderMap();
98 String commandId = (String) headers.get(CAMELIA_HEADER);
99
100 if (LOG.isDebugEnabled()) {
101 LOG.debug("After phase '" + event.getPhaseId() + "' viewId="
102 + facesContext.getViewRoot() + " commandId=" + commandId);
103 }
104
105 if (commandId == null) {
106 return;
107 }
108
109 RenderKit renderKit = (RenderKit) getRenderKit(facesContext, null);
110 if (renderKit == null) {
111 throw new FacesException(
112 "Can not get the service repository associated to the renderKit '"
113 + facesContext.getViewRoot().getRenderKitId()
114 + "' !");
115 }
116
117 ServiceFacade facade = renderKit.getServiceByCommandId(commandId);
118 if (facade == null) {
119 LOG.error("Can not find command '" + commandId + "'.");
120
121 throw new FacesException("Can not find service '" + commandId
122 + "'.");
123 }
124
125 IService service = facade.getService(facesContext);
126
127 if (TEST_SERVICE_WAIT) {
128 String wait = facesContext.getExternalContext().getInitParameter(
129 SERVICE_WAIT_PROPERTY);
130
131 if (wait != null && wait.length() > 0) {
132
133 int w = Integer.parseInt(wait);
134
135 if (w > 0) {
136 synchronized (wait) {
137 LOG.debug("WAIT ...");
138 try {
139 wait.wait(w);
140
141 } catch (Exception ex) {
142 LOG.debug(ex);
143 }
144 }
145 }
146 }
147 }
148
149 try {
150 service.service(facesContext, commandId);
151
152 } catch (IOException ex) {
153 LOG.error("Call of service '" + commandId
154 + "' throw an IO exception !", ex);
155
156 } catch (RuntimeException ex) {
157 LOG.error("Call of service '" + commandId
158 + "' throw an exception !", ex);
159 }
160
161 if (LOG.isDebugEnabled()) {
162 LOG.debug("Service done viewId=" + facesContext.getViewRoot()
163 + " commandId=" + commandId);
164 }
165 }
166
167 protected AbstractRenderKitRegistryImpl.RenderKit createRenderKit() {
168 return new RenderKit();
169 }
170
171
172
173
174
175
176 public static final class ServiceFacade {
177 private static final String REVISION = "$Revision: 1.18 $";
178
179 private String className;
180
181 private String id;
182
183 private boolean unavailable;
184
185 private IService service;
186
187 public ServiceFacade() {
188 }
189
190 public final void setId(String id) {
191 this.id = id;
192 }
193
194 public final void setClassName(String className) {
195 this.className = className;
196 }
197
198 public synchronized IService getService(FacesContext facesContext) {
199 if (service != null) {
200 return service;
201 }
202
203 if (unavailable) {
204 throw new FacesException("Service '" + id
205 + "' is unavailable !");
206 }
207
208 try {
209 unavailable = true;
210
211 Class clazz = ClassLocator.load(className, this, facesContext);
212
213 service = (IService) clazz.newInstance();
214
215 service.initialize(facesContext);
216
217 unavailable = false;
218
219 return service;
220
221 } catch (Throwable th) {
222 LOG.error("Can not start service '" + id + "'.", th);
223
224 throw new FacesException("Can not start service '" + id + "'.",
225 th);
226 }
227
228 }
229
230 public String getId() {
231 return id;
232 }
233 }
234
235
236
237
238
239
240 public static class RenderKit extends
241 AbstractRenderKitRegistryImpl.RenderKit {
242 private static final String REVISION = "$Revision: 1.18 $";
243
244 private final Map serviceFacadeByCommandId;
245
246 private final Map serviceFacadeByServiceId;
247
248 public RenderKit() {
249 serviceFacadeByCommandId = new HashMap(32);
250
251 serviceFacadeByServiceId = new HashMap(16);
252 }
253
254 public ServiceFacade getServiceById(String serviceId) {
255 return (ServiceFacade) serviceFacadeByServiceId.get(serviceId);
256 }
257
258 public ServiceFacade getServiceByCommandId(String commandId) {
259 return (ServiceFacade) serviceFacadeByCommandId.get(commandId);
260 }
261
262 public void addService(ServiceFacade serviceFacade) {
263 serviceFacadeByServiceId.put(serviceFacade.getId(), serviceFacade);
264 }
265
266 public void addCommand(String commandId, ServiceFacade serviceFacade) {
267 serviceFacadeByCommandId.put(commandId, serviceFacade);
268 }
269
270 }
271
272 public void configureRules(Digester digester) {
273
274 digester.addRule("rcfaces-config/services/render-kit", new Rule() {
275 private static final String REVISION = "$Revision: 1.18 $";
276
277 public void begin(String namespace, String name,
278 Attributes attributes) throws Exception {
279
280 String renderKitId = attributes.getValue("render-kit-id");
281
282 RenderKit renderKit = (RenderKit) allocate(renderKitId);
283
284 super.digester.push(renderKit);
285 }
286
287 public void end(String namespace, String name) throws Exception {
288 super.digester.pop();
289 }
290 });
291
292 digester.addObjectCreate("rcfaces-config/services/render-kit/service",
293 ServiceFacade.class);
294 digester.addSetProperties("rcfaces-config/services/render-kit/service",
295 "id", "id");
296 digester.addSetProperties("rcfaces-config/services/render-kit/service",
297 "class", "className");
298 digester.addRule("rcfaces-config/services/render-kit/service/command",
299 new Rule() {
300 private static final String REVISION = "$Revision: 1.18 $";
301
302 public void begin(String namespace, String name,
303 Attributes attributes) throws Exception {
304
305 ServiceFacade service = (ServiceFacade) super.digester
306 .peek();
307 RenderKit renderKit = (RenderKit) super.digester
308 .peek(1);
309
310 String commandId = attributes.getValue("id");
311
312 renderKit.addCommand(commandId, service);
313 }
314 });
315 digester.addSetNext("rcfaces-config/services/render-kit/service",
316 "addService");
317 }
318 }