copying Table and XML updates to Android

This commit is contained in:
benfry
2012-12-16 20:57:17 +00:00
parent 826851f461
commit 7944e2a6f1
8 changed files with 1579 additions and 930 deletions
+89 -7
View File
@@ -4151,9 +4151,23 @@ public class PApplet extends Activity implements PConstants, Runnable {
// DATA I/O
/**
* @webref input:files
* @param filename name of a file in the data folder or a URL.
* @see XML#parse(String)
* @see PApplet#loadBytes(String)
* @see PApplet#loadStrings(String)
* @see PApplet#loadTable(String)
*/
public XML loadXML(String filename) {
return loadXML(filename, null);
}
// version that uses 'options' though there are currently no supported options
public XML loadXML(String filename, String options) {
try {
return new XML(this, filename);
return new XML(createInput(filename), options);
} catch (Exception e) {
e.printStackTrace();
return null;
@@ -4161,9 +4175,14 @@ public class PApplet extends Activity implements PConstants, Runnable {
}
static public XML loadXML(File file) {
public XML parseXML(String xmlString) {
return parseXML(xmlString, null);
}
public XML parseXML(String xmlString, String options) {
try {
return new XML(file);
return XML.parse(xmlString, options);
} catch (Exception e) {
e.printStackTrace();
return null;
@@ -4171,17 +4190,80 @@ public class PApplet extends Activity implements PConstants, Runnable {
}
public boolean saveXML(XML xml, String filename) {
return saveXML(xml, filename, null);
}
public boolean saveXML(XML xml, String filename, String options) {
return xml.save(saveFile(filename), options);
}
public Table createTable() {
return new Table();
}
/**
* @webref input:files
* @param filename name of a file in the data folder or a URL.
* @see PApplet#loadBytes(String)
* @see PApplet#loadStrings(String)
* @see PApplet#loadXML(String)
*/
public Table loadTable(String filename) {
return new Table(this, filename);
return loadTable(filename, null);
}
static public Table loadTable(File file) {
return new Table(file);
public Table loadTable(String filename, String options) {
try {
String ext = checkExtension(filename);
if (ext != null) {
if (ext.equals("csv") || ext.equals("tsv")) {
if (options == null) {
options = ext;
} else {
options = ext + "," + options;
}
}
}
return new Table(createInput(filename), options);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
//////////////////////////////////////////////////////////////
public boolean saveTable(Table table, String filename) {
return saveTable(table, filename, null);
}
public boolean saveTable(Table table, String filename, String options) {
try {
table.save(saveFile(filename), options);
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected String checkExtension(String filename) {
int index = filename.lastIndexOf('.');
if (index == -1) {
return null;
}
return filename.substring(index + 1).toLowerCase();
}
// FONT I/O
@@ -1081,7 +1081,7 @@ public class PGraphicsAndroid2D extends PGraphics {
} else if (extension.equals("svgz")) {
try {
InputStream input = new GZIPInputStream(parent.createInput(filename));
XML xml = new XML(PApplet.createReader(input));
XML xml = new XML(input);
svg = new PShapeSVG(xml);
} catch (Exception e) {
e.printStackTrace();
File diff suppressed because it is too large Load Diff
@@ -12,4 +12,15 @@ public interface TableRow {
public float getFloat(String columnName);
public double getDouble(int column);
public double getDouble(String columnName);
public void setString(int column, String value);
public void setString(String columnName, String value);
public void setInt(int column, int value);
public void setInt(String columnName, int value);
public void setLong(int column, long value);
public void setLong(String columnName, long value);
public void setFloat(int column, float value);
public void setFloat(String columnName, float value);
public void setDouble(int column, double value);
public void setDouble(String columnName, double value);
}
+171 -86
View File
@@ -49,8 +49,8 @@ public class XML implements Serializable {
/** The internal representation, a DOM node. */
protected Node node;
/** Cached locally because it's used often. */
protected String name;
// /** Cached locally because it's used often. */
// protected String name;
/** The parent element. */
protected XML parent;
@@ -62,26 +62,40 @@ public class XML implements Serializable {
protected XML() { }
/**
* Begin parsing XML data passed in from a PApplet. This code
* wraps exception handling, for more advanced exception handling,
* use the constructor that takes a Reader or InputStream.
*
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
*/
public XML(PApplet parent, String filename) throws IOException, ParserConfigurationException, SAXException {
this(parent.createReader(filename));
}
// /**
// * Begin parsing XML data passed in from a PApplet. This code
// * wraps exception handling, for more advanced exception handling,
// * use the constructor that takes a Reader or InputStream.
// *
// * @throws SAXException
// * @throws ParserConfigurationException
// * @throws IOException
// */
// public XML(PApplet parent, String filename) throws IOException, ParserConfigurationException, SAXException {
// this(parent.createReader(filename));
// }
public XML(File file) throws IOException, ParserConfigurationException, SAXException {
this(PApplet.createReader(file));
this(file, null);
}
public XML(Reader reader) throws IOException, ParserConfigurationException, SAXException {
public XML(File file, String options) throws IOException, ParserConfigurationException, SAXException {
this(PApplet.createReader(file), options);
}
public XML(InputStream input) throws IOException, ParserConfigurationException, SAXException {
this(input, null);
}
public XML(InputStream input, String options) throws IOException, ParserConfigurationException, SAXException {
this(PApplet.createReader(input), options);
}
protected XML(Reader reader, String options) throws IOException, ParserConfigurationException, SAXException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// Prevent 503 errors from www.w3.org
@@ -115,7 +129,8 @@ public class XML implements Serializable {
// Document document = builder.parse(dataPath("1_alt.html"));
Document document = builder.parse(new InputSource(reader));
node = document.getDocumentElement();
name = node.getNodeName();
// name = node.getNodeName();
// NodeList nodeList = document.getDocumentElement().getChildNodes();
// for (int i = 0; i < nodeList.getLength(); i++) {
// }
@@ -124,46 +139,51 @@ public class XML implements Serializable {
// TODO is there a more efficient way of doing this? wow.
// i.e. can we use one static document object for all PNodeXML objects?
public XML(String name) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
node = document.createElement(name);
this.name = name;
this.parent = null;
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
public XML(String name) throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
node = document.createElement(name);
// this.name = name;
this.parent = null;
}
protected XML(XML parent, Node node) {
this.node = node;
this.parent = parent;
this.name = node.getNodeName();
// this.name = node.getNodeName();
}
static public XML parse(String xml) {
try {
return new XML(new StringReader(xml));
} catch (Exception e) {
e.printStackTrace();
return null;
}
/**
* xxxxxxx
*
* @webref xml:method
* @brief Converts String content to an XML object
* @param data the content to be parsed as XML
* @return an XML object, or null
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
* @see PApplet#loadXML(String)
*/
static public XML parse(String data) throws IOException, ParserConfigurationException, SAXException {
return XML.parse(data, null);
}
public boolean save(OutputStream output) {
static public XML parse(String data, String options) throws IOException, ParserConfigurationException, SAXException {
return new XML(new StringReader(data), null);
}
protected boolean save(OutputStream output) {
return save(PApplet.createWriter(output));
}
public boolean save(File file) {
public boolean save(File file, String options) {
return save(PApplet.createWriter(file));
}
@@ -189,7 +209,7 @@ public class XML implements Serializable {
/**
* Internal function; not included in reference.
*/
protected Node getNode() {
protected Object getNative() {
return node;
}
@@ -203,7 +223,8 @@ public class XML implements Serializable {
* @return the name, or null if the element only contains #PCDATA.
*/
public String getName() {
return name;
// return name;
return node.getNodeName();
}
/**
@@ -213,7 +234,7 @@ public class XML implements Serializable {
public void setName(String newName) {
Document document = node.getOwnerDocument();
node = document.renameNode(node, null, newName);
name = node.getNodeName();
// name = node.getNodeName();
}
@@ -334,6 +355,9 @@ public class XML implements Serializable {
* @return the first matching element
*/
public XML getChild(String name) {
if (name.length() > 0 && name.charAt(0) == '/') {
throw new IllegalArgumentException("getChild() should not begin with a slash");
}
if (name.indexOf('/') != -1) {
return getChildRecursive(PApplet.split(name, '/'), 0);
}
@@ -392,6 +416,9 @@ public class XML implements Serializable {
* @author processing.org
*/
public XML[] getChildren(String name) {
if (name.length() > 0 && name.charAt(0) == '/') {
throw new IllegalArgumentException("getChildren() should not begin with a slash");
}
if (name.indexOf('/') != -1) {
return getChildrenRecursive(PApplet.split(name, '/'), 0);
}
@@ -441,7 +468,7 @@ public class XML implements Serializable {
public XML addChild(XML child) {
Document document = node.getOwnerDocument();
Node newChild = document.importNode(child.getNode(), true);
Node newChild = document.importNode((Node) child.getNative(), true);
return appendChild(newChild);
}
@@ -467,36 +494,53 @@ public class XML implements Serializable {
}
/** Remove whitespace nodes. */
public void trim() {
//// public static boolean isWhitespace(XML xml) {
//// if (xml.node.getNodeType() != Node.TEXT_NODE)
//// return false;
//// Matcher m = whitespace.matcher(xml.node.getNodeValue());
//// return m.matches();
//// }
// trim(this);
// /** Remove whitespace nodes. */
// public void trim() {
////// public static boolean isWhitespace(XML xml) {
////// if (xml.node.getNodeType() != Node.TEXT_NODE)
////// return false;
////// Matcher m = whitespace.matcher(xml.node.getNodeValue());
////// return m.matches();
////// }
//// trim(this);
//// }
//
// checkChildren();
// int index = 0;
// for (int i = 0; i < children.length; i++) {
// if (i != index) {
// children[index] = children[i];
// }
// Node childNode = (Node) children[i].getNative();
// if (childNode.getNodeType() != Node.TEXT_NODE ||
// children[i].getContent().trim().length() > 0) {
// children[i].trim();
// index++;
// }
// }
// if (index != children.length) {
// children = (XML[]) PApplet.subset(children, 0, index);
// }
//
// // possibility, but would have to re-parse the object
//// helpdesk.objects.com.au/java/how-do-i-remove-whitespace-from-an-xml-document
//// TransformerFactory factory = TransformerFactory.newInstance();
//// Transformer transformer = factory.newTransformer(new StreamSource("strip-space.xsl"));
//// DOMSource source = new DOMSource(document);
//// StreamResult result = new StreamResult(System.out);
//// transformer.transform(source, result);
//
//// <xsl:stylesheet version="1.0"
//// xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
//// <xsl:output method="xml" omit-xml-declaration="yes"/>
//// <xsl:strip-space elements="*"/>
//// <xsl:template match="@*|node()">
//// <xsl:copy>
//// <xsl:apply-templates select="@*|node()"/>
//// </xsl:copy>
//// </xsl:template>
//// </xsl:stylesheet>
// }
//
//
// protected void trim() {
checkChildren();
int index = 0;
for (int i = 0; i < children.length; i++) {
if (i != index) {
children[index] = children[i];
}
Node childNode = children[i].getNode();
if (childNode.getNodeType() != Node.TEXT_NODE ||
children[i].getContent().trim().length() > 0) {
children[i].trim();
index++;
}
}
if (index != children.length) {
children = (XML[]) PApplet.subset(children, 0, index);
}
}
/**
@@ -718,20 +762,30 @@ public class XML implements Serializable {
}
/**
* Format this XML data as a String.
* @param indent -1 for a single line (and no declaration), >= 0 for indents and newlines
*/
public String format(int indent) {
try {
DOMSource dumSource = new DOMSource(node);
// entities = doctype.getEntities()
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
// if this is the root, output the decl, if not, hide it
TransformerFactory factory = TransformerFactory.newInstance();
if (indent != -1) {
factory.setAttribute("indent-number", indent);
}
Transformer transformer = factory.newTransformer();
// Add the XML declaration at the top if this node is the root and we're
// not writing to a single line (indent = -1 means single line).
if (indent == -1 || parent != null) {
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
} else {
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
}
// transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "sample.dtd");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
// transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "yes"); // huh?
// transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
@@ -745,18 +799,45 @@ public class XML implements Serializable {
// transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS
// indent by default, but sometimes this needs to be turned off
if (indent != 0) {
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent));
//transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", String.valueOf(indent));
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
} else {
transformer.setOutputProperty(OutputKeys.INDENT, "no");
}
// Properties p = transformer.getOutputProperties();
// for (Object key : p.keySet()) {
// System.out.println(key + " -> " + p.get(key));
// }
StringWriter sw = new StringWriter();
StreamResult sr = new StreamResult(sw);
transformer.transform(dumSource, sr);
return sw.toString();
// If you smell something, that's because this code stinks. No matter
// the settings of the Transformer object, if the XML document already
// has whitespace elements, it won't bother re-indenting/re-formatting.
// So instead, transform the data once into a single line string.
// If indent is -1, then we're done. Otherwise re-run and the settings
// of the factory will kick in. If you know a better way to do this,
// please contribute. I've wasted too much of my Sunday on it. But at
// least the Giants are getting blown out by the Falcons.
StringWriter tempWriter = new StringWriter();
StreamResult tempResult = new StreamResult(tempWriter);
transformer.transform(new DOMSource(node), tempResult);
String[] tempLines = PApplet.split(tempWriter.toString(), '\n');
if (tempLines[0].startsWith("<?xml")) {
// Remove XML declaration from the top before slamming into one line
tempLines = PApplet.subset(tempLines, 1);
}
String singleLine = PApplet.join(PApplet.trim(tempLines), "");
if (indent == -1) {
return singleLine;
}
StringWriter stringWriter = new StringWriter();
StreamResult xmlOutput = new StreamResult(stringWriter);
// DOMSource source = new DOMSource(node);
Source source = new StreamSource(new StringReader(singleLine));
transformer.transform(source, xmlOutput);
return stringWriter.toString();
// return xmlOutput.getWriter().toString();
} catch (Exception e) {
e.printStackTrace();
@@ -765,9 +846,13 @@ public class XML implements Serializable {
}
/**
* Return the XML document formatted with two spaces for indents.
* Chosen to do this since it's the most common case (e.g. with println()).
* Same as format(2). Use the format() function for more options.
*/
@Override
/** Return the XML data as a single line, with no DOCTYPE declaration. */
public String toString() {
return format(-1);
return format(2);
}
}
@@ -254,7 +254,7 @@ public class PGraphics2D extends PGraphicsOpenGL {
try {
InputStream input =
new GZIPInputStream(pg.parent.createInput(filename));
XML xml = new XML(PApplet.createReader(input));
XML xml = new XML(input);
svg = new PShapeSVG(xml);
} catch (Exception e) {
e.printStackTrace();
+4 -5
View File
@@ -492,10 +492,10 @@ public class Table {
// Object targetObject,
// Class target -> get this from the type of fieldName
// Class sketchClass = sketch.getClass();
Class sketchClass = enclosingObject.getClass();
Class<?> sketchClass = enclosingObject.getClass();
targetField = sketchClass.getDeclaredField(fieldName);
// PApplet.println("found " + targetField);
Class targetArray = targetField.getType();
Class<?> targetArray = targetField.getType();
if (!targetArray.isArray()) {
// fieldName is not an array
} else {
@@ -510,8 +510,8 @@ public class Table {
// Object enclosingObject = sketch;
// PApplet.println("enclosing obj is " + enclosingObject);
Class enclosingClass = target.getEnclosingClass();
Constructor con = null;
Class<?> enclosingClass = target.getEnclosingClass();
Constructor<?> con = null;
try {
if (enclosingClass == null) {
@@ -1595,7 +1595,6 @@ public class Table {
table.setDouble(row, column, value);
}
@Override
public void setDouble(String columnName, double value) {
table.setDouble(row, columnName, value);
}
+56 -53
View File
@@ -34,28 +34,6 @@ X better to do this instead of bringing back the magic event
X or implementing the magic event on Android
X also problematic with it not being called now
decisions on data
X are we comfortable with setInt/Float/etc instead of just set(int, blah)
X yes, better to have parity
X too weird to have to explain why getXxx() needs types and set() doesn't
X get/set with Java's 'Map' class?
X really useful, but leaning toward not including it
X or leave it in as an advanced feature?
X createXxx() methods less important
X XML.parse() - or new XML("<tag>") or new XML("tag")
_ add parseXML() and parseJSONObject(x)
X api note: size() used in data classes
X length() too confusing w/ array.length being built-in (when to use ()?)
X size() a bit confusing with the p5 size command, but less problematic
X also shorter than getCount() or getLength()
_ why not HashMap and ArrayList for JSON?
_ could enable loadHash() and loadArray() functions
_ or loadDict() and loadList() as the case might be
_ JSONObject.has(key) vs XML.hasAttribute(attr) vs HashMap.containsKey()
_ and how it should be handled with hash/dict
cleaning/earlier
C textureWrap() CLAMP and REPEAT now added
C begin/endContour()
@@ -77,7 +55,56 @@ X saveTable("filename.tsv") or saveTable("filename.txt", "tsv")
X createTable() method in PApplet
X removed getUniqueXxxx() and some others, pending names
_ OutOfMemory in image()
xml library
X removed 'name' field to avoid possibility of random errors
X confirmed that DOM "correct" version includes the text nodes
X new XML(name) also throws an ex, use createXML() or appendChild("name")
X remove XML.parse() from the reference (it throws an exception)
X use parseXML() instead
o do we need a trim() method for XML?
o use XSL transform to strip whitespace
o helpdesk.objects.com.au/java/how-do-i-remove-whitespace-from-an-xml-document
X messy, just not great
o isWhitespace() method for nodes? (that's the capitalization used in Character)
X doesn't help much
o get back to PhiLho once finished
X XML toString(0) means no indents or newlines
X but no way to remove indents and still have newlines...
X toString(-1)? a new method?
X format(2), format(4)... toString() -> default to 2 params
X fix this across the other items
X look into json and how it would work wrt XML
o 1) we bring back getFloatAttribute() et al.,
o and make getFloat() be equivalent to parseFloat(xml.getContent())
o 2) we keep getFloat() like it is, and add getFloatContent(), etc.
o 3) we deprecate our nice short getFloat/getInt/etc and go with
o getXxxxAttribute() and getXxxxContent() methods.
X not gonna do getFloatContent() since it's not really any shorter
X beginning slash in getChild() threw an NPE
decisions on data
X are we comfortable with setInt/Float/etc instead of just set(int, blah)
X yes, better to have parity
X too weird to have to explain why getXxx() needs types and set() doesn't
X get/set with Java's 'Map' class?
X really useful, but leaning toward not including it
X or leave it in as an advanced feature?
X createXxx() methods less important
X XML.parse() - or new XML("<tag>") or new XML("tag")
_ add parseXML() and parseJSONObject(x)
X api note: size() used in data classes
X length() too confusing w/ array.length being built-in (when to use ()?)
X size() a bit confusing with the p5 size command, but less problematic
X also shorter than getCount() or getLength()
_ why not HashMap and ArrayList for JSON?
_ could enable loadHash() and loadArray() functions
_ or loadDict() and loadList() as the case might be
_ JSONObject.has(key) vs XML.hasAttribute(attr) vs HashMap.containsKey()
_ and how it should be handled with hash/dict
_ right now using hasKey().. in JSONObject
_ image caches not being properly disposed (weak references broken?)
_ http://code.google.com/p/processing/issues/detail?id=1353
_ shader syntax (Andres request)
@@ -130,33 +157,6 @@ _ colorCalc() methods added to PShape.. should just be used from PGraphics
_ loadShape() needs to live in PApplet
_ make PShapeOpenGL a cache object
xml library
X removed 'name' field to avoid possibility of random errors
X confirmed that DOM "correct" version includes the text nodes
X new XML(name) also throws an ex, use createXML() or appendChild("name")
X remove XML.parse() from the reference (it throws an exception)
X use parseXML() instead
o do we need a trim() method for XML?
o use XSL transform to strip whitespace
o helpdesk.objects.com.au/java/how-do-i-remove-whitespace-from-an-xml-document
X messy, just not great
o isWhitespace() method for nodes? (that's the capitalization used in Character)
X doesn't help much
o get back to PhiLho once finished
X XML toString(0) means no indents or newlines
X but no way to remove indents and still have newlines...
X toString(-1)? a new method?
X format(2), format(4)... toString() -> default to 2 params
X fix this across the other items
X look into json and how it would work wrt XML
o 1) we bring back getFloatAttribute() et al.,
o and make getFloat() be equivalent to parseFloat(xml.getContent())
o 2) we keep getFloat() like it is, and add getFloatContent(), etc.
o 3) we deprecate our nice short getFloat/getInt/etc and go with
o getXxxxAttribute() and getXxxxContent() methods.
X not gonna do getFloatContent() since it's not really any shorter
X beginning slash in getChild() threw an NPE
async requests
Request r = createRequest("http://p5.org/feed/13134.jpg");
Request r = createRequest("http://p5.org/feed/13134.jpg", "callbackName");
@@ -227,9 +227,6 @@ _ maybe a hack where a new menubar is added?
_ splice() throws ClassCastException when used with objects like PVector
_ http://code.google.com/p/processing/issues/detail?id=1407
_ add "CGAffineTransformInvert: singular matrix" problem to the Wiki
_ http://code.google.com/p/processing/issues/detail?id=1363
api to be fixed/removed
_ remove PImage.delete() and friends from PImage, Movie, etc.
_ delete()/dispose() being used in the movie
@@ -533,6 +530,12 @@ _ document somehow.. svg viewer will be discontinued
_ http://www.adobe.com/svg/eol.html
CORE / PGraphicsJava2D
_ add "CGAffineTransformInvert: singular matrix" problem to the Wiki
_ http://code.google.com/p/processing/issues/detail?id=1363
CORE / OpenGL (Andres)
_ ortho() issues