View Javadoc

1   package org.apache.turbine.services.assemblerbroker;
2   
3   /*
4    * Copyright 2001-2005 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.Vector;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  import org.apache.turbine.modules.Assembler;
29  import org.apache.turbine.services.InitializationException;
30  import org.apache.turbine.services.TurbineBaseService;
31  import org.apache.turbine.services.assemblerbroker.util.AssemblerFactory;
32  import org.apache.turbine.util.TurbineException;
33  
34  /***
35   * TurbineAssemblerBrokerService allows assemblers (like screens,
36   * actions and layouts) to be loaded from one or more AssemblerFactory
37   * classes.  AssemblerFactory classes are registered with this broker
38   * by adding them to the TurbineResources.properties file.
39   *
40   * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
41   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
42   * @version $Id: TurbineAssemblerBrokerService.java 264148 2005-08-29 14:21:04Z henning $
43   */
44  public class TurbineAssemblerBrokerService
45          extends TurbineBaseService
46          implements AssemblerBrokerService
47  {
48      /*** Logging */
49      private static Log log
50              = LogFactory.getLog(TurbineAssemblerBrokerService.class);
51  
52      /*** A structure that holds the registered AssemblerFactories */
53      private Map factories = null;
54  
55      /***
56       * Get a list of AssemblerFactories of a certain type
57       *
58       * @param type type of Assembler
59       * @return list of AssemblerFactories
60       */
61      private List getFactoryGroup(String type)
62      {
63          if (!factories.containsKey(type))
64          {
65              factories.put(type, new Vector());
66          }
67          return (List) factories.get(type);
68      }
69  
70      /***
71       * Utiltiy method to register all factories for a given type.
72       *
73       * @param type type of Assembler
74       * @throws TurbineException
75       */
76      private void registerFactories(String type)
77          throws TurbineException
78      {
79          List names = getConfiguration().getList(type);
80  
81          log.info("Registering " + names.size() + " " + type + " factories.");
82  
83          for (Iterator it = names.iterator(); it.hasNext(); )
84          {
85              String factory = (String) it.next();
86              try
87              {
88                  Object o = Class.forName(factory).newInstance();
89                  registerFactory(type, (AssemblerFactory) o);
90              }
91              // these must be passed to the VM
92              catch (ThreadDeath e)
93              {
94                  throw e;
95              }
96              catch (OutOfMemoryError e)
97              {
98                  throw e;
99              }
100             // when using Class.forName(), NoClassDefFoundErrors are likely
101             // to happen (missing jar files)
102             catch (Throwable t)
103             {
104                 throw new TurbineException("Failed registering " + type
105                         + " factory: " + factory, t);
106             }
107         }
108     }
109 
110     /***
111      * Initializes the AssemblerBroker and loads the AssemblerFactory
112      * classes registered in TurbineResources.Properties.
113      *
114      * @throws InitializationException
115      */
116     public void init()
117         throws InitializationException
118     {
119         factories = new HashMap();
120         try
121         {
122             registerFactories(AssemblerBrokerService.ACTION_TYPE);
123             registerFactories(AssemblerBrokerService.SCREEN_TYPE);
124             registerFactories(AssemblerBrokerService.NAVIGATION_TYPE);
125             registerFactories(AssemblerBrokerService.LAYOUT_TYPE);
126             registerFactories(AssemblerBrokerService.PAGE_TYPE);
127             registerFactories(AssemblerBrokerService.SCHEDULEDJOB_TYPE);
128         }
129         catch (TurbineException e)
130         {
131             throw new InitializationException(
132                     "AssemblerBrokerService failed to initialize", e);
133         }
134         setInit(true);
135     }
136 
137     /***
138      * Register a new AssemblerFactory under a certain type
139      *
140      * @param type type of Assembler
141      * @param factory factory to register
142      */
143     public void registerFactory(String type, AssemblerFactory factory)
144     {
145         getFactoryGroup(type).add(factory);
146     }
147 
148     /***
149      * Attempt to retrieve an Assembler of a given type with
150      * a name.  Cycle through all the registered AssemblerFactory
151      * classes of type and return the first non-null assembly
152      * found.  If an assembly was not found return null.
153      *
154      * @param type type of Assembler
155      * @param name name of the requested Assembler
156      * @return an Assembler or null
157      * @throws TurbineException
158      */
159     public Assembler getAssembler(String type, String name)
160         throws TurbineException
161     {
162         List facs = getFactoryGroup(type);
163 
164         Assembler assembler = null;
165         for (Iterator it = facs.iterator(); (assembler == null) && it.hasNext();)
166         {
167             AssemblerFactory fac = (AssemblerFactory) it.next();
168             try
169             {
170                 assembler = fac.getAssembler(name);
171             }
172             catch (Exception e)
173             {
174                 throw new TurbineException("Failed to load an assembler for "
175                                            + name + " from the "
176                                            + type + " factory "
177                                            + fac.getClass().getName(), e);
178             }
179         }
180         return assembler;
181     }
182 }