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 2011/01/10 00:19:29 UTC
svn commit: r1057053 [5/12] - in /pivot/branches/3.x: ./ core/ core/src/
core/src/org/ core/src/org/apache/ core/src/org/apache/pivot/
core/src/org/apache/pivot/beans/ core/src/org/apache/pivot/bxml/
core/src/org/apache/pivot/csv/ core/src/org/apache/p...
Added: pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/Task.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/Task.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/Task.java (added)
+++ pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/Task.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,237 @@
+/*
+ * 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.util.concurrent;
+
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Abstract base class for "tasks". A task is an asynchronous operation that
+ * may optionally return a value.
+ *
+ * @param <V>
+ * The type of the value returned by the operation. May be {@link Void} to
+ * indicate that the task does not return a value.
+ */
+public abstract class Task<V> {
+ /**
+ * Task execution callback that is posted to the executor service.
+ */
+ private class ExecuteCallback implements Runnable {
+ @Override
+ public void run() {
+ V result = null;
+ Exception fault = null;
+
+ try {
+ result = execute();
+ }
+ catch(Exception exception) {
+ fault = exception;
+ }
+
+ TaskListener<V> taskListener;
+ synchronized (Task.this) {
+ Task.this.result = result;
+ Task.this.fault = fault;
+
+ abort = false;
+
+ taskListener = Task.this.taskListener;
+ Task.this.taskListener = null;
+ }
+
+ taskListener.taskExecuted(Task.this);
+ }
+ }
+
+ private static class DefaultExecutorService extends AbstractExecutorService {
+ private boolean shutdown = false;
+
+ @Override
+ public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
+ return true;
+ }
+
+ @Override
+ public void shutdown() {
+ shutdownNow();
+ }
+
+ @Override
+ public java.util.List<Runnable> shutdownNow() {
+ shutdown = true;
+ return new java.util.ArrayList<Runnable>();
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return shutdown;
+ }
+
+ @Override
+ public boolean isTerminated() {
+ return isShutdown();
+ }
+
+ @Override
+ public void execute(Runnable command) {
+ Thread thread = new Thread(command);
+ thread.start();
+ }
+ }
+
+ private ExecutorService executorService;
+
+ private V result = null;
+ private Exception fault = null;
+ private TaskListener<V> taskListener = null;
+
+ protected volatile long timeout = Long.MAX_VALUE;
+ protected volatile boolean abort = false;
+
+ // TODO This is a workaround for an issue with Executors.newCachedThreadPool(), which
+ // unpredictably throws IllegalThreadStateException when run in an applet.
+ public static final ExecutorService DEFAULT_EXECUTOR_SERVICE = new DefaultExecutorService();
+
+ public Task() {
+ this(DEFAULT_EXECUTOR_SERVICE);
+ }
+
+ public Task(ExecutorService executorService) {
+ if (executorService == null) {
+ throw new IllegalArgumentException("executorService is null.");
+ }
+
+ this.executorService = executorService;
+ }
+
+ /**
+ * Synchronously executes the task.
+ *
+ * @return
+ * The result of the task's execution.
+ *
+ * @throws TaskExecutionException
+ * If an error occurs while executing the task.
+ */
+ public abstract V execute() throws TaskExecutionException;
+
+ /**
+ * Asynchronously executes the task. The caller is notified of the task's
+ * completion via the listener argument. Note that the listener will be
+ * notified on the task's worker thread, not on the thread that executed
+ * the task.
+ *
+ * @param taskListener
+ * The listener to be notified when the task completes.
+ */
+ public synchronized void execute(TaskListener<V> taskListener) {
+ if (taskListener == null) {
+ throw new IllegalArgumentException("taskListener is null.");
+ }
+
+ if (this.taskListener != null) {
+ throw new IllegalThreadStateException("Task is already pending.");
+ }
+
+ this.taskListener = taskListener;
+
+ result = null;
+ fault = null;
+ abort = false;
+
+ // Create a new execute callback and post it to the executor service
+ ExecuteCallback executeCallback = new ExecuteCallback();
+ executorService.submit(executeCallback);
+ }
+
+ /**
+ * Returns the executor service used to execute this task.
+ */
+ public ExecutorService getExecutorService() {
+ return executorService;
+ }
+
+ /**
+ * Returns the result of executing the task.
+ *
+ * @return
+ * The task result, or <tt>null</tt> if the task is still executing or
+ * has failed. The result itself may also be <tt>null</tt>; callers should
+ * call {@link #isPending()} and {@link #getFault()} to distinguish
+ * between these cases.
+ */
+ public synchronized V getResult() {
+ return result;
+ }
+
+ /**
+ * Returns the fault that occurred while executing the task.
+ *
+ * @return
+ * The task fault, or <tt>null</tt> if the task is still executing or
+ * has succeeded. Callers should call {@link #isPending()} to distinguish
+ * between these cases.
+ */
+ public synchronized Exception getFault() {
+ return fault;
+ }
+
+ /**
+ * Returns the pending state of the task.
+ *
+ * @return
+ * <tt>true</tt> if the task is awaiting execution or currently executing;
+ * <tt>false</tt>, otherwise.
+ */
+ public synchronized boolean isPending() {
+ return (taskListener != null);
+ }
+
+
+ /**
+ * Returns the timeout value for this task.
+ *
+ * @see #setTimeout(long)
+ */
+ public synchronized long getTimeout() {
+ return timeout;
+ }
+
+ /**
+ * Sets the timeout value for this task. It is the responsibility of the
+ * implementing class to respect this value.
+ *
+ * @param timeout
+ * The time by which the task must complete execution. If the timeout is
+ * exceeded, a {@link TimeoutException} will be thrown.
+ */
+ public synchronized void setTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+ /**
+ * Sets the abort flag for this task to <tt>true</tt>. It is the
+ * responsibility of the implementing class to respect this value and
+ * throw a {@link AbortException}.
+ */
+ public synchronized void abort() {
+ abort = true;
+ }
+}
Added: pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskExecutionException.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskExecutionException.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskExecutionException.java (added)
+++ pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskExecutionException.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,40 @@
+/*
+ * 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.util.concurrent;
+
+/**
+ * Thrown when an error occurs during task execution.
+ */
+public class TaskExecutionException extends Exception {
+ private static final long serialVersionUID = 0;
+
+ public TaskExecutionException() {
+ super();
+ }
+
+ public TaskExecutionException(String message) {
+ super(message);
+ }
+
+ public TaskExecutionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public TaskExecutionException(Throwable cause) {
+ super(cause);
+ }
+}
Added: pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskGroup.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskGroup.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskGroup.java (added)
+++ pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskGroup.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,42 @@
+/*
+ * 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.util.concurrent;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Abstract base class for task groups.
+ */
+public abstract class TaskGroup extends Task<Void> {
+ protected int complete = 0;
+ protected ArrayList<Task<?>> tasks = new ArrayList<Task<?>>();
+
+ public TaskGroup() {
+ this(DEFAULT_EXECUTOR_SERVICE);
+ }
+
+ public TaskGroup(ExecutorService executorService) {
+ super(executorService);
+ }
+
+ public synchronized List<Task<?>> getTasks() {
+ return isPending() ? Collections.unmodifiableList(tasks) : tasks;
+ }
+}
Added: pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskListener.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskListener.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskListener.java (added)
+++ pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TaskListener.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,39 @@
+/*
+ * 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.util.concurrent;
+
+/**
+ * Task listener interface.
+ *
+ * @param <V>
+ * The return type of the task.
+ */
+public interface TaskListener<V> {
+ /**
+ * Called when the task has been executed. The return value of
+ * {@link Task#getFault()} can be checked to determine if the
+ * execution was successful or not.
+ * <p>
+ * Note that this method will be called on the executing thread,
+ * which is not guaranteed to be the same as the thread on which
+ * {@link Task#execute(TaskListener)} was called.
+ *
+ * @param task
+ * The source of the event.
+ */
+ public void taskExecuted(Task<V> task);
+}
Added: pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TimeoutException.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TimeoutException.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TimeoutException.java (added)
+++ pivot/branches/3.x/core/src/org/apache/pivot/util/concurrent/TimeoutException.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,32 @@
+/*
+ * 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.util.concurrent;
+
+/**
+ * Thrown when an executing task has timed out.
+ */
+public class TimeoutException extends RuntimeException {
+ private static final long serialVersionUID = 0;
+
+ public TimeoutException() {
+ super();
+ }
+
+ public TimeoutException(String message) {
+ super(message);
+ }
+}
Added: pivot/branches/3.x/core/src/org/apache/pivot/xml/Element.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/src/org/apache/pivot/xml/Element.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/src/org/apache/pivot/xml/Element.java (added)
+++ pivot/branches/3.x/core/src/org/apache/pivot/xml/Element.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,762 @@
+/*
+ * Contains code originally developed for Apache Pivot under the Apache
+ * License, Version 2.0:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.apache.pivot.xml;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Node class representing an XML element.
+ */
+public class Element extends Node {
+ /**
+ * Class representing an XML namespace.
+ */
+ public static class Namespace {
+ private Element element = null;
+
+ private String prefix;
+ private String uri;
+
+ public Namespace(String prefix, String uri) {
+ this.prefix = prefix;
+ this.uri = uri;
+ }
+
+ /**
+ * Returns the element to which this attribute belongs.
+ *
+ * @return
+ * This attribute's element, or <tt>null</tt> if the attribute does not
+ * belong to an element.
+ */
+ public Element getElement() {
+ return element;
+ }
+
+ /**
+ * Returns the prefix associated with this namespace.
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Returns the URI associated with this namespace.
+ */
+ public String getURI() {
+ return uri;
+ }
+ }
+
+ /**
+ * Class representing an XML attribute.
+ */
+ public static class Attribute {
+ private Element element = null;
+
+ private String namespacePrefix;
+ private String localName;
+ private String value;
+
+ public Attribute(String localName, String value) {
+ this(null, localName, value);
+ }
+
+ public Attribute(String namespacePrefix, String localName, String value) {
+ validateName(namespacePrefix, localName);
+
+ this.namespacePrefix = namespacePrefix;
+ this.localName = localName;
+
+ setValue(value);
+ }
+
+ /**
+ * Returns the element to which this attribute belongs.
+ *
+ * @return
+ * This attribute's element, or <tt>null</tt> if the attribute does not
+ * belong to an element.
+ */
+ public Element getElement() {
+ return element;
+ }
+
+ /**
+ * Returns the attribute's namespace prefix.
+ *
+ * @return
+ * The attribute's namespace prefix, or <tt>null</tt> if the attribute belongs to the
+ * default namespace.
+ */
+ public String getNamespacePrefix() {
+ return namespacePrefix;
+ }
+
+ /**
+ * Returns the attribute's local name.
+ */
+ public String getLocalName() {
+ return localName;
+ }
+
+ /**
+ * Returns the fully-qualified name of the attribute.
+ */
+ public String getName() {
+ String name;
+ if (namespacePrefix == null) {
+ name = localName;
+ } else {
+ name = namespacePrefix + ":" + localName;
+ }
+
+ return name;
+ }
+
+ /**
+ * Returns the attribute's value.
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the attribute's value.
+ *
+ * @param value
+ */
+ public void setValue(String value) {
+ if (value == null) {
+ throw new IllegalArgumentException();
+ }
+
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean equals = false;
+
+ if (this == o) {
+ equals = true;
+ } else if (o instanceof Attribute) {
+ Attribute attribute = (Attribute)o;
+ if (namespacePrefix == null) {
+ equals = (attribute.namespacePrefix == null);
+ } else {
+ equals = (namespacePrefix.equals(attribute.namespacePrefix));
+ }
+
+ equals &= (localName.equals(attribute.localName)
+ && value.equals(attribute.value));
+ }
+
+ return equals;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ if (namespacePrefix != null) {
+ result = 31 * result + namespacePrefix.hashCode();
+ }
+ result = prime * result + localName.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ String string = "";
+ if (namespacePrefix != null) {
+ string += namespacePrefix + ":";
+ }
+
+ string += localName + "=\"" + value + "\"";
+
+ return string;
+ }
+ }
+
+ private String namespacePrefix;
+ private String localName;
+
+ private String defaultNamespaceURI = null;
+ private ArrayList<Namespace> namespaces = new ArrayList<Namespace>() {
+ private static final long serialVersionUID = 0;
+
+ @Override
+ public boolean add(Namespace namespace) {
+ if (namespace.element != null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (namespaceMap.containsKey(namespace.getPrefix())) {
+ throw new IllegalArgumentException();
+ }
+
+ namespace.element = Element.this;
+ namespaceMap.put(namespace.getPrefix(), namespace);
+
+ return super.add(namespace);
+ }
+
+ @Override
+ public void add(int index, Namespace namespace) {
+ if (namespace.element != null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (namespaceMap.containsKey(namespace.getPrefix())) {
+ throw new IllegalArgumentException();
+ }
+
+ namespace.element = Element.this;
+ namespaceMap.put(namespace.getPrefix(), namespace);
+
+ super.add(index, namespace);
+ }
+
+ @Override
+ public Namespace remove(int index) {
+ Namespace namespace = super.remove(index);
+ namespaceMap.remove(namespace.getPrefix());
+ namespace.element = null;
+
+ return namespace;
+ }
+
+ @Override
+ public void clear() {
+ for (Namespace namespace : this) {
+ namespace.element = null;
+ }
+
+ namespaceMap.clear();
+
+ super.clear();
+ }
+
+ @Override
+ public Namespace set(int index, Namespace namespace) {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ private HashMap<String, Namespace> namespaceMap = new HashMap<String, Namespace>();
+
+ private ArrayList<Attribute> attributes = new ArrayList<Attribute>() {
+ private static final long serialVersionUID = 0;
+
+ @Override
+ public boolean add(Attribute attribute) {
+ if (attribute.element != null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (attributeMap.containsKey(attribute.getName())) {
+ throw new IllegalArgumentException();
+ }
+
+ attribute.element = Element.this;
+ attributeMap.put(attribute.getName(), attribute);
+
+ return super.add(attribute);
+ }
+
+ @Override
+ public void add(int index, Attribute attribute) {
+ if (attribute.element != null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (attributeMap.containsKey(attribute.getName())) {
+ throw new IllegalArgumentException();
+ }
+
+ attribute.element = Element.this;
+ attributeMap.put(attribute.getName(), attribute);
+
+ super.add(index, attribute);
+ }
+
+ @Override
+ public Attribute remove(int index) {
+ Attribute attribute = super.remove(index);
+ attributeMap.remove(attribute.getName());
+ attribute.element = null;
+
+ return attribute;
+ }
+
+ @Override
+ public void clear() {
+ for (Attribute attribute : this) {
+ attribute.element = null;
+ }
+
+ attributeMap.clear();
+
+ super.clear();
+ }
+
+ @Override
+ public Attribute set(int index, Attribute attribute) {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ private HashMap<String, Attribute> attributeMap = new HashMap<String, Attribute>();
+
+ private ArrayList<Node> nodes = new ArrayList<Node>() {
+ private static final long serialVersionUID = 0;
+
+ @Override
+ public boolean add(Node node) {
+ if (node.getParent() != null) {
+ throw new IllegalArgumentException();
+ }
+
+ node.setParent(Element.this);
+ return super.add(node);
+ }
+
+ @Override
+ public void add(int index, Node node) {
+ if (node.getParent() != null) {
+ throw new IllegalArgumentException();
+ }
+
+ node.setParent(Element.this);
+ super.add(index, node);
+ }
+
+ @Override
+ public Node remove(int index) {
+ Node node = super.remove(index);
+ node.setParent(null);
+
+ return node;
+ }
+
+ @Override
+ public void clear() {
+ for (Node node : this) {
+ node.setParent(null);
+ }
+
+ super.clear();
+ }
+
+ @Override
+ public Node set(int index, Node node) {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ public Element(String localName) {
+ this(null, localName);
+ }
+
+ public Element(String namespacePrefix, String localName) {
+ validateName(namespacePrefix, localName);
+
+ this.namespacePrefix = namespacePrefix;
+ this.localName = localName;
+ }
+
+ /**
+ * Returns the element's namespace prefix.
+ *
+ * @return
+ * The element's namespace prefix, or <tt>null</tt> if the element belongs to the
+ * default namespace.
+ */
+ public String getNamespacePrefix() {
+ return namespacePrefix;
+ }
+
+ /**
+ * Returns the element's local name.
+ */
+ public String getLocalName() {
+ return localName;
+ }
+
+ /**
+ * Returns the fully-qualified name of the element.
+ */
+ public String getName() {
+ String name;
+ if (namespacePrefix == null) {
+ name = localName;
+ } else {
+ name = namespacePrefix + ":" + localName;
+ }
+
+ return name;
+ }
+
+ /**
+ * Returns the element's default namespace URI.
+ *
+ * @return
+ * The default namespace URI declared by this element, or <tt>null</tt> if
+ * this element does not declare a default namespace.
+ */
+ public String getDefaultNamespaceURI() {
+ return defaultNamespaceURI;
+ }
+
+ /**
+ * Sets the element's default namespace URI.
+ *
+ * @param defaultNamespaceURI
+ * The default namespace URI declared by this element, or <tt>null</tt> if
+ * this element does not declare a default namespace.
+ */
+ public void setDefaultNamespaceURI(String defaultNamespaceURI) {
+ this.defaultNamespaceURI = defaultNamespaceURI;
+ }
+
+ /**
+ * Returns the element's namespace list.
+ */
+ public List<Namespace> getNamespaces() {
+ return namespaces;
+ }
+
+ /**
+ * Determines the namespace URI corresponding to the given prefix by traversing
+ * the element's ancestry.
+ *
+ * @param prefix
+ * The namespace prefix to look up, or <tt>null</tt> to determine the default
+ * namespace for this element.
+ *
+ * @return
+ * The namespace URI corresponding to the given prefix, or <tt>null</tt> if a
+ * URI could not be found.
+ */
+ public String getNamespaceURI(String prefix) {
+ String namespaceURI;
+
+ Element parent = getParent();
+ if (prefix == null) {
+ if (defaultNamespaceURI == null) {
+ namespaceURI = parent.getDefaultNamespaceURI();
+ } else {
+ namespaceURI = defaultNamespaceURI;
+ }
+ } else {
+ if (namespaceMap.containsKey(prefix)) {
+ namespaceURI = namespaceMap.get(prefix).getURI();
+ } else {
+ namespaceURI = parent.getNamespaceURI(prefix);
+ }
+ }
+
+ return namespaceURI;
+ }
+
+ /**
+ * Returns the element's attribute list.
+ */
+ public List<Attribute> getAttributes() {
+ return attributes;
+ }
+
+ /**
+ * Returns the element's attribute dictionary.
+ */
+ public String getAttributeValue(String attributeName) {
+ Attribute attribute = attributeMap.get(attributeName);
+ return (attribute == null) ? null : attribute.getValue();
+ }
+
+ /**
+ * Returns the element's node list.
+ */
+ public List<Node> getNodes() {
+ return nodes;
+ }
+
+ /**
+ * Returns a descendant element matching a given path.
+ *
+ * @param path
+ * A path of the form:
+ * <pre>
+ * tag[n]/tag[n]/...
+ * </pre>
+ * The bracketed index values are optional and refer to the <i>n</i>th
+ * occurrence of the given tag name within its parent element. If
+ * omitted, the path refers to the first occurrence of the named
+ * element (i.e. the element at index 0).
+ *
+ * @return
+ * The matching element, or <tt>null</tt> if no such element exists.
+ */
+ public Element getElement(String path) {
+ if (path == null) {
+ throw new IllegalArgumentException("path is null.");
+ }
+
+ if (path.length() == 0) {
+ throw new IllegalArgumentException("path is empty.");
+ }
+
+ List<String> pathComponents = Arrays.asList(path.split("/"));
+ Element current = this;
+
+ for (int i = 0, n = pathComponents.size(); i < n; i++) {
+ String pathComponent = pathComponents.get(i);
+
+ String tagName;
+ int index;
+ int leadingBracketIndex = pathComponent.indexOf('[');
+ if (leadingBracketIndex == -1) {
+ tagName = pathComponent;
+ index = 0;
+ } else {
+ tagName = pathComponent.substring(0, leadingBracketIndex);
+
+ int trailingBracketIndex = pathComponent.lastIndexOf(']');
+ if (trailingBracketIndex == -1) {
+ throw new IllegalArgumentException("Unterminated index identifier.");
+ }
+
+ index = Integer.parseInt(pathComponent.substring(leadingBracketIndex + 1,
+ trailingBracketIndex));
+ }
+
+
+ int j = 0;
+ int k = 0;
+ for (Node node : current.getNodes()) {
+ if (node instanceof Element) {
+ Element element = (Element)node;
+
+ if (element.getName().equals(tagName)) {
+ if (k == index) {
+ break;
+ }
+
+ k++;
+ }
+ }
+
+ j++;
+ }
+
+ if (j < current.getNodes().size()) {
+ current = (Element)current.getNodes().get(j);
+ } else {
+ current = null;
+ break;
+ }
+ }
+
+ return current;
+ }
+
+ /**
+ * Returns the sub-elements of of this element whose tag names match the
+ * given name.
+ *
+ * @param name
+ * The tag name to match.
+ *
+ * @return
+ * A sequence containing the matching elements. The sequence will be empty
+ * if no elements matched the given tag name.
+ */
+ public List<Element> getElements(String name) {
+ List<Element> elements = new ArrayList<Element>();
+
+ for (Node node : nodes) {
+ if (node instanceof Element) {
+ Element element = (Element)node;
+
+ if (element.getName().equals(name)) {
+ elements.add(element);
+ }
+ }
+ }
+
+ return elements;
+ }
+
+ /**
+ * Returns the sub-elements of a descendant element whose tag names match
+ * the given name.
+ *
+ * @param path
+ * The path to the descendant, relative to this element.
+ *
+ * @param name
+ * The tag name to match.
+ *
+ * @return
+ * The matching elements, or <tt>null</tt> if no such descendant exists.
+ *
+ * @see #getElement(Element, String)
+ * @see #getElements(String)
+ */
+ public List<Element> getElements(String path, String name) {
+ Element element = getElement(path);
+ return (element == null) ? null : element.getElements(name);
+ }
+
+ /**
+ * Returns the text content of this element. An element is defined to
+ * contain text when it contains a single child that is an instance of
+ * {@link TextNode}.
+ *
+ * @return
+ * The text content of the element, or <tt>null</tt> if this element does
+ * not contain text.
+ */
+ public String getText() {
+ String text = null;
+
+ if (nodes.size() == 1) {
+ Node node = nodes.get(0);
+
+ if (node instanceof TextNode) {
+ TextNode textNode = (TextNode)node;
+ text = textNode.getText();
+ }
+ }
+
+ return text;
+ }
+
+ /**
+ * Returns the text content of a descendant element.
+ *
+ * @param path
+ * The path to the descendant, relative to this element.
+ *
+ * @return
+ * The text of the descendant, or <tt>null</tt> if no such descendant
+ * exists.
+ *
+ * @see #getElement(Element, String)
+ * @see #getText()
+ */
+ public String getText(String path) {
+ Element element = getElement(path);
+ return (element == null) ? null : element.getText();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean equals = false;
+
+ if (this == o) {
+ equals = true;
+ } else if (o instanceof Element) {
+ Element element = (Element)o;
+ if (namespacePrefix == null) {
+ equals = (element.namespacePrefix == null);
+ } else {
+ equals = (namespacePrefix.equals(element.namespacePrefix));
+ }
+
+ equals &= (attributes.equals(element.attributes)
+ && nodes.equals(element.nodes));
+ }
+
+ return equals;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ if (namespacePrefix != null) {
+ result = 31 * result + namespacePrefix.hashCode();
+ }
+ result = prime * result + localName.hashCode();
+ result = prime * result + namespaces.hashCode();
+ result = prime * result + attributes.hashCode();
+ result = prime * result + nodes.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ String string = "<";
+ if (namespacePrefix != null) {
+ string += namespacePrefix + ":";
+ }
+
+ string += localName + ">";
+
+ return string;
+ }
+
+ private static void validateName(String namespacePrefix, String localName) {
+ // Validate prefix
+ if (namespacePrefix != null) {
+ if (namespacePrefix.length() == 0) {
+ throw new IllegalArgumentException("Namespace prefix is empty.");
+ }
+
+ char c = namespacePrefix.charAt(0);
+ if (!Character.isLetter(c)) {
+ throw new IllegalArgumentException("'" + c + "' is not a valid start"
+ + " character for a namespace prefix.");
+ }
+
+ for (int i = 1, n = namespacePrefix.length(); i < n; i++) {
+ c = namespacePrefix.charAt(i);
+
+ if (!Character.isLetterOrDigit(c)
+ && c != '-'
+ && c != '_'
+ && c != '.') {
+ throw new IllegalArgumentException("'" + c + "' is not a valid character"
+ + " for a namespace prefix.");
+ }
+ }
+ }
+
+ // Validate local name
+ if (localName == null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (localName.length() == 0) {
+ throw new IllegalArgumentException("Local name is empty.");
+ }
+
+ char c = localName.charAt(0);
+ if (!Character.isLetter(c)
+ && c != '_') {
+ throw new IllegalArgumentException("'" + c + "' is not a valid start"
+ + " character for a local name.");
+ }
+
+ for (int i = 1, n = localName.length(); i < n; i++) {
+ c = localName.charAt(i);
+
+ if (!Character.isLetterOrDigit(c)
+ && c != '-'
+ && c != '_'
+ && c != '.') {
+ throw new IllegalArgumentException("'" + c + "' is not a valid character"
+ + " for a local name.");
+ }
+ }
+ }
+}
Added: pivot/branches/3.x/core/src/org/apache/pivot/xml/Node.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/src/org/apache/pivot/xml/Node.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/src/org/apache/pivot/xml/Node.java (added)
+++ pivot/branches/3.x/core/src/org/apache/pivot/xml/Node.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,30 @@
+/*
+ * Contains code originally developed for Apache Pivot under the Apache
+ * License, Version 2.0:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.apache.pivot.xml;
+
+/**
+ * Abstract base class for XML nodes.
+ */
+public abstract class Node {
+ private Element parent = null;
+
+ /**
+ * Returns the parent element of the node.
+ */
+ public Element getParent() {
+ return parent;
+ }
+
+ /**
+ * Sets the parent element of the node.
+ *
+ * @param parent
+ */
+ protected void setParent(Element parent) {
+ this.parent = parent;
+ }
+}
Added: pivot/branches/3.x/core/src/org/apache/pivot/xml/TextNode.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/src/org/apache/pivot/xml/TextNode.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/src/org/apache/pivot/xml/TextNode.java (added)
+++ pivot/branches/3.x/core/src/org/apache/pivot/xml/TextNode.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,50 @@
+/*
+ * Contains code originally developed for Apache Pivot under the Apache
+ * License, Version 2.0:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.apache.pivot.xml;
+
+/**
+ * Class representing an XML text node.
+ */
+public class TextNode extends Node {
+ private String text;
+
+ public TextNode(String text) {
+ if (text == null) {
+ throw new IllegalArgumentException();
+ }
+
+ this.text = text;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ boolean equals = false;
+
+ if (this == o) {
+ equals = true;
+ } else if (o instanceof TextNode) {
+ TextNode textNode = (TextNode)o;
+ equals = (text.equals(textNode.text));
+ }
+
+ return equals;
+ }
+
+ @Override
+ public int hashCode() {
+ return text.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+}
Added: pivot/branches/3.x/core/src/org/apache/pivot/xml/XMLSerializer.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/src/org/apache/pivot/xml/XMLSerializer.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/src/org/apache/pivot/xml/XMLSerializer.java (added)
+++ pivot/branches/3.x/core/src/org/apache/pivot/xml/XMLSerializer.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,326 @@
+/*
+ * Contains code originally developed for Apache Pivot under the Apache
+ * License, Version 2.0:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.apache.pivot.xml;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.charset.Charset;
+
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.pivot.io.SerializationException;
+import org.apache.pivot.io.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 : listeners()) {
+ listener.beginElement(xmlSerializer, element);
+ }
+ }
+
+ @Override
+ public void endElement(XMLSerializer xmlSerializer) {
+ for (XMLSerializerListener listener : listeners()) {
+ listener.endElement(xmlSerializer);
+ }
+ }
+
+ @Override
+ public void readTextNode(XMLSerializer xmlSerializer, TextNode textNode) {
+ for (XMLSerializerListener listener : listeners()) {
+ 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";
+ public static final String XML_EXTENSION = "xml";
+ public static final String MIME_TYPE = "text/xml";
+ public static final int BUFFER_SIZE = 2048;
+
+ public XMLSerializer() {
+ this(Charset.forName(DEFAULT_CHARSET_NAME));
+ }
+
+ public XMLSerializer(Charset charset) {
+ if (charset == null) {
+ throw new IllegalArgumentException("charset is null.");
+ }
+
+ this.charset = charset;
+ }
+
+ public Charset getCharset() {
+ return charset;
+ }
+
+ @Override
+ public Element readObject(InputStream inputStream)
+ throws IOException, SerializationException {
+ if (inputStream == null) {
+ throw new IllegalArgumentException("inputStream is null.");
+ }
+
+ Reader reader = new BufferedReader(new InputStreamReader(inputStream, charset), BUFFER_SIZE);
+ Element element = readObject(reader);
+
+ return element;
+ }
+
+ public Element readObject(Reader reader) throws SerializationException {
+ if (reader == null) {
+ throw new IllegalArgumentException("reader is null.");
+ }
+
+ // Parse the XML stream
+ XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ xmlInputFactory.setProperty("javax.xml.stream.isCoalescing", true);
+
+ Element document = null;
+
+ try {
+ XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(reader);
+
+ Element current = null;
+
+ while (xmlStreamReader.hasNext()) {
+ int event = xmlStreamReader.next();
+
+ switch (event) {
+ case XMLStreamConstants.CHARACTERS: {
+ if (!xmlStreamReader.isWhiteSpace()) {
+ TextNode textNode = new TextNode(xmlStreamReader.getText());
+
+ // Notify listeners
+ if (xmlSerializerListeners != null) {
+ xmlSerializerListeners.readTextNode(this, textNode);
+ }
+
+ current.getNodes().add(textNode);
+ }
+
+ break;
+ }
+
+ case XMLStreamConstants.START_ELEMENT: {
+ // Create the element
+ String prefix = xmlStreamReader.getPrefix();
+ if (prefix != null
+ && prefix.length() == 0) {
+ prefix = null;
+ }
+
+ String localName = xmlStreamReader.getLocalName();
+
+ Element element = new Element(prefix, localName);
+
+ // Get the element's namespaces
+ for (int i = 0, n = xmlStreamReader.getNamespaceCount(); i < n; i++) {
+ String namespacePrefix = xmlStreamReader.getNamespacePrefix(i);
+ String namespaceURI = xmlStreamReader.getNamespaceURI(i);
+
+ if (namespacePrefix == null) {
+ element.setDefaultNamespaceURI(namespaceURI);
+ } else {
+ element.getNamespaces().add(new Element.Namespace(namespacePrefix, namespaceURI));
+ }
+ }
+
+ // Get the element's attributes
+ for (int i = 0, n = xmlStreamReader.getAttributeCount(); i < n; i++) {
+ String attributePrefix = xmlStreamReader.getAttributePrefix(i);
+ if (attributePrefix != null
+ && attributePrefix.length() == 0) {
+ attributePrefix = null;
+ }
+
+ String attributeLocalName = xmlStreamReader.getAttributeLocalName(i);
+ String attributeValue = xmlStreamReader.getAttributeValue(i);
+
+ element.getAttributes().add(new Element.Attribute(attributePrefix,
+ attributeLocalName, attributeValue));
+ }
+
+ if (current == null) {
+ document = element;
+ } else {
+ current.getNodes().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();
+
+ break;
+ }
+ }
+ }
+ } catch (XMLStreamException exception) {
+ throw new SerializationException(exception);
+ }
+
+ return document;
+ }
+
+ @Override
+ public void writeObject(Element element, OutputStream outputStream)
+ throws IOException, SerializationException {
+ if (outputStream == null) {
+ throw new IllegalArgumentException("outputStream is null.");
+ }
+
+ Writer writer = new BufferedWriter(new OutputStreamWriter(outputStream, charset),
+ BUFFER_SIZE);
+ writeObject(element, writer);
+ writer.flush();
+ }
+
+ public void writeObject(Element element, Writer writer) throws SerializationException {
+ if (writer == null) {
+ throw new IllegalArgumentException("writer is null.");
+ }
+
+ if (element == null) {
+ throw new IllegalArgumentException("element is null.");
+ }
+
+ XMLOutputFactory output = XMLOutputFactory.newInstance();
+
+ try {
+ XMLStreamWriter xmlStreamWriter = output.createXMLStreamWriter(writer);
+ xmlStreamWriter.writeStartDocument();
+ writeElement(element, xmlStreamWriter);
+ xmlStreamWriter.writeEndDocument();
+ } catch (XMLStreamException exception) {
+ throw new SerializationException(exception);
+ }
+ }
+
+ private void writeElement(Element element, XMLStreamWriter xmlStreamWriter)
+ throws XMLStreamException, SerializationException {
+ String namespacePrefix = element.getNamespacePrefix();
+ String localName = element.getLocalName();
+
+ if (namespacePrefix == null) {
+ if (element.getNodes().size() == 0) {
+ xmlStreamWriter.writeEmptyElement(localName);
+ } else {
+ xmlStreamWriter.writeStartElement(localName);
+ }
+ } else {
+ String namespaceURI = element.getNamespaceURI(namespacePrefix);
+
+ if (element.getNodes().size() == 0) {
+ xmlStreamWriter.writeEmptyElement(namespacePrefix, localName, namespaceURI);
+ } else {
+ xmlStreamWriter.writeStartElement(namespacePrefix, localName, namespaceURI);
+ }
+ }
+
+ // Write out the declared namespaces
+ String defaultNamespaceURI = element.getDefaultNamespaceURI();
+ if (defaultNamespaceURI != null) {
+ xmlStreamWriter.writeDefaultNamespace(defaultNamespaceURI);
+ }
+
+ for (Element.Namespace namespace : element.getNamespaces()) {
+ xmlStreamWriter.writeNamespace(namespace.getPrefix(), namespace.getURI());
+ }
+
+ // Write out the attributes
+ for (Element.Attribute attribute : element.getAttributes()) {
+ String attributeNamespacePrefix = attribute.getNamespacePrefix();
+ String attributeLocalName = attribute.getLocalName();
+ String attributeValue = attribute.getValue();
+
+ if (attributeNamespacePrefix == null) {
+ xmlStreamWriter.writeAttribute(attributeLocalName, attributeValue);
+ } else {
+ String attributeNamespaceURI = element.getNamespaceURI(attributeNamespacePrefix);
+
+ xmlStreamWriter.writeAttribute(attributeNamespacePrefix, attributeNamespaceURI,
+ attributeLocalName, attributeValue);
+ }
+ }
+
+ // Write out the child nodes
+ for (Node node : element.getNodes()) {
+ if (node instanceof Element) {
+ writeElement((Element)node, xmlStreamWriter);
+ } else if (node instanceof TextNode) {
+ writeTextNode((TextNode)node, xmlStreamWriter);
+ } else {
+ throw new SerializationException("Unsupported node type: "
+ + node.getClass().getName());
+ }
+ }
+
+ if (element.getNodes().size() > 0) {
+ xmlStreamWriter.writeEndElement();
+ }
+ }
+
+ private void writeTextNode(TextNode textNode, XMLStreamWriter xmlStreamWriter)
+ throws XMLStreamException {
+ xmlStreamWriter.writeCharacters(textNode.getText());
+ }
+
+ @Override
+ public String getMIMEType(Element object) {
+ return MIME_TYPE;
+ }
+
+ public ListenerList<XMLSerializerListener> getXMLSerializerListeners() {
+ if (xmlSerializerListeners == null) {
+ xmlSerializerListeners = new XMLSerializerListenerList();
+ }
+
+ return xmlSerializerListeners;
+ }
+}
Added: pivot/branches/3.x/core/src/org/apache/pivot/xml/XMLSerializerListener.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/src/org/apache/pivot/xml/XMLSerializerListener.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/src/org/apache/pivot/xml/XMLSerializerListener.java (added)
+++ pivot/branches/3.x/core/src/org/apache/pivot/xml/XMLSerializerListener.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,52 @@
+/*
+ * Contains code originally developed for Apache Pivot under the Apache
+ * License, Version 2.0:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+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);
+}
Added: pivot/branches/3.x/core/test/org/apache/pivot/beans/test/BeanAdapterTest.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/test/org/apache/pivot/beans/test/BeanAdapterTest.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/test/org/apache/pivot/beans/test/BeanAdapterTest.java (added)
+++ pivot/branches/3.x/core/test/org/apache/pivot/beans/test/BeanAdapterTest.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,33 @@
+package org.apache.pivot.beans.test;
+
+import org.apache.pivot.beans.BeanAdapter;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class BeanAdapterTest {
+ @Test
+ public void basicTest() {
+ SampleBean sampleBean = new SampleBean();
+ BeanAdapter beanAdapter = new BeanAdapter(sampleBean);
+
+ assertEquals(sampleBean.getA(), beanAdapter.get("a"));
+ assertEquals(sampleBean.getB(), beanAdapter.get("b"));
+ assertTrue(beanAdapter.isReadOnly("b"));
+
+ for (String property : beanAdapter.keySet()) {
+ assertFalse(beanAdapter.isReadOnly(property));
+ }
+
+ // Test explicit setter
+ beanAdapter.put("a", "100");
+ assertEquals(beanAdapter.get("a"), -100);
+
+ // Test type coercion
+ beanAdapter.put("a", 10.9);
+ assertEquals(beanAdapter.get("a"), 10);
+
+ beanAdapter.put("testEnum", "abcDef");
+ beanAdapter.put("testEnum", "ABC_DEF");
+ }
+}
Added: pivot/branches/3.x/core/test/org/apache/pivot/beans/test/SampleBean.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/test/org/apache/pivot/beans/test/SampleBean.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/test/org/apache/pivot/beans/test/SampleBean.java (added)
+++ pivot/branches/3.x/core/test/org/apache/pivot/beans/test/SampleBean.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,35 @@
+package org.apache.pivot.beans.test;
+
+public class SampleBean {
+ public enum TestEnum {
+ ABC_DEF
+ }
+
+ private int a = 20;
+ private String b = "ABCD";
+ private TestEnum testEnum = null;
+
+ public int getA() {
+ return a;
+ }
+
+ public void setA(int a) {
+ this.a = a;
+ }
+
+ public void setA(String a) {
+ setA(-Integer.parseInt(a));
+ }
+
+ public String getB() {
+ return b;
+ }
+
+ public TestEnum getTestEnum() {
+ return testEnum;
+ }
+
+ public void setTestEnum(TestEnum testEnum) {
+ this.testEnum = testEnum;
+ }
+}
Added: pivot/branches/3.x/core/test/org/apache/pivot/csv/test/CSVSerializerTest.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/test/org/apache/pivot/csv/test/CSVSerializerTest.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/test/org/apache/pivot/csv/test/CSVSerializerTest.java (added)
+++ pivot/branches/3.x/core/test/org/apache/pivot/csv/test/CSVSerializerTest.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,248 @@
+/*
+ * 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.csv.test;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.pivot.csv.CSVSerializer;
+import org.apache.pivot.csv.CSVSerializerListener;
+import org.apache.pivot.io.SerializationException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class CSVSerializerTest {
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testBasicReadObject() throws IOException, SerializationException {
+ // Test multiple line break formats
+ StringBuilder buf = new StringBuilder();
+ buf.append("a1,b1,c1\r\n");
+ buf.append("a2,b2,c2\n");
+ buf.append("a3,b3,c3\r");
+ buf.append("a4,b4,c4");
+
+ StringReader reader = new StringReader(buf.toString());
+
+ 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);
+
+ Map<String, Object> row;
+
+ // Test the first row
+ row = (Map<String, Object>)result.get(0);
+ assertEquals(row.get("A"), "a1");
+ assertEquals(row.get("B"), "b1");
+ assertEquals(row.get("C"), "c1");
+
+ // Test the second row
+ row = (Map<String, Object>)result.get(1);
+ assertEquals(row.get("A"), "a2");
+ assertEquals(row.get("B"), "b2");
+ assertEquals(row.get("C"), "c2");
+
+ // Test the third row
+ row = (Map<String, Object>)result.get(2);
+ assertEquals(row.get("A"), "a3");
+ assertEquals(row.get("B"), "b3");
+ assertEquals(row.get("C"), "c3");
+
+ // Test the fourth row
+ row = (Map<String, Object>)result.get(3);
+ assertEquals(row.get("A"), "a4");
+ assertEquals(row.get("B"), "b4");
+ assertEquals(row.get("C"), "c4");
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testQuotedCommaReadObject() throws IOException, SerializationException {
+ StringBuilder buf = new StringBuilder();
+ buf.append("a,\",b,\",c\r\n");
+
+ StringReader reader = new StringReader(buf.toString());
+
+ CSVSerializer serializer = new CSVSerializer();
+ serializer.setKeys("A", "B", "C");
+
+ List<?> result = serializer.readObject(reader);
+
+ Map<String, Object> row = (Map<String, Object>)result.get(0);
+ assertEquals("a", row.get("A"));
+ assertEquals(",b,", row.get("B"));
+ assertEquals("c", row.get("C"));
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testQuotedQuoteReadObject() throws IOException, SerializationException {
+ StringBuilder buf = new StringBuilder();
+ buf.append("a,\"\"\"b\"\"\",c\r\n");
+
+ StringReader reader = new StringReader(buf.toString());
+
+ CSVSerializer serializer = new CSVSerializer();
+ serializer.setKeys("A", "B", "C");
+
+ List<?> result = serializer.readObject(reader);
+
+ Map<String, Object> row = (Map<String, Object>)result.get(0);
+ assertEquals("a", row.get("A"));
+ assertEquals("\"b\"", row.get("B"));
+ assertEquals("c", row.get("C"));
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testQuotedNewlineReadObject() throws IOException, SerializationException {
+ StringBuilder buf = new StringBuilder();
+ buf.append("a,\"b\nb \",c\r\n");
+
+ StringReader reader = new StringReader(buf.toString());
+
+ CSVSerializer serializer = new CSVSerializer();
+ serializer.setKeys("A", "B", "C");
+
+ List<?> result = serializer.readObject(reader);
+
+ Map<String, Object> row = (Map<String, Object>)result.get(0);
+ assertEquals("a", row.get("A"));
+ assertEquals("b\nb", row.get("B"));
+ assertEquals("c", row.get("C"));
+ }
+
+ @Test
+ public void testBasicWriteObject() throws IOException {
+ List<Object> items = new ArrayList<Object>();
+
+ HashMap<String, Object> item1 = new HashMap<String, Object>();
+ item1.put("A", "a1");
+ item1.put("B", "b1");
+ item1.put("C", "c1");
+ items.add(item1);
+
+ HashMap<String, Object> item2 = new HashMap<String, Object>();
+ item2.put("A", "a2");
+ item2.put("B", "b2");
+ item2.put("C", "c2");
+ items.add(item2);
+
+ StringWriter writer = new StringWriter();
+
+ CSVSerializer serializer = new CSVSerializer();
+ serializer.setKeys("A", "B", "C");
+
+ serializer.writeObject(items, writer);
+
+ assertEquals("a1,b1,c1\r\na2,b2,c2\r\n", writer.toString());
+ }
+
+ @Test
+ public void testQuotedCommaWriteObject() throws IOException {
+ List<Object> items = new ArrayList<Object>();
+ HashMap<String, Object> item = new HashMap<String, Object>();
+ item.put("A", "a");
+ item.put("B", ",b,");
+ item.put("C", "c");
+ items.add(item);
+
+ StringWriter writer = new StringWriter();
+
+ CSVSerializer serializer = new CSVSerializer();
+ serializer.setKeys("A", "B", "C");
+
+ serializer.writeObject(items, writer);
+
+ assertEquals("a,\",b,\",c\r\n", writer.toString());
+ }
+
+ @Test
+ public void testQuotedQuoteWriteObject() throws IOException {
+ List<Object> items = new ArrayList<Object>();
+ HashMap<String, Object> item = new HashMap<String, Object>();
+ item.put("A", "a");
+ item.put("B", "\"b\"");
+ item.put("C", "c");
+ items.add(item);
+
+ StringWriter writer = new StringWriter();
+
+ CSVSerializer serializer = new CSVSerializer();
+ serializer.setKeys("A", "B", "C");
+
+ serializer.writeObject(items, writer);
+
+ assertEquals("a,\"\"\"b\"\"\",c\r\n", writer.toString());
+ }
+
+ @Test
+ public void testQuotedNewlineWriteObject() throws IOException {
+ List<Object> items = new ArrayList<Object>();
+ HashMap<String, Object> item = new HashMap<String, Object>();
+ item.put("A", "a");
+ item.put("B", "\nb\n");
+ item.put("C", "c");
+ items.add(item);
+
+ StringWriter writer = new StringWriter();
+
+ CSVSerializer serializer = new CSVSerializer();
+ serializer.setKeys("A", "B", "C");
+
+ serializer.writeObject(items, writer);
+
+ assertEquals("a,\"\nb\n\",c\r\n", writer.toString());
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testInlineKeys() throws IOException, SerializationException {
+ StringBuilder buf = new StringBuilder();
+ buf.append("A \t, B ,C \n");
+ buf.append("a1,b1,c1\n");
+
+ StringReader reader = new StringReader(buf.toString());
+
+ CSVSerializer serializer = new CSVSerializer();
+ List<?> result = serializer.readObject(reader);
+ Map<String, Object> row = (Map<String, Object>)result.get(0);
+ assertEquals(row.get("A"), "a1");
+ assertEquals(row.get("B"), "b1");
+ assertEquals(row.get("C"), "c1");
+ }
+}
Added: pivot/branches/3.x/core/test/org/apache/pivot/io/test/BinarySerializerTest.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/test/org/apache/pivot/io/test/BinarySerializerTest.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/test/org/apache/pivot/io/test/BinarySerializerTest.java (added)
+++ pivot/branches/3.x/core/test/org/apache/pivot/io/test/BinarySerializerTest.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,61 @@
+/*
+ * 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.io.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.apache.pivot.io.BinarySerializer;
+import org.apache.pivot.io.Serializer;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.fail;
+
+public class BinarySerializerTest {
+ @Test
+ public void testBinarySerializer() {
+ Serializer<Object> serializer = new BinarySerializer();
+
+ Object[] outputData = {
+ "Hello World",
+ 123.456,
+ true
+ };
+ Object[] inputData;
+
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ try {
+ serializer.writeObject(outputData, outputStream);
+ } finally {
+ outputStream.close();
+ }
+
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
+ try {
+ inputData = (Object[])serializer.readObject(inputStream);
+ } finally {
+ inputStream.close();
+ }
+
+ assertArrayEquals(outputData, inputData);
+ } catch(Exception exception) {
+ fail(exception.getMessage());
+ }
+ }
+}
Added: pivot/branches/3.x/core/test/org/apache/pivot/io/test/ByteArraySerializerTest.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/test/org/apache/pivot/io/test/ByteArraySerializerTest.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/test/org/apache/pivot/io/test/ByteArraySerializerTest.java (added)
+++ pivot/branches/3.x/core/test/org/apache/pivot/io/test/ByteArraySerializerTest.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,81 @@
+/*
+ * 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.io.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.apache.pivot.io.ByteArraySerializer;
+import org.apache.pivot.io.SerializationException;
+import org.apache.pivot.io.Serializer;
+import org.junit.Test;
+
+public class ByteArraySerializerTest {
+ public static final String testString = "// \n" + "// Hello from "
+ + ByteArraySerializerTest.class.getName() + "\n" + "// \n";
+ public static final byte[] testBytes = testString.getBytes();
+
+ public void log(String msg) {
+ System.out.println(msg);
+ }
+
+ @Test
+ public void readValues() throws IOException, SerializationException {
+ log("readValues()");
+
+ Serializer<byte[]> serializer = new ByteArraySerializer();
+
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(testBytes);
+ byte[] result = serializer.readObject(inputStream);
+ assertNotNull(result);
+
+ // dump content, but useful only for text resources ...
+ String dump = new String(result);
+ int dumpLength = dump.getBytes().length;
+ log("Result: " + dumpLength + " bytes \n" + dump);
+
+ assertTrue(dumpLength > 0);
+ }
+
+ @Test
+ public void writeValues() throws IOException, SerializationException {
+ log("writeValues()");
+
+ Serializer<byte[]> serializer = new ByteArraySerializer();
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ serializer.writeObject(testBytes, outputStream);
+
+ outputStream.flush();
+ outputStream.close();
+
+ byte[] result = outputStream.toByteArray();
+ assertNotNull(result);
+
+ // dump content, but useful only for text resources ...
+ String dump = new String(result);
+ int dumpLength = dump.getBytes().length;
+ log("Result: " + dumpLength + " bytes \n" + dump);
+
+ assertTrue(dumpLength > 0);
+ }
+
+}
Added: pivot/branches/3.x/core/test/org/apache/pivot/io/test/StringSerializerTest.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/test/org/apache/pivot/io/test/StringSerializerTest.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/test/org/apache/pivot/io/test/StringSerializerTest.java (added)
+++ pivot/branches/3.x/core/test/org/apache/pivot/io/test/StringSerializerTest.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,84 @@
+/*
+ * 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.io.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.apache.pivot.io.SerializationException;
+import org.apache.pivot.io.Serializer;
+import org.apache.pivot.io.StringSerializer;
+import org.junit.Test;
+
+public class StringSerializerTest {
+ public static final String testString = "// \n" + "// Hello from "
+ + StringSerializerTest.class.getName() + "\n" + "// \n";
+ public static final byte[] testBytes = testString.getBytes();
+
+ public void log(String msg) {
+ System.out.println(msg);
+ }
+
+ @Test
+ public void readValues() throws IOException, SerializationException {
+ log("readValues()");
+
+ Serializer<String> serializer = new StringSerializer();
+
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(testBytes);
+ String result = serializer.readObject(inputStream);
+ assertNotNull(result);
+ assertEquals(result, testString);
+
+ // dump content, but useful only for text resources ...
+ String dump = new String(result);
+ int dumpLength = dump.getBytes().length;
+ log("Result: " + dumpLength + " bytes \n" + dump);
+
+ assertTrue(dumpLength > 0);
+ }
+
+ @Test
+ public void writeValues() throws IOException, SerializationException {
+ log("writeValues()");
+
+ Serializer<String> serializer = new StringSerializer();
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ serializer.writeObject(testString, outputStream);
+
+ outputStream.flush();
+ outputStream.close();
+
+ String result = outputStream.toString();
+ assertNotNull(result);
+ assertEquals(result, testString);
+
+ // dump content, but useful only for text resources ...
+ String dump = new String(result);
+ int dumpLength = dump.getBytes().length;
+ log("Result: " + dumpLength + " bytes \n" + dump);
+
+ assertTrue(dumpLength > 0);
+ }
+
+}
Added: pivot/branches/3.x/core/test/org/apache/pivot/json/test/BindTest.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/test/org/apache/pivot/json/test/BindTest.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/test/org/apache/pivot/json/test/BindTest.java (added)
+++ pivot/branches/3.x/core/test/org/apache/pivot/json/test/BindTest.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,171 @@
+/*
+ * 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.test;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.pivot.beans.BeanAdapter;
+import org.apache.pivot.io.SerializationException;
+import org.apache.pivot.json.JSONSerializer;
+import org.apache.pivot.util.TypeLiteral;
+import org.junit.Test;
+
+public class BindTest {
+ /**
+ * Tests returning an untyped list.
+ *
+ * @throws IOException
+ * @throws SerializationException
+ */
+ @Test
+ public void testUntypedList() throws IOException, SerializationException {
+ JSONSerializer listSerializer = new JSONSerializer(ArrayList.class);
+ List<?> list = (List<?>)listSerializer.readObject(new StringReader("[1, 2, 3, 4, 5]"));
+ assertEquals(list.get(0), 1);
+ }
+
+ /**
+ * Tests returning a typed list using {@code org.apache.pivot.util.TypeLiteral}.
+ *
+ * @throws IOException
+ * @throws SerializationException
+ */
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testTypedList() throws IOException, SerializationException {
+ JSONSerializer listSerializer = new JSONSerializer();
+ List<Object> list =
+ (List<Object>)listSerializer.readObject(getClass().getResourceAsStream("list.json"));
+
+ JSONSerializer typedListSerializer =
+ new JSONSerializer((new TypeLiteral<ArrayList<SampleBean2>>() {}).getType());
+ ArrayList<SampleBean2> typedList =
+ (ArrayList<SampleBean2>)typedListSerializer.readObject(getClass().getResourceAsStream("list.json"));
+
+ Object item0 = typedList.get(0);
+ assertTrue(item0 instanceof SampleBean2);
+ assertEquals(typedList.get(0).getA(), BeanAdapter.get(list, "[0].a"));
+ }
+
+ /**
+ * Tests returning a subclass of a generic {@code org.apache.pivot.collections.List}.
+ *
+ * @throws IOException
+ * @throws SerializationException
+ */
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testListSubclass() throws IOException, SerializationException {
+ JSONSerializer listSerializer = new JSONSerializer();
+ List<Object> list =
+ (List<Object>)listSerializer.readObject(getClass().getResourceAsStream("list.json"));
+
+ JSONSerializer typedListSerializer = new JSONSerializer(SampleBean2ListSubclass.class);
+ SampleBean2List typedList =
+ (SampleBean2List)typedListSerializer.readObject(getClass().getResourceAsStream("list.json"));
+
+ Object item0 = typedList.get(0);
+ assertTrue(item0 instanceof SampleBean2);
+ assertEquals(typedList.get(0).getA(), BeanAdapter.get(list, "[0].a"));
+ }
+
+ /**
+ * Tests returning an untyped map.
+ *
+ * @throws IOException
+ * @throws SerializationException
+ */
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testUntypedMap() throws IOException, SerializationException {
+ JSONSerializer mapSerializer = new JSONSerializer(HashMap.class);
+ HashMap<String, ?> map = (HashMap<String, ?>)mapSerializer.readObject(new StringReader("{a:1, b:2, c:'3'}"));
+ assertEquals(map.get("a"), 1);
+ }
+
+ /**
+ * Tests returning a typed map using {@code org.apache.pivot.util.TypeLiteral}.
+ *
+ * @throws IOException
+ * @throws SerializationException
+ */
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testTypedMap() throws IOException, SerializationException {
+ JSONSerializer typedMapSerializer =
+ new JSONSerializer((new TypeLiteral<HashMap<String, SampleBean2>>() {}).getType());
+
+ HashMap<String, SampleBean2> map =
+ (HashMap<String, SampleBean2>)typedMapSerializer.readObject(new StringReader("{foo: {a:1, b:2, c:'3'}}"));
+
+ assertTrue(BeanAdapter.get(map, "foo") instanceof SampleBean2);
+ assertEquals(BeanAdapter.get(map, "foo.c"), "3");
+ }
+
+ /**
+ * Tests returning a subclass of a generic {@code org.apache.pivot.collections.Map}.
+ *
+ * @throws IOException
+ * @throws SerializationException
+ */
+ @Test
+ public void testMapSubclass() throws IOException, SerializationException {
+ JSONSerializer typedMapSerializer = new JSONSerializer(SampleBean2MapSubclass.class);
+
+ SampleBean2Map map =
+ (SampleBean2Map)typedMapSerializer.readObject(new StringReader("{foo: {a:1, b:2, c:'3'}}"));
+
+ assertTrue(BeanAdapter.get(map, "foo") instanceof SampleBean2);
+ assertEquals(BeanAdapter.get(map, "foo.c"), "3");
+ }
+
+ /**
+ * Tests returning a Java bean value.
+ *
+ * @throws IOException
+ * @throws SerializationException
+ */
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testBean() throws IOException, SerializationException {
+ JSONSerializer mapSerializer = new JSONSerializer();
+ Map<String, Object> map =
+ (Map<String, Object>)mapSerializer.readObject(getClass().getResourceAsStream("map.json"));
+
+ JSONSerializer beanSerializer = new JSONSerializer(SampleBean1.class);
+ SampleBean1 typedMap =
+ (SampleBean1)beanSerializer.readObject(getClass().getResourceAsStream("map.json"));
+
+ assertEquals(typedMap.getA(), BeanAdapter.get(map, "a"));
+ assertEquals(typedMap.getB(), BeanAdapter.get(map, "b"));
+ assertEquals(typedMap.getC(), BeanAdapter.get(map, "c"));
+ assertEquals(typedMap.getD(), BeanAdapter.get(map, "d"));
+ assertEquals(typedMap.getE(), BeanAdapter.get(map, "e"));
+ assertEquals(typedMap.getI().getA(), BeanAdapter.get(map, "i.a"));
+
+ Object k0 = typedMap.getK().get(0);
+ assertTrue(k0 instanceof SampleBean2);
+ assertEquals(typedMap.getK().get(0).getA(), BeanAdapter.get(map, "k[0].a"));
+ }
+}
Added: pivot/branches/3.x/core/test/org/apache/pivot/json/test/JSONSerializerTest.java
URL: http://svn.apache.org/viewvc/pivot/branches/3.x/core/test/org/apache/pivot/json/test/JSONSerializerTest.java?rev=1057053&view=auto
==============================================================================
--- pivot/branches/3.x/core/test/org/apache/pivot/json/test/JSONSerializerTest.java (added)
+++ pivot/branches/3.x/core/test/org/apache/pivot/json/test/JSONSerializerTest.java Sun Jan 9 23:19:19 2011
@@ -0,0 +1,145 @@
+/*
+ * 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.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.pivot.beans.BeanAdapter;
+import org.apache.pivot.io.SerializationException;
+import org.apache.pivot.json.JSONSerializer;
+import org.apache.pivot.json.JSONSerializerListener;
+import org.junit.Test;
+
+public class JSONSerializerTest {
+ @Test
+ public void testCarriageReturns() {
+ List<?> emptyList;
+ try {
+ emptyList = JSONSerializer.parseList("[\n]");
+ } catch(SerializationException exception) {
+ throw new RuntimeException(exception);
+ }
+
+ assertEquals(0, emptyList.size());
+ }
+
+ @Test
+ public void testE() throws SerializationException {
+ assertEquals(5000000, JSONSerializer.parseDouble("5.0E6"), 0);
+ assertEquals(0.000005, JSONSerializer.parseDouble("5.0E-6"), 0);
+ }
+
+ @Test(expected=SerializationException.class)
+ public void testFloatNaN() throws SerializationException {
+ JSONSerializer.toString(Float.NaN);
+ }
+
+ @Test(expected=SerializationException.class)
+ public void testFloatNegativeInfinity() throws SerializationException {
+ JSONSerializer.toString(Float.NEGATIVE_INFINITY);
+ }
+
+ @Test(expected=SerializationException.class)
+ public void testFloatPositiveInfinity() throws SerializationException {
+ JSONSerializer.toString(Float.POSITIVE_INFINITY);
+ }
+
+ @Test(expected=SerializationException.class)
+ public void testDoubleNaN() throws SerializationException {
+ JSONSerializer.toString(Double.NaN);
+ }
+
+ @Test(expected=SerializationException.class)
+ public void testDoubleNegativeInfinity() throws SerializationException {
+ JSONSerializer.toString(Double.NEGATIVE_INFINITY);
+ }
+
+ @Test(expected=SerializationException.class)
+ public void testDoublePositiveInfinityN() throws SerializationException {
+ JSONSerializer.toString(Double.POSITIVE_INFINITY);
+ }
+
+ @Test
+ public void testEquals() throws IOException, SerializationException {
+ JSONSerializer jsonSerializer = new JSONSerializer();
+ JSONSerializerListener jsonSerializerListener = new JSONSerializerListener() {
+ @Override
+ public void beginMap(JSONSerializer jsonSerializer, Map<String, ?> value) {
+ System.out.println("Begin dictionary: " + value);
+ }
+
+ @Override
+ public void endMap(JSONSerializer jsonSerializer) {
+ System.out.println("End dictionary");
+ }
+
+ @Override
+ public void readKey(JSONSerializer jsonSerializer, String key) {
+ System.out.println("Read key: " + key);
+ }
+
+ @Override
+ public void beginList(JSONSerializer jsonSerializer, List<?> value) {
+ System.out.println("Begin sequence: " + value);
+ }
+
+ @Override
+ public void endList(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("map.json"));
+
+ jsonSerializer.getJSONSerializerListeners().remove(jsonSerializerListener);
+ Object o2 = jsonSerializer.readObject(getClass().getResourceAsStream("map.json"));
+
+ assertTrue(o1.equals(o2));
+
+ List<?> d = BeanAdapter.get(o1, "d");
+ d.remove(0);
+
+ assertFalse(o1.equals(o2));
+ }
+}