/** * INTERNAL: When using the SAX or DOM Platform, this method is responsible for marshalling null * values for the XML Direct Mapping. * * @param xPathFragment * @param marshalRecord * @param object * @param session * @param namespaceResolver * @return true if this method caused any nodes to be marshaled, else false. */ public boolean directMarshal( XPathFragment xPathFragment, MarshalRecord marshalRecord, // Object object, CoreSession session, NamespaceResolver namespaceResolver) { // Handle attributes - XSI_NIL, ABSENT_NODE have the same behavior if (xPathFragment.isAttribute()) { // Write out an empty attribute if (marshalNullRepresentation == XMLNullRepresentationType.EMPTY_NODE) { marshalRecord.emptyAttribute(xPathFragment, namespaceResolver); return true; } else { // XSI_NIL attributes are invalid - and are ignored // ABSENT_NODE - Write out nothing return false; } } else { // Nillable: write out xsi:nil="true" attribute in empty element if (marshalNullRepresentation == XMLNullRepresentationType.XSI_NIL) { marshalRecord.nilSimple(namespaceResolver); return true; } else { // EMPTY_NODE - Write out empty element if (marshalNullRepresentation == XMLNullRepresentationType.EMPTY_NODE) { marshalRecord.emptySimple(namespaceResolver); return true; } else { // ABSENT_NODE - Write out nothing return false; } } } }
/** * INTERNAL: Private function to process or create an entry in the NamespaceResolver for the xsi * prefix. * * @param namespaceResolver * @return xsi prefix */ protected String processNamespaceResolverForXSIPrefix( NamespaceResolver namespaceResolver, MarshalRecord marshalRecord) { String xsiPrefix; if (null == namespaceResolver) { // add new xsi entry into the properties map xsiPrefix = Constants.SCHEMA_INSTANCE_PREFIX; marshalRecord.namespaceDeclaration( xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); } else { // find an existing xsi entry in the map xsiPrefix = namespaceResolver.resolveNamespaceURI( javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); if (null == xsiPrefix) { xsiPrefix = namespaceResolver.generatePrefix(Constants.SCHEMA_INSTANCE_PREFIX); marshalRecord.namespaceDeclaration( xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); } } return xsiPrefix; }
/** * INTERNAL: When using the SAX Platform, this method is responsible for marshalling null values * for the XML Composite Object Mapping. * * @param xPathFragment * @param marshalRecord * @param object * @param session * @param namespaceResolver * @return true if this method caused any nodes to be marshaled, else false. */ public boolean compositeObjectMarshal( XPathFragment xPathFragment, MarshalRecord marshalRecord, // Object object, CoreSession session, NamespaceResolver namespaceResolver) { if (marshalNullRepresentation == XMLNullRepresentationType.ABSENT_NODE) { return false; } // Nillable else if (marshalNullRepresentation == XMLNullRepresentationType.XSI_NIL) { marshalRecord.nilComplex(xPathFragment, namespaceResolver); return true; } else if (marshalNullRepresentation == XMLNullRepresentationType.EMPTY_NODE) { // Optional and Required // This call is really only valid when using DOM - TBD false // Write out empty element - we need to differentiate between // object=null and object=new Object() with null fields and 0-numeric primitive values // EMPTY_NODE - Write out empty element - Required marshalRecord.emptyComplex(xPathFragment, namespaceResolver); return true; } return false; }
@Override public boolean marshalAttributes( MarshalRecord marshalRecord, Object object, CoreAbstractSession session) { lazyInitialize(); boolean hasValue = false; NamespaceResolver namespaceResolver = ((Descriptor) descriptor).getNamespaceResolver(); List<XPathNode> attributeChildren = rootXPathNode.getAttributeChildren(); if (null != attributeChildren) { ObjectMarshalContext objectMarshalContext = ObjectMarshalContext.getInstance(); for (XPathNode anAttributeChildren : attributeChildren) { hasValue = anAttributeChildren.marshal( marshalRecord, object, session, namespaceResolver, null, objectMarshalContext, null) || hasValue; } } if (rootXPathNode.getAnyAttributeNode() != null) { hasValue = rootXPathNode .getAnyAttributeNode() .marshal( marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance(), null) || hasValue; } List<XPathNode> selfChildren = rootXPathNode.getSelfChildren(); if (null != selfChildren) { for (XPathNode selfXPathNode : selfChildren) { NodeValue marshalNodeValue = selfXPathNode.getMarshalNodeValue(); if (marshalNodeValue instanceof MappingNodeValue) { Mapping selfMapping = ((MappingNodeValue) marshalNodeValue).getMapping(); Object value = selfMapping.getAttributeValueFromObject(object); Descriptor referenceDescriptor = (Descriptor) selfMapping.getReferenceDescriptor(); Descriptor valueDescriptor; if (value != null && (referenceDescriptor == null || referenceDescriptor.hasInheritance())) { valueDescriptor = (Descriptor) session.getDescriptor(value.getClass()); } else { valueDescriptor = referenceDescriptor; } if (null != valueDescriptor) { marshalRecord.addXsiTypeAndClassIndicatorIfRequired( valueDescriptor, referenceDescriptor, (Field) selfMapping.getField(), false); } } selfXPathNode.marshalSelfAttributes( marshalRecord, object, session, namespaceResolver, marshalRecord.getMarshaller()); } } return hasValue; }
@Override public XMLRecord buildRow( XMLRecord record, Object object, CoreAbstractSession session, Marshaller marshaller, XPathFragment rootFragment) { lazyInitialize(); XPathNode textNode = rootXPathNode.getTextNode(); List<XPathNode> nonAttributeChildren = rootXPathNode.getNonAttributeChildren(); if (null == textNode && null == nonAttributeChildren) { return record; } Descriptor xmlDescriptor = (Descriptor) descriptor; XPathNode node = rootXPathNode; MarshalRecord marshalRecord = (MarshalRecord) record; QName schemaType = null; if (marshalRecord.getCycleDetectionStack().contains(object, marshaller.isEqualUsingIdenity())) { if (cycleRecoverableClass == null) { initCycleRecoverableClasses(); } if (cycleRecoverableClass != null && cycleRecoverableClass.isAssignableFrom(object.getClass())) { try { Object jaxbMarshaller = marshaller.getProperty(Constants.JAXB_MARSHALLER); // Create a proxy instance of CycleRecoverable$Context, a parameter to // the onCycleDetected method Object contextProxy = CycleRecoverableContextProxy.getProxy(cycleRecoverableContextClass, jaxbMarshaller); // Invoke onCycleDetected method, passing in proxy, and reset // 'object' to the returned value Method onCycleDetectedMethod = object .getClass() .getMethod(ON_CYCLE_DETECTED, new Class[] {cycleRecoverableContextClass}); object = PrivilegedAccessHelper.invokeMethod( onCycleDetectedMethod, object, new Object[] {contextProxy}); } catch (Exception e) { throw XMLMarshalException.marshalException(e); } // Returned object might have a different descriptor xmlDescriptor = (Descriptor) session.getDescriptor(object.getClass()); if (xmlDescriptor != null) { node = ((ObjectBuilder) xmlDescriptor.getObjectBuilder()).getRootXPathNode(); } else { node = null; } // Push new object marshalRecord.getCycleDetectionStack().push(object); // Write xsi:type if onCycleDetected returned an object of a type different than the one // mapped if (xmlDescriptor != descriptor) { if (xmlDescriptor == null) { schemaType = record.getConversionManager().schemaType(object.getClass()); } else { schemaType = xmlDescriptor.getSchemaReference().getSchemaContextAsQName(); } marshalRecord.writeXsiTypeAttribute( xmlDescriptor, schemaType.getNamespaceURI(), schemaType.getLocalPart(), schemaType.getPrefix(), false); } } else { // Push the duplicate object anyway, so that we can get the complete cycle string marshalRecord.getCycleDetectionStack().push(object); throw XMLMarshalException.objectCycleDetected( marshalRecord.getCycleDetectionStack().getCycleString()); } } else { marshalRecord.getCycleDetectionStack().push(object); } NamespaceResolver namespaceResolver = null; if (xmlDescriptor != null) { namespaceResolver = xmlDescriptor.getNamespaceResolver(); } MarshalContext marshalContext = null; if (xmlDescriptor != null && xmlDescriptor.isSequencedObject()) { SequencedObject sequencedObject = (SequencedObject) object; marshalContext = new SequencedMarshalContext(sequencedObject.getSettings()); } else { marshalContext = ObjectMarshalContext.getInstance(); } if (null == nonAttributeChildren) { textNode.marshal( (MarshalRecord) record, object, session, namespaceResolver, marshaller, marshalContext, rootFragment); } else { if (node == null) { // No descriptor for this object, so manually create a MappingNodeValue and marshal it XPathNode n = new XPathNode(); CompositeObjectMapping m = new XMLCompositeObjectMapping(); m.setXPath("."); XMLCompositeObjectMappingNodeValue nv = new XMLCompositeObjectMappingNodeValue(m); n.setMarshalNodeValue(nv); nv.marshalSingleValue( new XPathFragment("."), marshalRecord, null, object, session, namespaceResolver, marshalContext); } else { for (int x = 0, size = marshalContext.getNonAttributeChildrenSize(node); x < size; x++) { XPathNode xPathNode = (XPathNode) marshalContext.getNonAttributeChild(x, node); xPathNode.marshal( (MarshalRecord) record, object, session, namespaceResolver, marshaller, marshalContext.getMarshalContext(x), rootFragment); } } } marshalRecord.getCycleDetectionStack().pop(); return record; }