dev@jaxb.java.net

Re: Modifying methods in an xjc plugin

From: Gregory Kick <gk5885_at_gmail.com>
Date: Mon, 29 Jan 2007 17:34:50 -0800

Ok, here's the problem and how I was looking to solve it:

When unmarshalling generates the whole object tree, the
unmarshalCallback() takes care of everything and I don't have to worry
about setting the parent pointers. However, I'd like to be able to
have valid parent pointers without having to set them separately.

The first part of the solution was to make all generated classes
implement a Child interface like the following:

public interface Child
{
        public Object getParent();
        public void setParent(Object parent);
}

Now, for a property with cardinality of one:

setProperty(Child property)
{
    this.property = property;
}

becomes

setProperty(Child property)
{
    this.property = property;
    this.property.setParent(this);
}

That part's easy enough. The higher cardinality is the tricky part.
It seems that either a wrapper that implements List<T extends Child>
and delegates to a backing list that's provided at construction, or an
extension of of one of the List implementation that keeps track of
parent pointer would be the way to manage it. In either case, methods
like add() and remove() would provide the functionality to set and
unset the parent pointer of the elements in the list.

Once I decide on that, I need to figure out how to get it into the xjc
generated classes. Using the technique you explained earlier, I got
the new List implementation in there, but there were some problems.
What I ended up with was (using an extension of ArrayList with a
constructor like public void ParentTrackingArrayList(Object parent) as
a trial):

private List<Property> property = new ParentTrackingArrayList<Property>();

Unfortunately, this won't compile because it doesn't use a default
constructor. Also, since
coreList.fullName().equals("java.util.ArrayList") is no longer true
(in UntypedListField), it is attempting eager initialization when
really, I'd prefer that it is instantiated in the getter just like it
normally would.

So, it looks like I'd have to override the FieldRendererFactory to get
the right FieldRenderer to get the right FieldOutline etc. just to get
the list initialized properly? I don't really like this because it's
very elaborate and might not be composable with other plugins (because
of the new FieldRendererFactory). I'm still not very comfortable with
what should be added in the model vs. what should be added in the
outline. Am I on the right track with all of this?

Thanks for any help.

On 1/29/07, Kohsuke Kawaguchi <Kohsuke.Kawaguchi_at_sun.com> wrote:
> Gregory Kick wrote:
> > Kohsuke,
> >
> > I used your suggestion and once I figured out that I needed to be
> > doing this in postProcessModel() I was all set. Now, I have the
> > problem that I need to add an argument to the constructor. I suspect
> > that this will involve a new FieldRenderer, and FieldOutline. Am I on
> > the right track? Any suggestions as to how to string this all
> > together?
>
> You mean, you need to generate a new constructor with an argument? I
> think you can do that by touching the generated code model objects.
>
> Maybe I need to see what you are trying to generate in the end.
>
> >
> > On 1/25/07, Kohsuke Kawaguchi <Kohsuke.Kawaguchi_at_sun.com> wrote:
> >> Gregory Kick wrote:
> >> > I'd like to modify the getters for any field that implements List.
> >> > Specifically, i'd like to replace the List implementation with my own.
> >> > Is there a way to do that? I can only find methods for adding new
> >> > statements, instead of modifying them...
> >>
> >> Right. Modifying things that are already written is somewhat limited
> >> because XJC never needed it. We can certainly add them.
> >>
> >> But in your case, you might be better off to touch the Model object and
> >> set FieldRenderer to relevant CPropertyInfo.realization. See
> >> CollectionTypeAttribute.java line 39 to how to create a list
> >> FieldRenderer for custom collection type.
> >>
> >> --
> >> Kohsuke Kawaguchi
> >> Sun Microsystems kohsuke.kawaguchi_at_sun.com
> >>
> >>
> >>
> >
> >
>
>
> --
> Kohsuke Kawaguchi
> Sun Microsystems kohsuke.kawaguchi_at_sun.com
>
>
>


-- 
Gregory Kick
gk5885_at_gmail.com