View | Details | Raw Unified | Return to bug 285889 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/persistence/internal/oxm/TreeObjectBuilder.java (-15 / +24 lines)
Lines 81-87 Link Here
81
    }
81
    }
82
82
83
    public void addTransformationMapping(AbstractTransformationMapping transformationMapping) {
83
    public void addTransformationMapping(AbstractTransformationMapping transformationMapping) {
84
        if (null == getTransformationMappings()) {
84
        if (null == this.transformationMappings) {
85
            this.transformationMappings = new ArrayList();
85
            this.transformationMappings = new ArrayList();
86
        }
86
        }
87
        transformationMappings.add(transformationMapping);
87
        transformationMappings.add(transformationMapping);
Lines 96-102 Link Here
96
    }
96
    }
97
97
98
    public void addContainerValue(ContainerValue containerValue) {
98
    public void addContainerValue(ContainerValue containerValue) {
99
        if (null == getContainerValues()) {
99
        if (null == this.containerValues) {
100
            this.containerValues = new ArrayList();
100
            this.containerValues = new ArrayList();
101
        }
101
        }
102
        this.containerValues.add(containerValue);
102
        this.containerValues.add(containerValue);
Lines 107-113 Link Here
107
    }
107
    }
108
108
109
    public void addNullCapableValue(NullCapableValue nullCapableValue) {
109
    public void addNullCapableValue(NullCapableValue nullCapableValue) {
110
        if (null == getNullCapableValues()) {
110
        if (null == this.nullCapableValues) {
111
            this.nullCapableValues = new ArrayList();
111
            this.nullCapableValues = new ArrayList();
112
        }
112
        }
113
        this.nullCapableValues.add(nullCapableValue);
113
        this.nullCapableValues.add(nullCapableValue);
Lines 172-178 Link Here
172
                    mappingNodeValue = new XMLFragmentCollectionMappingNodeValue((XMLFragmentCollectionMapping)xmlMapping);
172
                    mappingNodeValue = new XMLFragmentCollectionMappingNodeValue((XMLFragmentCollectionMapping)xmlMapping);
173
                } else if (xmlMapping instanceof XMLCollectionReferenceMapping) {
173
                } else if (xmlMapping instanceof XMLCollectionReferenceMapping) {
174
                    XMLCollectionReferenceMapping xmlColMapping = (XMLCollectionReferenceMapping)xmlMapping;
174
                    XMLCollectionReferenceMapping xmlColMapping = (XMLCollectionReferenceMapping)xmlMapping;
175
                    Iterator fieldIt = xmlColMapping.getFields().iterator();
175
                    List fields = xmlColMapping.getFields();
176
                    XMLField xmlColMappingField = (XMLField) xmlColMapping.getField();
177
                    XPathNode branchNode;
178
                    if(null == xmlColMappingField) {
179
                        if(fields.size() > 1 && !xmlColMapping.usesSingleNode()) {
180
                            addChild(XPathFragment.SELF_FRAGMENT, new XMLCollectionReferenceMappingMarshalNodeValue(xmlColMapping), xmlDescriptor.getNamespaceResolver());
181
                        }
182
                        branchNode = rootXPathNode;
183
                    } else {
184
                        branchNode = addChild(((XMLField) xmlColMapping.getField()).getXPathFragment(), new XMLCollectionReferenceMappingMarshalNodeValue(xmlColMapping), xmlDescriptor.getNamespaceResolver());
185
                    }
186
                    Iterator fieldIt = fields.iterator();
176
                    while (fieldIt.hasNext()) {
187
                    while (fieldIt.hasNext()) {
177
                        XMLField xmlFld = (XMLField)fieldIt.next();
188
                        XMLField xmlFld = (XMLField)fieldIt.next();
178
                        mappingNodeValue = new XMLCollectionReferenceMappingNodeValue(xmlColMapping, xmlFld);
189
                        mappingNodeValue = new XMLCollectionReferenceMappingNodeValue(xmlColMapping, xmlFld);
Lines 182-188 Link Here
182
                        if (mappingNodeValue.isNullCapableValue()) {
193
                        if (mappingNodeValue.isNullCapableValue()) {
183
                            addNullCapableValue((NullCapableValue)mappingNodeValue);
194
                            addNullCapableValue((NullCapableValue)mappingNodeValue);
184
                        }
195
                        }
185
                        addChild(xmlFld.getXPathFragment(), mappingNodeValue, xmlDescriptor.getNamespaceResolver());
196
                        branchNode.addChild(xmlFld.getXPathFragment(), mappingNodeValue, xmlDescriptor.getNamespaceResolver());
186
                    }
197
                    }
187
                    continue;
198
                    continue;
188
                } else if (xmlMapping instanceof XMLObjectReferenceMapping) {
199
                } else if (xmlMapping instanceof XMLObjectReferenceMapping) {
Lines 283-290 Link Here
283
        }
294
        }
