views:

227

answers:

1

Hello Ladies and Gents,

I have a question on wrapping a jaxb created class and would really like to hear your inputs.

My xsd looks a bit like:

<ComplexService>
    <ComplexObject1>
        <Element1></Element1>
       <Parameter></Parameter>
    </ComplexObject1>

   <ComplexObject2>
        <Element2> </Element2>
        <Parameter> </Parameter>
   </ComplexObject2>

   ...

  <ComplexObject10>
        <Element10> </Element10>
        <Parameter> </Parameter>
  </ComplexObjec10>

The class created after running the above xsd through xjc looks a bit like :

public class ComplexService{

ComplexObject1 object1;
ComplexObject2 object2;
...
ComplexObject10 object10;

public static class ComplexObject1{
//Accessors and mutators on ComplexObject1
}

public static class ComplexObject2{
//Accessors and mutators on ComplexObject1
}

...

public static class ComplexObject10{
//Accessors and mutators on ComplexObject1
}

}

Now I want to create a wrapper around these CompleObjects as well the ComplexService class.

public class WrappedComplexObject1{

private final ComplexObject1;

public WrappedComplexObject1(){
complexObject1 = new ComplexObject1();
}

//Delegate calls to the underlying ComplexObject1
public String getServiceName(){
return complexObject1.getServiceName();
}

}

My questions are these:

  1. Would the above way be the preferred way to wrap the class? My objectives are to not mess with the underlying classes created by xjc; to provide a better named api (Class as well as method names).

  2. I also want to validate the data in these objects. Therefore I am thinking of using the decorator pattern to further wrap WrappedComplexObject1. Would this be a recommended approach?

  3. Lastly, the xsd contains the element "Parameter" which is structurally the same (just contains one value field). However, when xjc created the ComplexService class, for every ComplexObject a new Parameter class was created.

Should I worry about just having one wrapper class for "Parameter" or should I simply create one Parameter wrapper classes per ComplexObject.

Any suggestions, ideas, code samples would be most helpful.

Thanks

+1  A: 

Well as you can see there were no responses, so I am unsure if my way is the "preferred" way. However, this is what I ended up doing:

//Defined a Wrapper Super class. All the classes I wrapped would descend from this.

public abstract class WrappedSuperComplexObject{

    protected boolean isValid;
    protected String name;

    public boolean isValid(){
     return isValid;
    }

    public String getName(){
     return name; 
    }

}

//Wrapper product class

 public class WrappedComplexBondObject extends WrappedSuperComplexObject{ 

    //ComplexObject is an internal object created by JAXB 
    private final JAXBElement<Product> productElement; 

    public WrappedComplexBondObject(JAXBElement<Product> productElement) { 
           this.isValid = true;
           this.name = ProductEnum.BOND;
           this.productElement= productElement; 
    } 

    //Delegate all get/set class to the internal object
    public String getElement1() { 
           return productElement.getElement1(); 
    } 

    public String getParameter1() { 
           return productElement.getParameter1(); 
    } 

    }

// And then have a factory class that validates and creates the specific product instance.

public WrappedSuperComplexObject createWrappedInstance(JAXBElement<DataDocument> jaxbElement) throws WrappedException{

    DataDocument document = jaxbElement.getValue();
    WrappedValidationResult result = WrappedValidator.validate(document);

    if ( !result.isValid() ){
     throw new WrappedException(result.getMessage());
    }

    JAXBElement<Product> productElem = (JAXBElement<Product>) trade.getProduct();   
    String productName = productElem.getName().getLocalPart().toUpperCase();

    WrappedSuperComplexObject product = null;

     switch( WrappedProductEnum.valueOf(productName) ){

     case BOND:
      product = new WrappedComplexBondObject(productElem);
     break;

     default:
      product = new UnsupportedProduct("Product is not Supported.");
     break;

    }

    return product;  
}

For question 3, I ended up extracting the "Parameter" element from my main xsd and created a new xsd just for Parameter. I then referenced the "Parameter" element from my main xjc.

Hope this helps.

CaptainHastings
Thanks for the update!
Strawberry