    001    package org.apache.turbine.services.assemblerbroker.util.java;
    002
    003
    004    /*
    005     * Licensed to the Apache Software Foundation (ASF) under one
    006     * or more contributor license agreements.  See the NOTICE file
    007     * distributed with this work for additional information
    008     * regarding copyright ownership.  The ASF licenses this file
    009     * to you under the Apache License, Version 2.0 (the
    010     * "License"); you may not use this file except in compliance
    011     * with the License.  You may obtain a copy of the License at
    012     *
    013     *   http://www.apache.org/licenses/LICENSE-2.0
    014     *
    015     * Unless required by applicable law or agreed to in writing,
    016     * software distributed under the License is distributed on an
    017     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018     * KIND, either express or implied.  See the License for the
    019     * specific language governing permissions and limitations
    020     * under the License.
    021     */
    022
    023    import java.util.Collections;
    024    import java.util.HashMap;
    025    import java.util.List;
    026    import java.util.Map;
    027
    028    import org.apache.commons.lang.StringUtils;
    029    import org.apache.commons.logging.Log;
    030    import org.apache.commons.logging.LogFactory;
    031    import org.apache.turbine.modules.Assembler;
    032    import org.apache.turbine.modules.GenericLoader;
    033    import org.apache.turbine.modules.Loader;
    034    import org.apache.turbine.services.assemblerbroker.util.AssemblerFactory;
    035
    036    /**
    037     * A screen factory that attempts to load a java class from
    038     * the module packages defined in the TurbineResource.properties.
    039     *
    040     * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
    041     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    042     * @version $Id: JavaBaseFactory.java 1078552 2011-03-06 19:58:46Z tv $
    043     */
    044    public abstract class JavaBaseFactory<T extends Assembler>
    045        implements AssemblerFactory<T>
    046    {
    047        /** A vector of packages. */
    048        private static List<String> packages = GenericLoader.getPackages();
    049
    050        /** Logging */
    051        protected Log log = LogFactory.getLog(this.getClass());
    052
    053        /**
    054         * A cache for previously obtained Class instances, which we keep in order
    055         * to reduce the Class.forName() overhead (which can be sizable).
    056         */
    057        private final Map<String, Class<T>> classCache =
    058            Collections.synchronizedMap(new HashMap<String, Class<T>>());
    059
    060        /**
    061         * Get an Assembler.
    062         *
    063         * @param packageName java package name
    064         * @param name name of the requested Assembler
    065         * @return an Assembler
    066         */
    067        @SuppressWarnings("unchecked")
    068        public T getAssembler(String packageName, String name)
    069        {
    070            T assembler = null;
    071
    072            log.debug("Class Fragment is " + name);
    073
    074            if (StringUtils.isNotEmpty(name))
    075            {
    076                for (String p : packages)
    077                {
    078                    StringBuffer sb = new StringBuffer();
    079
    080                    sb.append(p).append('.').append(packageName).append('.').append(name);
    081
    082                    String className = sb.toString();
    083
    084                    log.debug("Trying " + className);
    085
    086                    try
    087                    {
    088                        Class<T> servClass = classCache.get(className);
    089                        if(servClass == null)
    090                        {
    091                            servClass = (Class<T>) Class.forName(className.toString());
    092                            classCache.put(className, servClass);
    093                        }
    094                        assembler = servClass.newInstance();
    095                        break; // for()
    096                    }
    097                    catch (ClassNotFoundException cnfe)
    098                    {
    099                        // Do this so we loop through all the packages.
    100                        log.debug(className + ": Not found");
    101                    }
    102                    catch (NoClassDefFoundError ncdfe)
    103                    {
    104                        // Do this so we loop through all the packages.
    105                        log.debug(className + ": No Class Definition found");
    106                    }
    107                    catch (ClassCastException cce)
    108                    {
    109                        // This means trouble!
    110                        // Alternatively we can throw this exception so
    111                        // that it will appear on the client browser
    112                        log.error("Could not load "+className, cce);
    113                        break; // for()
    114                    }
    115                    catch (InstantiationException ine)
    116                    {
    117                        // This means trouble!
    118                        // Alternatively we can throw this exception so
    119                        // that it will appear on the client browser
    120                        log.error("Could not load "+className, ine);
    121                        break; // for()
    122                    }
    123                    catch (IllegalAccessException ilae)
    124                    {
    125                        // This means trouble!
    126                        // Alternatively we can throw this exception so
    127                        // that it will appear on the client browser
    128                        log.error("Could not load "+className, ilae);
    129                        break; // for()
    130                    }
    131                    // With ClassCastException, InstantiationException we hit big problems
    132                }
    133            }
    134            log.debug("Returning: " + assembler);
    135
    136            return assembler;
    137        }
    138
    139        /**
    140         * Get the loader for this type of assembler
    141         *
    142         * @return a Loader
    143         */
    144        public abstract Loader<T> getLoader();
    145
    146        /**
    147         * Get the size of a possibly configured cache
    148         *
    149         * @return the size of the cache in bytes
    150         */
    151        public int getCacheSize()
    152        {
    153            return getLoader().getCacheSize();
    154        }
    155    }