Project

General

Profile

1
package eu.dnetlib.msro.openaireplus.workflows.nodes.contexts;
2

    
3
import java.io.StringReader;
4
import java.lang.reflect.Type;
5
import java.util.Map;
6
import java.util.Map.Entry;
7

    
8
import com.google.common.base.Function;
9
import com.google.common.collect.Maps;
10
import com.google.common.reflect.TypeToken;
11
import com.google.gson.Gson;
12
import org.apache.commons.lang.StringUtils;
13
import org.apache.commons.logging.Log;
14
import org.apache.commons.logging.LogFactory;
15
import org.dom4j.*;
16
import org.dom4j.io.SAXReader;
17

    
18
/**
19
 * Created by claudio on 01/03/16.
20
 */
21
public class ContextUtils {
22

    
23
	private static final Log log = LogFactory.getLog(ContextUtils.class);
24
	private static final String DASHBOARD_VISIBILITY = "status";
25

    
26
	public static ContextDesc getContext(final Iterable<String> it,
27
			final String contextId,
28
			final String contextLabel,
29
			final String contextType,
30
			final String params, final String dashboardVisibility) throws
31
			DocumentException {
32

    
33
		final Map<String, String> paramMap = getParamMap(params);
34
		paramMap.put(DASHBOARD_VISIBILITY, dashboardVisibility);
35
		return new ContextUtils().getContextDesc(it, contextId, contextLabel, contextType, paramMap);
36
	}
37

    
38
	private static Map<String, String> getParamMap(String jsonMap) {
39
		Map<String, String> paramMap = Maps.newHashMap();
40

    
41
		if (StringUtils.isNotBlank(jsonMap)) {
42
			Type mapType = new TypeToken<Map<String, String>>() {
43
			}.getType();
44
			paramMap = new Gson().fromJson(jsonMap, mapType);
45
		}
46
		return paramMap;
47
	}
48

    
49
	private ContextDesc getContextDesc(final Iterable<String> it,
50
			final String contextId,
51
			final String contextLabel,
52
			final String contextType,
53
			final Map<String, String> params) throws
54
			DocumentException {
55
		final ContextDesc context = new ContextDesc(contextId, contextLabel, contextType, params);
56
		final SAXReader reader = new SAXReader();
57

    
58
		for (String s : it) {
59
			populateContext(context, reader, s);
60
		}
61
		return context;
62
	}
63

    
64
	private void populateContext(final ContextDesc context, final SAXReader reader, final String s) throws DocumentException {
65
		final Document doc = reader.read(new StringReader(s));
66

    
67
		for (Object o : doc.selectNodes("//fundingtree")) {
68
			final Element treeNode = (Element) o;
69

    
70
			final String funder = treeNode.valueOf("./funder/id");
71
			if (StringUtils.isBlank(funder)) {
72
				log.debug("No funder found, skipping population from the following XML: \n" + s);
73
				return;
74
			}
75
			if (!context.getDbEntries().containsKey(funder)) {
76
				log.info("Found funder: " + funder);
77
				context.getDbEntries().put(funder, "<fundingtree>" + treeNode.selectSingleNode("./funder").asXML() + "</fundingtree>");
78
				log.debug("db entry: " + context.getDbEntries().get(funder));
79
			}
80

    
81
			final String openaireId = treeNode.valueOf("./*[starts-with(local-name(),'funding_level_')]/id");
82
			if (!context.getDbEntries().containsKey(openaireId) && StringUtils.isNotBlank(openaireId)) {
83
				log.info("Found funding: " + openaireId);
84
				context.getDbEntries().put(openaireId, treeNode.asXML());
85
				log.debug("db entry: " + context.getDbEntries().get(openaireId));
86
				final Node node0 = treeNode.selectSingleNode(".//funding_level_0");
87
				if (node0 != null) {
88
					final ContextPart part = calculatePart(node0);
89
					if (context.getCategories().containsKey(part.getId())) {
90
						for (ContextPart p : part.getParts().values()) {
91
							context.getCategories().get(part.getId()).addPart(p);
92
						}
93
					} else {
94
						context.getCategories().put(part.getId(), part);
95
					}
96
				}
97
			}
98
		}
99
	}
100

    
101
	private ContextPart calculatePart(final Node node) {
102

    
103
		// final String newId = contextId + "::" + StringUtils.substringAfter(node.valueOf("./id"), "::");
104
		// ids are built as: nsPrefix :: funderID :: fundingLevel0ID :: etc etc, hence it seems we might not need the contextId parameter.
105
		final String newId = StringUtils.substringAfter(node.valueOf("./id"), "::");
106

    
107
		final ContextPart part = new ContextPart(newId, node.valueOf("./description"));
108

    
109
		part.getParams().put("name", node.valueOf("./name"));
110
		part.getParams().put("openaireId", node.valueOf("./id"));
111
		part.getParams().put("class", node.valueOf("./class"));
112

    
113
		final Element parent = node.getParent() != null ? node.getParent().getParent() : null;
114

    
115
		if (parent != null && parent.getName().startsWith("funding_level_")) {
116
			final ContextPart p = calculatePart(parent);
117
			part.getParts().put(p.getId(), p);
118
		}
119
		return part;
120
	}
121

    
122
	public static Function<Entry<String, String>, String> getContextRowTransformer() {
123

    
124
		return new Function<Entry<String, String>, String>() {
125

    
126
			private final SAXReader reader = new SAXReader();
127

    
128
			@Override
129
			public String apply(final Entry<String, String> e) {
130
				try {
131
					final Document docFundingPath = reader.read(new StringReader(e.getValue()));
132

    
133
					final Element root = DocumentHelper.createElement("ROWS");
134

    
135
					final Map<String, String> fundingFields = Maps.newLinkedHashMap();
136
					fundingFields.put("_dnet_resource_identifier_", e.getKey());
137
					fundingFields.put("id", e.getKey());
138
					fundingFields.put("path", e.getValue());
139
					fundingFields.put("jurisdiction", docFundingPath.valueOf("//funder/jurisdiction"));
140
					final String desc = docFundingPath.valueOf("(//*[starts-with(local-name(),'funding_level_')])[1]/description");
141
					if (StringUtils.isNotBlank(desc)) {
142
						fundingFields.put("description", desc);
143
					}
144
					final Map<String, String> orgFields = findFunderInfo(docFundingPath);
145
					final String orgId = orgFields.get("id");
146
					if (StringUtils.isNotBlank(orgId)) {
147
						addRow(root, "dsm_organizations", orgFields);
148
						fundingFields.put("funder", orgId);
149
					}
150

    
151
					addRow(root, "fundingpaths", fundingFields);
152

    
153
					if (log.isDebugEnabled()) {
154
						log.debug("Db entries: " + root.asXML());
155
					}
156

    
157
					return root.asXML();
158
				} catch (DocumentException e1) {
159
					log.error("Error parsing xml", e1);
160
					throw new RuntimeException("Error parsing xml", e1);
161
				}
162
			}
163

    
164
			private Map<String, String> findFunderInfo(final Document doc) {
165
				final Map<String, String> res = Maps.newLinkedHashMap();
166
				res.put("_dnet_resource_identifier_", doc.valueOf("//funder/id"));
167
				res.put("id", doc.valueOf("//funder/id"));
168
				res.put("legalshortname", doc.valueOf("//funder/shortname"));
169
				res.put("legalname", doc.valueOf("//funder/name"));
170
				res.put("country", doc.valueOf("//funder/jurisdiction"));
171
				return res;
172
			}
173

    
174
			private void addRow(final Element root, final String table, final Map<String, String> fields) {
175
				final Element row = root.addElement("ROW");
176
				row.addAttribute("table", table);
177
				for (Map.Entry<String, String> e : fields.entrySet()) {
178
					final Element pathField = row.addElement("FIELD");
179
					pathField.addAttribute("name", e.getKey());
180
					pathField.setText(e.getValue());
181
				}
182
			}
183
		};
184
	}
185

    
186
}
(4-4/8)