mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
177 lines
5.6 KiB
Java
177 lines
5.6 KiB
Java
package com.avaje.tests.xml.runtime;
|
|
|
|
import java.io.IOException;
|
|
import java.util.Collection;
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
|
|
import javax.persistence.PersistenceException;
|
|
|
|
import org.w3c.dom.Node;
|
|
|
|
import com.avaje.ebean.bean.BeanCollection;
|
|
import com.avaje.ebean.bean.BeanCollectionAdd;
|
|
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
|
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
|
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
|
|
|
public class XrCollection extends XrNode implements XoiNode {
|
|
|
|
private final boolean invokeFetch;
|
|
|
|
private final BeanPropertyAssocMany<?> manyProp;
|
|
|
|
private final String mapKey;
|
|
|
|
private final BeanDescriptor<?> targetDescriptor;
|
|
|
|
/**
|
|
* Construct with no mapKey and no attributes.
|
|
*/
|
|
public XrCollection(String name, ElPropertyValue prop, XoiNode[] children, boolean invokeFetch) {
|
|
this(name, prop, children, null, invokeFetch, null);
|
|
}
|
|
|
|
/**
|
|
* Construct with no attributes.
|
|
*/
|
|
public XrCollection(String name, ElPropertyValue prop, XoiNode[] children, boolean invokeFetch, String mapKey) {
|
|
this(name, prop, children, null, invokeFetch, mapKey);
|
|
}
|
|
|
|
/**
|
|
* Construct with all options.
|
|
*/
|
|
public XrCollection(String name, ElPropertyValue prop, XoiNode[] children, XoiAttribute[] attributes, boolean invokeFetch, String mapKey) {
|
|
|
|
super(name, prop, null, null, null, children, attributes);
|
|
this.invokeFetch = invokeFetch;
|
|
this.decreaseDepth = true;
|
|
this.mapKey = mapKey;
|
|
this.manyProp = (BeanPropertyAssocMany<?>)prop.getBeanProperty();
|
|
this.targetDescriptor = manyProp.getTargetDescriptor();
|
|
}
|
|
|
|
|
|
@Override
|
|
public void readNode(Node node, XrReadContext ctx) {
|
|
|
|
Object parentBean = ctx.getBean();
|
|
|
|
// create a List/Set/Map to hold the details
|
|
Object details = manyProp.createEmpty(false);
|
|
|
|
// Wrapper used to add to the collection
|
|
BeanCollectionAdd bcAdd = manyProp.getBeanCollectionAdd(details, mapKey);
|
|
|
|
Node detailNode = nextElement(node.getFirstChild());
|
|
do {
|
|
Object detailBean = targetDescriptor.createBean();
|
|
ctx.setBean(detailBean);
|
|
|
|
for (int i = 0; i < childNodes.length; i++) {
|
|
childNodes[i].readNode(detailNode, ctx);
|
|
}
|
|
|
|
bcAdd.addBean(detailBean);
|
|
|
|
detailNode = nextElement(detailNode.getNextSibling());
|
|
|
|
} while(detailNode != null);
|
|
|
|
setObjectValue(parentBean, details);
|
|
ctx.setBean(parentBean);
|
|
}
|
|
|
|
private Node nextElement(Node node) {
|
|
|
|
while (node != null) {
|
|
int type = node.getNodeType();
|
|
if (type == Node.ELEMENT_NODE){
|
|
return node;
|
|
}
|
|
node = node.getNextSibling();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void writeContent(XrOutputWriter o, Object bean, Object val) throws IOException {
|
|
|
|
Collection<?> collection = (Collection<?>)val;
|
|
Iterator<?> it = collection.iterator();
|
|
while (it.hasNext()) {
|
|
Object childBean = it.next();
|
|
for (int i = 0; i < childNodes.length; i++) {
|
|
childNodes[i].writeNode(o, childBean);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void writeContent(XrOutputDocument out, Node e, Object bean, Object value) throws IOException {
|
|
|
|
Collection<?> collection = (Collection<?>)value;
|
|
Iterator<?> it = collection.iterator();
|
|
while (it.hasNext()) {
|
|
Object childBean = it.next();
|
|
for (int i = 0; i < childNodes.length; i++) {
|
|
childNodes[i].writeNode(out, e, childBean);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void writeNode(XrOutputDocument out, Node node, Object bean) throws IOException {
|
|
super.writeNode(out, node, bean);
|
|
}
|
|
|
|
// protected void writeNodeChildren(XmlOutputDocument out, Node childNode, Object bean, Object val) throws IOException {
|
|
//
|
|
// if (hasChildNodes) {
|
|
// for (int i = 0; i < childNodes.length; i++) {
|
|
// childNodes[i].writeNode(out, childNode, bean);
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
|
|
@Override
|
|
protected Object getObjectValue(Object bean) {
|
|
|
|
Object o = prop.elGetValue(bean);
|
|
Collection<?> collection = getDetailsIterator(o);
|
|
return collection;
|
|
}
|
|
|
|
|
|
/**
|
|
* Return the details of the collection or map taking care to avoid
|
|
* unnecessary fetching of the data.
|
|
*/
|
|
private Collection<?> getDetailsIterator(Object o) {
|
|
if (o == null) {
|
|
return null;
|
|
}
|
|
if (o instanceof BeanCollection<?>) {
|
|
BeanCollection<?> bc = (BeanCollection<?>) o;
|
|
if (!invokeFetch && !bc.isPopulated()) {
|
|
return null;
|
|
}
|
|
bc.size();
|
|
return bc.getActualDetails();
|
|
}
|
|
|
|
if (o instanceof Map<?,?>) {
|
|
// yes, we want the entrySet (to set the keys)
|
|
return ((Map<?, ?>) o).entrySet();
|
|
|
|
} else if (o instanceof Collection<?>) {
|
|
return ((Collection<?>) o);
|
|
}
|
|
String m = "expecting a Map or Collection but got [" + o.getClass().getName() + "]";
|
|
throw new PersistenceException(m);
|
|
}
|
|
|
|
}
|