New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XMLFormat generated for abstract types missing grandchildren types #178

Closed
jkida opened this Issue Dec 6, 2012 · 2 comments

Comments

Projects
None yet
2 participants
@jkida

jkida commented Dec 6, 2012

originally reported as "Unable to process fromXML when xsd uses an abstract type"

I have been using the scalaxb library with no real problems until now. I skimmed down the actual xsd to reproduce the error, and I am hoping someone can help me come up with a fix. I am NOT sure if the abstract type is actually the problem but am hoping someone can help me figure it out.

toXML actually works.. but if I take that xml output and run it through fromXML it erorrs. Take a look.

Thanks for any help anyone can provide, I am in the middle of a project and would hate to switch to jaxb at this point.

scala> val queueEntry = ACDQueueEntry("calid:123456", "tracking:123456")
queueEntry: com.nextiva.scalaxsi.ACDQueueEntry = ACDQueueEntry(calid:123456,tracking:123456)

scala> val acdCallOffered = ACDCallOfferedToAgentEvent(queueEntry)
acdCallOffered: com.nextiva.scalaxsi.ACDCallOfferedToAgentEvent = ACDCallOfferedToAgentEvent(ACDQueueEntry(calid:123456,tracking:123456))

scala> val sub = SubscriptionEvent("event:123456", acdCallOffered)
sub: com.nextiva.scalaxsi.SubscriptionEvent = SubscriptionEvent(event:123456,ACDCallOfferedToAgentEvent(ACDQueueEntry(calid:123456,tracking:123456)))

Writing toXML works..

scala> scalaxb.toXML[SubscriptionEvent](sub, "SubscriptionEvent", defaultScope)
res0: scala.xml.NodeSeq = <SubscriptionEvent xmlns="http://schema.broadsoft.com/xsi" xmlns:tns="http://schema.broadsoft.com/xsi" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><eventID>event:123456</eventID><eventData xsi:type="ACDCallOfferedToAgentEvent"><queueEntry><callId>calid:123456</callId><extTrackingId>tracking:123456</extTrackingId></queueEntry></eventData></SubscriptionEvent>

but if I take that XML output, and run it through the fromXML method i get an error

scalaxb.fromXML[SubscriptionEvent](scalaxb.toXML[SubscriptionEvent](sub, "SubscriptionEvent", defaultScope))
scalaxb.ParserFailure: Unknown type: (Some(http://schema.broadsoft.com/xsi),Some(ACDCallOfferedToAgentEvent))
    at scalaxb.package$.fromXML(scalaxb.scala:15)
    at com.nextiva.scalaxsi.XMLProtocol$DefaultScalaxsiSubscriptionEventFormat$$anonfun$parser$2.apply(xmlprotocol.scala:34)
    at com.nextiva.scalaxsi.XMLProtocol$DefaultScalaxsiSubscriptionEventFormat$$anonfun$parser$2.apply(xmlprotocol.scala:32)
    at scala.util.parsing.combinator.Parsers$Success.map(Parsers.scala:133)
    at scala.util.parsing.combinator.Parsers$Success.map(Parsers.scala:132)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:227)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:227)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:207)
    at scala.util.parsing.combinator.Parsers$$anon$2.apply(Parsers.scala:813)
    at scalaxb.ElemNameParser$class.parse(scalaxb.scala:675)
    at com.nextiva.scalaxsi.XMLProtocol$$anon$1.parse(xmlprotocol.scala:16)
    at scalaxb.ElemNameParser$class.reads(scalaxb.scala:655)
    at com.nextiva.scalaxsi.XMLProtocol$$anon$1.reads(xmlprotocol.scala:16)
    at scalaxb.package$.fromXML(scalaxb.scala:13)

