View Javadoc

1   package org.apache.turbine.services.assemblerbroker.util.java;
2   
3   
4   /*
5    * Licensed to the Apache Software Foundation (ASF) under one
6    * or more contributor license agreements.  See the NOTICE file
7    * distributed with this work for additional information
8    * regarding copyright ownership.  The ASF licenses this file
9    * to you under the Apache License, Version 2.0 (the
10   * "License"); you may not use this file except in compliance
11   * with the License.  You may obtain a copy of the License at
12   *
13   *   http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing,
16   * software distributed under the License is distributed on an
17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   * KIND, either express or implied.  See the License for the
19   * specific language governing permissions and limitations
20   * under the License.
21   */
22  
23  import java.util.List;
24  import java.util.concurrent.ConcurrentHashMap;
25  
26  import org.apache.commons.lang.StringUtils;
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.turbine.modules.Assembler;
30  import org.apache.turbine.modules.GenericLoader;
31  import org.apache.turbine.modules.Loader;
32  import org.apache.turbine.services.assemblerbroker.util.AssemblerFactory;
33  
34  /**
35   * A screen factory that attempts to load a java class from
36   * the module packages defined in the TurbineResource.properties.
37   *
38   * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
39   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
40   * @param <T> the specialized assembler type
41   */
42  public abstract class JavaBaseFactory<T extends Assembler>
43      implements AssemblerFactory<T>
44  {
45      /** A vector of packages. */
46      private static List<String> packages = GenericLoader.getPackages();
47  
48      /** Logging */
49      protected Log log = LogFactory.getLog(this.getClass());
50  
51      /**
52       * A cache for previously obtained Class instances, which we keep in order
53       * to reduce the Class.forName() overhead (which can be sizable).
54       */
55      private final ConcurrentHashMap<String, Class<T>> classCache = new ConcurrentHashMap<String, Class<T>>();
56  
57      /**
58       * Get an Assembler.
59       *
60       * @param packageName java package name
61       * @param name name of the requested Assembler
62       * @return an Assembler
63       */
64      @SuppressWarnings("unchecked")
65      public T getAssembler(String packageName, String name)
66      {
67          T assembler = null;
68  
69          log.debug("Class Fragment is " + name);
70  
71          if (StringUtils.isNotEmpty(name))
72          {
73              for (String p : packages)
74              {
75                  StringBuilder sb = new StringBuilder();
76  
77                  sb.append(p).append('.').append(packageName).append('.').append(name);
78                  String className = sb.toString();
79  
80                  log.debug("Trying " + className);
81  
82                  try
83                  {
84                      Class<T> servClass = classCache.get(className);
85                      if (servClass == null)
86                      {
87                          servClass = (Class<T>) Class.forName(className);
88                          classCache.put(className, servClass);
89                      }
90                      assembler = servClass.newInstance();
91                      break; // for()
92                  }
93                  catch (ClassNotFoundException cnfe)
94                  {
95                      // Do this so we loop through all the packages.
96                      log.debug(className + ": Not found");
97                  }
98                  catch (NoClassDefFoundError ncdfe)
99                  {
100                     // Do this so we loop through all the packages.
101                     log.debug(className + ": No Class Definition found");
102                 }
103                 catch (ClassCastException cce)
104                 {
105                     // This means trouble!
106                     // Alternatively we can throw this exception so
107                     // that it will appear on the client browser
108                     log.error("Could not load "+className, cce);
109                     break; // for()
110                 }
111                 catch (InstantiationException ine)
112                 {
113                     // This means trouble!
114                     // Alternatively we can throw this exception so
115                     // that it will appear on the client browser
116                     log.error("Could not load "+className, ine);
117                     break; // for()
118                 }
119                 catch (IllegalAccessException ilae)
120                 {
121                     // This means trouble!
122                     // Alternatively we can throw this exception so
123                     // that it will appear on the client browser
124                     log.error("Could not load "+className, ilae);
125                     break; // for()
126                 }
127                 // With ClassCastException, InstantiationException we hit big problems
128             }
129         }
130         log.debug("Returning: " + assembler);
131 
132         return assembler;
133     }
134 
135     /**
136      * Get the loader for this type of assembler
137      *
138      * @return a Loader
139      */
140     @Override
141     public abstract Loader<T> getLoader();
142 
143     /**
144      * Get the size of a possibly configured cache
145      *
146      * @return the size of the cache in bytes
147      */
148     @Override
149     public int getCacheSize()
150     {
151         return getLoader().getCacheSize();
152     }
153 }