View Javadoc

1   /*
2    * $Id: Services.java,v 1.1 2008/01/22 13:28:59 oeuillot Exp $
3    */
4   package org.rcfaces.core.internal;
5   
6   import java.io.CharArrayReader;
7   import java.io.IOException;
8   import java.io.InputStream;
9   import java.net.URL;
10  import java.util.Enumeration;
11  import java.util.HashMap;
12  import java.util.Map;
13  
14  import org.apache.commons.digester.Digester;
15  import org.apache.commons.digester.Rule;
16  import org.apache.commons.logging.Log;
17  import org.apache.commons.logging.LogFactory;
18  import org.xml.sax.Attributes;
19  import org.xml.sax.EntityResolver;
20  import org.xml.sax.InputSource;
21  import org.xml.sax.SAXException;
22  
23  /**
24   * 
25   * @author Olivier Oeuillot (latest modification by $Author: oeuillot $)
26   * @version $Revision: 1.1 $ $Date: 2008/01/22 13:28:59 $
27   */
28  public class Services {
29      private static final String REVISION = "$Revision: 1.1 $";
30  
31      private static final Log LOG = LogFactory.getLog(Services.class);
32  
33      private static final Services SINGLETON = new Services();
34  
35      private static final String RESOURCE_NAME = "META-INF/rcfaces-services.xml";
36  
37      private boolean servicesLoaded = false;
38  
39      private final Map services = new HashMap(32);
40  
41      public static Services get() {
42          return SINGLETON;
43      }
44  
45      private Services() {
46      }
47  
48      public Object getService(String id) {
49          synchronized (services) {
50              if (servicesLoaded == false) {
51                  servicesLoaded = true;
52  
53                  loadServices();
54              }
55          }
56  
57          Object service = services.get(id);
58  
59          if (LOG.isDebugEnabled()) {
60              LOG.debug("Service '" + id + "' => " + service);
61          }
62  
63          return service;
64      }
65  
66      private void loadServices() {
67          LOG.info("Load services ...");
68  
69          ClassLoader threadClassLoader = Thread.currentThread()
70                  .getContextClassLoader();
71  
72          ClassLoader classLoader = Services.class.getClassLoader();
73  
74          if (threadClassLoader != null) {
75              loadServices(threadClassLoader);
76          }
77  
78          if (classLoader != threadClassLoader) {
79              loadServices(classLoader);
80          }
81  
82          LOG.info(services.size() + " service(s) loaded.");
83      }
84  
85      private void loadServices(ClassLoader classLoader) {
86          LOG.info("Load services using '" + classLoader + "'");
87  
88          Enumeration enumeration;
89          try {
90              enumeration = classLoader.getResources(RESOURCE_NAME);
91  
92          } catch (IOException ex) {
93              LOG.error("Can not get Resources '" + RESOURCE_NAME + "'.", ex);
94              return;
95          }
96  
97          for (; enumeration.hasMoreElements();) {
98              URL url = (URL) enumeration.nextElement();
99  
100             loadService(classLoader, url);
101         }
102     }
103 
104     private void loadService(final ClassLoader classLoader, URL url) {
105         LOG.info("Load service '" + url + "'");
106 
107         Digester digester = new Digester();
108         digester.setUseContextClassLoader(true);
109 
110         digester.setEntityResolver(new EntityResolver() {
111             private static final String REVISION = "$Revision: 1.1 $";
112 
113             public InputSource resolveEntity(String string, String string1) {
114                 return new InputSource(new CharArrayReader(new char[0]));
115             }
116 
117         });
118 
119         digester.addRule("rcfaces-services/service", new Rule() {
120             private static final String REVISION = "$Revision: 1.1 $";
121 
122             public void begin(String namespace, String name,
123                     Attributes attributes) throws Exception {
124 
125                 super.digester.push(new Service());
126             }
127 
128             public void end(String namespace, String name) throws Exception {
129                 Service service = (Service) super.digester.pop();
130 
131                 LOG.debug("Load service '" + service.getId() + "' className='"
132                         + service.getClassName() + "'");
133 
134                 if (service.getClassName() == null) {
135                     return;
136                 }
137 
138                 Class clazz;
139                 try {
140                     clazz = classLoader.loadClass(service.getClassName());
141 
142                 } catch (Exception ex) {
143                     LOG.error("Can not load class '" + service.getClassName()
144                             + "'.", ex);
145                     return;
146                 }
147 
148                 Object serviceObject;
149                 try {
150                     serviceObject = clazz.newInstance();
151 
152                 } catch (Exception ex) {
153                     LOG.error("Can not instanciate class '" + clazz + "'.", ex);
154                     return;
155                 }
156 
157                 services.put(service.getId(), serviceObject);
158 
159                 LOG.info("Service '" + service.getId() + "' loaded: "
160                         + serviceObject);
161             }
162         });
163 
164         digester.addBeanPropertySetter("rcfaces-services/service/service-id",
165                 "id");
166 
167         digester.addBeanPropertySetter(
168                 "rcfaces-services/service/service-class", "className");
169 
170         InputStream ins;
171         try {
172             ins = url.openStream();
173 
174         } catch (IOException ex) {
175             LOG.error("Can not open stream from '" + url + "'.", ex);
176             return;
177         }
178 
179         if (ins == null) {
180             LOG.info("Can not open stream from '" + url + "'.");
181             return;
182         }
183 
184         try {
185             try {
186 
187                 digester.parse(ins);
188 
189             } finally {
190                 ins.close();
191             }
192         } catch (IOException ex) {
193             LOG.error("Can not load stream from '" + url + "'.", ex);
194 
195         } catch (SAXException ex) {
196             LOG.error("Invalid XML resource '" + url + "'.", ex);
197         }
198     }
199 
200     /**
201      * 
202      * @author Olivier Oeuillot (latest modification by $Author: oeuillot $)
203      * @version $Revision: 1.1 $ $Date: 2008/01/22 13:28:59 $
204      */
205     public static class Service {
206         private String id;
207 
208         private String className;
209 
210         public final String getId() {
211             return id;
212         }
213 
214         public final void setId(String id) {
215             this.id = id;
216         }
217 
218         public final String getClassName() {
219             return className;
220         }
221 
222         public final void setClassName(String className) {
223             this.className = className;
224         }
225 
226     }
227 }