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 11:35:49 UTC
[34/58] [abbrv] incubator-taverna-plugin-component git commit:
org.apache.taverna.component.*
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/local/LocalComponentRegistryFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/local/LocalComponentRegistryFactory.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/local/LocalComponentRegistryFactory.java
new file mode 100644
index 0000000..e8197c1
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/local/LocalComponentRegistryFactory.java
@@ -0,0 +1,44 @@
+package org.apache.taverna.component.registry.local;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.api.Registry;
+import org.apache.taverna.component.registry.ComponentUtil;
+import org.apache.taverna.component.utils.SystemUtils;
+import org.springframework.beans.factory.annotation.Required;
+
+public class LocalComponentRegistryFactory {
+ private final Map<File, Registry> registries = new HashMap<>();
+ private ComponentUtil util;
+ private SystemUtils system;
+
+ @Required
+ public void setComponentUtil(ComponentUtil util) {
+ this.util = util;
+ }
+
+ @Required
+ public void setSystemUtils(SystemUtils system) {
+ this.system = system;
+ }
+
+ public synchronized Registry getComponentRegistry(File registryDir)
+ throws ComponentException {
+ if (!registries.containsKey(registryDir))
+ registries.put(registryDir, new LocalComponentRegistry(registryDir,
+ util, system));
+ return registries.get(registryDir);
+ }
+
+ public Registry getComponentRegistry(URL componentRegistryBase)
+ throws ComponentException {
+ @SuppressWarnings("deprecation")
+ String hackedPath = URLDecoder.decode(componentRegistryBase.getPath());
+ return getComponentRegistry(new File(hackedPath));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/local/LocalComponentVersion.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/local/LocalComponentVersion.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/local/LocalComponentVersion.java
new file mode 100644
index 0000000..87f19d3
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/local/LocalComponentVersion.java
@@ -0,0 +1,93 @@
+/**
+ *
+ */
+package org.apache.taverna.component.registry.local;
+
+import static java.lang.Integer.parseInt;
+import static org.apache.commons.io.FileUtils.readFileToString;
+import static org.apache.log4j.Logger.getLogger;
+import static org.apache.taverna.component.registry.local.LocalComponent.COMPONENT_FILENAME;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.log4j.Logger;
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.registry.ComponentVersion;
+import org.apache.taverna.component.utils.SystemUtils;
+
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+
+/**
+ * @author alanrw
+ *
+ */
+class LocalComponentVersion extends ComponentVersion {
+ private static Logger logger = getLogger(LocalComponentVersion.class);
+
+ private final File componentVersionDir;
+ private SystemUtils system;
+
+ protected LocalComponentVersion(LocalComponent component,
+ File componentVersionDir, SystemUtils system) {
+ super(component);
+ this.componentVersionDir = componentVersionDir;
+ this.system = system;
+ }
+
+ @Override
+ protected final String internalGetDescription() {
+ File descriptionFile = new File(componentVersionDir, "description");
+ try {
+ if (descriptionFile.isFile())
+ return readFileToString(descriptionFile);
+ } catch (IOException e) {
+ logger.error("failed to get description from " + descriptionFile, e);
+ }
+ return "";
+ }
+
+ @Override
+ protected final Integer internalGetVersionNumber() {
+ return parseInt(componentVersionDir.getName());
+ }
+
+ @Override
+ protected final WorkflowBundle internalGetImplementation()
+ throws ComponentException {
+ File filename = new File(componentVersionDir, COMPONENT_FILENAME);
+ try {
+ return system.getBundle(filename);
+ } catch (Exception e) {
+ logger.error(
+ "failed to get component realization from " + filename, e);
+ throw new ComponentException("Unable to open dataflow", e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 + ((componentVersionDir == null) ? 0 : componentVersionDir
+ .hashCode());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ LocalComponentVersion other = (LocalComponentVersion) obj;
+ if (componentVersionDir == null)
+ return (other.componentVersionDir == null);
+ return componentVersionDir.equals(other.componentVersionDir);
+ }
+
+ @Override
+ public URL getHelpURL() {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/Client.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/Client.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/Client.java
new file mode 100644
index 0000000..0fe6304
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/Client.java
@@ -0,0 +1,637 @@
+package org.apache.taverna.component.registry.standard;
+
+import static java.lang.Math.min;
+import static java.lang.String.format;
+import static java.lang.System.getProperty;
+import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
+import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
+import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
+import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
+import static java.net.HttpURLConnection.HTTP_OK;
+import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
+import static java.net.URLEncoder.encode;
+import static javax.xml.bind.DatatypeConverter.printBase64Binary;
+import static org.apache.commons.io.IOUtils.copy;
+import static org.apache.log4j.Logger.getLogger;
+import static org.apache.taverna.component.registry.ClientVersion.VERSION;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import net.sf.taverna.t2.security.credentialmanager.CMException;
+import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
+import net.sf.taverna.t2.security.credentialmanager.UsernamePassword;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.registry.standard.Client.MyExperimentConnector.ServerResponse;
+import org.apache.taverna.component.registry.standard.annotations.Unused;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+class Client {
+ private static final String API_VERIFICATION_RESOURCE = "/component-profiles.xml";
+ private static final String WHOAMI = "/whoami.xml";
+ private static final String PLUGIN_USER_AGENT = "Taverna2-Component-plugin/"
+ + VERSION + " Java/" + getProperty("java.version");
+ private static final int MESSAGE_TRIM_LENGTH = 512;
+ private static final Logger logger = getLogger(Client.class);
+ private final MyExperimentConnector http;
+ private final URL registryBase;
+ private final JAXBContext jaxbContext;
+ private final CredentialManager cm;
+
+ Client(JAXBContext context, URL repository, CredentialManager cm)
+ throws ComponentException {
+ this(context, repository, true, cm);
+ }
+
+ Client(JAXBContext context, URL repository, boolean tryLogIn,
+ CredentialManager cm) throws ComponentException {
+ this.cm = cm;
+ this.registryBase = repository;
+ this.jaxbContext = context;
+ this.http = new MyExperimentConnector(tryLogIn);
+ logger.info("instantiated client connection engine to " + repository);
+ }
+
+ public boolean verify() {
+ try {
+ String url = url(API_VERIFICATION_RESOURCE);
+ logger.info("API verification: HEAD for " + url);
+ return http.HEAD(url).getCode() == HTTP_OK;
+ } catch (Exception e) {
+ logger.info("failed to connect to " + registryBase, e);
+ return false;
+ }
+ }
+
+ private String url(String uri, String... arguments)
+ throws MalformedURLException, UnsupportedEncodingException {
+ StringBuilder uriBuilder = new StringBuilder(uri);
+ for (String queryElement : arguments) {
+ String[] bits = queryElement.split("=", 2);
+ uriBuilder.append(uriBuilder.indexOf("?") < 0 ? "?" : "&")
+ .append(bits[0]).append('=')
+ .append(encode(bits[1], "UTF-8"));
+ }
+ return new URL(registryBase, uriBuilder.toString()).toString();
+ }
+
+ private Marshaller getMarshaller() throws JAXBException {
+ return jaxbContext.createMarshaller();
+ }
+
+ /**
+ * Does an HTTP GET against the configured repository.
+ *
+ * @param clazz
+ * The JAXB-annotated class that the result is supposed to be
+ * instantiated into.
+ * @param uri
+ * The path part of the URI within the repository.
+ * @param query
+ * The strings to put into the query part. Each should be in
+ * <tt>key=value</tt> form.
+ * @return The deserialized response object.
+ * @throws ComponentException
+ * If anything goes wrong.
+ */
+ public <T> T get(Class<T> clazz, String uri, String... query)
+ throws ComponentException {
+ try {
+ int redirectCounter = 0;
+
+ String url = url(uri, query);
+ ServerResponse response;
+ do {
+ if (redirectCounter++ > 5)
+ throw new ComponentException("too many redirects!");
+ logger.info("GET of " + url);
+ response = http.GET(url);
+ if (response.isFailure())
+ throw new ComponentException(
+ "Unable to perform request (%d): %s",
+ response.getCode(), response.getError());
+ } while ((url = response.getLocation()) != null);
+ return response.getResponse(clazz);
+
+ } catch (ComponentException e) {
+ throw e;
+ } catch (MalformedURLException e) {
+ throw new ComponentException("Problem constructing resource URL", e);
+ } catch (JAXBException e) {
+ throw new ComponentException("Problem when unmarshalling response",
+ e);
+ } catch (Exception e) {
+ throw new ComponentException("Problem when sending request", e);
+ }
+ }
+
+ /**
+ * Does an HTTP POST against the configured repository.
+ *
+ * @param clazz
+ * The JAXB-annotated class that the result is supposed to be
+ * instantiated into.
+ * @param elem
+ * The JAXB element to post to the resource.
+ * @param uri
+ * The path part of the URI within the repository.
+ * @param query
+ * The strings to put into the query part. Each should be in
+ * <tt>key=value</tt> form.
+ * @return The deserialized response object.
+ * @throws ComponentException
+ * If anything goes wrong.
+ */
+ public <T> T post(Class<T> clazz, JAXBElement<?> elem, String uri,
+ String... query) throws ComponentException {
+ try {
+
+ String url = url(uri, query);
+ logger.info("POST to " + url);
+ StringWriter sw = new StringWriter();
+ getMarshaller().marshal(elem, sw);
+ if (logger.isDebugEnabled())
+ logger.info("About to post XML document:\n" + sw);
+ ServerResponse response = http.POST(url, sw);
+ if (response.isFailure())
+ throw new ComponentException(
+ "Unable to perform request (%d): %s",
+ response.getCode(), response.getError());
+ if (response.getLocation() != null)
+ return get(clazz, response.getLocation());
+ return response.getResponse(clazz);
+
+ } catch (ComponentException e) {
+ throw e;
+ } catch (MalformedURLException e) {
+ throw new ComponentException("Problem constructing resource URL", e);
+ } catch (JAXBException e) {
+ throw new ComponentException("Problem when marshalling request", e);
+ } catch (Exception e) {
+ throw new ComponentException("Problem when sending request", e);
+ }
+ }
+
+ /**
+ * Does an HTTP PUT against the configured repository.
+ *
+ * @param clazz
+ * The JAXB-annotated class that the result is supposed to be
+ * instantiated into.
+ * @param elem
+ * The JAXB element to post to the resource.
+ * @param uri
+ * The path part of the URI within the repository.
+ * @param query
+ * The strings to put into the query part. Each should be in
+ * <tt>key=value</tt> form.
+ * @return The deserialized response object.
+ * @throws ComponentException
+ * If anything goes wrong.
+ */
+ @Unused
+ public <T> T put(Class<T> clazz, JAXBElement<?> elem, String uri,
+ String... query) throws ComponentException {
+ try {
+
+ String url = url(uri, query);
+ logger.info("PUT to " + url);
+ StringWriter sw = new StringWriter();
+ getMarshaller().marshal(elem, sw);
+ if (logger.isDebugEnabled())
+ logger.info("About to put XML document:\n" + sw);
+ ServerResponse response = http.PUT(url, sw);
+ if (response.isFailure())
+ throw new ComponentException(
+ "Unable to perform request (%d): %s",
+ response.getCode(), response.getError());
+ if (response.getLocation() != null)
+ return get(clazz, response.getLocation());
+ return response.getResponse(clazz);
+
+ } catch (ComponentException e) {
+ throw e;
+ } catch (MalformedURLException e) {
+ throw new ComponentException("Problem constructing resource URL", e);
+ } catch (JAXBException e) {
+ throw new ComponentException("Problem when marshalling request", e);
+ } catch (Exception e) {
+ throw new ComponentException("Problem when sending request", e);
+ }
+ }
+
+ /**
+ * Does an HTTP DELETE against the configured repository.
+ *
+ * @param uri
+ * The path part of the URI within the repository.
+ * @param query
+ * The strings to put into the query part. Each should be in
+ * <tt>key=value</tt> form.
+ * @throws ComponentException
+ * If anything goes wrong.
+ */
+ public void delete(String uri, String... query) throws ComponentException {
+ ServerResponse response;
+ try {
+
+ String url = url(uri, query);
+ logger.info("DELETE of " + url);
+ response = http.DELETE(url);
+
+ } catch (MalformedURLException e) {
+ throw new ComponentException("Problem constructing resource URL", e);
+ } catch (Exception e) {
+ throw new ComponentException("Unable to perform request", e);
+ }
+ if (response.isFailure())
+ throw new ComponentException("Unable to perform request (%d): %s",
+ response.getCode(), response.getError());
+ }
+
+ private String getCredentials(String urlString, boolean mandatory)
+ throws CMException, UnsupportedEncodingException {
+ final URI serviceURI = URI.create(urlString);
+
+ if (mandatory || cm.hasUsernamePasswordForService(serviceURI)) {
+ UsernamePassword userAndPass = cm.getUsernameAndPasswordForService(
+ serviceURI, true, null);
+ // Check for user didn't log in...
+ if (userAndPass == null)
+ return null;
+ return printBase64Binary(format("%s:%s", userAndPass.getUsername(),
+ userAndPass.getPasswordAsString()).getBytes("UTF-8"));
+ }
+ return null;
+ }
+
+ private void clearCredentials(String baseURL) throws CMException {
+ for (URI uri : cm.getServiceURIsForAllUsernameAndPasswordPairs())
+ if (uri.toString().startsWith(baseURL))
+ cm.deleteUsernameAndPasswordForService(uri);
+ }
+
+ private static Document getDocumentFromStream(InputStream inputStream)
+ throws SAXException, IOException, ParserConfigurationException {
+ DocumentBuilder db = DocumentBuilderFactory.newInstance()
+ .newDocumentBuilder();
+ Document doc;
+ try (InputStream is = new BufferedInputStream(inputStream)) {
+ if (!logger.isDebugEnabled())
+ doc = db.parse(is);
+ else {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ copy(is, baos);
+ String response = baos.toString("UTF-8");
+ logger.info("response message follows\n"
+ + response.substring(0,
+ min(MESSAGE_TRIM_LENGTH, response.length())));
+ doc = db.parse(new ByteArrayInputStream(baos.toByteArray()));
+ }
+ }
+ return doc;
+ }
+
+ class MyExperimentConnector {
+ // authentication settings (and the current user)
+ private String authString = null;
+
+ private void tryLogIn(boolean mandatory) throws ComponentException {
+ // check if the stored credentials are valid
+ ServerResponse response = null;
+ try {
+ String userPass = getCredentials(registryBase.toString(),
+ mandatory);
+ if (userPass == null)
+ logger.debug("no credentials available for " + registryBase);
+ else {
+ // set the system to the "logged in" state from INI file properties
+ authString = userPass;
+ response = GET(registryBase.toString() + WHOAMI);
+ }
+ } catch (Exception e) {
+ authString = null;
+ logger.debug("failed when verifying login credentials", e);
+ }
+
+ if (response == null || response.getCode() != HTTP_OK)
+ try {
+ if (response != null)
+ throw new ComponentException("failed to log in: "
+ + response.getError());
+ } finally {
+ try {
+ authString = null;
+ clearCredentials(registryBase.toString());
+ } catch (Exception e) {
+ logger.debug("failed to clear credentials", e);
+ }
+ }
+ if (authString != null)
+ logger.debug("logged in to repository successfully");
+ }
+
+ MyExperimentConnector(boolean tryLogIn) throws ComponentException {
+ if (tryLogIn)
+ tryLogIn(false);
+ }
+
+ // getter for the current status
+ private boolean isLoggedIn() {
+ return authString != null;
+ }
+
+ private HttpURLConnection connect(String method, String strURL)
+ throws MalformedURLException, IOException {
+ HttpURLConnection conn = (HttpURLConnection) new URL(strURL)
+ .openConnection();
+ conn.setRequestMethod(method);
+ if (method.equals("POST") || method.equals("PUT"))
+ conn.setDoOutput(true);
+ conn.setRequestProperty("User-Agent", PLUGIN_USER_AGENT);
+ if (authString != null)
+ conn.setRequestProperty("Authorization", "Basic " + authString);
+ return conn;
+ }
+
+ private boolean elevate() throws ComponentException {
+ tryLogIn(true);
+ return isLoggedIn();
+ }
+
+ /**
+ * Generic method to execute GET requests to myExperiment server.
+ *
+ * @param url
+ * The URL on myExperiment to issue GET request to.
+ * @return An object containing XML Document with server's response body
+ * and a response code. Response body XML document might be null
+ * if there was an error or the user wasn't authorised to
+ * perform a certain action. Response code will always be set.
+ * @throws Exception
+ */
+ public ServerResponse GET(String url) throws Exception {
+ if (!isLoggedIn())
+ logger.warn("not logged in");
+ return receiveServerResponse(connect("GET", url), url, true, false);
+ }
+
+ /**
+ * Generic method to execute GET requests to myExperiment server.
+ *
+ * @param url
+ * The URL on myExperiment to issue GET request to.
+ * @return An object containing XML Document with server's response body
+ * and a response code. Response body XML document might be null
+ * if there was an error or the user wasn't authorised to
+ * perform a certain action. Response code will always be set.
+ * @throws Exception
+ */
+ public ServerResponse HEAD(String url) throws Exception {
+ if (!isLoggedIn())
+ logger.warn("not logged in");
+ return receiveServerResponse(connect("HEAD", url), url, false, true);
+ }
+
+ /**
+ * Generic method to execute GET requests to myExperiment server.
+ *
+ * @param url
+ * The URL on myExperiment to POST to.
+ * @param xmlDataBody
+ * Body of the XML data to be POSTed to strURL.
+ * @return An object containing XML Document with server's response body
+ * and a response code. Response body XML document might be null
+ * if there was an error or the user wasn't authorised to
+ * perform a certain action. Response code will always be set.
+ * @throws Exception
+ */
+ public ServerResponse POST(String url, Object xmlDataBody)
+ throws Exception {
+ if (!isLoggedIn() && !elevate())
+ return null;
+
+ HttpURLConnection conn = connect("POST", url);
+ sendXmlBody(xmlDataBody, conn);
+ return receiveServerResponse(conn, url, false, false);
+ }
+
+ /**
+ * Generic method to execute DELETE requests to myExperiment server.
+ * This is only to be called when a user is logged in.
+ *
+ * @param url
+ * The URL on myExperiment to direct DELETE request to.
+ * @return An object containing XML Document with server's response body
+ * and a response code. Response body XML document might be null
+ * if there was an error or the user wasn't authorised to
+ * perform a certain action. Response code will always be set.
+ * @throws Exception
+ */
+ public ServerResponse DELETE(String url) throws Exception {
+ if (!isLoggedIn() && !elevate())
+ return null;
+ return receiveServerResponse(connect("DELETE", url), url, true,
+ false);
+ }
+
+ @Unused
+ public ServerResponse PUT(String url, Object xmlDataBody)
+ throws Exception {
+ if (!isLoggedIn() && !elevate())
+ return null;
+
+ HttpURLConnection conn = connect("PUT", url);
+ sendXmlBody(xmlDataBody, conn);
+ return receiveServerResponse(conn, url, false, false);
+ }
+
+ /**
+ * Factoring out of how to write a body.
+ *
+ * @param xmlDataBody
+ * What to write (an {@link InputStream}, a {@link Reader} or
+ * an object that will have it's {@link Object#toString()
+ * toString()} method called.
+ * @param conn
+ * Where to write it to.
+ * @throws IOException
+ * If anything goes wrong. The <code>conn</code> will be
+ * disconnected in the case of a failure.
+ */
+ private void sendXmlBody(Object xmlDataBody, HttpURLConnection conn)
+ throws IOException {
+ try {
+ conn.setRequestProperty("Content-Type", "application/xml");
+ if (xmlDataBody instanceof InputStream)
+ copy((InputStream) xmlDataBody, conn.getOutputStream());
+ else
+ try (OutputStreamWriter out = new OutputStreamWriter(
+ conn.getOutputStream())) {
+ if (xmlDataBody instanceof Reader)
+ copy((Reader) xmlDataBody, out);
+ else
+ out.write(xmlDataBody.toString());
+ }
+ } catch (IOException e) {
+ conn.disconnect();
+ throw e;
+ }
+ }
+
+ /**
+ * A common method for retrieving myExperiment server's response for all
+ * types of requests.
+ *
+ * @param conn
+ * Instance of the established URL connection to poll for
+ * server's response.
+ * @param url
+ * The URL on myExperiment with which the connection is
+ * established.
+ * @param isGETrequest
+ * Flag for identifying type of the request. True when the
+ * current connection executes GET request; false when it
+ * executes a POST request.
+ * @return An object containing XML Document with server's response body
+ * and a response code. Response body XML document might be null
+ * if there was an error or the user wasn't authorised to
+ * perform a certain action. Response code will always be set.
+ */
+ private ServerResponse receiveServerResponse(HttpURLConnection conn,
+ String url, boolean isGETrequest, boolean isHEADrequest)
+ throws Exception {
+ try {
+ switch (conn.getResponseCode()) {
+ case HTTP_OK:
+ /*
+ * data retrieval was successful - parse the response XML
+ * and return it along with response code
+ */
+ if (isHEADrequest)
+ return new ServerResponse(conn.getResponseCode(), null,
+ null);
+ return new ServerResponse(conn.getResponseCode(), null,
+ getDocumentFromStream(conn.getInputStream()));
+ case HTTP_NO_CONTENT:
+ return new ServerResponse(HTTP_OK, null, null);
+
+ case HttpURLConnection.HTTP_CREATED:
+ case HttpURLConnection.HTTP_MOVED_PERM:
+ case HttpURLConnection.HTTP_MOVED_TEMP:
+ case HttpURLConnection.HTTP_SEE_OTHER:
+ case HttpURLConnection.HTTP_USE_PROXY:
+ return new ServerResponse(conn.getResponseCode(),
+ conn.getHeaderField("Location"), null);
+
+ case HTTP_BAD_REQUEST:
+ case HTTP_FORBIDDEN:
+ /*
+ * this was a bad XML request - need full XML response to
+ * retrieve the error message from it; Java throws
+ * IOException if getInputStream() is used when non HTTP_OK
+ * response code was received - hence can use
+ * getErrorStream() straight away to fetch the error
+ * document
+ */
+ return new ServerResponse(conn.getResponseCode(), null,
+ getDocumentFromStream(conn.getErrorStream()));
+
+ case HTTP_UNAUTHORIZED:
+ // this content is not authorised for current user
+ logger.warn("non-authorised request to " + url + "\n"
+ + IOUtils.toString(conn.getErrorStream()));
+ return new ServerResponse(conn.getResponseCode(), null,
+ null);
+
+ case HTTP_NOT_FOUND:
+ if (isHEADrequest)
+ return new ServerResponse(conn.getResponseCode(), null,
+ null);
+ throw new FileNotFoundException("no such resource: " + url);
+ default:
+ // unexpected response code - raise an exception
+ throw new IOException(
+ format("Received unexpected HTTP response code (%d) while %s %s",
+ conn.getResponseCode(),
+ (isGETrequest ? "fetching data at"
+ : "posting data to"), url));
+ }
+ } finally {
+ conn.disconnect();
+ }
+ }
+
+ class ServerResponse {
+ private final int responseCode;
+ private final String responseLocation;
+ private final Document responseBody;
+
+ ServerResponse(int responseCode, String responseLocation,
+ Document responseBody) {
+ this.responseCode = responseCode;
+ this.responseBody = responseBody;
+ this.responseLocation = responseLocation;
+ }
+
+ public int getCode() {
+ return responseCode;
+ }
+
+ public boolean isFailure() {
+ return responseCode >= HTTP_BAD_REQUEST;
+ }
+
+ public String getLocation() {
+ return responseLocation;
+ }
+
+ public <T> T getResponse(Class<T> clazz) throws JAXBException {
+ return jaxbContext.createUnmarshaller()
+ .unmarshal(responseBody.getDocumentElement(), clazz)
+ .getValue();
+ }
+
+ /**
+ * Returns contents of the "reason" field of the error message.
+ */
+ public String getError() {
+ if (responseBody != null) {
+ Node reasonElement = responseBody.getDocumentElement()
+ .getElementsByTagName("reason").item(0);
+ if (reasonElement != null) {
+ String reason = reasonElement.getTextContent();
+ if (!reason.isEmpty())
+ return reason;
+ }
+ }
+ return format("unknown reason (%d)", responseCode);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponent.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponent.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponent.java
new file mode 100644
index 0000000..7109bec
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponent.java
@@ -0,0 +1,221 @@
+package org.apache.taverna.component.registry.standard;
+
+import static java.lang.String.format;
+import static org.apache.taverna.component.registry.standard.NewComponentRegistry.logger;
+import static org.apache.taverna.component.registry.standard.Policy.getPolicy;
+import static org.apache.taverna.component.utils.SystemUtils.getElementString;
+import static org.apache.taverna.component.utils.SystemUtils.getValue;
+
+import java.lang.ref.SoftReference;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.IllegalFormatException;
+
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.api.Family;
+import org.apache.taverna.component.api.License;
+import org.apache.taverna.component.api.Registry;
+import org.apache.taverna.component.api.SharingPolicy;
+import org.apache.taverna.component.registry.Component;
+import org.apache.taverna.component.registry.ComponentVersion;
+import org.apache.taverna.component.registry.api.ComponentType;
+import org.apache.taverna.component.registry.api.Description;
+import org.apache.taverna.component.utils.SystemUtils;
+
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+
+class NewComponent extends Component {
+ static final String ELEMENTS = "title,description";
+ static final String EXTRA = "license-type,permissions";
+
+ private final SystemUtils system;
+ final NewComponentRegistry registry;
+ final NewComponentFamily family;
+ private final String id;
+ private final String title;
+ private final String description;
+ private final String resource;
+
+ NewComponent(NewComponentRegistry registry, NewComponentFamily family,
+ Description cd, SystemUtils system) throws ComponentException {
+ super(cd.getUri());
+ this.system = system;
+ this.registry = registry;
+ this.family = family;
+ id = cd.getId().trim();
+ title = getElementString(cd, "title");
+ description = getElementString(cd, "description");
+ resource = cd.getResource();
+ }
+
+ NewComponent(NewComponentRegistry registry, NewComponentFamily family,
+ ComponentType ct, SystemUtils system) {
+ super(ct.getUri());
+ this.system = system;
+ this.registry = registry;
+ this.family = family;
+ id = ct.getId().trim();
+ title = ct.getTitle().trim();
+ description = ct.getDescription().trim();
+ resource = ct.getResource();
+ }
+
+ public ComponentType getCurrent(String elements) throws ComponentException {
+ return registry.getComponentById(id, null, elements);
+ }
+
+ @Override
+ protected String internalGetName() {
+ return title;
+ }
+
+ @Override
+ protected String internalGetDescription() {
+ return description;
+ }
+
+ @Override
+ protected void populateComponentVersionMap() {
+ try {
+ for (Description d : getCurrent("versions").getVersions()
+ .getWorkflow())
+ versionMap.put(d.getVersion(), new Version(d.getVersion(),
+ getValue(d)));
+ } catch (ComponentException e) {
+ logger.warn("failed to retrieve version list: " + e.getMessage());
+ }
+ }
+
+ @Override
+ protected Version internalAddVersionBasedOn(WorkflowBundle bundle,
+ String revisionComment) throws ComponentException {
+ /*
+ * Only fetch the license and sharing policy now; user might have
+ * updated them on the site and we want to duplicate.
+ */
+ ComponentType ct = getCurrent(EXTRA);
+ License license = registry.getLicense(getValue(ct.getLicenseType())
+ .trim());
+ SharingPolicy sharingPolicy = getPolicy(ct.getPermissions());
+
+ return (Version) registry.createComponentVersionFrom(this, title,
+ revisionComment, bundle, license, sharingPolicy);
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof NewComponent) {
+ NewComponent other = (NewComponent) o;
+ return registry.equals(other.registry) && id.equals(other.id);
+ }
+ return false;
+ }
+
+ public String getResourceLocation() {
+ return resource;
+ }
+
+ private static final int BASEHASH = NewComponent.class.hashCode();
+
+ @Override
+ public int hashCode() {
+ return BASEHASH ^ registry.hashCode() ^ id.hashCode();
+ }
+
+ class Version extends ComponentVersion {
+ private int version;
+ private String description;
+ private String location;
+ private SoftReference<WorkflowBundle> bundleRef;
+
+ private static final String htmlPageTemplate = "%1$s/workflows/%2$s/versions/%3$s.html";
+
+ protected Version(Integer version, String description, WorkflowBundle bundle) {
+ super(NewComponent.this);
+ this.version = version;
+ this.description = description;
+ this.bundleRef = new SoftReference<>(bundle);
+ }
+
+ protected Version(Integer version, String description) {
+ super(NewComponent.this);
+ this.version = version;
+ this.description = description;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Version) {
+ Version other = (Version) o;
+ return version == other.version
+ && NewComponent.this.equals(other.getComponent());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return NewComponent.this.hashCode() ^ (version << 16)
+ ^ (version >> 16);
+ }
+
+ @Override
+ protected Integer internalGetVersionNumber() {
+ return version;
+ }
+
+ @Override
+ protected String internalGetDescription() {
+ return description;
+ }
+
+ private String getLocationUri() throws ComponentException {
+ if (location == null)
+ location = registry.getComponentById(id, version,
+ "content-uri").getContentUri();
+ return location;
+ }
+
+ @Override
+ protected synchronized WorkflowBundle internalGetImplementation()
+ throws ComponentException {
+ if (bundleRef == null || bundleRef.get() == null) {
+ String contentUri = getLocationUri();
+ try {
+ WorkflowBundle result = system.getBundleFromUri(contentUri
+ + "?version=" + version);
+ bundleRef = new SoftReference<>(result);
+ return result;
+ } catch (Exception e) {
+ throw new ComponentException("Unable to open dataflow", e);
+ }
+ }
+ return bundleRef.get();
+ }
+
+ @Override
+ public URL getHelpURL() {
+ try {
+ return new URL(format(htmlPageTemplate,
+ registry.getRegistryBaseString(), getId(), version));
+ } catch (IllegalFormatException | MalformedURLException e) {
+ logger.error(e);
+ return null;
+ }
+ }
+ }
+
+ @Override
+ public Registry getRegistry() {
+ return registry;
+ }
+
+ @Override
+ public Family getFamily() {
+ return family;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentFamily.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentFamily.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentFamily.java
new file mode 100644
index 0000000..ff02a33
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentFamily.java
@@ -0,0 +1,133 @@
+package org.apache.taverna.component.registry.standard;
+
+import static org.apache.taverna.component.utils.SystemUtils.getElementString;
+
+import java.util.List;
+
+import org.apache.taverna.component.api.Component;
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.api.Version;
+import org.apache.taverna.component.api.profile.Profile;
+import org.apache.taverna.component.registry.ComponentFamily;
+import org.apache.taverna.component.registry.ComponentUtil;
+import org.apache.taverna.component.registry.api.ComponentFamilyType;
+import org.apache.taverna.component.registry.api.Description;
+
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+
+/**
+ * A family of components in the new-interface registry.
+ *
+ * @author Donal Fellows
+ */
+class NewComponentFamily extends ComponentFamily {
+ static final String ELEMENTS = "title,description";
+
+ private final NewComponentRegistry registry;
+ private final NewComponentProfile profile;
+ private final String id;
+ private final String name;
+ private final String description;
+ private final String uri;
+ private final String resource;
+
+ NewComponentFamily(NewComponentRegistry componentRegistry,
+ NewComponentProfile profile, Description familyDesc,
+ ComponentUtil util) throws ComponentException {
+ super(componentRegistry, util);
+ uri = familyDesc.getUri();
+ registry = componentRegistry;
+ this.profile = profile;
+ id = familyDesc.getId().trim();
+ name = getElementString(familyDesc, "title");
+ description = getElementString(familyDesc, "description");
+ resource = familyDesc.getResource();
+ }
+
+ public NewComponentFamily(NewComponentRegistry componentRegistry,
+ NewComponentProfile profile, ComponentFamilyType cft,
+ ComponentUtil util) {
+ super(componentRegistry, util);
+ uri = cft.getUri();
+ registry = componentRegistry;
+ this.profile = profile;
+ id = cft.getId();
+ name = cft.getTitle();
+ description = cft.getDescription();
+ resource = cft.getResource();
+ }
+
+ @Override
+ protected String internalGetName() {
+ return name;
+ }
+
+ @Override
+ protected String internalGetDescription() {
+ return description;
+ }
+
+ @Override
+ protected Profile internalGetComponentProfile() throws ComponentException {
+ return profile;
+ }
+
+ public List<Component> getMemberComponents() throws ComponentException {
+ return registry.listComponents(this);
+ }
+
+ @Override
+ protected void populateComponentCache() throws ComponentException {
+ for (Component c : getMemberComponents()) {
+ NewComponent component = (NewComponent) c;
+ componentCache.put(component.getName(), component);
+ }
+ }
+
+ @Override
+ protected Version internalCreateComponentBasedOn(String componentName,
+ String description, WorkflowBundle bundle) throws ComponentException {
+ if (componentName == null)
+ componentName = registry.annUtils.getTitle(bundle, "Untitled");
+ if (description == null)
+ componentName = registry.annUtils.getDescription(bundle,
+ "Undescribed");
+ return registry.createComponentFrom(this, componentName, description,
+ bundle, registry.getPreferredLicense(),
+ registry.getDefaultSharingPolicy());
+ }
+
+ @Override
+ protected void internalRemoveComponent(Component component)
+ throws ComponentException {
+ registry.deleteComponent((NewComponent) component);
+ }
+
+ String getId() {
+ return id;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof NewComponentFamily) {
+ NewComponentFamily other = (NewComponentFamily) o;
+ return registry.equals(other.registry) && id.equals(other.id);
+ }
+ return false;
+ }
+
+ private static final int BASEHASH = NewComponentFamily.class.hashCode();
+
+ @Override
+ public int hashCode() {
+ return BASEHASH ^ registry.hashCode() ^ id.hashCode();
+ }
+
+ public String getResourceLocation() {
+ return resource;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentLicense.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentLicense.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentLicense.java
new file mode 100644
index 0000000..ddb87c0
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentLicense.java
@@ -0,0 +1,58 @@
+package org.apache.taverna.component.registry.standard;
+
+import org.apache.taverna.component.api.License;
+import org.apache.taverna.component.registry.api.LicenseType;
+
+class NewComponentLicense implements License {
+ private NewComponentRegistry registry;
+ private String id;
+ private String title;
+ private String description;
+ private String abbreviation;
+
+ static final String ELEMENTS = "title,description,unique-name";
+
+ NewComponentLicense(NewComponentRegistry newComponentRegistry,
+ LicenseType lt) {
+ registry = newComponentRegistry;
+ id = lt.getId();
+ title = lt.getTitle();
+ description = lt.getDescription();
+ abbreviation = lt.getUniqueName();
+ }
+
+ String getId() {
+ return id;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof NewComponentLicense))
+ return false;
+ NewComponentLicense other = (NewComponentLicense) o;
+ return registry.equals(other.registry) && id.equals(other.id);
+ }
+
+ private static final int BASEHASH = NewComponentLicense.class.hashCode();
+
+ @Override
+ public int hashCode() {
+ return BASEHASH ^ registry.hashCode() ^ id.hashCode();
+ }
+
+ @Override
+ public String getName() {
+ return title;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public String getAbbreviation() {
+ return abbreviation;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentProfile.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentProfile.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentProfile.java
new file mode 100644
index 0000000..cade980
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentProfile.java
@@ -0,0 +1,103 @@
+package org.apache.taverna.component.registry.standard;
+
+import static org.apache.taverna.component.utils.SystemUtils.getElementString;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.profile.BaseProfileLocator;
+import org.apache.taverna.component.profile.ComponentProfileImpl;
+import org.apache.taverna.component.registry.api.ComponentProfileType;
+import org.apache.taverna.component.registry.api.Description;
+
+/**
+ * Profiles managed by the new-interface component registry.
+ *
+ * @author Donal Fellows
+ */
+class NewComponentProfile extends ComponentProfileImpl {
+ private static final String LOCATION = "content-uri";
+ static final String ELEMENTS = LOCATION;
+
+ private final NewComponentRegistry registry;
+ private String id;
+ private String location;
+ private String resource;
+ private final String uri;
+
+ private static URL contentUrl(ComponentProfileType cpt)
+ throws ComponentException {
+ try {
+ return new URL(cpt.getContentUri());
+ } catch (MalformedURLException e) {
+ throw new ComponentException("bad profile location", e);
+ }
+ }
+
+ private static URL getLocationURL(Description cpd) throws ComponentException {
+ try {
+ return new URL(getElementString(cpd, LOCATION));
+ } catch (MalformedURLException e) {
+ throw new ComponentException("bad profile location", e);
+ }
+ }
+
+ NewComponentProfile(NewComponentRegistry registry,
+ ComponentProfileType profile, BaseProfileLocator base)
+ throws ComponentException {
+ super(registry, contentUrl(profile), base);
+ this.registry = registry;
+ uri = profile.getUri();
+ id = profile.getId();
+ location = profile.getContentUri();
+ resource = profile.getResource();
+ }
+
+ NewComponentProfile(NewComponentRegistry registry, Description cpd,
+ BaseProfileLocator base) throws ComponentException {
+ super(registry, getLocationURL(cpd), base);
+ this.registry = registry;
+ uri = cpd.getUri();
+ id = cpd.getId();
+ location = getElementString(cpd, LOCATION);
+ resource = cpd.getResource();
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public String getID() {
+ return id;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof NewComponentProfile) {
+ NewComponentProfile other = (NewComponentProfile) o;
+ return registry.equals(other.registry) && id.equals(other.id);
+ }
+ return false;
+ }
+
+ private static final int BASEHASH = NewComponentProfile.class.hashCode();
+
+ @Override
+ public int hashCode() {
+ return BASEHASH ^ registry.hashCode() ^ id.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "Remote Component Profile[" + location + "]";
+ }
+
+ public String getResourceLocation() {
+ return resource;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentRegistry.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentRegistry.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentRegistry.java
new file mode 100644
index 0000000..b8d46f1
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentRegistry.java
@@ -0,0 +1,469 @@
+package org.apache.taverna.component.registry.standard;
+
+import static org.apache.log4j.Logger.getLogger;
+import static org.apache.taverna.component.registry.standard.Policy.PRIVATE;
+import static org.apache.taverna.component.utils.SystemUtils.getElementString;
+
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+
+import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
+
+import org.apache.log4j.Logger;
+import org.apache.taverna.component.api.Component;
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.api.Family;
+import org.apache.taverna.component.api.License;
+import org.apache.taverna.component.api.SharingPolicy;
+import org.apache.taverna.component.api.Version;
+import org.apache.taverna.component.api.Version.ID;
+import org.apache.taverna.component.api.profile.Profile;
+import org.apache.taverna.component.registry.ComponentRegistry;
+import org.apache.taverna.component.registry.ComponentUtil;
+import org.apache.taverna.component.registry.ComponentVersionIdentification;
+import org.apache.taverna.component.registry.api.ComponentDescriptionList;
+import org.apache.taverna.component.registry.api.ComponentFamilyList;
+import org.apache.taverna.component.registry.api.ComponentFamilyType;
+import org.apache.taverna.component.registry.api.ComponentProfileList;
+import org.apache.taverna.component.registry.api.ComponentProfileType;
+import org.apache.taverna.component.registry.api.ComponentType;
+import org.apache.taverna.component.registry.api.Content;
+import org.apache.taverna.component.registry.api.Description;
+import org.apache.taverna.component.registry.api.LicenseList;
+import org.apache.taverna.component.registry.api.LicenseType;
+import org.apache.taverna.component.registry.api.ObjectFactory;
+import org.apache.taverna.component.registry.api.Permissions;
+import org.apache.taverna.component.registry.api.PolicyList;
+import org.apache.taverna.component.utils.AnnotationUtils;
+import org.apache.taverna.component.utils.SystemUtils;
+
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+
+class NewComponentRegistry extends ComponentRegistry {
+ private static final String PROFILE_MIME_TYPE = "application/vnd.taverna.component-profile+xml";
+ private static final String T2FLOW_MIME_TYPE = "application/vnd.taverna.t2flow+xml";
+ static final Logger logger = getLogger(NewComponentRegistry.class);
+ static final JAXBContext jaxbContext;
+ static final Charset utf8;
+ private static final ObjectFactory objectFactory = new ObjectFactory();
+
+ // service URIs
+ private static final String COMPONENT_SERVICE = "/component.xml";
+ private static final String COMPONENT_FAMILY_SERVICE = "/component-family.xml";
+ private static final String COMPONENT_PROFILE_SERVICE = "/component-profile.xml";
+ private static final String COMPONENT_LIST = "/components.xml";
+ private static final String COMPONENT_FAMILY_LIST = "/component-families.xml";
+ private static final String COMPONENT_PROFILE_LIST = "/component-profiles.xml";
+ private static final String WORKFLOW_SERVICE = "/workflow.xml";
+ private static final String PACK_SERVICE = "/pack.xml";
+ private static final String FILE_SERVICE = "/file.xml";
+ private static final String LICENSE_LIST = "/licenses.xml";
+ private static final String POLICY_LIST = "/policies.xml";
+
+ static {
+ JAXBContext c = null;
+ Charset cs = null;
+ try {
+ c = JAXBContext.newInstance(ComponentDescriptionList.class,
+ ComponentFamilyList.class, ComponentProfileList.class,
+ ComponentType.class, ComponentFamilyType.class,
+ ComponentProfileType.class, PolicyList.class,
+ LicenseList.class);
+ cs = Charset.forName("UTF-8");
+ } catch (JAXBException e) {
+ throw new Error("failed to build context", e);
+ } catch (UnsupportedCharsetException e) {
+ throw new Error("failed to find charset", e);
+ } finally {
+ jaxbContext = c;
+ utf8 = cs;
+ }
+ }
+
+ Client client;
+ private final CredentialManager cm;
+ private final ComponentUtil util;
+ private final SystemUtils system;
+ final AnnotationUtils annUtils;
+
+ protected NewComponentRegistry(CredentialManager cm, URL registryBase,
+ ComponentUtil util, SystemUtils system, AnnotationUtils annUtils) throws ComponentException {
+ super(registryBase);
+ this.cm = cm;
+ this.util = util;
+ this.system = system;
+ this.annUtils = annUtils;
+ }
+
+ private void checkClientCreated() throws ComponentException {
+ try {
+ if (client == null)
+ client = new Client(jaxbContext, super.getRegistryBase(), cm);
+ } catch (Exception e) {
+ throw new ComponentException("Unable to access registry", e);
+ }
+ }
+
+ private List<Description> listComponentFamilies(String profileUri)
+ throws ComponentException {
+ checkClientCreated();
+ return client.get(ComponentFamilyList.class, COMPONENT_FAMILY_LIST,
+ "component-profile=" + profileUri,
+ "elements=" + NewComponentFamily.ELEMENTS).getPack();
+ }
+
+ ComponentType getComponentById(String id, Integer version, String elements)
+ throws ComponentException {
+ checkClientCreated();
+
+ if (version != null) {
+ return client.get(ComponentType.class, WORKFLOW_SERVICE,
+ "id=" + id, "version=" + version, "elements=" + elements);
+ }
+ return client.get(ComponentType.class, WORKFLOW_SERVICE, "id=" + id,
+ "elements=" + elements);
+ }
+
+ @SuppressWarnings("unused")
+ private ComponentFamilyType getComponentFamilyById(String id,
+ String elements) throws ComponentException {
+ checkClientCreated();
+
+ return client.get(ComponentFamilyType.class, PACK_SERVICE, "id=" + id,
+ "elements=" + elements);
+ }
+
+ private ComponentProfileType getComponentProfileById(String id,
+ String elements) throws ComponentException {
+ checkClientCreated();
+
+ return client.get(ComponentProfileType.class, FILE_SERVICE, "id=" + id,
+ "elements=" + elements);
+ }
+
+ @Override
+ protected void populateFamilyCache() throws ComponentException {
+ for (Profile pr : getComponentProfiles()) {
+ NewComponentProfile p = (NewComponentProfile) pr;
+ for (Description cfd : listComponentFamilies(p
+ .getResourceLocation()))
+ familyCache.put(getElementString(cfd, "title"),
+ new NewComponentFamily(this, p, cfd, util));
+ }
+ }
+
+ @Override
+ protected Family internalCreateComponentFamily(String familyName,
+ Profile componentProfile, String description, License license,
+ SharingPolicy sharingPolicy) throws ComponentException {
+ NewComponentProfile profile = (NewComponentProfile) componentProfile;
+
+ checkClientCreated();
+
+ return new NewComponentFamily(this, profile, client.post(
+ ComponentFamilyType.class,
+ objectFactory.createPack(makeComponentFamilyCreateRequest(
+ profile, familyName, description, license,
+ sharingPolicy)), COMPONENT_FAMILY_SERVICE, "elements="
+ + NewComponentFamily.ELEMENTS), util);
+ }
+
+ @Override
+ protected void internalRemoveComponentFamily(Family componentFamily)
+ throws ComponentException {
+ NewComponentFamily ncf = (NewComponentFamily) componentFamily;
+ checkClientCreated();
+
+ client.delete(WORKFLOW_SERVICE, "id=" + ncf.getId());
+ }
+
+ @Override
+ protected void populateProfileCache() throws ComponentException {
+ checkClientCreated();
+
+ for (Description cpd : client.get(ComponentProfileList.class,
+ COMPONENT_PROFILE_LIST,
+ "elements=" + NewComponentProfile.ELEMENTS).getFile())
+ if (cpd.getUri() != null && !cpd.getUri().isEmpty())
+ profileCache.add(new NewComponentProfile(this, cpd, util
+ .getBaseProfileLocator()));
+ }
+
+ @Override
+ protected Profile internalAddComponentProfile(Profile componentProfile,
+ License license, SharingPolicy sharingPolicy)
+ throws ComponentException {
+ if (componentProfile == null)
+ throw new ComponentException("component profile must not be null");
+ try {
+ if (componentProfile instanceof NewComponentProfile) {
+ NewComponentProfile profile = (NewComponentProfile) componentProfile;
+ if (profile.getComponentRegistry().equals(this))
+ return new NewComponentProfile(this,
+ getComponentProfileById(profile.getId(),
+ NewComponentProfile.ELEMENTS),
+ util.getBaseProfileLocator());
+ }
+ } catch (ComponentException e) {
+ // Do nothing but fall through
+ }
+ checkClientCreated();
+
+ return new NewComponentProfile(this, client.post(
+ ComponentProfileType.class, objectFactory
+ .createFile(makeComponentProfileCreateRequest(
+ componentProfile.getName(),
+ componentProfile.getDescription(),
+ componentProfile.getXML(), license,
+ sharingPolicy)), COMPONENT_PROFILE_SERVICE,
+ "elements=" + NewComponentProfile.ELEMENTS),
+ util.getBaseProfileLocator());
+ }
+
+ public Permissions getPermissions(SharingPolicy userSharingPolicy) {
+ if (userSharingPolicy == null)
+ userSharingPolicy = getDefaultSharingPolicy();
+ return ((Policy) userSharingPolicy).getPermissionsElement();
+ }
+
+ private ComponentProfileType makeComponentProfileCreateRequest(
+ String title, String description, String content, License license,
+ SharingPolicy sharingPolicy) throws ComponentException {
+ ComponentProfileType profile = new ComponentProfileType();
+
+ profile.setFilename(title + ".xml");
+ profile.setTitle(title);
+ profile.setTitle(description);
+ profile.setContentType(PROFILE_MIME_TYPE);
+ profile.setContent(new Content());
+ profile.getContent().setEncoding("base64");
+ profile.getContent().setType("binary");
+ profile.getContent().setValue(content.getBytes(utf8));
+ if (license == null)
+ license = getPreferredLicense();
+ profile.setLicenseType(new Description());
+ profile.getLicenseType().getContent().add(license.getAbbreviation());
+ profile.setPermissions(getPermissions(sharingPolicy));
+
+ return profile;
+ }
+
+ private ComponentFamilyType makeComponentFamilyCreateRequest(
+ NewComponentProfile profile, String familyName, String description,
+ License license, SharingPolicy sharingPolicy)
+ throws ComponentException {
+ ComponentFamilyType familyDoc = new ComponentFamilyType();
+
+ familyDoc.setComponentProfile(profile.getResourceLocation());
+ familyDoc.setDescription(description);
+ familyDoc.setTitle(familyName);
+ if (license == null)
+ license = getPreferredLicense();
+ familyDoc.setLicenseType(new Description());
+ familyDoc.getLicenseType().getContent().add(license.getAbbreviation());
+ familyDoc.setPermissions(getPermissions(sharingPolicy));
+
+ return familyDoc;
+ }
+
+ private ComponentType makeComponentVersionCreateRequest(String title,
+ String description, WorkflowBundle content, NewComponentFamily family,
+ License license, SharingPolicy sharingPolicy)
+ throws ComponentException {
+ ComponentType comp = new ComponentType();
+
+ comp.setTitle(title);
+ comp.setDescription(description);
+ if (family != null)
+ comp.setComponentFamily(family.getResourceLocation());
+ comp.setContentType(T2FLOW_MIME_TYPE);
+ comp.setContent(new Content());
+ comp.getContent().setEncoding("base64");
+ comp.getContent().setType("binary");
+ comp.getContent().setValue(system.serializeBundle(content));
+ if (license == null)
+ license = getPreferredLicense();
+ if (license != null) {
+ comp.setLicenseType(new Description());
+ comp.getLicenseType().getContent().add(license.getAbbreviation());
+ }
+ comp.setPermissions(getPermissions(sharingPolicy));
+
+ return comp;
+ }
+
+ private static final boolean DO_LIST_POLICIES = false;
+
+ private List<Description> listPolicies() throws ComponentException {
+ checkClientCreated();
+ return client.get(PolicyList.class, POLICY_LIST, "type=group")
+ .getPolicy();
+ }
+
+ @Override
+ protected void populatePermissionCache() {
+ permissionCache.add(Policy.PUBLIC);
+ permissionCache.add(Policy.PRIVATE);
+ try {
+ if (DO_LIST_POLICIES)
+ for (Description d : listPolicies())
+ permissionCache.add(new Policy.Group(d.getId()));
+ } catch (ComponentException e) {
+ logger.warn("failed to fetch sharing policies", e);
+ }
+ }
+
+ private List<LicenseType> listLicenses() throws ComponentException {
+ checkClientCreated();
+
+ return client.get(LicenseList.class, LICENSE_LIST,
+ "elements=" + NewComponentLicense.ELEMENTS).getLicense();
+ }
+
+ @Override
+ protected void populateLicenseCache() {
+ try {
+ for (LicenseType lt : listLicenses())
+ licenseCache.add(new NewComponentLicense(this, lt));
+ } catch (ComponentException e) {
+ logger.warn("failed to fetch licenses", e);
+ }
+ }
+
+ @Override
+ public License getPreferredLicense() throws ComponentException {
+ return getLicenseByAbbreviation(getNameOfPreferredLicense());
+ }
+
+ public String getNameOfPreferredLicense() {
+ return "by-nd";
+ }
+
+ public SharingPolicy getDefaultSharingPolicy() {
+ return PRIVATE;
+ }
+
+ private List<Description> listComponents(String query, String prefixes)
+ throws ComponentException {
+ checkClientCreated();
+
+ return client.get(ComponentDescriptionList.class, COMPONENT_LIST,
+ "query=" + query, "prefixes=" + prefixes,
+ "elements=" + NewComponent.ELEMENTS).getWorkflow();
+ }
+
+ @Override
+ public Set<ID> searchForComponents(String prefixes, String text)
+ throws ComponentException {
+ HashSet<ID> versions = new HashSet<>();
+ for (Description cd : listComponents(text, prefixes)) {
+ NewComponent nc = null;
+ for (Family f : getComponentFamilies()) {
+ nc = (NewComponent) ((NewComponentFamily) f)
+ .getComponent(getElementString(cd, "title"));
+ if (nc != null)
+ break;
+ }
+ if (nc != null)
+ versions.add(new ComponentVersionIdentification(
+ getRegistryBase(), nc.getFamily().getName(), nc
+ .getName(), cd.getVersion()));
+ else
+ logger.warn("could not construct component for " + cd.getUri());
+ }
+ return versions;
+ }
+
+ private List<Description> listComponents(String familyUri)
+ throws ComponentException {
+ checkClientCreated();
+
+ return client.get(ComponentDescriptionList.class, COMPONENT_LIST,
+ "component-family=" + familyUri,
+ "elements=" + NewComponent.ELEMENTS).getWorkflow();
+ }
+
+ protected List<Component> listComponents(NewComponentFamily family)
+ throws ComponentException {
+ List<Component> result = new ArrayList<>();
+ for (Description cd : listComponents(family.getResourceLocation()))
+ result.add(new NewComponent(this, family, cd, system));
+ return result;
+ }
+
+ protected void deleteComponent(NewComponent component)
+ throws ComponentException {
+ checkClientCreated();
+
+ client.delete(WORKFLOW_SERVICE, "id=" + component.getId());
+ }
+
+ protected Version createComponentFrom(NewComponentFamily family,
+ String componentName, String description,
+ WorkflowBundle implementation, License license,
+ SharingPolicy sharingPolicy) throws ComponentException {
+ checkClientCreated();
+
+ ComponentType ct = client.post(ComponentType.class, objectFactory
+ .createWorkflow(makeComponentVersionCreateRequest(
+ componentName, description, implementation, family,
+ license, sharingPolicy)), COMPONENT_SERVICE,
+ "elements=" + NewComponent.ELEMENTS);
+ NewComponent nc = new NewComponent(this, family, ct, system);
+ return nc.new Version(ct.getVersion(), description, implementation);
+ }
+
+ protected Version createComponentVersionFrom(NewComponent component,
+ String componentName, String description,
+ WorkflowBundle implementation, License license,
+ SharingPolicy sharingPolicy) throws ComponentException {
+ checkClientCreated();
+
+ ComponentType ct = client.post(ComponentType.class, objectFactory
+ .createWorkflow(makeComponentVersionCreateRequest(
+ componentName, description, implementation,
+ component.family, license, sharingPolicy)),
+ COMPONENT_SERVICE, "id=" + component.getId(), "elements="
+ + NewComponent.ELEMENTS);
+ return component.new Version(ct.getVersion(), description,
+ implementation);
+ }
+
+ public License getLicense(String name) throws ComponentException {
+ for (License l : getLicenses())
+ if (l.getAbbreviation().equals(name))
+ return l;
+ return null;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ // Careful! Java's URL equality IS BROKEN!
+ if (o != null && o instanceof NewComponentRegistry) {
+ NewComponentRegistry other = (NewComponentRegistry) o;
+ return getRegistryBaseString()
+ .equals(other.getRegistryBaseString());
+ }
+ return false;
+ }
+
+ private static final int BASEHASH = NewComponentRegistry.class.hashCode();
+
+ @Override
+ public int hashCode() {
+ return BASEHASH ^ getRegistryBaseString().hashCode();
+ }
+
+ @Override
+ public String getRegistryTypeName() {
+ return "Component API";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentRegistryFactory.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentRegistryFactory.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentRegistryFactory.java
new file mode 100644
index 0000000..04075ad
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/NewComponentRegistryFactory.java
@@ -0,0 +1,66 @@
+package org.apache.taverna.component.registry.standard;
+
+import static org.apache.taverna.component.registry.standard.NewComponentRegistry.jaxbContext;
+import static org.apache.taverna.component.registry.standard.NewComponentRegistry.logger;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
+
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.registry.ComponentRegistry;
+import org.apache.taverna.component.registry.ComponentUtil;
+import org.apache.taverna.component.utils.AnnotationUtils;
+import org.apache.taverna.component.utils.SystemUtils;
+import org.springframework.beans.factory.annotation.Required;
+
+public class NewComponentRegistryFactory {
+ private final Map<String, NewComponentRegistry> componentRegistries = new HashMap<>();
+ private CredentialManager cm;
+ private ComponentUtil util;
+ private SystemUtils system;
+ private AnnotationUtils annUtils;
+
+ @Required
+ public void setCredentialManager(CredentialManager cm) {
+ this.cm = cm;
+ }
+
+ @Required
+ public void setComponentUtil(ComponentUtil util) {
+ this.util = util;
+ }
+
+ @Required
+ public void setSystemUtils(SystemUtils system) {
+ this.system = system;
+ }
+
+ @Required
+ public void setAnnotationUtils(AnnotationUtils annUtils) {
+ this.annUtils = annUtils;
+ }
+
+ public synchronized ComponentRegistry getComponentRegistry(URL registryBase)
+ throws ComponentException {
+ if (!componentRegistries.containsKey(registryBase.toExternalForm())) {
+ logger.debug("constructing registry instance for " + registryBase);
+ componentRegistries.put(registryBase.toExternalForm(),
+ new NewComponentRegistry(cm, registryBase, util, system,
+ annUtils));
+ }
+ return componentRegistries.get(registryBase.toExternalForm());
+ }
+
+ public boolean verifyBase(URL registryBase) {
+ try {
+ return new Client(jaxbContext, registryBase, false, cm).verify();
+ } catch (Exception e) {
+ logger.info("failed to construct connection client to "
+ + registryBase, e);
+ return false;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/Policy.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/Policy.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/Policy.java
new file mode 100644
index 0000000..74b9496
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/Policy.java
@@ -0,0 +1,136 @@
+package org.apache.taverna.component.registry.standard;
+
+import static java.lang.System.identityHashCode;
+import static org.apache.taverna.component.registry.api.Privilege.DOWNLOAD;
+import static org.apache.taverna.component.registry.api.Privilege.VIEW;
+
+import org.apache.taverna.component.api.SharingPolicy;
+import org.apache.taverna.component.registry.api.Permissions;
+import org.apache.taverna.component.registry.api.Permissions.Permission;
+
+abstract class Policy implements SharingPolicy {
+ public static final SharingPolicy PUBLIC = new Public();
+ public static final SharingPolicy PRIVATE = new Private();
+
+ Policy() {
+ }
+
+ public abstract Permissions getPermissionsElement();
+
+ public static SharingPolicy getPolicy(Permissions perm) {
+ if (perm == null)
+ return PRIVATE;
+ if (perm.getGroupPolicyId() != null)
+ return new Group(perm.getGroupPolicyId());
+ for (Permission p : perm.getPermission())
+ if (p.getId() != null)
+ return new Group(p.getId().toString(), perm);
+ return PUBLIC;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof Policy))
+ return false;
+ return equals((Policy) o);
+ }
+
+ @Override
+ public abstract int hashCode();
+
+ protected abstract boolean equals(Policy p);
+
+ static class Public extends Policy {
+ @Override
+ public String getName() {
+ return "Public";
+ }
+
+ @Override
+ public Permissions getPermissionsElement() {
+ Permission.Privilege privView = new Permission.Privilege();
+ privView.setType(VIEW);
+ Permission.Privilege privDownload = new Permission.Privilege();
+ privDownload.setType(DOWNLOAD);
+ Permission perm = new Permission();
+ perm.setCategory("public");
+ perm.getPrivilege().add(privView);
+ perm.getPrivilege().add(privDownload);
+ Permissions result = new Permissions();
+ result.getPermission().add(perm);
+ return result;
+ }
+
+ @Override
+ protected boolean equals(Policy p) {
+ return p instanceof Public;
+ }
+
+ @Override
+ public int hashCode() {
+ return identityHashCode(PUBLIC);
+ }
+ }
+
+ static class Private extends Policy {
+ @Override
+ public String getName() {
+ return "Private";
+ }
+
+ @Override
+ public Permissions getPermissionsElement() {
+ return null;
+ }
+
+ @Override
+ protected boolean equals(Policy p) {
+ return p instanceof Private;
+ }
+
+ @Override
+ public int hashCode() {
+ return identityHashCode(PRIVATE);
+ }
+ }
+
+ static class Group extends Policy {
+ private String id;
+ private Permissions p;
+
+ public Group(String id) {
+ this.id = id;
+ }
+
+ public Group(String id, Permissions p) {
+ this.id = id;
+ this.p = p;
+ }
+
+ @Override
+ public String getName() {
+ return "Group(" + id + ")";
+ }
+
+ @Override
+ public Permissions getPermissionsElement() {
+ if (p != null)
+ return p;
+ Permissions result = new Permissions();
+ result.setGroupPolicyId(id);
+ return result;
+ }
+
+ @Override
+ protected boolean equals(Policy p) {
+ return (p instanceof Group) && id.equals(((Group) p).id);
+ }
+
+ private static final int BASEHASH = Group.class.hashCode();
+
+ @Override
+ public int hashCode() {
+ return BASEHASH ^ id.hashCode();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/annotations/Unused.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/annotations/Unused.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/annotations/Unused.java
new file mode 100644
index 0000000..4b6fe39
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/annotations/Unused.java
@@ -0,0 +1,25 @@
+package org.apache.taverna.component.registry.standard.annotations;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a constructor, field, method or parameter as unused. Unused members
+ * exist for the purpose of documentation or completeness.
+ *
+ * @author Donal Fellows
+ */
+@Documented
+@Target({ CONSTRUCTOR, FIELD, METHOD, PARAMETER, TYPE })
+@Retention(CLASS)
+public @interface Unused {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/annotations/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/annotations/package-info.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/annotations/package-info.java
new file mode 100644
index 0000000..ca6704f
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/annotations/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Miscellaneous annotations on other parts of the component engine.
+ *
+ * @author Donal Fellows
+ */
+package org.apache.taverna.component.registry.standard.annotations;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/package-info.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/package-info.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/package-info.java
new file mode 100644
index 0000000..43a53f7
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/registry/standard/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * This is the new interface to the myExperiment registry, a.k.a. μExperiment.
+ * @author Donal Fellows
+ */
+package org.apache.taverna.component.registry.standard;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/utils/AnnotationUtils.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/utils/AnnotationUtils.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/utils/AnnotationUtils.java
new file mode 100644
index 0000000..2e886de
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/utils/AnnotationUtils.java
@@ -0,0 +1,91 @@
+package org.apache.taverna.component.utils;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.WeakHashMap;
+
+import uk.org.taverna.scufl2.api.annotation.Annotation;
+import uk.org.taverna.scufl2.api.common.Child;
+import uk.org.taverna.scufl2.api.common.Scufl2Tools;
+import uk.org.taverna.scufl2.api.common.URITools;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.ucfpackage.UCFPackage.ResourceEntry;
+
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.rdf.model.Property;
+import com.hp.hpl.jena.rdf.model.Statement;
+
+public class AnnotationUtils {
+ private static final String TITLE_ANNOTATION = "http://purl.org/dc/terms/title";
+ private static final String DESCRIPTION_ANNOTATION = "http://purl.org/dc/terms/description";
+ private Scufl2Tools tools = new Scufl2Tools();
+ private URITools uris = new URITools();
+
+ public Model getAnnotationModel(Child<WorkflowBundle> subject) throws IOException {
+ return ModelFactory.createDefaultModel().add(getModel(subject));
+ }
+
+ private WeakHashMap<Child<?>, Model> cache = new WeakHashMap<>();
+
+ private static void readParse(Model model, WorkflowBundle bundle, String path)
+ throws IOException {
+ model.read(
+ new StringReader(bundle.getResources()
+ .getResourceAsString(path)), bundle.getGlobalBaseURI()
+ .resolve(path).toString(), "TTL");
+ }
+
+ public Model getModel(Child<WorkflowBundle> subject) throws IOException {
+ WorkflowBundle bundle = subject.getParent();
+ Model m = cache.get(subject);
+ if (m == null) {
+ m = ModelFactory.createDefaultModel();
+ long initialSize = m.size();
+ for (Annotation a : tools.annotationsFor(subject,
+ subject.getParent()))
+ if (!a.getBody().isAbsolute())
+ readParse(m, bundle, a.getBody().getPath());
+ if (m.size() == initialSize)
+ for (ResourceEntry o : bundle.getResources()
+ .listResources("annotation").values())
+ readParse(m, bundle, o.getPath());
+ cache.put(subject, m);
+ }
+ return m;
+ }
+
+ public Statement getAnnotation(Child<WorkflowBundle> subject,
+ String uriForAnnotation) throws IOException {
+ Model m = getModel(subject);
+ Property p = m.getProperty(uriForAnnotation);
+ return m.getResource(uris.uriForBean(subject).toString()).getProperty(
+ p);
+ }
+
+ /** Get the title of the main workflow in a workflow bundle. */
+ public String getTitle(WorkflowBundle bundle, String defaultTitle) {
+ try {
+ Statement s = getAnnotation(bundle.getMainWorkflow(),
+ TITLE_ANNOTATION);
+ if (s != null && s.getObject().isLiteral())
+ return s.getObject().asLiteral().getString();
+ } catch (IOException e) {
+ // TODO log this error?
+ }
+ return defaultTitle;
+ }
+
+ /** Get the description of the main workflow in a workflow bundle. */
+ public String getDescription(WorkflowBundle bundle, String defaultDescription) {
+ try {
+ Statement s = getAnnotation(bundle.getMainWorkflow(),
+ DESCRIPTION_ANNOTATION);
+ if (s != null && s.getObject().isLiteral())
+ return s.getObject().asLiteral().getString();
+ } catch (IOException e) {
+ // TODO log this error?
+ }
+ return defaultDescription;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/java/org/apache/taverna/component/utils/SystemUtils.java
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/java/org/apache/taverna/component/utils/SystemUtils.java b/taverna-component-activity/src/main/java/org/apache/taverna/component/utils/SystemUtils.java
new file mode 100644
index 0000000..61fecbc
--- /dev/null
+++ b/taverna-component-activity/src/main/java/org/apache/taverna/component/utils/SystemUtils.java
@@ -0,0 +1,118 @@
+package org.apache.taverna.component.utils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.JAXBElement;
+
+import org.apache.taverna.component.api.ComponentException;
+import org.apache.taverna.component.registry.api.Description;
+
+import net.sf.taverna.t2.workflowmodel.Dataflow;
+import uk.org.taverna.configuration.app.ApplicationConfiguration;
+import uk.org.taverna.platform.execution.api.InvalidWorkflowException;
+import uk.org.taverna.platform.execution.api.WorkflowCompiler;
+import uk.org.taverna.scufl2.api.container.WorkflowBundle;
+import uk.org.taverna.scufl2.api.io.WorkflowBundleIO;
+
+public class SystemUtils {
+ private static final String T2FLOW_TYPE = "application/vnd.taverna.t2flow+xml";
+ private static final String SCUFL2_TYPE = "application/vnd.taverna.scufl2.workflow-bundle";
+ private ApplicationConfiguration appConfig;
+ private WorkflowBundleIO workflowBundleIO;
+ private List<WorkflowCompiler> compilers;
+
+ public byte[] serializeBundle(WorkflowBundle bundle) throws ComponentException {
+ try {
+ ByteArrayOutputStream dataflowStream = new ByteArrayOutputStream();
+ workflowBundleIO.writeBundle(bundle, dataflowStream, SCUFL2_TYPE);
+ return dataflowStream.toByteArray();
+ } catch (Exception e) {
+ throw new ComponentException(
+ "failed to serialize component implementation", e);
+ }
+ }
+
+ private String determineMediaTypeForFilename(File file) {
+ String[] pieces = file.getName().split("\\.");
+ switch (pieces[pieces.length - 1]) {
+ case "t2flow":
+ return T2FLOW_TYPE;
+ default:
+ return SCUFL2_TYPE;
+ }
+ }
+
+ public void saveBundle(WorkflowBundle bundle, File file) throws Exception {
+ workflowBundleIO.writeBundle(bundle, file,
+ determineMediaTypeForFilename(file));
+ }
+
+ public WorkflowBundle getBundleFromUri(String uri) throws Exception {
+ return workflowBundleIO.readBundle(new URL(uri), null);
+ }
+
+ public WorkflowBundle getBundle(File file) throws Exception {
+ return workflowBundleIO.readBundle(file, null);
+ }
+
+ public static JAXBElement<?> getElement(Description d, String name)
+ throws ComponentException {
+ for (Object o : d.getContent())
+ if (o instanceof JAXBElement) {
+ JAXBElement<?> el = (JAXBElement<?>) o;
+ if (el.getName().getLocalPart().equals(name))
+ return el;
+ }
+ throw new ComponentException("no " + name + " element");
+ }
+
+ public static String getElementString(Description d, String name)
+ throws ComponentException {
+ return getElement(d, name).getValue().toString().trim();
+ }
+
+ public static String getValue(Description d) {
+ StringBuilder sb = new StringBuilder();
+ for (Object o : d.getContent())
+ if (!(o instanceof JAXBElement))
+ sb.append(o);
+ return sb.toString();
+ }
+
+ public File getApplicationHomeDir() {
+ return appConfig.getApplicationHomeDir();
+ }
+
+ public void setAppConfig(ApplicationConfiguration appConfig) {
+ this.appConfig = appConfig;
+ }
+
+ public void setWorkflowBundler(WorkflowBundleIO workflowBundler) {
+ this.workflowBundleIO = workflowBundler;
+ }
+
+ public void setCompilers(List<WorkflowCompiler> compilers) {
+ this.compilers = compilers;
+ }
+
+ public Dataflow compile(WorkflowBundle implementation)
+ throws InvalidWorkflowException {
+ InvalidWorkflowException exn = null;
+ if (compilers != null)
+ for (WorkflowCompiler c : new ArrayList<>(compilers))
+ try {
+ return c.getDataflow(implementation);
+ } catch (InvalidWorkflowException e) {
+ if (exn == null)
+ exn = e;
+ continue;
+ }
+ if (exn != null)
+ throw exn;
+ throw new InvalidWorkflowException("no compiler available");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/resources/EmptyProfile.xml
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/resources/EmptyProfile.xml b/taverna-component-activity/src/main/resources/EmptyProfile.xml
index 2851b83..cc5edd5 100644
--- a/taverna-component-activity/src/main/resources/EmptyProfile.xml
+++ b/taverna-component-activity/src/main/resources/EmptyProfile.xml
@@ -4,7 +4,7 @@
xmlns="http://ns.taverna.org.uk/2012/component/profile"
xsi:schemaLocation="http://ns.taverna.org.uk/2012/component/profile ComponentProfile.xsd">
- <id>net.sf.taverna.t2.component.profile.empty</id>
+ <id>org.apache.taverna.component.profile.empty</id>
<name>Empty profile</name>
<description>A basic empty profile that does not allow additional semantic annotation</description>
<component>
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/resources/META-INF/spring/component-activity-context.xml
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/resources/META-INF/spring/component-activity-context.xml b/taverna-component-activity/src/main/resources/META-INF/spring/component-activity-context.xml
index 4746ede..f1f47a6 100644
--- a/taverna-component-activity/src/main/resources/META-INF/spring/component-activity-context.xml
+++ b/taverna-component-activity/src/main/resources/META-INF/spring/component-activity-context.xml
@@ -7,16 +7,16 @@
http://www.springframework.org/schema/osgi/spring-osgi.xsd">
<bean id="ComponentLocalHealthChecker"
- class="net.sf.taverna.t2.component.ComponentActivityLocalChecker" />
+ class="org.apache.taverna.component.ComponentActivityLocalChecker" />
<bean id="ComponentUpgradeHealthChecker"
- class="net.sf.taverna.t2.component.ComponentActivityUpgradeChecker">
+ class="org.apache.taverna.component.ComponentActivityUpgradeChecker">
<property name="componentUtil" ref="componentUtil" />
</bean>
- <bean id="baseProfileLocator" class="net.sf.taverna.t2.component.profile.BaseProfileLocator">
+ <bean id="baseProfileLocator" class="org.apache.taverna.component.profile.BaseProfileLocator">
<property name="appConfig" ref="app-config" />
</bean>
- <bean id="componentActivityFactory" class="net.sf.taverna.t2.component.ComponentActivityFactory">
+ <bean id="componentActivityFactory" class="org.apache.taverna.component.ComponentActivityFactory">
<property name="componentUtil" ref="componentUtil" />
<property name="dataflowCache" ref="cache" />
<property name="edits" ref="edits" />
@@ -24,32 +24,32 @@
</bean>
<bean id="networkRegistry"
- class="net.sf.taverna.t2.component.registry.standard.NewComponentRegistryFactory">
+ class="org.apache.taverna.component.registry.standard.NewComponentRegistryFactory">
<property name="credentialManager" ref="credentialManager" />
<property name="componentUtil" ref="componentUtil" />
<property name="systemUtils" ref="systemUtil" />
<property name="annotationUtils" ref="annotationUtil" />
</bean>
<bean id="fileRegistry"
- class="net.sf.taverna.t2.component.registry.local.LocalComponentRegistryFactory">
+ class="org.apache.taverna.component.registry.local.LocalComponentRegistryFactory">
<property name="componentUtil" ref="componentUtil" />
<property name="systemUtils" ref="systemUtil" />
</bean>
- <bean id="componentUtil" class="net.sf.taverna.t2.component.registry.ComponentUtil">
+ <bean id="componentUtil" class="org.apache.taverna.component.registry.ComponentUtil">
<property name="networkLocator" ref="networkRegistry" />
<property name="fileLocator" ref="fileRegistry" />
<property name="baseLocator" ref="baseProfileLocator" />
</bean>
- <bean id="cache" class="net.sf.taverna.t2.component.registry.ComponentImplementationCache">
+ <bean id="cache" class="org.apache.taverna.component.registry.ComponentImplementationCache">
<property name="componentUtil" ref="componentUtil" />
</bean>
- <bean id="systemUtil" class="net.sf.taverna.t2.component.utils.SystemUtils">
+ <bean id="systemUtil" class="org.apache.taverna.component.utils.SystemUtils">
<property name="appConfig" ref="app-config" />
<property name="workflowBundler" ref="workflowBundleIO" />
<property name="compilers" ref="compilers" />
</bean>
- <bean id="annotationUtil" class="net.sf.taverna.t2.component.utils.AnnotationUtils" />
+ <bean id="annotationUtil" class="org.apache.taverna.component.utils.AnnotationUtils" />
<osgi:service ref="ComponentLocalHealthChecker"
interface="net.sf.taverna.t2.workflowmodel.health.HealthChecker" />
@@ -65,6 +65,6 @@
<osgi:reference id="credentialManager"
interface="net.sf.taverna.t2.security.credentialmanager.CredentialManager" />
<osgi:reference id="edits" interface="net.sf.taverna.t2.workflowmodel.Edits" />
- <osgi:reference id="workflowBundleIO" interface="uk.org.taverna.scufl2.api.io.WorkflowBundleIO" />
+ <osgi:reference id="workflowBundleIO" interface="org.apache.taverna.scufl2.api.io.WorkflowBundleIO" />
<osgi:list id="compilers" interface="uk.org.taverna.platform.execution.api.WorkflowCompiler" />
</beans>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/fb982e2f/taverna-component-activity/src/main/resources/NewMyExperimentSchema.xsd
----------------------------------------------------------------------
diff --git a/taverna-component-activity/src/main/resources/NewMyExperimentSchema.xsd b/taverna-component-activity/src/main/resources/NewMyExperimentSchema.xsd
index ba06860..0a8dc83 100644
--- a/taverna-component-activity/src/main/resources/NewMyExperimentSchema.xsd
+++ b/taverna-component-activity/src/main/resources/NewMyExperimentSchema.xsd
@@ -7,7 +7,7 @@
<xs:annotation>
<xs:appinfo>
<jxb:schemaBindings>
- <jxb:package name="net.sf.taverna.t2.component.registry.api" />
+ <jxb:package name="org.apache.taverna.component.registry.api" />
</jxb:schemaBindings>
</xs:appinfo>
</xs:annotation>