diff --git a/cli/src/main/scala/scalaxb/compiler/xsd2/ContextProcessor.scala b/cli/src/main/scala/scalaxb/compiler/xsd2/ContextProcessor.scala
index 08c7840e5..f267038f1 100644
--- a/cli/src/main/scala/scalaxb/compiler/xsd2/ContextProcessor.scala
+++ b/cli/src/main/scala/scalaxb/compiler/xsd2/ContextProcessor.scala
@@ -17,7 +17,7 @@ trait ContextProcessor extends ScalaNames { self: Namer with Lookup =>
tagged.tag.toString + "??"
}
- def getTraitName(tagged: Tagged[XComplexType]): String =
+ def getTraitName(tagged: TaggedType[XComplexType]): String =
context.traitNames.get(tagged) getOrElse {
error(tagged.tag.toString + "??")
}
diff --git a/cli/src/main/scala/scalaxb/compiler/xsd2/Generator.scala b/cli/src/main/scala/scalaxb/compiler/xsd2/Generator.scala
index 0bd75c6e2..0c8de2926 100644
--- a/cli/src/main/scala/scalaxb/compiler/xsd2/Generator.scala
+++ b/cli/src/main/scala/scalaxb/compiler/xsd2/Generator.scala
@@ -48,7 +48,7 @@ class Generator(val schema: ReferenceSchema,
case _ => Vector()
}): _*)
- def processComplexType(decl: Tagged[XComplexType]): Seq[Trippet] =
+ def processComplexType(decl: TaggedType[XComplexType]): Seq[Trippet] =
if (context.baseToSubs.contains(decl)) {
generateBaseComplexTypeTrait(buildTraitSymbol(decl), decl) +:
(if (decl.abstractValue) Vector()
@@ -58,7 +58,7 @@ class Generator(val schema: ReferenceSchema,
/** recursively return compositors.
*/
- private def compositorsR(decl: Tagged[XComplexType]): Seq[TaggedParticle[KeyedGroup]] = {
+ private def compositorsR(decl: TaggedType[XComplexType]): Seq[TaggedParticle[KeyedGroup]] = {
val ps = decl.primarySequence
val singleps = ps map { tagged => Occurrence(tagged).isSingle } getOrElse {false}
@@ -82,7 +82,7 @@ class Generator(val schema: ReferenceSchema,
else ps.toSeq ++ nonps
}
- def generateComplexTypeEntity(sym: ClassSymbol, decl: Tagged[XComplexType]): Trippet = {
+ def generateComplexTypeEntity(sym: ClassSymbol, decl: TaggedType[XComplexType]): Trippet = {
logger.debug("generateComplexTypeEntity: emitting %s" format sym.toString)
lazy val attributeSeqRef: Tagged[AttributeSeqParam] = TaggedAttributeSeqParam(AttributeSeqParam(), decl.tag)
@@ -132,7 +132,7 @@ class Generator(val schema: ReferenceSchema,
compositorCodes: _*)
}
- private def generateDefaultFormat(sym: ClassSymbol, decl: Tagged[XComplexType],
+ private def generateDefaultFormat(sym: ClassSymbol, decl: TaggedType[XComplexType],
hasAttributes: Boolean, hasSequenceParam: Boolean, longAll: Boolean): Tree = {
val particles = decl.splitNonEmptyParticles
val unmixedParserList = particles map { buildParticleParser(_, decl.effectiveMixed, decl.effectiveMixed) }
@@ -242,7 +242,7 @@ class Generator(val schema: ReferenceSchema,
).flatten)
}
- private def generateBaseComplexTypeTrait(sym: ClassSymbol, decl: Tagged[XComplexType]): Trippet = {
+ private def generateBaseComplexTypeTrait(sym: ClassSymbol, decl: TaggedType[XComplexType]): Trippet = {
logger.debug("generateBaseComplexTypeTrait: emitting %s" format sym.toString)
lazy val attributeSeqRef: Tagged[AttributeSeqParam] = TaggedAttributeSeqParam(AttributeSeqParam(), decl.tag)
@@ -270,7 +270,7 @@ class Generator(val schema: ReferenceSchema,
makeImplicitValue(sym))
}
- private def generateBaseComplexTypeFormat(sym: ClassSymbol, decl: Tagged[XComplexType]): Tree = {
+ private def generateBaseComplexTypeFormat(sym: ClassSymbol, decl: TaggedType[XComplexType]): Tree = {
logger.debug("generateBaseComplexTypeFormat - ", sym)
val dfmt = defaultFormatterSymbol(sym)
@@ -323,7 +323,7 @@ class Generator(val schema: ReferenceSchema,
NEW(ANONDEF(dfmt.decodedName) := BLOCK())
}
- def complexTypeSuperTypes(decl: Tagged[XComplexType]): Seq[Type] = {
+ def complexTypeSuperTypes(decl: TaggedType[XComplexType]): Seq[Type] = {
def choices: List[TaggedKeyedGroup] =
(for {
sch <- context.schemas
@@ -409,23 +409,29 @@ class Generator(val schema: ReferenceSchema,
Trippet(TRAITDEF(sym))
}
- def processSimpleType(decl: Tagged[XSimpleType]): Seq[Trippet] =
+ def processSimpleType(decl: TaggedType[XSimpleType]): Seq[Trippet] =
Seq(generateSimpleType(userDefinedClassSymbol(decl), decl))
- private def generateSimpleType(sym: ClassSymbol, decl: Tagged[XSimpleType]) = {
+ private def generateSimpleType(sym: ClassSymbol, decl: TaggedType[XSimpleType]) = {
val enums = filterEnumeration(decl)
val enumValues = enums map { enum =>
CASEOBJECTDEF(userDefinedClassSymbol(enum)) withParents(sym) := BLOCK(
- DEF(Any_toString) withFlags(Flags.OVERRIDE) := LIT(enum.value.value)
+ DEF(Any_toString) withFlags(Flags.OVERRIDE) := LIT(decl.enumValue(enum).toString)
)
}
+ val valueTree: Tree =
+ if (decl.qnameBased) PAREN(BLOCK(
+ VAL(TUPLE(ID("ns"), ID("localPart"))) := (HelperClass DOT "splitQName") APPLY(REF("value"), REF("scope")),
+ NEW(QNameClass, REF("ns") DOT "orNull", REF("localPart")) TOSTRING
+ ))
+ else REF("value")
val companionTree: Tree =
if (enums.isEmpty) OBJECTDEF(sym) := BLOCK(
- DEF("fromString", sym) withParams(PARAM("value", StringClass)) := REF(sym) APPLY()
+ DEF("fromString", sym) withParams(PARAM("value", StringClass), PARAM("scope", NamespaceBindingClass)) := REF(sym) APPLY()
)
else OBJECTDEF(sym) := BLOCK(
- DEF("fromString", sym) withParams(PARAM("value", StringClass)) := REF("value") MATCH(
- enums map { enum => CASE (LIT(enum.value.value)) ==> REF(userDefinedClassSymbol(enum)) }
+ DEF("fromString", sym) withParams(PARAM("value", StringClass), PARAM("scope", NamespaceBindingClass)) := valueTree MATCH(
+ enums map { enum => CASE (LIT(decl.enumValue(enum).toString)) ==> REF(userDefinedClassSymbol(enum)) }
))
Trippet(TRAITDEF(sym).tree :: companionTree ::
enumValues.toList, Nil,
@@ -433,13 +439,15 @@ class Generator(val schema: ReferenceSchema,
makeImplicitValue(sym) :: Nil)
}
- private def generateSimpleTypeFormat(sym: ClassSymbol, decl: Tagged[XSimpleType]): Tree = {
+ private def generateSimpleTypeFormat(sym: ClassSymbol, decl: TaggedType[XSimpleType]): Tree = {
val dfmt = defaultFormatterSymbol(sym)
TRAITDEF(dfmt.decodedName) withParents(XMLFormatClass TYPE_OF sym) := BLOCK(List(
DEF("reads", eitherType(StringClass, sym)) withParams(
- PARAM("seq", NodeSeqClass), PARAM("stack", TYPE_LIST(ElemNameClass))) :=
- RIGHT((sym DOT "fromString")(REF("seq") DOT "text")),
+ PARAM("seq", NodeSeqClass), PARAM("stack", TYPE_LIST(ElemNameClass))) := REF("seq") MATCH(
+ CASE(ID("elem") withType(ElemClass)) ==> RIGHT((sym DOT "fromString")(REF("elem") DOT "text", REF("elem") DOT "scope")),
+ CASE(WILDCARD) ==> RIGHT((sym DOT "fromString")(REF("seq") DOT "text", REF(TopScopeModule)))
+ ),
DEF("writes", NodeSeqClass) withParams(PARAM("__obj", sym),
PARAM("__namespace", optionType(StringClass)),
PARAM("__elementLabel", optionType(StringClass)),
diff --git a/cli/src/main/scala/scalaxb/compiler/xsd2/Lookup.scala b/cli/src/main/scala/scalaxb/compiler/xsd2/Lookup.scala
index 7f29c0d2a..4622c9914 100644
--- a/cli/src/main/scala/scalaxb/compiler/xsd2/Lookup.scala
+++ b/cli/src/main/scala/scalaxb/compiler/xsd2/Lookup.scala
@@ -114,10 +114,10 @@ trait Lookup extends ContextProcessor { self: Namer with Splitter with Symbols =
tagged.value.ref map { ref => buildAttributeGroupTypeSymbol(resolveAttributeGroup(ref)) } getOrElse {
userDefinedClassSymbol(tagged) }
- def buildComplexTypeSymbol(tagged: Tagged[XComplexType]): ClassSymbol =
+ def buildComplexTypeSymbol(tagged: TaggedType[XComplexType]): ClassSymbol =
userDefinedClassSymbol(tagged.tag.namespace, getName(tagged))
- def buildTraitSymbol(tagged: Tagged[XComplexType]): ClassSymbol =
+ def buildTraitSymbol(tagged: TaggedType[XComplexType]): ClassSymbol =
userDefinedClassSymbol(tagged.tag.namespace, getTraitName(tagged))
def buildNamedGroupSymbol(tagged: Tagged[XNamedGroup]): ClassSymbol =
diff --git a/cli/src/main/scala/scalaxb/compiler/xsd2/SchemaContext.scala b/cli/src/main/scala/scalaxb/compiler/xsd2/SchemaContext.scala
index 73dfb72c6..829717e5a 100644
--- a/cli/src/main/scala/scalaxb/compiler/xsd2/SchemaContext.scala
+++ b/cli/src/main/scala/scalaxb/compiler/xsd2/SchemaContext.scala
@@ -28,7 +28,7 @@ import java.net.URI
case class SchemaContext(schemas: mutable.ListBuffer[ReferenceSchema] = mutable.ListBuffer(),
names: mutable.ListMap[Tagged[_], String] = mutable.ListMap(),
- traitNames: mutable.ListMap[Tagged[XComplexType], String] = mutable.ListMap(),
+ traitNames: mutable.ListMap[TaggedType[XComplexType], String] = mutable.ListMap(),
packageNames: mutable.ListMap[Option[String], Option[String]] = mutable.ListMap(),
- baseToSubs: mutable.ListMap[Tagged[XComplexType], List[Tagged[XComplexType]]] = mutable.ListMap(),
+ baseToSubs: mutable.ListMap[TaggedType[XComplexType], List[TaggedType[XComplexType]]] = mutable.ListMap(),
prefixes: mutable.ListMap[URI, String] = mutable.ListMap())
diff --git a/cli/src/main/scala/scalaxb/compiler/xsd2/SchemaOps.scala b/cli/src/main/scala/scalaxb/compiler/xsd2/SchemaOps.scala
index 734614510..828308ae7 100644
--- a/cli/src/main/scala/scalaxb/compiler/xsd2/SchemaOps.scala
+++ b/cli/src/main/scala/scalaxb/compiler/xsd2/SchemaOps.scala
@@ -180,6 +180,31 @@ case class SimpleTypeOps(decl: TaggedType[XSimpleType]) {
case _ => sys.error("baseType#: Unsupported content " + decl.xSimpleDerivationOption3.value.toString)
}
}
+ /** this decl is a decendant of QName. */
+ def qnameBased(implicit lookup: Lookup): Boolean = {
+ import Defs._
+ import lookup.{BuiltInType, SimpleType}
+ import scalaxb.compiler.xsd.XsQName
+ decl.value.xSimpleDerivationOption3.value match {
+ case XRestriction(_, _, _, Some(base), _) =>
+ QualifiedName(base) match {
+ case BuiltInType(TaggedSymbol(XsQName, _)) => true
+ case SimpleType(tagged) => SimpleTypeOps(tagged).qnameBased
+ case _ => false
+ }
+ case XRestriction(_, XSimpleRestrictionModelSequence(Some(simpleType), _), _, _, _) =>
+ SimpleTypeOps(Tagged(simpleType, decl.tag)).qnameBased
+ case _ => false
+ }
+ }
+
+ def enumValue(enum: Tagged[XNoFixedFacet])(implicit lookup: Lookup): Any =
+ if (qnameBased) {
+ import scalaxb.compiler.Module.splitTypeName
+ val (ns, localPart) = splitTypeName(enum.value.value, lookup.scopeEv)
+ QualifiedName(ns map {new URI(_)}, localPart)
+ }
+ else enum.value.value
}
/** represents attributes param */
diff --git a/cli/src/main/scala/scalaxb/compiler/xsd2/namer.scala b/cli/src/main/scala/scalaxb/compiler/xsd2/namer.scala
index 229b77ddc..ea9d2510f 100644
--- a/cli/src/main/scala/scalaxb/compiler/xsd2/namer.scala
+++ b/cli/src/main/scala/scalaxb/compiler/xsd2/namer.scala
@@ -45,7 +45,7 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
}}
}
- def nameSimpleTypes(decl: Tagged[XSimpleType]) {
+ def nameSimpleTypes(decl: TaggedType[XSimpleType]) {
if (containsEnumeration(decl)) {
val name = makeProtectedSimpleTypeName(decl)
logger.debug("nameSimpleTypes: named %s", name)
@@ -54,7 +54,7 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
}
}
- def nameTrait(decl: Tagged[XComplexType]) {
+ def nameTrait(decl: TaggedType[XComplexType]) {
val rawName = decl.name.get
val initialName = if (rawName.last == 'e') rawName.dropRight(1) + "able"
else rawName + "able"
@@ -63,7 +63,7 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
traitNames(decl) = name
}
- def nameComplexTypes(decl: Tagged[XComplexType]) {
+ def nameComplexTypes(decl: TaggedType[XComplexType]) {
val name = makeProtectedComplexTypeName(decl)
logger.debug("nameComplexTypes: named %s", name)
names(decl) = name
@@ -83,7 +83,7 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
}
}
- def nameComplexTypeCompositors(decl: Tagged[XComplexType]) {
+ def nameComplexTypeCompositors(decl: TaggedType[XComplexType]) {
val primarySequence = decl.primarySequence
implicit val s = schema.unbound
val cs: Seq[TaggedParticle[KeyedGroup]] = decl.toSeq collect {
@@ -127,9 +127,9 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
}
}
- def nameEnumValues(decl: Tagged[XSimpleType]) {
+ def nameEnumValues(decl: TaggedType[XSimpleType]) {
filterEnumeration(decl) map { enum =>
- names(enum) = makeProtectedEnumTypeName(enum)
+ names(enum) = makeProtectedEnumTypeName(enum, decl)
}
}
@@ -140,14 +140,14 @@ trait Namer extends ScalaNames { self: Lookup with Splitter =>
def makeProtectedElementTypeName(elem: Tagged[XElement]): String =
makeProtectedTypeName(elem.name, "", elem.tag, true)
- def makeProtectedComplexTypeName(decl: Tagged[XComplexType]): String =
+ def makeProtectedComplexTypeName(decl: TaggedType[XComplexType]): String =
makeProtectedTypeName(decl.name, "Type", decl.tag, true)
- def makeProtectedSimpleTypeName(decl: Tagged[XSimpleType]): String =
+ def makeProtectedSimpleTypeName(decl: TaggedType[XSimpleType]): String =
makeProtectedTypeName(decl.name, "Type", decl.tag, true)
- def makeProtectedEnumTypeName(enum: Tagged[XNoFixedFacet]): String =
- makeProtectedTypeName(enum.value.value, "Value", enum.tag, true)
+ def makeProtectedEnumTypeName(enum: Tagged[XNoFixedFacet], decl: TaggedType[XSimpleType]): String =
+ makeProtectedTypeName(decl.enumValue(enum).toString, "Value", enum.tag, true)
def makeProtectedNamedGroup(tagged: Tagged[XNamedGroup]): String =
makeProtectedTypeName(tagged.name.get + "Group", "", tagged.tag, true)
diff --git a/cli/src/main/scala/scalaxb/compiler/xsd2/symbols.scala b/cli/src/main/scala/scalaxb/compiler/xsd2/symbols.scala
index e92844082..3eeded661 100644
--- a/cli/src/main/scala/scalaxb/compiler/xsd2/symbols.scala
+++ b/cli/src/main/scala/scalaxb/compiler/xsd2/symbols.scala
@@ -34,9 +34,6 @@ trait Symbols {
lazy val JavaxXmlNamespacePackage = JavaxXmlPackageClass.newPackage("namespace")
lazy val JavaxXmlNamespacePackageClass = JavaxXmlNamespacePackage.moduleClass
lazy val QNameClass = JavaxXmlNamespacePackageClass.newClass("QName")
-
- // workaround treehugger 0.2.0 bug
- lazy val NamespaceBindingClass = definitions.getClass("scala.xml.NamespaceBinding")
def xmlFormatType(arg: Type): Type = appliedType(XMLFormatClass.typeConstructor, List(arg))
def parserType(arg: Type): Type = appliedType(ParserClass.typeConstructor, List(arg))
diff --git a/cli/src/test/scala/EntitySpec.scala b/cli/src/test/scala/EntitySpec.scala
index ba5965044..202b3b8b3 100644
--- a/cli/src/test/scala/EntitySpec.scala
+++ b/cli/src/test/scala/EntitySpec.scala
@@ -17,6 +17,7 @@ object EntitySpec extends Specification { def is = sequential ^
"each enumerations represented as case object" ! enum2^
"be referenced as the trait" ! enum3^
"generate a companion object named similarly" ! enum4^
+ "generate a fromString method using underlying value if it derives from QName" !enum5^
end^
"top-level complex types should" ^
"generate a case class named similarly" ! complexType1^
@@ -85,6 +86,11 @@ object EntitySpec extends Specification { def is = sequential ^
+
+
+
+
+
@@ -109,6 +115,18 @@ object EntitySpec extends Specification { def is = sequential ^
enumEntitySource must contain("""object MilkType {""")
}
+ def enum5 = {
+ enumEntitySource must contain("""object QNameEnum {
+ def fromString(value: String, scope: scala.xml.NamespaceBinding): example.QNameEnum =
+ ({
+ val (ns, localPart) = scalaxb.Helper.splitQName(value, scope)
+ new javax.xml.namespace.QName(ns.orNull, localPart).toString
+ }) match {
+ case "{http://www.example.com/}Receiver" => example.U123httpu58u47u47wwwu46exampleu46comu47u125Receiver
+ }
+}""")
+ }
+
lazy val complexTypeEntitySource = module.processNode(complexTypeCardinalityXML, "example")(0)
lazy val expectedComplexTypeTest =