juneau-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jamesbog...@apache.org
Subject [04/51] [partial] incubator-juneau git commit: Initial Juno contents from IBM JazzHub repo
Date Mon, 01 Aug 2016 00:07:53 GMT
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeOutputStream.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeOutputStream.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeOutputStream.java
new file mode 100755
index 0000000..70807a8
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeOutputStream.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.utils;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Output stream that can send output to multiple output streams.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public class TeeOutputStream extends OutputStream {
+	private OutputStream[] outputStreams = new OutputStream[0];
+	private Map<String,OutputStream> outputStreamMap;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param outputStreams The list of output streams.
+	 */
+	public TeeOutputStream(OutputStream...outputStreams) {
+		this.outputStreams = outputStreams;
+	}
+
+	/**
+	 * Constructor.
+	 *
+	 * @param outputStreams The list of output streams.
+	 */
+	public TeeOutputStream(Collection<OutputStream> outputStreams) {
+		this.outputStreams = outputStreams.toArray(new OutputStream[outputStreams.size()]);
+	}
+
+	/**
+	 * Adds an output stream to this tee output stream.
+	 *
+	 * @param os The output stream to add to this tee output stream.
+	 * @param close If <jk>false</jk>, then calling {@link #close()} on this stream
+	 * 	will not filter to the specified output stream.
+	 * @return This object (for method chaining).
+	 */
+	public TeeOutputStream add(OutputStream os, boolean close) {
+		if (os == null)
+			return this;
+		if (! close)
+			os = new NoCloseOutputStream(os);
+		if (os == this)
+			throw new RuntimeException("Cannot add this output stream to itself.");
+		for (OutputStream os2 : outputStreams)
+			if (os2 == os)
+				throw new RuntimeException("Cannot add this output stream again.");
+		if (os instanceof TeeOutputStream) {
+			for (OutputStream os2 : ((TeeOutputStream)os).outputStreams)
+				add(os2, true);
+		} else {
+			outputStreams = ArrayUtils.append(outputStreams, os);
+		}
+		return this;
+	}
+
+	/**
+	 * Returns the output stream identified through the <code>id</code> parameter
+	 * passed in through the {@link #add(String, OutputStream, boolean)} method.
+	 *
+	 * @param id The ID associated with the output stream.
+	 * @return The output stream, or <jk>null</jk> if no identifier was specified when the output stream was added.
+	 */
+	public OutputStream getOutputStream(String id) {
+		if (outputStreamMap != null)
+			return outputStreamMap.get(id);
+		return null;
+	}
+
+	/**
+	 * Same as {@link #add(OutputStream, boolean)} but associates the stream with an identifier
+	 * so the stream can be retrieved through {@link #getOutputStream(String)}.
+	 *
+	 * @param id The ID to associate the output stream with.
+	 * @param os The output stream to add.
+	 * @param close Close the specified stream afterwards.
+	 * @return This object (for method chaining).
+	 */
+	public TeeOutputStream add(String id, OutputStream os, boolean close) {
+		if (id != null) {
+			if (outputStreamMap == null)
+				outputStreamMap = new TreeMap<String,OutputStream>();
+			outputStreamMap.put(id, os);
+		}
+		return add(os, close);
+	}
+
+	/**
+	 * Returns the number of inner streams in this tee stream.
+	 *
+	 * @return The number of streams in this tee stream.
+	 */
+	public int size() {
+		return outputStreams.length;
+	}
+
+	@Override /* OutputStream */
+	public void write(int b) throws IOException {
+		for (OutputStream os : outputStreams)
+			os.write(b);
+	}
+
+	@Override /* OutputStream */
+	public void write(byte b[], int off, int len) throws IOException {
+		for (OutputStream os : outputStreams)
+			os.write(b, off, len);
+	}
+
+	@Override /* OutputStream */
+	public void flush() throws IOException {
+		for (OutputStream os : outputStreams)
+			os.flush();
+	}
+
+	@Override /* OutputStream */
+	public void close() throws IOException {
+		for (OutputStream os : outputStreams)
+			os.close();
+	}
+
+	private static class NoCloseOutputStream extends OutputStream {
+		private OutputStream os;
+
+		private NoCloseOutputStream(OutputStream os) {
+			this.os = os;
+		}
+
+		@Override /* OutputStream */
+		public void write(int b) throws IOException {
+			os.write(b);
+		}
+
+		@Override /* OutputStream */
+		public void write(byte b[], int off, int len) throws IOException {
+			os.write(b, off, len);
+		}
+
+		@Override /* OutputStream */
+		public void flush() throws IOException {
+			os.flush();
+		}
+
+		@Override /* OutputStream */
+		public void close() throws IOException {
+			// Do nothing.
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter$1.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter$1.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter$1.class
new file mode 100755
index 0000000..caa1961
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter$1.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter$NoCloseWriter.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter$NoCloseWriter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter$NoCloseWriter.class
new file mode 100755
index 0000000..fc76e14
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter$NoCloseWriter.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter.class
new file mode 100755
index 0000000..b5702ac
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter.java
new file mode 100755
index 0000000..f01c3cd
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/TeeWriter.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.utils;
+
+import java.io.*;
+import java.util.*;
+
+
+/**
+ * Writer that can send output to multiple writers.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public class TeeWriter extends Writer {
+	private Writer[] writers = new Writer[0];
+	private Map<String,Writer> writerMap;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param writers The list of writers.
+	 */
+	public TeeWriter(Writer...writers) {
+		this.writers = writers;
+	}
+
+	/**
+	 * Constructor.
+	 *
+	 * @param writers The list of writers.
+	 */
+	public TeeWriter(Collection<Writer> writers) {
+		this.writers = writers.toArray(new Writer[writers.size()]);
+	}
+
+	/**
+	 * Adds a writer to this tee writer.
+	 *
+	 * @param w The writer to add to this tee writer.
+	 * @param close If <jk>false</jk>, then calling {@link #close()} on this tee writer
+	 * 	will not filter to the specified writer.
+	 * @return This object (for method chaining).
+	 */
+	public TeeWriter add(Writer w, boolean close) {
+		if (w == null)
+			return this;
+		if (! close)
+			w = new NoCloseWriter(w);
+		if (w == this)
+			throw new RuntimeException("Cannot add this writer to itself.");
+		for (Writer w2 : writers)
+			if (w2 == w)
+				throw new RuntimeException("Cannot add this writer again.");
+		if (w instanceof TeeWriter) {
+			for (Writer w2 : ((TeeWriter)w).writers)
+				add(w2, true);
+		} else {
+			writers = ArrayUtils.append(writers, w);
+		}
+		return this;
+	}
+
+	/**
+	 * Same as {@link #add(Writer, boolean)} but associates the writer with an identifier
+	 * so the writer can be retrieved through {@link #getWriter(String)}.
+	 *
+	 * @param id The ID to associate the writer with.
+	 * @param w The writer to add.
+	 * @param close Close the specified writer afterwards.
+	 * @return This object (for method chaining).
+	 */
+	public TeeWriter add(String id, Writer w, boolean close) {
+		if (id != null) {
+			if (writerMap == null)
+				writerMap = new TreeMap<String,Writer>();
+			writerMap.put(id, w);
+		}
+		return add(w, close);
+	}
+
+	/**
+	 * Returns the number of inner writers in this tee writer.
+	 *
+	 * @return The number of writers.
+	 */
+	public int size() {
+		return writers.length;
+	}
+
+	/**
+	 * Returns the writer identified through the <code>id</code> parameter
+	 * passed in through the {@link #add(String, Writer, boolean)} method.
+	 *
+	 * @param id The ID associated with the writer.
+	 * @return The writer, or <jk>null</jk> if no identifier was specified when the writer was added.
+	 */
+	public Writer getWriter(String id) {
+		if (writerMap != null)
+			return writerMap.get(id);
+		return null;
+	}
+
+	@Override /* Writer */
+	public void write(char[] cbuf, int off, int len) throws IOException {
+		for (Writer w : writers)
+			if (w != null)
+			w.write(cbuf, off, len);
+	}
+
+	@Override /* Writer */
+	public void flush() throws IOException {
+		for (Writer w : writers)
+			if (w != null)
+			w.flush();
+	}
+
+	@Override /* Writer */
+	public void close() throws IOException {
+		IOException e = null;
+		for (Writer w : writers) {
+			if (w != null) {
+				try {
+			w.close();
+				} catch (IOException e2) {
+					e = e2;
+				}
+			}
+		}
+		if (e != null)
+			throw e;
+	}
+
+	private static class NoCloseWriter extends Writer {
+		private Writer writer;
+
+		private NoCloseWriter(Writer writer) {
+			this.writer = writer;
+		}
+
+		@Override /* Writer */
+		public void write(char[] cbuf, int off, int len) throws IOException {
+			writer.write(cbuf, off, len);
+		}
+
+		@Override /* Writer */
+		public void flush() throws IOException {
+			writer.flush();
+		}
+
+		@Override /* Writer */
+		public void close() throws IOException {
+			// Do nothing.
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ThrowableUtils.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ThrowableUtils.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ThrowableUtils.class
new file mode 100755
index 0000000..55805dd
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ThrowableUtils.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ThrowableUtils.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ThrowableUtils.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ThrowableUtils.java
new file mode 100755
index 0000000..d2b25ae
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ThrowableUtils.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.utils;
+
+import java.text.*;
+
+/**
+ * Various utility methods for creating and working with throwables.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public class ThrowableUtils {
+
+	/**
+	 * Throws an {@link IllegalArgumentException} if the specified object is <jk>null</jk>.
+	 *
+	 * @param o The object to check.
+	 * @param msg The message of the IllegalArgumentException.
+	 * @param args {@link MessageFormat}-style arguments in the message.
+	 * @throws IllegalArgumentException
+	 */
+	public static void assertNotNull(Object o, String msg, Object...args) throws IllegalArgumentException {
+		if (o == null)
+			throw new IllegalArgumentException(MessageFormat.format(msg, args));
+	}
+
+	/**
+	 * Throws an {@link IllegalArgumentException} if the specified field is <jk>null</jk>.
+	 *
+	 * @param fieldValue The object to check.
+	 * @param fieldName The name of the field.
+	 * @throws IllegalArgumentException
+	 */
+	public static void assertFieldNotNull(Object fieldValue, String fieldName) throws IllegalArgumentException {
+		if (fieldValue == null)
+			throw new IllegalArgumentException("Field '" + fieldName + "' cannot be null.");
+	}
+
+	/**
+	 * Throws an {@link IllegalArgumentException} if the specified field is <code>&lt;=0</code>.
+	 *
+	 * @param fieldValue The object to check.
+	 * @param fieldName The name of the field.
+	 * @throws IllegalArgumentException
+	 */
+	public static void assertFieldPositive(int fieldValue, String fieldName) throws IllegalArgumentException {
+		if (fieldValue <= 0)
+			throw new IllegalArgumentException("Field '" + fieldName + "' must be a positive integer.");
+	}
+
+	/**
+	 * Shortcut for calling <code><jk>new</jk> IllegalArgumentException(MessageFormat.<jsm>format</jsm>(msg, args));</code>
+	 *
+	 * @param msg The message of the IllegalArgumentException.
+	 * @param args {@link MessageFormat}-style arguments in the message.
+	 * @throws IllegalArgumentException
+	 */
+	public static void illegalArg(String msg, Object...args) throws IllegalArgumentException {
+		throw new IllegalArgumentException(MessageFormat.format(msg, args));
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList$FileEntry.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList$FileEntry.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList$FileEntry.class
new file mode 100755
index 0000000..4b11004
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList$FileEntry.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList$ZipFileEntry.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList$ZipFileEntry.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList$ZipFileEntry.class
new file mode 100755
index 0000000..bad51b4
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList$ZipFileEntry.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList.class
new file mode 100755
index 0000000..77ab270
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList.java
new file mode 100755
index 0000000..1aebf3c
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/ZipFileList.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved.
+ *
+ * Note to U.S. Government Users Restricted Rights:
+ * Use, duplication or disclosure restricted by GSA ADP Schedule
+ * Contract with IBM Corp.
+ *******************************************************************************/
+package com.ibm.juno.core.utils;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+/**
+ * Utility class for representing the contents of a zip file as a list of entries
+ * whose contents don't resolve until serialize time.
+ * <p>
+ * Generally associated with <code>RestServlets</code> using the <code>responseHandlers</code>
+ * 	annotation so that REST methods can easily create ZIP file responses by simply returning instances
+ * 	of this class.
+ */
+@SuppressWarnings("serial")
+public class ZipFileList extends LinkedList<ZipFileList.ZipFileEntry> {
+
+	/**
+	 * The name of the zip file.
+	 */
+	public final String fileName;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param fileName The file name of the zip file to create.
+	 */
+	public ZipFileList(String fileName) {
+		this.fileName = fileName;
+	}
+
+	/**
+	 * Add an entry to this list.
+	 *
+	 * @param e The zip file entry.
+	 * @return This object (for method chaining).
+	 */
+	public ZipFileList append(ZipFileEntry e) {
+		add(e);
+		return this;
+	}
+
+	/**
+	 * Interface for ZipFileList entries.
+	 */
+	public static interface ZipFileEntry {
+		/**
+		 * Write this entry to the specified output stream.
+		 *
+		 * @param zos The output stream to write to.
+		 * @throws IOException
+		 */
+		void write(ZipOutputStream zos) throws IOException;
+	}
+
+	/**
+	 * ZipFileList entry for File entry types.
+	 */
+	public static class FileEntry implements ZipFileEntry {
+
+		/** The root file to base the entry paths on. */
+		protected File root;
+
+		/** The file being zipped. */
+		protected File file;
+
+		/**
+		 * Constructor.
+		 *
+		 * @param root The root file that represents the base path.
+		 * @param file The file to add to the zip file.
+		 */
+		public FileEntry(File root, File file) {
+			this.root = root;
+			this.file = file;
+		}
+
+		/**
+		 * Constructor.
+		 *
+		 * @param file The file to add to the zip file.
+		 */
+		public FileEntry(File file) {
+			this.file = file;
+			this.root = (file.isDirectory() ? file : file.getParentFile());
+		}
+
+		@Override /* ZipFileEntry */
+		public void write(ZipOutputStream zos) throws IOException {
+			addFile(zos, file);
+		}
+
+		/**
+		 * Subclasses can override this method to customize which files get added to a zip file.
+		 *
+		 * @param f The file being added to the zip file.
+		 * @return Always returns <jk>true</jk>.
+		 */
+		public boolean doAdd(File f) {
+			return true;
+		}
+
+		/**
+		 * Adds the specified file to the specified output stream.
+		 *
+		 * @param zos The output stream.
+		 * @param f The file to add.
+		 * @throws IOException
+		 */
+		protected void addFile(ZipOutputStream zos, File f) throws IOException {
+			if (doAdd(f)) {
+				if (f.isDirectory()) {
+					File[] fileList = f.listFiles();
+					if (fileList == null)
+						throw new IOException(f.toString());
+					for (File fc : fileList)
+						addFile(zos, fc);
+				} else if (f.canRead()) {
+					String path = f.getAbsolutePath().substring(root.getAbsolutePath().length() + 1).replace('\\', '/');
+					ZipEntry e = new ZipEntry(path);
+					e.setSize(f.length());
+					zos.putNextEntry(e);
+					IOPipe.create(new FileInputStream(f), zos).run();
+				}
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/package.html
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/package.html b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/package.html
new file mode 100755
index 0000000..97bdc68
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/utils/package.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<!--
+    Licensed Materials - Property of IBM
+    (c) Copyright IBM Corporation 2014. All Rights Reserved.
+   
+    Note to U.S. Government Users Restricted Rights:  
+    Use, duplication or disclosure restricted by GSA ADP Schedule 
+    Contract with IBM Corp. 
+ -->
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<style type="text/css">
+		/* For viewing in Page Designer */
+		@IMPORT url("../../../../../../javadoc.css");
+
+		/* For viewing in REST interface */
+		@IMPORT url("../htdocs/javadoc.css");
+		body { 
+			margin: 20px; 
+		}	
+	</style>
+	<script>
+		/* Replace all @code and @link tags. */	
+		window.onload = function() {
+			document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>');
+			document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>');
+		}
+	</script>
+</head>
+<body>
+<p>Utility classes</p>
+
+<script>
+	function toggle(x) {
+		var div = x.nextSibling;
+		while (div != null && div.nodeType != 1)
+			div = div.nextSibling;
+		if (div != null) {
+			var d = div.style.display;
+			if (d == 'block' || d == '') {
+				div.style.display = 'none';
+				x.className += " closed";
+			} else {
+				div.style.display = 'block';
+				x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' );
+			}
+		}
+	}
+</script>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/Namespace.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/Namespace.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/Namespace.class
new file mode 100755
index 0000000..281438e
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/Namespace.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/Namespace.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/Namespace.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/Namespace.java
new file mode 100755
index 0000000..7cb3b54
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/Namespace.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.xml;
+
+/**
+ * Represents a simple namespace mapping between a simple name and URI.
+ * <p>
+ * 	In general, the simple name will be used as the XML prefix mapping unless
+ * 	there are conflicts or prefix remappings in the serializer.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public final class Namespace implements Comparable<Namespace> {
+	final String name, uri;
+	private final int hashCode;
+
+	/**
+	 * Constructor.
+	 * <p>
+	 * 	Use this constructor when the long name and short name are the same value.
+	 *
+	 * @param name The long and short name of this schema.
+	 * @param uri The URI of this schema.
+	 */
+	protected Namespace(String name, String uri) {
+		this.name = name;
+		this.uri = uri;
+		this.hashCode = (name == null ? 0 : name.hashCode()) + uri.hashCode();
+	}
+
+	/**
+	 * Returns the namespace name.
+	 *
+	 * @return The namespace name.
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Returns the namespace URI.
+	 *
+	 * @return The namespace URI.
+	 */
+	public String getUri() {
+		return uri;
+	}
+
+	@Override /* Comparable */
+	public int compareTo(Namespace o) {
+		int i = name.compareTo(o.name);
+		if (i == 0)
+			i = uri.compareTo(o.uri);
+		return i;
+	}
+
+	/**
+	 * For performance reasons, equality is always based on identity, since
+	 * the {@link NamespaceFactory} class ensures no duplicate name+uri pairs.
+	 */
+	@Override /* Object */
+	public boolean equals(Object o) {
+		return this == o;
+	}
+
+	@Override /* Object */
+	public int hashCode() {
+		return hashCode;
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return "{name='"+name+"',uri:'"+uri+"'}";
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/NamespaceFactory.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/NamespaceFactory.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/NamespaceFactory.class
new file mode 100755
index 0000000..27b3171
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/NamespaceFactory.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/NamespaceFactory.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/NamespaceFactory.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/NamespaceFactory.java
new file mode 100755
index 0000000..20faa03
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/NamespaceFactory.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.xml;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.parser.*;
+import com.ibm.juno.core.utils.*;
+
+/**
+ * Factory class for getting unique instances of {@link Namespace} objects.
+ * <p>
+ * 	For performance reasons, {@link Namespace} objects are stored in {@link IdentityList IdentityLists}.
+ * 	For this to work property, namespaces with the same name and URI must only be represented by a single
+ * 	{@link Namespace} instance.
+ * 	This factory class ensures this identity uniqueness.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public final class NamespaceFactory {
+
+	private static ConcurrentHashMap<String,Namespace> cache = new ConcurrentHashMap<String,Namespace>();
+
+	/**
+	 * Get the {@link Namespace} with the specified name and URI, and create a new one
+	 * 	if this is the first time it's been encountered.
+	 *
+	 * @param name The namespace name.  See {@link Namespace#getName()}.
+	 * @param uri The namespace URI.  See {@link Namespace#getUri()}.
+	 * @return The namespace object.
+	 */
+	public static Namespace get(String name, String uri) {
+		String key = name + "+" + uri;
+		Namespace n = cache.get(key);
+		if (n == null) {
+			n = new Namespace(name, uri);
+			Namespace n2 = cache.putIfAbsent(key, n);
+			return (n2 == null ? n : n2);
+		}
+		return n;
+	}
+
+	/**
+	 * Converts the specified object into a {@link Namespace} object.
+	 * <p>
+	 * 	Can be any of following types:
+	 * <ul>
+	 * 	<li>A {@link Namespace} object
+	 * 	<li>A JSON string containing a single key/value pair indicating the name/URI mapping.
+	 * 	<li>A <code>Map</code> containing a single key/value pair indicating the name/URI mapping.
+	 * </ul>
+	 *
+	 * @param o The input.
+	 * @return The namespace object, or <jk>null</jk> if the input was <jk>null</jk> or an empty JSON object.
+	 */
+	@SuppressWarnings("rawtypes")
+	public static Namespace parseNamespace(Object o) {
+		if (o == null)
+			return null;
+		if (o instanceof Namespace)
+			return (Namespace)o;
+		try {
+			Map<?,?> m = (o instanceof Map ? (Map)o : new ObjectMap(o.toString()));
+			if (m.size() == 0)
+				return null;
+			if (m.size() > 1)
+				throw new RuntimeException("Too many namespaces specified.  Only one allowed. '"+o+"'");
+			Map.Entry<?,?> e = m.entrySet().iterator().next();
+			return get(e.getKey().toString(), e.getValue().toString());
+		} catch (ParseException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	/**
+	 * Converts the specified object into an array of {@link Namespace} object.
+	 * <p>
+	 * 	Can be any of following types:
+	 * <ul>
+	 * 	<li>A {@link Namespace} array
+	 * 	<li>A JSON string with key/value pairs indicating name/URI pairs.
+	 * 	<li>A <code>Map</code> with key/value pairs indicating name/URI pairs.
+	 * 	<li>A <code>Collection</code> containing any of object that can be passed to {@link #parseNamespace(Object)}.
+	 * </ul>
+	 *
+	 * @param o The input.
+	 * @return The namespace objects, or <jk>null</jk> if the input was <jk>null</jk> or an empty JSON object.
+	 */
+	@SuppressWarnings("rawtypes")
+	public static Namespace[] parseNamespaces(Object o) {
+		try {
+			if (o instanceof Namespace[])
+				return (Namespace[])o;
+
+			if (o instanceof CharSequence)
+				o = new ObjectMap(o.toString());
+
+			Namespace[] n;
+			int i = 0;
+			if (o instanceof Collection) {
+				Collection c = (Collection)o;
+				n = new Namespace[c.size()];
+				for (Object o2 : c)
+					n[i++] = parseNamespace(o2);
+			} else if (o instanceof Map) {
+				Map<?,?> m = (Map<?,?>)o;
+				n = new Namespace[m.size()];
+				for (Map.Entry e : m.entrySet())
+					n[i++] = get(e.getKey().toString(), e.getValue().toString());
+			} else {
+				throw new RuntimeException("Invalid type passed to NamespaceFactory.listFromObject: '"+o+"'");
+			}
+			return n;
+		} catch (ParseException e) {
+			throw new RuntimeException(e);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanMeta.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanMeta.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanMeta.class
new file mode 100755
index 0000000..507530b
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanMeta.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanMeta.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanMeta.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanMeta.java
new file mode 100755
index 0000000..3ffbe5c
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanMeta.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.xml;
+
+import java.util.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.xml.annotation.*;
+
+/**
+ * Metadata on beans specific to the XML serializers and parsers pulled from the {@link Xml @Xml} annotation on the class.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ * @param <T> The bean class type.
+ */
+public class XmlBeanMeta<T> {
+
+	// XML related fields
+	private final Map<String,BeanPropertyMeta<T>> xmlAttrs;                        // Map of bean properties that are represented as XML attributes.
+	private final BeanPropertyMeta<T> xmlContent;                                  // Bean property that is represented as XML content within the bean element.
+	private final XmlContentHandler<T> xmlContentHandler;                          // Class used to convert bean to XML content.
+	private final Map<String,BeanPropertyMeta<T>> childElementProperties;          // Properties defined with @Xml.childName annotation.
+	private final BeanMeta<T> beanMeta;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param beanMeta The metadata on the bean that this metadata applies to.
+	 * @param pNames Only look at these property names.  If <jk>null</jk>, apply to all bean properties.
+	 */
+	public XmlBeanMeta(BeanMeta<T> beanMeta, String[] pNames) {
+		this.beanMeta = beanMeta;
+		Class<T> c = beanMeta.getClassMeta().getInnerClass();
+
+		Map<String,BeanPropertyMeta<T>> tXmlAttrs = new LinkedHashMap<String,BeanPropertyMeta<T>>();
+		BeanPropertyMeta<T> tXmlContent = null;
+		XmlContentHandler<T> tXmlContentHandler = null;
+		Map<String,BeanPropertyMeta<T>> tChildElementProperties = new LinkedHashMap<String,BeanPropertyMeta<T>>();
+
+		for (BeanPropertyMeta<T> p : beanMeta.getPropertyMetas(pNames)) {
+			XmlFormat xf = p.getXmlMeta().getXmlFormat();
+			if (xf == XmlFormat.ATTR)
+				tXmlAttrs.put(p.getName(), p);
+			else if (xf == XmlFormat.CONTENT) {
+				if (tXmlContent != null)
+					throw new BeanRuntimeException(c, "Multiple instances of CONTENT properties defined on class.  Only one property can be designated as such.");
+				tXmlContent = p;
+				tXmlContentHandler = p.getXmlMeta().getXmlContentHandler();
+			}
+			// Look for any properties that are collections with @Xml.childName specified.
+			String n = p.getXmlMeta().getChildName();
+			if (n != null) {
+				if (tChildElementProperties.containsKey(n))
+					throw new BeanRuntimeException(c, "Multiple properties found with the name ''{0}''.", n);
+				tChildElementProperties.put(n, p);
+			}
+		}
+
+		xmlAttrs = Collections.unmodifiableMap(tXmlAttrs);
+		xmlContent = tXmlContent;
+		xmlContentHandler = tXmlContentHandler;
+		childElementProperties = (tChildElementProperties.isEmpty() ? null : Collections.unmodifiableMap(tChildElementProperties));
+	}
+
+	/**
+	 * Returns the list of properties annotated with an {@link Xml#format()} of {@link XmlFormat#ATTR}.
+	 * In other words, the list of properties that should be rendered as XML attributes instead of child elements.
+	 *
+	 * @return Metadata on the XML attribute properties of the bean.
+	 */
+	protected Map<String,BeanPropertyMeta<T>> getXmlAttrProperties() {
+		return xmlAttrs;
+	}
+
+	/**
+	 * Returns the bean property annotated with an {@link Xml#format()} value of {@link XmlFormat#CONTENT}
+	 *
+	 * @return The bean property, or <jk>null</jk> if annotation is not specified.
+	 */
+	protected BeanPropertyMeta<T> getXmlContentProperty() {
+		return xmlContent;
+	}
+
+	/**
+	 * Return the XML content handler for this bean.
+	 *
+	 * @return The XML content handler for this bean, or <jk>null</jk> if no content handler is defined.
+	 */
+	protected XmlContentHandler<T> getXmlContentHandler() {
+		return xmlContentHandler;
+	}
+
+	/**
+	 * Returns the child element properties for this bean.
+	 * See {@link Xml#childName()}
+	 *
+	 * @return The child element properties for this bean, or <jk>null</jk> if no child element properties are defined.
+	 */
+	protected Map<String,BeanPropertyMeta<T>> getChildElementProperties() {
+		return childElementProperties;
+	}
+
+	/**
+	 * Returns bean property meta with the specified name.
+	 * This is identical to calling {@link BeanMeta#getPropertyMeta(String)} except it first retrieves
+	 * 	the bean property meta based on the child name (e.g. a property whose name is "people", but whose child name is "person").
+	 *
+	 * @param fieldName The bean property name.
+	 * @return The property metadata.
+	 */
+	protected BeanPropertyMeta<T> getPropertyMeta(String fieldName) {
+		if (childElementProperties != null) {
+			BeanPropertyMeta<T> bpm = childElementProperties.get(fieldName);
+			if (bpm != null)
+				return bpm;
+		}
+		return beanMeta.getPropertyMeta(fieldName);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanPropertyMeta.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanPropertyMeta.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanPropertyMeta.class
new file mode 100755
index 0000000..f3e5a97
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanPropertyMeta.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanPropertyMeta.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanPropertyMeta.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanPropertyMeta.java
new file mode 100755
index 0000000..210ae0b
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlBeanPropertyMeta.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.xml;
+
+import java.util.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.xml.annotation.*;
+
+/**
+ * Metadata on bean properties specific to the XML serializers and parsers pulled from the {@link Xml @Xml} annotation on the bean property.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ * @param <T> The bean class.
+ */
+public class XmlBeanPropertyMeta<T> {
+
+	private Namespace namespace = null;
+	private XmlFormat xmlFormat = XmlFormat.NORMAL;
+	private XmlContentHandler<T> xmlContentHandler = null;
+	private String childName;
+	private final BeanPropertyMeta<T> beanPropertyMeta;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param beanPropertyMeta The metadata of the bean property of this additional metadata.
+	 */
+	public XmlBeanPropertyMeta(BeanPropertyMeta<T> beanPropertyMeta) {
+		this.beanPropertyMeta = beanPropertyMeta;
+
+		if (beanPropertyMeta.getField() != null)
+			findXmlInfo(beanPropertyMeta.getField().getAnnotation(Xml.class));
+		if (beanPropertyMeta.getGetter() != null)
+			findXmlInfo(beanPropertyMeta.getGetter().getAnnotation(Xml.class));
+		if (beanPropertyMeta.getSetter() != null)
+			findXmlInfo(beanPropertyMeta.getSetter().getAnnotation(Xml.class));
+
+		if (namespace == null)
+			namespace = beanPropertyMeta.getBeanMeta().getClassMeta().getXmlMeta().getNamespace();
+
+		if (beanPropertyMeta.isBeanUri() && xmlFormat != XmlFormat.ELEMENT)
+			xmlFormat = XmlFormat.ATTR;
+	}
+
+	/**
+	 * Returns the XML namespace associated with this bean property.
+	 * <p>
+	 * 	Namespace is determined in the following order:
+	 * <ol>
+	 * 	<li>{@link Xml#prefix()} annotation defined on bean property field.
+	 * 	<li>{@link Xml#prefix()} annotation defined on bean getter.
+	 * 	<li>{@link Xml#prefix()} annotation defined on bean setter.
+	 * 	<li>{@link Xml#prefix()} annotation defined on bean.
+	 * 	<li>{@link Xml#prefix()} annotation defined on bean package.
+	 * 	<li>{@link Xml#prefix()} annotation defined on bean superclasses.
+	 * 	<li>{@link Xml#prefix()} annotation defined on bean superclass packages.
+	 * 	<li>{@link Xml#prefix()} annotation defined on bean interfaces.
+	 * 	<li>{@link Xml#prefix()} annotation defined on bean interface packages.
+	 * </ol>
+	 *
+	 * @return The namespace associated with this bean property, or <jk>null</jk> if no namespace is
+	 * 	associated with it.
+	 */
+	public Namespace getNamespace() {
+		return namespace;
+	}
+
+	/**
+	 * Returns the XML format of this property from the {@link Xml#format} annotation on this bean property.
+	 *
+	 * @return The XML format, or {@link XmlFormat#NORMAL} if annotation not specified.
+	 */
+	protected XmlFormat getXmlFormat() {
+		return xmlFormat;
+	}
+
+	/**
+	 * Returns the XML content handler of this property from the {@link Xml#contentHandler} annotation on this bean property.
+	 *
+	 * @return The XML content handler, or <jk>null</jk> if annotation not specified.
+	 */
+	protected XmlContentHandler<T> getXmlContentHandler() {
+		return xmlContentHandler;
+	}
+
+	/**
+	 * Returns the child element of this property from the {@link Xml#childName} annotation on this bean property.
+	 *
+	 * @return The child element, or <jk>null</jk> if annotation not specified.
+	 */
+	protected String getChildName() {
+		return childName;
+	}
+
+	/**
+	 * Returns the bean property metadata that this metadata belongs to.
+	 *
+	 * @return The bean property metadata.  Never <jk>null</jk>.
+	 */
+	protected BeanPropertyMeta<T> getBeanPropertyMeta() {
+		return beanPropertyMeta;
+	}
+
+	@SuppressWarnings("unchecked")
+	private void findXmlInfo(Xml xml) {
+		if (xml == null)
+			return;
+		ClassMeta<?> cmProperty = beanPropertyMeta.getClassMeta();
+		ClassMeta<?> cmBean = beanPropertyMeta.getBeanMeta().getClassMeta();
+		String name = beanPropertyMeta.getName();
+		if (! xml.name().isEmpty())
+			throw new BeanRuntimeException(cmBean.getInnerClass(), "Annotation error on property ''{0}''.  Found @Xml.name annotation can only be specified on types.", name);
+
+		List<Xml> xmls = beanPropertyMeta.findAnnotations(Xml.class);
+		List<XmlSchema> schemas = beanPropertyMeta.findAnnotations(XmlSchema.class);
+		namespace = XmlUtils.findNamespace(xmls, schemas);
+
+		if (xmlFormat == XmlFormat.NORMAL)
+			xmlFormat = xml.format();
+
+		boolean isCollection = cmProperty.isCollection() || cmProperty.isArray();
+
+		String cen = xml.childName();
+		if ((! cen.isEmpty()) && (! isCollection))
+			throw new BeanRuntimeException(cmProperty.getInnerClass(), "Annotation error on property ''{0}''.  @Xml.childName can only be specified on collections and arrays.", name);
+
+		if (xmlFormat == XmlFormat.COLLAPSED) {
+			if (isCollection) {
+				if (cen.isEmpty())
+					cen = cmProperty.getXmlMeta().getChildName();
+				if (cen == null || cen.isEmpty())
+					cen = cmProperty.getElementType().getXmlMeta().getElementName();
+				if (cen == null || cen.isEmpty())
+					cen = name;
+			} else {
+				throw new BeanRuntimeException(cmBean.getInnerClass(), "Annotation error on property ''{0}''.  @Xml.format=COLLAPSED can only be specified on collections and arrays.", name);
+			}
+			if (cen.isEmpty() && isCollection)
+				cen = cmProperty.getXmlMeta().getElementName();
+		}
+
+		try {
+			if (xmlFormat == XmlFormat.CONTENT && xml.contentHandler() != XmlContentHandler.NULL.class)
+				xmlContentHandler = (XmlContentHandler<T>) xml.contentHandler().newInstance();
+		} catch (Exception e) {
+			throw new BeanRuntimeException(cmBean.getInnerClass(), "Could not instantiate content handler ''{0}''", xml.contentHandler().getName()).initCause(e);
+		}
+
+		if (! cen.isEmpty())
+			childName = cen;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlClassMeta.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlClassMeta.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlClassMeta.class
new file mode 100755
index 0000000..f5ffbb0
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlClassMeta.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlClassMeta.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlClassMeta.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlClassMeta.java
new file mode 100755
index 0000000..4252bab
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlClassMeta.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.xml;
+
+import java.util.*;
+
+import com.ibm.juno.core.utils.*;
+import com.ibm.juno.core.xml.annotation.*;
+
+
+/**
+ * Metadata on classes specific to the XML serializers and parsers pulled from the {@link Xml @Xml} annotation on the class.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public class XmlClassMeta {
+
+	private final Namespace namespace;
+	private final Xml xml;
+	private final XmlFormat format;
+	private final String elementName;
+	private final String childName;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param c The class that this annotation is defined on.
+	 */
+	public XmlClassMeta(Class<?> c) {
+		this.namespace = findNamespace(c);
+		this.xml =  ReflectionUtils.getAnnotation(Xml.class, c);
+		if (xml != null) {
+			this.format = xml.format();
+			this.elementName = StringUtils.nullIfEmpty(xml.name());
+			this.childName = StringUtils.nullIfEmpty(xml.childName());
+
+		} else {
+			this.format = XmlFormat.NORMAL;
+			this.elementName = null;
+			this.childName = null;
+		}
+	}
+
+	/**
+	 * Returns the {@link Xml} annotation defined on the class.
+	 *
+	 * @return The value of the {@link Xml} annotation defined on the class, or <jk>null</jk> if annotation is not specified.
+	 */
+	protected Xml getAnnotation() {
+		return xml;
+	}
+
+	/**
+	 * Returns the {@link Xml#format()} annotation defined on the class.
+	 *
+	 * @return The value of the {@link Xml#format()} annotation, or {@link XmlFormat#NORMAL} if not specified.
+	 */
+	protected XmlFormat getFormat() {
+		return format;
+	}
+
+	/**
+	 * Returns the {@link Xml#name()} annotation defined on the class.
+	 *
+	 * @return The value of the {@link Xml#name()} annotation, or <jk>null</jk> if not specified.
+	 */
+	protected String getElementName() {
+		return elementName;
+	}
+
+	/**
+	 * Returns the {@link Xml#childName()} annotation defined on the class.
+	 *
+	 * @return The value of the {@link Xml#childName()} annotation, or <jk>null</jk> if not specified.
+	 */
+	protected String getChildName() {
+		return childName;
+	}
+
+	/**
+	 * Returns the XML namespace associated with this class.
+	 * <p>
+	 * 	Namespace is determined in the following order:
+	 * <ol>
+	 * 	<li>{@link Xml#prefix()} annotation defined on class.
+	 * 	<li>{@link Xml#prefix()} annotation defined on package.
+	 * 	<li>{@link Xml#prefix()} annotation defined on superclasses.
+	 * 	<li>{@link Xml#prefix()} annotation defined on superclass packages.
+	 * 	<li>{@link Xml#prefix()} annotation defined on interfaces.
+	 * 	<li>{@link Xml#prefix()} annotation defined on interface packages.
+	 * </ol>
+	 *
+	 * @return The namespace associated with this class, or <jk>null</jk> if no namespace is
+	 * 	associated with it.
+	 */
+	protected Namespace getNamespace() {
+		return namespace;
+	}
+
+	private Namespace findNamespace(Class<?> c) {
+		if (c == null)
+			return null;
+
+		List<Xml> xmls = ReflectionUtils.findAnnotations(Xml.class, c);
+		List<XmlSchema> schemas = ReflectionUtils.findAnnotations(XmlSchema.class, c);
+		return XmlUtils.findNamespace(xmls, schemas);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler$NULL.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler$NULL.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler$NULL.class
new file mode 100755
index 0000000..cd9f86e
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler$NULL.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler.class
new file mode 100755
index 0000000..b0f1b7a
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler.java
new file mode 100755
index 0000000..3ebfef3
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlContentHandler.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2014. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.xml;
+
+import javax.xml.stream.*;
+
+import com.ibm.juno.core.dto.atom.*;
+import com.ibm.juno.core.xml.annotation.*;
+
+/**
+ * Customization class that allows a bean (or parts of a bean) to be serialized as XML text or mixed content.
+ * <p>
+ * 	For example, the ATOM specification allows text elements (e.g. title, subtitle...)
+ * 		to be either plain text or XML depending on the value of a <xa>type</xa> attribute.
+ * 	The behavior of text escaping thus depends on that attribute.
+ *
+ * <p class='bcode'>
+ * 	<xt>&lt;feed</xt> <xa>xmlns</xa>=<xs>"http://www.w3.org/2005/Atom"</xs><xt>&gt;</xt>
+ * 		<xt>&lt;title</xt> <xa>type</xa>=<xs>"html"</xs><xt>&gt;</xt>
+ * 			&amp;lt;p&amp;gt;&amp;lt;i&amp;gt;This is the title&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;
+ * 		<xt>&lt;/title&gt;</xt>
+ * 		<xt>&lt;title</xt> <xa>type</xa>=<xs>"xhtml"</xs><xt>&gt;</xt>
+ * 			<xt>&lt;div</xt> <xa>xmlns</xa>=<xs>"http://www.w3.org/1999/xhtml"</xs><xt>&gt;</xt>
+ * 				<xt>&lt;p&gt;&lt;i&gt;</xt>This is the subtitle<xt>&lt;/i&gt;&lt;/p&gt;</xt>
+ * 			<xt>&lt;/div&gt;</xt>
+ * 		<xt>&lt;/title&gt;</xt>
+ * 	<xt>&lt;/feed&gt;</xt>
+ * </p>
+ *
+ * <p>
+ * 	The ATOM {@link Text} class (the implementation for both the <xt>&lt;title&gt;</xt> and <xt>&lt;subtitle&gt;</xt>
+ * 		tags shown above) then associates a content handler through the {@link Xml#contentHandler()} annotation
+ * 		on the bean property containing the text, like so...
+ *
+ * <p class='bcode'>
+ * 	<ja>@Xml</ja>(format=<jsf>ATTR</jsf>)
+ * 	<jk>public</jk> String getType() {
+ * 		<jk>return</jk> <jf>type</jf>;
+ * 	}
+ *
+ * 	<ja>@Xml</ja>(format=<jsf>CONTENT</jsf>, contentHandler=TextContentHandler.<jk>class</jk>)
+ * 	<jk>public</jk> String getText() {
+ * 		<jk>return</jk> <jf>text</jf>;
+ * 	}
+ *
+ * 	<jk>public void</jk> setText(String text) {
+ * 		<jk>this</jk>.<jf>text</jf> = text;
+ * 	}
+ * </p>
+ *
+ * <p>
+ * 	The content handler that transforms the output is shown below...
+ *
+ * <p class='bcode'>
+ * 	<jk>public static class</jk> TextContentHandler <jk>implements</jk> XmlContentHandler&lt;Text&gt; {
+ *
+ * 		<ja>@Override</ja>
+ * 		<jk>public void</jk> parse(XMLStreamReader r, Text text) <jk>throws</jk> Exception {
+ * 			String type = text.<jf>type</jf>;
+ * 			<jk>if</jk> (type != <jk>null</jk> && type.equals(<js>"xhtml"</js>))
+ * 				text.<jf>text</jf> = <jsm>decode</jsm>(readXmlContents(r).trim());
+ * 			<jk>else</jk>
+ * 				text.<jf>text</jf> = <jsm>decode</jsm>(r.getElementText().trim());
+ * 		}
+ *
+ * 		<ja>@Override</ja>
+ * 		<jk>public void</jk> serialize(XmlSerializerWriter w, Text text) <jk>throws</jk> Exception {
+ * 			String type = text.<jf>type</jf>;
+ * 			String content = text.<jf>text</jf>;
+ * 			<jk>if</jk> (type != <jk>null</jk> && type.equals(<js>"xhtml"</js>))
+ * 				w.encodeTextInvalidChars(content);
+ * 			<jk>else</jk>
+ * 				w.encodeText(content);
+ * 		}
+ * 	}
+ * </p>
+ *
+ * <h6 class='topic'>Notes</h6>
+ * <ul>
+ * 	<li>The {@link Xml#contentHandler()} annotation can only be specified on a bean class, or a bean property
+ * 		of format {@link XmlFormat#CONTENT}.
+ * </ul>
+ *
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ * @param <T> The class type of the bean
+ */
+public interface XmlContentHandler<T> {
+
+	/**
+	 * Represents <jk>null</jk> on the {@link Xml#contentHandler()} annotation.
+	 */
+	public static interface NULL extends XmlContentHandler<Object> {}
+
+	/**
+	 * Reads XML element content the specified reader and sets the appropriate value on the specified bean.
+	 * <p>
+	 * 	When this method is called, the attributes have already been parsed and set on the bean.
+	 * 	Therefore, if the content handling is different based on some XML attribute (e.g.
+	 * 		<code><xa>type</xa>=<xs>"text/xml"</xs></code> vs <code><xa>type</xa>=<xs>"text/plain"</xs></code>)
+	 * 		then that attribute value can be obtained via the set bean property.
+	 *
+	 * @param r The XML stream reader.
+	 * 	When called, the reader is positioned on the element containing the text to read.
+	 * 	For example, calling <code>r.getElementText()</code> can be called immediately
+	 * 	to return the element text if the element contains only characters and whitespace.
+	 * 	However typically, the stream is going to contain XML elements that need to
+	 * 	be handled special (otherwise you wouldn't need to use an <code>XmlContentHandler</code>
+	 * 	to begin with).
+	 * @param bean The bean where the parsed contents are going to be placed.
+	 * 	Subclasses determine how the content maps to values in the bean.
+	 * 	However, typically the contents map to a single property on the bean.
+	 * @throws Exception If any problem occurs.  Causes parse to fail.
+	 */
+	public void parse(XMLStreamReader r, T bean) throws Exception;
+
+	/**
+	 * Writes XML element content from values in the specified bean.
+	 *
+	 * @param w The XML output writer.
+	 * 	When called, the XML element/attributes and
+	 * 		whitespace/indentation (if enabled) have already been written to the stream.
+	 * 	Subclasses must simply write the contents of the element.
+	 * @param bean The bean whose values will be converted to XML content.
+	 * @throws Exception If any problems occur.  Causes serialize to fail.
+	 */
+	public void serialize(XmlSerializerWriter w, T bean) throws Exception;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer$Simple.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer$Simple.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer$Simple.class
new file mode 100755
index 0000000..876d0e7
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer$Simple.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer.class
new file mode 100755
index 0000000..7eef3a8
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer.java
new file mode 100755
index 0000000..a2d7da0
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlDocSerializer.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2011, 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.xml;
+
+import static com.ibm.juno.core.xml.XmlSerializerProperties.*;
+
+import java.io.*;
+
+import com.ibm.juno.core.annotation.*;
+import com.ibm.juno.core.serializer.*;
+
+/**
+ * Serializes POJOs to HTTP responses as XML.
+ *
+ *
+ * <h6 class='topic'>Media types</h6>
+ * <p>
+ * 	Handles <code>Accept</code> types: <code>text/xml</code>
+ * <p>
+ * 	Produces <code>Content-Type</code> types: <code>text/xml</code>
+ *
+ *
+ * <h6 class='topic'>Description</h6>
+ * <p>
+ * 	Same as {@link XmlSerializer}, except prepends <code><xt>&lt;?xml</xt> <xa>version</xa>=<xs>'1.0'</xs> <xa>encoding</xa>=<xs>'UTF-8'</xs><xt>?&gt;</xt></code> to the response
+ * 	to make it a valid XML document.
+ *
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public class XmlDocSerializer extends XmlSerializer {
+
+	/** Default serializer without namespaces. */
+	@Produces(value="text/xml+simple",contentType="text/xml")
+	public static class Simple extends XmlDocSerializer {
+		/** Constructor */
+		public Simple() {
+			setProperty(XML_enableNamespaces, false);
+		}
+	}
+
+	//--------------------------------------------------------------------------------
+	// Overridden methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* Serializer */
+	protected void doSerialize(Object o, Writer out, SerializerContext ctx) throws IOException, SerializeException {
+		XmlSerializerContext xctx = (XmlSerializerContext)ctx;
+		XmlSerializerWriter w = xctx.getWriter(out);
+		w.append("<?xml")
+			.attr("version", "1.0")
+			.attr("encoding", "UTF-8")
+			.appendln("?>");
+		super.doSerialize(o, w, ctx);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParser.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParser.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParser.class
new file mode 100755
index 0000000..8ef1946
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParser.class differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParser.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParser.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParser.java
new file mode 100755
index 0000000..9503b03
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParser.java
@@ -0,0 +1,558 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2014, 2015. All Rights Reserved.
+ *
+ *  The source code for this program is not published or otherwise
+ *  divested of its trade secrets, irrespective of what has been
+ *  deposited with the U.S. Copyright Office.
+ *******************************************************************************/
+package com.ibm.juno.core.xml;
+
+import static com.ibm.juno.core.utils.StringUtils.*;
+import static com.ibm.juno.core.xml.XmlUtils.*;
+import static com.ibm.juno.core.xml.annotation.XmlFormat.*;
+import static javax.xml.stream.XMLStreamConstants.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import javax.xml.stream.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.annotation.*;
+import com.ibm.juno.core.filter.*;
+import com.ibm.juno.core.parser.*;
+import com.ibm.juno.core.xml.annotation.*;
+
+/**
+ * Parses text generated by the {@link XmlSerializer} class back into a POJO model.
+ *
+ *
+ * <h6 class='topic'>Media types</h6>
+ * <p>
+ * 	Handles <code>Content-Type</code> types: <code>text/xml</code>
+ *
+ *
+ * <h6 class='topic'>Description</h6>
+ * <p>
+ * 	See the {@link XmlSerializer} class for a description of Juno-generated XML.
+ *
+ *
+ * <h6 class='topic'>Configurable properties</h6>
+ * <p>
+ * 	This class has the following properties associated with it:
+ * <ul>
+ * 	<li>{@link XmlParserProperties}
+ * 	<li>{@link ParserProperties}
+ * 	<li>{@link BeanContextProperties}
+ * </ul>
+ *
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+@Consumes({"text/xml","application/xml"})
+public class XmlParser extends ReaderParser {
+
+	/** Default parser, all default settings.*/
+	public static final XmlParser DEFAULT = new XmlParser().lock();
+
+	private static final int UNKNOWN=0, OBJECT=1, ARRAY=2, STRING=3, NUMBER=4, BOOLEAN=5, NULL=6;
+
+
+	/** XML specific properties currently defined on this class */
+	protected transient XmlParserProperties xpp = new XmlParserProperties();
+
+
+	private <T> T parseAnything(ClassMeta<T> nt, XmlParserContext ctx, String currAttr, XMLStreamReader r, BeanPropertyMeta p, Object outer, boolean isRoot) throws ParseException, IOException {
+
+		try {
+			BeanContext bc = ctx.getBeanContext();
+			if (nt == null)
+				nt = (ClassMeta<T>)object();
+			PojoFilter<T,Object> filter = (PojoFilter<T,Object>)nt.getPojoFilter();
+			ClassMeta<?> ft = nt.getFilteredClassMeta();
+
+			String wrapperAttr = (isRoot && ctx.isPreserveRootElement()) ? r.getName().getLocalPart() : null;
+			String typeAttr = r.getAttributeValue(null, "type");
+			int jsonType = getJsonType(typeAttr);
+			String b = r.getAttributeValue(ctx.getXsiNs(), "nil");
+			if (b == null)
+				b = r.getAttributeValue(null, "nil");
+			boolean isNull = b != null && b.equals("true");
+			if (jsonType == 0) {
+				try {
+					String elementName = decode(r.getLocalName());
+					if (elementName == null || elementName.equals(currAttr))
+						jsonType = UNKNOWN;
+					else
+						jsonType = getJsonType(elementName);
+				} catch (Exception e) {
+					throw e;
+				}
+			}
+			if (! ft.canCreateNewInstance(outer)) {
+				String c = r.getAttributeValue(null, "_class");
+				if (c != null) {
+					ft = nt = (ClassMeta<T>)bc.getClassMetaFromString(c);
+				}
+			}
+			Object o = null;
+
+			if (jsonType == NULL) {
+				r.nextTag();	// Discard end tag
+				return null;
+			}
+			if (isNull) {
+				while (true) {
+					int e = r.next();
+					if (e == END_ELEMENT)
+						return null;
+				}
+			}
+
+			if (ft.isObject()) {
+				if (jsonType == OBJECT) {
+					ObjectMap m = new ObjectMap(bc);
+					parseIntoMap(ctx, r, m, string(), object());
+					if (wrapperAttr != null)
+						m = new ObjectMap(bc).append(wrapperAttr, m);
+					o = m.cast();
+				} else if (jsonType == ARRAY)
+					o = parseIntoCollection(ctx, r, new ObjectList(bc), object());
+				else if (jsonType == STRING) {
+					o = getText(ctx, r);
+					if (ft.isChar())
+						o = o.toString().charAt(0);
+				}
+				else if (jsonType == NUMBER)
+					o = parseNumber(getText(ctx, r), null);
+				else if (jsonType == BOOLEAN)
+					o = Boolean.parseBoolean(getText(ctx, r));
+				else if (jsonType == UNKNOWN)
+					o = getUnknown(ctx, r);
+			} else if (ft.isBoolean()) {
+				o = Boolean.parseBoolean(getText(ctx, r));
+			} else if (ft.isCharSequence()) {
+				o = getText(ctx, r);
+			} else if (ft.isChar()) {
+				o = getText(ctx, r).charAt(0);
+			} else if (ft.isMap()) {
+				Map m = (ft.canCreateNewInstance(outer) ? (Map)ft.newInstance(outer) : new ObjectMap(bc));
+				o = parseIntoMap(ctx, r, m, ft.getKeyType(), ft.getValueType());
+				if (wrapperAttr != null)
+					o = new ObjectMap(bc).append(wrapperAttr, m);
+			} else if (ft.isCollection()) {
+				Collection l = (ft.canCreateNewInstance(outer) ? (Collection)ft.newInstance(outer) : new ObjectList(bc));
+				o = parseIntoCollection(ctx, r, l, ft.getElementType());
+			} else if (ft.isNumber()) {
+				o = parseNumber(getText(ctx, r), (Class<? extends Number>)ft.getInnerClass());
+			} else if (ft.canCreateNewInstanceFromObjectMap(outer)) {
+				ObjectMap m = new ObjectMap(bc);
+				parseIntoMap(ctx, r, m, string(), object());
+				o = ft.newInstanceFromObjectMap(outer, m);
+			} else if (ft.canCreateNewBean(outer)) {
+				if (ft.getXmlMeta().getFormat() == XmlFormat.COLLAPSED) {
+					String fieldName = r.getLocalName();
+					BeanMap m = bc.newBeanMap(outer, ft.getInnerClass());
+					BeanPropertyMeta bpm = m.getMeta().getXmlMeta().getPropertyMeta(fieldName);
+					bpm.set(m, parseAnything(m.getMeta().getClassMeta(), ctx, currAttr, r, p, m.getBean(false), false));
+					o = m.getBean();
+				} else {
+					BeanMap m = bc.newBeanMap(outer, ft.getInnerClass());
+					o = parseIntoBean(ctx, r, m).getBean();
+				}
+			} else if (ft.isArray()) {
+				ArrayList l = (ArrayList)parseIntoCollection(ctx, r, new ArrayList(), ft.getElementType());
+				o = bc.toArray(ft, l);
+			} else if (ft.canCreateNewInstanceFromString(outer)) {
+				o = ft.newInstanceFromString(outer, getText(ctx, r));
+			} else {
+				throw new ParseException("Class ''{0}'' could not be instantiated.  Reason: ''{1}''", ft.getInnerClass().getName(), ft.getNotABeanReason());
+			}
+
+			if (filter != null && o != null)
+				o = filter.unfilter(o, nt);
+
+			if (outer != null)
+				setParent(nt, o, outer);
+
+			if (currAttr != null)
+				setName(nt, o, currAttr);
+
+			return (T)o;
+		} catch (ParseException e) {
+			throw e;
+		} catch (IOException e) {
+			throw e;
+		} catch (RuntimeException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new ParseException("Error occurred while trying to parse class type ''{0}''", nt).initCause(e);
+		}
+	}
+
+	private <K,V> Map<K,V> parseIntoMap(XmlParserContext ctx, XMLStreamReader r, Map<K,V> m, ClassMeta<K> keyType, ClassMeta<V> valueType) throws ParseException, IOException {
+		BeanContext bc = ctx.getBeanContext();
+		try {
+			int depth = 0;
+			for (int i = 0; i < r.getAttributeCount(); i++) {
+				String a = r.getAttributeLocalName(i);
+				// TODO - Need better handling of namespaces here.
+				if (! (a.equals("type"))) {
+					K key = convertAttrToType(m, a, keyType);
+					V value = convertAttrToType(m, r.getAttributeValue(i), valueType);
+					m.put(key, value);
+				}
+			}
+			do {
+				int event = r.nextTag();
+				String currAttr;
+				if (event == START_ELEMENT) {
+					depth++;
+					currAttr = decode(r.getLocalName());
+					K key = convertAttrToType(m, currAttr, keyType);
+					V value = parseAnything(valueType, ctx, currAttr, r, null, m, false);
+					if (valueType.isObject() && m.containsKey(key)) {
+						Object o = m.get(key);
+						if (o instanceof List)
+							((List)o).add(value);
+						else
+							m.put(key, (V)new ObjectList(o, value).setBeanContext(bc));
+					} else {
+						m.put(key, value);
+					}
+				} else if (event == END_ELEMENT) {
+					depth--;
+					return m;
+				}
+			} while (depth > 0);
+			return m;
+		} catch (XMLStreamException e) {
+			throw new ParseException(e);
+		}
+	}
+
+	private <E> Collection<E> parseIntoCollection(XmlParserContext ctx, XMLStreamReader r, Collection<E> l, ClassMeta<E> elementType) throws ParseException, IOException {
+		try {
+			int depth = 0;
+			do {
+				int event = r.nextTag();
+				if (event == START_ELEMENT) {
+					depth++;
+					E value = parseAnything(elementType, ctx, null, r, null, l, false);
+					l.add(value);
+				} else if (event == END_ELEMENT) {
+					depth--;
+					return l;
+				}
+			} while (depth > 0);
+			return l;
+		} catch (XMLStreamException e) {
+			throw new ParseException(e);
+		}
+	}
+
+	private Object[] parseArgs(XmlParserContext ctx, XMLStreamReader r, ClassMeta<?>[] argTypes) throws ParseException, IOException {
+		try {
+			int depth = 0;
+			Object[] o = new Object[argTypes.length];
+			int i = 0;
+			do {
+				int event = r.nextTag();
+				if (event == START_ELEMENT) {
+					depth++;
+					o[i] = parseAnything(argTypes[i], ctx, null, r, null, null, false);
+					i++;
+				} else if (event == END_ELEMENT) {
+					depth--;
+					return o;
+				}
+			} while (depth > 0);
+			return o;
+		} catch (XMLStreamException e) {
+			throw new ParseException(e);
+		}
+	}
+
+	private int getJsonType(String s) {
+		if (s == null)
+			return UNKNOWN;
+		char c = s.charAt(0);
+		switch(c) {
+			case 'o': return (s.equals("object") ? OBJECT : UNKNOWN);
+			case 'a': return (s.equals("array") ? ARRAY : UNKNOWN);
+			case 's': return (s.equals("string") ? STRING : UNKNOWN);
+			case 'b': return (s.equals("boolean") ? BOOLEAN : UNKNOWN);
+			case 'n': {
+				c = s.charAt(2);
+				switch(c) {
+					case 'm': return (s.equals("number") ? NUMBER : UNKNOWN);
+					case 'l': return (s.equals("null") ? NULL : UNKNOWN);
+				}
+				//return NUMBER;
+			}
+		}
+		return UNKNOWN;
+	}
+
+	private <T> BeanMap<T> parseIntoBean(XmlParserContext ctx, XMLStreamReader r, BeanMap<T> m) throws Exception {
+		BeanMeta bMeta = m.getMeta();
+		XmlBeanMeta xmlMeta = bMeta.getXmlMeta();
+
+		for (int i = 0; i < r.getAttributeCount(); i++) {
+			String key = decode(r.getAttributeLocalName(i));
+			String val = r.getAttributeValue(i);
+			BeanPropertyMeta bpm = xmlMeta.getPropertyMeta(key);
+			if (bpm == null) {
+				if (m.getMeta().isSubTyped()) {
+					m.put(key, val);
+				} else {
+					Location l = r.getLocation();
+					onUnknownProperty(ctx, key, m, l.getLineNumber(), l.getColumnNumber());
+				}
+			} else {
+				bpm.set(m, val);
+			}
+		}
+
+		BeanPropertyMeta cp = xmlMeta.getXmlContentProperty();
+		if (cp != null) {
+			XmlContentHandler h = xmlMeta.getXmlContentHandler();
+			if (h != null) {
+				h.parse(r, m.getBean());
+			} else {
+				String text = r.getElementText();
+				cp.set(m, decode(text.trim()));
+			}
+			return m;
+		}
+
+		int depth = 0;
+		do {
+			int event = r.nextTag();
+			String currAttr;
+			if (event == START_ELEMENT) {
+				depth++;
+				currAttr = decode(r.getLocalName());
+				BeanPropertyMeta pMeta = xmlMeta.getPropertyMeta(currAttr);
+				if (pMeta == null) {
+					if (m.getMeta().isSubTyped()) {
+						m.put(currAttr, parseAnything(ctx.getBeanContext().string(), ctx, currAttr, r, null, m.getBean(false), false));
+					} else {
+						Location l = r.getLocation();
+						onUnknownProperty(ctx, currAttr, m, l.getLineNumber(), l.getColumnNumber());
+						skipCurrentTag(r);
+					}
+				} else {
+					XmlFormat xf = pMeta.getXmlMeta().getXmlFormat();
+					if (xf == COLLAPSED) {
+						pMeta.add(m, parseAnything(pMeta.getClassMeta().getElementType(), ctx, currAttr, r, null, m.getBean(false), false));
+					} else if (xf == ATTR)  {
+						pMeta.set(m, decode(r.getAttributeValue(0)));
+						r.nextTag();
+					} else {
+						pMeta.set(m, parseAnything(pMeta.getClassMeta(), ctx, currAttr, r, pMeta, m.getBean(false), false));
+					}
+				}
+			} else if (event == END_ELEMENT) {
+				depth--;
+				return m;
+			}
+		} while (depth > 0);
+		return m;
+	}
+
+	private void skipCurrentTag(XMLStreamReader r) throws XMLStreamException {
+		int depth = 1;
+		do {
+			int event = r.next();
+			if (event == START_ELEMENT)
+				depth++;
+			else if (event == END_ELEMENT)
+				depth--;
+		} while (depth > 0);
+	}
+
+	private String getText(XmlParserContext ctx, XMLStreamReader r) throws Exception {
+		String s = r.getElementText();
+		if (s.length() == 0)
+			return s;
+		if (ctx.isTrimWhitespace() && Character.isWhitespace(s.charAt(0)) || Character.isWhitespace(s.charAt(s.length()-1)))
+			s = s.trim();
+		if (s.indexOf('_') == -1)
+			return s;
+		return decode(s);
+	}
+
+	private Object getUnknown(XmlParserContext ctx, XMLStreamReader r) throws Exception {
+		BeanContext bc = ctx.getBeanContext();
+		if (r.getEventType() != XMLStreamConstants.START_ELEMENT) {
+			throw new XMLStreamException("parser must be on START_ELEMENT to read next text", r.getLocation());
+		}
+		ObjectMap m = null;
+
+		// If this element has attributes, then it's always an ObjectMap.
+		if (r.getAttributeCount() > 0) {
+			m = new ObjectMap(bc);
+			for (int i = 0; i < r.getAttributeCount(); i++) {
+				String key = decode(r.getAttributeLocalName(i));
+				String val = r.getAttributeValue(i);
+				if (! key.equals("type"))
+					m.put(key, val);
+			}
+		}
+		int eventType = r.next();
+		StringBuilder sb = new StringBuilder();
+		while (eventType != XMLStreamConstants.END_ELEMENT) {
+			if (eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.ENTITY_REFERENCE) {
+				sb.append(r.getText());
+			} else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT) {
+				// skipping
+			} else if (eventType == XMLStreamConstants.END_DOCUMENT) {
+				throw new XMLStreamException("Unexpected end of document when reading element text content", r.getLocation());
+			} else if (eventType == XMLStreamConstants.START_ELEMENT) {
+				// Oops...this has an element in it.
+				// Parse it as a map.
+				if (m == null)
+					m = new ObjectMap(bc);
+				int depth = 0;
+				do {
+					int event = (eventType == -1 ? r.nextTag() : eventType);
+					String currAttr;
+					if (event == START_ELEMENT) {
+						depth++;
+						currAttr = decode(r.getLocalName());
+						String key = convertAttrToType(null, currAttr, string());
+						Object value = parseAnything(object(), ctx, currAttr, r, null, null, false);
+						if (m.containsKey(key)) {
+							Object o = m.get(key);
+							if (o instanceof ObjectList)
+								((ObjectList)o).add(value);
+							else
+								m.put(key, new ObjectList(o, value).setBeanContext(bc));
+						} else {
+							m.put(key, value);
+						}
+
+					} else if (event == END_ELEMENT) {
+						depth--;
+						break;
+					}
+					eventType = -1;
+				} while (depth > 0);
+				break;
+			} else {
+				throw new XMLStreamException("Unexpected event type " + eventType, r.getLocation());
+			}
+			eventType = r.next();
+		}
+		String s = sb.toString();
+		if (s.length() > 0) {
+			if (ctx.isTrimWhitespace() && Character.isWhitespace(s.charAt(0)) || Character.isWhitespace(s.charAt(s.length()-1)))
+				s = s.trim();
+			if (s.indexOf('_') != -1)
+				s = decode(s);
+		}
+		if (m != null) {
+			if (! s.isEmpty())
+				m.put("contents", s);
+			return m;
+		}
+		return s;
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Overridden methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* Parser */
+	public XmlParserContext createContext(ObjectMap properties, Method javaMethod, Object outer) {
+		return new XmlParserContext(getBeanContext(), pp, xpp, properties, javaMethod, outer);
+	}
+
+	@Override /* Parser */
+	protected <T> T doParse(Reader in, int estimatedSize, ClassMeta<T> type, ParserContext ctx) throws ParseException, IOException {
+		type = ctx.getBeanContext().normalizeClassMeta(type);
+		XmlParserContext xctx = (XmlParserContext)ctx;
+		return parseAnything(type, xctx, null, xctx.getReader(in, estimatedSize), null, ctx.getOuter(), true);
+	}
+
+	@Override /* ReaderParser */
+	protected <K,V> Map<K,V> doParseIntoMap(Reader in, int estimatedSize, Map<K,V> m, Type keyType, Type valueType, ParserContext ctx) throws ParseException, IOException {
+		ClassMeta cm = ctx.getBeanContext().getMapClassMeta(m.getClass(), keyType, valueType);
+		XmlParserContext xctx = (XmlParserContext)ctx;
+		return parseIntoMap(xctx, xctx.getReader(in, estimatedSize), m, cm.getKeyType(), cm.getValueType());
+	}
+
+	@Override /* ReaderParser */
+	protected <E> Collection<E> doParseIntoCollection(Reader in, int estimatedSize, Collection<E> c, Type elementType, ParserContext ctx) throws ParseException, IOException {
+		ClassMeta cm = ctx.getBeanContext().getCollectionClassMeta(c.getClass(), elementType);
+		XmlParserContext xctx = (XmlParserContext)ctx;
+		return parseIntoCollection(xctx, xctx.getReader(in, estimatedSize), c, cm.getElementType());
+	}
+
+	@Override /* ReaderParser */
+	protected Object[] doParseArgs(Reader in, int estimatedSize, ClassMeta<?>[] argTypes, ParserContext ctx) throws ParseException, IOException {
+		XmlParserContext xctx = (XmlParserContext)ctx;
+		return parseArgs(xctx, xctx.getReader(in, estimatedSize), argTypes);
+	}
+
+	@Override /* CoreApi */
+	public XmlParser setProperty(String property, Object value) throws LockedException {
+		checkLock();
+		if (! xpp.setProperty(property, value))
+			super.setProperty(property, value);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public XmlParser setProperties(ObjectMap properties) throws LockedException {
+		for (Map.Entry<String,Object> e : properties.entrySet())
+			setProperty(e.getKey(), e.getValue());
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public XmlParser addNotBeanClasses(Class<?>...classes) throws LockedException {
+		super.addNotBeanClasses(classes);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public XmlParser addFilters(Class<?>...classes) throws LockedException {
+		super.addFilters(classes);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public <T> XmlParser addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
+		super.addImplClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreApi */
+	public XmlParser setClassLoader(ClassLoader classLoader) throws LockedException {
+		super.setClassLoader(classLoader);
+		return this;
+	}
+
+	@Override /* Lockable */
+	public XmlParser lock() {
+		super.lock();
+		return this;
+	}
+
+	@Override /* Lockable */
+	public XmlParser clone() {
+		try {
+			XmlParser c = (XmlParser)super.clone();
+			c.xpp = xpp.clone();
+			return c;
+		} catch (CloneNotSupportedException e) {
+			throw new RuntimeException(e); // Shouldn't happen.
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserContext.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserContext.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserContext.class
new file mode 100755
index 0000000..7b0a2a3
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserContext.class differ


Mime
View raw message