>
>
> An interceptor would definitely work. In the USER_LOGICAL phase (I
> think),
> you should be able to do:
>
> List<Object> list = msg.getContent(List.class);
> for (int x = 0; x < list.size(); x++) {
> Object o = list.get(x);
> if (o instanceof List) {
> list.set(x, Collections.unmodifiableList((List)o)):
> }
> }
>
> That should work for you case.
>
> Dan
>
>
>
> On Friday, June 10, 2011 11:43:15 AM Jason Whaley wrote:
> > Is there a way to make this generally applicable to every single method
> > that would return a List<JaxbType>. What I've gathered so far is that
> > using a ResponseWrapper means:
> >
> > 1) The bean used as the class for @ResponseWrapper has to have a property
> > that matches the @WebResult name exactly.
> > 2) If I try to wildcard the List I use a property in the bean for
> > @ResponseWrapper (so that the same bean can be used across all
> @WebMethods
> > that return a List) I'm back to have a complexType of <xs:sequence>
> > containing types of xs:anyType again.
> >
> > This doesn't look like it will help with the requirements we're trying to
> > impose, unfortunately (unless I'm going about using @ResponseWrapper
> > incorrectly).
> >
> > Going back to my original assumption - if I wanted this to be generally
> > applicable to every @WebMethod, would a CXF interceptor be useful for
> this?
> > I'd for us to avoid having to have a single XmlAdapter or bean class for
> > @ResponseWrapper for every @WebMethod that returns a List/Collection.
> >
> > --Whaley
> >
> > On Wed, Jun 8, 2011 at 10:15 AM, Daniel Kulp <
[hidden email]> wrote:
> > > On Wednesday, June 08, 2011 11:22:08 AM Jason Whaley wrote:
> > > > The problem itself manifests where a @WebMethod is actually
> specifying
> > > > List<SomeJaxbBean> as the return type. As a simple example:
> > > >
> > > > @WebMethod(operationName = "getRoles")
> > > > @WebResult(name = "roles")
> > > > List<Role> getRoles( @WebParam(name="roleIds") List<String> roleIds
> );
> > > >
> > > > Would we be better off just wrapping that list in a specific class
> > > > used only as a return type (much like how I suspect wsdl2java would
> > > > generate it if you assume your wsdl had an output message that
> > > > returned a complexType containing a sequence)?
> > >
> > > Ah. Right. For this case, you should likely create a wrapper class
> for
> > > the
> > > response and use the @ResponseWrapper annotation to point to it.
> The
> > > "java2ws" tool has a flag to generate stubs for those if you need it,
> but
> > > it
> > > really would just be another JAXB annotated bean with your list as a
> > > property.
> > > If you have the @ResponseWrapper pointing to a valid class, CXF will
> use
> > > it so
> > > you should be able to use all the same JAXB things like the
> > > afterUnmarshal and
> > > such with it.
> > >
> > > Dan
> > >
> > > > On Tue, Jun 7, 2011 at 1:46 PM, Daniel Kulp <
[hidden email]>
> wrote:
> > > > > 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
> > > > >
[hidden email]
> > > > >
http://dankulp.com/blog> > > > > Talend -
http://www.talend.com> > >
> > > --
> > > Daniel Kulp
> > >
[hidden email]
> > >
http://dankulp.com/blog> > > Talend -
http://www.talend.com>
> --
> Daniel Kulp
>
[hidden email]
>
http://dankulp.com/blog> Talend -
http://www.talend.com>