PageRenderTime 51ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/modules-legacy/prov-json/src/main/java/org/openprovenance/prov/json/JSONConstructor.java

http://github.com/lucmoreau/ProvToolbox
Java | 807 lines | 716 code | 66 blank | 25 comment | 198 complexity | 5223649b7c80e5df7fbd0907ea0caf6f MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0, GPL-3.0
  1. package org.openprovenance.prov.json;
  2. import java.util.ArrayList;
  3. import java.util.Collection;
  4. import java.util.HashMap;
  5. import java.util.Hashtable;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.net.URLDecoder;
  9. import javax.xml.namespace.QName;
  10. import javax.xml.datatype.XMLGregorianCalendar;
  11. import org.openprovenance.prov.model.Entry;
  12. import org.openprovenance.prov.model.Key;
  13. import org.openprovenance.prov.model.ActedOnBehalfOf;
  14. import org.openprovenance.prov.model.Activity;
  15. import org.openprovenance.prov.model.Agent;
  16. import org.openprovenance.prov.model.AlternateOf;
  17. import org.openprovenance.prov.model.Attribute;
  18. import org.openprovenance.prov.model.DerivedByInsertionFrom;
  19. import org.openprovenance.prov.model.DerivedByRemovalFrom;
  20. import org.openprovenance.prov.model.DictionaryMembership;
  21. import org.openprovenance.prov.model.Document;
  22. import org.openprovenance.prov.model.Entity;
  23. import org.openprovenance.prov.model.HadMember;
  24. import org.openprovenance.prov.model.LangString;
  25. import org.openprovenance.prov.model.MentionOf;
  26. import org.openprovenance.prov.model.ModelConstructor;
  27. import org.openprovenance.prov.model.ModelConstructorExtension;
  28. import org.openprovenance.prov.model.Name;
  29. import org.openprovenance.prov.model.Bundle;
  30. import org.openprovenance.prov.model.Namespace;
  31. import org.openprovenance.prov.model.QualifiedName;
  32. import org.openprovenance.prov.model.QualifiedNameUtils;
  33. import org.openprovenance.prov.model.SpecializationOf;
  34. import org.openprovenance.prov.model.Statement;
  35. import org.openprovenance.prov.model.Used;
  36. import org.openprovenance.prov.model.WasAssociatedWith;
  37. import org.openprovenance.prov.model.WasAttributedTo;
  38. import org.openprovenance.prov.model.WasDerivedFrom;
  39. import org.openprovenance.prov.model.WasEndedBy;
  40. import org.openprovenance.prov.model.WasGeneratedBy;
  41. import org.openprovenance.prov.model.WasInfluencedBy;
  42. import org.openprovenance.prov.model.WasInformedBy;
  43. import org.openprovenance.prov.model.WasInvalidatedBy;
  44. import org.openprovenance.prov.model.WasStartedBy;
  45. import org.openprovenance.prov.model.extension.QualifiedAlternateOf;
  46. import org.openprovenance.prov.model.extension.QualifiedHadMember;
  47. import org.openprovenance.prov.model.extension.QualifiedSpecializationOf;
  48. import org.openprovenance.prov.model.ProvUtilities.BuildFlag;
  49. /**
  50. * @author Trung Dong Huynh
  51. *
  52. * Constructing a JSON structure from a Document that
  53. * follows the PROV-JSON representation.
  54. *
  55. */
  56. public class JSONConstructor implements ModelConstructor, ModelConstructorExtension {
  57. private class JsonProvRecord {
  58. String type;
  59. String id;
  60. List<Object[]> attributes;
  61. public JsonProvRecord(String type, String id, List<Object[]> attributes) {
  62. this.type = type;
  63. this.id = id;
  64. this.attributes = attributes;
  65. }
  66. }
  67. private Namespace documentNamespace = null;
  68. private Namespace currentNamespace = null;
  69. private Map<String, Object> documentBundles = new HashMap<String, Object>();
  70. private List<JsonProvRecord> documentRecords = new ArrayList<JsonProvRecord>();
  71. private List<JsonProvRecord> currentRecords = documentRecords;
  72. final private Name name;
  73. public JSONConstructor(Name name) {
  74. this.name=name;
  75. }
  76. public Map<String, Object> getJSONStructure() {
  77. // Build the document-level structure
  78. Map<String, Object> document = getJSONStructure(documentRecords,
  79. documentNamespace);
  80. if (!documentBundles.isEmpty())
  81. document.put("bundle", documentBundles);
  82. return document;
  83. }
  84. public Map<String, Object> getJSONStructure(List<JsonProvRecord> records,
  85. Namespace namespace) {
  86. Map<String, Object> bundle = new HashMap<String, Object>();
  87. Hashtable<String, String> prefixes = new Hashtable<String, String>(namespace.getPrefixes());
  88. if (namespace.getDefaultNamespace() != null) {
  89. prefixes.put("default", namespace.getDefaultNamespace());
  90. }
  91. if (!prefixes.isEmpty())
  92. bundle.put("prefix", prefixes);
  93. for (Object o : records) {
  94. if (o == null)
  95. continue;
  96. JsonProvRecord record = (JsonProvRecord) o;
  97. String type = record.type;
  98. @SuppressWarnings("unchecked")
  99. Map<Object, Object> structure = (Map<Object, Object>) bundle.get(type);
  100. if (structure == null) {
  101. structure = new HashMap<Object, Object>();
  102. bundle.put(type, structure);
  103. }
  104. Map<Object, Object> hash = new HashMap<Object, Object>();
  105. List<Object[]> tuples = (List<Object[]>) record.attributes;
  106. for (Object[] tuple : tuples) {
  107. Object attribute = tuple[0];
  108. Object value = tuple[1];
  109. if (hash.containsKey(attribute)) {
  110. Object existing = hash.get(attribute);
  111. if (existing instanceof List) {
  112. // Already a multi-value attribute
  113. @SuppressWarnings("unchecked")
  114. List<Object> values = (List<Object>) existing;
  115. values.add(value);
  116. } else {
  117. // A multi-value list needs to be created
  118. List<Object> values = new ArrayList<Object>();
  119. values.add(existing);
  120. values.add(value);
  121. hash.put(attribute, values);
  122. }
  123. } else {
  124. hash.put(attribute, value);
  125. }
  126. }
  127. if (structure.containsKey(record.id)) {
  128. Object existing = structure.get(record.id);
  129. if (existing instanceof List) {
  130. @SuppressWarnings("unchecked")
  131. List<Object> values = (List<Object>) existing;
  132. values.add(hash);
  133. } else {
  134. // A multi-value list needs to be created
  135. List<Object> values = new ArrayList<Object>();
  136. values.add(existing);
  137. values.add(hash);
  138. structure.put(record.id, values);
  139. }
  140. } else
  141. structure.put(record.id, hash);
  142. }
  143. return bundle;
  144. }
  145. private static final Map<String, Integer> countMap = new HashMap<String, Integer>();
  146. private static String getBlankID(String type) {
  147. if (!countMap.containsKey(type)) {
  148. countMap.put(type, 0);
  149. }
  150. int count = countMap.get(type);
  151. count += 1;
  152. countMap.put(type, count);
  153. return "_:" + type + count;
  154. }
  155. private Object[] tuple(Object o1, Object o2) {
  156. Object[] tuple = { o1, o2 };
  157. return tuple;
  158. }
  159. static final QualifiedNameUtils qnU=new QualifiedNameUtils();
  160. public String qualifiedNameToString(Namespace namespace, QualifiedName id) {
  161. QName tmp;
  162. String prefix=id.getPrefix();
  163. String local=id.getLocalPart();
  164. if (prefix==null) {
  165. tmp=new QName(id.getNamespaceURI(),qnU.unescapeProvLocalName(local));
  166. } else {
  167. tmp=new QName(id.getNamespaceURI(),qnU.unescapeProvLocalName(local),prefix);
  168. }
  169. return namespace.qualifiedNameToString(tmp);
  170. }
  171. private Object typedLiteral(String value, String datatype, String lang) {
  172. // Converting default types to JSON primitives
  173. if (datatype == "xsd:string" && lang == null)
  174. return value;
  175. if (datatype == "xsd:double")
  176. return Double.parseDouble(value);
  177. if (datatype == "xsd:int")
  178. return Integer.parseInt(value);
  179. if (datatype == "xsd:boolean")
  180. return Boolean.parseBoolean(value);
  181. // Creating a typed literal structure
  182. Map<String, String> result = new HashMap<String, String>();
  183. result.put("$", value);
  184. if (datatype != null) {
  185. result.put("type", datatype);
  186. }
  187. if (lang != null) {
  188. result.put("lang", lang);
  189. }
  190. return result;
  191. }
  192. private String convertValueToString(Object value, Object convertedValue) {
  193. if (convertedValue instanceof String) {
  194. return (String) convertedValue;
  195. }
  196. if (convertedValue instanceof QualifiedName)
  197. return qualifiedNameToString(currentNamespace,(QualifiedName) convertedValue);
  198. if (convertedValue instanceof LangString) {
  199. LangString iStr = (LangString) convertedValue;
  200. return iStr.getValue();
  201. }
  202. if (convertedValue instanceof byte[]) {
  203. return (String) value;
  204. }
  205. return (String) value;
  206. }
  207. private Object convertTypedValue(Object value, QualifiedName type) {
  208. String datatype = qualifiedNameToString(currentNamespace,type);
  209. Object result;
  210. if (value instanceof QualifiedName) {
  211. result = typedLiteral(qualifiedNameToString(currentNamespace,(QualifiedName) value), datatype, null);
  212. }
  213. else if (value instanceof LangString) {
  214. LangString iStr = (LangString) value;
  215. String lang = iStr.getLang();
  216. if (lang != null) {
  217. // If 'lang' is defined
  218. result = typedLiteral(iStr.getValue(), null, lang);
  219. }
  220. else {
  221. // Otherwise, just return the string
  222. result = iStr.getValue();
  223. }
  224. }
  225. else {
  226. result = typedLiteral(value.toString(), datatype, null);
  227. }
  228. return result;
  229. }
  230. private Object[] convertAttribute(Attribute attr) {
  231. String attrName = qualifiedNameToString(currentNamespace,attr.getElementName());
  232. Object value = attr.getValue();
  233. QualifiedName type = attr.getType();
  234. Object attrValue = convertTypedValue(value, type);
  235. return tuple(attrName, attrValue);
  236. }
  237. private List<Object[]> convertAttributes(Collection<Attribute> attrs) {
  238. List<Object[]> result = new ArrayList<Object[]>();
  239. if (attrs != null)
  240. for (Attribute attr : attrs) {
  241. result.add(convertAttribute(attr));
  242. }
  243. return result;
  244. }
  245. @Override
  246. public Entity newEntity(QualifiedName id, Collection<Attribute> attributes) {
  247. List<Object[]> attrs = convertAttributes(attributes);
  248. JsonProvRecord record = new JsonProvRecord("entity",
  249. qualifiedNameToString(currentNamespace,id),
  250. attrs);
  251. this.currentRecords.add(record);
  252. return null;
  253. }
  254. @Override
  255. public Activity newActivity(QualifiedName id, XMLGregorianCalendar startTime,
  256. XMLGregorianCalendar endTime,
  257. Collection<Attribute> attributes) {
  258. List<Object[]> attrs = convertAttributes(attributes);
  259. if (startTime != null) {
  260. attrs.add(tuple("prov:startTime", startTime.toXMLFormat()));
  261. }
  262. if (endTime != null) {
  263. attrs.add(tuple("prov:endTime", endTime.toXMLFormat()));
  264. }
  265. JsonProvRecord record = new JsonProvRecord("activity",
  266. qualifiedNameToString(currentNamespace,id),
  267. attrs);
  268. this.currentRecords.add(record);
  269. return null;
  270. }
  271. @Override
  272. public Agent newAgent(QualifiedName id, Collection<Attribute> attributes) {
  273. List<Object[]> attrs = convertAttributes(attributes);
  274. JsonProvRecord record = new JsonProvRecord("agent",
  275. qualifiedNameToString(currentNamespace,id),
  276. attrs);
  277. this.currentRecords.add(record);
  278. return null;
  279. }
  280. @Override
  281. public Used newUsed(QualifiedName id, QualifiedName activity, QualifiedName entity,
  282. XMLGregorianCalendar time,
  283. Collection<Attribute> attributes) {
  284. List<Object[]> attrs = convertAttributes(attributes);
  285. if (activity != null)
  286. attrs.add(tuple("prov:activity", qualifiedNameToString(currentNamespace,activity)));
  287. if (entity != null)
  288. attrs.add(tuple("prov:entity", qualifiedNameToString(currentNamespace,entity)));
  289. if (time != null)
  290. attrs.add(tuple("prov:time", time.toXMLFormat()));
  291. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  292. : getBlankID("u");
  293. JsonProvRecord record = new JsonProvRecord("used", recordID, attrs);
  294. this.currentRecords.add(record);
  295. return null;
  296. }
  297. @Override
  298. public WasGeneratedBy newWasGeneratedBy(QualifiedName id, QualifiedName entity,
  299. QualifiedName activity,
  300. XMLGregorianCalendar time,
  301. Collection<Attribute> attributes) {
  302. List<Object[]> attrs = convertAttributes(attributes);
  303. if (entity != null)
  304. attrs.add(tuple("prov:entity", qualifiedNameToString(currentNamespace,entity)));
  305. if (activity != null)
  306. attrs.add(tuple("prov:activity", qualifiedNameToString(currentNamespace,activity)));
  307. if (time != null)
  308. attrs.add(tuple("prov:time", time.toXMLFormat()));
  309. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  310. : getBlankID("wGB");
  311. JsonProvRecord record = new JsonProvRecord("wasGeneratedBy", recordID,
  312. attrs);
  313. this.currentRecords.add(record);
  314. return null;
  315. }
  316. @Override
  317. public WasInvalidatedBy newWasInvalidatedBy(QualifiedName id,
  318. QualifiedName entity,
  319. QualifiedName activity,
  320. XMLGregorianCalendar time,
  321. Collection<Attribute> attributes) {
  322. List<Object[]> attrs = convertAttributes(attributes);
  323. if (entity != null)
  324. attrs.add(tuple("prov:entity", qualifiedNameToString(currentNamespace,entity)));
  325. if (activity != null)
  326. attrs.add(tuple("prov:activity", qualifiedNameToString(currentNamespace,activity)));
  327. if (time != null)
  328. attrs.add(tuple("prov:time", time.toXMLFormat()));
  329. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  330. : getBlankID("wIB");
  331. JsonProvRecord record = new JsonProvRecord("wasInvalidatedBy",
  332. recordID, attrs);
  333. this.currentRecords.add(record);
  334. return null;
  335. }
  336. @Override
  337. public WasStartedBy newWasStartedBy(QualifiedName id, QualifiedName activity,
  338. QualifiedName trigger, QualifiedName starter,
  339. XMLGregorianCalendar time,
  340. Collection<Attribute> attributes) {
  341. List<Object[]> attrs = convertAttributes(attributes);
  342. if (activity != null)
  343. attrs.add(tuple("prov:activity", qualifiedNameToString(currentNamespace,activity)));
  344. if (trigger != null)
  345. attrs.add(tuple("prov:trigger", qualifiedNameToString(currentNamespace,trigger)));
  346. if (starter != null)
  347. attrs.add(tuple("prov:starter", qualifiedNameToString(currentNamespace,starter)));
  348. if (time != null)
  349. attrs.add(tuple("prov:time", time.toXMLFormat()));
  350. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  351. : getBlankID("wSB");
  352. JsonProvRecord record = new JsonProvRecord("wasStartedBy", recordID,
  353. attrs);
  354. this.currentRecords.add(record);
  355. return null;
  356. }
  357. @Override
  358. public WasEndedBy newWasEndedBy(QualifiedName id, QualifiedName activity, QualifiedName trigger,
  359. QualifiedName ender, XMLGregorianCalendar time,
  360. Collection<Attribute> attributes) {
  361. List<Object[]> attrs = convertAttributes(attributes);
  362. if (activity != null)
  363. attrs.add(tuple("prov:activity", qualifiedNameToString(currentNamespace,activity)));
  364. if (trigger != null)
  365. attrs.add(tuple("prov:trigger", qualifiedNameToString(currentNamespace,trigger)));
  366. if (ender != null)
  367. attrs.add(tuple("prov:ender", qualifiedNameToString(currentNamespace,ender)));
  368. if (time != null)
  369. attrs.add(tuple("prov:time", time.toXMLFormat()));
  370. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  371. : getBlankID("wEB");
  372. JsonProvRecord record = new JsonProvRecord("wasEndedBy", recordID,
  373. attrs);
  374. this.currentRecords.add(record);
  375. return null;
  376. }
  377. @Override
  378. public WasDerivedFrom newWasDerivedFrom(QualifiedName id, QualifiedName e2, QualifiedName e1,
  379. QualifiedName activity, QualifiedName generation,
  380. QualifiedName usage,
  381. Collection<Attribute> attributes) {
  382. List<Object[]> attrs = convertAttributes(attributes);
  383. if (e2 != null)
  384. attrs.add(tuple("prov:generatedEntity", qualifiedNameToString(currentNamespace,e2)));
  385. if (e1 != null)
  386. attrs.add(tuple("prov:usedEntity", qualifiedNameToString(currentNamespace,e1)));
  387. if (activity != null)
  388. attrs.add(tuple("prov:activity", qualifiedNameToString(currentNamespace,activity)));
  389. if (generation != null)
  390. attrs.add(tuple("prov:generation",
  391. qualifiedNameToString(currentNamespace,generation)));
  392. if (usage != null)
  393. attrs.add(tuple("prov:usage", qualifiedNameToString(currentNamespace,usage)));
  394. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  395. : getBlankID("wDF");
  396. JsonProvRecord record = new JsonProvRecord("wasDerivedFrom", recordID,
  397. attrs);
  398. this.currentRecords.add(record);
  399. return null;
  400. }
  401. @Override
  402. public WasAssociatedWith newWasAssociatedWith(QualifiedName id,
  403. QualifiedName a,
  404. QualifiedName ag,
  405. QualifiedName plan,
  406. Collection<Attribute> attributes) {
  407. List<Object[]> attrs = convertAttributes(attributes);
  408. if (a != null)
  409. attrs.add(tuple("prov:activity", qualifiedNameToString(currentNamespace,a)));
  410. if (ag != null)
  411. attrs.add(tuple("prov:agent", qualifiedNameToString(currentNamespace,ag)));
  412. if (plan != null)
  413. attrs.add(tuple("prov:plan", qualifiedNameToString(currentNamespace,plan)));
  414. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  415. : getBlankID("wAW");
  416. JsonProvRecord record = new JsonProvRecord("wasAssociatedWith",
  417. recordID, attrs);
  418. this.currentRecords.add(record);
  419. return null;
  420. }
  421. @Override
  422. public WasAttributedTo newWasAttributedTo(QualifiedName id, QualifiedName e, QualifiedName ag,
  423. Collection<Attribute> attributes) {
  424. List<Object[]> attrs = convertAttributes(attributes);
  425. if (e != null)
  426. attrs.add(tuple("prov:entity", qualifiedNameToString(currentNamespace,e)));
  427. if (ag != null)
  428. attrs.add(tuple("prov:agent", qualifiedNameToString(currentNamespace,ag)));
  429. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  430. : getBlankID("wAT");
  431. JsonProvRecord record = new JsonProvRecord("wasAttributedTo", recordID,
  432. attrs);
  433. this.currentRecords.add(record);
  434. return null;
  435. }
  436. @Override
  437. public ActedOnBehalfOf newActedOnBehalfOf(QualifiedName id, QualifiedName ag2, QualifiedName ag1,
  438. QualifiedName a,
  439. Collection<Attribute> attributes) {
  440. List<Object[]> attrs = convertAttributes(attributes);
  441. if (ag2 != null)
  442. attrs.add(tuple("prov:delegate", qualifiedNameToString(currentNamespace,ag2)));
  443. if (ag1 != null)
  444. attrs.add(tuple("prov:responsible", qualifiedNameToString(currentNamespace,ag1)));
  445. if (a != null)
  446. attrs.add(tuple("prov:activity", qualifiedNameToString(currentNamespace,a)));
  447. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  448. : getBlankID("aOBO");
  449. JsonProvRecord record = new JsonProvRecord("actedOnBehalfOf", recordID,
  450. attrs);
  451. this.currentRecords.add(record);
  452. return null;
  453. }
  454. @Override
  455. public WasInformedBy newWasInformedBy(QualifiedName id, QualifiedName a2, QualifiedName a1,
  456. Collection<Attribute> attributes) {
  457. List<Object[]> attrs = convertAttributes(attributes);
  458. if (a2 != null)
  459. attrs.add(tuple("prov:informed", qualifiedNameToString(currentNamespace,a2)));
  460. if (a1 != null)
  461. attrs.add(tuple("prov:informant", qualifiedNameToString(currentNamespace,a1)));
  462. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  463. : getBlankID("Infm");
  464. JsonProvRecord record = new JsonProvRecord("wasInformedBy", recordID,
  465. attrs);
  466. this.currentRecords.add(record);
  467. return null;
  468. }
  469. @Override
  470. public WasInfluencedBy newWasInfluencedBy(QualifiedName id, QualifiedName a2, QualifiedName a1,
  471. Collection<Attribute> attributes) {
  472. List<Object[]> attrs = convertAttributes(attributes);
  473. if (a2 != null)
  474. attrs.add(tuple("prov:influencee", qualifiedNameToString(currentNamespace,a2)));
  475. if (a1 != null)
  476. attrs.add(tuple("prov:influencer", qualifiedNameToString(currentNamespace,a1)));
  477. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  478. : getBlankID("Infl");
  479. JsonProvRecord record = new JsonProvRecord("wasInfluencedBy", recordID,
  480. attrs);
  481. this.currentRecords.add(record);
  482. return null;
  483. }
  484. @Override
  485. public AlternateOf newAlternateOf(QualifiedName e1, QualifiedName e2) {
  486. List<Object[]> attrs = new ArrayList<Object[]>();
  487. if (e2 != null)
  488. attrs.add(tuple("prov:alternate2", qualifiedNameToString(currentNamespace,e2)));
  489. if (e1 != null)
  490. attrs.add(tuple("prov:alternate1", qualifiedNameToString(currentNamespace,e1)));
  491. String recordID = getBlankID("aO");
  492. JsonProvRecord record = new JsonProvRecord("alternateOf", recordID,
  493. attrs);
  494. this.currentRecords.add(record);
  495. return null;
  496. }
  497. @Override
  498. public SpecializationOf newSpecializationOf(QualifiedName e2, QualifiedName e1) {
  499. List<Object[]> attrs = new ArrayList<Object[]>();
  500. if (e2 != null)
  501. attrs.add(tuple("prov:specificEntity", qualifiedNameToString(currentNamespace,e2)));
  502. if (e1 != null)
  503. attrs.add(tuple("prov:generalEntity", qualifiedNameToString(currentNamespace,e1)));
  504. String recordID = getBlankID("sO");
  505. JsonProvRecord record = new JsonProvRecord("specializationOf",
  506. recordID, attrs);
  507. this.currentRecords.add(record);
  508. return null;
  509. }
  510. @Override
  511. public MentionOf newMentionOf(QualifiedName e2, QualifiedName e1, QualifiedName b) {
  512. List<Object[]> attrs = new ArrayList<Object[]>();
  513. if (e2 != null)
  514. attrs.add(tuple("prov:specificEntity", qualifiedNameToString(currentNamespace,e2)));
  515. if (e1 != null)
  516. attrs.add(tuple("prov:generalEntity", qualifiedNameToString(currentNamespace,e1)));
  517. if (b != null)
  518. attrs.add(tuple("prov:bundle", qualifiedNameToString(currentNamespace,b)));
  519. String recordID = getBlankID("mO");
  520. JsonProvRecord record = new JsonProvRecord("mentionOf", recordID, attrs);
  521. this.currentRecords.add(record);
  522. return null;
  523. }
  524. @Override
  525. public HadMember newHadMember(QualifiedName c, Collection<QualifiedName> e) {
  526. List<Object[]> attrs = new ArrayList<Object[]>();
  527. if (c != null)
  528. attrs.add(tuple("prov:collection", qualifiedNameToString(currentNamespace,c)));
  529. if (e != null && !e.isEmpty()) {
  530. List<String> entityList = new ArrayList<String>();
  531. for (QualifiedName entity : e)
  532. entityList.add(qualifiedNameToString(currentNamespace,entity));
  533. attrs.add(tuple("prov:entity", entityList));
  534. }
  535. String recordID = getBlankID("hM");
  536. JsonProvRecord record = new JsonProvRecord("hadMember", recordID, attrs);
  537. this.currentRecords.add(record);
  538. return null;
  539. }
  540. @Override
  541. public Document newDocument(Namespace namespaces,
  542. Collection<Statement> statements,
  543. Collection<Bundle> bundles) {
  544. // This class only collect statements into a structure ready for JSON conversion
  545. // No new document will be returned
  546. return null;
  547. }
  548. @Override
  549. public Bundle newNamedBundle(QualifiedName id, Namespace namespaces,
  550. Collection<Statement> statements) {
  551. Object bundle = getJSONStructure(currentRecords, currentNamespace);
  552. documentBundles.put(qualifiedNameToString(currentNamespace,id), bundle);
  553. // Reset to document-level records and namespaces
  554. currentRecords = documentRecords;
  555. currentNamespace = documentNamespace;
  556. return null;
  557. }
  558. @Override
  559. public void startDocument(Namespace namespace) {
  560. documentNamespace = namespace;
  561. currentNamespace = documentNamespace;
  562. }
  563. @Override
  564. public void startBundle(QualifiedName bundleId, Namespace namespaces) {
  565. currentNamespace = namespaces;
  566. // Create a new, separate list of records for the bundle
  567. currentRecords = new ArrayList<JsonProvRecord>();
  568. }
  569. private Object encodeKeyEntitySet(List<Entry> keyEntitySet) {
  570. // Check for the types of keys
  571. boolean isAllKeyOfSameDatatype = true;
  572. Key firstKey = keyEntitySet.get(0).getKey();
  573. QualifiedName firstKeyClass = firstKey.getType();
  574. if (name.PROV_LANG_STRING.equals(firstKeyClass)) {
  575. // LangString cannot be encoded in the compact form
  576. isAllKeyOfSameDatatype=false;
  577. }
  578. if (isAllKeyOfSameDatatype) {
  579. for (Entry pair : keyEntitySet) {
  580. QualifiedName keyClass = pair.getKey().getType();
  581. if (keyClass != firstKeyClass) {
  582. isAllKeyOfSameDatatype = false;
  583. break;
  584. }
  585. }
  586. }
  587. if (isAllKeyOfSameDatatype) {
  588. // encode as a dictionary
  589. Map<Object, String> dictionary = new HashMap<Object, String>();
  590. String keyDatatype = qualifiedNameToString(currentNamespace,keyEntitySet.get(0).getKey().getType());
  591. // TODO This does not conform with PROV-JSON !!!
  592. dictionary.put("$key-datatype", keyDatatype);
  593. for (Entry pair : keyEntitySet) {
  594. // String key = convertValueToString(pair.key);
  595. String key = convertValueToString(pair.getKey().getValue(), pair.getKey().getConvertedValue());
  596. String entity = qualifiedNameToString(currentNamespace,pair.getEntity());
  597. dictionary.put(key, entity);
  598. }
  599. return dictionary;
  600. }
  601. // encode as a generic list of key-value pairs
  602. List<Map<String, Object>> values = new ArrayList<Map<String, Object>>(
  603. keyEntitySet.size());
  604. for (Entry pair : keyEntitySet) {
  605. Object entity = qualifiedNameToString(currentNamespace,pair.getEntity());
  606. Map<String, Object> item = new Hashtable<String, Object>();
  607. item.put("$", entity);
  608. Key key = pair.getKey();
  609. item.put("key", convertTypedValue(key.getValue(), key.getType()));
  610. values.add(item);
  611. }
  612. return values;
  613. }
  614. @Override
  615. public DerivedByInsertionFrom newDerivedByInsertionFrom(QualifiedName id,
  616. QualifiedName after,
  617. QualifiedName before,
  618. List<Entry> keyEntitySet,
  619. Collection<Attribute> attributes) {
  620. List<Object[]> attrs = convertAttributes(attributes);
  621. if (after != null)
  622. attrs.add(tuple("prov:after", qualifiedNameToString(currentNamespace,after)));
  623. if (before != null)
  624. attrs.add(tuple("prov:before", qualifiedNameToString(currentNamespace,before)));
  625. if (keyEntitySet != null && !keyEntitySet.isEmpty()) {
  626. attrs.add(tuple("prov:key-entity-set",
  627. encodeKeyEntitySet(keyEntitySet)));
  628. }
  629. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  630. : getBlankID("dBIF");
  631. JsonProvRecord record = new JsonProvRecord("derivedByInsertionFrom",
  632. recordID, attrs);
  633. this.currentRecords.add(record);
  634. return null;
  635. }
  636. @Override
  637. public DerivedByRemovalFrom newDerivedByRemovalFrom(QualifiedName id,
  638. QualifiedName after,
  639. QualifiedName before,
  640. List<Key> keys,
  641. Collection<Attribute> attributes) {
  642. List<Object[]> attrs = convertAttributes(attributes);
  643. if (after != null)
  644. attrs.add(tuple("prov:after", qualifiedNameToString(currentNamespace,after)));
  645. if (before != null)
  646. attrs.add(tuple("prov:before", qualifiedNameToString(currentNamespace,before)));
  647. if (keys != null && !keys.isEmpty()) {
  648. List<Object> values = new ArrayList<Object>(keys.size());
  649. for (Key key : keys) {
  650. values.add(convertTypedValue(key.getValue(), key.getType()));
  651. }
  652. attrs.add(tuple("prov:key-set", values));
  653. }
  654. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  655. : getBlankID("dBRF");
  656. JsonProvRecord record = new JsonProvRecord("derivedByRemovalFrom",
  657. recordID, attrs);
  658. this.currentRecords.add(record);
  659. return null;
  660. }
  661. @Override
  662. public DictionaryMembership newDictionaryMembership(QualifiedName dict,
  663. List<Entry> keyEntitySet) {
  664. List<Object[]> attrs = new ArrayList<Object[]>();
  665. if (dict != null)
  666. attrs.add(tuple("prov:dictionary", qualifiedNameToString(currentNamespace,dict)));
  667. if (keyEntitySet != null && !keyEntitySet.isEmpty()) {
  668. attrs.add(tuple("prov:key-entity-set",
  669. encodeKeyEntitySet(keyEntitySet)));
  670. }
  671. String recordID = getBlankID("hDM");
  672. JsonProvRecord record = new JsonProvRecord("hadDictionaryMember",
  673. recordID, attrs);
  674. this.currentRecords.add(record);
  675. return null;
  676. }
  677. @Override
  678. public QualifiedName newQualifiedName(String namespace, String local,
  679. String prefix) {
  680. return null;
  681. }
  682. @Override
  683. public QualifiedName newQualifiedName(String namespace, String local,
  684. String prefix, BuildFlag flag) {
  685. return null;
  686. }
  687. @Override
  688. public QualifiedAlternateOf newQualifiedAlternateOf(QualifiedName id,
  689. QualifiedName e2,
  690. QualifiedName e1,
  691. Collection<Attribute> attributes) {
  692. List<Object[]> attrs = convertAttributes(attributes);
  693. if (e2 != null)
  694. attrs.add(tuple("prov:alternate2", qualifiedNameToString(currentNamespace,e2)));
  695. if (e1 != null)
  696. attrs.add(tuple("prov:alternate1", qualifiedNameToString(currentNamespace,e1)));
  697. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  698. : getBlankID("a0");
  699. JsonProvRecord record = new JsonProvRecord("provext:alternateOf", recordID,
  700. attrs);
  701. this.currentRecords.add(record);
  702. return null;
  703. }
  704. @Override
  705. public QualifiedSpecializationOf newQualifiedSpecializationOf(QualifiedName id,
  706. QualifiedName e2,
  707. QualifiedName e1,
  708. Collection<Attribute> attributes) {
  709. List<Object[]> attrs = convertAttributes(attributes);
  710. if (e2 != null)
  711. attrs.add(tuple("prov:specificEntity", qualifiedNameToString(currentNamespace,e2)));
  712. if (e1 != null)
  713. attrs.add(tuple("prov:generalEntity", qualifiedNameToString(currentNamespace,e1)));
  714. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  715. : getBlankID("s0");
  716. JsonProvRecord record = new JsonProvRecord("provext:specializationOf",
  717. recordID, attrs);
  718. this.currentRecords.add(record);
  719. return null;
  720. }
  721. @Override
  722. public QualifiedHadMember newQualifiedHadMember(QualifiedName id,
  723. QualifiedName c,
  724. Collection<QualifiedName> e,
  725. Collection<Attribute> attributes) {
  726. List<Object[]> attrs = convertAttributes(attributes);
  727. if (c != null)
  728. attrs.add(tuple("prov:collection", qualifiedNameToString(currentNamespace,c)));
  729. if (e != null && !e.isEmpty()) {
  730. List<String> entityList = new ArrayList<String>();
  731. for (QualifiedName entity : e)
  732. entityList.add(qualifiedNameToString(currentNamespace,entity));
  733. attrs.add(tuple("prov:entity", entityList));
  734. }
  735. String recordID = (id != null) ? qualifiedNameToString(currentNamespace,id)
  736. : getBlankID("hM");
  737. JsonProvRecord record = new JsonProvRecord("provext:hadMember", recordID, attrs);
  738. this.currentRecords.add(record);
  739. return null;
  740. }
  741. }