[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [eclipselink-users] Best practices for modularity?
|
ah, I see. This is an interesting strategy. It gives me a lot of food for
thought, and I'll definitely keep it in mind.
Thanks,
Polly
Blaise Doughan wrote:
>
> Hi Polly,
>
> I'm going to try and develop this a little more but here are some
> current thoughts:
>
> We use MOXy to map our XML mapping data to our programmatic metadata.
> This means that you could use MOXy to unmarshal your XML metadata files
> into the programmatic metadata:
>
> import java.io.File;
> import
> org.eclipse.persistence.internal.sessions.factories.EclipseLinkObjectPersistenceRuntimeXMLProject;
> import org.eclipse.persistence.oxm.*;
> import org.eclipse.persistence.sessions.Project;
> ...
> EclipseLinkObjectPersistenceRuntimeXMLProject project = new
> EclipseLinkObjectPersistenceRuntimeXMLProject();
> XMLContext xmlContext = new XMLContext(project);
>
> XMLUnmarshaller unmarshaller = xmlContext.createUnmarshaller();
> Project baseProject = (Project) unmarshaller.unmarshal(new
> File("your_base_metadata.xml"));
> Project extensionProject = (Project) unmarshaller.unmarshal(new
> File("your_extension_metadata.xml"));
>
> Then you could pull data from extensionProject into the baseProject,
> useful methods here are the following:
>
> XMLDescriptor customerDescriptor = (XMLDescriptor)
> project.getClassDescriptor(Customer.class);
> XMLDirectMapping firstNameMapping = (XMLDirectMapping)
> customerDescriptor.getMappingForAttributeName("firstName");
>
> Finally you would create an XMLContext on your combined project, if you
> moved everything into your base project, then this would be done as
> follows:
>
> XMLContext xmlContext2 = new XMLContext(baseProject);
>
> ---
>
> Other Items:
>
> * You are correct you can not use multiple Any mappings at the same
> level.
> * To get the xsi prefix to appear in the out document, in the UI be
> sure that in the schemas panel it is selected as a declaration to
> be included, or programmatically add it to the NamespaceResolver
> held onto by the descriptor.
>
>
> -Blaise
>
> amphoras wrote:
>> Hi Blaise,
>>
>> Thanks for your detailed and helpful response. I just have a few more
>> questions.
>>
>>
>>>> 1. What does it mean to have a "primary" project versus "additional"
>>>> projects in the session? The documentation talks about how to
>>>> configure
>>>> these but doesn't really go into the ramifications. Does the order of
>>>>
>>> the
>>>
>>>> projects matter?
>>>>
>>
>>
>>> I never really thought of it as primary vs additional projects. Each
>>> project is equal, the order is only
>>> significant if you have multiple objects mapped to the same default root
>>> element. As a default root
>>> element must correspond to only one descriptor.
>>>
>>
>> What I was trying to do was create an incomplete/abstract mapping for a
>> class in my "common" project.xml file. Then I created another mapping
>> for
>> the same class in my "app" project.xml file that fills in the missing
>> pieces
>> and overrides certain settings from the "common" mapping. My session.xml
>> file loads both project files.
>>
>> I found that since both mappings are for the same class, whichever one
>> that
>> I set as the "primary" in the session was wiped out by the second one.
>> Actually, all settings were replaced except for one. The "common" and
>> "app"
>> versions of the class mappings have different "default root element"
>> settings, and I found that both were available for unmarshalling. So the
>> result was cumulative. It sounds like you expect that the default root
>> element should have been replaced by the second class mapping?
>>
>> ---
>>
>>
>>>> 2. Is is possible for an application's mappings to override the ones
>>>>
>>> from
>>>
>>>> the common project?
>>>>
>>
>>
>>> I'll describe a strategy we use to unmarshal our own metadata. We use
>>> the Java version of the metadata and create a subclass of the project
>>> for each version that we distribute. Each descriptor is built in its
>>> own method, and when new features are added the corresponding mapping
>>> project overrides the corresponding buildDescriptor method.
>>> ...
>>>
>>
>> yes, that is the exact behavior that I'm looking for! Is it possible to
>> do
>> this using the deployment project.xml files? I am trying to do as much
>> as I
>> can using the xml files. I am ok with creating event listeners like the
>> amendment method, but I am trying to minimize use of Java for ease of
>> changing the mappings.
>>
>> ---
>>
>>
>>>> 3. Is is possible for the common project to define mappings that are
>>>> "abstract" or based on interfaces? I see that there is an
>>>> XMLChoiceMapping, but I am not sure how to use that because I won't
>>>> know
>>>> ahead of time what application-specific class I need to use. I would
>>>>
>>> like
>>>
>>>> to have a common POJO that contains composite objects that are defined
>>>>
>>> in
>>>
>>>> the application-specific project. Is that possible?
>>>>
>>
>>
>>> I have seen users make use of our Any mappings for this. Their scenario
>>> is usually the following, they have one OXM project that corresponds to
>>> the message envelope, and many OXM projects that correspond to possible
>>> payloads. To implement this they use an XMLAnyObjectMapping to map the
>>> message body property on their message object, and then in the payload
>>> projects they ensure that all of objects that form the root of the body
>>> have default root elements set. You will need to ensure that the
>>> XMLContext is created with both the message and payload projects.
>>>
>>
>> yes, exactly. I have an element like this:
>>
>> <Foo>
>> <Action></Action>
>> <Data></Data>
>> <Data></Data>
>> ...
>> </Foo>
>>
>> "Action" is a class hierarchy of different kinds of actions, and "Data"
>> is a
>> collection of any type of element. So I configured "Action" with an
>> XMLChoiceMapping and "Data" as XMLAnyCollectionMapping, and that works!
>> I
>> did try to set "Action" to XMLAnyObjectMapping, but EclipseLink got
>> confused. So I guess you can't use two "any" mappings next to one
>> another,
>> which makes sense. The XMLChoiceMapping works fine for the "Action".
>>
>> The only problem is when I try to go roundtrip more than once. I can
>> unmarshall the document and marshall it back out, but the Action element
>> is
>> output with the attribute 'xsi:type="ns1:ProcessType"'. I don't think
>> this
>> attribute is allowed by the schema, and when I unmarshall the document
>> again, I get:
>>
>> [Fatal Error] :178:72: The prefix "xsi" for attribute "xsi:type"
>> associated
>> with an element type "ns1:Process" is not bound.
>>
>> I noticed that the "xsi" namespace is not defined in the output file even
>> though it was in the original one. So my questions are:
>>
>> a. Can I suppress the xsi:type attribute from being generated?
>> b. Failing that, I need to get this attribute added to the schema,
>> correct?
>> c. How do I get the "xsi" namespace to be generated for the output?
>>
>> ---
>>
>>
>>>> 4. Is is possible to map different root elements to the same POJO? Or
>>>> can I use a regular expression when matching the root element name?
>>>> Our
>>>> schema is defined such that we have root elements with different names
>>>> that have very similar content, so I'd like to be able to map them to
>>>>
>>> the
>>>
>>>> same POJO. From what I've seen from the code, it looks like I will not
>>>>
>>> be
>>>
>>>> able to do this directly. So I think my alternative is to come up with
>>>>
>>> a
>>>
>>>> transformation to apply before unmarshalling and after marshalling to
>>>> change the root element name. Or do you have other suggestions?
>>>>
>>
>>
>>> You can map multiple root elements to the same POJO. Currently this can
>>> not be done in the UI, but you can create an "After Load" method and
>>> modify the descriptor by hand. You can call
>>> "setDefaultRootElement(String)" multiple times on the descriptor. All
>>> of these names will be used to recognize the object during
>>> unmarshalling, but the last defaultRootElement set will be used for
>>> marshalling.
>>>
>>
>> Hmm, my scenario is that the class mapping is in the "common" project,
>> and I
>> won't know what the possible default root elements are ahead of time.
>> Only
>> the "app" project will know that, and it needs to define multiple root
>> elements (around 5). So I cannot call setDefaultRootElement() from the
>> amendment method while the "common" project is loading. This is similar
>> to
>> the "data" element in question 3 that was solved by the "any" mapping. I
>> need to go roundtrip using these many root elements, so marshalling using
>> the last defined root element also won't work.
>>
>>
>>> If you want to use a different root element, you can wrap
>>> your object in an instance of org.eclipse.persistence.oxm.XMLRoot of
>>> javax.xml.bind.JAXBElement (if your are using JAXB).
>>>
>>
>> can you clarify this? I've never actually worked with JAXB directly. So
>> far I've been very happy to let EclipseLink hide JAXB under the covers.
>> ;)
>>
>> If I can marshall to those different root elements using a callback
>> method,
>> that would be fine. I can figure out what root element to use based on
>> data
>> inside the object.
>>
>> Or... would the "preserve document" setting help in this case?
>>
>> ---
>>
>>
>>>> 5. Can you share any other best practices for implementing a modular
>>>> design with these mappings?
>>>>
>>
>>
>>> I mentioned a couple of our most common strategies above. Can you share
>>> more details about the type of modularity you would like to see?
>>>
>>
>> sure, I'll summarize from my response above:
>> * ability to allow the project.xml files to inherit and override mappings
>> like you are doing with Java.
>> * ability to defer defining root elements to another project.xml file.
>> * ability to marshall using different root elements using a callback
>> method
>> or some way to "remember" what was unmarshalled.
>>
>> Thanks for your help! This is much easier than debugging random
>> EclipseLink
>> source code in hope of finding a hint. :)
>>
>> --Polly
>>
>
> _______________________________________________
> eclipselink-users mailing list
> eclipselink-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>
>
--
View this message in context: http://www.nabble.com/Best-practices-for-modularity--tp18654654p18819875.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.