/** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.airavata.workflow.model.graph.system; import java.util.ArrayList; import java.util.List; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import org.apache.airavata.common.exception.AiravataException; import org.apache.airavata.model.application.io.DataType; import org.apache.airavata.common.utils.XMLUtil; import org.apache.airavata.workflow.model.graph.DataEdge; import org.apache.airavata.workflow.model.graph.DataPort; import org.apache.airavata.workflow.model.graph.Graph; import org.apache.airavata.workflow.model.graph.GraphException; import org.apache.airavata.workflow.model.graph.GraphSchema; import org.apache.airavata.workflow.model.graph.Port; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xmlpull.infoset.XmlElement; import org.xmlpull.infoset.XmlNamespace; abstract public class ParameterNode extends SystemNode { private static final String NAME_TAG = "name"; private static final String DESCRIPTION_TAG = "description"; private static final String DATA_TYPE_QNAME_TAG = "dataType"; private static final String METADATA_TAG = "metadata"; private boolean configured; private static final Logger log = LoggerFactory.getLogger(ParameterNode.class); /** * Type of the parameter (e.g. xsd:string, xsd:int) */ private DataType parameterType; private String configuredName; private String description; private XmlElement metadata; private JsonObject metadataJson; /** * Constructs a ParameterNode. * * @param nodeElement * @throws GraphException */ public ParameterNode(XmlElement nodeElement) throws GraphException { super(nodeElement); } public ParameterNode(JsonObject nodeObject) throws GraphException { super(nodeObject); } /** * Constructs a ParameterNode. * * @param graph * */ public ParameterNode(Graph graph) { super(graph); } /** * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#setName(java.lang.String) */ @Override public void setName(String name) { super.setName(name); // Creates the ID to the new one based on the new name. This is // for readability of workflow scripts. createID(); } /** * @param parameterType */ public void setParameterType(DataType parameterType) { this.parameterType = parameterType; } /** * Returns the type of the parameter * * @return The type of the parameter (e.g. string, int) */ public DataType getParameterType() { return this.parameterType; } /** * Returns the configuredName. * * @return The configuredName */ public String getConfiguredName() { return this.configuredName; } /** * Sets configuredName. * * @param configuredName * The configuredName to set. */ public void setConfiguredName(String configuredName) { this.configuredName = configuredName; setName(configuredName); } /** * Returns the description. * * @return The description */ public String getDescription() { return this.description; } /** * Sets description. * * @param description * The description to set. */ public void setDescription(String description) { this.description = description; } /** * @param metadata */ public void setMetadata(XmlElement metadata) { if (metadata == null) { this.metadata = null; return; } // clone and detach from the parent try { this.metadata = XMLUtil.deepClone(metadata); } catch (AiravataException e) { log.error(e.getMessage(), e); } // Reformat List<String> emptyTexts = new ArrayList<String>(); for (Object child : this.metadata.children()) { if (child instanceof XmlElement) { XmlElement element = (XmlElement) child; for (XmlNamespace ns : element.namespaces()) { // move the namespace declaration up if possible. if (this.metadata.lookupNamespaceByPrefix(ns.getPrefix()) == null) { // If this prefix is not used yet, copy to the root. this.metadata.declareNamespace(ns); } } } else if (child instanceof String) { String text = (String) child; // Remove the white spaces. if (text.trim().length() == 0) { // We cannot remove it in the iterator. emptyTexts.add(text); } } } for (String text : emptyTexts) { this.metadata.removeChild(text); } } public void setMetadataJson(JsonObject metadata1) { this.metadataJson = metadata1; } /** * @return The metadata */ public XmlElement getMetadata() { return this.metadata; } /** * @param configured */ public void setConfigured(boolean configured) { this.configured = configured; } /** * @return true if configured; false otherwise. */ public boolean isConfigured() { return this.configured; } /** * Checks if this InputNode is connected. * * @return true if this InputNode is connected; false otherwise; */ public boolean isConnected() { if (getEdges().size() > 0) { return true; } else { return false; } } /** * Returns the port of this ParameterNode. * * Note that a ParameterNode always has only one port. * * @return The port */ abstract public SystemDataPort getPort(); /** * Returns the first port that this node is connected to/from. * * @return The first port that this node is connected to/from */ abstract public Port getConnectedPort(); @Override protected void parseConfiguration(XmlElement configElement) { XmlElement nameElement = configElement.element(null, NAME_TAG); if (nameElement != null) { // If the name is set here, this node has been configured. this.configured = true; this.configuredName = nameElement.requiredText(); } XmlElement descElement = configElement.element(null, DESCRIPTION_TAG); if (descElement != null) { this.description = descElement.requiredText(); } XmlElement typeElement = configElement.element(null, DATA_TYPE_QNAME_TAG); if (typeElement != null) { String qnameText = typeElement.requiredText(); if (qnameText != null && !qnameText.equals("")) { this.parameterType = DataType.valueOf(qnameText); } } XmlElement metadataElement = configElement.element(null, METADATA_TAG); if (metadataElement != null) { for (XmlElement appinfo : metadataElement.requiredElementContent()) { // Call setMetadata to clone and reformat. setMetadata(appinfo); // It should have only one element. break; } } } protected void parseConfiguration(JsonObject configObject) { JsonElement nameElement = configObject.get(NAME_TAG); if (nameElement != null) { this.configured = true; this.configuredName = nameElement.getAsString(); } JsonElement descriptionElement = configObject.get(DESCRIPTION_TAG); if (descriptionElement != null) { this.description = descriptionElement.getAsString(); } JsonElement typeElement = configObject.get(DATA_TYPE_QNAME_TAG); if (typeElement != null) { this.parameterType = DataType.valueOf(typeElement.getAsString()); } JsonElement metadataElement = configObject.get(METADATA_TAG); if (metadataElement != null) { JsonObject metaObject = (JsonObject) metadataElement; JsonElement appInfoElement = metaObject.get("appinfo"); if (appInfoElement != null) { setMetadataJson((JsonObject) appInfoElement); } } } @Override protected XmlElement addConfigurationElement(XmlElement nodeElement) { XmlElement configElement = nodeElement.addElement(GraphSchema.NS, GraphSchema.NODE_CONFIG_TAG); if (this.configured) { // Don't save the name here if this node has not been configured. XmlElement nameElement = configElement.addElement(GraphSchema.NS, NAME_TAG); nameElement.addChild(this.configuredName); } if (this.description != null) { XmlElement descriptionElement = configElement.addElement(GraphSchema.NS, DESCRIPTION_TAG); descriptionElement.addChild(this.description); } if (this.parameterType != null) { XmlElement qnameElement = configElement.addElement(GraphSchema.NS, DATA_TYPE_QNAME_TAG); qnameElement.addChild(this.parameterType.toString()); } if (this.metadata != null) { XmlElement metadataElement = configElement.addElement(GraphSchema.NS, METADATA_TAG); // Clone the metadata to avoid parent problem because this can be // called multiple times. try { metadataElement.addChild(XMLUtil.deepClone(this.metadata)); } catch (AiravataException e) { log.error(e.getMessage(), e); } } return configElement; } @Override protected JsonObject addConfigurationElement(JsonObject nodeObject) { JsonObject configObject = new JsonObject(); if (this.configured) { // Don't save the name here if this node has not been configured. configObject.addProperty(NAME_TAG, this.configuredName); } if (this.description != null) { configObject.addProperty(DESCRIPTION_TAG, this.description); } if (this.parameterType != null) { configObject.addProperty(DATA_TYPE_QNAME_TAG, this.parameterType.toString()); } if (this.metadata != null) { configObject.add(METADATA_TAG, this.metadataJson); } nodeObject.add(GraphSchema.NODE_CONFIG_TAG, configObject); return configObject; } protected List<DataEdge> getEdges() { DataPort port = getPort(); List<DataEdge> edges = port.getEdges(); return edges; } }