Here is the XSD, i tried to trim it down because the real xsd has hundreds of classes..

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://schema.broadsoft.com/xsi"
  targetNamespace="http://schema.broadsoft.com/xsi"
  attributeFormDefault="unqualified" elementFormDefault="qualified"
  version="1.0">


  <xs:complexType name="SubscriptionEvent">
    <xs:annotation>
      <xs:documentation>
        This represents event for a particular subscription.
      </xs:documentation>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="BaseEvent">
        <xs:sequence>
          <xs:element name="eventID" type="EventId">
            <xs:annotation>
              <xs:documentation>
                A UUID for the Event.
                This should be returned in the corresponding EventResponse.
              </xs:documentation>
            </xs:annotation>
          </xs:element>
          <xs:element name="eventData" type="EventData">
            <xs:annotation>
              <xs:documentation>
                Contains all the required details of the Event.
              </xs:documentation>
            </xs:annotation>
          </xs:element>
        </xs:sequence>

      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="EventData" abstract="true">
    <xs:annotation>
      <xs:documentation>
        Event is an abstract type from which all other Events are derived.
      </xs:documentation>
    </xs:annotation>
  </xs:complexType>

  <xs:complexType name="ACDEvent">
    <xs:annotation>
      <xs:documentation>
        The base event for ACD Events
      </xs:documentation>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="EventData">
        <xs:sequence>
          <xs:element name="queueEntry" type="ACDQueueEntry">
            <xs:annotation>
              <xs:documentation>
                The details of the ACDQueueEntry. An ACDQueueEntry contains
                information about a call in the ACD queue.
              </xs:documentation>
            </xs:annotation>
          </xs:element>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

<xs:complexType name="ACDQueueEntry">
    <xs:annotation>
      <xs:documentation>
        A ACDQueueEntry provides information about each call
        maintained in a ACD queue.
      </xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="callId" type="CallId">
        <xs:annotation>
          <xs:documentation>
            The call Id of the call for the ACD entry.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="extTrackingId" type="ExternalTrackingId">
        <xs:annotation>
          <xs:documentation>
            The external tracking Id of the call for the ACD entry.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:sequence>
  </xs:complexType>


  <xs:complexType name="ACDCallOfferedToAgentEvent">
    <xs:annotation>
      <xs:documentation>
        The ACD Call Offered event is sent when the ACD distributes the call to
        an agent. This event indicates that the call is offered to the
        agent but remains in the queue.
      </xs:documentation>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="ACDEvent" />
    </xs:complexContent>
  </xs:complexType>

  <xs:simpleType name="CallId">
    <xs:annotation>
      <xs:documentation>
        A call ID for a call. A call ID is of the form
        sessionId:callId where
        sessionId is the session identifier and
        callId is the call
        identifier of the call within the session. The
        call ID tracks a
        specific call leg within a call, there will be a
        different call
        ID for the originating vs. terminating half of a
        call. The call
        ID also changes when a call is placed via the Xsi,
        the initial
        call placed will have one value, and when the call
        actually
        rings out to the destination, the ID value will change.
      </xs:documentation>
    </xs:annotation>
    <xs:restriction base="NonEmptyToken" />
  </xs:simpleType>


  <xs:simpleType name="ExternalTrackingId">
    <xs:annotation>
      <xs:documentation>
        An ExternalTrackingId uniquely identifies a call
        session. An external tracking Id is of the form
        "parameter1:parameter2" where: 
        parameter1: NonNegativeInteger
        that is incremented each time a
        call session is created on a
        BroadWorks server. When it reaches
        the NonNegativeInteger maximum
        value (2^31-1) it rolls back to
        0.

        parameter2: Broadworks server
        identifier on which the call was created. This
        identifier is unique inside an AS cluster.

        The value "6:1" is an example of an externalTrackingId.

        An ExternalTrackingId is represented with a string.
      </xs:documentation>
    </xs:annotation>
    <xs:restriction base="NonEmptyToken" />
  </xs:simpleType>


  <xs:simpleType name="EventId">
    <xs:annotation>
      <xs:documentation>
        A universally unique ID(UUID) for an Event.
        This should be returned in the corresponding EventResponse.
        EventId should be same and unique for a pair of Event(Notification) and
        EventResponse.
            </xs:documentation>
    </xs:annotation>
    <xs:restriction base="NonEmptyString">
      <xs:maxLength value="256" />
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="BaseEvent" abstract="true">
    <xs:annotation>
      <xs:documentation>
        This is an abstract type for Xsi events.
      </xs:documentation>
    </xs:annotation>
  </xs:complexType>


  <xs:simpleType name="NonEmptyToken">
    <xs:annotation>
      <xs:documentation>
        Token that cannot be empty. Used where
        whitespace is not considered
        relevant and hence can be
        collapsed.
      </xs:documentation>
    </xs:annotation>
    <xs:restriction base="xs:token">
      <xs:minLength value="1" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="NonEmptyString">
    <xs:annotation>
      <xs:documentation>
        String that cannot be empty. Used when
        whitespace is considered valid
        and hence should be preserved
        instead of replaced or collapsed. For example, a SIP
        quoted-string value can contain
        valid whitespace.
      </xs:documentation>
    </xs:annotation>
    <xs:restriction base="xs:string">
      <xs:minLength value="1" />
    </xs:restriction>
  </xs:simpleType>

