| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.sdo.helper; |
| |
| |
| import org.eclipse.persistence.exceptions.DescriptorException; |
| import org.eclipse.persistence.mappings.AttributeAccessor; |
| import commonj.sdo.Property; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import org.w3c.dom.Node; |
| import org.eclipse.persistence.oxm.XMLUnmarshaller; |
| import org.eclipse.persistence.oxm.XMLRoot; |
| import org.eclipse.persistence.sdo.helper.SDOXMLHelper; |
| import commonj.sdo.helper.HelperContext; |
| import org.w3c.dom.Document; |
| import org.eclipse.persistence.platform.xml.XMLPlatformFactory; |
| import org.eclipse.persistence.oxm.XMLMarshaller; |
| import org.eclipse.persistence.sdo.SDOProperty; |
| import org.eclipse.persistence.sdo.SDODataObject; |
| |
| import org.eclipse.persistence.platform.xml.XMLPlatform; |
| |
| /** |
| * <p><b>Purpose</b>: A wrapper class for handling cases when the domain object attributes are |
| * to be accessed thru the accessor methods that are called "get" and "set". This is to be used |
| * when marsalling/unmarshalling SDODataObjects. The propertyName is the name of the property on |
| * the DataObject and that must be set on this accessor. |
| */ |
| public class SDOFragmentMappingAttributeAccessor extends AttributeAccessor { |
| protected SDOProperty property; |
| protected HelperContext helperContext; |
| |
| public SDOFragmentMappingAttributeAccessor(SDOProperty property, HelperContext helper) { |
| this.property = property; |
| this.helperContext = helper; |
| } |
| |
| /** |
| * Gets the value of an instance variable in the object. |
| */ |
| @Override |
| public Object getAttributeValueFromObject(Object anObject) throws DescriptorException { |
| Object attributeValue = ((SDODataObject)anObject).get(property); |
| if (attributeValue != null) { |
| if (property.isMany()) { |
| // handle collection case |
| ArrayList<Object> fragments = new ArrayList<Object>(); |
| Iterator<Object> objects = ((Collection)attributeValue).iterator(); |
| while (objects.hasNext()) { |
| fragments.add(buildFragment(property, (SDODataObject)anObject, ((SDODataObject)objects.next()))); |
| } |
| attributeValue = fragments; |
| } else { |
| attributeValue = buildFragment(property, (SDODataObject)anObject, (SDODataObject)attributeValue); |
| } |
| } |
| |
| return attributeValue; |
| } |
| |
| /** |
| * Set get and set method after creating these methods by using |
| * get and set method names |
| */ |
| @Override |
| public void initializeAttributes(Class<?> theJavaClass) throws DescriptorException { |
| if (getAttributeName() == null) { |
| throw DescriptorException.attributeNameNotSpecified(); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| @Override |
| public boolean isMethodAttributeAccessor() { |
| return true; |
| } |
| |
| /** |
| * Sets the value of the instance variable in the object to the value. |
| */ |
| @Override |
| public void setAttributeValueInObject(Object domainObject, Object attributeValue) throws DescriptorException { |
| XMLUnmarshaller unmarshaller = ((SDOXMLHelper)helperContext.getXMLHelper()).getXmlContext().createUnmarshaller(); |
| unmarshaller.setUnmarshalListener(new org.eclipse.persistence.sdo.helper.SDOCSUnmarshalListener(helperContext)); |
| |
| if (attributeValue instanceof Collection) { |
| //handle collection case |
| ArrayList result = new ArrayList(); |
| Iterator fragments = ((Collection)attributeValue).iterator(); |
| while (fragments.hasNext()) { |
| Node next = (Node)fragments.next(); |
| |
| //Handle Simple Case here |
| Object dataObject = unmarshaller.unmarshal(next); |
| if(dataObject instanceof org.eclipse.persistence.oxm.XMLRoot) { |
| dataObject = ((XMLRoot)dataObject).getObject(); |
| } |
| result.add(dataObject); |
| } |
| ((SDODataObject)domainObject).set(property, result); |
| } else { |
| Object result = null; |
| if (!(attributeValue == null)) { |
| Node value = (Node)attributeValue; |
| result = unmarshaller.unmarshal(value); |
| if(result instanceof org.eclipse.persistence.oxm.XMLRoot) { |
| result = ((XMLRoot)result).getObject(); |
| } |
| } |
| ((SDODataObject)domainObject).set(property, result); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public void setProperty(SDOProperty property) { |
| this.property = property; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public SDOProperty getPropertyName() { |
| return property; |
| } |
| |
| private Object buildFragment(Property property, SDODataObject parentObject, SDODataObject value) { |
| //build an XML Fragment from this SDO |
| XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform(); |
| XMLMarshaller xmlMarshaller = ((SDOXMLHelper)helperContext.getXMLHelper()).getXmlContext().createMarshaller(); |
| Document doc = xmlPlatform.createDocument(); |
| XMLRoot root = new XMLRoot(); |
| root.setObject(value); |
| root.setLocalName(property.getName()); |
| if(((SDOProperty)property).isNamespaceQualified()){ |
| root.setNamespaceURI(parentObject.getType().getURI()); |
| } |
| xmlMarshaller.marshal(root, doc); |
| return doc.getDocumentElement(); |
| } |
| } |