/* * PluginBean.java * * This work is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, * or (at your option) any later version. * * This work is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * Copyright (c) 2006 Per Cederberg. All rights reserved. */ package org.liquidsite.app.template; import java.lang.reflect.Constructor; import java.util.HashMap; import org.liquidsite.util.log.Log; import freemarker.ext.beans.BeansWrapper; import freemarker.template.TemplateHashModel; import freemarker.template.TemplateModel; /** * The plugin bean. This class provides a template bean with a list * of all currently loaded plugin beans. Upon access to a plugin * bean, a new instance will also be created. The instance of each * plugin bean is kept for the lifetime of this bean. * * @author Per Cederberg, <per at percederberg dot net> * @version 1.0 */ public class PluginBean extends TemplateBean implements TemplateHashModel { /** * The class logger. */ private static final Log LOG = new Log(PluginBean.class); /** * The plugin class map. Each plugin bean class is indexed by the * plugin bean name. */ private static HashMap pluginClasses = new HashMap(); /** * The template model map. Each template model in this map * corresponds to a plugin bean instance and is indexed by * the plugin bean name. */ private HashMap models = new HashMap(); /** * Adds a plugin class mapping. * * @param name the template bean name * @param cls the template bean class * * @throws TemplateException if the template bean mapping couldn't * be added */ public static void add(String name, Class cls) throws TemplateException { String msg; if (pluginClasses.containsKey(name)) { msg = "cannot redefine plugin class for '" + name + "'"; throw new TemplateException(msg); } if (!TemplateBean.class.isAssignableFrom(cls)) { msg = "template bean plugin class " + cls.getName() + " is not instance of " + TemplateBean.class.getName(); throw new TemplateException(msg); } pluginClasses.put(name, cls); } /** * Removes all registered plugin class mappings. */ public static void removeAll() { pluginClasses.clear(); } /** * Creates a new plugin bean. * * @param context the bean context */ PluginBean(BeanContext context) { super(context); } /** * Checks if the hash model is empty. * * @return true if no plugin beans are available, or * false otherwise */ public boolean isEmpty() { return pluginClasses.isEmpty(); } /** * Returns a plugin bean as a template model. * * @param id the plugin bean name * * @return the template model object, or * null if the plugin name isn't defined */ public TemplateModel get(String id) { TemplateModel model; Class cls; Constructor cons; Object obj; if (models.containsKey(id)) { return (TemplateModel) models.get(id); } else if (!pluginClasses.containsKey(id)) { return null; } else { cls = (Class) pluginClasses.get(id); try { cons = cls.getConstructor(new Class[] { BeanContext.class }); obj = cons.newInstance(new Object[] { getContext() }); if (obj instanceof TemplateModel) { model = (TemplateModel) obj; } else { model = BeansWrapper.getDefaultInstance().wrap(obj); } } catch (Exception e) { LOG.error("failed to create plugin bean '" + id + "': " + e.toString()); return null; } models.put(id, model); return model; } } }