Project

General

Profile

1
package eu.dnetlib.msro.workflows.graph;
2

    
3
import java.util.ArrayList;
4
import java.util.HashMap;
5
import java.util.HashSet;
6
import java.util.List;
7
import java.util.Map;
8
import java.util.Set;
9

    
10
import javax.annotation.Resource;
11

    
12
import org.apache.commons.lang3.StringUtils;
13
import org.apache.commons.logging.Log;
14
import org.apache.commons.logging.LogFactory;
15
import org.dom4j.Document;
16
import org.dom4j.Element;
17
import org.dom4j.Node;
18
import org.springframework.beans.factory.annotation.Required;
19

    
20
import com.google.common.collect.Sets;
21

    
22
import eu.dnetlib.conf.PropertyFetcher;
23
import eu.dnetlib.msro.workflows.util.NodeHelper;
24
import eu.dnetlib.rmi.manager.MSROException;
25

    
26
/**
27
 * Created by michele on 19/11/15.
28
 */
29
public class GraphLoader {
30

    
31
	private NodeHelper nodeHelper;
32

    
33
	@Resource(name = "propertyFetcher")
34
	private PropertyFetcher propertyFetcher;
35

    
36
	private static final Log log = LogFactory.getLog(GraphLoader.class);
37

    
38
	public Graph loadGraph(final Document doc, final Map<String, String> globalParams) throws MSROException {
39
		final Graph graph = new Graph();
40

    
41
		for (final Object o : doc.selectNodes("//CONFIGURATION/WORKFLOW/NODE")) {
42
			final Element n = (Element) o;
43
			final String nodeName = n.valueOf("@name");
44
			final String nodeType = n.valueOf("@type");
45
			final boolean isStart = StringUtils.equalsIgnoreCase(n.valueOf("@isStart"), "true");
46
			final boolean isJoin = StringUtils.equalsIgnoreCase(n.valueOf("@isJoin"), "true");
47
			final Map<String, Object> params = calculateParamsForNode(n, globalParams);
48

    
49
			if (isStart) {
50
				graph.addNode(GraphNode.newStartNode(nodeName, nodeType, params));
51
			} else if (isJoin) {
52
				graph.addNode(GraphNode.newJoinNode(nodeName, nodeType, params));
53
			} else {
54
				graph.addNode(GraphNode.newNode(nodeName, nodeType, params));
55
			}
56

    
57
			for (final Object o1 : n.selectNodes(".//ARC")) {
58
				final Element a = (Element) o1;
59
				final String arcName = a.valueOf("@name");
60
				final String to = a.valueOf("@to");
61
				graph.addArc(new Arc(StringUtils.isNotBlank(arcName) ? arcName : Arc.DEFAULT_ARC, nodeName, to));
62
			}
63

    
64
			graph.addNode(GraphNode.newSuccessNode());
65
		}
66

    
67
		checkValidity(graph);
68

    
69
		return graph;
70
	}
71

    
72
	public Map<String, Object> calculateParamsForNode(final Node node, final Map<String, String> globalParams) {
73
		final Map<String, Object> params = new HashMap<String, Object>();
74

    
75
		for (final Object o : node.selectNodes(".//PARAM")) {
76
			final Element p = (Element) o;
77

    
78
			final String pName = p.valueOf("@name");
79
			final String pValue = p.valueOf("@value");
80
			final String pRef = p.valueOf("@ref");
81
			final String pProp = p.valueOf("@property");
82

    
83
			if (StringUtils.isNotBlank(pRef) && StringUtils.isNotBlank(globalParams.get(pRef))) {
84
				params.put(pName, globalParams.get(pRef));
85
			} else if (StringUtils.isNotBlank(pValue)) {
86
				params.put(pName, pValue);
87
			} else if (StringUtils.isNotBlank(pProp)) {
88
				params.put(pName, resolveProperty(pProp));
89
			} else if (p.selectSingleNode("./MAP") != null) {
90

    
91
				final Map<String, String> map = new HashMap<String, String>();
92
				for (final Object e : p.selectNodes("./MAP/ENTRY")) {
93
					final Element entry = (Element) e;
94
					final String eKey = entry.valueOf("@key");
95
					final String eValue = entry.valueOf("@value");
96
					final String eRef = entry.valueOf("@ref");
97
					final String eProp = entry.valueOf("@property");
98

    
99
					if (StringUtils.isNotBlank(eRef) && StringUtils.isNotBlank(globalParams.get(eRef))) {
100
						map.put(eKey, globalParams.get(eRef));
101
					} else if (StringUtils.isNotBlank(eValue)) {
102
						map.put(eKey, eValue);
103
					} else if (StringUtils.isNotBlank(eProp)) {
104
						map.put(eKey, resolveProperty(eProp));
105
					}
106
				}
107
				params.put(pName, map);
108
			} else if (p.selectSingleNode("./LIST") != null) {
109
				final List<String> list = new ArrayList<String>();
110
				for (final Object i : p.selectNodes("./LIST/ITEM")) {
111
					final Element item = (Element) i;
112
					final String iValue = item.valueOf("@value");
113
					final String iRef = item.valueOf("@ref");
114
					final String iProp = item.valueOf("@property");
115

    
116
					if (StringUtils.isNotBlank(iRef) && StringUtils.isNotBlank(globalParams.get(iRef))) {
117
						list.add(globalParams.get(iRef));
118
					} else if (StringUtils.isNotBlank(iValue)) {
119
						list.add(iValue);
120
					} else if (StringUtils.isNotBlank(iProp)) {
121
						list.add(resolveProperty(iProp));
122
					}
123
				}
124
				params.put(pName, list);
125
			}
126
		}
127

    
128
		return params;
129
	}
130

    
131
	private String resolveProperty(final String propertyName) {
132
		if (!this.propertyFetcher.getProps().containsKey(propertyName)) {
133
			log.warn("unable to find system property: " + propertyName);
134
		}
135
		return this.propertyFetcher.getProperty(propertyName);
136
	}
137

    
138
	private void checkValidity(final Graph graph) throws MSROException {
139

    
140
		final Set<String> nodesFromArcs = new HashSet<String>();
141

    
142
		boolean foundSuccess = false;
143
		boolean foundStart = false;
144

    
145
		for (final Arc arc : graph.getArcs()) {
146
			if (StringUtils.isBlank(arc.getFrom()) || StringUtils.isBlank(arc.getFrom())) { throw new MSROException("Invalid arc: missing from e/o to"); }
147
			if (StringUtils.equals(arc.getTo(), GraphNode.SUCCESS_NODE)) {
148
				foundSuccess = true;
149
			}
150
			nodesFromArcs.add(arc.getFrom());
151
			nodesFromArcs.add(arc.getTo());
152
		}
153

    
154
		if (!foundSuccess) { throw new MSROException("Arc to success not found"); }
155

    
156
		final Set<String> diff = Sets.symmetricDifference(graph.nodeNames(), nodesFromArcs);
157
		if (!diff.isEmpty()) { throw new MSROException("Missing or invalid nodes in arcs: " + diff); }
158

    
159
		for (final GraphNode n : graph.nodes()) {
160
			if (StringUtils.isBlank(n.getName())) { throw new MSROException("Invalid node: missing name"); }
161
			if (n.isStart()) {
162
				foundStart = true;
163
			}
164
			if (!this.nodeHelper.isValidType(n.getType())) { throw new MSROException("Invalid node type: " + n.getType()); }
165
		}
166
		if (!foundStart) { throw new MSROException("Start node not found"); }
167
	}
168

    
169
	public NodeHelper getNodeHelper() {
170
		return this.nodeHelper;
171
	}
172

    
173
	@Required
174
	public void setNodeHelper(final NodeHelper nodeHelper) {
175
		this.nodeHelper = nodeHelper;
176
	}
177

    
178
}
(3-3/4)