284
    }
295
    }
285
296
286
    public void addChild(XPathFragment xPathFragment, NodeValue nodeValue, NamespaceResolver namespaceResolver) {
297
    public XPathNode addChild(XPathFragment xPathFragment, NodeValue nodeValue, NamespaceResolver namespaceResolver) {
287
        getRootXPathNode().addChild(xPathFragment, nodeValue, namespaceResolver);
298
        return getRootXPathNode().addChild(xPathFragment, nodeValue, namespaceResolver);
288
    }
299
    }
289
300
290
    public AbstractRecord buildRow(AbstractRecord record, Object object, org.eclipse.persistence.internal.sessions.AbstractSession session) {
301
    public AbstractRecord buildRow(AbstractRecord record, Object object, org.eclipse.persistence.internal.sessions.AbstractSession session) {
Lines 315-325 Link Here
315
        boolean hasValue = false;
326
        boolean hasValue = false;
316
        NamespaceResolver namespaceResolver = ((XMLDescriptor)this.getDescriptor()).getNamespaceResolver();
327
        NamespaceResolver namespaceResolver = ((XMLDescriptor)this.getDescriptor()).getNamespaceResolver();
317
328
318
        List attributeChildren = rootXPathNode.getAttributeChildren();
329
        List<XPathNode> attributeChildren = rootXPathNode.getAttributeChildren();
319
        if (null != attributeChildren) {
330
        if (null != attributeChildren) {
320
            for (int x = 0, attributeChildrenSize=attributeChildren.size(); x < attributeChildrenSize; x++) {
331
            for (int x = 0, attributeChildrenSize=attributeChildren.size(); x < attributeChildrenSize; x++) {
321
                XPathNode attributeNode = (XPathNode)rootXPathNode.getAttributeChildren().get(x);
332
                hasValue = attributeChildren.get(x).marshal(marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance()) || hasValue;
322
                hasValue = attributeNode.marshal(marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance()) || hasValue;
323
            }
333
            }
324
        }
334
        }
325
335
Lines 327-337 Link Here
327
            hasValue = rootXPathNode.getAnyAttributeNode().marshal(marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance()) || hasValue;
337
            hasValue = rootXPathNode.getAnyAttributeNode().marshal(marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance()) || hasValue;
328
        }
338
        }
329
339
330
        List selfChildren = rootXPathNode.getSelfChildren();
340
        List<XPathNode> selfChildren = rootXPathNode.getSelfChildren();
331
        if (null != selfChildren) {
341
        if (null != selfChildren) {
332
            for (int x = 0, selfChildrenSize=selfChildren.size(); x < selfChildrenSize; x++) {
342
            for (int x = 0, selfChildrenSize=selfChildren.size(); x < selfChildrenSize; x++) {
333
                XPathNode childNode = (XPathNode)selfChildren.get(x);
343
                selfChildren.get(x).marshalSelfAttributes(marshalRecord, object, session, namespaceResolver, marshalRecord.getMarshaller());
334
                childNode.marshalSelfAttributes(marshalRecord, object, session, namespaceResolver, marshalRecord.getMarshaller());
335
            }
344
            }
336
        }
345
        }
337
346
Lines 375-379 Link Here
375
    public AbstractRecord createRecord(int size, AbstractSession session) {
384
    public AbstractRecord createRecord(int size, AbstractSession session) {
376
        return createRecord(session);
385
        return createRecord(session);
377
    }
386
    }
378
        
387
379
}
388
}
(-)src/org/eclipse/persistence/internal/oxm/UnmarshalXPathEngine.java (-3 / +11 lines)
Lines 252-261 Link Here
252
252
253
    private Node selectSingleAttribute(Node contextNode, XPathFragment xPathFragment, XMLNamespaceResolver xmlNamespaceResolver) {
253
    private Node selectSingleAttribute(Node contextNode, XPathFragment xPathFragment, XMLNamespaceResolver xmlNamespaceResolver) {
254
        if (xPathFragment.hasNamespace()) {
254
        if (xPathFragment.hasNamespace()) {
255
            String attributeNamespaceURI = xmlNamespaceResolver.resolveNamespacePrefix(xPathFragment.getPrefix());
255
            if(Node.ELEMENT_NODE == contextNode.getNodeType()) {
256
            return contextNode.getAttributes().getNamedItemNS(attributeNamespaceURI, xPathFragment.getLocalName());
256
                String attributeNamespaceURI = xmlNamespaceResolver.resolveNamespacePrefix(xPathFragment.getPrefix());
257
                return contextNode.getAttributes().getNamedItemNS(attributeNamespaceURI, xPathFragment.getLocalName());
258
            } else {
259
                return null;
260
            }
257
        } else {
261
        } else {
258
            return contextNode.getAttributes().getNamedItem(xPathFragment.getShortName());
262
            if(Node.ELEMENT_NODE == contextNode.getNodeType()) {
263
                return contextNode.getAttributes().getNamedItem(xPathFragment.getShortName());
264
            } else {
265
                return null;
266
            }
259
        }
267
        }
260
    }
268
    }
