diff options
author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-04-09 15:05:50 +0200 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2016-04-25 22:19:34 +0200 |
commit | f98526eb42909efbc8b2b4f85dfbfd588e25f515 (patch) | |
tree | bea818972f52b58ee49569da40affd7223e8d1ac | |
parent | bc25012753704943808bb8f71d75f27f68c13da9 (diff) |
First steps towards typesystem serialization. struct types can be successfully serialized.
-rw-r--r-- | src/plugins/xml/XmlOutput.cpp | 123 | ||||
-rw-r--r-- | testdata/integration/ontology_serialization/typesystem.in.osml | 10 | ||||
-rw-r--r-- | testdata/integration/ontology_serialization/typesystem.out.osxml | 21 |
3 files changed, 144 insertions, 10 deletions
diff --git a/src/plugins/xml/XmlOutput.cpp b/src/plugins/xml/XmlOutput.cpp index 1bc1ab7..8c45a52 100644 --- a/src/plugins/xml/XmlOutput.cpp +++ b/src/plugins/xml/XmlOutput.cpp @@ -65,6 +65,10 @@ static Rooted<Element> transformOntology(Handle<Element> parent, /* * Typesystem transformation. */ + +static std::string getTypeRef(Handle<Typesystem> referencing, + Handle<Type> referenced); + static Rooted<Element> transformTypesystem(Handle<Element> parent, Handle<Typesystem> t, TransformParams &P); @@ -275,13 +279,19 @@ static Rooted<Element> transformFieldDescriptor(Handle<Element> parent, syntax->addChild(close); } } - // translate the child references. - for (auto s : fd->getChildren()) { - std::string ref = - getStructuredClassRef(fd->getParent().cast<Descriptor>(), s); - Rooted<Element> childRef{ - new Element(P.mgr, fieldDescriptor, "childRef", {{"ref", ref}})}; - fieldDescriptor->addChild(childRef); + if (!fd->isPrimitive()) { + // translate the child references. + for (auto s : fd->getChildren()) { + std::string ref = + getStructuredClassRef(fd->getParent().cast<Descriptor>(), s); + Rooted<Element> childRef{new Element(P.mgr, fieldDescriptor, + "childRef", {{"ref", ref}})}; + fieldDescriptor->addChild(childRef); + } + } else { + // translate the primitive type. + fieldDescriptor->getAttributes().emplace( + "type", getTypeRef(nullptr, fd->getPrimitiveType())); } return fieldDescriptor; } @@ -408,15 +418,108 @@ Rooted<Element> transformOntology(Handle<Element> parent, Handle<Ontology> o, /* * Typesystem transformation functions. */ + +std::string getTypeRef(Handle<Typesystem> referencing, Handle<Type> referenced) +{ + std::string typeRef; + if (referencing != referenced->getTypesystem() && + !(referenced->getTypesystem()->isa(&RttiTypes::SystemTypesystem))) { + // qualify the name if that's necessary. + typeRef = referenced->getTypesystem()->getName() + "." + + referenced->getName(); + } else { + typeRef = referenced->getName(); + } + return typeRef; +} + +Rooted<Element> transformStructTypeEntry(Handle<Element> parent, + Handle<StructType> t, + Handle<Attribute> a, + TransformParams &P) +{ + // create an xml element for the attribute. + Rooted<Element> attribute{new Element(P.mgr, parent, "field")}; + addNameAttribute(a, attribute->getAttributes()); + // add the type reference + { + std::string typeRef = getTypeRef(t->getTypesystem(), a->getType()); + attribute->getAttributes().emplace("type", typeRef); + } + // set the default value. + if (a->getDefaultValue() != nullptr) { + attribute->getAttributes().emplace("default", + toString(a->getDefaultValue(), P)); + } + // set the optional flag. + attribute->getAttributes().emplace("optional", + getStringForBool(a->isOptional())); + return attribute; +} + +Rooted<Element> transformStructType(Handle<Element> parent, + Handle<StructType> t, TransformParams &P) +{ + // create an xml element for the struct type itself. + Rooted<Element> structType{new Element(P.mgr, parent, "struct")}; + addNameAttribute(t, structType->getAttributes()); + // transform all attributes. + for (auto &a : t->getAttributes()) { + Rooted<Element> attribute = + transformStructTypeEntry(structType, t, a, P); + structType->addChild(attribute); + } + return structType; +} Rooted<Element> transformTypesystem(Handle<Element> parent, Handle<Typesystem> t, TransformParams &P) { - // TODO: implement. - return nullptr; + // do not transform the system typesystem. + if (t->isa(&RttiTypes::SystemTypesystem)) { + return nullptr; + } + // only transform this typesystem if it was not transformed already. + if (t->getLocation().getSourceId() != P.documentId) { + // also: store that we have serialized this ontology. + if (!P.serialized.insert(t->getLocation().getSourceId()).second) { + return nullptr; + } + } + + if (P.flat) { + // transform all referenced typesystems if we want a standalone version. + for (auto t2 : t->getTypesystemReferences()) { + Rooted<Element> refTypes = transformTypesystem(parent, t2, P); + if (refTypes != nullptr) { + parent->addChild(refTypes); + } + } + } + + // transform the typesystem itself. + // create an XML element for the ontology. + Rooted<Element> typesystem{new Element(P.mgr, parent, "typesystem")}; + addNameAttribute(t, typesystem->getAttributes()); + // transform all types + for (auto tp : t->getTypes()) { + Rooted<Element> type; + if (tp->isa(&RttiTypes::StructType)) { + type = transformStructType(typesystem, tp.cast<StructType>(), P); + } else { + P.logger.warning(std::string("Type ") + tp->getName() + + " can not be serialized, because it is neither a " + "StructType nor an EnumType."); + } + if (type != nullptr) { + typesystem->addChild(type); + } + } + // return the transformed Ontology. + return typesystem; } /* - * Attributes transform functions. + * DocumentEntity attributes transform functions. */ std::map<std::string, std::string> transformAttributes(const std::string &name, diff --git a/testdata/integration/ontology_serialization/typesystem.in.osml b/testdata/integration/ontology_serialization/typesystem.in.osml new file mode 100644 index 0000000..ec61dd3 --- /dev/null +++ b/testdata/integration/ontology_serialization/typesystem.in.osml @@ -0,0 +1,10 @@ +\document + \typesystem#bla + \struct#myStruct + \field#i[type=int,default=1] + \field#s[type=string,default=""] + \ontology#test + \struct#a[root=true] + \primitive[type=myStruct] + +\a [4,"bla"] diff --git a/testdata/integration/ontology_serialization/typesystem.out.osxml b/testdata/integration/ontology_serialization/typesystem.out.osxml new file mode 100644 index 0000000..a8c02ae --- /dev/null +++ b/testdata/integration/ontology_serialization/typesystem.out.osxml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<document> + <ontology name="test"> + <struct cardinality="{*}" name="a" root="true" transparent="false"> + <syntax/> + <primitive optional="false" subtree="false" type="bla.myStruct"> + <syntax/> + </primitive> + </struct> + </ontology> + <typesystem name="bla"> + <struct name="myStruct"> + <field default="1" name="i" optional="true" type="int"/> + <field default="" name="s" optional="true" type="string"/> + </struct> + </typesystem> + <test:a>[ + "i"= 4, + "s"= "bla" +]</test:a> +</document> |