You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2010/08/29 16:11:12 UTC
svn commit: r990580 - in /pivot/trunk:
core/src/org/apache/pivot/collections/ core/src/org/apache/pivot/json/
core/src/org/apache/pivot/serialization/ core/src/org/apache/pivot/xml/
core/test/org/apache/pivot/json/test/ core/test/org/apache/pivot/seria...
Author: gbrown
Date: Sun Aug 29 14:11:12 2010
New Revision: 990580
URL: http://svn.apache.org/viewvc?rev=990580&view=rev
Log:
Resolve PIVOT-620.
Added:
pivot/trunk/core/src/org/apache/pivot/json/JSONSerializerListener.java
pivot/trunk/core/src/org/apache/pivot/serialization/CSVSerializerListener.java
pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializerListener.java
Modified:
pivot/trunk/core/src/org/apache/pivot/collections/ArrayAdapter.java
pivot/trunk/core/src/org/apache/pivot/json/JSONSerializer.java
pivot/trunk/core/src/org/apache/pivot/serialization/CSVSerializer.java
pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java
pivot/trunk/core/test/org/apache/pivot/json/test/JSONSerializerTest.java
pivot/trunk/core/test/org/apache/pivot/json/test/sample.json
pivot/trunk/core/test/org/apache/pivot/serialization/test/CSVSerializerTest.java
pivot/trunk/core/test/org/apache/pivot/xml/test/XMLSerializerTest.java
pivot/trunk/demos/src/org/apache/pivot/demos/million/LargeData.java
pivot/trunk/web/src/org/apache/pivot/web/Query.java
pivot/trunk/wtk/src/org/apache/pivot/wtk/TextAreaContentListener2.java
Modified: pivot/trunk/core/src/org/apache/pivot/collections/ArrayAdapter.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/collections/ArrayAdapter.java?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/collections/ArrayAdapter.java (original)
+++ pivot/trunk/core/src/org/apache/pivot/collections/ArrayAdapter.java Sun Aug 29 14:11:12 2010
@@ -16,12 +16,16 @@
*/
package org.apache.pivot.collections;
+import java.io.Serializable;
+
import org.apache.pivot.collections.Sequence;
/**
* Implementation of the {@link Sequence} interface that wraps an array.
*/
-public class ArrayAdapter<T> implements Sequence<T> {
+public class ArrayAdapter<T> implements Sequence<T>, Serializable {
+ private static final long serialVersionUID = 1143706808122308239L;
+
private T[] array;
public ArrayAdapter(T[] array) {
Modified: pivot/trunk/core/src/org/apache/pivot/json/JSONSerializer.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/json/JSONSerializer.java?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/json/JSONSerializer.java (original)
+++ pivot/trunk/core/src/org/apache/pivot/json/JSONSerializer.java Sun Aug 29 14:11:12 2010
@@ -43,12 +43,79 @@ import org.apache.pivot.io.EchoReader;
import org.apache.pivot.io.EchoWriter;
import org.apache.pivot.serialization.SerializationException;
import org.apache.pivot.serialization.Serializer;
+import org.apache.pivot.util.ListenerList;
/**
* Implementation of the {@link Serializer} interface that reads data from
* and writes data to a JavaScript Object Notation (JSON) file.
*/
public class JSONSerializer implements Serializer<Object> {
+ private static class JSONSerializerListenerList extends ListenerList<JSONSerializerListener>
+ implements JSONSerializerListener {
+ @Override
+ public void beginDictionary(JSONSerializer jsonSerializer, Dictionary<String, ?> value) {
+ for (JSONSerializerListener listener : this) {
+ listener.beginDictionary(jsonSerializer, value);
+ }
+ }
+
+ @Override
+ public void endDictionary(JSONSerializer jsonSerializer) {
+ for (JSONSerializerListener listener : this) {
+ listener.endDictionary(jsonSerializer);
+ }
+ }
+
+ @Override
+ public void readKey(JSONSerializer jsonSerializer, String key) {
+ for (JSONSerializerListener listener : this) {
+ listener.readKey(jsonSerializer, key);
+ }
+ }
+
+ @Override
+ public void beginSequence(JSONSerializer jsonSerializer, Sequence<?> value) {
+ for (JSONSerializerListener listener : this) {
+ listener.beginSequence(jsonSerializer, value);
+ }
+ }
+
+ @Override
+ public void endSequence(JSONSerializer jsonSerializer) {
+ for (JSONSerializerListener listener : this) {
+ listener.endSequence(jsonSerializer);
+ }
+ }
+
+ @Override
+ public void readString(JSONSerializer jsonSerializer, String value) {
+ for (JSONSerializerListener listener : this) {
+ listener.readString(jsonSerializer, value);
+ }
+ }
+
+ @Override
+ public void readNumber(JSONSerializer jsonSerializer, Number value) {
+ for (JSONSerializerListener listener : this) {
+ listener.readNumber(jsonSerializer, value);
+ }
+ }
+
+ @Override
+ public void readBoolean(JSONSerializer jsonSerializer, Boolean value) {
+ for (JSONSerializerListener listener : this) {
+ listener.readBoolean(jsonSerializer, value);
+ }
+ }
+
+ @Override
+ public void readNull(JSONSerializer jsonSerializer) {
+ for (JSONSerializerListener listener : this) {
+ listener.readNull(jsonSerializer);
+ }
+ }
+ }
+
private Charset charset;
private Type type;
@@ -57,6 +124,8 @@ public class JSONSerializer implements S
private int c = -1;
+ private JSONSerializerListenerList jsonSerializerListeners = null;
+
public static final String DEFAULT_CHARSET_NAME = "UTF-8";
public static final Type DEFAULT_TYPE = Object.class;
@@ -169,14 +238,17 @@ public class JSONSerializer implements S
* The reader from which data will be read.
*
* @return
- * One of the following types, depending on the content of the stream:
+ * One of the following types, depending on the content of the stream
+ * and the value of {@link #getType()}:
*
* <ul>
+ * <li>pivot.collections.Dictionary</li>
+ * <li>pivot.collections.Sequence</li>
* <li>java.lang.String</li>
* <li>java.lang.Number</li>
* <li>java.lang.Boolean</li>
- * <li>pivot.collections.List</li>
- * <li>pivot.collections.Map</li>
+ * <li><tt>null</tt></li>
+ * <li>A JavaBean object</li>
* </ul>
*/
public Object readObject(Reader reader)
@@ -214,17 +286,17 @@ public class JSONSerializer implements S
}
if (c == 'n') {
- object = readNull(reader);
+ object = readNullValue(reader);
} else if (c == '"' || c == '\'') {
- object = readString(reader, type);
+ object = readStringValue(reader, type);
} else if (c == '+' || c == '-' || Character.isDigit(c)) {
- object = readNumber(reader, type);
+ object = readNumberValue(reader, type);
} else if (c == 't' || c == 'f') {
- object = readBoolean(reader, type);
+ object = readBooleanValue(reader, type);
} else if (c == '[') {
- object = readList(reader, type);
+ object = readListValue(reader, type);
} else if (c == '{') {
- object = readMap(reader, type);
+ object = readMapValue(reader, type);
} else {
throw new SerializationException("Unexpected character in input stream.");
}
@@ -278,7 +350,7 @@ public class JSONSerializer implements S
}
}
- private Object readNull(Reader reader)
+ private Object readNullValue(Reader reader)
throws IOException, SerializationException {
String nullString = "null";
@@ -298,10 +370,15 @@ public class JSONSerializer implements S
throw new SerializationException("Incomplete null value in input stream.");
}
+ // Notify the listeners
+ if (jsonSerializerListeners != null) {
+ jsonSerializerListeners.readNull(this);
+ }
+
return null;
}
- private Object readString(Reader reader, Type type)
+ private String readString(Reader reader)
throws IOException, SerializationException {
if (!(type instanceof Class<?>)) {
throw new SerializationException("Cannot convert string to " + type + ".");
@@ -363,10 +440,22 @@ public class JSONSerializer implements S
// Move to the next character after the delimiter
c = reader.read();
- return BeanAdapter.coerce(stringBuilder.toString(), (Class<?>)type);
+ return stringBuilder.toString();
+ }
+
+ private Object readStringValue(Reader reader, Type type)
+ throws IOException, SerializationException {
+ String string = readString(reader);
+
+ // Notify the listeners
+ if (jsonSerializerListeners != null) {
+ jsonSerializerListeners.readString(this, string);
+ }
+
+ return BeanAdapter.coerce(string, (Class<?>)type);
}
- private Object readNumber(Reader reader, Type type)
+ private Object readNumberValue(Reader reader, Type type)
throws IOException, SerializationException {
if (!(type instanceof Class<?>)) {
throw new SerializationException("Cannot convert number to " + type + ".");
@@ -405,10 +494,15 @@ public class JSONSerializer implements S
number = Double.parseDouble(stringBuilder.toString()) * (negative ? -1.0d : 1.0d);
}
+ // Notify the listeners
+ if (jsonSerializerListeners != null) {
+ jsonSerializerListeners.readNumber(this, number);
+ }
+
return BeanAdapter.coerce(number, (Class<?>)type);
}
- private Object readBoolean(Reader reader, Type type)
+ private Object readBooleanValue(Reader reader, Type type)
throws IOException, SerializationException {
if (!(type instanceof Class<?>)) {
throw new SerializationException("Cannot convert number to " + type + ".");
@@ -431,11 +525,19 @@ public class JSONSerializer implements S
throw new SerializationException("Incomplete boolean value in input stream.");
}
- return BeanAdapter.coerce(Boolean.parseBoolean(text), (Class<?>)type);
+ // Get the boolean value
+ Boolean value = Boolean.parseBoolean(text);
+
+ // Notify the listeners
+ if (jsonSerializerListeners != null) {
+ jsonSerializerListeners.readBoolean(this, value);
+ }
+
+ return BeanAdapter.coerce(value, (Class<?>)type);
}
@SuppressWarnings("unchecked")
- private Object readList(Reader reader, Type type)
+ private Object readListValue(Reader reader, Type type)
throws IOException, SerializationException {
Sequence<Object> sequence;
Type itemType;
@@ -480,6 +582,11 @@ public class JSONSerializer implements S
}
}
+ // Notify the listeners
+ if (jsonSerializerListeners != null) {
+ jsonSerializerListeners.beginSequence(this, sequence);
+ }
+
// Move to the next character after '['
c = reader.read();
skipWhitespaceAndComments(reader);
@@ -503,11 +610,16 @@ public class JSONSerializer implements S
// Move to the next character after ']'
c = reader.read();
+ // Notify the listeners
+ if (jsonSerializerListeners != null) {
+ jsonSerializerListeners.endSequence(this);
+ }
+
return sequence;
}
@SuppressWarnings("unchecked")
- private Object readMap(Reader reader, Type type)
+ private Object readMapValue(Reader reader, Type type)
throws IOException, SerializationException {
Dictionary<String, Object> dictionary;
Type valueType;
@@ -561,6 +673,11 @@ public class JSONSerializer implements S
}
}
+ // Notify the listeners
+ if (jsonSerializerListeners != null) {
+ jsonSerializerListeners.beginDictionary(this, dictionary);
+ }
+
// Move to the next character after '{'
c = reader.read();
skipWhitespaceAndComments(reader);
@@ -570,11 +687,11 @@ public class JSONSerializer implements S
if (c == '"' || c == '\'') {
// The key is a delimited string
- key = (String)readString(reader, String.class);
+ key = readString(reader);
} else {
// The key is an undelimited string; it must adhere to Java
// identifier syntax
- StringBuilder keyStringBuilder = new StringBuilder();
+ StringBuilder keyBuilder = new StringBuilder();
if (!Character.isJavaIdentifierStart(c)) {
throw new SerializationException("Illegal identifier start character.");
@@ -586,7 +703,7 @@ public class JSONSerializer implements S
throw new SerializationException("Illegal identifier character.");
}
- keyStringBuilder.append((char)c);
+ keyBuilder.append((char)c);
c = reader.read();
}
@@ -594,7 +711,7 @@ public class JSONSerializer implements S
throw new SerializationException("Unexpected end of input stream.");
}
- key = keyStringBuilder.toString();
+ key = keyBuilder.toString();
}
if (key == null
@@ -602,6 +719,11 @@ public class JSONSerializer implements S
throw new SerializationException("\"" + key + "\" is not a valid key.");
}
+ // Notify listeners
+ if (jsonSerializerListeners != null) {
+ jsonSerializerListeners.readKey(this, key);
+ }
+
skipWhitespaceAndComments(reader);
if (c != ':') {
@@ -630,6 +752,11 @@ public class JSONSerializer implements S
// Move to the first character after '}'
c = reader.read();
+ // Notify the listeners
+ if (jsonSerializerListeners != null) {
+ jsonSerializerListeners.endDictionary(this);
+ }
+
return (dictionary instanceof BeanAdapter) ? ((BeanAdapter)dictionary).getBean() : dictionary;
}
@@ -665,11 +792,12 @@ public class JSONSerializer implements S
* The object to serialize. Must be one of the following types:
*
* <ul>
+ * <li>pivot.collections.Map</li>
+ * <li>pivot.collections.List</li>
* <li>java.lang.String</li>
* <li>java.lang.Number</li>
* <li>java.lang.Boolean</li>
- * <li>pivot.collections.List</li>
- * <li>pivot.collections.Map</li>
+ * <li><tt>null</tt></li>
* </ul>
*
* @param writer
@@ -1081,4 +1209,12 @@ public class JSONSerializer implements S
throw new RuntimeException(exception);
}
}
+
+ public ListenerList<JSONSerializerListener> getJSONSerializerListeners() {
+ if (jsonSerializerListeners == null) {
+ jsonSerializerListeners = new JSONSerializerListenerList();
+ }
+
+ return jsonSerializerListeners;
+ }
}
Added: pivot/trunk/core/src/org/apache/pivot/json/JSONSerializerListener.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/json/JSONSerializerListener.java?rev=990580&view=auto
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/json/JSONSerializerListener.java (added)
+++ pivot/trunk/core/src/org/apache/pivot/json/JSONSerializerListener.java Sun Aug 29 14:11:12 2010
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.json;
+
+import org.apache.pivot.collections.Dictionary;
+import org.apache.pivot.collections.Sequence;
+
+/**
+ * JSON serializer listener interface.
+ */
+public interface JSONSerializerListener {
+ /**
+ * JSON serializer listener adapter.
+ */
+ public static class Adapter implements JSONSerializerListener {
+ @Override
+ public void beginDictionary(JSONSerializer jsonSerializer, Dictionary<String, ?> value) {
+ }
+
+ @Override
+ public void endDictionary(JSONSerializer jsonSerializer) {
+ }
+
+ @Override
+ public void readKey(JSONSerializer jsonSerializer, String key) {
+ }
+
+ @Override
+ public void beginSequence(JSONSerializer jsonSerializer, Sequence<?> value) {
+ }
+
+ @Override
+ public void endSequence(JSONSerializer jsonSerializer) {
+ }
+
+ @Override
+ public void readString(JSONSerializer jsonSerializer, String value) {
+ }
+
+ @Override
+ public void readNumber(JSONSerializer jsonSerializer, Number value) {
+ }
+
+ @Override
+ public void readBoolean(JSONSerializer jsonSerializer, Boolean value) {
+ }
+
+ @Override
+ public void readNull(JSONSerializer jsonSerializer) {
+ }
+ }
+
+ /**
+ * Called when the serializer has begun reading a dictionary value.
+ *
+ * @param jsonSerializer
+ * @param value
+ */
+ public void beginDictionary(JSONSerializer jsonSerializer, Dictionary<String, ?> value);
+
+ /**
+ * Called when the serializer has finished reading a dictionary value.
+ *
+ * @param jsonSerializer
+ */
+ public void endDictionary(JSONSerializer jsonSerializer);
+
+ /**
+ * Called when the serializer has read a dictionary key.
+ *
+ * @param jsonSerializer
+ * @param key
+ */
+ public void readKey(JSONSerializer jsonSerializer, String key);
+
+ /**
+ * Called when the serializer has begun reading a sequence value.
+ *
+ * @param jsonSerializer
+ * @param value
+ */
+ public void beginSequence(JSONSerializer jsonSerializer, Sequence<?> value);
+
+ /**
+ * Called when the serializer has finished reading a sequence value.
+ *
+ * @param jsonSerializer
+ */
+ public void endSequence(JSONSerializer jsonSerializer);
+
+ /**
+ * Called when the serializer has read a string value.
+ *
+ * @param jsonSerializer
+ * @param value
+ */
+ public void readString(JSONSerializer jsonSerializer, String value);
+
+ /**
+ * Called when the serializer has read a numeric value.
+ *
+ * @param jsonSerializer
+ * @param value
+ */
+ public void readNumber(JSONSerializer jsonSerializer, Number value);
+
+ /**
+ * Called when the serializer has read a boolean value.
+ *
+ * @param jsonSerializer
+ * @param value
+ */
+ public void readBoolean(JSONSerializer jsonSerializer, Boolean value);
+
+ /**
+ * Called when the serializer has read a null value.
+ *
+ * @param jsonSerializer
+ */
+ public void readNull(JSONSerializer jsonSerializer);
+}
Modified: pivot/trunk/core/src/org/apache/pivot/serialization/CSVSerializer.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/serialization/CSVSerializer.java?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/serialization/CSVSerializer.java (original)
+++ pivot/trunk/core/src/org/apache/pivot/serialization/CSVSerializer.java Sun Aug 29 14:11:12 2010
@@ -29,7 +29,6 @@ import java.io.Writer;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
-import java.util.NoSuchElementException;
import org.apache.pivot.beans.BeanAdapter;
import org.apache.pivot.collections.ArrayAdapter;
@@ -40,48 +39,34 @@ import org.apache.pivot.collections.List
import org.apache.pivot.collections.Sequence;
import org.apache.pivot.io.EchoReader;
import org.apache.pivot.io.EchoWriter;
+import org.apache.pivot.util.ListenerList;
/**
* Implementation of the {@link Serializer} interface that reads data from
* and writes data to a comma-separated value (CSV) file.
*/
public class CSVSerializer implements Serializer<List<?>> {
- /**
- * Allows a caller to retrieve the contents of a CSV stream iteratively.
- */
- public class StreamIterator {
- private Reader reader;
-
- private StreamIterator(Reader reader) throws IOException {
- this.reader = reader;
-
- // Move to the first character
- c = reader.read();
- }
-
- public boolean hasNext() {
- return (c != -1);
- }
-
- public Object next() throws IOException, SerializationException {
- if (c == -1) {
- throw new NoSuchElementException();
+ private static class CSVSerializerListenerList extends ListenerList<CSVSerializerListener>
+ implements CSVSerializerListener {
+ @Override
+ public void beginList(CSVSerializer csvSerializer, List<?> list) {
+ for (CSVSerializerListener listener : this) {
+ listener.beginList(csvSerializer, list);
}
+ }
- Object item = readItem(reader);
- if (item != null) {
- // Move to next line
- while (c != -1
- && (c == '\r' || c == '\n')) {
- c = reader.read();
- }
+ @Override
+ public void endList(CSVSerializer csvSerializer) {
+ for (CSVSerializerListener listener : this) {
+ listener.endList(csvSerializer);
}
-
- return item;
}
- public void remove() {
- throw new UnsupportedOperationException();
+ @Override
+ public void readItem(CSVSerializer csvSerializer, Object item) {
+ for (CSVSerializerListener listener : this) {
+ listener.readItem(csvSerializer, item);
+ }
}
}
@@ -93,7 +78,9 @@ public class CSVSerializer implements Se
private boolean writeKeys = false;
private boolean verbose = false;
- int c = -1;
+ private int c = -1;
+
+ private CSVSerializerListenerList csvSerializerListeners = null;
public static final String DEFAULT_CHARSET_NAME = "ISO-8859-1";
public static final Type DEFAULT_ITEM_TYPE = HashMap.class;
@@ -271,8 +258,13 @@ public class CSVSerializer implements Se
}
}
+ // Create the list and notify the listeners
ArrayList<Object> items = new ArrayList<Object>();
+ if (csvSerializerListeners != null) {
+ csvSerializerListeners.beginList(this, items);
+ }
+
// Move to the first character
c = lineNumberReader.read();
@@ -299,36 +291,12 @@ public class CSVSerializer implements Se
throw exception;
}
- return items;
- }
-
- /**
- * Reads values from a comma-separated value stream.
- *
- * @param inputStream
- * The input stream from which data will be read.
- *
- * @see #getStreamIterator(Reader)
- */
- public StreamIterator getStreamIterator(InputStream inputStream) throws IOException {
- Reader reader = new BufferedReader(new InputStreamReader(inputStream, charset),
- BUFFER_SIZE);
- return getStreamIterator(reader);
- }
+ // Notify the listeners
+ if (csvSerializerListeners != null) {
+ csvSerializerListeners.endList(this);
+ }
- /**
- * Reads values from a comma-separated value stream.
- *
- * @param reader
- * The reader from which data will be read.
- *
- * @return
- * A stream iterator on the data read from the CSV file. The list items are
- * instances of Dictionary<String, Object> populated by mapping columns in
- * the CSV file to keys in the key sequence.
- */
- public StreamIterator getStreamIterator(Reader reader) throws IOException {
- return new StreamIterator(reader);
+ return items;
}
@SuppressWarnings("unchecked")
@@ -385,6 +353,11 @@ public class CSVSerializer implements Se
itemDictionary.put(key, value);
}
+
+ // Notify the listeners
+ if (csvSerializerListeners != null) {
+ csvSerializerListeners.readItem(this, item);
+ }
}
return item;
@@ -566,4 +539,12 @@ public class CSVSerializer implements Se
public String getMIMEType(List<?> objects) {
return MIME_TYPE + "; charset=" + charset.name();
}
+
+ public ListenerList<CSVSerializerListener> getCSVSerializerListeners() {
+ if (csvSerializerListeners == null) {
+ csvSerializerListeners = new CSVSerializerListenerList();
+ }
+
+ return csvSerializerListeners;
+ }
}
Added: pivot/trunk/core/src/org/apache/pivot/serialization/CSVSerializerListener.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/serialization/CSVSerializerListener.java?rev=990580&view=auto
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/serialization/CSVSerializerListener.java (added)
+++ pivot/trunk/core/src/org/apache/pivot/serialization/CSVSerializerListener.java Sun Aug 29 14:11:12 2010
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.serialization;
+
+import org.apache.pivot.collections.List;
+
+/**
+ * CSV serializer listener interface.
+ */
+public interface CSVSerializerListener {
+ /**
+ * CSV serializer listener adapter.
+ */
+ public static class Adapter implements CSVSerializerListener {
+ @Override
+ public void beginList(CSVSerializer csvSerializer, List<?> list) {
+ }
+
+ @Override
+ public void endList(CSVSerializer csvSerializer) {
+ }
+
+ @Override
+ public void readItem(CSVSerializer csvSerializer, Object item) {
+ }
+ }
+
+ /**
+ * Called when the serializer has begun reading the list.
+ *
+ * @param csvSerializer
+ * @param list
+ */
+ public void beginList(CSVSerializer csvSerializer, List<?> list);
+
+ /**
+ * Called when the serializer has finished reading the list.
+ *
+ * @param csvSerializer
+ */
+ public void endList(CSVSerializer csvSerializer);
+
+ /**
+ * Called when the serializer has read an item.
+ *
+ * @param csvSerializer
+ * @param item
+ */
+ public void readItem(CSVSerializer csvSerializer, Object item);
+}
Modified: pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java (original)
+++ pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializer.java Sun Aug 29 14:11:12 2010
@@ -36,13 +36,40 @@ import javax.xml.stream.XMLStreamWriter;
import org.apache.pivot.serialization.SerializationException;
import org.apache.pivot.serialization.Serializer;
+import org.apache.pivot.util.ListenerList;
/**
* Reads and writes XML data.
*/
public class XMLSerializer implements Serializer<Element> {
+ private static class XMLSerializerListenerList extends ListenerList<XMLSerializerListener>
+ implements XMLSerializerListener {
+ @Override
+ public void beginElement(XMLSerializer xmlSerializer, Element element) {
+ for (XMLSerializerListener listener : this) {
+ listener.beginElement(xmlSerializer, element);
+ }
+ }
+
+ @Override
+ public void endElement(XMLSerializer xmlSerializer) {
+ for (XMLSerializerListener listener : this) {
+ listener.endElement(xmlSerializer);
+ }
+ }
+
+ @Override
+ public void readTextNode(XMLSerializer xmlSerializer, TextNode textNode) {
+ for (XMLSerializerListener listener : this) {
+ listener.readTextNode(xmlSerializer, textNode);
+ }
+ }
+ }
+
private Charset charset = null;
+ private XMLSerializerListenerList xmlSerializerListeners = null;
+
public static final String XMLNS_ATTRIBUTE_PREFIX = "xmlns";
public static final String DEFAULT_CHARSET_NAME = "UTF-8";
@@ -51,11 +78,7 @@ public class XMLSerializer implements Se
public static final int BUFFER_SIZE = 2048;
public XMLSerializer() {
- this(DEFAULT_CHARSET_NAME);
- }
-
- public XMLSerializer(String charsetName) {
- this(charsetName == null ? Charset.defaultCharset() : Charset.forName(charsetName));
+ this(Charset.forName(DEFAULT_CHARSET_NAME));
}
public XMLSerializer(Charset charset) {
@@ -105,8 +128,14 @@ public class XMLSerializer implements Se
switch (event) {
case XMLStreamConstants.CHARACTERS: {
if (!xmlStreamReader.isWhiteSpace()) {
- String text = xmlStreamReader.getText();
- current.add(new TextNode(text));
+ TextNode textNode = new TextNode(xmlStreamReader.getText());
+
+ // Notify listeners
+ if (xmlSerializerListeners != null) {
+ xmlSerializerListeners.readTextNode(this, textNode);
+ }
+
+ current.add(textNode);
}
break;
@@ -157,12 +186,22 @@ public class XMLSerializer implements Se
current.add(element);
}
+ // Notify listeners
+ if (xmlSerializerListeners != null) {
+ xmlSerializerListeners.beginElement(this, element);
+ }
+
current = element;
break;
}
case XMLStreamConstants.END_ELEMENT: {
+ // Notify listeners
+ if (xmlSerializerListeners != null) {
+ xmlSerializerListeners.endElement(this);
+ }
+
// Move up the stack
current = current.getParent();
@@ -286,4 +325,12 @@ public class XMLSerializer implements Se
public String getMIMEType(Element object) {
return MIME_TYPE;
}
+
+ public ListenerList<XMLSerializerListener> getXMLSerializerListeners() {
+ if (xmlSerializerListeners == null) {
+ xmlSerializerListeners = new XMLSerializerListenerList();
+ }
+
+ return xmlSerializerListeners;
+ }
}
Added: pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializerListener.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializerListener.java?rev=990580&view=auto
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializerListener.java (added)
+++ pivot/trunk/core/src/org/apache/pivot/xml/XMLSerializerListener.java Sun Aug 29 14:11:12 2010
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pivot.xml;
+
+/**
+ * XML serializer listener interface.
+ */
+public interface XMLSerializerListener {
+ /**
+ * XML serializer listener adapter.
+ */
+ public static class Adapter implements XMLSerializerListener {
+ @Override
+ public void beginElement(XMLSerializer xmlSerializer, Element element) {
+ }
+
+ @Override
+ public void endElement(XMLSerializer xmlSerializer) {
+ }
+
+ @Override
+ public void readTextNode(XMLSerializer xmlSerializer, TextNode textNode) {
+ }
+ }
+
+ /**
+ * Called when the serializer has begun reading an element.
+ *
+ * @param xmlSerializer
+ * @param element
+ */
+ public void beginElement(XMLSerializer xmlSerializer, Element element);
+
+ /**
+ * Called when the serializer has finished reading an element.
+ *
+ * @param xmlSerializer
+ */
+ public void endElement(XMLSerializer xmlSerializer);
+
+ /**
+ * Called when the serializer has read a text node.
+ *
+ * @param xmlSerializer
+ * @param textNode
+ */
+ public void readTextNode(XMLSerializer xmlSerializer, TextNode textNode);
+}
Modified: pivot/trunk/core/test/org/apache/pivot/json/test/JSONSerializerTest.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/test/org/apache/pivot/json/test/JSONSerializerTest.java?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/core/test/org/apache/pivot/json/test/JSONSerializerTest.java (original)
+++ pivot/trunk/core/test/org/apache/pivot/json/test/JSONSerializerTest.java Sun Aug 29 14:11:12 2010
@@ -22,9 +22,12 @@ import static org.junit.Assert.assertTru
import java.io.IOException;
+import org.apache.pivot.collections.Dictionary;
import org.apache.pivot.collections.List;
+import org.apache.pivot.collections.Sequence;
import org.apache.pivot.json.JSON;
import org.apache.pivot.json.JSONSerializer;
+import org.apache.pivot.json.JSONSerializerListener;
import org.apache.pivot.serialization.SerializationException;
import org.junit.Test;
@@ -54,7 +57,57 @@ public class JSONSerializerTest {
@Test
public void testEquals() throws IOException, SerializationException {
JSONSerializer jsonSerializer = new JSONSerializer();
+ JSONSerializerListener jsonSerializerListener = new JSONSerializerListener() {
+ @Override
+ public void beginDictionary(JSONSerializer jsonSerializer, Dictionary<String, ?> value) {
+ System.out.println("Begin dictionary: " + value);
+ }
+
+ @Override
+ public void endDictionary(JSONSerializer jsonSerializer) {
+ System.out.println("End dictionary");
+ }
+
+ @Override
+ public void readKey(JSONSerializer jsonSerializer, String key) {
+ System.out.println("Read key: " + key);
+ }
+
+ @Override
+ public void beginSequence(JSONSerializer jsonSerializer, Sequence<?> value) {
+ System.out.println("Begin sequence: " + value);
+ }
+
+ @Override
+ public void endSequence(JSONSerializer jsonSerializer) {
+ System.out.println("End sequence");
+ }
+
+ @Override
+ public void readString(JSONSerializer jsonSerializer, String value) {
+ System.out.println("Read string: " + value);
+ }
+
+ @Override
+ public void readNumber(JSONSerializer jsonSerializer, Number value) {
+ System.out.println("Read number: " + value);
+ }
+
+ @Override
+ public void readBoolean(JSONSerializer jsonSerializer, Boolean value) {
+ System.out.println("Read boolean: " + value);
+ }
+
+ @Override
+ public void readNull(JSONSerializer jsonSerializer) {
+ System.out.println("Read null");
+ }
+ };
+
+ jsonSerializer.getJSONSerializerListeners().add(jsonSerializerListener);
Object o1 = jsonSerializer.readObject(getClass().getResourceAsStream("sample.json"));
+
+ jsonSerializer.getJSONSerializerListeners().remove(jsonSerializerListener);
Object o2 = jsonSerializer.readObject(getClass().getResourceAsStream("sample.json"));
assertTrue(o1.equals(o2));
Modified: pivot/trunk/core/test/org/apache/pivot/json/test/sample.json
URL: http://svn.apache.org/viewvc/pivot/trunk/core/test/org/apache/pivot/json/test/sample.json?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/core/test/org/apache/pivot/json/test/sample.json (original)
+++ pivot/trunk/core/test/org/apache/pivot/json/test/sample.json Sun Aug 29 14:11:12 2010
@@ -19,5 +19,5 @@
c: false,
d: ["1", "2", "3"],
e: {f: 4, g: 5, h: 6},
- i: { a: 200, b: "Goodbye", c: true}
+ "i": { a: 200, b: "Goodbye", c: true}
}
Modified: pivot/trunk/core/test/org/apache/pivot/serialization/test/CSVSerializerTest.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/test/org/apache/pivot/serialization/test/CSVSerializerTest.java?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/core/test/org/apache/pivot/serialization/test/CSVSerializerTest.java (original)
+++ pivot/trunk/core/test/org/apache/pivot/serialization/test/CSVSerializerTest.java Sun Aug 29 14:11:12 2010
@@ -24,6 +24,7 @@ import org.apache.pivot.collections.Arra
import org.apache.pivot.collections.Dictionary;
import org.apache.pivot.collections.HashMap;
import org.apache.pivot.collections.List;
+import org.apache.pivot.serialization.CSVSerializerListener;
import org.apache.pivot.serialization.CSVSerializer;
import org.apache.pivot.serialization.SerializationException;
@@ -46,8 +47,22 @@ public class CSVSerializerTest {
CSVSerializer serializer = new CSVSerializer();
serializer.setKeys("A", "B", "C");
+ serializer.getCSVSerializerListeners().add(new CSVSerializerListener() {
+ public void beginList(CSVSerializer csvSerializer, List<?> list) {
+ System.out.println("Begin list: " + list);
+ }
+
+ public void endList(CSVSerializer csvSerializer) {
+ System.out.println("End list");
+ }
+
+ public void readItem(CSVSerializer csvSerializer, Object item) {
+ System.out.println("Read item: " + item);
+ }
+ });
List<?> result = serializer.readObject(reader);
+
Dictionary<String, Object> row;
// Test the first row
Modified: pivot/trunk/core/test/org/apache/pivot/xml/test/XMLSerializerTest.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/test/org/apache/pivot/xml/test/XMLSerializerTest.java?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/core/test/org/apache/pivot/xml/test/XMLSerializerTest.java (original)
+++ pivot/trunk/core/test/org/apache/pivot/xml/test/XMLSerializerTest.java Sun Aug 29 14:11:12 2010
@@ -21,8 +21,10 @@ import java.io.IOException;
import org.apache.pivot.collections.List;
import org.apache.pivot.serialization.SerializationException;
import org.apache.pivot.xml.Element;
+import org.apache.pivot.xml.TextNode;
import org.apache.pivot.xml.XML;
import org.apache.pivot.xml.XMLSerializer;
+import org.apache.pivot.xml.XMLSerializerListener;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@@ -87,7 +89,27 @@ public class XMLSerializerTest {
@Test
public void equalsTest() throws IOException, SerializationException {
XMLSerializer xmlSerializer = new XMLSerializer();
+ XMLSerializerListener xmlSerializerListener = new XMLSerializerListener() {
+ @Override
+ public void beginElement(XMLSerializer xmlSerializer, Element element) {
+ System.out.println("Begin element: " + element);
+ }
+
+ @Override
+ public void endElement(XMLSerializer xmlSerializer) {
+ System.out.println("End element");
+ }
+
+ @Override
+ public void readTextNode(XMLSerializer xmlSerializer, TextNode textNode) {
+ System.out.println("Read text node: " + textNode);
+ }
+ };
+
+ xmlSerializer.getXMLSerializerListeners().add(xmlSerializerListener);
Element root1 = xmlSerializer.readObject(getClass().getResourceAsStream("sample.xml"));
+
+ xmlSerializer.getXMLSerializerListeners().remove(xmlSerializerListener);
Element root2 = xmlSerializer.readObject(getClass().getResourceAsStream("sample.xml"));
assertTrue(root1.equals(root2));
Modified: pivot/trunk/demos/src/org/apache/pivot/demos/million/LargeData.java
URL: http://svn.apache.org/viewvc/pivot/trunk/demos/src/org/apache/pivot/demos/million/LargeData.java?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/demos/src/org/apache/pivot/demos/million/LargeData.java (original)
+++ pivot/trunk/demos/src/org/apache/pivot/demos/million/LargeData.java Sun Aug 29 14:11:12 2010
@@ -25,110 +25,96 @@ import org.apache.pivot.beans.BXMLSerial
import org.apache.pivot.collections.ArrayList;
import org.apache.pivot.collections.List;
import org.apache.pivot.collections.Map;
+import org.apache.pivot.io.IOTask;
+import org.apache.pivot.serialization.CSVSerializerListener;
import org.apache.pivot.serialization.CSVSerializer;
import org.apache.pivot.serialization.SerializationException;
+import org.apache.pivot.util.concurrent.Task;
+import org.apache.pivot.util.concurrent.TaskListener;
+import org.apache.pivot.util.concurrent.TaskExecutionException;
import org.apache.pivot.wtk.Application;
import org.apache.pivot.wtk.ApplicationContext;
import org.apache.pivot.wtk.Button;
import org.apache.pivot.wtk.ButtonPressListener;
-import org.apache.pivot.wtk.DesktopApplicationContext;
import org.apache.pivot.wtk.Display;
import org.apache.pivot.wtk.Label;
import org.apache.pivot.wtk.ListButton;
import org.apache.pivot.wtk.PushButton;
import org.apache.pivot.wtk.TableView;
import org.apache.pivot.wtk.TableViewSortListener;
+import org.apache.pivot.wtk.TaskAdapter;
import org.apache.pivot.wtk.Window;
import org.apache.pivot.wtk.content.TableViewRowComparator;
public class LargeData implements Application {
- private class LoadDataCallback implements Runnable {
- private class AddRowsCallback implements Runnable {
- private ArrayList<Object> page;
-
- public AddRowsCallback(ArrayList<Object> page) {
- this.page = page;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void run() {
- List<Object> tableData = (List<Object>)tableView.getTableData();
- for (Object item : page) {
- tableData.add(item);
- }
- }
- }
-
+ private class LoadDataTask extends IOTask<Void> {
private URL fileURL;
- public LoadDataCallback(URL fileURL) {
+ public LoadDataTask(URL fileURL) {
this.fileURL = fileURL;
}
@Override
- public void run() {
- Exception fault = null;
-
- long t0 = System.currentTimeMillis();
-
- int i = 0;
+ public Void execute() throws TaskExecutionException {
try {
InputStream inputStream = null;
try {
- inputStream = fileURL.openStream();
+ inputStream = new MonitoredInputStream(fileURL.openStream());
CSVSerializer csvSerializer = new CSVSerializer();
csvSerializer.setKeys("c0", "c1", "c2", "c3");
+ csvSerializer.getCSVSerializerListeners().add(new CSVSerializerListener.Adapter() {
+ private ArrayList<Object> page = new ArrayList<Object>(pageSize);
- CSVSerializer.StreamIterator streamIterator = csvSerializer.getStreamIterator(inputStream);
+ @Override
+ public void endList(CSVSerializer csvSerializer) {
+ if (page.getLength() > 0) {
+ ApplicationContext.queueCallback(new AddRowsCallback(page));
+ }
+ }
- ArrayList<Object> page = new ArrayList<Object>(pageSize);
- while (streamIterator.hasNext()
- && !abort) {
- Object item = streamIterator.next();
- if (item != null) {
+ @Override
+ public void readItem(CSVSerializer csvSerializer, Object item) {
page.add(item);
- }
- i++;
- if (!streamIterator.hasNext()
- || page.getLength() == pageSize) {
- ApplicationContext.queueCallback(new AddRowsCallback(page));
- page = new ArrayList<Object>(pageSize);
+ if (page.getLength() == pageSize) {
+ ApplicationContext.queueCallback(new AddRowsCallback(page));
+ page = new ArrayList<Object>(pageSize);
+ }
}
- }
+ });
+
+ csvSerializer.readObject(inputStream);
} finally {
if (inputStream != null) {
inputStream.close();
}
}
} catch(IOException exception) {
- fault = exception;
+ throw new TaskExecutionException(exception);
} catch(SerializationException exception) {
- fault = exception;
+ throw new TaskExecutionException(exception);
}
- long t1 = System.currentTimeMillis();
+ return null;
+ }
+ }
- final String status;
- if (abort) {
- status = "Aborted";
- } else if (fault != null) {
- status = fault.toString();
- } else {
- status = "Read " + i + " rows in " + (t1 - t0) + "ms";
- }
+ private class AddRowsCallback implements Runnable {
+ private ArrayList<Object> page;
- ApplicationContext.queueCallback(new Runnable() {
- @Override
- public void run() {
- statusLabel.setText(status);
- loadDataButton.setEnabled(true);
- cancelButton.setEnabled(false);
- }
- });
+ public AddRowsCallback(ArrayList<Object> page) {
+ this.page = page;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run() {
+ List<Object> tableData = (List<Object>)tableView.getTableData();
+ for (Object item : page) {
+ tableData.add(item);
+ }
}
}
@@ -142,14 +128,12 @@ public class LargeData implements Applic
private TableView tableView = null;
private int pageSize = 0;
-
- private volatile boolean abort = false;
+ private LoadDataTask loadDataTask = null;
private static final String BASE_PATH_KEY = "basePath";
@Override
- public void startup(Display display, Map<String, String> properties)
- throws Exception {
+ public void startup(Display display, Map<String, String> properties) throws Exception {
basePath = properties.get(BASE_PATH_KEY);
if (basePath == null) {
throw new IllegalArgumentException(BASE_PATH_KEY + " is required.");
@@ -176,7 +160,7 @@ public class LargeData implements Applic
cancelButton.getButtonPressListeners().add(new ButtonPressListener() {
@Override
public void buttonPressed(Button button) {
- abort = true;
+ loadDataTask.abort();
loadDataButton.setEnabled(true);
cancelButton.setEnabled(false);
@@ -218,8 +202,6 @@ public class LargeData implements Applic
}
private void loadData() {
- abort = false;
-
int index = fileListButton.getSelectedIndex();
int capacity = (int)Math.pow(10, index + 1);
tableView.setTableData(new ArrayList<Object>(capacity));
@@ -240,15 +222,31 @@ public class LargeData implements Applic
if (fileURL != null) {
statusLabel.setText("Loading " + fileURL);
- LoadDataCallback callback = new LoadDataCallback(fileURL);
- Thread thread = new Thread(callback);
- thread.setDaemon(true);
- thread.setPriority(Thread.MIN_PRIORITY);
- thread.start();
- }
- }
+ final long t0 = System.currentTimeMillis();
+
+ loadDataTask = new LoadDataTask(fileURL);
+ loadDataTask.execute(new TaskAdapter<Void>(new TaskListener<Void>() {
+ @Override
+ public void taskExecuted(Task<Void> task) {
+ long t1 = System.currentTimeMillis();
- public static void main(String[] args) {
- DesktopApplicationContext.main(LargeData.class, args);
+ statusLabel.setText("Read " + tableView.getTableData().getLength() + " rows in "
+ + (t1 - t0) + "ms");
+ loadDataButton.setEnabled(true);
+ cancelButton.setEnabled(false);
+
+ loadDataTask = null;
+ }
+
+ @Override
+ public void executeFailed(Task<Void> task) {
+ statusLabel.setText(task.getFault().toString());
+ loadDataButton.setEnabled(true);
+ cancelButton.setEnabled(false);
+
+ loadDataTask = null;
+ }
+ }));
+ }
}
}
Modified: pivot/trunk/web/src/org/apache/pivot/web/Query.java
URL: http://svn.apache.org/viewvc/pivot/trunk/web/src/org/apache/pivot/web/Query.java?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/web/src/org/apache/pivot/web/Query.java (original)
+++ pivot/trunk/web/src/org/apache/pivot/web/Query.java Sun Aug 29 14:11:12 2010
@@ -314,7 +314,7 @@ public abstract class Query<V> extends I
* query.
*
* @param serializer
- * The serializer (must be non-null).
+ * The serializer (must be non-null).
*/
public void setSerializer(Serializer<?> serializer) {
if (serializer == null) {
Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/TextAreaContentListener2.java
URL: http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/TextAreaContentListener2.java?rev=990580&r1=990579&r2=990580&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/TextAreaContentListener2.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/TextAreaContentListener2.java Sun Aug 29 14:11:12 2010
@@ -60,7 +60,7 @@ public interface TextAreaContentListener
* @param index
* The index from which the text was removed.
*
- * @param characters
+ * @param count
* The number of characters that were removed.
*/
public void textRemoved(TextArea2 textArea, int index, int count);