Index: foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/XMLAnyObjectMappingNodeValue.java =================================================================== --- foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/XMLAnyObjectMappingNodeValue.java (revision 3701) +++ foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/XMLAnyObjectMappingNodeValue.java (working copy) @@ -30,6 +30,7 @@ import org.eclipse.persistence.oxm.XMLDescriptor; import org.eclipse.persistence.oxm.XMLMarshaller; import org.eclipse.persistence.oxm.XMLRoot; +import org.eclipse.persistence.oxm.mappings.UnmarshalKeepAsElementPolicy; import org.eclipse.persistence.oxm.mappings.XMLAnyObjectMapping; import org.eclipse.persistence.oxm.record.MarshalRecord; import org.eclipse.persistence.oxm.record.UnmarshalRecord; @@ -187,7 +188,27 @@ xmlDescriptor = xmlContext.getDescriptor(qname); } workingDescriptor = xmlDescriptor; + UnmarshalKeepAsElementPolicy policy = xmlAnyObjectMapping.getKeepAsElementPolicy(); + if ((xmlDescriptor == null) && (policy == UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT)) { + //setup handler stuff + SAXFragmentBuilder builder = unmarshalRecord.getFragmentBuilder(); + builder.setOwningRecord(unmarshalRecord); + try { + String namespaceURI = ""; + if (xPathFragment.getNamespaceURI() != null) { + namespaceURI = xPathFragment.getNamespaceURI(); + } + String qName = xPathFragment.getLocalName(); + if (xPathFragment.getPrefix() != null) { + qName = xPathFragment.getPrefix() + ":" + qName; + } + builder.startElement(namespaceURI, xPathFragment.getLocalName(), qName, atts); + unmarshalRecord.getXMLReader().setContentHandler(builder); + } catch (SAXException ex) { + } + } + if (null == xmlDescriptor) { //need to give to special handler, let it find out what to do depending on if this is simple or complex content AnyMappingContentHandler handler = new AnyMappingContentHandler(unmarshalRecord, xmlAnyObjectMapping.usesXMLRoot()); @@ -230,8 +251,20 @@ } } } else { - // TEXT VALUE - endElementProcessText(unmarshalRecord, xPathFragment); + SAXFragmentBuilder builder = unmarshalRecord.getFragmentBuilder(); + + UnmarshalKeepAsElementPolicy keepAsElementPolicy = xmlAnyObjectMapping.getKeepAsElementPolicy(); + + if ((keepAsElementPolicy == UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT) && (builder.getNodes().size() != 0)) { + Object node = builder.getNodes().pop(); + if(xmlAnyObjectMapping.getConverter() != null) { + node = xmlAnyObjectMapping.getConverter().convertDataValueToObjectValue(node, unmarshalRecord.getSession(), unmarshalRecord.getUnmarshaller()); + } + unmarshalRecord.setAttributeValue(node, xmlAnyObjectMapping); + } else { + // TEXT VALUE + endElementProcessText(unmarshalRecord, xPathFragment); + } } } @@ -296,7 +329,6 @@ if (generatedNamespace != null) { marshalRecord.attribute(XMLConstants.XMLNS_URL, XMLConstants.XMLNS_URL, XMLConstants.XMLNS + ":" + generatedNamespace.getPrefix(), generatedNamespace.getNamespaceURI()); } - if (qname != null) { String prefix = marshalRecord.getNamespaceResolver().resolveNamespaceURI(qname.getNamespaceURI()); if ((prefix == null) || prefix.equals("")) { @@ -309,7 +341,11 @@ } } - marshalRecord.characters((String) value); + if (value instanceof String) { + marshalRecord.characters((String) value); + } else { + marshalRecord.node((org.w3c.dom.Node) value, marshalRecord.getNamespaceResolver()); + } if (xmlRootFragment != null) { marshalRecord.endElement(xmlRootFragment, namespaceResolver); @@ -319,5 +355,5 @@ public XMLAnyObjectMapping getMapping() { return xmlAnyObjectMapping; } - + } \ No newline at end of file Index: foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/oxm/mappings/XMLAnyObjectMapping.java =================================================================== --- foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/oxm/mappings/XMLAnyObjectMapping.java (revision 3701) +++ foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/oxm/mappings/XMLAnyObjectMapping.java (working copy) @@ -160,6 +160,7 @@ private boolean useXMLRoot; private boolean areOtherMappingInThisContext = true; private XMLConverter converter; + private UnmarshalKeepAsElementPolicy keepAsElementPolicy; public XMLAnyObjectMapping() { useXMLRoot = false; @@ -301,10 +302,11 @@ int i = 0; int length = unmappedChildren.size(); while (iter.hasNext()) { + Object objectValue = null; org.w3c.dom.Node next = (Node) iter.next(); if (next.getNodeType() == Node.TEXT_NODE) { if ((i == (length - 1)) || (next.getNodeValue().trim().length() > 0)) { - Object objectValue = next.getNodeValue(); + objectValue = next.getNodeValue(); if(getConverter() != null) { objectValue = getConverter().convertDataValueToObjectValue(objectValue, session, record.getUnmarshaller()); } @@ -320,13 +322,22 @@ if (!useXMLRoot) { referenceDescriptor = getDescriptor(nestedRecord, session, null); - if (referenceDescriptor != null) { + if (referenceDescriptor != null && keepAsElementPolicy != UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT) { ObjectBuilder builder = referenceDescriptor.getObjectBuilder(); - Object objectValue = builder.buildObject(query, nestedRecord, joinManager); + objectValue = builder.buildObject(query, nestedRecord, joinManager); if(getConverter() != null) { objectValue = getConverter().convertDataValueToObjectValue(objectValue, session, record.getUnmarshaller()); } return objectValue; + } else { + if (keepAsElementPolicy == UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT) { + XMLPlatformFactory.getInstance().getXMLPlatform().namespaceQualifyFragment((Element) next); + objectValue = next; + if(getConverter() != null) { + objectValue = getConverter().convertDataValueToObjectValue(objectValue, session, record.getUnmarshaller()); + } + return objectValue; + } } } else { String schemaType = ((Element) next).getAttributeNS(XMLConstants.SCHEMA_INSTANCE_URL, XMLConstants.SCHEMA_TYPE_ATTRIBUTE); @@ -355,12 +366,21 @@ } if (referenceDescriptor != null) { ObjectBuilder builder = referenceDescriptor.getObjectBuilder(); - Object objectValue = builder.buildObject(query, nestedRecord, joinManager); + objectValue = builder.buildObject(query, nestedRecord, joinManager); Object updated = ((XMLDescriptor) referenceDescriptor).wrapObjectInXMLRoot(objectValue, next.getNamespaceURI(), next.getLocalName(), next.getPrefix(), false); if(getConverter() != null) { updated = getConverter().convertDataValueToObjectValue(objectValue, session, record.getUnmarshaller()); } return updated; + } else if ((referenceDescriptor != null) && (getKeepAsElementPolicy() != UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT)) { + ObjectBuilder builder = referenceDescriptor.getObjectBuilder(); + objectValue = builder.buildObject(query, nestedRecord, joinManager); + Object updated = ((XMLDescriptor) referenceDescriptor).wrapObjectInXMLRoot(objectValue, next.getNamespaceURI(), next.getLocalName(), next.getPrefix(), false); + + if(getConverter() != null) { + updated = getConverter().convertDataValueToObjectValue(updated, session, record.getUnmarshaller()); + } + return updated; } else { Object value = null; Node textchild = ((Element) next).getFirstChild(); @@ -691,4 +711,12 @@ public void setConverter(XMLConverter converter) { this.converter = converter; } + + public UnmarshalKeepAsElementPolicy getKeepAsElementPolicy() { + return keepAsElementPolicy; + } + + public void setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy keepAsElementPolicy) { + this.keepAsElementPolicy = keepAsElementPolicy; + } } Index: moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/compiler/MappingsGenerator.java =================================================================== --- moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/compiler/MappingsGenerator.java (revision 3701) +++ moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/compiler/MappingsGenerator.java (working copy) @@ -28,11 +28,8 @@ import org.eclipse.persistence.oxm.annotations.*; import org.eclipse.persistence.jaxb.javamodel.Helper; import org.eclipse.persistence.jaxb.javamodel.JavaClass; -import org.eclipse.persistence.jaxb.javamodel.JavaField; -import org.eclipse.persistence.jaxb.javamodel.JavaHasAnnotations; import org.eclipse.persistence.jaxb.javamodel.JavaMethod; import org.eclipse.persistence.jaxb.JAXBEnumTypeConverter; -import org.eclipse.persistence.internal.helper.ClassConstants; import org.eclipse.persistence.internal.jaxb.JaxbClassLoader; import org.eclipse.persistence.internal.jaxb.DomHandlerConverter; import org.eclipse.persistence.internal.jaxb.MultiArgInstantiationPolicy; @@ -41,7 +38,6 @@ import org.eclipse.persistence.mappings.AttributeAccessor; import org.eclipse.persistence.mappings.DatabaseMapping; - import org.eclipse.persistence.oxm.*; import org.eclipse.persistence.oxm.mappings.*; import org.eclipse.persistence.oxm.mappings.converters.XMLRootConverter; @@ -272,7 +268,11 @@ if (property.isSwaAttachmentRef() || property.isMtomAttachment()) { generateBinaryMapping(property, descriptor, namespaceInfo); } else { - generateDirectMapping(property, descriptor, namespaceInfo); + if (referenceClass.getQualifiedName().equals("java.lang.Object")) { + generateAnyObjectMapping(property, descriptor, namespaceInfo); + } else { + generateDirectMapping(property, descriptor, namespaceInfo); + } } } } @@ -561,6 +561,19 @@ descriptor.addMapping(mapping); } + public void generateAnyObjectMapping(Property property, XMLDescriptor descriptor, NamespaceInfo namespaceInfo) { + XMLAnyObjectMapping mapping = new XMLAnyObjectMapping(); + mapping.setAttributeName(property.getPropertyName()); + if (property.isMethodProperty()) { + mapping.setGetMethodName(property.getGetMethodName()); + mapping.setSetMethodName(property.getSetMethodName()); + } + + mapping.setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy.KEEP_UNKNOWN_AS_ELEMENT); + + descriptor.addMapping(mapping); + } + protected boolean areEquals(JavaClass src, Class tgt) { if (src == null || tgt == null) { return false;