Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[eclipselink-dev] MissingDescriptorListener and deployment xml


bugs 231312, 231897, 223913, 228895 are all related to the 'native' deployment XML
This thread started with o.e.p.sessions.factories.MissingDescriptorListener - it is used in o.e.p.sessions.factories.XMLProjectReader
to read in legacy TopLink 10.1.3/11.1.1 deployment XML as well as EclipseLink 1.0 deployment XML. However, the namespace prefixes are different "toplink:" vs. "eclipselink:"
Some changes were checked-in to fix some code in the listener:
public class MissingDescriptorListener extends SessionEventAdapter {
. . .
    session.getDescriptor(Call.class).getInheritancePolicy().addClassIndicator(javaClass, "eclipselink:xml-interaction");

Unfortunately any legacy TopLink deployment XML read in would not be parsed correctly since it has the TopLink namespace prefix. Further down, there is:

if (name.equals(XML_BINARY_MAPPING_CLASS)) {
    session.addDescriptors(new OXMObjectPersistenceRuntimeXMLProject());
}

The code in OXMObjectPersistenceRuntimeXMLProject uses the TopLink namespace prefix; thus any EclipseLink deployment XML written out that uses XMLBinaryDataMapping
(for example to handle Web Services binary-attachments) will be wrong:

<eclipselink:attribute-mapping xsi:type="eclipselink:xml-binary-data-mapping">
  <eclipselink:attribute-name>b</eclipselink:attribute-name>
  <eclipselink:field name="ns1:b" xsi:type="eclipselink:node">
    <eclipselink:schema-type>{http://www.w3.org/2001/XMLSchema}base64Binary</eclipselink:schema-type>
  </eclipselink:field>
  <toplink:is-swa-ref>true</toplink:is-swa-ref>
  <toplink:mime-type>application/octet-stream</toplink:mime-type>
  <toplink:should-inline-data>false</toplink:should-inline-data>
</eclipselink:attribute-mapping>

I discussed this with Blaise and he agreed that the best way to handle this is to have two new MOXy capabilities:

  1. allow XML schemas and instance documents to work with a default namespace, thereby removing the requirement that a namespace prefix has to be in the mapping meta-data at all
  2. when an o.e.p.oxm.XMLUnmarshaller reads in an instance document that has namespace prefixes (e.g. legacy TopLink deployment descriptor files), they can be optionally ignored

Given the timelines for EclipseLink milestones and the 1.0 release, he did not want to commit to working on the feature (there was an ADE bug tracking this and just yesterday,
someone on the eclipselink-user mailing list asked about default namespaces - 236051).

To solve this problem in the interim, the listener needs to extract from the SessionEvent the session's Project and use whatever prefix it was built with. We introduce two new sub-classes - o.e.p.sessions.factories.NamespaceResolverWithPrefixes and o.e.p.sessions.factories.NamespaceResolvableProject

public class NamespaceResolverWithPrefixes extends NamespaceResolver {

    protected String primaryPrefix = "";
    protected String secondaryPrefix = "";

    public void putPrimary(String ns1, String primaryNamespace) {
        this.primaryPrefix = ns1;
        put(ns1, primaryNamespace);
    }
    public String getPrimaryPrefix() {
        return primaryPrefix;
    }
    public void putSecondary(String ns1, String secondaryNamespace) {
        this.secondaryPrefix = ns1;
        put(ns1, secondaryNamespace);
    }
    public String getSecondaryPrefix() {
        return secondaryPrefix;
    }
...
public abstract class NamespaceResolvableProject extends Project {
    
    protected NamespaceResolverWithPrefixes ns;
    
    public NamespaceResolvableProject() {
        super();
        buildNamespaceResolver();
        buildDescriptors();
        setNamespaceResolverOnDescriptors();
    }
    public NamespaceResolvableProject(NamespaceResolverWithPrefixes ns) {
        super();
        this.ns = ns;
        buildDescriptors();
        setNamespaceResolverOnDescriptors();
    }

    protected abstract void buildDescriptors();

    protected void buildNamespaceResolver() {
        ns = new NamespaceResolverWithPrefixes();
        ns.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
        ns.put("xsd", "http://www.w3.org/2001/XMLSchema");
        String ns1 = getPrimaryNamespacePrefix();
        if (ns1 != null && ns1.length() > 0) {
            ns.putPrimary(ns1, getPrimaryNamespace());
        }
        String ns2 = getSecondaryNamespacePrefix();
        if (ns2 != null && ns2.length() > 0) {
            ns.putSecondary(ns2, getSecondaryNamespace());
        }
    }
    
    public String getPrimaryNamespacePrefix() {
        return null;
    }
    public String getPrimaryNamespace() {
        return null;
    }
    
    public String getPrimaryNamespaceXPath() {
        if (ns.getPrimaryPrefix() != null) {
            return ns.getPrimaryPrefix() + ":";
        }
        return "";
    }

A NamespaceResolvableProject can be built with some other project's NamespaceResolver, or it can build its own, based on overridable methods
that track a primary and secondary namespace prefix. A regular _expression_ is run over o.e.p.sessions.factories.ObjectPersistenceRuntimeXMLProject, converting all XPath strings from

nameMapping.setXPath("toplink:name/text()");

to

nameMapping.setXPath(getPrimaryNamespaceXPath() + "name/text()");

As a side-effect we can re-assemble the class hierarchy of RuntimeXMLProject's to proper single-rooted hierarchy:

ObjectPersistenceRuntimeXMLProject (read TL 10.1.3.n)
→ ObjectPersistenceRuntimeXMLProject_11_1_1 (read TL 11.1.1.n)

EclipseLinkObjectPersistenceRuntimeXMLProject (read EL 1.n)*
→ ObjectPersistenceWorkbenchXMLProject (write EL 1.n)


ObjectPersistenceRuntimeXMLProject
→ ObjectPersistenceRuntimeXMLProject_11_1_1
  → EclipseLinkObjectPersistenceRuntimeXMLProject
    → ObjectPersistenceWorkbenchXMLProject


* this file is ~7000 lines of duplicated code cut-&-paste from ObjectPersistenceRuntimeXMLProject and ObjectPersistenceRuntimeXMLProject_11_1_1.
With a single-root hierarchy, it shrinks down to ~85 lines.
Whenever the default namespace feature becomes available in EclipseLink, we can override the getPrimaryNamespacePrefix method in EclipseLinkObjectPersistenceRuntimeXMLProject to return the empty string "" - and we can still inherit 100% of the code in the super-classes above.

All the patches and new source files are attach'd to bug 231312.

The Core LRG runs and I have manually run some DBWS binary-attachment testcases

--
Oracle Email Signature Logo
Mike Norman | Principal Software Designer | 613.288.4638
Oracle Server Technologies | EclipseLink Product
45 O'Connor Street, Suite 400 | Ottawa, ON K1P 1A4 | (fax) 613.238.2818


Back to the top