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

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

    
32
		return new ContextUtils().getContextDesc(it, contextId, contextLabel, contextType, getParamMap(params));
33
	}
34

    
35
	private static Map<String, String> getParamMap(String jsonMap) {
36
		Map<String, String> paramMap = Maps.newHashMap();
37
		if (StringUtils.isNotBlank(jsonMap)) {
38
			Type mapType = new TypeToken<Map<String, String>>() {
39
			}.getType();
40
			paramMap = new Gson().fromJson(jsonMap, mapType);
41
		}
42
		return paramMap;
43
	}
44

    
45
	private ContextDesc getContextDesc(final Iterable<String> it,
46
			final String contextId,
47
			final String contextLabel,
48
			final String contextType,
49
			final Map<String, String> params) throws
50
			DocumentException {
51
		final ContextDesc context = new ContextDesc(contextId, contextLabel, contextType, params);
52
		final SAXReader reader = new SAXReader();
53

    
54
		for (String s : it) {
55
			populateContext(context, reader, s);
56
		}
57
		return context;
58
	}
59

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

    
63
		for (Object o : doc.selectNodes("//fundingtree")) {
64
			final Element treeNode = (Element) o;
65

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

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

    
97
	private ContextPart calculatePart(final Node node) {
98

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

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

    
105
		part.getParams().put("name", node.valueOf("./name"));
106
		part.getParams().put("openaireId", node.valueOf("./id"));
107
		part.getParams().put("class", node.valueOf("./class"));
108

    
109
		final Element parent = node.getParent() != null ? node.getParent().getParent() : null;
110

    
111
		if (parent != null && parent.getName().startsWith("funding_level_")) {
112
			final ContextPart p = calculatePart(parent);
113
			part.getParts().put(p.getId(), p);
114
		}
115
		return part;
116
	}
117

    
118
	public static Function<Entry<String, String>, String> getContextRowTransformer() {
119

    
120
		return new Function<Entry<String, String>, String>() {
121

    
122
			private final SAXReader reader = new SAXReader();
123

    
124
			@Override
125
			public String apply(final Entry<String, String> e) {
126
				try {
127
					final Document docFundingPath = reader.read(new StringReader(e.getValue()));
128

    
129
					final Element root = DocumentHelper.createElement("ROWS");
130

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

    
147
					addRow(root, "fundingpaths", fundingFields);
148

    
149
					if (log.isDebugEnabled()) {
150
						log.debug("Db entries: " + root.asXML());
151
					}
152

    
153
					return root.asXML();
154
				} catch (DocumentException e1) {
155
					log.error("Error parsing xml", e1);
156
					throw new RuntimeException("Error parsing xml", e1);
157
				}
158
			}
159

    
160
			private Map<String, String> findFunderInfo(final Document doc) {
161
				final Map<String, String> res = Maps.newLinkedHashMap();
162
				res.put("_dnet_resource_identifier_", doc.valueOf("//funder/id"));
163
				res.put("id", doc.valueOf("//funder/id"));
164
				res.put("legalshortname", doc.valueOf("//funder/shortname"));
165
				res.put("legalname", doc.valueOf("//funder/name"));
166
				return res;
167
			}
168

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

    
181
}
(4-4/8)