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 |
} |