261
    
269
    
(-)src/org/eclipse/persistence/internal/oxm/XMLCollectionReferenceMappingMarshalNodeValue.java (+178 lines)
Line 0 Link Here
1
/*******************************************************************************
2
* Copyright (c) 1998, 2009 Oracle. All rights reserved.
3
* This program and the accompanying materials are made available under the
4
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
5
* which accompanies this distribution.
6
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
* and the Eclipse Distribution License is available at
8
* http://www.eclipse.org/org/documents/edl-v10.php.
9
*
10
* Contributors:
11
*     bdoughan - October 21/2009 - 2.0 - Initial implementation
12
******************************************************************************/
13
package org.eclipse.persistence.internal.oxm;
14
15
import java.util.List;
16
import javax.xml.namespace.QName;
17
18
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
19
import org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext;
20
import org.eclipse.persistence.internal.queries.ContainerPolicy;
21
import org.eclipse.persistence.internal.sessions.AbstractSession;
22
import org.eclipse.persistence.oxm.NamespaceResolver;
23
import org.eclipse.persistence.oxm.XMLDescriptor;
24
import org.eclipse.persistence.oxm.XMLField;
25
import org.eclipse.persistence.oxm.mappings.XMLCollectionReferenceMapping;
26
import org.eclipse.persistence.oxm.record.MarshalRecord;
27
28
public class XMLCollectionReferenceMappingMarshalNodeValue extends MappingNodeValue implements ContainerValue {
29
30
    private XMLCollectionReferenceMapping xmlCollectionReferenceMapping;
31
    private XPathNode branchNode;
32
33
    public XMLCollectionReferenceMappingMarshalNodeValue(XMLCollectionReferenceMapping xmlCollectionReferenceMapping) {
34
        this.xmlCollectionReferenceMapping = xmlCollectionReferenceMapping;
35
        branchNode = new XPathNode();
36
        NamespaceResolver namespaceResolver = ((XMLDescriptor) xmlCollectionReferenceMapping.getDescriptor()).getNamespaceResolver();
37
        List fkFields = xmlCollectionReferenceMapping.getFields();
38
        for(int x=0, fkFieldsSize=fkFields.size(); x<fkFieldsSize; x++) {
39
            XMLField fkField = (XMLField) fkFields.get(x);
40
            branchNode.addChild(fkField.getXPathFragment(), new XMLCollectionReferenceMappingFKMarshalNodeValue(xmlCollectionReferenceMapping, fkField), namespaceResolver);
41
        }
42
    }
43
44
    public Object getContainerInstance() {
45
        return getContainerPolicy().containerInstance();
46
    }
47
48
    public ContainerPolicy getContainerPolicy() {
49
        return xmlCollectionReferenceMapping.getContainerPolicy();
50
    }
51
52
    @Override
53
    public XMLCollectionReferenceMapping getMapping() {
54
        return xmlCollectionReferenceMapping;
55
    }
56
57
    public boolean getReuseContainer() {
58
        return xmlCollectionReferenceMapping.getReuseContainer();
59
    }
60
61
    public void setContainerInstance(Object object, Object containerInstance) {
62
        xmlCollectionReferenceMapping.setAttributeValueInObject(object, containerInstance);
63
    }
64
65
    @Override
66
    public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, AbstractSession session, NamespaceResolver namespaceResolver) {
67
        if (xmlCollectionReferenceMapping.isReadOnly()) {
68
            return false;
69
        }
70
71
        Object collection = xmlCollectionReferenceMapping.getAttributeAccessor().getAttributeValueFromObject(object);
72
        if (null == collection) {
73
            return false;
74
        }
75
        ContainerPolicy cp = getContainerPolicy();
76
        Object iterator = cp.iteratorFor(collection);
77
        if (cp.hasNext(iterator)) {
78
            XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
79
            marshalRecord.closeStartGroupingElements(groupingFragment);
80
        } else {
81
            return false;
82
        }
83
        if(xPathFragment != XPathFragment.SELF_FRAGMENT) {
84
            marshalRecord.openStartElement(xPathFragment, namespaceResolver);
85
        }
86
        while (cp.hasNext(iterator)) {
87
            Object objectValue = cp.next(iterator, session);
88
            marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, ObjectMarshalContext.getInstance());
89
        }
90
        if(xPathFragment != XPathFragment.SELF_FRAGMENT) {
91
            marshalRecord.endElement(xPathFragment, namespaceResolver);
92
        }
93
        return true;
94
    }
95
96
    @Override
97
    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object value, AbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
