You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by st...@apache.org on 2015/02/23 16:37:17 UTC
[17/49] incubator-taverna-server git commit: taverna-* module names
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/ProfileList.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/ProfileList.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/ProfileList.java
new file mode 100644
index 0000000..69c3622
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/ProfileList.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 The University of Manchester
+ *
+ * See the file "LICENSE.txt" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+
+/**
+ * Description of the profiles that can apply to a workflow.
+ *
+ * @author Donal K. Fellows
+ */
+@XmlRootElement(name = "profiles")
+@XmlType(name = "ProfileList")
+public class ProfileList {
+ public List<ProfileList.Info> profile = new ArrayList<ProfileList.Info>();
+
+ /**
+ * Description of a single workflow profile.
+ *
+ * @author Donal Fellows
+ */
+ @XmlRootElement(name = "profile")
+ @XmlType(name = "Profile")
+ public static class Info {
+ @XmlValue
+ public String name;
+ /**
+ * Whether this is the main profile.
+ */
+ @XmlAttribute(name = "isMain")
+ public Boolean main;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Roles.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Roles.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Roles.java
new file mode 100644
index 0000000..8079b1c
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Roles.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+/**
+ * The roles defined in this webapp.
+ *
+ * @author Donal Fellows
+ */
+public interface Roles {
+ /** The role of a normal user. */
+ static final String USER = "ROLE_tavernauser";
+ /**
+ * The role of an administrator. Administrators <i>should</i> have the
+ * normal user role as well.
+ */
+ static final String ADMIN = "ROLE_tavernasuperuser";
+ /**
+ * The role of a workflow accessing itself. Do not give users this role.
+ */
+ static final String SELF = "ROLE_tavernaworkflow";
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/RunReference.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/RunReference.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/RunReference.java
new file mode 100644
index 0000000..3486bf7
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/RunReference.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import static org.taverna.server.master.common.Namespaces.SERVER;
+import static org.taverna.server.master.common.Namespaces.XLINK;
+import static org.taverna.server.master.common.VersionedElement.VERSION;
+
+import java.net.URI;
+
+import javax.ws.rs.core.UriBuilder;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+
+/**
+ * A reference to a single workflow run, described using JAXB.
+ *
+ * @author Donal Fellows
+ * @see org.taverna.server.master.interfaces.TavernaRun TavernaRun
+ */
+@XmlRootElement
+@XmlType(name = "TavernaRun")
+@XmlSeeAlso( { Workflow.class, DirEntryReference.class })
+public class RunReference {
+ /**
+ * Where to get information about the run. For REST.
+ */
+ @XmlAttribute(name = "href", namespace = XLINK)
+ @XmlSchemaType(name = "anyURI")
+ public URI link;
+ /** What version of server produced this element? */
+ @XmlAttribute(namespace = SERVER)
+ public String serverVersion;
+ /**
+ * The name of the run. For SOAP.
+ */
+ @XmlValue
+ public String name;
+
+ /**
+ * Make a blank run reference.
+ */
+ public RunReference() {
+ }
+
+ /**
+ * Make a reference to the given workflow run.
+ *
+ * @param name
+ * The name of the run.
+ * @param ub
+ * A factory for URIs, or <tt>null</tt> if none is to be made.
+ */
+ public RunReference(String name, UriBuilder ub) {
+ this.serverVersion = VERSION;
+ this.name = name;
+ if (ub != null)
+ this.link = ub.build(name);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Status.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Status.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Status.java
new file mode 100644
index 0000000..8e360dc
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Status.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * States of a workflow run. They are {@link #Initialized Initialized},
+ * {@link #Operating Operating}, {@link #Stopped Stopped}, and {@link #Finished
+ * Finished}. Conceptually, there is also a <tt>Destroyed</tt> state, but the
+ * workflow run does not exist (and hence can't have its state queried or set)
+ * in that case.
+ *
+ * @author Donal Fellows
+ */
+@XmlEnum
+@XmlType(name = "Status")
+public enum Status {
+ /**
+ * The workflow run has been created, but is not yet running. The run will
+ * need to be manually moved to {@link #Operating Operating} when ready.
+ */
+ Initialized,
+ /**
+ * The workflow run is going, reading input, generating output, etc. Will
+ * eventually either move automatically to {@link #Finished Finished} or can
+ * be moved manually to {@link #Stopped Stopped} (where supported).
+ */
+ Operating,
+ /**
+ * The workflow run is paused, and will need to be moved back to
+ * {@link #Operating Operating} manually.
+ */
+ Stopped,
+ /**
+ * The workflow run has ceased; data files will continue to exist until the
+ * run is destroyed (which may be manual or automatic).
+ */
+ Finished
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Trust.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Trust.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Trust.java
new file mode 100644
index 0000000..6d77aa7
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Trust.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011-2012 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import static org.taverna.server.master.common.Namespaces.XLINK;
+
+import java.io.Serializable;
+import java.security.cert.Certificate;
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * A description of a trusted identity or identities. This description is
+ * characterised by a file visible to the workflow run that contains one or more
+ * certificates.
+ *
+ * @author Donal Fellows
+ */
+@XmlType(name = "TrustDescriptor")
+@XmlRootElement(name = "trustedIdentity")
+@SuppressWarnings("serial")
+public final class Trust implements Serializable {
+ /** The location of this descriptor in the REST world. */
+ @XmlAttribute(namespace = XLINK)
+ public String href;
+ /**
+ * The location of this descriptor in the SOAP world. Must match corrected
+ * with the {@link #href} field.
+ */
+ @XmlTransient
+ public String id;
+ /**
+ * The file containing the certificate(s). This is resolved with respect to
+ * the workflow run working directory.
+ */
+ @XmlElement
+ public String certificateFile;
+ /**
+ * The type of certificate file. Defaults to <tt>X.509</tt> if unspecified.
+ */
+ @XmlElement
+ public String fileType;
+ /**
+ * The encoded serialized keystore containing the certificate(s).
+ */
+ @XmlElement
+ public byte[] certificateBytes;
+ /**
+ * The names of the server(s) identified by this trust.
+ */
+ @XmlElement
+ public List<String> serverName;
+ /**
+ * The collection of certificates loaded from the specified file. This is
+ * always <tt>null</tt> before validation.
+ */
+ public transient Collection<? extends Certificate> loadedCertificates;
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof Trust))
+ return false;
+ return id.equals(((Trust) o).id);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Uri.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Uri.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Uri.java
new file mode 100644
index 0000000..d6d057c
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Uri.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2010-2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import static javax.ws.rs.core.UriBuilder.fromUri;
+import static org.apache.commons.logging.LogFactory.getLog;
+import static org.taverna.server.master.common.Namespaces.XLINK;
+
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.Map;
+
+import javax.annotation.PreDestroy;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriBuilderException;
+import javax.ws.rs.core.UriInfo;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.commons.logging.Log;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.web.PortMapper;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A class that makes it simpler to work with an element with a {@link URI} in
+ * an <tt>href</tt> attribute. Done with JAXB.
+ *
+ * @author Donal Fellows
+ */
+@XmlType(name = "Location")
+public class Uri {
+ static Log log = getLog("Taverna.Server.UriRewriter");
+ private static final String SECURE_SCHEME = "https";
+ /**
+ * This type is characterised by an attribute that is the reference to some
+ * other element.
+ */
+ @XmlAttribute(name = "href", namespace = XLINK)
+ @XmlSchemaType(name = "anyURI")
+ public URI ref;
+
+ /** Make a reference that points nowhere. */
+ public Uri() {
+ }
+
+ /**
+ * Make a reference to the given location.
+ *
+ * @param ref
+ * Where to point to.
+ */
+ public Uri(@Nonnull URI ref) {
+ this.ref = secure(ref);
+ }
+
+ /**
+ * Make a reference from the factory with the given parameters.
+ *
+ * @param ub
+ * The configured factory.
+ * @param strings
+ * The parameters to the factory.
+ */
+ public Uri(@Nonnull UriBuilder ub, String... strings) {
+ ref = secure(ub).build((Object[]) strings);
+ }
+
+ /**
+ * Make a reference from the factory with the given parameters.
+ *
+ * @param ui
+ * The factory factory.
+ * @param path
+ * The path to configure the factory with.
+ * @param strings
+ * The parameters to the factory.
+ */
+ public Uri(@Nonnull UriInfo ui, @Nonnull String path, String... strings) {
+ this(ui, true, path, strings);
+ }
+
+ /**
+ * Make a reference from the factory with the given parameters.
+ *
+ * @param ui
+ * The factory factory.
+ * @param secure
+ * Whether the URI should be required to use HTTPS.
+ * @param path
+ * The path to configure the factory with.
+ * @param strings
+ * The parameters to the factory.
+ */
+ public Uri(@Nonnull UriInfo ui, boolean secure, @Nonnull String path,
+ String... strings) {
+ UriBuilder ub = ui.getAbsolutePathBuilder();
+ if (secure) {
+ ub = secure(ub);
+ }
+ ref = ub.path(path).build((Object[]) strings);
+ }
+
+ public static UriBuilder secure(UriBuilder ub) {
+ return Rewriter.getInstance().getSecuredUriBuilder(ub);
+ }
+
+ public static UriBuilder secure(UriInfo ui) {
+ return secure(ui.getAbsolutePathBuilder());
+ }
+
+ public static URI secure(URI uri) {
+ URI newURI = secure(fromUri(uri)).build();
+ if (log.isDebugEnabled())
+ log.debug("rewrote " + uri + " to " + newURI);
+ return newURI;
+ }
+
+ public static URI secure(URI base, String uri) {
+ URI newURI = secure(fromUri(base.resolve(uri))).build();
+ if (log.isDebugEnabled())
+ log.debug("rewrote " + uri + " to " + newURI);
+ return newURI;
+ }
+
+ /**
+ * A bean that allows configuration of how to rewrite generated URIs to be
+ * secure.
+ *
+ * @author Donal Fellows
+ */
+ public static class Rewriter {
+ private static Rewriter instance;
+ private PortMapper portMapper;
+ private boolean suppress;
+ private String rewriteRE = "://[^/]+/[^/]+";
+ private String rewriteTarget;
+
+ static Rewriter getInstance() {
+ if (instance == null)
+ new Rewriter();
+ return instance;
+ }
+
+ @Autowired
+ public void setPortMapper(PortMapper portMapper) {
+ this.portMapper = portMapper;
+ }
+
+ /**
+ * Whether to suppress rewriting of URIs to be secure.
+ *
+ * @param suppressSecurity
+ * True if no rewriting should be done.
+ */
+ public void setSuppressSecurity(boolean suppressSecurity) {
+ suppress = suppressSecurity;
+ }
+
+ public void setRewriteRegexp(String rewriteRegexp) {
+ this.rewriteRE = rewriteRegexp;
+ }
+
+ /**
+ * What to rewrite the host, port and web-app name to be.
+ *
+ * @param rewriteTarget
+ * What to rewrite to, or "<tt>NONE</tt>" for no rewrite.
+ */
+ public void setRewriteTarget(String rewriteTarget) {
+ if (rewriteTarget.isEmpty())
+ this.rewriteTarget = null;
+ else if (rewriteTarget.equals("NONE"))
+ this.rewriteTarget = null;
+ else if (rewriteTarget.startsWith("${"))
+ this.rewriteTarget = null;
+ else
+ this.rewriteTarget = "://" + rewriteTarget;
+ }
+
+ private Integer lookupHttpsPort(URI uri) {
+ if (portMapper != null)
+ return portMapper.lookupHttpsPort(uri.getPort());
+ return null;
+ }
+
+ public Rewriter() {
+ instance = this;
+ }
+
+ @PreDestroy
+ public void done() {
+ instance = null;
+ Uri.log = null;
+ }
+
+ @Nonnull
+ URI rewrite(@Nonnull String url) {
+ if (rewriteTarget != null)
+ url = url.replaceFirst(rewriteRE, rewriteTarget);
+ return URI.create(url);
+ }
+
+ @Nonnull
+ public UriBuilder getSecuredUriBuilder(@Nonnull UriBuilder uribuilder) {
+ if (suppress)
+ return uribuilder.clone();
+ UriBuilder ub = new RewritingUriBuilder(uribuilder);
+ Integer secPort = null;
+ try {
+ secPort = lookupHttpsPort(ub.build());
+ } catch (Exception e) {
+ /*
+ * Do not log this; we know why it happens and don't actually
+ * care to do anything about it. All it does is fill up the log
+ * with pointless scariness!
+ */
+
+ // log.debug("failed to extract current URI port", e);
+ }
+ if (secPort == null || secPort.intValue() == -1)
+ return ub.scheme(SECURE_SCHEME);
+ return ub.scheme(SECURE_SCHEME).port(secPort);
+ }
+
+ /**
+ * {@link UriBuilder} that applies a rewrite rule to the URIs produced
+ * by the wrapped builder.
+ *
+ * @author Donal Fellows
+ */
+ class RewritingUriBuilder extends UriBuilder {
+ private UriBuilder wrapped;
+
+ RewritingUriBuilder(UriBuilder builder) {
+ wrapped = builder.clone();
+ }
+
+ private URI rewrite(URI uri) {
+ return Rewriter.this.rewrite(uri.toString());
+ }
+
+ @Override
+ public UriBuilder clone() {
+ return new RewritingUriBuilder(wrapped);
+ }
+
+ @Override
+ public URI buildFromMap(Map<String, ?> values)
+ throws IllegalArgumentException, UriBuilderException {
+ return rewrite(wrapped.buildFromMap(values));
+ }
+
+ @Override
+ public URI buildFromEncodedMap(Map<String, ? extends Object> values)
+ throws IllegalArgumentException, UriBuilderException {
+ return rewrite(wrapped.buildFromEncodedMap(values));
+ }
+
+ @Override
+ public URI build(Object... values) throws IllegalArgumentException,
+ UriBuilderException {
+ return rewrite(wrapped.build(values));
+ }
+
+ @Override
+ public URI build(Object[] values, boolean encodeSlashInPath)
+ throws IllegalArgumentException, UriBuilderException {
+ return rewrite(wrapped.build(values, encodeSlashInPath));
+ }
+
+ @Override
+ public URI buildFromEncoded(Object... values)
+ throws IllegalArgumentException, UriBuilderException {
+ return rewrite(wrapped.buildFromEncoded(values));
+ }
+
+ @Override
+ public URI buildFromMap(Map<String, ?> values,
+ boolean encodeSlashInPath) throws IllegalArgumentException,
+ UriBuilderException {
+ return rewrite(wrapped.buildFromEncoded(values,
+ encodeSlashInPath));
+ }
+
+ @Override
+ public UriBuilder uri(URI uri) throws IllegalArgumentException {
+ wrapped.uri(uri);
+ return this;
+ }
+
+ @Override
+ public UriBuilder uri(String uriTemplate)
+ throws IllegalArgumentException {
+ wrapped.uri(uriTemplate);
+ return this;
+ }
+
+ @Override
+ public String toTemplate() {
+ return wrapped.toTemplate();
+ }
+
+ @Override
+ public UriBuilder scheme(String scheme)
+ throws IllegalArgumentException {
+ wrapped.scheme(scheme);
+ return this;
+ }
+
+ @Override
+ public UriBuilder schemeSpecificPart(String ssp)
+ throws IllegalArgumentException {
+ wrapped.schemeSpecificPart(ssp);
+ return this;
+ }
+
+ @Override
+ public UriBuilder userInfo(String ui) {
+ wrapped.userInfo(ui);
+ return this;
+ }
+
+ @Override
+ public UriBuilder host(String host) throws IllegalArgumentException {
+ wrapped.host(host);
+ return this;
+ }
+
+ @Override
+ public UriBuilder port(int port) throws IllegalArgumentException {
+ wrapped.port(port);
+ return this;
+ }
+
+ @Override
+ public UriBuilder replacePath(String path) {
+ wrapped.replacePath(path);
+ return this;
+ }
+
+ @Override
+ public UriBuilder path(String path) throws IllegalArgumentException {
+ wrapped.path(path);
+ return this;
+ }
+
+ @Override
+ public UriBuilder path(
+ @java.lang.SuppressWarnings("rawtypes") Class resource)
+ throws IllegalArgumentException {
+ wrapped.path(resource);
+ return this;
+ }
+
+ @Override
+ public UriBuilder path(
+ @java.lang.SuppressWarnings("rawtypes") Class resource,
+ String method) throws IllegalArgumentException {
+ wrapped.path(resource, method);
+ return this;
+ }
+
+ @Override
+ public UriBuilder path(Method method)
+ throws IllegalArgumentException {
+ wrapped.path(method);
+ return this;
+ }
+
+ @Override
+ public UriBuilder segment(String... segments)
+ throws IllegalArgumentException {
+ wrapped.segment(segments);
+ return this;
+ }
+
+ @Override
+ public UriBuilder replaceMatrix(String matrix)
+ throws IllegalArgumentException {
+ wrapped.replaceMatrix(matrix);
+ return this;
+ }
+
+ @Override
+ public UriBuilder matrixParam(String name, Object... values)
+ throws IllegalArgumentException {
+ wrapped.matrixParam(name, values);
+ return this;
+ }
+
+ @Override
+ public UriBuilder replaceMatrixParam(String name, Object... values)
+ throws IllegalArgumentException {
+ wrapped.replaceMatrixParam(name, values);
+ return this;
+ }
+
+ @Override
+ public UriBuilder replaceQuery(String query)
+ throws IllegalArgumentException {
+ wrapped.replaceQuery(query);
+ return this;
+ }
+
+ @Override
+ public UriBuilder queryParam(String name, Object... values)
+ throws IllegalArgumentException {
+ wrapped.queryParam(name, values);
+ return this;
+ }
+
+ @Override
+ public UriBuilder replaceQueryParam(String name, Object... values)
+ throws IllegalArgumentException {
+ wrapped.replaceQueryParam(name, values);
+ return this;
+ }
+
+ @Override
+ public UriBuilder fragment(String fragment) {
+ wrapped.fragment(fragment);
+ return this;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/VersionedElement.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/VersionedElement.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/VersionedElement.java
new file mode 100644
index 0000000..6eddf2d
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/VersionedElement.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010-2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import static org.apache.commons.logging.LogFactory.getLog;
+import static org.taverna.server.master.common.Namespaces.SERVER;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.commons.logging.Log;
+
+/**
+ * The type of an element that declares the version of the server that produced
+ * it.
+ *
+ * @author Donal Fellows
+ */
+@XmlType(name = "VersionedElement", namespace = SERVER)
+public abstract class VersionedElement {
+ /** What version of server produced this element? */
+ @XmlAttribute(namespace = SERVER)
+ public String serverVersion;
+ /** What revision of server produced this element? Derived from SCM commit. */
+ @XmlAttribute(namespace = SERVER)
+ public String serverRevision;
+ /** When was the server built? */
+ @XmlAttribute(namespace = SERVER)
+ public String serverBuildTimestamp;
+ public static final String VERSION, REVISION, TIMESTAMP;
+ static {
+ Log log = getLog("Taverna.Server.Webapp");
+ Properties p = new Properties();
+ try {
+ try (InputStream is = VersionedElement.class
+ .getResourceAsStream("/version.properties")) {
+ p.load(is);
+ }
+ } catch (IOException e) {
+ log.warn("failed to read /version.properties", e);
+ }
+ VERSION = p.getProperty("tavernaserver.version", "unknownVersion");
+ REVISION = String.format("%s (tag: %s)",
+ p.getProperty("tavernaserver.branch", "unknownRevision"),
+ p.getProperty("tavernaserver.revision.describe", "unknownTag"));
+ TIMESTAMP = p
+ .getProperty("tavernaserver.timestamp", "unknownTimestamp");
+ }
+
+ public VersionedElement() {
+ }
+
+ protected VersionedElement(boolean ignored) {
+ serverVersion = VERSION;
+ serverRevision = REVISION;
+ serverBuildTimestamp = TIMESTAMP;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Workflow.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Workflow.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Workflow.java
new file mode 100644
index 0000000..ba6a68c
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/Workflow.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2010-2012 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common;
+
+import static javax.xml.bind.Marshaller.JAXB_ENCODING;
+import static javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT;
+import static javax.xml.bind.annotation.XmlAccessType.NONE;
+import static org.apache.commons.logging.LogFactory.getLog;
+import static org.taverna.server.master.rest.handler.Scufl2DocumentHandler.SCUFL2;
+import static org.taverna.server.master.rest.handler.T2FlowDocumentHandler.T2FLOW;
+import static org.taverna.server.master.rest.handler.T2FlowDocumentHandler.T2FLOW_NS;
+import static org.taverna.server.master.rest.handler.T2FlowDocumentHandler.T2FLOW_ROOTNAME;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Serializable;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.net.URL;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.taverna.server.master.rest.handler.Scufl2DocumentHandler;
+import org.taverna.server.master.rest.handler.T2FlowDocumentHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import uk.org.taverna.scufl2.api.common.NamedSet;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.io.ReaderException;
+import uk.org.taverna.scufl2.api.io.WorkflowBundleIO;
+import uk.org.taverna.scufl2.api.io.WriterException;
+import uk.org.taverna.scufl2.api.profiles.Profile;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Encapsulation of a T2flow or Scufl2 document.
+ *
+ * @author Donal K. Fellows
+ */
+@XmlRootElement(name = "workflow")
+@XmlType(name = "Workflow")
+@XmlAccessorType(NONE)
+public class Workflow implements Serializable, Externalizable {
+ /** Literal document, if present. */
+ @XmlAnyElement(lax = true)
+ private Element content;
+ /** SCUFL2 bundle, if present. */
+ @XmlTransient
+ private WorkflowBundle bundle;
+ /** Which came first, the bundle or the t2flow document. */
+ @XmlTransient
+ private boolean isBundleFirst;
+
+ private static Marshaller marshaller;
+ private static Unmarshaller unmarshaller;
+ private final static String ENCODING = "UTF-8";
+ private final static WorkflowBundleIO io;
+ static {
+ try {
+ JAXBContext context = JAXBContext.newInstance(Workflow.class);
+ marshaller = context.createMarshaller();
+ unmarshaller = context.createUnmarshaller();
+ marshaller.setProperty(JAXB_ENCODING, ENCODING);
+ marshaller.setProperty(JAXB_FORMATTED_OUTPUT, false);
+ } catch (JAXBException e) {
+ getLog("Taverna.Server.Webapp").fatal(
+ "failed to build JAXB context for working with "
+ + Workflow.class, e);
+ }
+ io = new WorkflowBundleIO();
+ }
+
+ public enum ContentType {
+ T2FLOW(T2FlowDocumentHandler.T2FLOW), SCUFL2(
+ Scufl2DocumentHandler.SCUFL2);
+ private String type;
+
+ ContentType(String type) {
+ this.type = type;
+ }
+
+ public String getContentType() {
+ return type;
+ }
+ }
+
+ public Workflow() {
+ }
+
+ public Workflow(Element element) {
+ this.content = element;
+ this.isBundleFirst = false;
+ }
+
+ public Workflow(WorkflowBundle bundle) {
+ this.bundle = bundle;
+ this.isBundleFirst = true;
+ }
+
+ public Workflow(URL url) throws ReaderException, IOException {
+ this(io.readBundle(url, null));
+ }
+
+ /**
+ * What content type would this workflow "prefer" to be?
+ */
+ public ContentType getPreferredContentType() {
+ if (isBundleFirst)
+ return ContentType.SCUFL2;
+ else
+ return ContentType.T2FLOW;
+ }
+
+ /**
+ * Retrieves the workflow as a SCUFL2 document, converting it if necessary.
+ *
+ * @return The SCUFL2 document.
+ * @throws IOException
+ * If anything goes wrong.
+ */
+ public WorkflowBundle getScufl2Workflow() throws IOException {
+ try {
+ if (bundle == null)
+ bundle = io.readBundle(new ByteArrayInputStream(getAsT2Flow()),
+ T2FLOW);
+ return bundle;
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new IOException("problem when converting to SCUFL2", e);
+ }
+ }
+
+ /**
+ * Get the bytes of the serialized SCUFL2 workflow.
+ *
+ * @return Array of bytes.
+ * @throws IOException
+ * If serialization fails.
+ * @throws WriterException
+ * If conversion fails.
+ */
+ public byte[] getScufl2Bytes() throws IOException, WriterException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ io.writeBundle(getScufl2Workflow(), baos, SCUFL2);
+ return baos.toByteArray();
+ }
+
+ /**
+ * Retrieves the workflow as a T2Flow document, converting it if necessary.
+ *
+ * @return The T2Flow document.
+ * @throws IOException
+ * If anything goes wrong.
+ */
+ public Element getT2flowWorkflow() throws IOException {
+ try {
+ if (content != null)
+ return content;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ io.writeBundle(bundle, baos, T2FLOW);
+ Document doc;
+ try {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory
+ .newInstance();
+ dbf.setNamespaceAware(true);
+ doc = dbf.newDocumentBuilder().parse(
+ new ByteArrayInputStream(baos.toByteArray()));
+ } catch (SAXException e) {
+ throw new IOException("failed to convert to DOM tree", e);
+ }
+ Element e = doc.getDocumentElement();
+ if (e.getNamespaceURI().equals(T2FLOW_NS)
+ && e.getNodeName().equals(T2FLOW_ROOTNAME))
+ return content = e;
+ throw new IOException(
+ "unexpected element when converting to T2Flow: {"
+ + e.getNamespaceURI() + "}" + e.getNodeName());
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new IOException("problem when converting to SCUFL2", e);
+ }
+ }
+
+ /**
+ * @return The name of the main workflow profile, or <tt>null</tt> if there
+ * is none.
+ */
+ public String getMainProfileName() {
+ try {
+ return getScufl2Workflow().getMainProfile().getName();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * @return The set of profiles supported over this workflow.
+ */
+ public NamedSet<Profile> getProfiles() {
+ try {
+ return getScufl2Workflow().getProfiles();
+ } catch (IOException e) {
+ return new NamedSet<Profile>();
+ }
+ }
+
+ /**
+ * Convert from marshalled form.
+ *
+ * @throws JAXBException
+ * If the conversion fails.
+ */
+ public static Workflow unmarshal(String representation)
+ throws JAXBException {
+ StringReader sr = new StringReader(representation);
+ return (Workflow) unmarshaller.unmarshal(sr);
+ }
+
+ /**
+ * Convert to marshalled form.
+ */
+ public String marshal() throws JAXBException {
+ StringWriter sw = new StringWriter();
+ marshaller.marshal(this, sw);
+ return sw.toString();
+ }
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ try {
+ ByteArrayInputStream bytes = readbytes(in);
+ if (bytes != null)
+ try (Reader r = new InputStreamReader(bytes, ENCODING)) {
+ content = ((Workflow) unmarshaller.unmarshal(r)).content;
+ }
+ bytes = readbytes(in);
+ if (bytes != null)
+ bundle = io.readBundle(bytes, SCUFL2);
+ isBundleFirst = in.readBoolean();
+ return;
+ } catch (JAXBException e) {
+ throw new IOException("failed to unmarshal", e);
+ } catch (ClassCastException e) {
+ throw new IOException("bizarre result of unmarshalling", e);
+ } catch (ReaderException e) {
+ throw new IOException("failed to unmarshal", e);
+ }
+ }
+
+ private byte[] getAsT2Flow() throws IOException, JAXBException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStreamWriter w = new OutputStreamWriter(baos, ENCODING);
+ marshaller.marshal(this, w);
+ w.close();
+ return baos.toByteArray();
+ }
+
+ private byte[] getAsScufl2() throws IOException, WriterException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ io.writeBundle(bundle, baos, SCUFL2);
+ baos.close();
+ return baos.toByteArray();
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ try {
+ writebytes(out, (content != null) ? getAsT2Flow() : null);
+ } catch (JAXBException e) {
+ throw new IOException("failed to marshal t2flow", e);
+ }
+ try {
+ writebytes(out, (bundle != null) ? getAsScufl2() : null);
+ } catch (WriterException e) {
+ throw new IOException("failed to marshal scufl2", e);
+ }
+ out.writeBoolean(isBundleFirst);
+ }
+
+ private ByteArrayInputStream readbytes(ObjectInput in) throws IOException {
+ int len = in.readInt();
+ if (len > 0) {
+ byte[] bytes = new byte[len];
+ in.readFully(bytes);
+ return new ByteArrayInputStream(bytes);
+ }
+ return null;
+ }
+
+ private void writebytes(ObjectOutput out, byte[] data) throws IOException {
+ out.writeInt(data == null ? 0 : data.length);
+ if (data != null && data.length > 0)
+ out.write(data);
+ }
+
+ /**
+ * Make up for the lack of an integrated XPath engine.
+ *
+ * @param name
+ * The element names to look up from the root of the contained
+ * document.
+ * @return The looked up element, or <tt>null</tt> if it doesn't exist.
+ */
+ private Element getEl(String... name) {
+ Element el = content;
+ boolean skip = true;
+ for (String n : name) {
+ if (skip) {
+ skip = false;
+ continue;
+ }
+ if (el == null)
+ return null;
+ NodeList nl = el.getElementsByTagNameNS(T2FLOW_NS, n);
+ if (nl.getLength() == 0)
+ return null;
+ Node node = nl.item(0);
+ if (node instanceof Element)
+ el = (Element) node;
+ else
+ return null;
+ }
+ return el;
+ }
+
+ /**
+ * @return The content of the embedded
+ * <tt><workflow><dataflow><name></tt> element.
+ */
+ @XmlTransient
+ public String getName() {
+ return getEl("workflow", "dataflow", "name").getTextContent();
+ }
+
+ /**
+ * @return The embedded <tt><workflow></tt> element.
+ */
+ @XmlTransient
+ public Element getWorkflowRoot() {
+ return getEl("workflow");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/package-info.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/package-info.java
new file mode 100644
index 0000000..fd040de
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/package-info.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+/**
+ * This package contains the common XML elements used throughout Taverna Server's various interfaces.
+ * @author Donal Fellows
+ */
+@XmlSchema(namespace = SERVER, elementFormDefault = QUALIFIED, attributeFormDefault = QUALIFIED, xmlns = {
+ @XmlNs(prefix = "xlink", namespaceURI = XLINK),
+ @XmlNs(prefix = "ts", namespaceURI = SERVER),
+ @XmlNs(prefix = "ts-rest", namespaceURI = SERVER_REST),
+ @XmlNs(prefix = "ts-soap", namespaceURI = SERVER_SOAP),
+ @XmlNs(prefix = "feed", namespaceURI = FEED),
+ @XmlNs(prefix = "admin", namespaceURI = ADMIN) })
+package org.taverna.server.master.common;
+
+import static javax.xml.bind.annotation.XmlNsForm.QUALIFIED;
+import static org.taverna.server.master.common.Namespaces.ADMIN;
+import static org.taverna.server.master.common.Namespaces.FEED;
+import static org.taverna.server.master.common.Namespaces.SERVER;
+import static org.taverna.server.master.common.Namespaces.SERVER_REST;
+import static org.taverna.server.master.common.Namespaces.SERVER_SOAP;
+import static org.taverna.server.master.common.Namespaces.XLINK;
+
+import javax.xml.bind.annotation.XmlNs;
+import javax.xml.bind.annotation.XmlSchema;
+
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/common/version/Version.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/common/version/Version.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/version/Version.java
new file mode 100644
index 0000000..e9c58a9
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/common/version/Version.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.common.version;
+
+import static org.taverna.server.master.common.version.Constants.PATCH;
+import static org.taverna.server.master.common.version.Constants.VERSION;
+
+/**
+ * Common location for describing the version of the server.
+ *
+ * @author Donal Fellows
+ */
+public interface Version {
+ public static final String JAVA = VERSION + Constants.releaseChar + PATCH;
+ public static final String HTML = VERSION + Constants.releaseHEnt + PATCH;
+ public static final String XML = VERSION + Constants.releaseXEnt + PATCH;
+}
+
+/**
+ * The pieces of a version string.
+ *
+ * @author Donal Fellows
+ */
+interface Constants {
+ static final String MAJOR = "2";
+ static final String MINOR = "5";
+ static final String PATCH = "4";
+
+ static final char alphaChar = '\u03b1';
+ static final char betaChar = '\u03b2';
+ static final char releaseChar = '.';
+ static final String alphaHEnt = "α";
+ static final String betaHEnt = "β";
+ static final String releaseHEnt = ".";
+ static final String alphaXEnt = "α";
+ static final String betaXEnt = "β";
+ static final String releaseXEnt = ".";
+
+ static final String VERSION = MAJOR + "." + MINOR;
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/defaults/Default.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/defaults/Default.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/defaults/Default.java
new file mode 100644
index 0000000..c2a2bc9
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/defaults/Default.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2013 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.defaults;
+
+import org.taverna.server.master.common.Status;
+import org.taverna.server.master.localworker.LocalWorkerState;
+
+/**
+ * This defines a collection of default values, collecting them from various
+ * parts of the server.
+ *
+ * @author Donal Fellows
+ */
+public interface Default {
+ /** The default value of the <tt>prefix</tt> property. */
+ static final String AUTHORITY_PREFIX = "LOCALUSER_";
+
+ /**
+ * The name of the resource that is the implementation of the subprocess
+ * that this class will fork off.
+ */
+ static final String SERVER_WORKER_IMPLEMENTATION_JAR = "util/server.worker.jar";
+
+ /**
+ * The name of the resource that is the implementation of the subprocess
+ * that manages secure forking.
+ */
+ static final String SECURE_FORK_IMPLEMENTATION_JAR = "util/secure.fork.jar";
+
+ /**
+ * The name of the resource that is the implementation of the subprocess
+ * that acts as the RMI registry.
+ */
+ static final String REGISTRY_JAR = "util/rmi.daemon.jar";
+
+ /** Initial lifetime of runs, in minutes. */
+ static final int RUN_LIFE_MINUTES = 20;
+
+ /**
+ * Maximum number of runs to exist at once. Note that this includes when
+ * they are just existing for the purposes of file transfer (
+ * {@link Status#Initialized}/{@link Status#Finished} states).
+ */
+ static final int RUN_COUNT_MAX = 5;
+
+ /**
+ * Prefix to use for RMI names.
+ */
+ static final String RMI_PREFIX = "ForkRunFactory.";
+
+ /** Default value for {@link LocalWorkerState#passwordFile}. */
+ static final String PASSWORD_FILE = null;
+
+ /**
+ * The extra arguments to pass to the subprocess.
+ */
+ static final String[] EXTRA_ARGUMENTS = new String[0];
+
+ /**
+ * How long to wait for subprocess startup, in seconds.
+ */
+ static final int SUBPROCESS_START_WAIT = 40;
+
+ /**
+ * Polling interval to use during startup, in milliseconds.
+ */
+ static final int SUBPROCESS_START_POLL_SLEEP = 1000;
+
+ /**
+ * Maximum number of {@link Status#Operating} runs at any time.
+ */
+ static final int RUN_OPERATING_LIMIT = 10;
+
+ /**
+ * What fields of a certificate we look at when understanding who it is
+ * talking about, in the order that we look.
+ */
+ static final String[] CERTIFICATE_FIELD_NAMES = { "CN", "COMMONNAME",
+ "COMMON NAME", "COMMON_NAME", "OU", "ORGANIZATIONALUNITNAME",
+ "ORGANIZATIONAL UNIT NAME", "O", "ORGANIZATIONNAME",
+ "ORGANIZATION NAME" };
+
+ /** The type of certificates that are processed if we don't say otherwise. */
+ static final String CERTIFICATE_TYPE = "X.509";
+
+ /** Max size of credential file, in kiB. */
+ static final int CREDENTIAL_FILE_SIZE_LIMIT = 20;
+
+ /**
+ * The notification message format to use if none is configured.
+ */
+ public static final String NOTIFY_MESSAGE_FORMAT = "Your job with ID={0} has finished with exit code {1,number,integer}.";
+
+ /** The address of the SMS gateway service used. */
+ public static final String SMS_GATEWAY_URL = "https://www.intellisoftware.co.uk/smsgateway/sendmsg.aspx";
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/defaults/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/defaults/package-info.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/defaults/package-info.java
new file mode 100644
index 0000000..239b260
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/defaults/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * This package contains information about the various default values supported by the server.
+ * @author Donal Fellows
+ */
+package org.taverna.server.master.defaults;
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadInputPortNameException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadInputPortNameException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadInputPortNameException.java
new file mode 100644
index 0000000..0b6247e
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadInputPortNameException.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.ws.WebFault;
+
+/**
+ * Indicates that the port name was not recognized.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "BadInputPortNameFault")
+@SuppressWarnings("serial")
+public class BadInputPortNameException extends Exception {
+ public BadInputPortNameException(String msg) {
+ super(msg);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadPropertyValueException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadPropertyValueException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadPropertyValueException.java
new file mode 100644
index 0000000..303b19b
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadPropertyValueException.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.ws.WebFault;
+
+/**
+ * Indicates a bad property value.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "BadPropertyValueFault")
+public class BadPropertyValueException extends NoListenerException {
+ private static final long serialVersionUID = -8459491388504556875L;
+
+ public BadPropertyValueException(String msg) {
+ super(msg);
+ }
+
+ public BadPropertyValueException(String msg, Throwable e) {
+ super(msg, e);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadStateChangeException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadStateChangeException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadStateChangeException.java
new file mode 100644
index 0000000..4b843e2
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/BadStateChangeException.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.ws.WebFault;
+
+/**
+ * Exception that is thrown to indicate that the state change requested for a
+ * run is impossible.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "NoUpdateFault")
+public class BadStateChangeException extends NoUpdateException {
+ private static final long serialVersionUID = -4490826388447601775L;
+
+ public BadStateChangeException() {
+ super("cannot do that state change");
+ }
+
+ public BadStateChangeException(Throwable t) {
+ super("cannot do that state change", t);
+ }
+
+ public BadStateChangeException(String msg, Throwable t) {
+ super(msg, t);
+ }
+
+ public BadStateChangeException(String message) {
+ super(message);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/FilesystemAccessException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/FilesystemAccessException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/FilesystemAccessException.java
new file mode 100644
index 0000000..0b6cf07
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/FilesystemAccessException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import java.rmi.RemoteException;
+
+import javax.xml.ws.WebFault;
+
+/**
+ * An exception that happened when the underlying filesystem was accessed.
+ * @author Donal Fellows
+ */
+@WebFault(name = "FilesystemAccessFault")
+public class FilesystemAccessException extends Exception {
+ private static final long serialVersionUID = 8715937300989820318L;
+
+ public FilesystemAccessException(String msg) {
+ super(msg);
+ }
+
+ public FilesystemAccessException(String string, Throwable cause) {
+ super(string, getRealCause(cause));
+ }
+
+ private static Throwable getRealCause(Throwable t) {
+ if (t instanceof RemoteException) {
+ RemoteException remote = (RemoteException) t;
+ if (remote.detail != null)
+ return remote.detail;
+ }
+ if (t.getCause() != null)
+ return t.getCause();
+ return t;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/GeneralFailureException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/GeneralFailureException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/GeneralFailureException.java
new file mode 100644
index 0000000..11d47c7
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/GeneralFailureException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import static org.taverna.server.master.common.Namespaces.SERVER_SOAP;
+
+import javax.xml.ws.WebFault;
+
+/**
+ * Some sort of exception that occurred which we can't map any other way. This
+ * is generally indicative of a problem server-side.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "GeneralFailureFault", targetNamespace = SERVER_SOAP)
+@SuppressWarnings("serial")
+public class GeneralFailureException extends RuntimeException {
+ public GeneralFailureException(Throwable cause) {
+ super(cause.getMessage(), cause);
+ }
+
+ public GeneralFailureException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/InvalidCredentialException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/InvalidCredentialException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/InvalidCredentialException.java
new file mode 100644
index 0000000..67ba551
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/InvalidCredentialException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+/**
+ * An exception that is thrown to indicate that a credential-descriptor or
+ * trust-descriptor supplied as part of a credential or trust management
+ * operation is invalid.
+ *
+ * @author Donal Fellows
+ *
+ */
+@SuppressWarnings("serial")
+public class InvalidCredentialException extends Exception {
+ private static final String MSG = "that credential is invalid";
+
+ public InvalidCredentialException() {
+ super(MSG);
+ }
+
+ public InvalidCredentialException(String reason) {
+ super(MSG + ": " + reason);
+ }
+
+ public InvalidCredentialException(String reason, Throwable cause) {
+ this(reason);
+ initCause(cause);
+ }
+
+ public InvalidCredentialException(Throwable cause) {
+ this(cause.getMessage(), cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoCreateException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoCreateException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoCreateException.java
new file mode 100644
index 0000000..e2ddf4c
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoCreateException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.ws.WebFault;
+
+
+/**
+ * Exception that is thrown to indicate that the user is not permitted to
+ * create something.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "NoCreateFault")
+public class NoCreateException extends NoUpdateException {
+ private static final long serialVersionUID = 270413810410167235L;
+
+ public NoCreateException() {
+ super("not permitted to create");
+ }
+
+ public NoCreateException(String string) {
+ super(string);
+ }
+
+ public NoCreateException(String string, Throwable e) {
+ super(string, e);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoCredentialException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoCredentialException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoCredentialException.java
new file mode 100644
index 0000000..7077fc4
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoCredentialException.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+/**
+ * Exception that indicates the absence of an expected credential.
+ *
+ * @author Donal Fellows
+ */
+@SuppressWarnings("serial")
+public class NoCredentialException extends Exception {
+ public NoCredentialException() {
+ super("no such credential");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoDestroyException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoDestroyException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoDestroyException.java
new file mode 100644
index 0000000..d7b0d29
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoDestroyException.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.ws.WebFault;
+
+
+/**
+ * Exception that is thrown to indicate that the user is not permitted to
+ * destroy something.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "NoDestroyFault")
+public class NoDestroyException extends NoUpdateException {
+ private static final long serialVersionUID = 6207448533265237933L;
+
+ public NoDestroyException() {
+ super("not permitted to destroy");
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoDirectoryEntryException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoDirectoryEntryException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoDirectoryEntryException.java
new file mode 100644
index 0000000..0d6ca63
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoDirectoryEntryException.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.ws.WebFault;
+
+/**
+ * Indicates that the file or directory name was not recognized.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "NoDirectoryEntryFault")
+@SuppressWarnings("serial")
+public class NoDirectoryEntryException extends Exception {
+ public NoDirectoryEntryException(String msg) {
+ super(msg);
+ }
+ public NoDirectoryEntryException(String msg,Exception cause) {
+ super(msg, cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoListenerException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoListenerException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoListenerException.java
new file mode 100644
index 0000000..f4b8e81
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoListenerException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.ws.WebFault;
+
+/**
+ * Exception thrown to indicate that no listener by that name exists, or that
+ * some other problem with listeners has occurred.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "NoListenerFault")
+@XmlSeeAlso(BadPropertyValueException.class)
+public class NoListenerException extends Exception {
+ private static final long serialVersionUID = -2550897312787546547L;
+
+ public NoListenerException() {
+ super("no such listener");
+ }
+
+ public NoListenerException(String msg) {
+ super(msg);
+ }
+
+ public NoListenerException(String msg, Throwable t) {
+ super(msg, t);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoUpdateException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoUpdateException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoUpdateException.java
new file mode 100644
index 0000000..c49d111
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NoUpdateException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.ws.WebFault;
+
+/**
+ * Exception that is thrown to indicate that the user is not permitted to update
+ * something.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "NoUpdateFault")
+@XmlSeeAlso( { NoCreateException.class, NoDestroyException.class, BadStateChangeException.class })
+public class NoUpdateException extends Exception {
+ private static final long serialVersionUID = 4230987102653846379L;
+
+ public NoUpdateException() {
+ super("not permitted to update");
+ }
+
+ public NoUpdateException(String msg) {
+ super(msg);
+ }
+
+ public NoUpdateException(String string, Throwable e) {
+ super(string, e);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NotOwnerException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NotOwnerException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NotOwnerException.java
new file mode 100644
index 0000000..6e1f792
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/NotOwnerException.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.ws.WebFault;
+
+/**
+ * An exception thrown when an operation is attempted which only the owner is
+ * permitted to do. Notably, permissions may <i>only</i> be manipulated by the
+ * owner.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "NotOwnerFault")
+@SuppressWarnings("serial")
+public class NotOwnerException extends Exception {
+ public NotOwnerException() {
+ super("not permitted; not the owner");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/OverloadedException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/OverloadedException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/OverloadedException.java
new file mode 100644
index 0000000..dda371e
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/OverloadedException.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2013 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.ws.WebFault;
+
+/**
+ * Exception that is thrown to indicate that the state change requested for a
+ * run is currently impossible due to excessive server load.
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "OverloadedFault")
+public class OverloadedException extends BadStateChangeException {
+ private static final long serialVersionUID = 490826388447601776L;
+
+ public OverloadedException() {
+ super("server too busy; try later please");
+ }
+
+ public OverloadedException(Throwable t) {
+ super("server too busy; try later please", t);
+ }
+
+ public OverloadedException(String msg, Throwable t) {
+ super(msg, t);
+ }
+
+ public OverloadedException(String message) {
+ super(message);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/UnknownRunException.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/UnknownRunException.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/UnknownRunException.java
new file mode 100644
index 0000000..4632d4a
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/UnknownRunException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.exceptions;
+
+import javax.xml.ws.WebFault;
+
+/**
+ * Exception thrown to indicate that the handle of the run is unknown (or
+ * unacceptable to the current user).
+ *
+ * @author Donal Fellows
+ */
+@WebFault(name = "UnknownRunFault")
+public class UnknownRunException extends Exception {
+ private static final long serialVersionUID = -3028749401786242841L;
+
+ public UnknownRunException() {
+ super("unknown run UUID");
+ }
+
+ public UnknownRunException(Throwable t) {
+ super("implementation problems", t);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/package-info.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/package-info.java
new file mode 100644
index 0000000..29ccacd
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/exceptions/package-info.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+/**
+ * This package contains the exceptions/faults thrown by Taverna Server.
+ * @author Donal Fellows
+ */
+@XmlSchema(namespace = SERVER, elementFormDefault = QUALIFIED, attributeFormDefault = QUALIFIED, xmlns = {
+ @XmlNs(prefix = "xlink", namespaceURI = XLINK),
+ @XmlNs(prefix = "ts", namespaceURI = SERVER),
+ @XmlNs(prefix = "ts-rest", namespaceURI = SERVER_REST),
+ @XmlNs(prefix = "ts-soap", namespaceURI = SERVER_SOAP),
+ @XmlNs(prefix = "feed", namespaceURI = FEED),
+ @XmlNs(prefix = "admin", namespaceURI = ADMIN) })
+package org.taverna.server.master.exceptions;
+
+import static javax.xml.bind.annotation.XmlNsForm.QUALIFIED;
+import static org.taverna.server.master.common.Namespaces.ADMIN;
+import static org.taverna.server.master.common.Namespaces.FEED;
+import static org.taverna.server.master.common.Namespaces.SERVER;
+import static org.taverna.server.master.common.Namespaces.SERVER_REST;
+import static org.taverna.server.master.common.Namespaces.SERVER_SOAP;
+import static org.taverna.server.master.common.Namespaces.XLINK;
+
+import javax.xml.bind.annotation.XmlNs;
+import javax.xml.bind.annotation.XmlSchema;
+
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/facade/Facade.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/facade/Facade.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/facade/Facade.java
new file mode 100644
index 0000000..0015754
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/facade/Facade.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010-2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.facade;
+
+import static javax.ws.rs.core.MediaType.TEXT_HTML_TYPE;
+import static javax.ws.rs.core.Response.ok;
+
+import java.io.IOException;
+import java.net.URL;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+import org.taverna.server.master.utils.Contextualizer;
+
+/**
+ * This is a simple class that is used to serve up a file (with a simple
+ * substitution applied) as the root of the T2Server webapp.
+ *
+ * @author Donal Fellows
+ */
+@Path("/")
+public class Facade {
+ private Log log = LogFactory.getLog("Taverna.Server.Utils");
+ private String welcome;
+ private Contextualizer contextualizer;
+
+ /**
+ * Set what resource file to use as the template for the response.
+ *
+ * @param file
+ * The file from which to load the data (presumed HTML) to serve
+ * up as the root content.
+ * @throws IOException
+ * If the file doesn't exist.
+ */
+ public void setFile(String file) throws IOException {
+ URL full = Facade.class.getResource(file);
+ log.info("setting " + full + " as source of root page");
+ this.welcome = IOUtils.toString(full);
+ }
+
+ @Required
+ public void setContextualizer(Contextualizer contextualizer) {
+ this.contextualizer = contextualizer;
+ }
+
+ /**
+ * Serve up some HTML as the root of the service.
+ *
+ * @param ui
+ * A reference to how we were accessed by the service.
+ * @return The response, containing the HTML.
+ */
+ @GET
+ @Path("{dummy:.*}")
+ @Produces("text/html")
+ public Response get(@Context UriInfo ui) {
+ return ok(contextualizer.contextualize(ui, welcome), TEXT_HTML_TYPE)
+ .build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/facade/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/facade/package-info.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/facade/package-info.java
new file mode 100644
index 0000000..73c884f
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/facade/package-info.java
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+/**
+ * Simple facade used at the top level of the Taverna Server in order to
+ * provide an entry splash page.
+ */
+package org.taverna.server.master.facade;
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/ConfigurableRunFactory.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/ConfigurableRunFactory.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/ConfigurableRunFactory.java
new file mode 100644
index 0000000..954b6f1
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/ConfigurableRunFactory.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2012 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.factories;
+
+/**
+ * Interface to run factories for the purpose of configuration.
+ *
+ * @author Donal Fellows
+ */
+public interface ConfigurableRunFactory extends RunFactory {
+ /** Where is the registry? Getter */
+ String getRegistryHost();
+
+ /** Where is the registry? Setter */
+ void setRegistryHost(String host);
+
+ /** Where is the registry? Getter */
+ int getRegistryPort();
+
+ /** Where is the registry? Setter */
+ void setRegistryPort(int port);
+
+ /** How much can be done at once? Getter */
+ int getMaxRuns();
+
+ /** How much can be done at once? Setter */
+ void setMaxRuns(int maxRuns);
+
+ /** How long will things live? Getter */
+ int getDefaultLifetime();
+
+ /** How long will things live? Setter */
+ void setDefaultLifetime(int defaultLifetime);
+
+ /** How often do we probe for info? Getter */
+ int getSleepTime();
+
+ /** How often do we probe for info? Setter */
+ void setSleepTime(int sleepTime);
+
+ /** How long do we allow for actions? Getter */
+ int getWaitSeconds();
+
+ /** How long do we allow for actions? Setter */
+ void setWaitSeconds(int seconds);
+
+ /** How do we start the workflow engine? Getter */
+ String getExecuteWorkflowScript();
+
+ /** How do we start the workflow engine? Setter */
+ void setExecuteWorkflowScript(String executeWorkflowScript);
+
+ /** How do we start the file system access process? Getter */
+ String getServerWorkerJar();
+
+ /** How do we start the file system access process? Setter */
+ void setServerWorkerJar(String serverWorkerJar);
+
+ /**
+ * How do we start the file system access process? Extra arguments to pass.
+ * Getter
+ */
+ String[] getExtraArguments();
+
+ /**
+ * How do we start the file system access process? Extra arguments to pass.
+ * Setter
+ */
+ void setExtraArguments(String[] firstArguments);
+
+ /** Where is Java? Getter */
+ String getJavaBinary();
+
+ /** Where is Java? Setter */
+ void setJavaBinary(String javaBinary);
+
+ /** Where do we get passwords from? Getter */
+ String getPasswordFile();
+
+ /** Where do we get passwords from? Setter */
+ void setPasswordFile(String newValue);
+
+ /** How do we switch users? Getter */
+ String getServerForkerJar();
+
+ /** How do we switch users? Setter */
+ void setServerForkerJar(String newValue);
+
+ /** How many runs have there been? */
+ int getTotalRuns();
+
+ /** How long did the last subprocess startup take? */
+ int getLastStartupCheckCount();
+
+ /** What are the current runs? */
+ String[] getCurrentRunNames();
+
+ /** What is the RMI ID of the factory process? */
+ String getFactoryProcessName();
+
+ /** What was the last observed exit code? */
+ Integer getLastExitCode();
+
+ /** What factory process to use for a particular user? */
+ String[] getFactoryProcessMapping();
+
+ /** How many runs can be operating at once? Setter */
+ void setOperatingLimit(int operatingLimit);
+
+ /** How many runs can be operating at once? Getter */
+ int getOperatingLimit();
+
+ /**
+ * How many runs are actually operating?
+ *
+ * @throws Exception
+ * if anything goes wrong
+ */
+ int getOperatingCount() throws Exception;
+
+ /** How do we start the RMI registry process? Getter */
+ String getRmiRegistryJar();
+
+ /** How do we start the RMI registry process? Setter */
+ void setRmiRegistryJar(String rmiRegistryJar);
+
+ boolean getGenerateProvenance();
+
+ void setGenerateProvenance(boolean generateProvenance);
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/ListenerFactory.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/ListenerFactory.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/ListenerFactory.java
new file mode 100644
index 0000000..ecc13cd
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/ListenerFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.factories;
+
+import java.util.List;
+
+import org.taverna.server.master.exceptions.NoListenerException;
+import org.taverna.server.master.interfaces.Listener;
+import org.taverna.server.master.interfaces.TavernaRun;
+
+/**
+ * How to make event listeners of various types that are attached to a workflow
+ * instance.
+ *
+ * @author Donal Fellows
+ */
+public interface ListenerFactory {
+ /**
+ * Make an event listener.
+ *
+ * @param run
+ * The workflow instance to attach the event listener to.
+ * @param listenerType
+ * The type of event listener to create. Must be one of the
+ * strings returned by {@link #getSupportedListenerTypes()}.
+ * @param configuration
+ * A configuration document to pass to the listener.
+ * @return The event listener that was created.
+ * @throws NoListenerException
+ * If the <b>listenerType</b> is unrecognized or the
+ * <b>configuration</b> is bad in some way.
+ */
+ public Listener makeListener(TavernaRun run, String listenerType,
+ String configuration) throws NoListenerException;
+
+ /**
+ * What types of listener are supported? Note that we assume that the list
+ * of types is the same for all users and all workflow instances.
+ *
+ * @return A list of supported listener types.
+ */
+ public List<String> getSupportedListenerTypes();
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/RunFactory.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/RunFactory.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/RunFactory.java
new file mode 100644
index 0000000..eeacad7
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/RunFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010-2013 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.factories;
+
+import org.taverna.server.master.common.Workflow;
+import org.taverna.server.master.exceptions.NoCreateException;
+import org.taverna.server.master.interfaces.TavernaRun;
+import org.taverna.server.master.utils.UsernamePrincipal;
+
+/**
+ * How to construct a Taverna Server Workflow Run.
+ *
+ * @author Donal Fellows
+ */
+public interface RunFactory {
+ /**
+ * Make a Taverna Server workflow run that is bound to a particular user
+ * (the "creator") and able to run a particular workflow.
+ *
+ * @param creator
+ * The user creating the workflow instance.
+ * @param workflow
+ * The workflow to instantiate
+ * @return An object representing the run.
+ * @throws NoCreateException
+ * On failure.
+ */
+ TavernaRun create(UsernamePrincipal creator, Workflow workflow)
+ throws NoCreateException;
+
+ /**
+ * Check whether the factory is permitting runs to actually start operating.
+ *
+ * @return Whether a run should start.
+ */
+ boolean isAllowingRunsToStart();
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/package-info.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/package-info.java
new file mode 100644
index 0000000..39b9ac6
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/factories/package-info.java
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+/**
+ * These interfaces define the principal way for the <i>factories</i> of
+ * worker classes to be invoked.
+ */
+package org.taverna.server.master.factories;
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/AuthorityDerivedIDMapper.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/AuthorityDerivedIDMapper.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/AuthorityDerivedIDMapper.java
new file mode 100644
index 0000000..63402ef
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/AuthorityDerivedIDMapper.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.identity;
+
+import static org.taverna.server.master.defaults.Default.AUTHORITY_PREFIX;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.taverna.server.master.interfaces.LocalIdentityMapper;
+import org.taverna.server.master.utils.UsernamePrincipal;
+
+/**
+ * Extracts the local user id from the set of Spring Security authorities
+ * granted to the current user. This is done by scanning the set of authorities
+ * to see if any of them start with the substring listed in the <tt>prefix</tt>
+ * property; the username is the rest of the authority string in that case.
+ *
+ * @author Donal Fellows
+ */
+public class AuthorityDerivedIDMapper implements LocalIdentityMapper {
+ private String prefix = AUTHORITY_PREFIX;
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ @Override
+ public String getUsernameForPrincipal(UsernamePrincipal user) {
+ Authentication auth = SecurityContextHolder.getContext()
+ .getAuthentication();
+ if (auth == null || !auth.isAuthenticated())
+ return null;
+ for (GrantedAuthority authority : auth.getAuthorities()) {
+ String token = authority.getAuthority();
+ if (token == null)
+ continue;
+ if (token.startsWith(prefix))
+ return token.substring(prefix.length());
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/CompositeIDMapper.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/CompositeIDMapper.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/CompositeIDMapper.java
new file mode 100644
index 0000000..b5fcd5a
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/CompositeIDMapper.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010-2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.identity;
+
+import static org.apache.commons.logging.LogFactory.getLog;
+
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.apache.commons.logging.Log;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.taverna.server.master.interfaces.LocalIdentityMapper;
+import org.taverna.server.master.utils.UsernamePrincipal;
+
+/**
+ * An identity mapper that composes the results from other mappers, using the
+ * identity mappers in order until one can provide a non-<tt>null</tt> answer.
+ *
+ * @author Donal Fellows.
+ */
+public class CompositeIDMapper implements LocalIdentityMapper,
+ ApplicationContextAware {
+ private Log log = getLog("Taverna.Server.IdentityMapper");
+ private List<LocalIdentityMapper> mappers;
+ private ApplicationContext context;
+
+ /**
+ * @param mappers
+ * The list of mappers to delegate to. Order is significant.
+ */
+ public void setIdentityMappers(List<LocalIdentityMapper> mappers) {
+ this.mappers = mappers;
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ context = applicationContext;
+ }
+
+ @Override
+ public String getUsernameForPrincipal(UsernamePrincipal user) {
+ if (mappers == null)
+ return null;
+ for (LocalIdentityMapper m : mappers) {
+ String u = m.getUsernameForPrincipal(user);
+ if (u == null)
+ continue;
+ for (Entry<String, ? extends LocalIdentityMapper> entry : context
+ .getBeansOfType(m.getClass()).entrySet())
+ if (m == entry.getValue()) {
+ log.info("used " + entry.getKey() + " LIM to map " + user
+ + " to " + u);
+ break;
+ }
+ return u;
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/ConstantIDMapper.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/ConstantIDMapper.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/ConstantIDMapper.java
new file mode 100644
index 0000000..e81f926
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/ConstantIDMapper.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010-2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.identity;
+
+import org.taverna.server.master.interfaces.LocalIdentityMapper;
+import org.taverna.server.master.utils.UsernamePrincipal;
+
+/**
+ * A trivial principal to user mapper that always uses the same ID.
+ * @author Donal Fellows
+ */
+public class ConstantIDMapper implements LocalIdentityMapper {
+ private String id;
+
+ /**
+ * Sets what local user ID all users should be mapped to.
+ *
+ * @param id
+ * The local user ID.
+ */
+ public void setConstantId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String getUsernameForPrincipal(UsernamePrincipal user) {
+ return id;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-server/blob/2c71f9a9/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/NameIDMapper.java
----------------------------------------------------------------------
diff --git a/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/NameIDMapper.java b/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/NameIDMapper.java
new file mode 100644
index 0000000..42a3874
--- /dev/null
+++ b/taverna-server-webapp/src/main/java/org/taverna/server/master/identity/NameIDMapper.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010-2011 The University of Manchester
+ *
+ * See the file "LICENSE" for license terms.
+ */
+package org.taverna.server.master.identity;
+
+import static java.util.regex.Pattern.compile;
+
+import java.security.Principal;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import org.taverna.server.master.interfaces.LocalIdentityMapper;
+import org.taverna.server.master.utils.UsernamePrincipal;
+
+/**
+ * A trivial identity mapper that just uses the name out of the
+ * {@link Principal}, or uses a regular expression to extract it from the string
+ * representation of the principal.
+ *
+ * @author Donal Fellows
+ */
+public class NameIDMapper implements LocalIdentityMapper {
+ private Pattern pat;
+
+ /**
+ * @param regexp
+ * The regular expression to use. The first capturing group
+ * within the RE will be the result of the extraction.
+ * @throws PatternSyntaxException
+ * If the pattern is invalid.
+ */
+ public void setRegexp(String regexp) throws PatternSyntaxException {
+ pat = compile(regexp);
+ }
+
+ @Override
+ public String getUsernameForPrincipal(UsernamePrincipal user) {
+ if (pat != null) {
+ Matcher m = pat.matcher(user.toString());
+ if (m.find() && m.groupCount() > 0) {
+ return m.group(1);
+ }
+ return null;
+ }
+ return user.getName();
+ }
+}