blob: 45522945f46e832b1521f0b3af98cc670ae5d7e9 [file] [log] [blame]
/**
*
* 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;
}
}