package com.c2kernel.process.module; import java.io.IOException; import java.net.URL; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Properties; import com.c2kernel.common.CannotManageException; import com.c2kernel.common.InvalidDataException; import com.c2kernel.common.ObjectAlreadyExistsException; import com.c2kernel.common.ObjectCannotBeUpdated; import com.c2kernel.common.ObjectNotFoundException; import com.c2kernel.entity.proxy.ItemProxy; import com.c2kernel.lookup.DomainPath; import com.c2kernel.persistency.outcome.OutcomeValidator; import com.c2kernel.persistency.outcome.Schema; import com.c2kernel.process.Gateway; import com.c2kernel.scripting.ScriptingEngineException; import com.c2kernel.utils.FileStringUtility; import com.c2kernel.utils.Logger; import com.c2kernel.utils.Resource; public class ModuleManager { ArrayList modules = new ArrayList(); HashMap modulesXML = new HashMap(); Properties props = new Properties(); boolean isServer; OutcomeValidator moduleValidator; public ModuleManager(Enumeration moduleEnum, boolean isServer) throws ModuleException { this.isServer = isServer; try { Schema moduleSchema = new Schema("Module", 0, false, FileStringUtility.url2String(Resource.getKernelResourceURL("boot/OD/Module.xsd"))); moduleValidator = new OutcomeValidator(moduleSchema); } catch (InvalidDataException ex) { Logger.error(ex); throw new ModuleException("Module Schema is not valid"); } catch (IOException ex) { throw new ModuleException("Could not load Module Schema from kernel resources"); } ArrayList loadedModules = new ArrayList(); ArrayList moduleNs = new ArrayList(); while(moduleEnum.hasMoreElements()) { URL newModuleURL = moduleEnum.nextElement(); try { String moduleXML = FileStringUtility.url2String(newModuleURL); String errors = moduleValidator.validate(moduleXML); if (errors.length() > 0) throw new ModuleException("Module XML found at "+newModuleURL+" was not valid: "+errors); Module newModule = (Module)Gateway.getMarshaller().unmarshall(moduleXML); Resource.addModuleBaseURL(newModule.ns, newModule.resURL); modules.add(newModule); modulesXML.put(newModule.ns, moduleXML); if (loadedModules.contains(newModule.getName())) throw new ModuleException("Module name clash: "+newModule.getName()); if (moduleNs.contains(newModule.getNs())) throw new ModuleException("Module namespace clash: "+newModule.getNs()); Logger.debug(4, "Module found: "+newModule.getNs()+" - "+newModule.getName()); loadedModules.add(newModule.getName()); moduleNs.add(newModule.getNs()); Properties modProp = newModule.getProperties(isServer); for (Enumeration e = modProp.propertyNames(); e.hasMoreElements();) { String propName = (String)e.nextElement(); props.put(propName, modProp.get(propName)); } } catch (ModuleException e) { Logger.error("Could not load module description from "+newModuleURL); throw e; } catch (Exception e) { Logger.error(e); throw new ModuleException("Could not load module.xml from "+newModuleURL); } } Logger.debug(5, "Checking dependencies"); //TODO: order the importing so each modules dependencies are imported ahead of it boolean depFailed = false; for (Module thisMod : modules) { ArrayList deps = thisMod.getDependencies(); for (String dep : deps) { if (!loadedModules.contains(dep)) { Logger.error("UNMET MODULE DEPENDENCY: "+thisMod.getName()+" requires "+dep); depFailed = true; } } } if (depFailed) Logger.die("Unmet module dependencies. Cannot continue"); } public String getModuleVersions() { StringBuffer ver = new StringBuffer(); for (Module thisMod : modules) { if (ver.length()>0) ver.append("; "); ver.append(thisMod.getName()+" ("+thisMod.getVersion()+")"); } return ver.toString(); } public Properties getAllModuleProperties() { return props; } public void runScripts(String event) { for (Module thisMod : modules) { try { thisMod.runScript(event, isServer); } catch (ScriptingEngineException e) { Logger.error(e); Logger.die(e.getMessage()); } } } public void registerModules() throws ObjectNotFoundException, ObjectCannotBeUpdated, CannotManageException, ObjectAlreadyExistsException, NoSuchAlgorithmException { ItemProxy serverEntity = (ItemProxy)Gateway.getProxyManager().getProxy(new DomainPath("/servers/"+Gateway.getProperty("ItemServer.name"))); Logger.debug(3, "Registering modules"); for (Module thisMod : modules) { Logger.msg("Registering module "+thisMod.getName()); thisMod.importAll(serverEntity, modulesXML.get(thisMod.ns)); Logger.msg("Module "+thisMod.getName()+" registered"); } } public void dumpModules() { for (Module thisMod : modules) { try { FileStringUtility.string2File(thisMod.getName()+".xml", Gateway.getMarshaller().marshall(thisMod)); } catch (Exception e) { Logger.error(e); } } } }