From 2827a4b2d5aea32dc3c26a80f47309a6b68ac34b Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Tue, 19 Jun 2012 21:00:29 +0200 Subject: Refactor modules Support workflows on module resources --- src/main/java/com/c2kernel/process/Bootstrap.java | 16 +- src/main/java/com/c2kernel/process/Gateway.java | 1 + src/main/java/com/c2kernel/process/Module.java | 315 --------------------- .../java/com/c2kernel/process/ModuleException.java | 9 - .../java/com/c2kernel/process/ModuleManager.java | 90 ------ .../java/com/c2kernel/process/StandardClient.java | 9 +- .../java/com/c2kernel/process/module/Module.java | 296 +++++++++++++++++++ .../c2kernel/process/module/ModuleException.java | 9 + .../com/c2kernel/process/module/ModuleManager.java | 91 ++++++ 9 files changed, 419 insertions(+), 417 deletions(-) delete mode 100644 src/main/java/com/c2kernel/process/Module.java delete mode 100644 src/main/java/com/c2kernel/process/ModuleException.java delete mode 100644 src/main/java/com/c2kernel/process/ModuleManager.java create mode 100644 src/main/java/com/c2kernel/process/module/Module.java create mode 100644 src/main/java/com/c2kernel/process/module/ModuleException.java create mode 100644 src/main/java/com/c2kernel/process/module/ModuleManager.java (limited to 'src/main/java/com/c2kernel/process') diff --git a/src/main/java/com/c2kernel/process/Bootstrap.java b/src/main/java/com/c2kernel/process/Bootstrap.java index 99b40f3..39a13d2 100644 --- a/src/main/java/com/c2kernel/process/Bootstrap.java +++ b/src/main/java/com/c2kernel/process/Bootstrap.java @@ -60,9 +60,11 @@ public class Bootstrap Thread.currentThread().setName("Bootstrapper"); // make sure all of the boot items are up-to-date + Logger.msg("Bootstrap.run() - Verifying kernel boot data items"); verifyBootDataItems(); // verify the server item's wf + Logger.msg("Bootstrap.run() - Initialising Server Item Workflow"); initServerItemWf(); // register modules @@ -159,6 +161,18 @@ public class Bootstrap String propVal = propName.equals("Name")?itemName:pd.getDefaultValue(); props.list.add(new Property(propName, propVal)); } + + // HACK: this gives all module resources a workflow. Maybe have a 'debug' flag in the module xml or server config to do this. Normally module resources should be read-only, as they would be reset at next boot. + CompositeActivity ca = new CompositeActivity(); + if (ns!=null) { + String wf; + if (itemType.equals("CA")) wf = "ManageCompositeActDef"; + else if (itemType.equals("EA")) wf = "ManageElementaryActDef"; + else if (itemType.equals("OD")) wf = "ManageSchema"; + else if (itemType.equals("SC")) wf = "ManageScript"; + else throw new Exception("Unknown bootstrap item type: "+itemType); + ca = (CompositeActivity) ((CompositeActivityDef)LocalObjectLoader.getActDef(wf, "last")).instantiate(); + } EntityPath entityPath = Gateway.getLDAPLookup().getNextKeyManager().generateNextEntityKey(); TraceableEntity newItem = (TraceableEntity)Gateway.getCorbaServer().createEntity(entityPath); @@ -166,7 +180,7 @@ public class Bootstrap newItem.initialise( 1, CastorXMLUtility.marshall(props), - CastorXMLUtility.marshall(new CompositeActivity())); + CastorXMLUtility.marshall(ca)); DomainPath newDomPath = new DomainPath(getTypeRoot(itemType).toString()+"/system/"+(ns==null?"kernel":ns)+"/"+itemName); newDomPath.setEntity(entityPath); Gateway.getLDAPLookup().add(newDomPath); diff --git a/src/main/java/com/c2kernel/process/Gateway.java b/src/main/java/com/c2kernel/process/Gateway.java index 399a81b..82357d8 100644 --- a/src/main/java/com/c2kernel/process/Gateway.java +++ b/src/main/java/com/c2kernel/process/Gateway.java @@ -19,6 +19,7 @@ import com.c2kernel.lookup.LDAPLookup; import com.c2kernel.lookup.LDAPProperties; import com.c2kernel.persistency.ClusterStorageException; import com.c2kernel.persistency.TransactionManager; +import com.c2kernel.process.module.ModuleManager; import com.c2kernel.utils.CastorXMLUtility; import com.c2kernel.utils.FileStringUtility; import com.c2kernel.utils.Language; diff --git a/src/main/java/com/c2kernel/process/Module.java b/src/main/java/com/c2kernel/process/Module.java deleted file mode 100644 index 6e5f8d1..0000000 --- a/src/main/java/com/c2kernel/process/Module.java +++ /dev/null @@ -1,315 +0,0 @@ -package com.c2kernel.process; - -import java.io.StringReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Properties; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; -import org.xml.sax.InputSource; - -import com.c2kernel.common.ObjectNotFoundException; -import com.c2kernel.entity.proxy.ItemProxy; -import com.c2kernel.events.Event; -import com.c2kernel.events.History; -import com.c2kernel.lifecycle.instance.predefined.entitycreation.Dependency; -import com.c2kernel.lifecycle.instance.predefined.entitycreation.DependencyMember; -import com.c2kernel.lifecycle.instance.predefined.entitycreation.NewAgent; -import com.c2kernel.lifecycle.instance.predefined.entitycreation.NewItem; -import com.c2kernel.lifecycle.instance.predefined.entitycreation.Property; -import com.c2kernel.lifecycle.instance.stateMachine.States; -import com.c2kernel.lifecycle.instance.stateMachine.Transitions; -import com.c2kernel.lookup.DomainPath; -import com.c2kernel.persistency.outcome.Outcome; -import com.c2kernel.persistency.outcome.Viewpoint; -import com.c2kernel.scripting.ErrorInfo; -import com.c2kernel.scripting.Script; -import com.c2kernel.scripting.ScriptingEngineException; -import com.c2kernel.utils.CastorXMLUtility; -import com.c2kernel.utils.Logger; -import com.c2kernel.utils.Resource; - -public class Module { - - private final String ns, name, desc, version; - private String resURL; - private final ArrayList dependency = new ArrayList(); - private final Properties clientProps = new Properties(); - private final Properties serverProps = new Properties(); - private final HashMap clientScripts = new HashMap(); - private final HashMap serverScripts = new HashMap(); - private final ArrayList imports = new ArrayList(); - private static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - private final DocumentBuilder parser; - private Document moduleDOM; - - static { - dbf.setValidating(false); - dbf.setNamespaceAware(false); - } - - public Module(String moduleXML) throws ModuleException { - try { - parser = dbf.newDocumentBuilder(); - moduleDOM = parser.parse(new InputSource(new StringReader(moduleXML))); - } catch (Exception e) { - Logger.error(e); - throw new ModuleException("Could not process modules. XML Parser exception"); - } - - Element root = (Element)moduleDOM.getElementsByTagName("CristalModule").item(0); - - // Get module metadata - ns = root.getAttribute("ns"); - name = root.getAttribute("name"); - - Element info = (Element)moduleDOM.getElementsByTagName("Info").item(0); - desc = ((Text)info.getElementsByTagName("Description").item(0).getFirstChild()).getData(); - version = ((Text)info.getElementsByTagName("Version").item(0).getFirstChild()).getData(); - NodeList nl = info.getElementsByTagName("Dependency"); - for (int i=0; i0) { - resURL = ((Text)nl.item(0).getFirstChild()).getData(); - Resource.addModuleBaseURL(ns, resURL); - } - - // Get config properties - nl = root.getElementsByTagName("Config"); - for (int i=0; i0) { - Element impElem = (Element)nl.item(0); - nl = impElem.getChildNodes(); - for (int i=0; i scripts = isServer?serverScripts:clientScripts; - Script thisScript = scripts.get(event); - if (thisScript == null) return null; - try { - Object result = thisScript.execute(); - if (result instanceof ErrorInfo) - return (ErrorInfo)result; - else - return new ErrorInfo(result.toString()); - } catch (ScriptingEngineException ex) { - Logger.error(ex); - return new ErrorInfo("Error running "+event+" script in module "+ns); - } - } - - public void importAll(ItemProxy serverEntity) { - for (ModuleImport thisImp : imports) { - if (thisImp instanceof ModuleResource) { - ModuleResource thisRes = (ModuleResource)thisImp; - try { - Bootstrap.verifyResource(ns, thisRes.importName, thisRes.resourceType, Resource.getTextResource(ns, thisRes.resourceLocation)); - } catch (Exception ex) { - Logger.error(ex); - } - } - else if (thisImp instanceof ModuleItem) { - ModuleItem thisItem = (ModuleItem)thisImp; - try { - NewItem item = new NewItem(thisItem.importName, "/desc/"+ns, thisItem.workflow); - item.propertyList = thisItem.props; - DomainPath itemPath = new DomainPath(new DomainPath(item.initialPath), item.name); - if (itemPath.exists()) continue; - serverEntity.requestAction( - Gateway.getLDAPLookup().getRoleManager().getAgentPath("system").getSysKey(), - "workflow/predefined/CreateNewItem", - Transitions.DONE, - CastorXMLUtility.marshall(item)); - Logger.msg("Module.importAll() - Created item: "+thisItem.importName); - ItemProxy newProxy = (ItemProxy)Gateway.getProxyManager().getProxy(itemPath); - History hist = new History(newProxy.getSystemKey(), newProxy); - for (String thisView : thisItem.outcomes.keySet()) { - String[] info = thisView.split(":"); - int version = Integer.parseInt(info[1]); - String data = Resource.getTextResource(ns, thisItem.outcomes.get(thisView)); - Event newEvent = hist.addEvent("system", "Admin", Transitions.DONE, "Import", "Import", "Import", States.FINISHED); - Outcome newOutcome = new Outcome(newEvent.getID(), data, info[0], version); - Viewpoint newLastView = new Viewpoint(newProxy.getSystemKey(), info[0], info[2], version, newEvent.getID()); - Gateway.getStorage().put(newProxy.getSystemKey(), newOutcome, newProxy); - Gateway.getStorage().put(newProxy.getSystemKey(), newLastView, newProxy); - } - for (Dependency thisDep : thisItem.deps) { - Gateway.getStorage().put(newProxy.getSystemKey(), thisDep.create(), newProxy); - } - Gateway.getStorage().commit(newProxy); - } catch (Exception ex) { - Logger.error("Error importing item "+thisItem.importName+" from module "+name); - Logger.error(ex); - } - } - else if (thisImp instanceof ModuleAgent) { - ModuleAgent thisAgent = (ModuleAgent)thisImp; - try { - Gateway.getLDAPLookup().getRoleManager().getAgentPath(thisAgent.importName); - Logger.msg(3, "Module.importAll() - User '"+thisAgent.importName+"' found."); - return; - } catch (ObjectNotFoundException ex) { } - Logger.msg("Module.importAll() - User '"+thisAgent.importName+"' not found. Creating."); - - NewAgent agent = new NewAgent(thisAgent.importName, thisAgent.password); - agent.roles = thisAgent.roles; - try { - serverEntity.requestAction( - Gateway.getLDAPLookup().getRoleManager().getAgentPath("system").getSysKey(), - "workflow/predefined/CreateNewAgent", - Transitions.DONE, - CastorXMLUtility.marshall(agent)); - } catch (Exception ex) { - Logger.error("Error importing agent "+thisAgent.importName+" from module "+name); - Logger.error(ex); - } - } - } - } - - public Properties getClientProperties() { - return clientProps; - } - - public Properties getServerProperties() { - return serverProps; - } - - public String getNs() { - return ns; - } - public String getName() { - return name; - } - public String getDesc() { - return desc; - } - public String getVersion() { - return version; - } - public String getResURL() { - return resURL; - } - public ArrayList getDependencies() { - return dependency; - } - public boolean hasDependency(String dep) { - return dependency.contains(dep); - } - - public abstract class ModuleImport { - String importName; - } - - public class ModuleResource extends ModuleImport { - String resourceType; - String resourceLocation; - } - - public class ModuleItem extends ModuleImport { - ArrayList props = new ArrayList(); - HashMap outcomes = new HashMap(); - ArrayList deps = new ArrayList(); - String workflow; - } - - public class ModuleAgent extends ModuleImport { - String password; - ArrayList roles = new ArrayList(); - } -} \ No newline at end of file diff --git a/src/main/java/com/c2kernel/process/ModuleException.java b/src/main/java/com/c2kernel/process/ModuleException.java deleted file mode 100644 index 5e60801..0000000 --- a/src/main/java/com/c2kernel/process/ModuleException.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.c2kernel.process; - -public class ModuleException extends Exception { - - public ModuleException(String msg) { - super(msg); - } - -} diff --git a/src/main/java/com/c2kernel/process/ModuleManager.java b/src/main/java/com/c2kernel/process/ModuleManager.java deleted file mode 100644 index b336681..0000000 --- a/src/main/java/com/c2kernel/process/ModuleManager.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.c2kernel.process; - -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Properties; - -import com.c2kernel.common.ObjectNotFoundException; -import com.c2kernel.entity.proxy.ItemProxy; -import com.c2kernel.lookup.DomainPath; -import com.c2kernel.utils.FileStringUtility; -import com.c2kernel.utils.Logger; - -public class ModuleManager { - ArrayList modules = new ArrayList(); - Properties props = new Properties(); - boolean isServer; - - public ModuleManager(Enumeration moduleEnum, boolean isServer) throws ModuleException{ - this.isServer = isServer; - ArrayList loadedModules = new ArrayList(); - ArrayList moduleNs = new ArrayList(); - while(moduleEnum.hasMoreElements()) { - URL newModuleURL = moduleEnum.nextElement(); - try { - Module newModule = new Module(FileStringUtility.url2String(newModuleURL)); - modules.add(newModule); - 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 = isServer?newModule.getServerProperties():newModule.getClientProperties(); - 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 (IOException e) { - Logger.error(e); - throw new ModuleException("Could not load module.xml from "+newModuleURL); - } - } - - Logger.debug(5, "Checking dependencies"); - 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) { - thisMod.runScript(event, isServer); - } - } - - public void registerModules() throws ObjectNotFoundException { - 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); - Logger.msg("Module "+thisMod.getName()+" registered"); - } - } -} diff --git a/src/main/java/com/c2kernel/process/StandardClient.java b/src/main/java/com/c2kernel/process/StandardClient.java index f6f48ed..2ef6107 100644 --- a/src/main/java/com/c2kernel/process/StandardClient.java +++ b/src/main/java/com/c2kernel/process/StandardClient.java @@ -10,9 +10,14 @@ package com.c2kernel.process; +import com.c2kernel.entity.proxy.AgentProxy; + abstract public class StandardClient extends AbstractMain -{ +{ - //TODO: Auto-update from server + static public void main(String[] args) throws Exception { + Gateway.init(readC2KArgs(args), false); + AgentProxy user = Gateway.connect("username", "password"); + } } diff --git a/src/main/java/com/c2kernel/process/module/Module.java b/src/main/java/com/c2kernel/process/module/Module.java new file mode 100644 index 0000000..08ea4dc --- /dev/null +++ b/src/main/java/com/c2kernel/process/module/Module.java @@ -0,0 +1,296 @@ +package com.c2kernel.process.module; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; +import org.xml.sax.InputSource; + +import com.c2kernel.common.ObjectNotFoundException; +import com.c2kernel.entity.proxy.ItemProxy; +import com.c2kernel.events.Event; +import com.c2kernel.events.History; +import com.c2kernel.lifecycle.instance.predefined.entitycreation.Dependency; +import com.c2kernel.lifecycle.instance.predefined.entitycreation.DependencyMember; +import com.c2kernel.lifecycle.instance.predefined.entitycreation.NewAgent; +import com.c2kernel.lifecycle.instance.predefined.entitycreation.NewItem; +import com.c2kernel.lifecycle.instance.predefined.entitycreation.Property; +import com.c2kernel.lifecycle.instance.stateMachine.States; +import com.c2kernel.lifecycle.instance.stateMachine.Transitions; +import com.c2kernel.lookup.DomainPath; +import com.c2kernel.persistency.outcome.Outcome; +import com.c2kernel.persistency.outcome.Viewpoint; +import com.c2kernel.process.Bootstrap; +import com.c2kernel.process.Gateway; +import com.c2kernel.scripting.ErrorInfo; +import com.c2kernel.scripting.Script; +import com.c2kernel.scripting.ScriptingEngineException; +import com.c2kernel.utils.CastorXMLUtility; +import com.c2kernel.utils.Logger; +import com.c2kernel.utils.Resource; + +public class Module { + + private final String ns, name, desc, version; + private String resURL; + private final ArrayList dependency = new ArrayList(); + private final Properties clientProps = new Properties(); + private final Properties serverProps = new Properties(); + private final HashMap clientScripts = new HashMap(); + private final HashMap serverScripts = new HashMap(); + private final ArrayList imports = new ArrayList(); + private static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + private final DocumentBuilder parser; + private Document moduleDOM; + + static { + dbf.setValidating(false); + dbf.setNamespaceAware(false); + } + + public Module(String moduleXML) throws ModuleException { + try { + parser = dbf.newDocumentBuilder(); + moduleDOM = parser.parse(new InputSource(new StringReader(moduleXML))); + } catch (Exception e) { + Logger.error(e); + throw new ModuleException("Could not process modules. XML Parser exception"); + } + + Element root = (Element)moduleDOM.getElementsByTagName("CristalModule").item(0); + + // Get module metadata + ns = root.getAttribute("ns"); + name = root.getAttribute("name"); + + Element info = (Element)moduleDOM.getElementsByTagName("Info").item(0); + desc = ((Text)info.getElementsByTagName("Description").item(0).getFirstChild()).getData(); + version = ((Text)info.getElementsByTagName("Version").item(0).getFirstChild()).getData(); + NodeList nl = info.getElementsByTagName("Dependency"); + for (int i=0; i0) { + resURL = ((Text)nl.item(0).getFirstChild()).getData(); + Resource.addModuleBaseURL(ns, resURL); + } + + // Get config properties + nl = root.getElementsByTagName("Config"); + for (int i=0; i0) { + Element impElem = (Element)nl.item(0); + nl = impElem.getChildNodes(); + for (int i=0; i scripts = isServer?serverScripts:clientScripts; + Script thisScript = scripts.get(event); + if (thisScript == null) return null; + try { + Object result = thisScript.execute(); + if (result instanceof ErrorInfo) + return (ErrorInfo)result; + else + return new ErrorInfo(result.toString()); + } catch (ScriptingEngineException ex) { + Logger.error(ex); + return new ErrorInfo("Error running "+event+" script in module "+ns); + } + } + + public void importAll(ItemProxy serverEntity) { + for (ModuleImport thisImp : imports) { + if (thisImp instanceof ModuleResource) { + ModuleResource thisRes = (ModuleResource)thisImp; + try { + Bootstrap.verifyResource(ns, thisRes.importName, thisRes.resourceType, Resource.getTextResource(ns, thisRes.resourceLocation)); + } catch (Exception ex) { + Logger.error(ex); + } + } + else if (thisImp instanceof ModuleItem) { + ModuleItem thisItem = (ModuleItem)thisImp; + try { + NewItem item = new NewItem(thisItem.importName, "/desc/"+ns, thisItem.workflow); + item.propertyList = thisItem.props; + DomainPath itemPath = new DomainPath(new DomainPath(item.initialPath), item.name); + if (itemPath.exists()) continue; + serverEntity.requestAction( + Gateway.getLDAPLookup().getRoleManager().getAgentPath("system").getSysKey(), + "workflow/predefined/CreateNewItem", + Transitions.DONE, + CastorXMLUtility.marshall(item)); + Logger.msg("Module.importAll() - Created item: "+thisItem.importName); + ItemProxy newProxy = (ItemProxy)Gateway.getProxyManager().getProxy(itemPath); + History hist = new History(newProxy.getSystemKey(), newProxy); + for (String thisView : thisItem.outcomes.keySet()) { + String[] info = thisView.split(":"); + int version = Integer.parseInt(info[1]); + String data = Resource.getTextResource(ns, thisItem.outcomes.get(thisView)); + Event newEvent = hist.addEvent("system", "Admin", Transitions.DONE, "Import", "Import", "Import", States.FINISHED); + Outcome newOutcome = new Outcome(newEvent.getID(), data, info[0], version); + Viewpoint newLastView = new Viewpoint(newProxy.getSystemKey(), info[0], info[2], version, newEvent.getID()); + Gateway.getStorage().put(newProxy.getSystemKey(), newOutcome, newProxy); + Gateway.getStorage().put(newProxy.getSystemKey(), newLastView, newProxy); + } + for (Dependency thisDep : thisItem.deps) { + Gateway.getStorage().put(newProxy.getSystemKey(), thisDep.create(), newProxy); + } + Gateway.getStorage().commit(newProxy); + } catch (Exception ex) { + Logger.error("Error importing item "+thisItem.importName+" from module "+name); + Logger.error(ex); + } + } + else if (thisImp instanceof ModuleAgent) { + ModuleAgent thisAgent = (ModuleAgent)thisImp; + try { + Gateway.getLDAPLookup().getRoleManager().getAgentPath(thisAgent.importName); + Logger.msg(3, "Module.importAll() - User '"+thisAgent.importName+"' found."); + return; + } catch (ObjectNotFoundException ex) { } + Logger.msg("Module.importAll() - User '"+thisAgent.importName+"' not found. Creating."); + + NewAgent agent = new NewAgent(thisAgent.importName, thisAgent.password); + agent.roles = thisAgent.roles; + try { + serverEntity.requestAction( + Gateway.getLDAPLookup().getRoleManager().getAgentPath("system").getSysKey(), + "workflow/predefined/CreateNewAgent", + Transitions.DONE, + CastorXMLUtility.marshall(agent)); + } catch (Exception ex) { + Logger.error("Error importing agent "+thisAgent.importName+" from module "+name); + Logger.error(ex); + } + } + } + } + + public Properties getClientProperties() { + return clientProps; + } + + public Properties getServerProperties() { + return serverProps; + } + + public String getNs() { + return ns; + } + public String getName() { + return name; + } + public String getDesc() { + return desc; + } + public String getVersion() { + return version; + } + public String getResURL() { + return resURL; + } + public ArrayList getDependencies() { + return dependency; + } + public boolean hasDependency(String dep) { + return dependency.contains(dep); + } +} \ No newline at end of file diff --git a/src/main/java/com/c2kernel/process/module/ModuleException.java b/src/main/java/com/c2kernel/process/module/ModuleException.java new file mode 100644 index 0000000..cc15565 --- /dev/null +++ b/src/main/java/com/c2kernel/process/module/ModuleException.java @@ -0,0 +1,9 @@ +package com.c2kernel.process.module; + +public class ModuleException extends Exception { + + public ModuleException(String msg) { + super(msg); + } + +} diff --git a/src/main/java/com/c2kernel/process/module/ModuleManager.java b/src/main/java/com/c2kernel/process/module/ModuleManager.java new file mode 100644 index 0000000..b99b325 --- /dev/null +++ b/src/main/java/com/c2kernel/process/module/ModuleManager.java @@ -0,0 +1,91 @@ +package com.c2kernel.process.module; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Properties; + +import com.c2kernel.common.ObjectNotFoundException; +import com.c2kernel.entity.proxy.ItemProxy; +import com.c2kernel.lookup.DomainPath; +import com.c2kernel.process.Gateway; +import com.c2kernel.utils.FileStringUtility; +import com.c2kernel.utils.Logger; + +public class ModuleManager { + ArrayList modules = new ArrayList(); + Properties props = new Properties(); + boolean isServer; + + public ModuleManager(Enumeration moduleEnum, boolean isServer) throws ModuleException{ + this.isServer = isServer; + ArrayList loadedModules = new ArrayList(); + ArrayList moduleNs = new ArrayList(); + while(moduleEnum.hasMoreElements()) { + URL newModuleURL = moduleEnum.nextElement(); + try { + Module newModule = new Module(FileStringUtility.url2String(newModuleURL)); + modules.add(newModule); + 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 = isServer?newModule.getServerProperties():newModule.getClientProperties(); + 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 (IOException e) { + Logger.error(e); + throw new ModuleException("Could not load module.xml from "+newModuleURL); + } + } + + Logger.debug(5, "Checking dependencies"); + 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) { + thisMod.runScript(event, isServer); + } + } + + public void registerModules() throws ObjectNotFoundException { + 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); + Logger.msg("Module "+thisMod.getName()+" registered"); + } + } +} -- cgit v1.2.3