package org.toobs.framework.pres.component; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Vector; import java.net.URL; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.exolab.castor.xml.Unmarshaller; import org.toobs.framework.exception.PermissionException; import org.toobs.framework.pres.component.config.ContentType; import org.toobs.framework.pres.componentlayout.config.ComponentLayout; import org.toobs.framework.pres.componentlayout.config.ComponentLayoutConfig; import org.toobs.framework.util.Configuration; @SuppressWarnings("unchecked") public final class ComponentLayoutManager implements IComponentLayoutManager { private static Log log = LogFactory.getLog(ComponentLayoutManager.class); private static Map registry; private static boolean doReload = false; private static boolean initDone = false; private static long[] lastModified; private static long localDeployTime = 0L; private List configFiles = null; private ComponentLayoutManager() throws ComponentInitializationException { log.info("Constructing new ComponentLayoutManager"); registry = new HashMap(); } public RuntimeLayout getLayout(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 (RuntimeLayout) registry.get(Id); } } public RuntimeLayout getLayout(PermissionException permissionException) throws ComponentNotFoundException, ComponentInitializationException { String objectErrorPage = permissionException.getAction() + permissionException.getObjectTypeName(); synchronized (registry) { if (!registry.containsKey(objectErrorPage)) { log.info("Permission Error page " + objectErrorPage + " not defined"); return null; } return (RuntimeLayout) registry.get(objectErrorPage); } } // 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 { if (log.isDebugEnabled()) { log.debug("Checking Configuration file: " + fileName); } ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); URL configFileURL = classLoader.getResource(fileName); if (configFileURL == null) { log.warn("Configuration file " + fileName + " not found"); continue; } File configFile = new File(configFileURL.getFile()); if (log.isDebugEnabled()) { log.debug("Layout Config: " + fileName + " File Mod: " + new Date(configFile.lastModified()) + " Last Mod: " + new Date(lastModified[fileCounter])); } if (configFile.lastModified() <= lastModified[fileCounter]) { continue; } log.info("Reloading ComponentLayoutConfig file [" + fileName + "]"); //registry.clear(); reader = new InputStreamReader(configFileURL.openStream()); Unmarshaller unmarshaller = new Unmarshaller( Class.forName(ComponentLayoutConfig.class.getName())); unmarshaller.setValidation(false); ComponentLayoutConfig componentLayoutConfig = (ComponentLayoutConfig) unmarshaller.unmarshal(reader); if (componentLayoutConfig.getFullReload()) { lastModified = new long[l]; } ComponentLayout[] layouts = componentLayoutConfig.getComponentLayout(); //HashMap tempLayoutMap = new HashMap(); if ((layouts != null) && (layouts.length > 0)) { ComponentLayout compLayout = null; RuntimeLayout layout = null; RuntimeLayoutConfig layoutConfig = null; for (int i = 0; i < layouts.length; i ++) { compLayout = layouts[i]; layoutConfig = new RuntimeLayoutConfig(); layout = new RuntimeLayout(); // Inherited from extended definition String extendStr = compLayout.getExtends(); if (extendStr != null) { String[] extSplit = extendStr.split(";"); for (int ext = 0; ext < extSplit.length; ext++) { String extension = extSplit[ext]; RuntimeLayout extend = (RuntimeLayout)registry.get(extension); if (extend == null) { log.error("The ComponentLayout extension " + extension + " for " + compLayout.getId() + " could not be located in the registry.\n" + "Check the spelling and case of the extends property and ensure it is defined before\n" + "the dependent templates"); throw new ComponentInitializationException("Missing extension " + extension + " for " + compLayout.getId()); } RuntimeLayoutConfig extendConfig = extend.getConfig(); if (extend == null) { throw new ComponentInitializationException("Layout " + compLayout.getId() + " cannot extend " + extension + " cause it does not exist or has not yet been loaded"); } layoutConfig.addParam(extendConfig.getAllParams()); layoutConfig.addContentParam(extendConfig.getAllContentParams()); layoutConfig.addSection(extendConfig.getAllSections()); layoutConfig.setNoAccessLayout(extendConfig.getNoAccessLayout()); //layout.addTransform(extend.getAllTransforms()); layout.getTransforms().putAll(extend.getTransforms()); layout.setUseComponentScan(extend.isUseComponentScan()); layout.setEmbedded(extend.isEmbedded()); } } if (compLayout.getParameterMapping() != null) { layoutConfig.addParam(compLayout.getParameterMapping().getParameter()); } if (compLayout.getContentParameters() != null) { layoutConfig.addContentParam(compLayout.getContentParameters().getParameter()); } layoutConfig.addSection(compLayout.getSection()); if (compLayout.getNoAccessLayout() != null) { layoutConfig.setNoAccessLayout(compLayout.getNoAccessLayout()); } layout.setId(compLayout.getId()); layout.setUseComponentScan(compLayout.getUseComponentScan() || layout.isEmbedded()); layout.setEmbedded(compLayout.getEmbedded() || layout.isEmbedded()); //Set component pipeline properties. if (compLayout.getPipeline() != null) { Enumeration contentTypeEnum = compLayout.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++) { layout.getTransforms().put(ctSplit[ct], theseTransforms); } } } /* if (compLayout.getTransformCount() > 0) { layout.getTransforms().clear(); for (int t = 0; t < compLayout.getTransformCount(); t++) { layout.addTransform(new Transform(compLayout.getTransform(t))); } } */ layout.setConfig(layoutConfig); layout.setDoItRef(compLayout.getDoItRef()); if (log.isDebugEnabled()) { log.debug("Layout " + compLayout.getId() + " xml " + layout.getLayoutXml()); } if (registry.containsKey(compLayout.getId()) && !initDone) { log.warn("Overriding layout with Id: " + compLayout.getId()); } registry.put(compLayout.getId(), layout); } } //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 List getConfigFiles() { return configFiles; } public void setConfigFiles(List configFiles) { this.configFiles = configFiles; } public void addConfigFiles(List configFiles) { this.configFiles.addAll(configFiles); } }