Hi Polly,

The differences between the different types of <mapping>s, when you use 
an abstract vs. concrete, and when you reference using a type name vs. a 
class name, can all be confusing issues. The tutorial has some 
discussion of this at 
http://jibx.sourceforge.net/tutorial/binding-mappings.html but some 
parts are not as clear as they could be because new features were added 
over time and I was too lazy (or busy, if you want to be charitable) to 
rewrite the tutorial.

The Jibx2Wsdl code 
(http://www.sosnoski.com/jibx-wiki/space/axis2-jibx/jibx2wsdl) has an 
example (example4) which includes multiple layers of substitution 
groups. The inheritance structure uses both interfaces and subclassing, 
with a base Item interface thats implemented by Book and Dvd, an IDvd 
interface that extends Item and is implemented by another Dvd class, and 
several subclasses of the latter Dvd class. Here's part of the binding 
generated for this:

  <mapping abstract="true" 
extends="com.sosnoski.ws.library.jibx2wsdl.Item" 
class="com.sosnoski.ws.library.jibx2wsdl.hd.IDvd" name="IDvd">
    <structure map-as="tns:IDvd"/>
  </mapping>
  <mapping abstract="true" type-name="tns:dvd1" 
class="com.sosnoski.ws.library.jibx2wsdl.hd.Dvd">
    <structure map-as="tns:IDvd"/>
  </mapping>
  <mapping abstract="true" 
extends="com.sosnoski.ws.library.jibx2wsdl.hd.IDvd" 
class="com.sosnoski.ws.library.jibx2wsdl.hd.Dvd" name="dvd1">
    <structure map-as="tns:dvd1"/>
  </mapping>
  <mapping extends="com.sosnoski.ws.library.jibx2wsdl.hd.Dvd" 
class="com.sosnoski.ws.library.jibx2wsdl.hd.HdDvd" name="hdDvd">
    <structure map-as="tns:dvd1"/>
    <value style="element" name="studio" get-method="getStudio" 
set-method="setStudio" usage="optional"/>
  </mapping>
  <mapping extends="com.sosnoski.ws.library.jibx2wsdl.hd.Dvd" 
class="com.sosnoski.ws.library.jibx2wsdl.hd.BluRayDvd" name="bluRayDvd">
    <structure map-as="tns:dvd1"/>
    <value style="attribute" name="releaseYear" 
get-method="getReleaseYear" set-method="setReleaseYear"/>
  </mapping>
  <mapping extends="com.sosnoski.ws.library.jibx2wsdl.hd.Dvd" 
class="com.sosnoski.ws.library.jibx2wsdl.hd.Dvd$FutureDvd" 
name="dvdFutureDvd">
    <structure map-as="tns:dvd1"/>
    <value style="element" name="format" get-method="getFormat" 
set-method="setFormat" usage="optional"/>
  </mapping>

The substitution group structure is shown by the <mapping>s with names 
which extend other <mapping>s. So in this case, the mappings for 
<hdDvd>, <bluRayDvd>, and <hdDvd> all extend the mapping for the 
com.sosnoski.ws.library.jibx2wsdl.hd.Dvd base class, and that base class 
<mapping> in turn extends the <mapping> for the IDvd interface, which in 
turn extends the <mapping> for the Item interface.

That's how the substitution group handling works - you have a <mapping> 
for each element in the substitution group to some class, and that 
<mapping> extends the class corresponding to the head of the 
substitution group. If there are multiple layers in the substitution you 
just use multiple layers in the <mapping> extensions.

But when you do this you can't just invoke the base class <mapping> 
using a <structure map-as='base-class"/>, because that would create a 
new child element. So it's often convenient to have abstract mappings 
with a type-name but no element name in parallel to the mappings with 
names used by the substitution group structure. In the sample above, the 
second mapping definition is of this type. The type-name for this 
mapping is then referenced inside the other mappings to handle the XML 
structure matching the base complexType.

Hmmm. That still sounds confusing when I read over what I've written, 
but hopefully it'll give you a start in the right direction. Feel free 
to ask for clarification if needed.

  - Dennis

Dennis M. Sosnoski
SOA and Web Services in Java
Training and Consulting
http://www.sosnoski.com - http://www.sosnoski.co.nz
Seattle, WA +1-425-939-0576 - Wellington, NZ +64-4-298-6117



amphoras wrote:
> Hi Joshua,
>
> Thank you so much for taking the time to help me with this.  I have
> spent countless hours on this until my eyes glazed over.  ;)
>
> The problem with my object model is that it's deeply hierarchical and
> nested, and unfortunately I can't really change it.  That's why we are
> using JiBX.  We figured that it's the only tool that can handle our
> crazy data structure.  It works as advertised for us for everything
> but the schema group substitution.
>
> Since I simplified my example earlier, I did not tell you that
> actually SuperHeader has four more levels of superclasses above it,
> and it has two subclasses, one of which is Header.  In addition,
> Container is contained by other objects as well.  This is why I ended
> up "double-declaring" these elements.  So I tried to mimic your
> example as best as I could, following the way that you double-declared
> the "Header" example.  I also noticed that sometimes you used "map-as"
> with the classname and other times with the mapping type-name.  I
> think I read that they're supposed to be functionally equivalent, but
> for some reason, I can only use the mapping type-name.  Using the
> classname causes all kinds of errors.
>
> Sadly, there's still something wrong.  The error that I get is:
>
> junit.framework.AssertionFailedError: Element
> "{http://www.gmail.com/my}Header"; has no mapping that extends
> org.standard.Header
>       at junit.framework.Assert.fail(Assert.java:47)
>
> Normally, at this point I'll start to try different things.  But after
> having done that for hours before and not getting anywhere, I don't
> think that I have a good enough understanding of JiBX to succeed that
> way.  So I'm hoping that you or someone else can see what I'm doing
> wrong.
>
> Here's what I have:
>
> <binding>
>   <namespace uri="http://www.gmail.com/st"; default="elements"/>
>   <namespace uri="http://www.gmail.com/my"; default="none" prefix="my"/>
>
>   <mapping type-name="SuperHeader" abstract="true"
>               class="org.standard.SuperHeader">
>     <structure map-as="SuperSuperHeader"/>
>   </mapping>
>
>   <mapping name="SuperHeader"
>               class="org.standard.SuperHeader"
>       extends="org.standard.SuperSuperHeader">
>     <structure map-as="SuperHeader"/>
>     <value name="companyId" field="companyId" />
>   </mapping>
>
>
>   <mapping type-name="Header" abstract="true"
>               class="org.standard.Header">
>     <structure map-as="Header"/>
>   </mapping>
>
>   <mapping name="Header"
>               class="org.standard.Header"
>       extends="org.standard.SuperSuperHeader">
>     <structure map-as="Header"/>
>     <value name="branchId" field="branchId" />
>   </mapping>
>
>
>   <mapping name="myHeader"
>               class="com.my.Header"
>       extends="org.standard.Header">
>     <structure map-as="Header"/>
>     <value name="employeeId" field="employeeId" ns="http://www.gmail.com/my"; 
> />
>   </mapping>
>
>
>   <mapping type-name="Container" abstract="true"
>               class="org.standard.Container">                 
>     <structure field="header"/>
>   </mapping>
>
>   <mapping name="Container"
>               class="org.standard.Container">                 
>     <structure map-as="Container" />
>   </mapping>
> </binding>
>
> Again, I really appreciate your time and any help that you or anybody
> else can give me.
>
> Thanks!
> --Polly
>
>
> On 1/24/08, Joshua Davies <[EMAIL PROTECTED]> wrote:
>   
>> I think your problem is here:
>>
>>  <mapping type-name="Container" abstract="true"
>>                class="org.standard.Container">
>>    <structure name="Header" field="header" map-as="Header" usage="optional"/>
>>    ...
>>  </mapping>
>>
>>  <mapping name="Container"
>>                class="org.standard.Container">
>>    <structure map-as="Container"/>
>>  </mapping>
>>
>> You're telling Jibx that Container includes a Container element as it's
>> first element.  In general, you don't have to "double-declare" elements
>> this way unless you're extending from something that can appear as a
>> standalone element (such as your "Header" example).
>>
>> I took this out and made a few other minor changes to your binding and,
>> assuming that I understand your class structure and XML structure
>> correctly, was able to produce a binding file that works correctly:
>>
>> <binding direction="input">
>>  <namespace uri="http://www.gmail.com/st"; prefix="st"
>>      default="elements" />
>>  <namespace uri="http://www.gmail.com/my"; prefix="my" />
>>
>>  <mapping class="org.standard.SuperHeader" abstract="true"
>>           ns="http://www.gmail.com/st";>
>>    <value name="companyId" field="companyId" />
>>  </mapping>
>>
>>  <mapping class="org.standard.Header" ns="http://www.gmail.com/st";
>>           type-name="header" abstract="true">
>>    <structure map-as="org.standard.SuperHeader" />
>>    <value name="branchId" field="branchId" />
>>  </mapping>
>>
>>  <mapping name="Header" class="org.standard.Header"
>>           extends="org.standard.SuperHeader"
>>           ns="http://www.gmail.com/st";>
>>    <structure map-as="header" />
>>  </mapping>
>>
>>  <mapping name="myHeader" class="com.my.Header"
>>           extends="org.standard.Header" ns="http://www.gmail.com/my";>
>>    <structure map-as="header" />
>>    <value name="employeeId" field="employeeId"
>>           ns="http://www.gmail.com/my"; />
>>  </mapping>
>>
>>  <mapping name="Container" class="org.standard.Container"
>>           ns="http://www.gmail.com/st";>
>>    <structure field="header" />
>>  </mapping>
>> </binding>
>>
>> I added some random data elements to each of the classes so that I could
>> verify that the bindings were being processed correctly.
>>
>> I tested this against the following two XML documents:
>>
>> <st:Container xmlns:st="http://www.gmail.com/st";>
>>  <my:myHeader xmlns:my="http://www.gmail.com/my";>
>>    <st:companyId>123</st:companyId>
>>    <st:branchId>456</st:branchId>
>>    <my:employeeId>abc</my:employeeId>
>>  </my:myHeader>
>> </st:Container>
>>
>> and:
>>
>> <st:Container xmlns:st="http://www.gmail.com/st";>
>>  <st:Header>
>>    <st:companyId>123</st:companyId>
>>    <st:branchId>456</st:branchId>
>>  </st:Header>
>> </st:Container>
>>
>> Which I beleive encompass your primary use cases (again, data elements
>> made up so I could verify that everything unmarshalled correctly).
>>
>> I take it from your description below that myHeader extends Header,
>> which extends SuperHeader (and Container extends nothing, but has a data
>> element of type SuperHeader).  If I'm off about the actual type
>> hierarchy, things change around a bit, but not much.
>>
>> On Wed, 2008-01-23 at 17:52 -0500, amphoras wrote:
>>     
>>> Hi,
>>>
>>> First, I want to say that JiBX is a really neat tool.  It makes XML to
>>> Java serialization so easy.  However, we are using schema group
>>> substitution a lot, and this seems to be an "advanced" feature.  I
>>> would really appreciate your help.
>>>
>>> I have read the page about mapping inheritance
>>> (http://jibx.sourceforge.net/tutorial/binding-mappings.html#inherit)
>>> many times, but I am still not able to get it to work.  What I have is
>>> this class hierarchy:
>>>
>>> org.standard.SuperHeader
>>> org.standard.Header
>>> com.my.Header
>>>
>>> The schema for my Header says (st=standard):
>>> <xsd:element name="Header" type="HeaderType" substitutionGroup="st:Header" 
>>> />
>>>
>>> The JiBX mapping is defined as follows:
>>>   <mapping type-name="Header" abstract="true"
>>>               class="org.standard.Header"
>>>       extends="org.standard.SuperHeader">
>>>     <structure map-as="SuperHeader"/>
>>>     ...
>>>   </mapping>
>>>
>>>   <mapping name="Header"
>>>               class="org.standard.Header"
>>>       extends="org.standard.SuperHeader">
>>>     <structure map-as="Header"/>
>>>   </mapping>
>>>
>>>
>>> subclass:
>>>   <mapping name="myHeader"
>>>               class="com.my.Header"
>>>       extends="org.standard.Header">
>>>     <structure map-as="Header"/>
>>>     ...
>>>   </mapping>
>>>
>>> Then I have a container class, let's call "org.standard.Container"
>>> that can contain either "org.standard.Header" or "com.my.Header":
>>>
>>>   <mapping type-name="Container" abstract="true"
>>>               class="org.standard.Container">
>>>     <structure name="Header" field="header" map-as="Header" 
>>> usage="optional"/>
>>>     ...
>>>   </mapping>
>>>
>>>   <mapping name="Container"
>>>               class="org.standard.Container">
>>>     <structure map-as="Container"/>
>>>   </mapping>
>>>
>>> The Java class is like:
>>>
>>> package org.standard;
>>>
>>> public class Container {
>>>     Header header;
>>> }
>>>
>>> When I process XML that contains <st:Header>, everything's fine.  But
>>> when I process XML that contains <my:Header>, it doesn't work:
>>>
>>> Here's the XML:
>>> <st:Container>
>>>     <my:Header>
>>>     ...
>>>     </my:Header>
>>> </st:Container>
>>>
>>> I get:
>>>
>>> org.jibx.runtime.JiBXException: Expected "{http://standard}Container";
>>> end tag, found "{http://my}Header"; start tag (line 67, col 35)
>>>       at 
>>> org.jibx.runtime.impl.UnmarshallingContext.parsePastCurrentEndTag(Unknown
>>> Source)
>>>
>>> I have tried all different combinations of "map-as" to no avail.  I
>>> really like the natural, OO way that JiBX does schema group
>>> substitution, so I really want to get this to work.  I appreciate any
>>> help that you can give me.
>>>
>>> Thanks!
>>> --Polly
>>>
>>>       
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Microsoft
> Defy all challenges. Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> jibx-users mailing list
> jibx-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/jibx-users
>
>   

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
jibx-users mailing list
jibx-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jibx-users

Reply via email to