/* jBilling - The Enterprise Open Source Billing System Copyright (C) 2003-2011 Enterprise jBilling Software Ltd. and Emiliano Conde This file is part of jbilling. jbilling is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. jbilling 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with jbilling. If not, see <http://www.gnu.org/licenses/>. */ /* * Created on Apr 15, 2003 * */ package com.sapienter.jbilling.server.pluggableTask.admin; import java.util.Iterator; import java.util.List; import org.apache.log4j.Logger; import com.sapienter.jbilling.server.pluggableTask.PluggableTask; import com.sapienter.jbilling.server.util.Context; import org.springframework.util.ClassUtils; import java.util.ArrayList; public class PluggableTaskManager<T> { private static final Logger LOG = Logger.getLogger(PluggableTaskManager.class); private List<PluggableTaskDTO> classes = null; private Iterator it = null; private int lastProcessingOrder; public PluggableTaskManager(Integer entityId, Integer taskCategory) throws PluggableTaskException { try { lastProcessingOrder = 0; classes = new ArrayList<PluggableTaskDTO>(); classes.addAll(((PluggableTaskDAS) Context.getBean(Context.Name.PLUGGABLE_TASK_DAS)).findByEntityCategory( entityId, taskCategory)); it = classes.iterator(); LOG.debug("total classes = " + classes.size()); } catch (Exception e) { throw new PluggableTaskException(e); } } public List<PluggableTaskDTO> getAllTasks() { return classes; } public T getNextClass() throws PluggableTaskException { if (it != null && it.hasNext()) { PluggableTaskDTO aRule = (PluggableTaskDTO) it.next(); // check if the order by is in place int processingOrder = aRule.getProcessingOrder().intValue(); // this is helpful also to identify bad data in the table if (processingOrder <= lastProcessingOrder) { // means that the results are not ordered ! LOG.fatal("Results of processing tasks are not ordered"); throw new PluggableTaskException("Processing tasks not ordered"); } lastProcessingOrder = processingOrder; String className = aRule.getType().getClassName(); String interfaceName = aRule.getType().getCategory().getInterfaceName(); LOG.debug("Applying task " + className); return getInstance(className, interfaceName, aRule); } return null; } /** * Get a plug-in instance initialized using the parameters from the given PluggableTaskDTO entity. Used to * load and initialize a plug-in from the database. * * @param className class name to get instance of * @param interfaceName plug-in interface * @param pluggableTask pluggable task entity to initialize plug-in parameters from * @return instance of the plug-in class initialized with parameters * @throws PluggableTaskException throw if an unhandled exception occurs */ @SuppressWarnings("unchecked") public T getInstance(String className, String interfaceName, PluggableTaskDTO pluggableTask) throws PluggableTaskException { try { T instance = (T) getInstance(className, interfaceName); ((PluggableTask) instance).initializeParamters(pluggableTask); return instance; } catch (Exception e) { throw new PluggableTaskException("Unhandled exception initializing plug-in instance", e); } } /** * Get a plug-in instance for the given class name, ensuring that the resulting instance matches * the desired plug-in interface. * * @param className class name to get instance of * @param interfaceName plug-in interface * @return instance of the plug-in class * @throws PluggableTaskException thrown if plug-in class or interface could not be found, or if plug-in * does not implement the interface. */ public static Object getInstance(String className, String interfaceName) throws PluggableTaskException { try { Class task = getClass(className); Class iface = getClass(interfaceName); if (task == null) { throw new PluggableTaskException("Could not load plug-in class '" + className + "', class not found."); } if (iface == null) { throw new PluggableTaskException("Could not load interface '" + interfaceName + "', class not found."); } if (!iface.isAssignableFrom(task)) { throw new PluggableTaskException("Plug-in '" + className + "' does not implement '" + interfaceName + "'"); } LOG.debug("Creating a new instance of " + className); return task.newInstance(); } catch (Exception e) { throw new PluggableTaskException("Unhandled exception fetching plug-in instance", e); } } /** * Attempts to fetch the class by name. This method goes through all the common class loaders * allow the loading of plug-ins from 3rd party libraries and to ensure portability across containers. * * @param className class to load * @return class if name found and loadable, null if class could not be found in any class loader */ private static Class getClass(String className) { // attempt to load from the thread class loader try { ClassLoader loader = Thread.currentThread().getContextClassLoader(); return loader.loadClass(className); } catch (ClassNotFoundException e) { LOG.debug("Cannot load class from the current thread context class loader."); } // last ditch attempt to load from whatever class loader was used to execute this code try { return Class.forName(className); } catch (ClassNotFoundException e) { LOG.fatal("Cannot load class from the caller class loader.", e); } return null; } }