package org.toobs.framework.pres.component; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.net.URL; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.exolab.castor.xml.Unmarshaller; import org.toobs.data.beanutil.converter.DateToStringConverter; import org.toobs.data.beanutil.converter.StringToDateConverter; import org.toobs.framework.exception.ParameterException; import org.toobs.framework.pres.component.config.Component; import org.toobs.framework.pres.component.config.ComponentConfig; import org.toobs.framework.pres.component.config.ContentType; import org.toobs.framework.pres.component.config.DataSourceProperty; import org.toobs.framework.pres.component.datasource.api.IDataSource; import org.toobs.framework.util.Configuration; import java.util.Vector; import java.util.Enumeration; /** * @author pudney */ @SuppressWarnings("unchecked") public final class ComponentManager implements IComponentManager { private static Log log = LogFactory.getLog(ComponentManager.class); private static Map registry; private static boolean doReload = true; private static boolean initDone = false; private static long[] lastModified; private static long localDeployTime = 0L; private IDataSource defaultDatasource; private List configFiles = null; private ComponentManager() throws ComponentInitializationException { log.info("Constructing new ComponentManager"); registry = new HashMap(); ConvertUtils.register(new DateToStringConverter(), String.class); //ConvertUtils.register(new StringToDateConverter(), Date.class); } public org.toobs.framework.pres.component.Component getComponent(String Id, long deployTime) throws ComponentNotFoundException, ComponentInitializationException { //if (doReload || !initDone) { if (doReload || deployTime > localDeployTime) { //Date initStart = new Date(); this.init(); //Date initEnd = new Date(); //log.info("Init Time: " + (initEnd.getTime() - initStart.getTime())); } synchronized (registry) { if (!registry.containsKey(Id)) { ComponentNotFoundException ex = new ComponentNotFoundException(); ex.setComponentId(Id); throw ex; } localDeployTime = deployTime; return (org.toobs.framework.pres.component.Component) registry.get(Id); } } public String renderComponent( org.toobs.framework.pres.component.Component component, String contentType, Map params, Map paramsOut, boolean appendUrlScanner) throws ComponentNotInitializedException, ComponentException, ParameterException { return component.render(contentType, params, paramsOut, appendUrlScanner); } // Read from config file public void init() throws ComponentInitializationException { synchronized (registry) { InputStreamReader reader = null; if(configFiles == null) { return; } int l = configFiles.size(); if (lastModified == null) { log.info("LastModified is null " + this.toString() + " Registry " + registry); lastModified = new long[l]; } for(int fileCounter = 0; fileCounter < l; fileCounter++) { String fileName = (String)configFiles.get(fileCounter); try { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); URL configFileURL = classLoader.getResource(fileName); if (configFileURL == null) { log.warn("Skipping missing ComponentConfig file [" + fileName + "]"); continue; } File configFile = new File(configFileURL.getFile()); if (configFile.lastModified() <= lastModified[fileCounter]) { continue; } log.info("Reloading ComponentConfig file [" + fileName + "]"); //registry.clear(); reader = new InputStreamReader(configFileURL.openStream()); Unmarshaller unmarshaller = new Unmarshaller( Class.forName(ComponentConfig.class.getName())); unmarshaller.setValidation(false); ComponentConfig componentConfig = (ComponentConfig) unmarshaller.unmarshal(reader); Component[] components = componentConfig.getComponent(); if ((components != null) && (components.length > 0)) { Component comp = null; org.toobs.framework.pres.component.Component uic = null; for (int i = 0; i < components.length; i++) { comp = components[i]; Map dsParams = new HashMap(); if(comp.getDataSource() != null){ String dsClassName = comp.getDataSource().getClassName(); DataSourceProperty[] dsProperties = comp.getDataSource().getDataSourceProperty(); if ((dsProperties != null) && (dsProperties.length > 0)) { String propertyName = null; String[] propertyValue = null; for (int p = 0; p < dsProperties.length; p++) { propertyName = dsProperties[p].getDataSourcePropertyName(); propertyValue = dsProperties[p].getDataSourcePropertyValue(); dsParams.put(propertyName, propertyValue); } } uic = new org.toobs.framework.pres.component.Component(dsClassName, dsParams); } else { uic = new org.toobs.framework.pres.component.Component(); uic.setDs(defaultDatasource); } uic.setId(comp.getId()); uic.setFileName(fileName); uic.setRenderErrorObject(comp.getRenderErrorObject()); //Set object config property. uic.setObjectsConfig(comp.getGetObject()); //Set component pipeline properties. HashMap transforms = new HashMap(); Enumeration contentTypeEnum = comp.getPipeline().enumerateContentType(); while (contentTypeEnum.hasMoreElements()) { Vector theseTransforms = new Vector(); ContentType thisContentType = (ContentType) contentTypeEnum.nextElement(); Enumeration transEnum = thisContentType.enumerateTransform(); while (transEnum.hasMoreElements()) { org.toobs.framework.pres.component.config.Transform thisTransformConfig = (org.toobs.framework.pres.component.config.Transform) transEnum.nextElement(); org.toobs.framework.pres.component.Transform thisTransform = new org.toobs.framework.pres.component.Transform(); thisTransform.setTransformName(thisTransformConfig.getTransformName()); thisTransform.setTransformParams(thisTransformConfig.getParameterMapping()); theseTransforms.add(thisTransform); } String[] ctSplit = thisContentType.getContentType().split(";"); for (int ct = 0; ct < ctSplit.length; ct++) { transforms.put(ctSplit[ct], theseTransforms); } } uic.setTransforms(transforms); uic.setControllerNames(new String[comp.getControllerCount()]); for (int c=0; c < comp.getControllerCount(); c++) { uic.getControllerNames()[c] = comp.getController(c).getName(); } uic.setStyles(new String[comp.getStyleCount()]); for (int c=0; c < comp.getStyleCount(); c++) { uic.getStyles()[c] = comp.getStyle(c).getName(); } uic.init(); if (registry.containsKey(uic.getId()) && !initDone) { log.warn("Overriding component with Id: " + uic.getId()); } registry.put(uic.getId(), uic); } } //doReload = Configuration.getInstance().getReloadComponents(); lastModified[fileCounter] = configFile.lastModified(); doReload = false; } catch (Exception ex) { log.error("ComponentLayout initialization failed " + ex.getMessage(), ex); doReload = true; } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { } } } } initDone = true; } } public IDataSource getDefaultDatasource() { return defaultDatasource; } public void setDefaultDatasource(IDataSource defaultDatasource) { this.defaultDatasource = defaultDatasource; } public List getConfigFiles() { return configFiles; } public void setConfigFiles(List configFiles) { this.configFiles = configFiles; } public void addConfigFiles(List configFiles) { this.configFiles.addAll(configFiles); } }