98
        if (xmlCollectionReferenceMapping.usesSingleNode()) {
99
            XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
100
            if (xPathFragment.isAttribute()) {
101
                marshalRecord.attribute(xPathFragment, namespaceResolver, (String) value);
102
                marshalRecord.closeStartGroupingElements(groupingFragment);
103
            } else {
104
                marshalRecord.closeStartGroupingElements(groupingFragment);
105
                marshalRecord.characters((String) value);
106
            }
107
        } else {
108
            for (int x = 0, size = marshalContext.getNonAttributeChildrenSize(branchNode); x < size; x++) {
109
                XPathNode xPathNode = (XPathNode)marshalContext.getNonAttributeChild(x, branchNode);
110
                xPathNode.marshal((MarshalRecord)marshalRecord, value, session, namespaceResolver, marshalRecord.getMarshaller(), marshalContext.getMarshalContext(x));
111
            }
112
            
113
        }
114
        return true;
115
    }
116
117
    @Override
118
    public boolean isMarshalNodeValue() {
119
        return !xmlCollectionReferenceMapping.usesSingleNode();
120
    }
121
122
    @Override
123
    public boolean isUnmarshalNodeValue() {
124
        return false;
125
    }
126
127
    private static class XMLCollectionReferenceMappingFKMarshalNodeValue extends MappingNodeValue {
128
129
        private XMLCollectionReferenceMapping xmlCollectionReferenceMapping;
130
        private XMLField xmlField;
131
132
        public XMLCollectionReferenceMappingFKMarshalNodeValue(XMLCollectionReferenceMapping xmlCollectionReferenceMapping, XMLField xmlField) {
133
            this.xmlCollectionReferenceMapping = xmlCollectionReferenceMapping;
134
            this.xmlField = xmlField;
135
        }
136
137
        @Override
138
        public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, AbstractSession session, NamespaceResolver namespaceResolver) {
139
            XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
140
            marshalRecord.closeStartGroupingElements(groupingFragment);
141
            return marshalSingleValue(xPathFragment, marshalRecord, null, object, session, namespaceResolver, ObjectMarshalContext.getInstance());
142
        }
143
144
        @Override
145
        public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object value, AbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
146
            Object fieldValue = xmlCollectionReferenceMapping.buildFieldValue(value, xmlField, session);
147
            if (fieldValue == null) {
148
                if(null != value) {
149
                    XMLField f2 = (XMLField) xmlCollectionReferenceMapping.getSourceToTargetKeyFieldAssociations().get(xmlField);
150
                    fieldValue = marshalRecord.getMarshaller().getXMLContext().getValueByXPath(value, f2.getXPath(), f2.getNamespaceResolver(), Object.class);
151
                }
152
                if(null == fieldValue) {
153
                    return false;
154
                }
155
            }
156
            QName schemaType = getSchemaType(xmlField, fieldValue, session);
157
            String stringValue = getValueToWrite(schemaType, fieldValue, (XMLConversionManager) session.getDatasourcePlatform().getConversionManager(), namespaceResolver);
158
            if (stringValue != null) {
159
                if (xPathFragment.isAttribute()) {
160
                    marshalRecord.attribute(xPathFragment, namespaceResolver, stringValue);
161
                    marshalRecord.closeStartElement();
162
                } else {
163
                    marshalRecord.closeStartElement();
164
                    marshalRecord.characters(stringValue);
165
                }
166
                return true;
167
            }
168
            return false;
169
        }
170
171
        @Override
172
        public XMLCollectionReferenceMapping getMapping() {
173
            return xmlCollectionReferenceMapping;
174
        }
175
176
    }
177
178
}
(-)src/org/eclipse/persistence/internal/oxm/XMLCollectionReferenceMappingNodeValue.java (-6 / +17 lines)
Lines 122-132 Link Here
122
     * Indicate if the next XPathFragment is an attribute or text() node.
122
     * Indicate if the next XPathFragment is an attribute or text() node.
123
     */
123
     */
124
    public boolean isOwningNode(XPathFragment xPathFragment) {
124
    public boolean isOwningNode(XPathFragment xPathFragment) {
125
        if (xmlCollectionReferenceMapping.usesSingleNode()) {
125
        if(isMarshalNodeValue()) {
126
            return xPathFragment.nameIsText() || xPathFragment.isAttribute();
126
            if (xmlCollectionReferenceMapping.usesSingleNode()) {
127
                return xPathFragment.nameIsText() || xPathFragment.isAttribute();
128
            }
129
            XPathFragment nextFragment = xPathFragment.getNextFragment();
130
            return (nextFragment != null) && (nextFragment.nameIsText() || nextFragment.isAttribute());
127
        }
131
        }
128
        XPathFragment nextFragment = xPathFragment.getNextFragment();
132
        return super.isOwningNode(xPathFragment);
129
        return (nextFragment != null) && (nextFragment.nameIsText() || nextFragment.isAttribute());
130
    }
133
    }