</xs:schema>
@eed3si9n

This comment has been minimized.

Show comment
Hide comment
@eed3si9n

eed3si9n Dec 10, 2012

Owner

Hi John, thanks for reporting this. This is a bug by scalaxb:

  trait DefaultBroadsoftEventDataFormat extends scalaxb.XMLFormat[broadsoft.EventData] {
    def reads(seq: scala.xml.NodeSeq, stack: List[scalaxb.ElemName]): Either[String, broadsoft.EventData] = seq match {
      case node: scala.xml.Node =>     
        scalaxb.Helper.instanceType(node) match {
          case (Some("http://schema.broadsoft.com/xsi"), Some("ACDEvent")) => Right(scalaxb.fromXML[broadsoft.ACDEventable](node, stack))
          case x => Left("Unknown type: " + x)
        }
      case _ => Left("reads failed: seq must be scala.xml.Node")  
    }
  ...
  }

The pattern matching generated for EventData is missing cases for grandchild types.

Owner

eed3si9n commented Dec 10, 2012

Hi John, thanks for reporting this. This is a bug by scalaxb:

  trait DefaultBroadsoftEventDataFormat extends scalaxb.XMLFormat[broadsoft.EventData] {
    def reads(seq: scala.xml.NodeSeq, stack: List[scalaxb.ElemName]): Either[String, broadsoft.EventData] = seq match {
      case node: scala.xml.Node =>     
        scalaxb.Helper.instanceType(node) match {
          case (Some("http://schema.broadsoft.com/xsi"), Some("ACDEvent")) => Right(scalaxb.fromXML[broadsoft.ACDEventable](node, stack))
          case x => Left("Unknown type: " + x)
        }
      case _ => Left("reads failed: seq must be scala.xml.Node")  
    }
  ...
  }

The pattern matching generated for EventData is missing cases for grandchild types.

@eed3si9n eed3si9n closed this in 068d884 Dec 10, 2012

@eed3si9n

This comment has been minimized.

Show comment
Hide comment
@eed3si9n

eed3si9n Dec 10, 2012

Owner

scalaxb 1.0.0-RC3 is out with the fix.

Owner

eed3si9n commented Dec 10, 2012

scalaxb 1.0.0-RC3 is out with the fix.

eed3si9n added a commit that referenced this issue May 26, 2013

eed3si9n added a commit that referenced this issue Jul 18, 2013

eed3si9n added a commit that referenced this issue Jul 28, 2013

eed3si9n added a commit that referenced this issue Sep 12, 2013

eed3si9n added a commit that referenced this issue Nov 8, 2014

eed3si9n added a commit that referenced this issue Jul 7, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment