All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sencha.gxt.data.client.loader.XmlReader Maven / Gradle / Ivy

/**
 * Sencha GXT 3.1.1 - Sencha for GWT
 * Copyright(c) 2007-2014, Sencha, Inc.
 * [email protected]
 *
 * http://www.sencha.com/products/gxt/license/
 */
package com.sencha.gxt.data.client.loader;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.Text;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.XMLParser;
import com.google.web.bindery.autobean.shared.AutoBean;
import com.google.web.bindery.autobean.shared.AutoBeanFactory;
import com.google.web.bindery.autobean.shared.Splittable;
import com.sencha.gxt.core.client.GXT;
import com.sencha.gxt.core.client.dom.DomQuery;
import com.sencha.gxt.core.shared.FastMap;
import com.sencha.gxt.data.shared.loader.AbstractAutoBeanReader;

/**
 * A DataReader implementation that reads XML data and build it
 * into the given {@link AutoBean} type, using other types from the given
 * factory.
 *
 * 

* These AutoBean interfaces should use * {@link com.google.web.bindery.autobean.shared.AutoBean.PropertyName} to * specify the path to properties. Collections can be referenced by specifying * the path to the items. * *

* Subclasses can override {@link #createReturnData(Object, Object)} to control * what object is returned by the reader. * * @param * the model type to return from the reader * @param * an intermediate type that represents the data passed in as XML. * May be the same as M */ public class XmlReader extends AbstractAutoBeanReader { /** * A {@link Splittable} for XML data. */ public final static class XmlSplittable implements Splittable { private final Node node; private final NodeList nodes; private final Map reifiedData = new FastMap(); /** * Create an XML splittable rooted at the document element of the given * document. * * @param doc * the document representing the root of this XML splittable */ public XmlSplittable(final Document doc) { this(getNode(doc.getDocumentElement())); } /** * Create an XML splittable from the given node. * * @param node * the node representing the root of this XML splittable */ public XmlSplittable(final Node node) { this.node = node; this.nodes = null; } /** * Create an XML splittable for the given list of nodes. * * @param nodes * the nodes representing this XML splittable */ public XmlSplittable(final NodeList nodes) { this.node = null; this.nodes = nodes; } @Override public boolean asBoolean() { return "true".equals(asString()); } @Override public double asNumber() { return Double.parseDouble(asString()); } @Override public void assign(final Splittable parent, final int index) { } @Override public void assign(final Splittable parent, final String propertyName) { } @Override public String asString() { if (GXT.isIE6() || GXT.isIE7() || GXT.isIE8() || GXT.isIE9()) { return ieNativeAsString(getFirstNode()); } else { return nativeAsString(getFirstNode()); } } @Override public Splittable deepCopy() { throw new UnsupportedOperationException("Cannot clone XmlSplittable"); } @Override public Splittable get(final int index) { return new XmlSplittable(nodes.getItem(index)); } @Override public Splittable get(final String key) { if ("".equals(key)) { return new XmlSplittable(getFirstNode()); } // [...@...] is a case where we are getting something which may not // be an // attribute - only look for 'naked' @s // first try - look for 'anything, followed by an @, followed by not // a // [,], or . if (key.matches(".*@[^\\[\\]\\.]+")) { final String attrValue = DomQuery.selectValue(key, getFirstNode()); if (attrValue == null) { return null; } return new XmlSplittable(getFirstNode().getOwnerDocument().createTextNode(attrValue)); } final NodeList nodes = DomQuery.select(key, (Element) getFirstNode()).cast(); if (nodes == null || nodes.getLength() == 0) { return null; } return new XmlSplittable(nodes); } @Override public String getPayload() { throw new UnsupportedOperationException("Cannot convert XmlSplittable to payload"); } @Override public List getPropertyKeys() { final NodeList children = ((Element) getFirstNode()).getChildNodes(); final List keys = new ArrayList(); for (int i = 0; i < children.getLength(); i++) { if (Element.is(children.getItem(i))) { keys.add(children.getItem(i).getNodeName()); } } return keys; } @Override public Object getReified(final String key) { return reifiedData.get(key); } private native String ieNativeAsString(Node node) /*-{ return node.text; }-*/; @Override public boolean isBoolean() { return isString();// TODO } @Override public boolean isIndexed() { return (nodes != null); } @Override public boolean isKeyed() { return (getFirstNode() instanceof Element); } @Override public boolean isNull(final int index) { return get(index) == null; } @Override public boolean isNull(final String key) { return get(key) == null; } @Override public boolean isNumber() { return isString();// TODO } @Override public boolean isReified(final String key) { return reifiedData.containsKey(key); } @Override public boolean isString() { return getFirstNode() instanceof Text; } @Override public boolean isUndefined(final String key) { // TODO return false; } private native String nativeAsString(Node node) /*-{ return node.textContent; }-*/; @Override public void setReified(final String key, final Object object) { reifiedData.put(key, object); } @Override public void setSize(final int i) { } @Override public int size() { int size = 0; for (int i = 0; i < nodes.getLength(); i++) { if (Element.is(nodes.getItem(i))) { size++; } } return size; } @Override public native String toString() /*-{ var node = [email protected]::getFirstNode()(); if (@com.sencha.gxt.core.client.GXT::isIE6()() || @com.sencha.gxt.core.client.GXT::isIE7()()) { return node.xml; } else { return new XMLSerializer().serializeToString(node); } }-*/; private Node getFirstNode() { if (node != null) { return node; } assert nodes != null && nodes.getLength() != 0; return nodes.getItem(0); } @Override public void removeReified(final String key) { reifiedData.remove(key); } } private static native Node getNode(com.google.gwt.xml.client.Node n) /*-{ return [email protected]::getJsObject()(); }-*/; /** * Creates a new XML reader that can turn XML into an AutoBean. * * @param factory * an auto bean factory capable of encoding objects of type M * @param rootBeanType * AutoBean based type to represent the base data */ public XmlReader(final AutoBeanFactory factory, final Class rootBeanType) { super(factory, rootBeanType); } @Override protected Splittable readSplittable(final Object loadConfig, final String data) { return new XmlSplittable(XMLParser.parse(data)); } }