diff options
Diffstat (limited to 'src/main/java/org/cristalise/kernel/process')
25 files changed, 2981 insertions, 0 deletions
diff --git a/src/main/java/org/cristalise/kernel/process/AbstractMain.java b/src/main/java/org/cristalise/kernel/process/AbstractMain.java new file mode 100644 index 0000000..5acfbef --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/AbstractMain.java @@ -0,0 +1,178 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.cristalise.kernel.process.resource.BadArgumentsException;
+import org.cristalise.kernel.utils.FileStringUtility;
+import org.cristalise.kernel.utils.Logger;
+
+
+/**************************************************************************
+ *
+ * @author $Author: abranson $ $Date: 2004/10/25 15:27:35 $
+ * @version $Revision: 1.67 $
+ **************************************************************************/
+abstract public class AbstractMain
+{
+ public static boolean isServer = false;
+ private static ShutdownHandler shutdownHandler;
+
+ public static String MAIN_ARG_NONEWLOGSTREAM = "noNewLogStream";
+ public static String MAIN_ARG_CONFIG = "config";
+ public static String MAIN_ARG_LOGLEVEL = "logLevel";
+ public static String MAIN_ARG_LOGFILE = "logFile";
+ public static String MAIN_ARG_CONNECT = "connect";
+
+
+
+ /**************************************************************************
+ * reading and setting input paramaters
+ **************************************************************************
+ *
+ * Known arguments :
+ * <ul>
+ * <li>logLevel: the log level 0-9 (+10 to have time, +20 to have only one level)</li>
+ * <li>logFile: the full path of the target log file. if none, the Logstream is the stdOut</li>
+ * <li>noNewLogStream: if present no new Logstream is added to the logger (
+ * considers that the Logger is already configured)</li>
+ *
+ * <li>config</li>
+ * <li>connect</li>
+ * <li>LocalCentre</li>
+ * </ul>
+ *
+ *
+ * @param args
+ * @return
+ * @throws BadArgumentsException
+ */
+ public static Properties readC2KArgs( String[] args ) throws BadArgumentsException {
+ Properties c2kProps;
+ Properties argProps = new Properties();
+ int logLevel = 0;
+ PrintStream logStream = System.out;
+
+ int i = 0;
+ while( i < args.length ) {
+ if (args[i].startsWith("-") && args[i].length()>1) {
+ String key = args[i].substring(1);
+ if (argProps.containsKey(key))
+ throw new BadArgumentsException("Argument "+args[i]+" given twice");
+ String value = "";
+ if (!args[i+1].startsWith("-"))
+ value = args[++i];
+ argProps.put(key, value);
+ i++;
+ }
+ else
+ throw new BadArgumentsException("Bad argument: "+args[i]);
+
+ }
+
+ if (argProps.containsKey("logFile"))
+ try {
+ logStream = new PrintStream(new FileOutputStream(argProps.getProperty("logFile"), true));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ throw new BadArgumentsException("Logfile "+argProps.getProperty("logFile")+" cannot be created");
+ }
+
+
+ // if the optional arg "noNewLogStream" isn't present => add a
+ // new LogStream
+ boolean wMustAddNewLogStream = !argProps.contains(MAIN_ARG_NONEWLOGSTREAM);
+ if (wMustAddNewLogStream) {
+
+ // Set up log stream
+ if (argProps.containsKey("logLevel"))
+ logLevel = Integer.parseInt(argProps.getProperty("logLevel"));
+
+ Logger.addLogStream(logStream, logLevel);
+ }
+ if (wMustAddNewLogStream) Logger.msg(
+ String.format("New logStream added at logLevel %d: %s", logLevel, logStream.getClass().getName()));
+
+
+ // Dump params if log high enough
+
+ if (Logger.doLog(3)) for (Enumeration<?> e = argProps.propertyNames(); e.hasMoreElements();) {
+ String next = (String)e.nextElement();
+ System.out.println("AbstractMain: Param "+next+": "+argProps.getProperty(next));
+ }
+
+ String configPath = argProps.getProperty("config");
+ if (configPath == null)
+ throw new BadArgumentsException("Config file not specified");
+
+ if (!new File(configPath).exists())
+ throw new BadArgumentsException("Config file "+configPath+" not found");
+ else
+ Logger.msg(0, "Config file: "+configPath);
+
+ // Load config & connect files into c2kprops
+ c2kProps = FileStringUtility.loadConfigFile(argProps.getProperty("config") );
+ c2kProps.putAll(argProps); // args overlap config
+
+ String connectFile = c2kProps.getProperty("connect");
+ if (connectFile == null)
+ throw new BadArgumentsException("Connect file not specified");
+
+ if (!new File(connectFile).exists())
+ throw new BadArgumentsException("Connect file "+connectFile+" not found");
+ else
+ Logger.msg(0, "Connect file: "+connectFile);
+
+ FileStringUtility.appendConfigFile( c2kProps, connectFile);
+
+ if (!c2kProps.containsKey("LocalCentre")) {
+ String connectFileName = new File(connectFile).getName();
+ String centreId = connectFileName.substring(0, connectFileName.lastIndexOf(".clc"));
+ c2kProps.setProperty("LocalCentre", centreId);
+ }
+
+ c2kProps.putAll(argProps); // args override connect file too
+ Logger.msg(7, "AbstractMain::standardSetUp() - readC2KArgs() DONE.");
+
+ return c2kProps;
+ }
+
+ public static void setShutdownHandler(ShutdownHandler handler) {
+ shutdownHandler = handler;
+ }
+
+ public static void shutdown(int errCode) {
+ if (shutdownHandler!= null)
+ shutdownHandler.shutdown(errCode, isServer);
+ else
+ try {
+ Gateway.close();
+ } catch (Exception ex) {
+ Logger.error(ex);
+ }
+ }
+}
diff --git a/src/main/java/org/cristalise/kernel/process/Bootstrap.java b/src/main/java/org/cristalise/kernel/process/Bootstrap.java new file mode 100644 index 0000000..8934cd8 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/Bootstrap.java @@ -0,0 +1,394 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+import org.cristalise.kernel.common.InvalidDataException;
+import org.cristalise.kernel.common.ObjectNotFoundException;
+import org.cristalise.kernel.entity.proxy.AgentProxy;
+import org.cristalise.kernel.entity.proxy.ItemProxy;
+import org.cristalise.kernel.events.Event;
+import org.cristalise.kernel.events.History;
+import org.cristalise.kernel.lifecycle.CompositeActivityDef;
+import org.cristalise.kernel.lifecycle.instance.CompositeActivity;
+import org.cristalise.kernel.lifecycle.instance.Workflow;
+import org.cristalise.kernel.lifecycle.instance.predefined.server.ServerPredefinedStepContainer;
+import org.cristalise.kernel.lifecycle.instance.stateMachine.Transition;
+import org.cristalise.kernel.lookup.AgentPath;
+import org.cristalise.kernel.lookup.DomainPath;
+import org.cristalise.kernel.lookup.InvalidItemPathException;
+import org.cristalise.kernel.lookup.ItemPath;
+import org.cristalise.kernel.lookup.LookupManager;
+import org.cristalise.kernel.lookup.Path;
+import org.cristalise.kernel.lookup.RolePath;
+import org.cristalise.kernel.persistency.ClusterStorage;
+import org.cristalise.kernel.persistency.outcome.Outcome;
+import org.cristalise.kernel.persistency.outcome.OutcomeValidator;
+import org.cristalise.kernel.persistency.outcome.Viewpoint;
+import org.cristalise.kernel.process.resource.DefaultResourceImportHandler;
+import org.cristalise.kernel.process.resource.ResourceImportHandler;
+import org.cristalise.kernel.property.Property;
+import org.cristalise.kernel.property.PropertyArrayList;
+import org.cristalise.kernel.property.PropertyDescription;
+import org.cristalise.kernel.property.PropertyDescriptionList;
+import org.cristalise.kernel.utils.FileStringUtility;
+import org.cristalise.kernel.utils.LocalObjectLoader;
+import org.cristalise.kernel.utils.Logger;
+import org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.XMLUnit;
+
+
+/**
+ * @version $Revision: 1.25 $ $Date: 2006/01/10 09:48:32 $
+ * @author $Author: abranson $
+ */
+
+public class Bootstrap
+{
+ static DomainPath thisServerPath;
+ static HashMap<String, ResourceImportHandler> resHandlerCache = new HashMap<String, ResourceImportHandler>();
+ static HashMap<String, AgentProxy> systemAgents = new HashMap<String, AgentProxy>();
+
+ /**
+ * Run everything without timing-out the service wrapper
+ */
+ public static void run() throws Exception {
+ // check for system agents
+ checkAdminAgents();
+
+ // create the server's mother item
+ createServerItem();
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Thread.currentThread().setName("Bootstrapper");
+
+ ClassLoader wClassLoader = Bootstrap.class.getClassLoader();
+ Logger.msg(String.format("Bootstrap.run() setContextClassLoader=[%s]",wClassLoader));
+ Thread.currentThread().setContextClassLoader(wClassLoader);
+
+ // 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();
+
+ Gateway.getModuleManager().setUser(systemAgents.get("system"));
+ Gateway.getModuleManager().registerModules();
+
+ Logger.msg("Bootstrap.run() - Bootstrapping complete");
+ } catch (Throwable e) {
+ Logger.error(e);
+ Logger.die("Exception performing bootstrap. Check that everything is OK.");
+ }
+ }
+ }).start();
+ }
+
+ /**************************************************************************
+ * Checks all kernel descriptions, stored in resources
+ **************************************************************************/
+ public static void verifyBootDataItems() throws Exception {
+ String bootItems;
+ Logger.msg(1, "Verifying kernel boot items");
+ bootItems = FileStringUtility.url2String(Gateway.getResource().getKernelResourceURL("boot/allbootitems.txt"));
+ verifyBootDataItems(bootItems, null, true);
+ Logger.msg(1, "Boot data items complete");
+ }
+
+ private static void verifyBootDataItems(String bootList, String ns, boolean reset) throws InvalidItemPathException {
+ StringTokenizer str = new StringTokenizer(bootList, "\n\r");
+ while (str.hasMoreTokens()) {
+ String thisItem = str.nextToken();
+ ItemPath itemPath = null;
+ String[] itemParts = thisItem.split("/");
+ if (itemParts.length == 3) { // includes UUID
+ itemPath = new ItemPath(itemParts[2]);
+ }
+ String itemType = itemParts[0];
+ String itemName = itemParts[1];
+ try {
+ String location = "boot/"+thisItem+(itemType.equals("OD")?".xsd":".xml");
+ verifyResource(ns, itemName, 0, itemType, itemPath, location, reset);
+ } catch (Exception e) {
+ Logger.error(e);
+ Logger.die("Error importing bootstrap items. Unsafe to continue.");
+ }
+ }
+ }
+
+ public static DomainPath verifyResource(String ns, String itemName, int version, String itemType, ItemPath itemPath, String dataLocation, boolean reset) throws Exception {
+ LookupManager lookupManager = Gateway.getLookupManager();
+ ResourceImportHandler typeImpHandler = getHandler(itemType);
+ Logger.msg(1, "Bootstrap.verifyResource() - Verifying version "+version+" of "+typeImpHandler.getName()+" "+itemName);
+
+ // Find or create Item for Resource
+ DomainPath modDomPath = typeImpHandler.getPath(itemName, ns);
+ ItemProxy thisProxy;
+ Iterator<Path> en = Gateway.getLookup().search(typeImpHandler.getTypeRoot(), itemName);
+ if (!en.hasNext()) {
+ if (itemPath == null) itemPath = new ItemPath();
+ Logger.msg("Bootstrap.verifyResource() - "+typeImpHandler.getName()+" "+itemName+" not found. Creating new.");
+ thisProxy = createResourceItem(typeImpHandler, itemName, ns, itemPath);
+ }
+ else {
+ DomainPath path = (DomainPath)en.next();
+ thisProxy = Gateway.getProxyManager().getProxy(path);
+ if (itemPath != null && !path.getItemPath().equals(itemPath)) {
+ Logger.warning("Resource "+itemType+"/"+itemName+" should have path "+itemPath+" but was found with path "+path.getItemPath());
+ itemPath = path.getItemPath();
+ }
+ if (itemPath == null) itemPath = path.getItemPath();
+ // Verify module property and location
+
+ String moduleName = (ns==null?"kernel":ns);
+ String itemModule;
+ try{
+ itemModule = thisProxy.getProperty("Module");
+ if (!itemModule.equals("") && !itemModule.equals("null") && !moduleName.equals(itemModule)) {
+ Logger.error("Bootstrap.verifyResource() - Module clash! Resource '"+itemName+"' included in module "+moduleName+" but is assigned to '"+itemModule+"'. Not overwriting.");
+ return path;
+ }
+ } catch (ObjectNotFoundException ex) {
+ itemModule = "";
+ }
+
+ if (!moduleName.equals(itemModule)) { // write module property
+ Gateway.getStorage().put(itemPath, new Property("Module", moduleName, false), thisProxy);
+ }
+
+ if (!modDomPath.equals(path)) { // move item to module subtree
+ Logger.msg("Module item "+itemName+" found with path "+path.toString()+". Moving to "+modDomPath.toString());
+ modDomPath.setItemPath(itemPath);
+ if (!modDomPath.exists())
+ lookupManager.add(modDomPath);
+ lookupManager.delete(path);
+ }
+ }
+
+ // Verify/Import Outcomes, creating events and views as necessary
+ Set<Outcome> impList = typeImpHandler.getResourceOutcomes(itemName, ns, dataLocation, version);
+ for (Outcome newOutcome : impList) {
+ try {
+ Viewpoint currentData = (Viewpoint)thisProxy.getObject(ClusterStorage.VIEWPOINT+"/"+newOutcome.getSchemaType()+"/"+version);
+ Outcome oldData = currentData.getOutcome();
+ XMLUnit.setIgnoreWhitespace(true);
+ XMLUnit.setIgnoreComments(true);
+ Diff xmlDiff = new Diff(newOutcome.getDOM(), oldData.getDOM());
+ if (xmlDiff.identical()) {
+ Logger.msg(5, "Bootstrap.verifyResource() - Data identical, no update required");
+ continue;
+ }
+ else {
+ Logger.msg("Difference found in "+itemName+": "+xmlDiff.toString());
+ if (!reset && !currentData.getEvent().getStepPath().equals("Bootstrap")) {
+ Logger.msg("Version "+version+" was not set by Bootstrap, and reset not requested. Not overwriting.");
+ continue;
+ }
+ }
+
+ } catch (ObjectNotFoundException ex) {
+ Logger.msg("Bootstrap.verifyResource() - Item "+itemName+" exists but version "+version+" not found! Attempting to insert new.");
+ }
+
+ // data was missing or doesn't match
+ // validate it (but not for kernel objects because we need those to validate the rest)
+ if (ns!= null) {
+ OutcomeValidator validator = OutcomeValidator.getValidator(LocalObjectLoader.getSchema(newOutcome.getSchemaType(), newOutcome.getSchemaVersion()));
+ String error = validator.validate(newOutcome.getData());
+ if (error.length() > 0) {
+ Logger.error("Outcome not valid: \n " + error);
+ throw new InvalidDataException(error);
+ }
+ }
+
+ // store
+ Logger.msg("Bootstrap.verifyResource() - Writing new "+newOutcome.getSchemaType()+" v"+version+" to "+typeImpHandler.getName()+" "+itemName);
+ History hist = new History(itemPath, thisProxy);
+ Transition predefDone = new Transition(0, "Done", 0, 0);
+ Event newEvent = hist.addEvent(systemAgents.get("system").getPath(), "Admin", "Bootstrap", "Bootstrap", "Bootstrap", newOutcome.getSchemaType(), 0, "PredefinedStep", 0, predefDone, String.valueOf(version));
+ newOutcome.setID(newEvent.getID());
+ Viewpoint newLastView = new Viewpoint(itemPath, newOutcome.getSchemaType(), "last", 0, newEvent.getID());
+ Viewpoint newNumberView = new Viewpoint(itemPath, newOutcome.getSchemaType(), String.valueOf(version), 0, newEvent.getID());
+ Gateway.getStorage().put(itemPath, newOutcome, thisProxy);
+ Gateway.getStorage().put(itemPath, newLastView, thisProxy);
+ Gateway.getStorage().put(itemPath, newNumberView, thisProxy);
+ }
+ Gateway.getStorage().commit(thisProxy);
+ return modDomPath;
+ }
+
+ private static ResourceImportHandler getHandler(String resType) throws Exception {
+ if (resHandlerCache.containsKey(resType))
+ return resHandlerCache.get(resType);
+ ResourceImportHandler handler = null;
+ if (Gateway.getProperties().containsKey("ResourceImportHandler."+resType)) {
+ try {
+ handler = (ResourceImportHandler) Gateway.getProperties().getInstance("ResourceImportHandler."+resType);
+ } catch (Exception ex) {
+ Logger.error(ex);
+ Logger.error("Exception loading ResourceHandler for "+resType+". Using default.");
+ }
+ }
+
+ if (handler == null)
+ handler = new DefaultResourceImportHandler(resType);
+
+ resHandlerCache.put(resType, handler);
+ return handler;
+ }
+
+ /**
+ * @param itemType
+ * @param itemName
+ * @param data
+ */
+ private static ItemProxy createResourceItem(ResourceImportHandler impHandler, String itemName, String ns, ItemPath itemPath) throws Exception {
+ // create props
+ PropertyDescriptionList pdList = impHandler.getPropDesc();
+ PropertyArrayList props = new PropertyArrayList();
+ LookupManager lookupManager = Gateway.getLookupManager();
+
+ for (int i = 0; i < pdList.list.size(); i++) {
+ PropertyDescription pd = pdList.list.get(i);
+ String propName = pd.getName();
+ String propVal = propName.equals("Name")?itemName:pd.getDefaultValue();
+ props.list.add(new Property(propName, propVal, pd.getIsMutable()));
+ }
+
+ CompositeActivity ca = new CompositeActivity();
+ if (ns!=null && Gateway.getProperties().getBoolean("Module.debug", false))
+ try {
+ ca = (CompositeActivity) ((CompositeActivityDef)LocalObjectLoader.getActDef(impHandler.getWorkflowName(), 0)).instantiate();
+ } catch (ObjectNotFoundException ex) {
+ Logger.error("Module resource workflow "+impHandler.getWorkflowName()+" not found. Using empty.");
+ }
+
+
+ Gateway.getCorbaServer().createItem(itemPath);
+ lookupManager.add(itemPath);
+ DomainPath newDomPath = impHandler.getPath(itemName, ns);
+ newDomPath.setItemPath(itemPath);
+ lookupManager.add(newDomPath);
+ ItemProxy newItemProxy = Gateway.getProxyManager().getProxy(itemPath);
+ newItemProxy.initialise( systemAgents.get("system").getPath(), props, ca, null);
+ return newItemProxy;
+ }
+
+ /**************************************************************************
+ * Checks for the existence of the admin users so you can use Cristal
+ **************************************************************************/
+ private static void checkAgent(String name, String pass, RolePath rolePath, String uuid) throws Exception {
+ Logger.msg(1, "Bootstrap.checkAgent() - Checking for existence of '"+name+"' user.");
+ LookupManager lookup = Gateway.getLookupManager();
+
+ try {
+ systemAgents.put(name, Gateway.getProxyManager().getAgentProxy(lookup.getAgentPath(name)));
+ Logger.msg(3, "Bootstrap.checkAgent() - User '"+name+"' found.");
+ return;
+ } catch (ObjectNotFoundException ex) { }
+
+ Logger.msg("Bootstrap.checkAgent() - User '"+name+"' not found. Creating.");
+
+ try {
+ AgentPath agentPath = new AgentPath(new ItemPath(uuid), name);
+ agentPath.setPassword(pass);
+ Gateway.getCorbaServer().createAgent(agentPath);
+ lookup.add(agentPath);
+
+ // assign admin role
+ Logger.msg("Bootstrap.checkAgent() - Assigning role '"+rolePath.getName()+"'");
+ Gateway.getLookupManager().addRole(agentPath, rolePath);
+ Gateway.getStorage().put(agentPath, new Property("Name", name, true), null);
+ Gateway.getStorage().put(agentPath, new Property("Type", "Agent", false), null);
+ systemAgents.put(name, Gateway.getProxyManager().getAgentProxy(agentPath));
+ } catch (Exception ex) {
+ Logger.error("Unable to create "+name+" user.");
+ throw ex;
+ }
+ }
+
+ /**
+ *
+ */
+ public static void checkAdminAgents() throws Exception {
+
+ // check for administrative user & admin role
+ String adminPassword = Gateway.getProperties().getString("AdminPassword", "admin12345");
+ RolePath rootRole = new RolePath();
+ if (!rootRole.exists()) Gateway.getLookupManager().createRole(rootRole);
+ RolePath adminRole = new RolePath(rootRole, "Admin", false);
+ if (!adminRole.exists()) Gateway.getLookupManager().createRole(adminRole);
+
+ // check for import user
+ checkAgent("system", adminPassword, adminRole, new UUID(0, 0).toString());
+
+ checkAgent("admin", adminPassword, adminRole, new UUID(0, 1).toString());
+
+ // check for local usercode user & role
+ RolePath usercodeRole = new RolePath(rootRole, "UserCode", true);
+ if (!usercodeRole.exists()) Gateway.getLookupManager().createRole(usercodeRole);
+ checkAgent(InetAddress.getLocalHost().getHostName(), "uc", usercodeRole, UUID.randomUUID().toString());
+ }
+
+ public static void createServerItem() throws Exception {
+ LookupManager lookupManager = Gateway.getLookupManager();
+ String serverName = Gateway.getProperties().getString("ItemServer.name", InetAddress.getLocalHost().getHostName());
+ thisServerPath = new DomainPath("/servers/"+serverName);
+ ItemPath serverEntity;
+ try {
+ serverEntity = thisServerPath.getItemPath();
+ } catch (ObjectNotFoundException ex) {
+ Logger.msg("Creating server item "+thisServerPath);
+ serverEntity = new ItemPath();
+ Gateway.getCorbaServer().createItem(serverEntity);
+ lookupManager.add(serverEntity);
+ thisServerPath.setItemPath(serverEntity);
+ lookupManager.add(thisServerPath);
+ }
+ Gateway.getStorage().put(serverEntity, new Property("Name", serverName, false), null);
+ Gateway.getStorage().put(serverEntity, new Property("Type", "Server", false), null);
+ Gateway.getStorage().put(serverEntity, new Property("KernelVersion", Gateway.getKernelVersion(), true), null);
+ int proxyPort = Gateway.getProperties().getInt("ItemServer.Proxy.port", 1553);
+ Gateway.getStorage().put(serverEntity,
+ new Property("ProxyPort", String.valueOf(proxyPort), false), null);
+ Gateway.getStorage().put(serverEntity,
+ new Property("ConsolePort", String.valueOf(Logger.getConsolePort()), true), null);
+ Gateway.getProxyManager().connectToProxyServer(serverName, proxyPort);
+
+ }
+
+ public static void initServerItemWf() throws Exception {
+ CompositeActivityDef serverWfCa = (CompositeActivityDef)LocalObjectLoader.getActDef("ServerItemWorkflow", 0);
+ Workflow wf = new Workflow((CompositeActivity)serverWfCa.instantiate(), new ServerPredefinedStepContainer());
+ wf.initialise(thisServerPath.getItemPath(), systemAgents.get("system").getPath());
+ Gateway.getStorage().put(thisServerPath.getItemPath(), wf, null);
+ }
+}
diff --git a/src/main/java/org/cristalise/kernel/process/ClientShell.java b/src/main/java/org/cristalise/kernel/process/ClientShell.java new file mode 100644 index 0000000..0a9ad83 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/ClientShell.java @@ -0,0 +1,71 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process;
+
+import java.util.Scanner;
+
+import org.cristalise.kernel.entity.proxy.AgentProxy;
+import org.cristalise.kernel.process.auth.ProxyLogin;
+import org.cristalise.kernel.scripting.Script;
+import org.cristalise.kernel.scripting.ScriptParsingException;
+
+
+public class ClientShell extends StandardClient {
+
+ AgentProxy user;
+ Script console;
+
+ public ClientShell(AgentProxy user) throws Exception {
+ this.user = user;
+ console = new Script("javascript", user, System.out);
+ }
+
+ public void run() {
+ Scanner scan = new Scanner(System.in);
+ System.out.print("> ");
+ while (scan.hasNextLine()) {
+ String command = scan.nextLine();
+ try {
+ console.setScript(command);
+ Object response = console.execute();
+ if (response == null)
+ System.out.println("Ok");
+ else
+ System.out.println(response);
+ } catch (ScriptParsingException e) {
+ System.err.println("Syntax error: "+e.getMessage());
+ } catch (Throwable ex) {
+ ex.printStackTrace();
+ }
+ System.out.print("> ");
+ }
+ shutdown(0);
+ }
+
+ public static void main(String[] args) throws Exception {
+ Gateway.init(readC2KArgs(args));
+ ProxyLogin auth = (ProxyLogin)Gateway.getProperties().getInstance("cli.auth");
+ AgentProxy user = auth.authenticate(Gateway.getProperties().getProperty("Name"));
+ ClientShell shell = new ClientShell(user);
+ shell.run();
+ }
+
+}
diff --git a/src/main/java/org/cristalise/kernel/process/Gateway.java b/src/main/java/org/cristalise/kernel/process/Gateway.java new file mode 100644 index 0000000..c7936c3 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/Gateway.java @@ -0,0 +1,426 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process;
+
+/**
+ * @version $Revision: 1.17 $ $Date: 2005/10/12 12:51:54 $
+ * @author $Author: abranson $
+ */
+
+import java.net.MalformedURLException;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.cristalise.kernel.common.CannotManageException;
+import org.cristalise.kernel.common.InvalidDataException;
+import org.cristalise.kernel.common.ObjectNotFoundException;
+import org.cristalise.kernel.common.PersistencyException;
+import org.cristalise.kernel.entity.CorbaServer;
+import org.cristalise.kernel.entity.proxy.AgentProxy;
+import org.cristalise.kernel.entity.proxy.ProxyManager;
+import org.cristalise.kernel.entity.proxy.ProxyServer;
+import org.cristalise.kernel.lookup.AgentPath;
+import org.cristalise.kernel.lookup.Lookup;
+import org.cristalise.kernel.lookup.LookupManager;
+import org.cristalise.kernel.persistency.TransactionManager;
+import org.cristalise.kernel.process.auth.Authenticator;
+import org.cristalise.kernel.process.module.ModuleManager;
+import org.cristalise.kernel.process.resource.Resource;
+import org.cristalise.kernel.process.resource.ResourceLoader;
+import org.cristalise.kernel.utils.CastorXMLUtility;
+import org.cristalise.kernel.utils.FileStringUtility;
+import org.cristalise.kernel.utils.Language;
+import org.cristalise.kernel.utils.Logger;
+import org.cristalise.kernel.utils.ObjectProperties;
+
+
+
+/**************************************************************************
+ * The Gateway is the central object of a CRISTAL process. It initializes,
+ * maintains and shuts down every other subsystem in both the client and the
+ * server.
+ *
+ * Child objects:
+ * <ul>
+ * <li>Lookup - Provides access to the CRISTAL directory. Find or
+ * search for Items or Agents.
+ * <li>EntityProxyManager - Gives a local proxy object for Entities found
+ * in LDAP. Execute activities in Items, query or subscribe to Entity data.
+ * <li>TransactionManager - Access to the configured CRISTAL databases
+ * <li>CorbaServer - Manages the memory pool of active Entities
+ * <li>mORB - the Orbacus CORBA ORB
+ * </ul>
+ *
+ * @author $Author: abranson $ $Date: 2005/10/12 12:51:54 $
+ * @version $Revision: 1.17 $
+ **************************************************************************/
+
+public class Gateway
+{
+ static private ObjectProperties mC2KProps = new ObjectProperties();
+ static private ModuleManager mModules;
+ static private org.omg.CORBA.ORB mORB;
+ static private boolean orbDestroyed = false;
+ static private Lookup mLookup;
+ static private LookupManager mLookupManager = null;
+ static private TransactionManager mStorage;
+ static private ProxyManager mProxyManager;
+ static private ProxyServer mProxyServer;
+ static private CorbaServer mCorbaServer;
+ static private CastorXMLUtility mMarshaller;
+ static private ResourceLoader mResource;
+
+
+
+ private Gateway() { }
+
+ /**
+ * Initialises the Gateway and all of the client objects it holds, with
+ * the exception of the Lookup, which is initialised during connect()
+ *
+ * @param props - java.util.Properties containing all application properties.
+ * If null, the java system properties are used
+ * @throws InvalidDataException - invalid properties caused a failure in initialisation
+ */
+ static public void init(Properties props) throws InvalidDataException {
+ init(props, null);
+ }
+
+ /**
+ * Initialises the Gateway and all of the client objects it holds, with
+ * the exception of the Lookup, which is initialised during connect()
+ *
+ * @param props - java.util.Properties containing all application properties.
+ * If null, the java system properties are used
+ * @param res - ResourceLoader for the kernel to use to resolve all class resource requests
+ * such as for bootstrap descriptions and version information
+ * @throws InvalidDataException - invalid properties caused a failure in initialisation
+ */
+ static public void init(Properties props, ResourceLoader res) throws InvalidDataException {
+
+ // Init properties & resources
+ mC2KProps.clear();
+
+ orbDestroyed = false;
+ mResource = res;
+ if (mResource == null) mResource = new Resource();
+
+ // report version info
+ Logger.msg("Kernel version: "+getKernelVersion());
+
+ // load kernel mapfiles giving the resourse loader and the properties of
+ // the application to be able to configure castor
+ try {
+ mMarshaller = new CastorXMLUtility(mResource, props, mResource.getKernelResourceURL("mapFiles/"));
+ } catch (MalformedURLException e1) {
+ throw new InvalidDataException("Invalid Resource Location");
+ }
+
+
+ // init module manager
+ try {
+ mModules = new ModuleManager(mResource.getModuleDefURLs(), AbstractMain.isServer);
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new InvalidDataException("Could not load module definitions.");
+ }
+
+ // merge in module props
+ Properties moduleProperties = mModules.getAllModuleProperties();
+ for (Enumeration<?> e = moduleProperties.propertyNames(); e.hasMoreElements();) {
+ String propName = (String)e.nextElement();
+ mC2KProps.put(propName, moduleProperties.get(propName));
+ }
+
+ // Overwrite with argument props
+ if (props != null) mC2KProps.putAll(props);
+
+ // dump properties
+ dumpC2KProps(7);
+
+ //Initialise language file
+ String languageFile = getProperties().getString("language.file");
+ if (languageFile != null && languageFile.length() > 0) {
+ Language.isTranlated=true;
+ Language.mTableOfTranslation = FileStringUtility.loadLanguageFile(languageFile);
+ }
+ }
+
+ /**
+ * Makes this process capable of creating and managing server entities. Runs the
+ * bootstrap to create the root LDAP contexts, initialises the CORBA server and
+ * time-out manager.
+ *
+ * @throws InvalidDataException - error initialising
+ */
+ static public void startServer(Authenticator auth) throws InvalidDataException, CannotManageException {
+ try {
+ // check top level directory contexts
+ if (mLookup instanceof LookupManager) {
+ mLookupManager = (LookupManager)mLookup;
+ mLookupManager.initializeDirectory();
+ }
+ else {
+ throw new CannotManageException("Lookup implementation is not a LookupManager. Cannot write to directory");
+ }
+
+ // start entity proxy server
+ mProxyServer = new ProxyServer(mC2KProps.getProperty("ItemServer.name"));
+
+ // Init ORB - set various config
+ String serverName = mC2KProps.getProperty("ItemServer.name");
+ if (serverName != null)
+ mC2KProps.put("com.sun.CORBA.ORBServerHost", serverName);
+ String serverPort = mC2KProps.getProperty("ItemServer.iiop", "1500");
+ mC2KProps.put("com.sun.CORBA.ORBServerPort", serverPort);
+ //TODO: externalize this (or replace corba completely)
+ mC2KProps.put("com.sun.CORBA.POA.ORBServerId", "1");
+ mC2KProps.put("com.sun.CORBA.POA.ORBPersistentServerPort", serverPort);
+ mC2KProps.put("com.sun.CORBA.codeset.charsets", "0x05010001, 0x00010109"); // need to force UTF-8 in the Sun ORB
+ mC2KProps.put("com.sun.CORBA.codeset.wcharsets", "0x00010109, 0x05010001");
+ //Standard initialisation of the ORB
+ orbDestroyed = false;
+ mORB = org.omg.CORBA.ORB.init(new String[0], mC2KProps);
+
+ Logger.msg("Gateway.init() - ORB initialised. ORB is " + mORB.getClass().getName() );
+
+ // start corba server components
+ mCorbaServer = new CorbaServer();
+
+ // start checking bootstrap & module items
+ Bootstrap.run();
+ System.out.println("Server '"+serverName+"' initialised.");
+ } catch (Exception ex) {
+ Logger.error(ex);
+ Logger.die("Exception starting server components. Shutting down.");
+ }
+
+ }
+
+ public static ModuleManager getModuleManager() {
+ return mModules;
+ }
+
+ /**
+ * Connects to the LDAP server in an administrative context - using the admin username and
+ * password given in the LDAP.user and LDAP.password props of the kernel properties.
+ *
+ * @throws InvalidDataException - bad params
+ * @throws PersistencyException - error starting storages
+ */
+ static public Authenticator connect()
+ throws InvalidDataException,
+ PersistencyException
+ {
+ try {
+ Authenticator auth = (Authenticator)mC2KProps.getInstance("Authenticator");
+ auth.authenticate("System");
+
+ mLookup = (Lookup)mC2KProps.getInstance("Lookup");
+ mLookup.open(auth);
+
+ mStorage = new TransactionManager(auth);
+ mProxyManager = new ProxyManager();
+
+ return auth;
+ } catch (Exception ex) {
+ Logger.error(ex);
+ throw new InvalidDataException("Cannot connect server process. Please check config.");
+ }
+
+
+ }
+
+ /**
+ * Logs in with the given username and password, and initialises the lookup, storage and proxy manager.
+ *
+ * @param agentName - username
+ * @param agentPassword - password
+ * @return an AgentProxy on the requested user
+ * @throws InvalidDataException
+ * @throws PersistencyException
+ * @throws ClassNotFoundException
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ */
+ static public AgentProxy connect(String agentName, String agentPassword, String resource)
+ throws InvalidDataException, ObjectNotFoundException, PersistencyException, InstantiationException, IllegalAccessException, ClassNotFoundException
+ {
+ Authenticator auth = (Authenticator)mC2KProps.getInstance("Authenticator");
+ if (!auth.authenticate(agentName, agentPassword, resource))
+ throw new InvalidDataException("Login failed");
+
+ mLookup = (Lookup)mC2KProps.getInstance("Lookup");
+ mLookup.open(auth);
+
+ mStorage = new TransactionManager(auth);
+ mProxyManager = new ProxyManager();
+
+ // find agent proxy
+ AgentPath agentPath = mLookup.getAgentPath(agentName);
+ AgentProxy userProxy = (AgentProxy) mProxyManager.getProxy(agentPath);
+ userProxy.setAuthObj(auth);
+
+ // Run module startup scripts. Server does this during bootstrap
+ mModules.setUser(userProxy);
+ mModules.runScripts("startup");
+
+ return userProxy;
+ }
+
+ static public AgentProxy connect(String agentName, String agentPassword)
+ throws InvalidDataException, ObjectNotFoundException, PersistencyException, InstantiationException, IllegalAccessException, ClassNotFoundException
+ {
+ return connect(agentName, agentPassword, null);
+ }
+
+ /**
+ * Shuts down all kernel api objects
+ */
+ public static void close()
+ {
+ // run shutdown module scripts
+ if (mModules != null)
+ mModules.runScripts("shutdown");
+
+ // shut down servers if running
+ if (mCorbaServer != null)
+ mCorbaServer.close();
+ mCorbaServer = null;
+
+ // disconnect from storages
+ if (mStorage != null)
+ mStorage.close();
+ mStorage = null;
+
+ // disconnect from ldap
+ if (mLookup != null)
+ mLookup.close();
+ mLookup = null;
+ mLookupManager = null;
+
+ // shut down proxy manager & server
+ if (mProxyManager != null)
+ mProxyManager.shutdown();
+ if (mProxyServer != null)
+ mProxyServer.shutdownServer();
+ mProxyManager = null;
+ mProxyServer = null;
+
+ // close log consoles
+ Logger.closeConsole();
+
+ // finally, destroy the ORB
+ if (!orbDestroyed) {
+ getORB().destroy();
+ orbDestroyed = true;
+ mORB = null;
+ }
+
+ // clean up remaining objects
+ mModules = null;
+ mResource = null;
+ mMarshaller = null;
+ mC2KProps.clear();
+ }
+
+ static public org.omg.CORBA.ORB getORB()
+ {
+ if (orbDestroyed) throw new RuntimeException("Gateway has been closed. ORB is destroyed. ");
+
+ if (mORB == null) {
+ mC2KProps.put("com.sun.CORBA.codeset.charsets", "0x05010001, 0x00010109"); // need to force UTF-8 in the Sun ORB
+ mC2KProps.put("com.sun.CORBA.codeset.wcharsets", "0x00010109, 0x05010001");
+ mORB = org.omg.CORBA.ORB.init(new String[0], mC2KProps);
+ }
+ return mORB;
+ }
+
+ static public Lookup getLookup()
+ {
+ return mLookup;
+ }
+
+ static public LookupManager getLookupManager() throws CannotManageException
+ {
+ if (mLookupManager == null)
+ throw new CannotManageException("No Lookup Manager created. Not a server process.");
+ else
+ return mLookupManager;
+ }
+
+ static public CorbaServer getCorbaServer()
+ {
+ return mCorbaServer;
+ }
+
+ static public TransactionManager getStorage()
+ {
+ return mStorage;
+ }
+
+ static public CastorXMLUtility getMarshaller()
+ {
+ return mMarshaller;
+ }
+
+ static public ResourceLoader getResource()
+ {
+ return mResource;
+ }
+
+ static public ProxyManager getProxyManager()
+ {
+ return mProxyManager;
+ }
+
+
+ public static ProxyServer getProxyServer() {
+ return mProxyServer;
+ }
+
+ static public String getCentreId() {
+ return getProperties().getString("LocalCentre");
+ }
+
+ static public Enumeration<?> propertyNames() {
+ return mC2KProps.propertyNames();
+ }
+
+ static public void dumpC2KProps(int logLevel) {
+ if (!Logger.doLog(logLevel)) return;
+ mC2KProps.dumpProps(logLevel);
+ }
+
+ static public ObjectProperties getProperties() {
+ return mC2KProps;
+ }
+
+ static public String getKernelVersion() {
+ try {
+ return mResource.getTextResource(null, "textFiles/version.txt");
+ } catch (Exception ex) {
+ return "No version info found";
+ }
+
+ }
+}
+
diff --git a/src/main/java/org/cristalise/kernel/process/ShutdownHandler.java b/src/main/java/org/cristalise/kernel/process/ShutdownHandler.java new file mode 100644 index 0000000..f34800d --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/ShutdownHandler.java @@ -0,0 +1,26 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process;
+
+public interface ShutdownHandler {
+
+ public void shutdown(int errCode, boolean isServer);
+}
diff --git a/src/main/java/org/cristalise/kernel/process/StandardClient.java b/src/main/java/org/cristalise/kernel/process/StandardClient.java new file mode 100644 index 0000000..c97fed0 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/StandardClient.java @@ -0,0 +1,31 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process;
+
+
+abstract public class StandardClient extends AbstractMain
+{
+
+ static public void main(String[] args) throws Exception {
+ Gateway.init(readC2KArgs(args));
+ //AgentProxy user = Gateway.connect("username", "password");
+ }
+}
diff --git a/src/main/java/org/cristalise/kernel/process/StandardServer.java b/src/main/java/org/cristalise/kernel/process/StandardServer.java new file mode 100644 index 0000000..9d31b8e --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/StandardServer.java @@ -0,0 +1,67 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process;
+
+import org.cristalise.kernel.process.auth.Authenticator;
+import org.cristalise.kernel.utils.Logger;
+
+/**************************************************************************
+ * Base class for all servers i.e. c2k processes that serve Entities
+ *
+ * @author $Author: abranson $ $Date: 2005/04/28 13:49:43 $
+ * @version $Revision: 1.47 $
+ **************************************************************************/
+public class StandardServer extends AbstractMain
+{
+ protected static StandardServer server;
+
+ /**************************************************************************
+ * void StandardInitalisation( String[] )
+ *
+ * Set-up calls to ORB, POA and Factorys, both optional and required.
+ **************************************************************************/
+ protected static void standardInitialisation( String[] args )
+ throws Exception
+ {
+ isServer = true;
+
+ // read args and init Gateway
+ Gateway.init(readC2KArgs(args));
+
+ // connect to LDAP as root
+ Authenticator auth = Gateway.connect();
+
+ //start console
+ Logger.initConsole("ItemServer");
+
+ //initialize the server objects
+ Gateway.startServer(auth);
+
+ Logger.msg(5, "StandardServer::standardInitialisation - complete.");
+
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ //initialise everything
+ standardInitialisation( args );
+ }
+}
diff --git a/src/main/java/org/cristalise/kernel/process/UserCodeProcess.java b/src/main/java/org/cristalise/kernel/process/UserCodeProcess.java new file mode 100644 index 0000000..ff63baf --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/UserCodeProcess.java @@ -0,0 +1,276 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.cristalise.kernel.common.InvalidTransitionException;
+import org.cristalise.kernel.entity.C2KLocalObject;
+import org.cristalise.kernel.entity.agent.Job;
+import org.cristalise.kernel.entity.proxy.AgentProxy;
+import org.cristalise.kernel.entity.proxy.MemberSubscription;
+import org.cristalise.kernel.entity.proxy.ProxyObserver;
+import org.cristalise.kernel.persistency.ClusterStorage;
+import org.cristalise.kernel.scripting.ErrorInfo;
+import org.cristalise.kernel.scripting.ScriptErrorException;
+import org.cristalise.kernel.utils.Logger;
+
+
+/**************************************************************************
+ *
+ * $Revision: 1.31 $
+ * $Date: 2004/10/21 08:02:19 $
+ *
+ * Copyright (C) 2003 CERN - European Organization for Nuclear Research
+ * All rights reserved.
+ **************************************************************************/
+public class UserCodeProcess extends StandardClient implements ProxyObserver<Job>, Runnable {
+
+ // Default state machine transitions
+ private static final int START = 1;
+ private static final int COMPLETE = 2;
+ private static final int SUSPEND = 3;
+ private static final int RESUME = 4;
+
+ protected AgentProxy agent;
+ static boolean active = true;
+ ArrayList<String> ignoredPaths = new ArrayList<String>();
+ HashMap<String, ErrorInfo> errors = new HashMap<String, ErrorInfo>();
+ final HashMap<String, C2KLocalObject> jobs = new HashMap<String, C2KLocalObject>();
+
+ public UserCodeProcess(String agentName, String agentPass, String resource) {
+ // login - try for a while in case server hasn't imported our user yet
+ for (int i=1;i<6;i++) {
+ try {
+ Logger.msg("Login attempt "+i+" of 5");
+ agent = Gateway.connect(agentName, agentPass, resource);
+ break;
+ } catch (Exception ex) {
+ Logger.error("Could not log in.");
+ Logger.error(ex);
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException ex2) { }
+ }
+ }
+ System.out.println(getDesc()+" initialised for " + agentName);
+ }
+
+ @Override
+ public void run() {
+ Thread.currentThread().setName("Usercode Process");
+ // subscribe to job list
+ agent.subscribe(new MemberSubscription<Job>(this, ClusterStorage.JOB, true));
+ while (active) {
+ Job thisJob = null;
+ synchronized (jobs) {
+ if (jobs.size() > 0) {
+ thisJob = getJob(jobs, COMPLETE);
+ if (thisJob == null)
+ thisJob = getJob(jobs, START);
+ if (thisJob == null)
+ thisJob = getJob(jobs, SUSPEND);
+ if (thisJob == null)
+ thisJob = getJob(jobs, RESUME);
+
+ if (thisJob == null) {
+ Logger.error("No supported jobs, but joblist is not empty! Discarding remaining jobs");
+ jobs.clear();
+ }
+ else
+ jobs.remove(ClusterStorage.getPath(thisJob));
+ }
+ }
+
+ if (thisJob != null) {
+ String jobKey = thisJob.getItemPath()+":"+thisJob.getStepPath();
+ int transitionId = thisJob.getTransition().getId();
+ try {
+ if (transitionId==START) {
+ Logger.msg(5, "Testing start conditions");
+ boolean start = assessStartConditions(thisJob);
+ if (start) {
+ Logger.msg(5, "Attempting to start");
+ agent.execute(thisJob);
+ }
+ else {
+ Logger.msg(5, "Start conditions failed "+thisJob.getStepName()+" in "+thisJob.getItemPath());
+ }
+ }
+ else if (transitionId==COMPLETE) {
+ Logger.msg(5, "Executing logic");
+ runUCLogic(thisJob);
+ if (ignoredPaths.contains(jobKey))
+ ignoredPaths.remove(jobKey);
+ }
+ else if (transitionId==SUSPEND) {
+ if (ignoredPaths.contains(jobKey)) {
+ if (errors.containsKey(jobKey)) {
+ thisJob.setOutcome(Gateway.getMarshaller().marshall(errors.get(jobKey)));
+ errors.remove(jobKey);
+ }
+ agent.execute(thisJob);
+ }
+ }
+ else if (transitionId==RESUME) {
+ if (!ignoredPaths.contains(jobKey))
+ agent.execute(thisJob);
+ }
+ } catch (ScriptErrorException ex) {
+ errors.put(jobKey, ex.getErrors());
+ ignoredPaths.add(jobKey);
+ } catch (InvalidTransitionException ex) {
+ // must have already been done by someone else - ignore
+ } catch (Throwable ex) {
+ Logger.error("Error executing "+thisJob.getTransition().getName()+" job:");
+ Logger.error(ex);
+ ErrorInfo ei = new ErrorInfo();
+ ei.setFatal();
+ ei.addError(ex.getClass().getSimpleName());
+ ei.addError(ex.getMessage());
+ errors.put(jobKey, ei);
+ ignoredPaths.add(jobKey);
+ }
+ }
+ try {
+ synchronized (jobs) {
+ if (jobs.size() == 0) {
+ Logger.msg("Sleeping");
+ while (active && jobs.size() == 0)
+ jobs.wait(2000);
+ }
+ }
+ } catch (InterruptedException ex) { }
+ }
+
+ // shut down
+ try
+ {
+ Gateway.close();
+ }
+ catch( Exception ex )
+ {
+ Logger.error(ex);
+ }
+ }
+
+ private static Job getJob(HashMap<String, C2KLocalObject> jobs, int transition) {
+ for (C2KLocalObject c2kLocalObject : jobs.values()) {
+ Job thisJob = (Job)c2kLocalObject;
+ if (thisJob.getTransition().getId() == transition) {
+ Logger.msg(1,"=================================================================");
+ Logger.msg(1, "Got "+thisJob.getTransition().getName()+" job for "+thisJob.getStepName()+" in "+thisJob.getItemPath());
+ return thisJob;
+ }
+ }
+ return null;
+ }
+
+ public boolean assessStartConditions(Job job) {
+ // default implementation - has no start conditions.
+ return true;
+ }
+
+ public void runUCLogic(Job job) throws Exception {
+ // default implementation - the agent will execute any scripts defined when we execute
+ agent.execute(job);
+ }
+
+
+ /**
+ * Receives job from the AgentProxy. Reactivates thread if sleeping.
+ */
+ @Override
+ public void add(Job contents) {
+ synchronized(jobs) {
+ Logger.msg(7, "Adding "+ClusterStorage.getPath(contents));
+ jobs.put(ClusterStorage.getPath(contents), contents);
+ jobs.notify();
+ }
+
+ }
+
+ @Override
+ public void control(String control, String msg) {
+ if (MemberSubscription.ERROR.equals(control))
+ Logger.error("Error in job subscription: "+msg);
+ }
+
+ /**
+ * Removes job removal notification from the AgentProxy.
+ */
+ @Override
+ public void remove(String id) {
+ synchronized(jobs) {
+ Logger.msg(7, "Deleting "+id);
+ jobs.remove(id);
+ }
+ }
+
+ public static UserCodeProcess getInstance() throws UnknownHostException {
+ return new UserCodeProcess(InetAddress.getLocalHost().getHostName(), "uc", Gateway.getProperties().getString("AuthResource", "Cristal"));
+ }
+
+ static public void main(String[] args)
+ {
+ int status = 0;
+
+ try
+ {
+ Gateway.init(readC2KArgs(args));
+ UserCodeProcess proc = getInstance();
+ new Thread(proc).start();
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ shutdown();
+ }
+ }));
+ }
+ catch( Exception ex )
+ {
+ Logger.error(ex);
+
+ try
+ {
+ Gateway.close();
+ }
+ catch(Exception ex1)
+ {
+ Logger.error(ex1);
+ }
+ status = 1;
+ System.exit(status);
+ }
+ }
+
+ public String getDesc() {
+ return("Usercode Process");
+ }
+
+ public static void shutdown() {
+ active = false;
+ }
+
+}
diff --git a/src/main/java/org/cristalise/kernel/process/auth/Authenticator.java b/src/main/java/org/cristalise/kernel/process/auth/Authenticator.java new file mode 100644 index 0000000..2d92d4d --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/auth/Authenticator.java @@ -0,0 +1,93 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.auth;
+
+import org.cristalise.kernel.common.InvalidDataException;
+import org.cristalise.kernel.common.ObjectNotFoundException;
+
+/**
+ * This interface is used by the kernel to store an authenticated connection
+ * and/or token that will be used by kernel components. The CRISTAL property
+ * 'Authenticator' is used to specify the implementation used. It is
+ * instantiated by the connect() methods of the Gateway, and will be found in
+ * the AgentProxy returned by connect(). Lookup and ClusterStorage instances are
+ * initialized with this Authenticator, which is expected to maintain the same
+ * user's connection through the process lifetime, reconnecting if the
+ * connection is lost.
+ *
+ * @since 3.0
+ *
+ */
+public interface Authenticator {
+
+ /**
+ * Authenticates a CRISTAL agent. If this method returns true, then the
+ * connect method will create and return an AgentProxy for the given
+ * username using the Lookup and ProxyManager.
+ *
+ * @param agentName
+ * The username of the Agent to be authenticated. This must be
+ * already present as an Agent in the CRISTAL directory.
+ * @param password
+ * The Agent's password
+ * @param resource
+ * The authentication resource/domain/realm of the agent.
+ * Included so that domains may include CRISTAL users from
+ * different realms. This parameter is passed into the connect()
+ * method if required. May be null.
+ * @return a boolean indicating if the authentication was successful. If so,
+ * then the Gateway will generate an AgentProxy for the given user.
+ * @throws ObjectNotFoundException
+ * When the Agent doesn't exist
+ * @throws InvalidDataException
+ * When authentication fails for another reason
+ */
+ public boolean authenticate(String agentName, String password,
+ String resource) throws InvalidDataException,
+ ObjectNotFoundException;
+
+ /**
+ * Authenticates a superuser connection for the server. It must be able to
+ * act on behalf of any other Agent, as the server needs to do this.
+ * Credentials may be in the CRISTAL properties, or some other mechanism.
+ *
+ * @param resource
+ * @return
+ * @throws InvalidDataException
+ * @throws ObjectNotFoundException
+ */
+ public boolean authenticate(String resource) throws InvalidDataException,
+ ObjectNotFoundException;
+
+ /**
+ * Lookup and storage implementations that need to use user or superuser
+ * authentication can retrieve it using this method. This will be highly
+ * implementation specific.
+ *
+ * @return the connection/token created during authentication
+ */
+ public Object getAuthObject();
+
+ /**
+ * Close or expire the connection as the CRISTAL process shuts down.
+ */
+ public void disconnect();
+}
diff --git a/src/main/java/org/cristalise/kernel/process/auth/ConsoleAuth.java b/src/main/java/org/cristalise/kernel/process/auth/ConsoleAuth.java new file mode 100644 index 0000000..319c792 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/auth/ConsoleAuth.java @@ -0,0 +1,65 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.auth;
+
+import java.util.Properties;
+import java.util.Scanner;
+
+import org.cristalise.kernel.entity.proxy.AgentProxy;
+import org.cristalise.kernel.process.Gateway;
+
+
+public class ConsoleAuth implements ProxyLogin {
+
+ public ConsoleAuth() {
+ }
+
+ @Override
+ public void initialize(Properties props) throws Exception {
+
+ }
+ @Override
+ public AgentProxy authenticate(String resource) throws Exception {
+ AgentProxy user = null;
+ if (resource!=null) System.out.println("Please log in"+(resource.length()>0?"to "+resource:""));
+ Scanner scan = new Scanner(System.in);
+ int loginAttempts = 0;
+ while (user == null && loginAttempts++ < 3) {
+ System.out.print("User:");
+ String username = scan.nextLine();
+ System.out.print("Password:");
+ String pass = scan.nextLine();
+ try {
+ user = Gateway.connect(username, pass, resource);
+ } catch (Exception ex) {
+ System.err.println(ex.getMessage());
+ }
+ }
+
+ if (user == null) {
+ System.err.println("Bye");
+ System.exit(0);
+ }
+ return user;
+
+ }
+
+}
diff --git a/src/main/java/org/cristalise/kernel/process/auth/ProxyLogin.java b/src/main/java/org/cristalise/kernel/process/auth/ProxyLogin.java new file mode 100644 index 0000000..9305d50 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/auth/ProxyLogin.java @@ -0,0 +1,42 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.auth;
+
+import java.util.Properties;
+
+import org.cristalise.kernel.entity.proxy.AgentProxy;
+
+
+/**
+ * This interface is used by client processes to implement alternative login
+ * mechanisms aside from the standard username and password. Implementations may
+ * synchronize Agents with an external user library, such as Active Directory.
+ * Implementations are expected to set up the Gateway process and its
+ * authenticated components itself.
+ *
+ */
+public interface ProxyLogin {
+
+ public void initialize(Properties props) throws Exception;
+
+ public AgentProxy authenticate(String resource) throws Exception;
+
+}
diff --git a/src/main/java/org/cristalise/kernel/process/module/Module.java b/src/main/java/org/cristalise/kernel/process/module/Module.java new file mode 100644 index 0000000..840614b --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/module/Module.java @@ -0,0 +1,224 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.module;
+
+import java.util.ArrayList;
+import java.util.Properties;
+
+import org.cristalise.kernel.common.ObjectNotFoundException;
+import org.cristalise.kernel.entity.imports.ImportAgent;
+import org.cristalise.kernel.entity.imports.ImportDependency;
+import org.cristalise.kernel.entity.imports.ImportDependencyMember;
+import org.cristalise.kernel.entity.imports.ImportItem;
+import org.cristalise.kernel.entity.imports.ImportOutcome;
+import org.cristalise.kernel.entity.imports.ImportRole;
+import org.cristalise.kernel.entity.proxy.AgentProxy;
+import org.cristalise.kernel.entity.proxy.ItemProxy;
+import org.cristalise.kernel.lookup.DomainPath;
+import org.cristalise.kernel.lookup.RolePath;
+import org.cristalise.kernel.process.Gateway;
+import org.cristalise.kernel.property.Property;
+import org.cristalise.kernel.scripting.ErrorInfo;
+import org.cristalise.kernel.scripting.ScriptingEngineException;
+import org.cristalise.kernel.utils.Logger;
+
+
+public class Module extends ImportItem {
+
+ private ModuleInfo info;
+ private String resURL;
+ private ModuleImports imports = new ModuleImports();
+ private ArrayList<ModuleConfig> config = new ArrayList<ModuleConfig>();
+ private ArrayList<ModuleScript> scripts = new ArrayList<ModuleScript>();
+
+ public Module() {
+ super();
+ // Module properties
+ properties.add(new Property("Type", "Module", false));
+ setInitialPath("/desc/modules/");
+ setWorkflow("NoWorkflow");
+ setWorkflowVer(0);
+ imports.list.add(this);
+ }
+
+ public void runScript(String event, AgentProxy user, boolean isServer) throws ScriptingEngineException {
+ for (ModuleScript script : scripts) {
+ if (script.shouldRun(event, isServer)) {
+ Logger.msg("Running "+script.event+" "+script.target+" script from "+name);
+ Object result = script.getScript(ns, user).execute();
+ if (result instanceof ErrorInfo) {
+ ErrorInfo error = (ErrorInfo) result;
+ Logger.error(error.toString());
+ if (error.getFatal())
+ throw new ScriptingEngineException("Fatal Script Error");
+ }
+ else if (result != null)
+ Logger.msg(result.toString());
+ }
+ }
+ }
+
+ public void setModuleXML(String moduleXML) {
+ ImportOutcome moduleOutcome = new ImportOutcome("Module", 0, "last", null);
+ moduleOutcome.data = moduleXML;
+ outcomes.add(moduleOutcome);
+ }
+
+ @Override
+ public void setNamespace(String ns) {
+ super.setNamespace(ns);
+ replaceProp(new Property("Namespace", ns, false));
+ }
+
+ @Override
+ public void setName(String name) {
+ super.setName(name);
+ replaceProp(new Property("Name", name, false));
+ }
+
+ private void replaceProp(Property newProp) {
+ for (Property prop : properties) {
+ if (prop.getName().equals("Namespace")) {
+ prop.setMutable(newProp.isMutable());
+ prop.setValue(newProp.getValue());
+ return;
+ }
+ }
+ properties.add(newProp);
+ }
+ public void importAll(ItemProxy serverEntity, AgentProxy systemAgent, String moduleXML, boolean reset) throws Exception {
+ setModuleXML(moduleXML);
+
+ for (ModuleResource thisRes : imports.getResources()) {
+ try {
+ thisRes.setNamespace(ns);
+ thisRes.create(systemAgent.getPath(), reset);
+ } catch (Exception ex) {
+ Logger.error(ex);
+ Logger.die("Error importing module resources. Unsafe to continue.");
+ }
+ }
+
+ for (ImportRole thisRole : imports.getRoles()) {
+ RolePath rolePath;
+ try {
+ String roleName = thisRole.name;
+ if (roleName.indexOf('/') > -1) roleName = roleName.substring(roleName.indexOf('/')+1);
+ rolePath = Gateway.getLookup().getRolePath(roleName);
+ if (rolePath.hasJobList() != thisRole.hasJobList()) {
+ Logger.msg("Module.importAll() - Role '"+thisRole.name+"' has incorrect joblist settings. Correcting.");
+ rolePath.setHasJobList(thisRole.hasJobList());
+ Gateway.getLookupManager().createRole(rolePath);
+ }
+ } catch (ObjectNotFoundException ex) {
+ Logger.msg("Module.importAll() - Role '"+thisRole.name+"' not found. Creating.");
+ thisRole.create(systemAgent.getPath(), reset);
+ }
+ }
+
+ for (ImportAgent thisAgent : imports.getAgents()) {
+ try {
+ Gateway.getLookup().getAgentPath(thisAgent.name);
+ Logger.msg(3, "Module.importAll() - User '"+thisAgent.name+"' found.");
+ continue;
+ } catch (ObjectNotFoundException ex) { }
+ Logger.msg("Module.importAll() - User '"+thisAgent.name+"' not found. Creating.");
+ thisAgent.create(systemAgent.getPath(), reset);
+ }
+
+ for (ImportItem thisItem : imports.getItems()) {
+ thisItem.setNamespace(ns);
+ thisItem.create(systemAgent.getPath(), reset);
+ }
+
+ }
+
+ public Properties getProperties(boolean isServer) {
+ Properties props = new Properties();
+ for (ModuleConfig thisProp : config) {
+ if (thisProp.include(isServer))
+ props.put(thisProp.name, thisProp.value);
+ }
+ return props;
+ }
+
+ public ArrayList<ModuleScript> getScripts() {
+ return scripts;
+ }
+
+ public void setResURL(String resURL) {
+ this.resURL = resURL;
+ }
+ public String getDesc() {
+ return info.desc;
+ }
+ public String getVersion() {
+ return info.version;
+ }
+ public String getResURL() {
+ return resURL;
+ }
+ public ArrayList<String> getDependencies() {
+ return info.dependency;
+ }
+ public boolean hasDependency(String dep) {
+ return info.dependency.contains(dep);
+ }
+
+ public ModuleInfo getInfo() {
+ return info;
+ }
+
+ public void setInfo(ModuleInfo info) {
+ this.info = info;
+ replaceProp(new Property("Version", info.version, true));
+ }
+
+ public ModuleImports getImports() {
+ return imports;
+ }
+
+ public void setImports(ModuleImports imp) {
+ // Add dependency for all children
+ imports = imp;
+ ImportDependency children = new ImportDependency("Contents");
+ for (ModuleImport thisImport : imports.list) {
+ DomainPath path = thisImport.domainPath;
+ if (path != null)
+ children.dependencyMemberList.add(new ImportDependencyMember(path.toString()));
+ }
+ dependencyList.add(children);
+ }
+
+ public void setConfig(ArrayList<ModuleConfig> config) {
+ this.config = config;
+ }
+
+ public void setScripts(ArrayList<ModuleScript> scripts) {
+ this.scripts = scripts;
+ }
+
+ public ArrayList<ModuleConfig> getConfig() {
+ return config;
+ }
+
+
+} diff --git a/src/main/java/org/cristalise/kernel/process/module/ModuleConfig.java b/src/main/java/org/cristalise/kernel/process/module/ModuleConfig.java new file mode 100644 index 0000000..1165e31 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/module/ModuleConfig.java @@ -0,0 +1,42 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.module;
+
+public class ModuleConfig {
+
+ public String name;
+ public String value;
+ public String target;
+
+ public ModuleConfig() {
+ }
+
+ public ModuleConfig(String name, String value, String target) {
+ super();
+ this.name = name;
+ this.value = value;
+ this.target = target;
+ }
+
+ public boolean include(boolean isServer) {
+ return (target == null || target.length() == 0 || isServer == target.equals("server"));
+ }
+}
diff --git a/src/main/java/org/cristalise/kernel/process/module/ModuleException.java b/src/main/java/org/cristalise/kernel/process/module/ModuleException.java new file mode 100644 index 0000000..e09107e --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/module/ModuleException.java @@ -0,0 +1,29 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.module;
+
+public class ModuleException extends Exception {
+
+ public ModuleException(String msg) {
+ super(msg);
+ }
+
+}
diff --git a/src/main/java/org/cristalise/kernel/process/module/ModuleImport.java b/src/main/java/org/cristalise/kernel/process/module/ModuleImport.java new file mode 100644 index 0000000..22faa5a --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/module/ModuleImport.java @@ -0,0 +1,87 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.module;
+
+import org.cristalise.kernel.common.CannotManageException;
+import org.cristalise.kernel.common.InvalidCollectionModification;
+import org.cristalise.kernel.common.ObjectAlreadyExistsException;
+import org.cristalise.kernel.common.ObjectCannotBeUpdated;
+import org.cristalise.kernel.common.ObjectNotFoundException;
+import org.cristalise.kernel.lookup.AgentPath;
+import org.cristalise.kernel.lookup.DomainPath;
+import org.cristalise.kernel.lookup.InvalidItemPathException;
+import org.cristalise.kernel.lookup.ItemPath;
+
+
+public abstract class ModuleImport {
+
+ protected String ns;
+ protected String name;
+ protected DomainPath domainPath;
+ protected ItemPath itemPath;
+
+ public ModuleImport() {
+ }
+
+ public abstract void create(AgentPath agentPath, boolean reset) throws ObjectNotFoundException,
+ ObjectCannotBeUpdated, CannotManageException, ObjectAlreadyExistsException, InvalidCollectionModification;
+
+ public void setID( String uuid ) throws InvalidItemPathException
+ {
+ if (uuid != null && uuid.length() > 0) itemPath = new ItemPath(uuid);
+ }
+
+ public String getID() {
+ return itemPath==null?null:itemPath.getUUID().toString();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setNamespace(String ns) {
+ this.ns = ns;
+ }
+
+ public String getNamespace() {
+ return ns;
+ }
+
+ public DomainPath getDomainPath() {
+ return domainPath;
+ }
+
+ public void setDomainPath(DomainPath domainPath) {
+ this.domainPath = domainPath;
+ }
+
+ public ItemPath getItemPath() {
+ return itemPath;
+ }
+
+ public void setItemPath(ItemPath itemPath) {
+ this.itemPath = itemPath;
+ }
+}
\ No newline at end of file diff --git a/src/main/java/org/cristalise/kernel/process/module/ModuleImports.java b/src/main/java/org/cristalise/kernel/process/module/ModuleImports.java new file mode 100644 index 0000000..53c7e9d --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/module/ModuleImports.java @@ -0,0 +1,78 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.module;
+
+import java.util.ArrayList;
+
+import org.cristalise.kernel.entity.imports.ImportAgent;
+import org.cristalise.kernel.entity.imports.ImportItem;
+import org.cristalise.kernel.entity.imports.ImportRole;
+import org.cristalise.kernel.utils.CastorArrayList;
+
+
+public class ModuleImports extends CastorArrayList<ModuleImport> {
+
+ public ModuleImports()
+ {
+ super();
+ }
+
+ public ModuleImports(ArrayList<ModuleImport> aList)
+ {
+ super(aList);
+ }
+
+ public ArrayList<ModuleResource> getResources() {
+ ArrayList<ModuleResource> subset = new ArrayList<ModuleResource>();
+ for (ModuleImport imp : list) {
+ if (imp instanceof ModuleResource)
+ subset.add((ModuleResource)imp);
+ }
+ return subset;
+ }
+
+ public ArrayList<ImportItem> getItems() {
+ ArrayList<ImportItem> subset = new ArrayList<ImportItem>();
+ for (ModuleImport imp : list) {
+ if (imp instanceof ImportItem)
+ subset.add((ImportItem)imp);
+ }
+ return subset;
+ }
+
+ public ArrayList<ImportAgent> getAgents() {
+ ArrayList<ImportAgent> subset = new ArrayList<ImportAgent>();
+ for (ModuleImport imp : list) {
+ if (imp instanceof ImportAgent)
+ subset.add((ImportAgent)imp);
+ }
+ return subset;
+ }
+
+ public ArrayList<ImportRole> getRoles() {
+ ArrayList<ImportRole> subset = new ArrayList<ImportRole>();
+ for (ModuleImport imp : list) {
+ if (imp instanceof ImportRole)
+ subset.add((ImportRole)imp);
+ }
+ return subset;
+ }
+}
diff --git a/src/main/java/org/cristalise/kernel/process/module/ModuleInfo.java b/src/main/java/org/cristalise/kernel/process/module/ModuleInfo.java new file mode 100644 index 0000000..8f482fc --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/module/ModuleInfo.java @@ -0,0 +1,34 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.module;
+
+import java.util.ArrayList;
+
+public class ModuleInfo {
+
+ public String desc;
+ public String version;
+ public ArrayList<String> dependency = new ArrayList<String>();
+
+ public ModuleInfo() {
+ }
+
+}
diff --git a/src/main/java/org/cristalise/kernel/process/module/ModuleManager.java b/src/main/java/org/cristalise/kernel/process/module/ModuleManager.java new file mode 100644 index 0000000..d95abe6 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/module/ModuleManager.java @@ -0,0 +1,211 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.module;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.cristalise.kernel.common.InvalidDataException;
+import org.cristalise.kernel.common.ObjectNotFoundException;
+import org.cristalise.kernel.entity.proxy.AgentProxy;
+import org.cristalise.kernel.entity.proxy.ItemProxy;
+import org.cristalise.kernel.lookup.DomainPath;
+import org.cristalise.kernel.persistency.outcome.OutcomeValidator;
+import org.cristalise.kernel.persistency.outcome.Schema;
+import org.cristalise.kernel.process.Gateway;
+import org.cristalise.kernel.scripting.ScriptingEngineException;
+import org.cristalise.kernel.utils.FileStringUtility;
+import org.cristalise.kernel.utils.Logger;
+
+
+public class ModuleManager {
+ ArrayList<Module> modules = new ArrayList<Module>();
+ HashMap<String, String> modulesXML = new HashMap<String, String>();
+ Properties props = new Properties();
+ AgentProxy user;
+ boolean isServer;
+ OutcomeValidator moduleValidator;
+
+ public ModuleManager(Enumeration<URL> moduleEnum, boolean isServer) throws ModuleException {
+ this.isServer = isServer;
+ try {
+ Schema moduleSchema = new Schema("Module", 0,
+ FileStringUtility.url2String(Gateway.getResource().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<String> loadedModules = new ArrayList<String>();
+ ArrayList<String> moduleNs = new ArrayList<String>();
+ 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);
+ if (newModule.getResURL() != null && newModule.getResURL().length()>0) Gateway.getResource().addModuleBaseURL(newModule.getNamespace(), newModule.getResURL());
+ modules.add(newModule);
+ modulesXML.put(newModule.getNamespace(), moduleXML);
+ if (loadedModules.contains(newModule.getName())) throw new ModuleException("Module name clash: "+newModule.getName());
+ if (moduleNs.contains(newModule.getNamespace())) throw new ModuleException("Module namespace clash: "+newModule.getNamespace());
+ Logger.debug(4, "Module found: "+newModule.getNamespace()+" - "+newModule.getName());
+ loadedModules.add(newModule.getName()); moduleNs.add(newModule.getNamespace());
+ } 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");
+ boolean allDepsPresent = true;
+
+ ArrayList<String> prevModules = new ArrayList<String>();
+ for (int i=0; i<modules.size();i++) {
+ boolean depClean = false;
+ int skipped = 0;
+ Module thisMod = modules.get(i);
+ Logger.msg(5, "Checking dependencies of module "+thisMod.getName());
+ while (!depClean) {
+ ArrayList<String> deps = thisMod.getDependencies();
+ depClean = true;
+ for (String dep : deps) {
+ Logger.msg(6, thisMod.getName()+" depends on "+dep);
+ if (!loadedModules.contains(dep)) {
+ Logger.error("UNMET MODULE DEPENDENCY: "+thisMod.getName()+" requires "+dep);
+ allDepsPresent = false;
+ }
+ else if (!prevModules.contains(dep)) {
+ Logger.msg(1, "ModuleManager: Shuffling "+thisMod.getName()+" to the end to fulfil dependency on "+dep);
+ modules.remove(i);
+ modules.add(thisMod);
+ thisMod = modules.get(i);
+ skipped++;
+ depClean = false;
+ break;
+ }
+ }
+ if (skipped > modules.size()-i) {
+ StringBuffer badMod = new StringBuffer();
+ for (Module mod : modules.subList(i, modules.size())) {
+ badMod.append(mod.getName()).append(" ");
+ }
+ Logger.die("Circular module dependencies involving: "+badMod);
+ }
+ }
+ // Current module is 'next', this is the correct order to load the properties
+ Properties modProp = thisMod.getProperties(isServer);
+ for (Enumeration<?> e = modProp.propertyNames(); e.hasMoreElements();) {
+ String propName = (String)e.nextElement();
+ props.put(propName, modProp.get(propName));
+ }
+ prevModules.add(thisMod.getName());
+ }
+ if (!allDepsPresent) Logger.die("Unmet module dependencies. Cannot continue");
+ }
+
+ public void setUser(AgentProxy user) {
+ this.user = user;
+ }
+
+ 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, user, isServer);
+ } catch (ScriptingEngineException e) {
+ Logger.error(e);
+ Logger.die(e.getMessage());
+ }
+ }
+ }
+
+ public void registerModules() throws ModuleException {
+ ItemProxy serverEntity;
+ try {
+ serverEntity = Gateway.getProxyManager().getProxy(new DomainPath("/servers/"+Gateway.getProperties().getString("ItemServer.name")));
+ } catch (ObjectNotFoundException e) {
+ throw new ModuleException("Cannot find local server name.");
+ }
+ Logger.debug(3, "Registering modules");
+
+ boolean reset = Gateway.getProperties().getBoolean("Module.reset", false);
+
+ for (Module thisMod : modules) {
+
+ Logger.msg("Registering module "+thisMod.getName());
+ try {
+ String thisResetKey = "Module."+thisMod.getNamespace()+".reset";
+ boolean thisReset = reset;
+ if (Gateway.getProperties().containsKey(thisResetKey))
+ thisReset = Gateway.getProperties().getBoolean(thisResetKey);
+ thisMod.importAll(serverEntity, user, modulesXML.get(thisMod.getNamespace()), thisReset);
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new ModuleException("Error importing items for module "+thisMod.getName());
+ }
+ Logger.msg("Module "+thisMod.getName()+" registered");
+
+ try {
+ thisMod.runScript("startup", user, true);
+ } catch (ScriptingEngineException e) {
+ Logger.error(e);
+ throw new ModuleException("Error in startup script for module "+thisMod.getName());
+ }
+
+ }
+ }
+
+ public void dumpModules() {
+ for (Module thisMod : modules) {
+ try {
+ FileStringUtility.string2File(thisMod.getName()+".xml", Gateway.getMarshaller().marshall(thisMod));
+ } catch (Exception e) {
+ Logger.error(e);
+ }
+ }
+
+ }
+}
diff --git a/src/main/java/org/cristalise/kernel/process/module/ModuleResource.java b/src/main/java/org/cristalise/kernel/process/module/ModuleResource.java new file mode 100644 index 0000000..74b5673 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/module/ModuleResource.java @@ -0,0 +1,80 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.module;
+
+import org.cristalise.kernel.common.CannotManageException;
+import org.cristalise.kernel.common.ObjectAlreadyExistsException;
+import org.cristalise.kernel.common.ObjectCannotBeUpdated;
+import org.cristalise.kernel.common.ObjectNotFoundException;
+import org.cristalise.kernel.lookup.AgentPath;
+import org.cristalise.kernel.process.Bootstrap;
+import org.cristalise.kernel.utils.Logger;
+
+
+public class ModuleResource extends ModuleImport {
+
+ public int version;
+ public String resourceType;
+ public String resourceLocation;
+
+ public ModuleResource() {
+ // if not given, version defaults to 0
+ version = 0;
+ }
+
+ @Override
+ public void create(AgentPath agentPath, boolean reset)
+ throws ObjectNotFoundException, ObjectCannotBeUpdated,
+ CannotManageException, ObjectAlreadyExistsException {
+ try {
+ domainPath = Bootstrap.verifyResource(ns, name, version, resourceType, itemPath, resourceLocation, reset);
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new CannotManageException("Exception verifying module resource "+ns+"/"+name);
+ }
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ public String getResourceType() {
+ return resourceType;
+ }
+
+ public void setResourceType(String resourceType) {
+ this.resourceType = resourceType;
+ }
+
+ public String getResourceLocation() {
+ return resourceLocation;
+ }
+
+ public void setResourceLocation(String resourceLocation) {
+ this.resourceLocation = resourceLocation;
+ }
+
+
+}
\ No newline at end of file diff --git a/src/main/java/org/cristalise/kernel/process/module/ModuleScript.java b/src/main/java/org/cristalise/kernel/process/module/ModuleScript.java new file mode 100644 index 0000000..4e81864 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/module/ModuleScript.java @@ -0,0 +1,53 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.module;
+
+import org.cristalise.kernel.entity.proxy.AgentProxy;
+import org.cristalise.kernel.scripting.Script;
+import org.cristalise.kernel.scripting.ScriptingEngineException;
+
+public class ModuleScript {
+
+
+ public String target;
+ public String event;
+ public String lang;
+ public String script;
+ public ModuleScript() {
+ }
+
+ public ModuleScript(String target, String event, String lang, String script) {
+ super();
+ this.target = target;
+ this.event = event;
+ this.lang = lang;
+ this.script = script;
+ }
+
+ public Script getScript(String ns, AgentProxy user) throws ScriptingEngineException {
+ return new Script(lang, ns+" "+target+" "+event, script, user);
+ }
+
+ public boolean shouldRun(String event, boolean isServer) {
+ return ((this.target == null || this.target.length() == 0 || isServer == target.equals("server")) &&
+ (this.event == null || this.event.length() == 0 || event.equals(this.event)));
+ }
+}
diff --git a/src/main/java/org/cristalise/kernel/process/resource/BadArgumentsException.java b/src/main/java/org/cristalise/kernel/process/resource/BadArgumentsException.java new file mode 100644 index 0000000..d8d7dc9 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/resource/BadArgumentsException.java @@ -0,0 +1,37 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.resource;
+
+public class BadArgumentsException extends Exception {
+
+ public BadArgumentsException() {
+ super();
+ }
+
+ public BadArgumentsException(String message) {
+ super(message);
+ }
+
+ public BadArgumentsException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/src/main/java/org/cristalise/kernel/process/resource/DefaultResourceImportHandler.java b/src/main/java/org/cristalise/kernel/process/resource/DefaultResourceImportHandler.java new file mode 100644 index 0000000..dbd2d44 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/resource/DefaultResourceImportHandler.java @@ -0,0 +1,106 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.resource;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.cristalise.kernel.lookup.DomainPath;
+import org.cristalise.kernel.persistency.outcome.Outcome;
+import org.cristalise.kernel.process.Gateway;
+import org.cristalise.kernel.property.PropertyDescriptionList;
+
+
+public class DefaultResourceImportHandler implements ResourceImportHandler {
+
+ String schemaName;
+ String typeRoot;
+ DomainPath typeRootPath;
+ String wfDef;
+ PropertyDescriptionList props;
+
+ public DefaultResourceImportHandler(String resType) throws Exception {
+ if (resType.equals("CA")) {
+ wfDef = "ManageCompositeActDef";
+ schemaName = "CompositeActivityDef";
+ typeRoot = "/desc/ActivityDesc";
+ }
+ else if (resType.equals("EA")) {
+ wfDef = "ManageElementaryActDef";
+ schemaName = "ElementaryActivityDef";
+ typeRoot = "/desc/ActivityDesc";
+ }
+ else if (resType.equals("OD")) {
+ wfDef = "ManageSchema";
+ schemaName = "Schema";
+ typeRoot = "/desc/OutcomeDesc";
+ }
+ else if (resType.equals("SC")) {
+ wfDef = "ManageScript";
+ schemaName = "Script";
+ typeRoot = "/desc/Script";
+ }
+ else if (resType.equals("SM")) {
+ wfDef = "ManageStateMachine";
+ schemaName = "StateMachine";
+ typeRoot = "/desc/StateMachine";
+ }
+ else throw new Exception("Unknown bootstrap item type: "+resType);
+ typeRootPath = new DomainPath(typeRoot);
+ props = (PropertyDescriptionList)Gateway.getMarshaller().unmarshall(Gateway.getResource().getTextResource(null, "boot/property/"+resType+"Prop.xml"));
+ }
+
+ @Override
+ public DomainPath getTypeRoot() {
+ return typeRootPath;
+ }
+
+ @Override
+ public String getName() {
+ return schemaName;
+ }
+
+ @Override
+ public DomainPath getPath(String name, String ns) throws Exception {
+ return new DomainPath(typeRoot+"/system/"+(ns==null?"kernel":ns)+'/'+name);
+ }
+
+ @Override
+ public Set<Outcome> getResourceOutcomes(String name, String ns, String location, int version) throws Exception {
+ HashSet<Outcome> retArr = new HashSet<Outcome>();
+ String data = Gateway.getResource().getTextResource(ns, location);
+ if (data == null)
+ throw new Exception("No data found for "+schemaName+" "+name);
+ Outcome resOutcome = new Outcome(0, data, schemaName, 0);
+ retArr.add(resOutcome);
+ return retArr;
+ }
+
+ @Override
+ public PropertyDescriptionList getPropDesc() throws Exception {
+ return props;
+ }
+
+ @Override
+ public String getWorkflowName() throws Exception {
+ return wfDef;
+ }
+}
diff --git a/src/main/java/org/cristalise/kernel/process/resource/Resource.java b/src/main/java/org/cristalise/kernel/process/resource/Resource.java new file mode 100644 index 0000000..25b1ee8 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/resource/Resource.java @@ -0,0 +1,196 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.resource;
+
+//Java
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+import org.cristalise.kernel.common.InvalidDataException;
+import org.cristalise.kernel.common.ObjectNotFoundException;
+import org.cristalise.kernel.utils.FileStringUtility;
+import org.cristalise.kernel.utils.Logger;
+
+
+/**************************************************************************
+ *
+ * @author $Author: abranson $ $Date: 2005/10/05 07:39:36 $
+ * @version $Revision: 1.71 $
+ **************************************************************************/
+public class Resource implements ResourceLoader {
+
+ private final Hashtable<String, String> txtCache = new Hashtable<String, String>();
+ private final URL baseURL;
+ private final HashMap<String, URL> moduleBaseURLs = new HashMap<String, URL>();
+ private final HashMap<String, URL> allBaseURLs = new HashMap<String, URL>();
+
+ public Resource() throws InvalidDataException {
+ baseURL = getURLorResURL("org/cristalise/kernel/utils/resources/");
+ allBaseURLs.put(null, baseURL);
+ }
+
+ /* (non-Javadoc)
+ * @see org.cristalise.kernel.utils.ResourceLoader#getKernelBaseURL()
+ */
+ @Override
+ public URL getKernelBaseURL() {
+ return baseURL;
+ }
+
+ @Override
+ public ClassLoader getClassLoader(String className) {
+ return Resource.class.getClassLoader();
+ }
+
+ @Override
+ public Class<?> getClassForName(String name) throws ClassNotFoundException {
+ return Class.forName(name);
+ }
+
+ /* (non-Javadoc)
+ * @see org.cristalise.kernel.utils.ResourceLoader#getKernelResourceURL(java.lang.String)
+ */
+ @Override
+ public URL getKernelResourceURL(String resName) throws MalformedURLException {
+ return new URL(baseURL, resName);
+ }
+
+ /* (non-Javadoc)
+ * @see org.cristalise.kernel.utils.ResourceLoader#addModuleBaseURL(java.lang.String, java.net.URL)
+ */
+ @Override
+ public void addModuleBaseURL(String ns, URL newBaseURL) {
+ moduleBaseURLs.put(ns, newBaseURL);
+ allBaseURLs.put(ns, newBaseURL);
+ Logger.msg("Adding resource URL for "+ns+": "+newBaseURL.toString());
+ }
+
+ /* (non-Javadoc)
+ * @see org.cristalise.kernel.utils.ResourceLoader#addModuleBaseURL(java.lang.String, java.lang.String)
+ */
+ @Override
+ public void addModuleBaseURL(String ns, String newBaseURL) throws InvalidDataException {
+ addModuleBaseURL(ns, getURLorResURL(newBaseURL));
+ }
+
+ /* (non-Javadoc)
+ * @see org.cristalise.kernel.utils.ResourceLoader#getModuleBaseURLs()
+ */
+ @Override
+ public HashMap<String, URL> getModuleBaseURLs() {
+ return moduleBaseURLs;
+ }
+
+ private HashMap<String, URL> getAllBaseURLs() {
+ return allBaseURLs;
+ }
+
+ /* (non-Javadoc)
+ * @see org.cristalise.kernel.utils.ResourceLoader#getModuleResourceURL(java.lang.String, java.lang.String)
+ */
+ @Override
+ public URL getModuleResourceURL(String ns, String resName) throws MalformedURLException {
+ return new URL(moduleBaseURLs.get(ns), resName);
+ }
+
+ static private URL getURLorResURL(String newURL) throws InvalidDataException {
+ URL result;
+ try {
+ result = new URL(newURL);
+ } catch (java.net.MalformedURLException ex) {
+ //it is assumed that a 'wrong' URL denotes a directory
+ //of files resolvable from the CLASSPATH
+ result = Resource.class.getClassLoader().getResource(newURL);
+ }
+ if (result == null) {
+ Logger.error("URL "+newURL+" could not be found");
+ throw new InvalidDataException();
+ }
+ return result;
+ }
+ /* (non-Javadoc)
+ * @see org.cristalise.kernel.utils.ResourceLoader#findTextResource(java.lang.String)
+ */
+
+ @Override
+ public String findTextResource(String resName) {
+ for (String ns : getAllBaseURLs().keySet()) {
+ try {
+ return getTextResource(ns, resName);
+ } catch (ObjectNotFoundException ex) { }
+ }
+ Logger.warning("Text resource '"+resName+"' not found.");
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.cristalise.kernel.utils.ResourceLoader#getAllTextResources(java.lang.String)
+ */
+ @Override
+ public HashMap<String, String> getAllTextResources(String resName) {
+ HashMap<String, String> results = new HashMap<String, String>();
+ for (String ns : getAllBaseURLs().keySet()) {
+ try {
+ results.put(ns, getTextResource(ns, resName));
+ } catch (ObjectNotFoundException ex) { }
+ }
+ return results;
+ }
+
+ /* (non-Javadoc)
+ * @see org.cristalise.kernel.utils.ResourceLoader#getTextResource(java.lang.String, java.lang.String)
+ */
+ @Override
+ public String getTextResource(String ns, String resName) throws ObjectNotFoundException
+ // throws IOException
+ {
+ Logger.msg(8, "Resource::getTextResource() - Getting resource from "+ns+": " + resName);
+
+ if (txtCache.containsKey(ns+'/'+resName)) {
+ return txtCache.get(ns+'/'+resName);
+ }
+
+ try {
+
+ String newRes = null;
+ URL loc;
+
+ if (ns == null) // kernel
+ loc = getKernelResourceURL(resName);
+ else
+ loc = getModuleResourceURL(ns, resName);
+ Logger.msg(5, "Loading resource: "+loc.toString());
+ newRes = FileStringUtility.url2String(loc);
+ txtCache.put(ns+'/'+resName, newRes);
+ return newRes;
+ } catch (Exception e) {
+ throw new ObjectNotFoundException(e.getMessage());
+ }
+ }
+
+ @Override
+ public Enumeration<URL> getModuleDefURLs() throws Exception {
+ return ClassLoader.getSystemResources("META-INF/cristal/module.xml");
+ }
+}
diff --git a/src/main/java/org/cristalise/kernel/process/resource/ResourceImportHandler.java b/src/main/java/org/cristalise/kernel/process/resource/ResourceImportHandler.java new file mode 100644 index 0000000..9d37e31 --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/resource/ResourceImportHandler.java @@ -0,0 +1,68 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.resource;
+
+import java.util.Set;
+
+import org.cristalise.kernel.lookup.DomainPath;
+import org.cristalise.kernel.persistency.outcome.Outcome;
+import org.cristalise.kernel.property.PropertyDescriptionList;
+
+
+public interface ResourceImportHandler {
+
+
+ /** Returns the DomainPath for a specific resource
+ * @param ns - module namespace
+ * @param name - resource name
+ * @return
+ */
+ public DomainPath getPath(String name, String ns) throws Exception;
+
+ /** Generates the outcomes that the resource should contain.
+ * @param res - the module resource definition
+ * @return a set of outcomes to be synced with the resource item.
+ * @throws Exception - if the supplied resources are not valid
+ */
+ public Set<Outcome> getResourceOutcomes(String name, String ns, String location, int version) throws Exception;
+
+ /** Gives the CompActDef name to instantiate to provide the workflow for this type of resource.
+ * Should be found in the CA typeroot (/desc/ActivityDesc/)
+ * @return String workflow name
+ * @throws Exception
+ */
+ public String getWorkflowName() throws Exception;
+
+ /** Should return all of the Properties the resource Item
+ * will have on creation. The Property 'Name' will be created and populated automatically, even if not declared.
+ * @return a PropertyDescriptionList - an arraylist of PropertyDescriptions
+ * @throws Exception
+ */
+ public PropertyDescriptionList getPropDesc() throws Exception;
+
+ /** The directory context to search for existing resources. The name of the resource must be unique below this point.
+ * @return Root path
+ */
+ public DomainPath getTypeRoot();
+
+ public String getName();
+
+}
diff --git a/src/main/java/org/cristalise/kernel/process/resource/ResourceLoader.java b/src/main/java/org/cristalise/kernel/process/resource/ResourceLoader.java new file mode 100644 index 0000000..4ef0e9d --- /dev/null +++ b/src/main/java/org/cristalise/kernel/process/resource/ResourceLoader.java @@ -0,0 +1,67 @@ +/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.process.resource;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+
+import org.cristalise.kernel.common.InvalidDataException;
+import org.cristalise.kernel.common.ObjectNotFoundException;
+
+
+public interface ResourceLoader {
+
+ public URL getKernelBaseURL();
+
+ public URL getKernelResourceURL(String resName)
+ throws MalformedURLException;
+
+ public void addModuleBaseURL(String ns, URL newBaseURL);
+
+ public void addModuleBaseURL(String ns, String newBaseURL)
+ throws InvalidDataException;
+
+ public HashMap<String, URL> getModuleBaseURLs();
+
+ public URL getModuleResourceURL(String ns, String resName)
+ throws MalformedURLException;
+
+ /**************************************************************************
+ * Gets any text resource files
+ **************************************************************************/
+
+ public String findTextResource(String resName);
+
+ public HashMap<String, String> getAllTextResources(String resName);
+
+ public String getTextResource(String ns, String resName)
+ throws ObjectNotFoundException;
+
+ public Class<?> getClassForName(String name)
+ throws ClassNotFoundException;
+
+ public ClassLoader getClassLoader(String className);
+
+ public Enumeration<URL> getModuleDefURLs() throws Exception;
+
+}
\ No newline at end of file |
