View Javadoc

1   /*
2    * $Id: ServicesRegistryImpl.java,v 1.18 2011/06/16 09:29:40 jbmeslin Exp $
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   * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
29   * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:40 $
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      * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
174      * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:40 $
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      * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
238      * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:40 $
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 }