131
134
132
    public boolean isContainerValue() {
135
    public boolean isContainerValue() {
Lines 176-182 Link Here
176
                objectValue = cp.next(iterator, session);
179
                objectValue = cp.next(iterator, session);
177
                Object fieldValue = xmlCollectionReferenceMapping.buildFieldValue(objectValue, xmlField, session);
180
                Object fieldValue = xmlCollectionReferenceMapping.buildFieldValue(objectValue, xmlField, session);
178
                if (fieldValue == null) {
181
                if (fieldValue == null) {
179
                    return false;
182
                    if(null != objectValue) {
183
                        XMLField fkField = (XMLField) xmlCollectionReferenceMapping.getSourceToTargetKeyFieldAssociations().get(xmlField);
184
                        fieldValue = marshalRecord.getMarshaller().getXMLContext().getValueByXPath(objectValue, fkField.getXPath(), fkField.getNamespaceResolver(), Object.class);
185
                    }
180
                }
186
                }
181
                schemaType = getSchemaType(xmlField, fieldValue, session);
187
                schemaType = getSchemaType(xmlField, fieldValue, session);
182
                newValue = getValueToWrite(schemaType, fieldValue, (XMLConversionManager) session.getDatasourcePlatform().getConversionManager(), namespaceResolver);
188
                newValue = getValueToWrite(schemaType, fieldValue, (XMLConversionManager) session.getDatasourcePlatform().getConversionManager(), namespaceResolver);
Lines 262-265 Link Here
262
        return getMapping().getReuseContainer();
268
        return getMapping().getReuseContainer();
263
    }
269
    }
264
270
265
}
271
    @Override
272
    public boolean isMarshalNodeValue() {
273
        return xmlCollectionReferenceMapping.getFields().size() == 1 || xmlCollectionReferenceMapping.usesSingleNode();
274
    }
275
276
}
(-)src/org/eclipse/persistence/internal/oxm/XMLObjectReferenceMappingNodeValue.java (-1 / +7 lines)
Lines 155-161 Link Here
155
    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object targetObject, AbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
155
    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object targetObject, AbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
156
        Object fieldValue = xmlObjectReferenceMapping.buildFieldValue(targetObject, xmlField, session);
156
        Object fieldValue = xmlObjectReferenceMapping.buildFieldValue(targetObject, xmlField, session);
157
        if (fieldValue == null) {
157
        if (fieldValue == null) {
158
            return false;
158
            if(null != targetObject) {
159
                XMLField fkField = (XMLField) xmlObjectReferenceMapping.getSourceToTargetKeyFieldAssociations().get(xmlField);
160
                fieldValue = marshalRecord.getMarshaller().getXMLContext().getValueByXPath(targetObject, fkField.getXPath(), fkField.getNamespaceResolver(), Object.class);
161
            }
162
            if(null == fieldValue) {
163
                return false;
164
            }
159
        }
165
        }
160
166
161
        QName schemaType = getSchemaType(xmlField, fieldValue, session);
167
        QName schemaType = getSchemaType(xmlField, fieldValue, session);
(-)src/org/eclipse/persistence/internal/oxm/XPathNode.java (-6 / +7 lines)
Lines 109-123 Link Here
109
        this.parent = parent;
109
        this.parent = parent;
110
    }
110
    }
111
111
112
    public List getAttributeChildren() {
112
    public List<XPathNode> getAttributeChildren() {
113
        return this.attributeChildren;
113
        return this.attributeChildren;
114
    }
114
    }
115
115
116
    public List getNonAttributeChildren() {
116
    public List<XPathNode> getNonAttributeChildren() {
117
        return this.nonAttributeChildren;
117
        return this.nonAttributeChildren;
118
    }
118
    }
119
119
120
    public List getSelfChildren() {
120
    public List<XPathNode> getSelfChildren() {
121
        return this.selfChildren;
121
        return this.selfChildren;
122
    }
122
    }
123
123
Lines 183-189 Link Here
183
        }
183
        }
184
    }
184
    }
185
185
186
    public void addChild(XPathFragment anXPathFragment, NodeValue aNodeValue, NamespaceResolver namespaceResolver) {
186
    public XPathNode addChild(XPathFragment anXPathFragment, NodeValue aNodeValue, NamespaceResolver namespaceResolver) {
187
        if (null != anXPathFragment && anXPathFragment.nameIsText()) {
187
        if (null != anXPathFragment && anXPathFragment.nameIsText()) {
188
            if (aNodeValue.isOwningNode(anXPathFragment)) {
188
            if (aNodeValue.isOwningNode(anXPathFragment)) {
189
                XPathNode textXPathNode = new XPathNode();
189
                XPathNode textXPathNode = new XPathNode();
Lines 200-206 Link Here
200
                    nonAttributeChildren = new ArrayList();
200
                    nonAttributeChildren = new ArrayList();
201
                }
201
                }
202
                nonAttributeChildren.add(textXPathNode);
202
                nonAttributeChildren.add(textXPathNode);
203
                return;
203
                return textXPathNode;
204
            }
204
            }
205
        }
205
        }
