Created
November 24, 2010 13:25
-
-
Save honnix/713648 to your computer and use it in GitHub Desktop.
transform ASN.1 module into xml schema
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.ericsson.asn12schema.transformer | |
import scala.xml.{UnprefixedAttribute, Null} | |
import com.honnix.asn12schema.model.datatype.complex.{ASN1EnumeratedType, ASN1SetField, ASN1SetOfType, ASN1SetType} | |
import com.honnix.asn12schema.model.ASN1Module | |
import com.honnix.asn12schema.model.datatype.primitive.{ASN1PrimitiveType, ASN1BooleanType, ASN1IA5StringType, ASN1IntegerType} | |
class DefaultTransformer extends Transformer { | |
private def dealWithIntOrString(field: ASN1SetField) = { | |
val t = field.dataType.asInstanceOf[ASN1PrimitiveType] | |
val defaultOrNull = if (t.default.isEmpty) Null else new UnprefixedAttribute("default", t.default.get.toString, Null) | |
val schemaType = if (t.isInstanceOf[ASN1IntegerType]) "xs:integer" else "xs:string" | |
if (t.hasRange) | |
if (field.identifier) | |
<xs:element name={field.name} type={field.name + field.mySet.name + "IdentifierType"} minOccurs={if (field.mandatory) "1" else "0"} /> % defaultOrNull | |
else | |
<xs:element name={field.name} minOccurs={if (field.mandatory) "1" else "0"}> | |
<xs:simpleType> | |
<xs:restriction base={schemaType}> { | |
if (t.isInstanceOf[ASN1IntegerType]) { | |
val tmp = t.asInstanceOf[ASN1IntegerType] | |
if (tmp.minVal != Int.MinValue) <xs:minInclusive value={tmp.minVal.toString} /> else Null | |
if (tmp.maxVal != Int.MaxValue) <xs:maxInclusive value={tmp.maxVal.toString} /> else Null | |
} else { | |
val tmp = t.asInstanceOf[ASN1IA5StringType] | |
if (tmp.minLen != 0) <xs:minLength value={tmp.minLen.toString} /> else Null | |
if (tmp.maxLen != Int.MaxValue) <xs:maxLength value={tmp.maxLen.toString} /> else Null | |
} | |
} | |
</xs:restriction> | |
</xs:simpleType> | |
</xs:element> % defaultOrNull | |
else <xs:element name={field.name} type={schemaType} minOccurs={if (field.mandatory) "1" else "0"} /> % defaultOrNull | |
} | |
private def generateField(field: ASN1SetField) = field.dataType match { | |
case t: ASN1IntegerType => dealWithIntOrString(field) | |
case t: ASN1IA5StringType => dealWithIntOrString(field) | |
case t: ASN1BooleanType => | |
val defaultOrNull = if (t.default.isEmpty) Null else new UnprefixedAttribute("default", t.default.get.toString, Null) | |
<xs:element name={field.name} type="xs:boolean" minOccurs={if (field.mandatory) "1" else "0"} /> % defaultOrNull | |
case t: ASN1SetOfType => | |
<xs:element name={field.name} type={t.elemType.name + "Type"} minOccurs={if (field.mandatory) "1" else "0"} | |
maxOccurs={if (t.size != Int.MaxValue) t.size.toString else "unbounded"} /> | |
case _ => <xs:element name={field.name} type={field.dataType.name + "Type"} minOccurs={if (field.mandatory) "1" else "0"} /> | |
} | |
private def generateKey(identifier: ASN1SetField, operation: String) = { | |
<xs:key name={identifier.name + "Key_" + operation}> | |
<xs:selector xpath="." /> | |
<xs:field xpath={"@" + identifier.name} /> | |
</xs:key> | |
<xs:keyref name={identifier.name + "KeyRef_" + operation} refer={identifier.name + "Key_" + operation}> | |
<xs:selector xpath="." /> | |
<xs:field xpath={identifier.name} /> | |
</xs:keyref> | |
} | |
private def getIdentifierType(identifier: ASN1SetField) = identifier.dataType match { | |
case t: ASN1IntegerType => if (t.hasRange) identifier.name + identifier.mySet.name + "IdentifierType" else "xs:integer" | |
case t: ASN1IA5StringType => if (t.hasRange) identifier.name + identifier.mySet.name + "IdentifierType" else "xs:string" | |
case _ => identifier.dataType.name + "Type" | |
} | |
private def generateCreateOrGetResponse(asn1Set: ASN1SetType, operation: String) = | |
<xs:element name={operation + asn1Set.name}> | |
<xs:complexType> | |
<xs:sequence>{asn1Set.fields map generateField}</xs:sequence> { | |
asn1Set.identifiers map {x => | |
<xs:attribute name={x.name} type={getIdentifierType(x)} use="required" /> | |
} | |
} | |
</xs:complexType> | |
{asn1Set.identifiers map(generateKey(_, operation))} | |
</xs:element> | |
private def generateSet(asn1Set: ASN1SetType) = | |
<xs:element name={"set" + asn1Set.name}> | |
<xs:complexType> | |
<xs:sequence>{asn1Set.fields.filter(!_.identifier) map generateField}</xs:sequence> { | |
asn1Set.identifiers map {x => | |
<xs:attribute name={x.name} type={getIdentifierType(x)} use="required" /> | |
} | |
} | |
</xs:complexType> | |
</xs:element> | |
private def generateMissedOperation(asn1Set: ASN1SetType, operation: String) = | |
<xs:element name={operation + asn1Set.name}> | |
<xs:complexType> { | |
asn1Set.identifiers map {x => | |
<xs:attribute name={x.name} type={getIdentifierType(x)} use="required" /> | |
} | |
} | |
</xs:complexType> | |
</xs:element> | |
private def generateIdentifierType(identifiers: List[ASN1SetField]) = | |
identifiers map {x => | |
x.dataType match { | |
case t: ASN1IntegerType => | |
if (t.hasRange) | |
<xs:simpleType name={x.name + x.mySet.name + "IdentifierType"}> | |
<xs:restriction base="xs:integer"> { | |
if (t.minVal != Int.MinValue) <xs:minInclusive value={t.minVal.toString} /> else Null | |
if (t.maxVal != Int.MaxValue) <xs:maxInclusive value={t.maxVal.toString} /> else Null | |
} | |
</xs:restriction> | |
</xs:simpleType> | |
else Null | |
case t: ASN1IA5StringType => | |
if (t.hasRange) | |
<xs:simpleType name={x.name + x.mySet.name + "IdentifierType"}> | |
<xs:restriction base="xs:string"> { | |
if (t.minLen != 0) <xs:minLength value={t.minLen.toString} /> else Null | |
if (t.maxLen != Int.MaxValue) <xs:maxLength value={t.maxLen.toString} /> else Null | |
} | |
</xs:restriction> | |
</xs:simpleType> | |
else Null | |
case _ => Null | |
} | |
} | |
private def generateOthers(asn1Module: ASN1Module, mos: List[String]) = | |
asn1Module.definitions.filterNot(x => mos.exists(_ == x.name)) map {x => | |
x match { | |
case t: ASN1EnumeratedType => | |
<xs:simpleType name={t.name + "Type"}> | |
<xs:restriction base="xs:string"> { | |
t.values map {x => | |
<xs:enumeration value={x._2} /> | |
} | |
} | |
</xs:restriction> | |
</xs:simpleType> | |
case t: ASN1SetType => | |
<xs:complexType name={t.name + "Type"}> | |
<xs:sequence>{t.fields map generateField}</xs:sequence> { | |
t.identifiers map {x => | |
<xs:attribute name={x.name} type={getIdentifierType(x)} use="required" /> | |
} | |
} | |
</xs:complexType> ++ | |
generateIdentifierType(t.identifiers) | |
} | |
} | |
def transform(asn1Module: ASN1Module, mos: List[String]) = { | |
val namespace = "http://schemas.honnix.com/xxx/UserProvisioning/" + asn1Module.name + "/" | |
<xs:schema xmlns={namespace} xmlns:ns={namespace} xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
targetNamespace={namespace} elementFormDefault="qualified" attributeFormDefault="unqualified"> { | |
val elements = mos map {x: String => | |
val asn1Set = asn1Module.definitions.find(_.name == x).get.asInstanceOf[ASN1SetType] | |
generateCreateOrGetResponse(asn1Set, "create") ++ generateSet(asn1Set) ++ | |
generateMissedOperation(asn1Set, "delete") ++ generateMissedOperation(asn1Set, "get") ++ | |
generateCreateOrGetResponse(asn1Set, "getResponse") ++ generateIdentifierType(asn1Set.identifiers) | |
} | |
elements ++ generateOthers(asn1Module, mos) | |
} | |
</xs:schema> | |
} | |
} |
You can try to do that. It's very simple.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Maybe you can rewrite my schema2wsdl tool using Scala !!!