From: Mathieu Baudier Date: Thu, 14 Mar 2013 12:59:41 +0000 (+0000) Subject: Help working X-Git-Tag: argeo-slc-2.1.7~409 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=6de9c4036be9e318f59a0ffa187570f5999c53cb;p=gpl%2Fargeo-slc.git Help working git-svn-id: https://svn.argeo.org/slc/trunk@6131 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/demo/slc_demo_cli.properties b/demo/slc_demo_cli.properties new file mode 100644 index 000000000..816be5f46 --- /dev/null +++ b/demo/slc_demo_cli.properties @@ -0,0 +1,15 @@ +argeo.osgi.start=\ +org.springframework.osgi.extender,\ +org.argeo.node.repo.jackrabbit,\ +org.argeo.security.dao.os,\ +org.argeo.slc.node.jackrabbit,\ +org.argeo.slc.agent,\ +org.argeo.slc.agent.jcr,\ +org.argeo.slc.support.equinox,\ +org.argeo.slc.support.maven,\ + +slc.executionModules=org.argeo.slc.demo.ant,\ +org.argeo.slc.demo.basic,\ +org.argeo.slc.demo.minimal,\ + +log4j.configuration=file:../../log4j.properties diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/AbstractSpecAttribute.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/AbstractSpecAttribute.java index 0e1685ba4..109c0335e 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/AbstractSpecAttribute.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/AbstractSpecAttribute.java @@ -27,6 +27,8 @@ public abstract class AbstractSpecAttribute implements ExecutionSpecAttribute, private Boolean isConstant = false; private Boolean isHidden = false; + private String description; + /** Has to be set at instantiation */ public Boolean getIsImmutable() { return isImmutable; @@ -77,4 +79,12 @@ public abstract class AbstractSpecAttribute implements ExecutionSpecAttribute, this.isConstant = isFrozen; } + public void setDescription(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } + } diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultAgent.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultAgent.java index 41c66622d..aaa687fd7 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultAgent.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultAgent.java @@ -27,6 +27,7 @@ import java.util.Map; import java.util.UUID; import org.argeo.slc.BasicNameVersion; +import org.argeo.slc.NameVersion; import org.argeo.slc.SlcException; import org.argeo.slc.execution.ExecutionModuleDescriptor; import org.argeo.slc.execution.ExecutionModulesManager; @@ -40,7 +41,6 @@ public class DefaultAgent implements SlcAgent { private final static String UTF8 = "UTF-8"; private String agentUuid = null; - // private SlcAgentDescriptor agentDescriptor; private ExecutionModulesManager modulesManager; private ThreadGroup processesThreadGroup; @@ -55,38 +55,12 @@ public class DefaultAgent implements SlcAgent { /** Initialization */ public void init() { agentUuid = initAgentUuid(); - // agentDescriptor = new SlcAgentDescriptor(); - // agentDescriptor.setUuid(initAgentUuid()); - // try { - // agentDescriptor.setHost(InetAddress.getLocalHost().getHostName()); - // } catch (UnknownHostException e) { - // log.error("Cannot resolve localhost host name: " + e.getMessage()); - // agentDescriptor.setHost("localhost"); - // } processesThreadGroup = new ThreadGroup("SLC Processes of Agent #" + agentUuid); - // modulesManager.registerProcessNotifier(this, - // new HashMap()); - - // final String module = System - // .getProperty(ExecutionModulesManager.UNIQUE_LAUNCH_MODULE_PROPERTY); - // final String flow = System - // .getProperty(ExecutionModulesManager.UNIQUE_LAUNCH_FLOW_PROPERTY); - // if (module != null) { - // // launch a flow and stops - // new Thread("Unique Flow") { - // @Override - // public void run() { - // executeFlowAndExit(module, null, flow); - // } - // }.start(); - // } } /** Clean up (needs to be called by overriding method) */ public void destroy() { - // modulesManager.unregisterProcessNotifier(this, - // new HashMap()); } /** @@ -97,13 +71,6 @@ public class DefaultAgent implements SlcAgent { return UUID.randomUUID().toString(); } - /* - * UNIQUE FLOW - */ - // protected void executeFlowAndExit(final String module, - // final String version, final String flow) { - // } - /* * SLC AGENT */ @@ -128,20 +95,15 @@ public class DefaultAgent implements SlcAgent { String[] path = uri.getPath().split("/"); if (path.length < 3) throw new SlcException("Badly formatted URI: " + uri); - String moduleName = path[1]; - // TODO process version - String moduleVersion = null; + NameVersion nameVersion = new BasicNameVersion(path[1]); StringBuilder flow = new StringBuilder(); for (int i = 2; i < path.length; i++) flow.append('/').append(path[i]); - Map values = new HashMap(); - if (uri.getQuery() != null) - values = getQueryMap(uri.getQuery()); - + Map values = getQueryMap(uri.getQuery()); // Get execution module descriptor ExecutionModuleDescriptor emd = getExecutionModuleDescriptor( - moduleName, moduleVersion); + nameVersion.getName(), nameVersion.getVersion()); process.getRealizedFlows().add( emd.asRealizedFlow(flow.toString(), values)); } @@ -186,7 +148,8 @@ public class DefaultAgent implements SlcAgent { // Get execution module descriptor ExecutionModuleDescriptor emd; try { - modulesManager.start(new BasicNameVersion(moduleName, moduleVersion)); + modulesManager + .start(new BasicNameVersion(moduleName, moduleVersion)); emd = modulesManager.getExecutionModuleDescriptor(moduleName, moduleVersion); } catch (SlcException e) { @@ -210,34 +173,25 @@ public class DefaultAgent implements SlcAgent { return true; } - /* - * PROCESS NOTIFIER - */ - // public void updateStatus(ExecutionProcess process, String oldStatus, - // String newStatus) { - // if (newStatus.equals(ExecutionProcess.COMPLETED) - // || newStatus.equals(ExecutionProcess.ERROR) - // || newStatus.equals(ExecutionProcess.KILLED)) { - // runningProcesses.remove(process.getUuid()); - // } - // } - // - // public void addSteps(ExecutionProcess process, List steps) - // { - // } - /* * UTILITIES */ - private static Map getQueryMap(String query) { - String[] params = query.split("&"); + /** + * @param query + * can be null + */ + static Map getQueryMap(String query) { Map map = new LinkedHashMap(); + if (query == null) + return map; + String[] params = query.split("&"); for (String param : params) { - String name = param.split("=")[0]; - String value = param.split("=")[1]; + String[] arr = param.split("="); + String name = arr[0]; + Object value = arr.length > 1 ? param.split("=")[1] : Boolean.TRUE; try { map.put(URLDecoder.decode(name, UTF8), - URLDecoder.decode(value, UTF8)); + URLDecoder.decode(value.toString(), UTF8)); } catch (UnsupportedEncodingException e) { throw new SlcException("Cannot decode '" + param + "'", e); } diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultAgentCli.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultAgentCli.java index c902ad3a3..b09aee755 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultAgentCli.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultAgentCli.java @@ -6,10 +6,13 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.security.OsAuthenticationToken; +import org.argeo.slc.BasicNameVersion; +import org.argeo.slc.NameVersion; import org.argeo.slc.SlcException; import org.argeo.slc.execution.ExecutionFlowDescriptor; import org.argeo.slc.execution.ExecutionModuleDescriptor; @@ -46,7 +49,7 @@ public class DefaultAgentCli implements SlcAgentCli { if (args.length > 0 && args[0].equals("help")) { StringBuilder buf = new StringBuilder(); help(args, buf); - log.info(buf); + log.info("\n" + buf); return buf.toString(); } else { List uris = asURIs(args); @@ -56,6 +59,80 @@ public class DefaultAgentCli implements SlcAgentCli { } } + protected void help(String[] rawArgs, StringBuilder buf) { + String[] args = Arrays.copyOfRange(rawArgs, 1, rawArgs.length); + if (args.length == 0) {// modules + for (ExecutionModuleDescriptor emd : agent + .listExecutionModuleDescriptors()) { + appendModule(emd, buf); + } + } else if (args.length == 1 && !args[0].contains("/")) {// single module + NameVersion nameVersion = new BasicNameVersion(args[0]); + ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor( + nameVersion.getName(), nameVersion.getVersion()); + appendModule(emd, buf); + + // flows + for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) { + buf.append(" ").append(efd.getName()); + if (efd.getDescription() != null + && !efd.getDescription().trim().equals("")) + buf.append(" : ").append(" ").append(efd.getDescription()); + buf.append('\n'); + } + return; + } else { + List uris = asURIs(args); + for (URI uri : uris) { + appendUriHelp(uri, buf); + } + } + } + + protected void appendUriHelp(URI uri, StringBuilder buf) { + String[] path = uri.getPath().split("/"); + NameVersion nameVersion = new BasicNameVersion(path[1]); + ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor( + nameVersion.getName(), nameVersion.getVersion()); + + StringBuilder flow = new StringBuilder(); + for (int i = 2; i < path.length; i++) + flow.append('/').append(path[i]); + String flowPath = flow.toString(); + ExecutionFlowDescriptor efd = findExecutionFlowDescriptor(emd, flowPath); + if (efd == null) + throw new SlcException("Flow " + uri + " not found"); + + appendModule(emd, buf); + + buf.append(" ").append(efd.getName()); + if (efd.getDescription() != null + && !efd.getDescription().trim().equals("")) + buf.append(" : ").append(" ").append(efd.getDescription()); + buf.append('\n'); + Map values = DefaultAgent.getQueryMap(uri.getQuery()); + ExecutionSpec spec = efd.getExecutionSpec(); + for (String attrKey : spec.getAttributes().keySet()) { + ExecutionSpecAttribute esa = spec.getAttributes().get(attrKey); + buf.append(" --").append(attrKey); + if (values.containsKey(attrKey)) + buf.append(" ").append(values.get(attrKey)); + if (esa.getValue() != null) + buf.append(" (").append(esa.getValue()).append(')'); + buf.append('\n'); + } + } + + private void appendModule(ExecutionModuleDescriptor emd, StringBuilder buf) { + buf.append("# ").append(emd.getName()); + if (emd.getDescription() != null + && !emd.getDescription().trim().equals("")) + buf.append(" : ").append(emd.getDescription()); + if (emd.getVersion() != null) + buf.append(" (v").append(emd.getVersion()).append(")"); + buf.append('\n'); + } + public static List asURIs(String[] args) { try { List uris = new ArrayList(); @@ -72,14 +149,17 @@ public class DefaultAgentCli implements SlcAgentCli { currUri.append(URLEncoder.encode(arg, UTF8)); currKey = null; } else { // module - if (currUri != null) + if (currUri != null) { uris.add(new URI(currUri.toString())); + } currUri = new StringBuilder("flow:"); String currModule = arg; currUri.append('/').append(currModule); if (!arg.contains("/")) { // flow path not in arg go to next arg + if (!argIt.hasNext()) + throw new SlcException("No flow found"); String currFlow = argIt.next(); if (!currFlow.startsWith("/")) currFlow = "/" + currFlow; @@ -90,6 +170,16 @@ public class DefaultAgentCli implements SlcAgentCli { if (currUri == null) {// first args leftOvers.add(arg); } else { + String key; + if (arg.startsWith("--")) + key = arg.substring(2); + else if (arg.startsWith("-")) + key = arg.substring(1); + else { + throw new SlcException("Cannot intepret key: " + + arg); + } + if (!hasArgs) { currUri.append('?'); hasArgs = true; @@ -103,14 +193,6 @@ public class DefaultAgentCli implements SlcAgentCli { currKey = null; } - String key; - if (arg.startsWith("--")) - key = arg.substring(2); - else if (arg.startsWith("-")) - key = arg.substring(1); - else - throw new SlcException("Cannot intepret key: " - + arg); currKey = key; currUri.append(URLEncoder.encode(key, UTF8)) .append('='); @@ -126,81 +208,22 @@ public class DefaultAgentCli implements SlcAgentCli { } } - protected void help(String[] rawArgs, StringBuilder buf) { - String[] args = Arrays.copyOfRange(rawArgs, 1, rawArgs.length); - List uris = asURIs(args); - uris: for (URI uri : uris) { - String[] path = uri.getPath().split("/"); - if (path.length < 2) { - for (ExecutionModuleDescriptor emd : agent - .listExecutionModuleDescriptors()) { - buf.append( - "# Execution Module " + emd.getName() + " v" - + emd.getVersion()).append('\n'); - if (emd.getDescription() != null - && !emd.getDescription().trim().equals("")) - buf.append(emd.getDescription()).append('\n'); - } - continue uris; - } - - String moduleName = path[1]; - // TODO process version - String moduleVersion = null; - - ExecutionModuleDescriptor emd = agent.getExecutionModuleDescriptor( - moduleName, moduleVersion); - - if (path.length >= 2) { - StringBuilder flow = new StringBuilder(); - for (int i = 2; i < path.length; i++) - flow.append('/').append(path[i]); - String flowPath = flow.toString(); - ExecutionFlowDescriptor flowDescriptor = null; - for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) { - if (efd.getName().equals(flowPath)) { - flowDescriptor = efd; - break; - } - } - if (flowDescriptor == null) - throw new SlcException("Flow " + uri + " not found"); - - buf.append( - "# Execution Module " + emd.getName() + " v" - + emd.getVersion()).append('\n'); - buf.append(" Flow ").append(flowDescriptor.getName()); - if (flowDescriptor.getDescription() != null - && !flowDescriptor.getDescription().trim().equals("")) - buf.append(" ").append(flowDescriptor.getDescription()); - buf.append('\n'); - ExecutionSpec spec = flowDescriptor.getExecutionSpec(); - for (String attrKey : spec.getAttributes().keySet()) { - ExecutionSpecAttribute esa = spec.getAttributes().get( - attrKey); - buf.append(" --").append(attrKey); - // TODO check values in query part - if (esa.getValue() != null) - buf.append(" ").append(esa.getValue()); - buf.append('\n'); - } - } else { - // module only - buf.append( - "# Execution Module " + emd.getName() + " v" - + emd.getVersion()).append('\n'); - if (emd.getDescription() != null - && !emd.getDescription().trim().equals("")) - buf.append(emd.getDescription()).append('\n'); - for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) { - buf.append(" ").append(efd.getName()); - if (efd.getDescription() != null - && !efd.getDescription().trim().equals("")) - buf.append(" ").append(efd.getDescription()); - } - buf.append('\n'); + private ExecutionFlowDescriptor findExecutionFlowDescriptor( + ExecutionModuleDescriptor emd, String flowPath) { + ExecutionFlowDescriptor flowDescriptor = null; + for (ExecutionFlowDescriptor efd : emd.getExecutionFlows()) { + String name = efd.getName(); + // normalize name as flow path + if (!name.startsWith("/")) + name = "/" + name; + if (name.endsWith("/")) + name = name.substring(0, name.length() - 1); + if (name.equals(flowPath)) { + flowDescriptor = efd; + break; } } + return flowDescriptor; } public void setAgent(SlcAgent agent) { diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java index 3c81ec192..cec087f9d 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/DefaultExecutionFlowDescriptorConverter.java @@ -24,8 +24,6 @@ import java.util.TreeSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.argeo.slc.SlcException; -import org.argeo.slc.UnsupportedException; import org.argeo.slc.execution.ExecutionFlow; import org.argeo.slc.execution.ExecutionFlowDescriptor; import org.argeo.slc.execution.ExecutionFlowDescriptorConverter; @@ -75,8 +73,8 @@ public class DefaultExecutionFlowDescriptorConverter implements .getAttributes().get(key); if (attribute == null) - throw new SlcException("No spec attribute defined for '" - + key + "'"); + throw new FlowConfigurationException( + "No spec attribute defined for '" + key + "'"); if (attribute.getIsConstant()) continue values; @@ -131,8 +129,9 @@ public class DefaultExecutionFlowDescriptorConverter implements Object obj = PrimitiveUtils.convert(type, ref); convertedValues.put(key, obj); } else { - throw new UnsupportedException("Ref value type", - refValue.getType()); + throw new FlowConfigurationException( + "Ref value type not supported: " + + refValue.getType()); } } else { // default is to take the value as is @@ -164,19 +163,20 @@ public class DefaultExecutionFlowDescriptorConverter implements md.getExecutionFlows().addAll(set); } - @SuppressWarnings("deprecation") public ExecutionFlowDescriptor getExecutionFlowDescriptor( ExecutionFlow executionFlow) { if (executionFlow.getName() == null) - throw new SlcException("Flow name is null: " + executionFlow); + throw new FlowConfigurationException("Flow name is null: " + + executionFlow); String name = executionFlow.getName(); ExecutionSpec executionSpec = executionFlow.getExecutionSpec(); if (executionSpec == null) - throw new SlcException("Execution spec is null: " + executionFlow); + throw new FlowConfigurationException("Execution spec is null: " + + executionFlow); if (executionSpec.getName() == null) - throw new SlcException("Execution spec name is null: " - + executionSpec); + throw new FlowConfigurationException( + "Execution spec name is null: " + executionSpec); Map values = new TreeMap(); for (String key : executionSpec.getAttributes().keySet()) { @@ -204,18 +204,18 @@ public class DefaultExecutionFlowDescriptorConverter implements buildRefValue((RefSpecAttribute) attribute, executionFlow, key)); } else { - throw new SlcException("Unkown spec attribute type " - + attribute.getClass()); + throw new FlowConfigurationException( + "Unkown spec attribute type " + attribute.getClass()); } } ExecutionFlowDescriptor efd = new ExecutionFlowDescriptor(name, null, values, executionSpec); - if (executionFlow.getPath() != null) - efd.setPath(executionFlow.getPath()); - else - efd.setPath(""); + // if (executionFlow.getPath() != null) + // efd.setPath(executionFlow.getPath()); + // else + // efd.setPath(""); // Takes description from spring BeanFactory bf = getBeanFactory(); diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ExecutionThread.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ExecutionThread.java index 6a1c97284..9289c7f56 100644 --- a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ExecutionThread.java +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/ExecutionThread.java @@ -31,12 +31,10 @@ import org.springframework.security.context.SecurityContextHolder; /** Thread of a single execution */ public class ExecutionThread extends Thread { public final static String SYSPROP_EXECUTION_AUTO_UPGRADE = "slc.execution.autoupgrade"; - private final static Log log = LogFactory.getLog(ExecutionThread.class); private ExecutionModulesManager executionModulesManager; private final RealizedFlow realizedFlow; - // private final ProcessThread processThread; private List destructionCallbacks = new ArrayList(); @@ -47,7 +45,6 @@ public class ExecutionThread extends Thread { + realizedFlow.getFlowDescriptor().getName()); this.realizedFlow = realizedFlow; this.executionModulesManager = executionModulesManager; - // this.processThread = processThread; } public void run() { @@ -73,11 +70,19 @@ public class ExecutionThread extends Thread { if (autoUpgrade != null && autoUpgrade.equals("true")) executionModulesManager.upgrade(realizedFlow .getModuleNameVersion()); - executionModulesManager.start(realizedFlow.getModuleNameVersion()); + // // START FLOW + // executionModulesManager.execute(realizedFlow); // END FLOW + } catch (FlowConfigurationException e) { + String msg = "Configuration problem with flow " + flowName + ":\n" + + e.getMessage(); + log.error(msg); + getProcessThreadGroup().dispatchAddStep( + new ExecutionStep(realizedFlow.getModuleName(), + ExecutionStep.ERROR, msg + " " + e.getMessage())); } catch (Exception e) { // TODO: re-throw exception ? String msg = "Execution of flow " + flowName + " failed."; @@ -85,9 +90,7 @@ public class ExecutionThread extends Thread { getProcessThreadGroup().dispatchAddStep( new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.ERROR, msg + " " + e.getMessage())); - // processThread.notifyError(); } finally { - // processThread.flowCompleted(); getProcessThreadGroup().dispatchAddStep( new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.PHASE_END, "Flow " + flowName)); @@ -95,10 +98,6 @@ public class ExecutionThread extends Thread { } } - // private void dispatchAddStep(ExecutionStep step) { - // getProcessThreadGroup().dispatchAddStep(step); - // } - private synchronized void processDestructionCallbacks() { for (int i = destructionCallbacks.size() - 1; i >= 0; i--) { try { @@ -120,11 +119,5 @@ public class ExecutionThread extends Thread { protected ProcessThreadGroup getProcessThreadGroup() { return (ProcessThreadGroup) getThreadGroup(); - // return processThread.getProcessThreadGroup(); } - - // public RealizedFlow getRealizedFlow() { - // return realizedFlow; - // } - -} +} \ No newline at end of file diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/FlowConfigurationException.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/FlowConfigurationException.java new file mode 100644 index 000000000..aeda5aca5 --- /dev/null +++ b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/FlowConfigurationException.java @@ -0,0 +1,12 @@ +package org.argeo.slc.core.execution; + +import org.argeo.slc.SlcException; + +/** The stack trace of such exceptions does not need to be displayed */ +public class FlowConfigurationException extends SlcException { + private static final long serialVersionUID = 8456260596346797321L; + + public FlowConfigurationException(String message) { + super(message); + } +} diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/BasicNameVersion.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/BasicNameVersion.java index 8d7a8e184..73f12fc4a 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/BasicNameVersion.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/BasicNameVersion.java @@ -17,7 +17,6 @@ package org.argeo.slc; import java.io.Serializable; - public class BasicNameVersion implements NameVersion, Comparable, Serializable { private static final long serialVersionUID = -5127304279136195127L; @@ -27,6 +26,18 @@ public class BasicNameVersion implements NameVersion, Comparable, public BasicNameVersion() { } + /** Interprets string in OSGi-like format my.module.name;version=0.0.0 */ + public BasicNameVersion(String nameVersion) { + int index = nameVersion.indexOf(";version="); + if (index < 0) { + name = nameVersion; + version = null; + } else { + name = nameVersion.substring(0, index); + version = nameVersion.substring(index + ";version=".length()); + } + } + public BasicNameVersion(String name, String version) { this.name = name; this.version = version; @@ -79,5 +90,4 @@ public class BasicNameVersion implements NameVersion, Comparable, else return name.compareTo(o.getName()); } - } diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionSpecAttribute.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionSpecAttribute.java index 8a7c1cb15..a430e5bb0 100644 --- a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionSpecAttribute.java +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/execution/ExecutionSpecAttribute.java @@ -56,6 +56,9 @@ public interface ExecutionSpecAttribute { */ public Object getValue(); + /** Description of this attribute, can be null */ + public String getDescription(); + /** @deprecated use {@link #getIsImmutable()} instead */ public Boolean getIsParameter();