206
206
Lines 255-261 Link Here
255
                }
255
                }
256
                setAnyNode(xPathNode);
256
                setAnyNode(xPathNode);
257
            }
257
            }
258
            return;
258
            return xPathNode;
259
        }
259
        }
260
        boolean isSelfFragment = XPathFragment.SELF_FRAGMENT.equals(anXPathFragment);
260
        boolean isSelfFragment = XPathFragment.SELF_FRAGMENT.equals(anXPathFragment);
261
261
Lines 289-294 Link Here
289
            XPathFragment nextFragment = anXPathFragment.getNextFragment();
289
            XPathFragment nextFragment = anXPathFragment.getNextFragment();
290
            xPathNode.addChild(nextFragment, aNodeValue, namespaceResolver);
290
            xPathNode.addChild(nextFragment, aNodeValue, namespaceResolver);
291
        }
291
        }
292
        return xPathNode;
292
    }
293
    }
293
294
294
    public boolean marshal(MarshalRecord marshalRecord, Object object, AbstractSession session, NamespaceResolver namespaceResolver, XMLMarshaller marshaller, MarshalContext marshalContext) {
295
    public boolean marshal(MarshalRecord marshalRecord, Object object, AbstractSession session, NamespaceResolver namespaceResolver, XMLMarshaller marshaller, MarshalContext marshalContext) {
(-)src/org/eclipse/persistence/oxm/mappings/XMLCollectionReferenceMapping.java (+31 lines)
Lines 24-29 Link Here
24
import org.eclipse.persistence.exceptions.DatabaseException;
24
import org.eclipse.persistence.exceptions.DatabaseException;
25
import org.eclipse.persistence.exceptions.DescriptorException;
25
import org.eclipse.persistence.exceptions.DescriptorException;
26
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
26
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
27
import org.eclipse.persistence.internal.helper.DatabaseField;
27
import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
28
import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
28
import org.eclipse.persistence.internal.oxm.Reference;
29
import org.eclipse.persistence.internal.oxm.Reference;
29
import org.eclipse.persistence.internal.oxm.ReferenceResolver;
30
import org.eclipse.persistence.internal.oxm.ReferenceResolver;
Lines 62-67 Link Here
62
public class XMLCollectionReferenceMapping extends XMLObjectReferenceMapping implements ContainerMapping {
63
public class XMLCollectionReferenceMapping extends XMLObjectReferenceMapping implements ContainerMapping {
63
    protected ContainerPolicy containerPolicy; // type of container used to hold the aggregate objects
64
    protected ContainerPolicy containerPolicy; // type of container used to hold the aggregate objects
64
    private static final String SPACE = " ";
65
    private static final String SPACE = " ";
66
    private DatabaseField field;
65
    private boolean usesSingleNode;
67
    private boolean usesSingleNode;
66
    private boolean reuseContainer;
68
    private boolean reuseContainer;
67
69
Lines 77-82 Link Here
77
        this.usesSingleNode = false;
79
        this.usesSingleNode = false;
78
    }
80
    }
79
81
82
    public DatabaseField getField() {
83
        return field;
84
    }
85
86
    public void setField(DatabaseField field) {
87
        this.field = field;
88
    }
89
90
    
91
    /**
92
     * Get the XPath String
93
     * @return String the XPath String associated with this Mapping
94
     */
95
    public String getXPath() {
96
        return getField().getName();
97
    }
98
99
    /**
100
     * Set the Mapping field name attribute to the given XPath String
101
     * @param xpathString String
102
     */
103
    public void setXPath(String xpathString) {
104
        this.setField(new XMLField(xpathString));
105
    }
106
80
    /**    
107
    /**    
81
     * INTERNAL:
108
     * INTERNAL:
82
     * Retrieve the target object's primary key value that is mapped to a given
109
     * Retrieve the target object's primary key value that is mapped to a given
Lines 141-146 Link Here
141
        }        
168
        }        
142
169
143
        ClassDescriptor descriptor = session.getClassDescriptor(getReferenceClass());
170
        ClassDescriptor descriptor = session.getClassDescriptor(getReferenceClass());
171
        DatabaseField typedField = descriptor.getTypedField(tgtFld);
144
        Class type = descriptor.getTypedField(tgtFld).getType();
172
        Class type = descriptor.getTypedField(tgtFld).getType();
145
        XMLConversionManager xmlConversionManager = (XMLConversionManager) session.getDatasourcePlatform().getConversionManager();
173
        XMLConversionManager xmlConversionManager = (XMLConversionManager) session.getDatasourcePlatform().getConversionManager();
146
        for (StringTokenizer stok = new StringTokenizer((String) object); stok.hasMoreTokens();) {
174
        for (StringTokenizer stok = new StringTokenizer((String) object); stok.hasMoreTokens();) {
Lines 166-171 Link Here
166
     */
194
     */
167
    public void initialize(AbstractSession session) throws DescriptorException {
195
    public void initialize(AbstractSession session) throws DescriptorException {
168
        super.initialize(session);
196
        super.initialize(session);
197
        if(null != getField()) {
198
            setField(getDescriptor().buildField(getField()));
199
        }
169
        ContainerPolicy cp = getContainerPolicy();
200
        ContainerPolicy cp = getContainerPolicy();
170
        if (cp != null) {
201
        if (cp != null) {
171
            if (cp.getContainerClass() == null) {
202
            if (cp.getContainerClass() == null) {
(-)src/org/eclipse/persistence/oxm/record/UnmarshalRecord.java (-6 / +18 lines)
Lines 515-526 Link Here
515
        // if the object has any primary key fields set, add it to the cache
515
        // if the object has any primary key fields set, add it to the cache
516
        if (session.isUnitOfWork()) {
516
        if (session.isUnitOfWork()) {
517
            ClassDescriptor xmlDescriptor = treeObjectBuilder.getDescriptor();
517
            ClassDescriptor xmlDescriptor = treeObjectBuilder.getDescriptor();
518
            if ((xmlDescriptor != null) && (xmlDescriptor.getPrimaryKeyFieldNames().size() > 0)) {
518
            if(null != xmlDescriptor) {
519
                Vector pk = treeObjectBuilder.extractPrimaryKeyFromObject(currentObject, session);
519
                List primaryKeyFields = xmlDescriptor.getPrimaryKeyFields();
520
                CacheKey key = session.getIdentityMapAccessorInstance().acquireDeferredLock(pk, xmlDescriptor.getJavaClass(), xmlDescriptor);
520
                int primaryKeyFieldsSize = primaryKeyFields.size();
521
                key.setRecord(this);
521
                if (primaryKeyFieldsSize > 0) {
522
                key.setObject(currentObject);
522
                    Vector pk = treeObjectBuilder.extractPrimaryKeyFromObject(currentObject, session);
523
                key.releaseDeferredLock();
523
                    if(pk.contains(null)) {
524
                        for(int x=0; x<primaryKeyFieldsSize; x++) {
525
                            if(null == pk.get(x)) {
526
                                XMLField pkField = (XMLField) xmlDescriptor.getPrimaryKeyFields().get(x);
527
                                pk.set(x, getUnmarshaller().getXMLContext().getValueByXPath(currentObject, pkField.getXPath(), pkField.getNamespaceResolver(), Object.class));
528
                            }
529
                        }
530
                    }
531
                    CacheKey key = session.getIdentityMapAccessorInstance().acquireDeferredLock(pk, xmlDescriptor.getJavaClass(), xmlDescriptor);
532
                    key.setRecord(this);
533
                    key.setObject(currentObject);
534
                    key.releaseDeferredLock();
535
                }
524
            }
536
            }
525
        }
537
        }
526
538
(-)src/org/eclipse/persistence/oxm/XMLContext.java (-2 / +9 lines)
Lines 765-772 Link Here
765
        } 
765
        } 
766
        Session session = this.getSession(object); 
766
        Session session = this.getSession(object); 
767
        XMLDescriptor xmlDescriptor = (XMLDescriptor) session.getDescriptor(object); 
767
        XMLDescriptor xmlDescriptor = (XMLDescriptor) session.getDescriptor(object); 
768
        StringTokenizer stringTokenizer = new StringTokenizer(xPath, "/"); 
768
        StringTokenizer stringTokenizer = new StringTokenizer(xPath, "/");
769
        return getValueByXPath(object, xmlDescriptor.getObjectBuilder(), stringTokenizer, namespaceResolver, returnType);
769
        T value = getValueByXPath(object, xmlDescriptor.getObjectBuilder(), stringTokenizer, namespaceResolver, returnType);
770
        if(null == value) {
771
            DatabaseMapping selfMapping = xmlDescriptor.getObjectBuilder().getMappingForField(new XMLField("."));
772
            if(null != selfMapping) {
773
                return getValueByXPath(selfMapping.getAttributeValueFromObject(object), selfMapping.getReferenceDescriptor().getObjectBuilder(), new StringTokenizer(xPath, "/"), ((XMLDescriptor) selfMapping.getReferenceDescriptor()).getNamespaceResolver(), returnType);
774
            }
775
        }
776
        return value;
770
    } 
777
    } 
771
 
778
 
772
    private <T> T getValueByXPath(Object object, ObjectBuilder objectBuilder, StringTokenizer stringTokenizer, NamespaceResolver namespaceResolver, Class<T> returnType) {
779
    private <T> T getValueByXPath(Object object, ObjectBuilder objectBuilder, StringTokenizer stringTokenizer, NamespaceResolver namespaceResolver, Class<T> returnType) {
(-)src/org/eclipse/persistence/oxm/XMLDescriptor.java (-2 / +60 lines)
Lines 17-22 Link Here
17
import java.util.HashMap;
17
import java.util.HashMap;
18
import java.util.Iterator;
18
import java.util.Iterator;
19
import java.util.List;
19
import java.util.List;
20
import java.util.StringTokenizer;
20
import java.util.Vector;
21
import java.util.Vector;
21
import javax.xml.namespace.QName;
22
import javax.xml.namespace.QName;
22
import org.eclipse.persistence.descriptors.ClassDescriptor;
23
import org.eclipse.persistence.descriptors.ClassDescriptor;
Lines 30-35 Link Here
30
import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
31
import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
31
import org.eclipse.persistence.internal.identitymaps.AbstractIdentityMap;
32
import org.eclipse.persistence.internal.identitymaps.AbstractIdentityMap;
32
import org.eclipse.persistence.internal.oxm.TreeObjectBuilder;
33
import org.eclipse.persistence.internal.oxm.TreeObjectBuilder;
34
import org.eclipse.persistence.internal.oxm.XPathFragment;
33
import org.eclipse.persistence.internal.sessions.AbstractRecord;
35
import org.eclipse.persistence.internal.sessions.AbstractRecord;
34
import org.eclipse.persistence.internal.sessions.AbstractSession;
36
import org.eclipse.persistence.internal.sessions.AbstractSession;
35
import org.eclipse.persistence.mappings.DatabaseMapping;
37
import org.eclipse.persistence.mappings.DatabaseMapping;
Lines 806-810 Link Here
806
    public void setResultAlwaysXMLRoot(boolean resultAlwaysXMLRoot) {
808
    public void setResultAlwaysXMLRoot(boolean resultAlwaysXMLRoot) {
807
        this.resultAlwaysXMLRoot = resultAlwaysXMLRoot;
809
        this.resultAlwaysXMLRoot = resultAlwaysXMLRoot;
808
    }
810
    }
809
    
811
810
}
812
    @Override
813
    public DatabaseField getTypedField(DatabaseField field) {
814
        XMLField foundField = (XMLField) super.getTypedField(field);
815
        if(null != foundField) {
816
            return foundField;
817
        }
818
        StringTokenizer stringTokenizer = new StringTokenizer(field.getName(), "/");
819
        DatabaseField typedField = getTypedField(stringTokenizer);
820
        if(null == typedField) {
821
            DatabaseMapping selfMapping = objectBuilder.getMappingForField(new XMLField("."));
822
            if(null != selfMapping) {
823
                return selfMapping.getReferenceDescriptor().getTypedField(field); 
824
            }
825
        }
826
        return typedField;
827
    }
828
829
    protected DatabaseField getTypedField(StringTokenizer stringTokenizer) {
830
        String xPath = ""; 
831
        XMLField xmlField = new XMLField(); 
832
        xmlField.setNamespaceResolver(namespaceResolver); 
833
        while(stringTokenizer.hasMoreElements()) {
834
            String nextToken = stringTokenizer.nextToken();
835
            xmlField.setXPath(xPath + nextToken);
836
            xmlField.initialize();
837
            DatabaseMapping mapping = objectBuilder.getMappingForField(xmlField); 
838
            if(null == mapping) {
839
                XPathFragment xPathFragment = new XPathFragment(nextToken);
840
                if(xPathFragment.getIndexValue() > 0) {
841
                    xmlField.setXPath(xPath + nextToken.substring(0, nextToken.indexOf('[')));
842
                    xmlField.initialize();
843
                    mapping = objectBuilder.getMappingForField(xmlField);
844
                    if(null != mapping) {
845
                        if(mapping.isCollectionMapping()) {
846
                            if(mapping.getContainerPolicy().isListPolicy()) {
847
                                if(stringTokenizer.hasMoreElements()) {
848
                                    return ((XMLDescriptor) mapping.getReferenceDescriptor()).getTypedField(stringTokenizer); 
849
                                } else {
850
                                    return mapping.getField();
851
                                }
852
                            }
853
                        }
854
                    }
855
                }
856
            } else {
857
                if(stringTokenizer.hasMoreElements()) {
858
                    return ((XMLDescriptor) mapping.getReferenceDescriptor()).getTypedField(stringTokenizer);
859
                } else {
860
                    return mapping.getField();
861
                } 
862
            } 
863
            xPath = xPath + nextToken + "/"; 
864
        }
865
        return null; 
866
    }
867
868
}

Return to bug 285889