1 |
41483
|
claudio.at
|
package eu.dnetlib.msro.openaireplus.workflows.nodes.contexts;
|
2 |
|
|
|
3 |
|
|
import java.io.StringReader;
|
4 |
48139
|
alessia.ba
|
import java.lang.reflect.Type;
|
5 |
41483
|
claudio.at
|
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 |
48139
|
alessia.ba
|
import com.google.common.reflect.TypeToken;
|
11 |
|
|
import com.google.gson.Gson;
|
12 |
41483
|
claudio.at
|
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 |
51999
|
alessia.ba
|
private static final String DASHBOARD_VISIBILITY = "status";
|
25 |
41483
|
claudio.at
|
|
26 |
48139
|
alessia.ba
|
public static ContextDesc getContext(final Iterable<String> it,
|
27 |
|
|
final String contextId,
|
28 |
|
|
final String contextLabel,
|
29 |
|
|
final String contextType,
|
30 |
51999
|
alessia.ba
|
final String params, final String dashboardVisibility) throws
|
31 |
41483
|
claudio.at
|
DocumentException {
|
32 |
|
|
|
33 |
51999
|
alessia.ba
|
final Map<String, String> paramMap = getParamMap(params);
|
34 |
|
|
paramMap.put(DASHBOARD_VISIBILITY, dashboardVisibility);
|
35 |
|
|
return new ContextUtils().getContextDesc(it, contextId, contextLabel, contextType, paramMap);
|
36 |
41483
|
claudio.at
|
}
|
37 |
|
|
|
38 |
48139
|
alessia.ba
|
private static Map<String, String> getParamMap(String jsonMap) {
|
39 |
|
|
Map<String, String> paramMap = Maps.newHashMap();
|
40 |
51999
|
alessia.ba
|
|
41 |
48139
|
alessia.ba
|
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 |
41483
|
claudio.at
|
|
49 |
48139
|
alessia.ba
|
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 |
41483
|
claudio.at
|
DocumentException {
|
55 |
48139
|
alessia.ba
|
final ContextDesc context = new ContextDesc(contextId, contextLabel, contextType, params);
|
56 |
41483
|
claudio.at
|
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 |
41703
|
claudio.at
|
final String funder = treeNode.valueOf("./funder/id");
|
71 |
48139
|
alessia.ba
|
if (StringUtils.isBlank(funder)) {
|
72 |
|
|
log.debug("No funder found, skipping population from the following XML: \n" + s);
|
73 |
43167
|
alessia.ba
|
return;
|
74 |
|
|
}
|
75 |
41483
|
claudio.at
|
if (!context.getDbEntries().containsKey(funder)) {
|
76 |
41485
|
claudio.at
|
log.info("Found funder: " + funder);
|
77 |
48139
|
alessia.ba
|
context.getDbEntries().put(funder, "<fundingtree>" + treeNode.selectSingleNode("./funder").asXML() + "</fundingtree>");
|
78 |
41703
|
claudio.at
|
log.debug("db entry: " + context.getDbEntries().get(funder));
|
79 |
41483
|
claudio.at
|
}
|
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 |
41703
|
claudio.at
|
log.debug("db entry: " + context.getDbEntries().get(openaireId));
|
86 |
41483
|
claudio.at
|
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 |
48139
|
alessia.ba
|
context.getCategories().get(part.getId()).addPart(p);
|
92 |
41483
|
claudio.at
|
}
|
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 |
41486
|
claudio.at
|
private final SAXReader reader = new SAXReader();
|
127 |
|
|
|
128 |
41483
|
claudio.at
|
@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 |
52343
|
alessia.ba
|
addRow(root, "dsm_organizations", orgFields);
|
148 |
41483
|
claudio.at
|
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 |
57679
|
alessia.ba
|
res.put("country", doc.valueOf("//funder/jurisdiction"));
|
171 |
41483
|
claudio.at
|
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 |
|
|
}
|