My gut feeling is that the best option is to construct the JAXB bean like 
normal:

public class MyFoo {
   List<Blah> blahs = new ArrayList<Blah>();

  ...   all the normal things ....

}


but then add a method like:

publi void afterUnmarshal(Unmarshaller, Object parent) {
    blahs = Collections.unmodifiableList(blahs);
}

to reset it to an unmodifiable collection after the unmarshalling is done.   
The call to the afterUnmarshal method is part of the spec:

http://download.oracle.com/javase/6/docs/api/javax/xml/bind/Unmarshaller.html#unmarshalEventCallback


Dan




On Tuesday, June 07, 2011 12:22:50 PM Jason Whaley wrote:
> (bear with me, this is a bit of a long question)
> 
> I'm working on a project, Kuali Rice (http://www.kuali.org/rice), that
> basically acts as a service bus for a series of other systems.  We are
> using CXF behind the scenes to publish JAX-WS annotated services that
> are written code-first.  These services can either be looked up and
> accessed by a client through a JAX-WS service proxy or, if Rice is
> running embedded in an app, an actual reference to the implementation
> can be given the to client.
> 
> This works great in the general case.  However we've recently started
> trying to enforce immutability on lots of our model objects and
> Collections/Maps of those model objects for various reasons.  Our
> services are using these immutable model objects as both parameters
> and return types.  Where this breaks down with JAX-WS and SOAP is in
> the case where a service method returns a Collection of these model
> objects back and we want the Collection itself to be immutable (e.g.
> the type you would get back from one of the
> Collections.unmodifiable*() methods).  If a client makes a service
> call through the JAX-WS proxy and the return type is
> List<SomeModelObject> then what it gets back is a modifiable List.
> This basically means that the two possible implementations that a
> client can reference will have different behaviors that break the
> documented expectation of what gets returned from method calls that
> return a List type (that expectation being an immutable list).
> 
> Despite the fact that these services are code first, we are striving
> to to make sure that the generated WSDL/XSD from our JAXB and JAX-WS
> annotated types and services produce somewhat of a sane contract for
> possibly non-java clients to use in the future.  As such, doing
> something like introducing an actual type for an ImmutableList (or
> using something like ImmutableList from guava) would create needless
> and java specific types in the generated WSDL/XSD.  We didn't go that
> route for that very reason.
> 
> The first thing I tried was to write a simple XmlAdapter to that would
> return an immutable List reference during unmarshalling.  It ended up
> looking like this:
> 
> 
> public class ImmutableListAdapter extends XmlAdapter<Object[], List<?>> {
> 
>     @Override
>     public List<?> unmarshal(Object[] objects) throws Exception {
>         return Collections.unmodifiableList(Arrays.asList(objects));
>     }
> 
>     @Override
>     public Object[] marshal(List<?> objects) throws Exception {
>         return objects.toArray();
>     }
> 
> }
> 
> 
> This works, but now the generated XSD/WSDL has those sequences that
> represent Lists as a sequence of <xs:any> types, which again we'd
> prefer not to have in order to keep the XSD/WSDL sane in the future
> for non java clients to use.   We could write an adapter for every
> single List<SomeModelObject> there such that the unbounded wildcard
> type isn't used and we are marshing to/from a
> SomeJaxbAnnotatedModelObject[] instead of Object[] each time (thus
> preventing the sequences of xs:any), but this seems like massive
> overkill to do for every single model object that we have.   Is there
> another possible way to do this with a XmlAdapter that wouldn't
> require such duplication?
> 
> If a JAXB Adapter is not the way to go with this, would it possible
> (and straightforward) to do this in a CXF interceptor that might do
> the same thing as this XmlAdapter but in such a way that it does not
> alter the generated XSD?  If so, what phase should that interceptor be
> bound to?

-- 
Daniel Kulp
[email protected]
http://dankulp.com/blog
Talend - http://www.talend.com

Reply via email to