blob: cba5dd45a6789aaddc7db6abaf3282e6ba69693d [file] [log] [blame]
/*
* 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();
}
}