View Javadoc

1   /*
2    * Copyright 2003,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of 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,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  /* 
17  
18   */
19  
20  package org.apache.pluto.portalImpl.services.factorymanager;
21  
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.LinkedList;
25  import java.util.List;
26  import java.util.Map;
27  
28  import javax.servlet.ServletConfig;
29  import javax.servlet.ServletContext;
30  
31  import org.apache.pluto.factory.Factory;
32  import org.apache.pluto.portalImpl.util.Properties;
33  import org.apache.pluto.util.StringUtils;
34  
35  /***
36   * Manages the life-time of factories registered during container startup.
37   * A service has to derive from {@link Factory} and implement the
38   * <CODE>init()</CODE> and <CODE>destroy()</CODE> methods as appropriate.
39   * 
40   * @see Factory
41   */
42  public class FactoryManagerServiceImpl extends FactoryManagerService
43  {
44  
45      private final static String CONFIG_FACTORY_PRE = "factory.";
46  
47      /***
48       ** Initializes all factories specified in the configuration beginning with 'factory.'.
49       ** By specifying a different implementation of the factory the behaviour
50       ** of the portlet container can be modified.
51       **
52       ** @param   config
53       **          the servlet configuration
54       **
55       ** @exception    Exception
56       **               if initializing any of the factories fails
57       **/
58  
59      protected void init (ServletConfig config, Properties aProperties) throws Exception
60      {
61  
62          ServletContext context = null;
63  
64          if (config != null)
65              context = config.getServletContext ();
66  
67          if (context != null)
68              context.log ("FactoryManager: Loading factories...");
69  
70          Map factoryImpls = new HashMap();
71          Map factoryProps = new HashMap();
72  
73          Iterator configNames = aProperties.keys();
74          String lastFactoryInterfaceName = null;
75          while (configNames.hasNext())
76          {
77              String configName = (String)configNames.next();
78              if (configName.startsWith(CONFIG_FACTORY_PRE))
79              {
80                  String name = configName.substring(CONFIG_FACTORY_PRE.length());
81                  if ((lastFactoryInterfaceName!=null) &&
82                      (name.startsWith(lastFactoryInterfaceName)) )
83                  {
84                      String propertyName = name.substring(lastFactoryInterfaceName.length()+1);
85                      String propertyValue = aProperties.getString(configName);
86                      Map properties = (Map)factoryProps.get(lastFactoryInterfaceName);
87                      properties.put(propertyName, propertyValue);
88                  }
89                  else
90                  {
91                      String factoryInterfaceName = name;
92                      String factoryImplName = aProperties.getString(configName);
93                      factoryImpls.put(factoryInterfaceName, factoryImplName);
94                      factoryProps.put(factoryInterfaceName, new HashMap());
95                      // remember interface name to get all properties
96                      lastFactoryInterfaceName = factoryInterfaceName;
97                  }
98              }
99          }
100 
101         int numAll = 0;
102 
103         for (Iterator iter = factoryImpls.keySet().iterator(); iter.hasNext (); )
104         {
105             String factoryInterfaceName = (String) iter.next ();
106 
107             numAll++;
108 
109             // try to get hold of the factory
110 
111             Class factoryInterface;
112 
113             try
114             {
115                 factoryInterface = Class.forName (factoryInterfaceName);
116             }
117             catch (ClassNotFoundException exc)
118             {
119                 if (context != null)
120                     context.log ("FactoryManager: A factory with name " + factoryInterfaceName + " cannot be found.");
121 
122                 continue;
123             }
124 
125             String factoryImplName = (String)factoryImpls.get(factoryInterfaceName);
126 
127             Class factoryImpl = null;
128 
129             Factory factory = null;
130 
131             try
132             {
133                 factoryImpl = Class.forName (factoryImplName);
134 
135                 factory = (Factory) factoryImpl.newInstance ();
136 
137                 Map props = (Map)factoryProps.get(factoryInterfaceName);
138 
139                 if (context != null)
140                     context.log (StringUtils.nameOf (factoryInterface) + " initializing...");
141 
142                 factory.init (config, props);
143 
144                 if (context != null)
145                     context.log (StringUtils.nameOf (factoryInterface) + " done.");
146             }
147             catch (ClassNotFoundException exc)
148             {
149                 if (context != null)
150                     context.log ("FactoryManager: A factory implementation with name " + factoryImplName + " cannot be found.", exc);
151 
152                 throw exc;
153             }
154             catch (ClassCastException exc)
155             {
156                 if (context != null)
157                     context.log ("FactoryManager: Factory implementation " + factoryImplName + " is not a factory of the required type.", exc);
158 
159                 throw exc;
160             }
161             catch (InstantiationException exc)
162             {
163                 if (context != null)
164                     context.log ("FactoryManager: Factory implementation " + factoryImplName + " cannot be instantiated.", exc);
165 
166                 throw exc;
167             }
168             catch (Exception exc)
169             {
170                 if (context != null)
171                     context.log ("FactoryManager: An unidentified error occurred", exc);
172 
173                 throw exc;
174             }
175 
176             if (factory != null)
177             {
178                 factoryMap.put (factoryInterface, factory);
179 
180                 // build up list in reverse order for later destruction
181 
182                 factoryList.add (0, factory);
183 
184             }
185         }
186 
187         if (context != null)
188             context.log ("FactoryManager: Factories initialized (" + numAll + " successful).");
189             
190     }
191 
192     /***
193      ** Destroys all services.
194      **
195      ** @param   config
196      **          the servlet configuration
197      **/
198 
199     protected void destroy (ServletConfig config)
200     {
201 
202         ServletContext context = null;
203 
204         if (config != null)
205             context = config.getServletContext ();
206 
207         // destroy the services in reverse order
208   
209         for (Iterator iterator = factoryList.iterator (); iterator.hasNext (); )
210         {
211             Factory factory = (Factory) iterator.next ();
212 
213             try
214             {
215                 factory.destroy ();
216             }
217             catch (Exception exc)
218             {
219                 if (context != null)
220                     context.log ("FactoryManager: Factory couldn't be destroyed.", exc);
221             }
222         }
223 
224         factoryList.clear();
225         factoryMap.clear();
226 
227     }
228 
229     /***
230      ** Returns the service implementation for the given service class, or
231      ** <CODE>null</CODE> if no such service is registered.
232      **
233      ** @param   theClass
234      **          the service class
235      **
236      ** @return   the service implementation
237      **/
238 
239     public Factory getFactory (Class theClass)
240     {
241         // at this state the services map is read-only,
242         // therefore we can go without synchronization
243 
244         return ((Factory) factoryMap.get (theClass));
245     }
246 
247     // --- PRIVATE MEMBERS --- //
248 
249     private Map  factoryMap  = new HashMap ();
250     private List factoryList = new LinkedList ();
251 
252 }