Permalink
Browse files

Fixed: Namespace management in PROV-JSON export/import

  • Loading branch information...
1 parent 9eea8df commit 0e61615f0fa8ab2fa355e5c194cb8a65239acdd9 @trungdong trungdong committed Mar 31, 2014
@@ -34,6 +34,7 @@ public Converter (ProvFactory pFactory) {
}
+ @SuppressWarnings("unchecked")
public Document readDocument(String file) throws JsonSyntaxException, JsonIOException, FileNotFoundException {
Document doc = (Document) gson.fromJson(new BufferedReader(new FileReader(file)), class1);
return doc;
@@ -44,5 +45,14 @@ public void writeDocument(Document doc, String file) throws IOException {
gson.toJson(doc, writer);
writer.close();
}
+
+ public String getString(Document doc) {
+ return gson.toJson(doc);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Document fromString(String jsonStr) {
+ return (Document) gson.fromJson(jsonStr, class1);
+ }
}

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -59,7 +59,9 @@
*
*/
public class ProvDocumentDeserializer implements JsonDeserializer<Document> {
- Namespace ns;
+ Namespace documentNamespace;
+ Namespace currentNamespace;
+
private static final String PROV_JSON_PREFIX = "prefix";
@@ -83,43 +85,38 @@ public Document deserialize(JsonElement json, Type typeOfT,
JsonObject provJSONDoc = json.getAsJsonObject();
// Initialise namespaces
- Hashtable<String, String> namespaces = decodePrefixes(provJSONDoc);
-
- ns = new Namespace();
- // prefixes prov and xsd are implicit in prov-json
- ns.addKnownNamespaces();
- if (namespaces != null) {
- for (String prefix : namespaces.keySet()) {
- String aNamespace = namespaces.get(prefix);
- if (prefix.equals("default")) {
- ns.registerDefault(aNamespace);
- } else {
- ns.register(prefix, aNamespace);
- }
- }
- }
+ currentNamespace = decodePrefixes(provJSONDoc);
+ documentNamespace = currentNamespace;
// Decoding structures
List<StatementOrBundle> statements = decodeBundle(provJSONDoc);
// Create the document
Document doc = pf.newDocument();
- doc.setNamespace(ns);
+ doc.setNamespace(currentNamespace);
doc.getStatementOrBundle().addAll(statements);
return doc;
}
- private Hashtable<String, String> decodePrefixes(JsonObject bundleStructure) {
- Hashtable<String, String> namespaces = new Hashtable<String, String>();
+ private Namespace decodePrefixes(JsonObject bundleStructure) {
+ Namespace ns = new Namespace();
+ // prefixes prov and xsd are implicit in prov-json
+ ns.addKnownNamespaces();
JsonObject prefixes = getObjectAndRemove(bundleStructure,
PROV_JSON_PREFIX);
if (prefixes != null) {
- for (Map.Entry<String, JsonElement> pair : prefixes.entrySet())
- namespaces.put(pair.getKey(), pair.getValue().getAsString());
- return namespaces;
- } else
- return null;
+ for (Map.Entry<String, JsonElement> pair : prefixes.entrySet()) {
+ String prefix = pair.getKey();
+ String uri = pair.getValue().getAsString();
+ if (prefix.equals("default")) {
+ ns.registerDefault(uri);
+ } else {
+ ns.register(prefix, uri);
+ }
+ }
+ }
+ return ns;
}
private List<StatementOrBundle> decodeBundle(JsonObject bundleStructure) {
@@ -169,7 +166,7 @@ private StatementOrBundle decodeStatement(String statementType,
// Ignore all blank node IDs
id = null;
} else {
- id = ns.stringToQualifiedName(idStr,pf);
+ id = currentNamespace.stringToQualifiedName(idStr, pf);
}
// Decoding attributes
ProvJSONStatement provStatement = ProvJSONStatement.valueOf(statementType);
@@ -214,17 +211,19 @@ private StatementOrBundle decodeStatement(String statementType,
statement = pf.newWasAttributedTo(id, entity, agent);
break;
case bundle:
- @SuppressWarnings("unused")
- Hashtable<String, String> localNamespaces = decodePrefixes(attributeMap);
- // TODO: Use the local namespace while preserving the top-level
- // namespace
+ currentNamespace = decodePrefixes(attributeMap);
+ currentNamespace.setParent(documentNamespace);
+ // Re-resolve the bundle's id with the bundle's namespace
+ id = currentNamespace.stringToQualifiedName(idStr, pf);
@SuppressWarnings("rawtypes")
Collection statements = decodeBundle(attributeMap);
NamedBundle namedBundle = pf.getObjectFactory().createNamedBundle();
namedBundle.setId(id);
namedBundle.getStatement()
.addAll((Collection<? extends Statement>) statements);
statement = namedBundle;
+ // Restore the document's namespace as the current one
+ currentNamespace = documentNamespace;
break;
case wasInformedBy:
QualifiedName informed = optionalQualifiedName("prov:informed", attributeMap);
@@ -473,7 +472,7 @@ private StatementOrBundle decodeStatement(String statementType,
List ll = ((HasOther) statement).getOther();
List<Attribute> attributes = (List<Attribute>) ll;
for (Map.Entry<String, JsonElement> aPair : attributeMap.entrySet()) {
- QualifiedName attributeName = ns.stringToQualifiedName(aPair.getKey(),pf);
+ QualifiedName attributeName = currentNamespace.stringToQualifiedName(aPair.getKey(),pf);
JsonElement element = aPair.getValue();
values = pickMultiValues(element);
for (JsonElement value : values) {
@@ -524,18 +523,18 @@ private Attribute decodeAttributeValue(JsonElement element, QualifiedName elemen
// Internationalized strings
String lang = struct.get("lang").getAsString();
LangString iString = pf.getObjectFactory()
- .createInternationalizedString();
+ .createInternationalizedString();
iString.setValue(value);
iString.setLang(lang);
return pf.newAttribute(elementName,
iString,
name.PROV_LANG_STRING);
} else if (struct.has("type")) {
String datatypeAsString = struct.get("type").getAsString();
- QualifiedName xsdType = ns.stringToQualifiedName(datatypeAsString, pf);
- if (xsdType.equals(name.XSD_QNAME)) {
+ QualifiedName xsdType = currentNamespace.stringToQualifiedName(datatypeAsString, pf);
+ if (xsdType.equals(name.XSD_QNAME) || xsdType.equals(name.PROV_QUALIFIED_NAME)) {
return pf.newAttribute(elementName,
- ns.stringToQualifiedName(value,pf), xsdType);
+ currentNamespace.stringToQualifiedName(value,pf), xsdType);
} else {
return pf.newAttribute(elementName, value, xsdType);
}
@@ -604,15 +603,15 @@ private String popString(JsonObject jo, String memberName) {
private QualifiedName qualifiedName(String attributeName, JsonObject attributeMap) {
- return ns.stringToQualifiedName(popString(attributeMap,
- attributeName),
- pf);
+ return currentNamespace.stringToQualifiedName(popString(attributeMap,
+ attributeName),
+ pf);
}
// TODO: this name is legacy, what should it be?
private QualifiedName anyRef(String attributeName, JsonObject attributeMap) {
if (attributeMap.has(attributeName))
- return ns.stringToQualifiedName(popString(attributeMap,
+ return currentNamespace.stringToQualifiedName(popString(attributeMap,
attributeName),
pf);
else
@@ -642,7 +641,7 @@ private XMLGregorianCalendar optionalTime(String attributeName,
List<JsonElement> elements = popMultiValAttribute(attributeName,
attributeMap);
for (JsonElement element : elements) {
- results.add(ns.stringToQualifiedName(element.getAsString(),pf));
+ results.add(currentNamespace.stringToQualifiedName(element.getAsString(),pf));
}
return results;
}
@@ -668,7 +667,7 @@ private XMLGregorianCalendar optionalTime(String attributeName,
Entry pair = pf.newEntry((Key) decodeAttributeValue(item.remove("key"),
name.PROV_KEY),
- ns.stringToQualifiedName(this.popString(item, "$"),pf));
+ currentNamespace.stringToQualifiedName(this.popString(item, "$"),pf));
results.add(pair);
}
} else if (kESElement.isJsonObject()) {
@@ -677,7 +676,7 @@ private XMLGregorianCalendar optionalTime(String attributeName,
// TODO This does not conform with PROV-JSON !!!
String keyDatatype = dictionary.remove("$key-datatype")
.getAsString();
- QualifiedName datatype = ns.stringToQualifiedName(keyDatatype,pf);
+ QualifiedName datatype = currentNamespace.stringToQualifiedName(keyDatatype,pf);
for (Map.Entry<String, JsonElement> entry : dictionary.entrySet()) {
String entryKey = entry.getKey();
JsonElement entryValue = entry.getValue();
@@ -698,14 +697,14 @@ public Entry decodeDictionaryEntry(QualifiedName datatype,
Key kk;
if (datatype.equals(name.XSD_QNAME)) {
kk=(Key) pf.newAttribute(name.PROV_KEY,
- ns.stringToQualifiedName(entryKey,pf), datatype);
+ currentNamespace.stringToQualifiedName(entryKey,pf), datatype);
} else {
kk=(Key) pf.newAttribute(name.PROV_KEY, entryKey, datatype);
}
Entry pair = pf.newEntry(kk,
- ns.stringToQualifiedName(entryValue.getAsString(), pf));
+ currentNamespace.stringToQualifiedName(entryValue.getAsString(), pf));
return pair;
}
@@ -23,13 +23,7 @@ public ProvDocumentSerializer(ProvFactory pFactory) {
public JsonElement serialize(final Document doc,
Type typeOfSrc,
JsonSerializationContext context) {
- QualifiedNameExport qExport = new QualifiedNameExport() {
- @Override
- public String qualifiedNameToString(QualifiedName qname) {
- return doc.getNamespace().qualifiedNameToString(qname);
- }
- };
- JSONConstructor jsonConstructor = new JSONConstructor(qExport, pFactory.getName());
+ JSONConstructor jsonConstructor = new JSONConstructor(pFactory.getName());
BeanTraversal bt = new BeanTraversal(jsonConstructor,
pFactory);
bt.convert(doc);
@@ -9,7 +9,7 @@
public Name(ProvFactory pFactory) {
this.pFactory=pFactory;
PROV_LANG_STRING = newProvQualifiedName("InternationalizedString");
-
+ PROV_QUALIFIED_NAME = newProvQualifiedName("QualifiedName");
PROV_REVISION = newProvQualifiedName("Revision");
PROV_QUOTATION = newProvQualifiedName("Quotation");
PROV_PRIMARY_SOURCE = newProvQualifiedName("PrimarySource");
@@ -114,6 +114,7 @@ public QualifiedName newProvQualifiedName(String local) {
final public QualifiedName PROV_LANG_STRING ;
+ final public QualifiedName PROV_QUALIFIED_NAME ;
final public QualifiedName PROV_REVISION ;
final public QualifiedName PROV_QUOTATION ;
final public QualifiedName PROV_PRIMARY_SOURCE ;
@@ -264,11 +264,12 @@ public String qualifiedNameToString(QualifiedName name, Namespace child) {
return pref + ":" + name.getLocalPart();
} else {
if (parent!=null) {
- parent.qualifiedNameToString(name,this);
+ return parent.qualifiedNameToString(name,this);
}
- throw new QualifiedNameException("unknown qualified name " + name
- + " with namespace " + toString()
- + ((child==null)? "" : (" and " + child)));
+ else
+ throw new QualifiedNameException("unknown qualified name " + name
+ + " with namespace " + toString()
+ + ((child==null)? "" : (" and " + child)));
}
}
}
@@ -49,17 +49,15 @@ private boolean collectionEqual(Collection<?> c1, Collection<?> c2) {
private boolean statementEqual(StatementOrBundle r1,
StatementOrBundle r2) {
// If one of the statemens is a named bundle
- if (r1 instanceof NamedBundle || r2 instanceof NamedBundle) {
- if (r1 instanceof NamedBundle && r2 instanceof NamedBundle) {
- NamedBundle b1 = (NamedBundle) r1;
- NamedBundle b2 = (NamedBundle) r2;
- if (!b1.getId().equals(b2.getId()))
- return false;
- List<?> stmts1 = b1.getStatement();
- List<?> stmts2 = b2.getStatement();
- return statementListEqual((List<StatementOrBundle>) stmts1,
- (List<StatementOrBundle>) stmts2);
- }
+ if (r1 instanceof NamedBundle && r2 instanceof NamedBundle) {
+ NamedBundle b1 = (NamedBundle) r1;
+ NamedBundle b2 = (NamedBundle) r2;
+ if (!b1.getId().equals(b2.getId()))
+ return false;
+ List<?> stmts1 = b1.getStatement();
+ List<?> stmts2 = b2.getStatement();
+ return statementListEqual((List<StatementOrBundle>) stmts1,
+ (List<StatementOrBundle>) stmts2);
}
// Two normal statements
Class<?> class1 = r1.getClass();

0 comments on commit 0e61615

Please sign in to comment.