You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2016/08/01 00:07:52 UTC
[03/51] [partial] incubator-juneau git commit: Initial Juno contents
from IBM JazzHub repo
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.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserContext.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserContext.java
new file mode 100755
index 0000000..322cdc8
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserContext.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * 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.xml.XmlParserProperties.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+
+import javax.xml.stream.*;
+import javax.xml.stream.util.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.parser.*;
+import com.ibm.juno.core.utils.*;
+
+/**
+ * Context object that lives for the duration of a single parsing of {@link XmlParser}.
+ * <p>
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public final class XmlParserContext extends ParserContext {
+
+ /**
+ * XMLSchema namespace URI ({@link String}, default=<js>"http://www.w3.org/2001/XMLSchema-instance"</js>).
+ * <p>
+ * The XMLSchema namespace.
+ */
+ private final String xsiNs;
+ private final boolean
+ trimWhitespace,
+ validating,
+ coalescing,
+ replaceEntityReferences,
+ preserveRootElement;
+ private final XMLReporter reporter;
+ private final XMLResolver resolver;
+ private final XMLEventAllocator eventAllocator;
+ private XMLStreamReader xmlStreamReader;
+
+
+ /**
+ * Create a new parser context with the specified options.
+ *
+ * @param beanContext The bean context being used.
+ * @param pp The default parser properties.
+ * @param xpp The default XML parser properties.
+ * @param op The override properties.
+ * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+ * @param outer The outer object for instantiating top-level non-static inner classes.
+ */
+ public XmlParserContext(BeanContext beanContext, ParserProperties pp, XmlParserProperties xpp, ObjectMap op, Method javaMethod, Object outer) {
+ super(beanContext, pp, op, javaMethod, outer);
+ if (op == null || op.isEmpty()) {
+ xsiNs = xpp.getXsiNs();
+ trimWhitespace = xpp.isTrimWhitespace();
+ validating = xpp.isValidating();
+ coalescing = xpp.isCoalescing();
+ replaceEntityReferences = xpp.isReplaceEntityReferences();
+ reporter = xpp.getReporter();
+ resolver = xpp.getResolver();
+ eventAllocator = xpp.getEventAllocator();
+ preserveRootElement = xpp.isPreserveRootElement();
+ } else {
+ xsiNs = op.getString(XML_xsiNs, xpp.getXsiNs());
+ trimWhitespace = op.getBoolean(XML_trimWhitespace, xpp.isTrimWhitespace());
+ validating = op.getBoolean(XML_validating, xpp.isValidating());
+ coalescing = op.getBoolean(XML_coalescing, xpp.isCoalescing());
+ replaceEntityReferences = op.getBoolean(XML_replaceEntityReferences, xpp.isReplaceEntityReferences());
+ reporter = (XMLReporter)op.get(XML_reporter, xpp.getReporter());
+ resolver = (XMLResolver)op.get(XML_resolver, xpp.getResolver());
+ eventAllocator = (XMLEventAllocator)op.get(XML_eventAllocator, xpp.getEventAllocator());
+ preserveRootElement = op.getBoolean(XML_preserveRootElement, xpp.isPreserveRootElement());
+ }
+ }
+
+ /**
+ * Returns the {@link XmlParserProperties#XML_xsiNs} setting in this context.
+ *
+ * @return The {@link XmlParserProperties#XML_xsiNs} setting in this context.
+ */
+ public String getXsiNs() {
+ return xsiNs;
+ }
+
+ /**
+ * Returns the {@link XmlParserProperties#XML_trimWhitespace} setting in this context.
+ *
+ * @return The {@link XmlParserProperties#XML_trimWhitespace} setting in this context.
+ */
+ public boolean isTrimWhitespace() {
+ return trimWhitespace;
+ }
+
+ /**
+ * Returns the {@link XmlParserProperties#XML_preserveRootElement} setting in this context.
+ *
+ * @return The {@link XmlParserProperties#XML_preserveRootElement} setting in this context.
+ */
+ public boolean isPreserveRootElement() {
+ return preserveRootElement;
+ }
+
+ /**
+ * Returns the {@link XmlParserProperties#XML_validating} setting in this context.
+ *
+ * @return The {@link XmlParserProperties#XML_validating} setting in this context.
+ */
+ public boolean isValidating() {
+ return validating;
+ }
+
+ /**
+ * Returns the {@link XmlParserProperties#XML_coalescing} setting in this context.
+ *
+ * @return The {@link XmlParserProperties#XML_coalescing} setting in this context.
+ */
+ public boolean isCoalescing() {
+ return coalescing;
+ }
+
+ /**
+ * Returns the {@link XmlParserProperties#XML_replaceEntityReferences} setting in this context.
+ *
+ * @return The {@link XmlParserProperties#XML_replaceEntityReferences} setting in this context.
+ */
+ public boolean isReplaceEntityReferences() {
+ return replaceEntityReferences;
+ }
+
+ /**
+ * Returns the {@link XmlParserProperties#XML_reporter} setting in this context.
+ *
+ * @return The {@link XmlParserProperties#XML_reporter} setting in this context.
+ */
+ public XMLReporter getReporter() {
+ return reporter;
+ }
+
+ /**
+ * Returns the {@link XmlParserProperties#XML_resolver} setting in this context.
+ *
+ * @return The {@link XmlParserProperties#XML_resolver} setting in this context.
+ */
+ public XMLResolver getResolver() {
+ return resolver;
+ }
+
+ /**
+ * Returns the {@link XmlParserProperties#XML_eventAllocator} setting in this context.
+ *
+ * @return The {@link XmlParserProperties#XML_eventAllocator} setting in this context.
+ */
+ public XMLEventAllocator getEventAllocator() {
+ return eventAllocator;
+ }
+
+
+ /**
+ * Wrap the specified reader in a STAX reader based on settings in this context.
+ *
+ * @param r The input reader.
+ * @param estimatedSize The estimated size of the contents of the reader.
+ * @return The new STAX reader.
+ * @throws ParseException If problem occurred trying to create reader.
+ */
+ public XMLStreamReader getReader(Reader r, int estimatedSize) throws ParseException {
+ try {
+ r = IOUtils.getBufferedReader(r, estimatedSize);
+ XMLInputFactory factory = XMLInputFactory.newInstance();
+ factory.setProperty(XMLInputFactory.IS_VALIDATING, validating);
+ factory.setProperty(XMLInputFactory.IS_COALESCING, coalescing);
+ factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, replaceEntityReferences);
+ if (factory.isPropertySupported(XMLInputFactory.REPORTER) && reporter != null)
+ factory.setProperty(XMLInputFactory.REPORTER, reporter);
+ if (factory.isPropertySupported(XMLInputFactory.RESOLVER) && resolver != null)
+ factory.setProperty(XMLInputFactory.RESOLVER, resolver);
+ if (factory.isPropertySupported(XMLInputFactory.ALLOCATOR) && eventAllocator != null)
+ factory.setProperty(XMLInputFactory.ALLOCATOR, eventAllocator);
+ xmlStreamReader = factory.createXMLStreamReader(r);
+ xmlStreamReader.nextTag();
+ } catch (Error e) {
+ close();
+ throw new ParseException(e.getLocalizedMessage());
+ } catch (XMLStreamException e) {
+ close();
+ throw new ParseException(e);
+ }
+
+ return xmlStreamReader;
+ }
+
+ /**
+ * Silently closes the XML stream returned by the call to {@link #getReader(Reader, int)}.
+ */
+ @Override /* ParserContext */
+ public void close() throws ParseException {
+ super.close();
+ try {
+ if (xmlStreamReader != null)
+ xmlStreamReader.close();
+ } catch (XMLStreamException e) {
+ // Ignore.
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserProperties.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserProperties.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserProperties.class
new file mode 100755
index 0000000..c5e5e4f
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserProperties.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/XmlParserProperties.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserProperties.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserProperties.java
new file mode 100755
index 0000000..23b9503
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlParserProperties.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * � 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 javax.xml.stream.*;
+import javax.xml.stream.util.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.parser.*;
+
+/**
+ * Configurable properties on the {@link XmlParser} class.
+ * <p>
+ * Use the {@link XmlParser#setProperty(String, Object)} method to set property values.
+ * <p>
+ * In addition to these properties, the following properties are also applicable for {@link XmlParser}.
+ * <ul>
+ * <li>{@link ParserProperties}
+ * <li>{@link BeanContextProperties}
+ * </ul>
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public final class XmlParserProperties implements Cloneable {
+
+ /**
+ * XMLSchema-instance namespace URI ({@link String}, default=<js>"http://www.w3.org/2001/XMLSchema-instance"</js>).
+ * <p>
+ * The XMLSchema namespace.
+ */
+ public static final String XML_xsiNs = "XmlParser.xsiNs";
+
+ /**
+ * Trim whitespace from text elements ({@link Boolean}, default=<jk>false</jk>).
+ * <p>
+ * If <jk>true</jk>, whitespace in text elements will be automatically trimmed.
+ */
+ public static final String XML_trimWhitespace = "XmlParser.trimWhitespace";
+
+ /**
+ * Set validating mode ({@link Boolean}, default=<jk>false</jk>).
+ * <p>
+ * If <jk>true</jk>, XML document will be validated.
+ * See {@link XMLInputFactory#IS_VALIDATING} for more info.
+ */
+ public static final String XML_validating = "XmlParser.validating";
+
+ /**
+ * Set coalescing mode ({@link Boolean}, default=<jk>false</jk>).
+ * <p>
+ * If <jk>true</jk>, XML text elements will be coalesced.
+ * See {@link XMLInputFactory#IS_COALESCING} for more info.
+ */
+ public static final String XML_coalescing = "XmlParser.coalescing";
+
+ /**
+ * Replace entity references ({@link Boolean}, default=<jk>true</jk>).
+ * <p>
+ * If <jk>true</jk>, entity references will be replace during parsing.
+ * See {@link XMLInputFactory#IS_REPLACING_ENTITY_REFERENCES} for more info.
+ */
+ public static final String XML_replaceEntityReferences = "XmlParser.replaceEntityReferences";
+
+ /**
+ * XML reporter ({@link XMLReporter}, default=<jk>null</jk>).
+ * <p>
+ * Associates an {@link XMLReporter} with this parser.
+ * <p>
+ * Note: Reporters are not copied to new parsers during a clone.
+ */
+ public static final String XML_reporter = "XmlParser.reporter";
+
+ /**
+ * XML resolver ({@link XMLResolver}, default=<jk>null</jk>).
+ * <p>
+ * Associates an {@link XMLResolver} with this parser.
+ */
+ public static final String XML_resolver = "XmlParser.resolver";
+
+ /**
+ * XML event allocator. ({@link XMLEventAllocator}, default=<jk>false</jk>).
+ * <p>
+ * Associates an {@link XMLEventAllocator} with this parser.
+ */
+ public static final String XML_eventAllocator = "XmlParser.eventAllocator";
+
+ /**
+ * Preserve root element during generalized parsing ({@link Boolean}, default=<jk>false</jk>).
+ * <p>
+ * If <jk>true</jk>, when parsing into a generic {@link ObjectMap}, the map will
+ * contain a single entry whose key is the root element name.
+ *
+ * Example:
+ * <table class='styled'>
+ * <tr>
+ * <td>XML</td>
+ * <td>ObjectMap.toString(), preserveRootElement==false</td>
+ * <td>ObjectMap.toString(), preserveRootElement==true</td>
+ * </tr>
+ * <tr>
+ * <td><code><xt><root><a></xt>foobar<xt></a></root></xt><code></td>
+ * <td><code>{ a:<js>'foobar'</js> }</code></td>
+ * <td><code>{ root: { a:<js>'foobar'</js> }}</code></td>
+ * </tr>
+ * </table>
+ *
+ */
+ public static final String XML_preserveRootElement = "XmlParser.preserveRootElement";
+
+ private String xsiNs = "http://www.w3.org/2001/XMLSchema-instance";
+ private boolean
+ trimWhitespace = false,
+ validating = false,
+ coalescing = false,
+ replaceEntityReferences = true,
+ preserveRootElement = false;
+ private XMLReporter reporter;
+ private XMLResolver resolver;
+ private XMLEventAllocator eventAllocator;
+
+ /**
+ * Sets the specified property value.
+ * @param property The property name.
+ * @param value The property value.
+ * @return <jk>true</jk> if property name was valid and property was set.
+ * @throws LockedException If bean context is locked.
+ */
+ protected boolean setProperty(String property, Object value) throws LockedException {
+ BeanContext bc = BeanContext.DEFAULT;
+ if (property.equals(XML_trimWhitespace))
+ trimWhitespace = bc.convertToType(value, Boolean.class);
+ else if (property.equals(XML_validating))
+ validating = bc.convertToType(value, Boolean.class);
+ else if (property.equals(XML_coalescing))
+ coalescing = bc.convertToType(value, Boolean.class);
+ else if (property.equals(XML_replaceEntityReferences))
+ replaceEntityReferences = bc.convertToType(value, Boolean.class);
+ else if (property.equals(XML_xsiNs))
+ xsiNs = value.toString();
+ else if (property.equals(XML_reporter) && value instanceof XMLReporter)
+ reporter = (XMLReporter)value;
+ else if (property.equals(XML_resolver) && value instanceof XMLResolver)
+ resolver = (XMLResolver)value;
+ else if (property.equals(XML_eventAllocator) && value instanceof XMLEventAllocator)
+ eventAllocator = (XMLEventAllocator)value;
+ else if (property.equals(XML_preserveRootElement))
+ preserveRootElement = bc.convertToType(value, Boolean.class);
+ else
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns the current {@link #XML_xsiNs} value.
+ * @return The current {@link #XML_xsiNs} value.
+ */
+ public String getXsiNs() {
+ return xsiNs;
+ }
+
+ /**
+ * Returns the current {@link #XML_trimWhitespace} value.
+ * @return The current {@link #XML_trimWhitespace} value.
+ */
+ public boolean isTrimWhitespace() {
+ return trimWhitespace;
+ }
+
+ /**
+ * Returns the current {@link #XML_preserveRootElement} value.
+ * @return The current {@link #XML_preserveRootElement} value.
+ */
+ public boolean isPreserveRootElement() {
+ return preserveRootElement;
+ }
+
+ /**
+ * Returns the current {@link #XML_validating} value.
+ * @return The current {@link #XML_validating} value.
+ */
+ public boolean isValidating() {
+ return validating;
+ }
+
+ /**
+ * Returns the current {@link #XML_coalescing} value.
+ * @return The current {@link #XML_coalescing} value.
+ */
+ public boolean isCoalescing() {
+ return coalescing;
+ }
+
+ /**
+ * Returns the current {@link #XML_replaceEntityReferences} value.
+ * @return The current {@link #XML_replaceEntityReferences} value.
+ */
+ public boolean isReplaceEntityReferences() {
+ return replaceEntityReferences;
+ }
+
+ /**
+ * Returns the current {@link #XML_reporter} value.
+ * @return The current {@link #XML_reporter} value.
+ */
+ public XMLReporter getReporter() {
+ return reporter;
+ }
+
+ /**
+ * Returns the current {@link #XML_reporter} value.
+ * @return The current {@link #XML_reporter} value.
+ */
+ public XMLResolver getResolver() {
+ return resolver;
+ }
+
+ /**
+ * Returns the current {@link #XML_eventAllocator} value.
+ * @return The current {@link #XML_eventAllocator} value.
+ */
+ public XMLEventAllocator getEventAllocator() {
+ return eventAllocator;
+ }
+
+
+ //--------------------------------------------------------------------------------
+ // Overridden methods
+ //--------------------------------------------------------------------------------
+
+ @Override /* Object */
+ public XmlParserProperties clone() {
+ try {
+ return (XmlParserProperties)super.clone();
+ } 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/XmlSchemaDocSerializer.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaDocSerializer.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaDocSerializer.class
new file mode 100755
index 0000000..4aa659b
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaDocSerializer.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/XmlSchemaDocSerializer.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaDocSerializer.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaDocSerializer.java
new file mode 100755
index 0000000..0c3b5f5
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaDocSerializer.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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 java.io.*;
+
+import com.ibm.juno.core.serializer.*;
+
+/**
+ * Serializes POJO metadata to HTTP responses as XML.
+ *
+ *
+ * <h6 class='topic'>Media types</h6>
+ * <p>
+ * Handles <code>Accept</code> types: <code>text/xml+schema</code>
+ * <p>
+ * Produces <code>Content-Type</code> types: <code>text/xml</code>
+ *
+ *
+ * <h6 class='topic'>Description</h6>
+ * <p>
+ * Same as {@link XmlSchemaSerializer}, except prepends <code><xt><?xml</xt> <xa>version</xa>=<xs>'1.0'</xs> <xa>encoding</xa>=<xs>'UTF-8'</xs><xt>?></xt></code> to the response
+ * to make it a valid XML document.
+ *
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+public class XmlSchemaDocSerializer extends XmlSchemaSerializer {
+
+ //--------------------------------------------------------------------------------
+ // 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/XmlSchemaSerializer$1.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$1.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$1.class
new file mode 100755
index 0000000..98bc0e8
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$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/xml/XmlSchemaSerializer$QueueEntry.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$QueueEntry.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$QueueEntry.class
new file mode 100755
index 0000000..7948545
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$QueueEntry.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/XmlSchemaSerializer$Schema.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$Schema.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$Schema.class
new file mode 100755
index 0000000..fa87011
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$Schema.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/XmlSchemaSerializer$Schemas.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$Schemas.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$Schemas.class
new file mode 100755
index 0000000..fba563f
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer$Schemas.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/XmlSchemaSerializer.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer.class
new file mode 100755
index 0000000..1361066
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer.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/XmlSchemaSerializer.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer.java
new file mode 100755
index 0000000..bc40ae4
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSchemaSerializer.java
@@ -0,0 +1,588 @@
+/*******************************************************************************
+ * 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.annotation.XmlFormat.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.text.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.xml.*;
+import javax.xml.transform.stream.*;
+import javax.xml.validation.*;
+
+import org.w3c.dom.bootstrap.*;
+import org.w3c.dom.ls.*;
+import org.xml.sax.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.annotation.*;
+import com.ibm.juno.core.serializer.*;
+import com.ibm.juno.core.utils.*;
+import com.ibm.juno.core.xml.annotation.*;
+
+/**
+ * Serializes POJO metadata to HTTP responses as XML.
+ *
+ *
+ * <h6 class='topic'>Media types</h6>
+ * <p>
+ * Handles <code>Accept</code> types: <code>text/xml+schema</code>
+ * <p>
+ * Produces <code>Content-Type</code> types: <code>text/xml</code>
+ *
+ *
+ * <h6 class='topic'>Description</h6>
+ * <p>
+ * Produces the XML-schema representation of the XML produced by the {@link XmlSerializer} class with the same properties.
+ *
+ *
+ * <h6 class='topic'>Configurable properties</h6>
+ * <p>
+ * This class has the following properties associated with it:
+ * <ul>
+ * <li>{@link XmlSerializerProperties}
+ * <li>{@link SerializerProperties}
+ * <li>{@link BeanContextProperties}
+ * </ul>
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+@Produces(value="text/xml+schema",contentType="text/xml")
+public class XmlSchemaSerializer extends XmlSerializer {
+
+ @Override /* XmlSerializer */
+ protected void doSerialize(Object o, Writer out, SerializerContext ctx) throws IOException, SerializeException {
+ XmlSerializerContext xctx = (XmlSerializerContext)ctx;
+
+ if (xctx.isEnableNamespaces() && xctx.isAutoDetectNamespaces())
+ findNsfMappings(o, xctx);
+
+ Namespace xs = xctx.getXsNamespace();
+ Namespace[] allNs = ArrayUtils.append(new Namespace[]{xctx.getDefaultNamespace()}, xctx.getNamespaces());
+
+ Schemas s = new Schemas(xs, xctx.getDefaultNamespace(), allNs, xctx);
+ s.process(o, xctx);
+ s.serializeTo(out);
+ }
+
+ /**
+ * Returns an XML-Schema validator based on the output returned by {@link #doSerialize(Object, Writer, SerializerContext)};
+ *
+ * @param o The object to serialize.
+ * @param ctx The serializer context object return by {@link #createContext(ObjectMap, Method)}.<br>
+ * Can be <jk>null</jk>.
+ * @return The new validator.
+ * @throws SAXException If a problem was detected in the XML-Schema output produced by this serializer.
+ * @throws SerializeException If a problem occurred trying to convert the output.
+ */
+ public Validator getValidator(Object o, SerializerContext ctx) throws SerializeException, SAXException {
+ String xmlSchema = serialize(o, ctx);
+
+ // create a SchemaFactory capable of understanding WXS schemas
+ SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+
+ if (xmlSchema.indexOf('\u0000') != -1) {
+
+ // Break it up into a map of namespaceURI->schema document
+ final Map<String,String> schemas = new HashMap<String,String>();
+ String[] ss = xmlSchema.split("\u0000");
+ xmlSchema = ss[0];
+ for (String s : ss) {
+ Matcher m = pTargetNs.matcher(s);
+ if (m.find())
+ schemas.put(m.group(1), s);
+ }
+
+ // Create a custom resolver
+ factory.setResourceResolver(
+ new LSResourceResolver() {
+
+ @Override /* LSResourceResolver */
+ public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
+
+ String schema = schemas.get(namespaceURI);
+ if (schema == null)
+ throw new RuntimeException(MessageFormat.format("No schema found for namespaceURI ''{0}''", namespaceURI));
+
+ try {
+ DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
+ DOMImplementationLS domImplementationLS = (DOMImplementationLS)registry.getDOMImplementation("LS 3.0");
+ LSInput in = domImplementationLS.createLSInput();
+ in.setCharacterStream(new StringReader(schema));
+ in.setSystemId(systemId);
+ return in;
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ );
+ }
+ return factory.newSchema(new StreamSource(new StringReader(xmlSchema))).newValidator();
+ }
+
+ private static Pattern pTargetNs = Pattern.compile("targetNamespace=['\"]([^'\"]+)['\"]");
+
+
+ /* An instance of a global element, global attribute, or XML type to be serialized. */
+ private static class QueueEntry {
+ Namespace ns;
+ String name;
+ ClassMeta<?> cm;
+ QueueEntry(Namespace ns, String name, ClassMeta<?> cm) {
+ this.ns = ns;
+ this.name = name;
+ this.cm = cm;
+ }
+ }
+
+ /* An encapsulation of all schemas present in the metamodel of the serialized object. */
+ private class Schemas extends LinkedHashMap<Namespace,Schema> {
+
+ private static final long serialVersionUID = 1L;
+
+ private Namespace defaultNs;
+ private LinkedList<QueueEntry>
+ elementQueue = new LinkedList<QueueEntry>(),
+ attributeQueue = new LinkedList<QueueEntry>(),
+ typeQueue = new LinkedList<QueueEntry>();
+
+ private Schemas(Namespace xs, Namespace defaultNs, Namespace[] allNs, XmlSerializerContext ctx) throws IOException {
+ this.defaultNs = defaultNs;
+ for (Namespace ns : allNs)
+ put(ns, new Schema(this, xs, ns, defaultNs, allNs, ctx));
+ }
+
+ private Schema getSchema(Namespace ns) {
+ if (ns == null)
+ ns = defaultNs;
+ Schema s = get(ns);
+ if (s == null)
+ throw new RuntimeException("No schema defined for namespace '"+ns+"'");
+ return s;
+ }
+
+ private void process(Object o, SerializerContext ctx) throws IOException {
+ ClassMeta<?> cm = ctx.getBeanContext().getClassMetaForObject(o);
+ Namespace ns = defaultNs;
+ if (cm == null)
+ queueElement(ns, "null", object());
+ else {
+ XmlClassMeta xmlMeta = cm.getXmlMeta();
+ if (xmlMeta.getElementName() != null && xmlMeta.getNamespace() != null)
+ ns = xmlMeta.getNamespace();
+ queueElement(ns, xmlMeta.getElementName(), cm);
+ }
+ processQueue();
+ }
+
+
+ private void processQueue() throws IOException {
+ boolean b;
+ do {
+ b = false;
+ while (! elementQueue.isEmpty()) {
+ QueueEntry q = elementQueue.removeFirst();
+ b |= getSchema(q.ns).processElement(q.name, q.cm);
+ }
+ while (! typeQueue.isEmpty()) {
+ QueueEntry q = typeQueue.removeFirst();
+ b |= getSchema(q.ns).processType(q.name, q.cm);
+ }
+ while (! attributeQueue.isEmpty()) {
+ QueueEntry q = attributeQueue.removeFirst();
+ b |= getSchema(q.ns).processAttribute(q.name, q.cm);
+ }
+ } while (b);
+ }
+
+ private void queueElement(Namespace ns, String name, ClassMeta<?> cm) {
+ elementQueue.add(new QueueEntry(ns, name, cm));
+ }
+
+ private void queueType(Namespace ns, String name, ClassMeta<?> cm) {
+ if (name == null)
+ name = XmlUtils.encodeElementName(cm.toString());
+ typeQueue.add(new QueueEntry(ns, name, cm));
+ }
+
+ private void queueAttribute(Namespace ns, String name, ClassMeta<?> cm) {
+ attributeQueue.add(new QueueEntry(ns, name, cm));
+ }
+
+ private void serializeTo(Writer w) throws IOException {
+ boolean b = false;
+ for (Schema s : values()) {
+ if (b)
+ w.append('\u0000');
+ w.append(s.toString());
+ b = true;
+ }
+ }
+ }
+
+ /* An encapsulation of a single schema. */
+ private class Schema {
+ private StringWriter sw = new StringWriter();
+ private XmlSerializerWriter w;
+ private XmlSerializerContext ctx;
+ private Namespace defaultNs, targetNs;
+ private Schemas schemas;
+ private Set<String>
+ processedTypes = new HashSet<String>(),
+ processedAttributes = new HashSet<String>(),
+ processedElements = new HashSet<String>();
+
+ public Schema(Schemas schemas, Namespace xs, Namespace targetNs, Namespace defaultNs, Namespace[] allNs, XmlSerializerContext ctx) throws IOException {
+ this.schemas = schemas;
+ this.defaultNs = defaultNs;
+ this.targetNs = targetNs;
+ this.ctx = ctx;
+ w = new XmlSerializerWriter(sw, ctx.isUseIndentation(), ctx.getQuoteChar(), null, null, true, null);
+ int i = ctx.getIndent();
+ w.oTag(i, "schema");
+ w.attr("xmlns", xs.getUri());
+ w.attr("targetNamespace", targetNs.getUri());
+ w.attr("elementFormDefault", "qualified");
+ if (targetNs != defaultNs)
+ w.attr("attributeFormDefault", "qualified");
+ for (Namespace ns2 : allNs)
+ w.attr("xmlns", ns2.name, ns2.uri);
+ w.append('>').nl();
+ for (Namespace ns : allNs) {
+ if (ns != targetNs) {
+ w.oTag(i+1, "import")
+ .attr("namespace", ns.getUri())
+ .attr("schemaLocation", ns.getName()+".xsd")
+ .append("/>").nl();
+ }
+ }
+ }
+
+ private boolean processElement(String name, ClassMeta<?> cm) throws IOException {
+ if (processedElements.contains(name))
+ return false;
+ processedElements.add(name);
+
+ ClassMeta<?> ft = cm.getFilteredClassMeta();
+ int i = ctx.getIndent() + 1;
+ if (name == null)
+ name = getElementName(ft);
+ Namespace ns = first(ft.getXmlMeta().getNamespace(), defaultNs);
+ String type = getXmlType(ns, ft);
+
+ w.oTag(i, "element")
+ .attr("name", XmlUtils.encodeElementName(name))
+ .attr("type", type)
+ .append('/').append('>').nl();
+
+ schemas.queueType(ns, null, ft);
+ schemas.processQueue();
+ return true;
+ }
+
+ private boolean processAttribute(String name, ClassMeta<?> cm) throws IOException {
+ if (processedAttributes.contains(name))
+ return false;
+ processedAttributes.add(name);
+
+ int i = ctx.getIndent() + 1;
+ String type = getXmlAttrType(cm);
+
+ w.oTag(i, "attribute")
+ .attr("name", name)
+ .attr("type", type)
+ .append('/').append('>').nl();
+
+ return true;
+ }
+
+ private boolean processType(String name, ClassMeta<?> cm) throws IOException {
+ if (processedTypes.contains(name))
+ return false;
+ processedTypes.add(name);
+
+ int i = ctx.getIndent() + 1;
+
+ cm = cm.getFilteredClassMeta();
+
+ w.oTag(i, "complexType")
+ .attr("name", name);
+
+ // This element can have mixed content if:
+ // 1) It's a generic Object (so it can theoretically be anything)
+ // 2) The bean has a property defined with @XmlFormat.CONTENT.
+ if ((cm.isBean() && cm.getBeanMeta().getXmlMeta().getXmlContentProperty() != null) || cm.isObject())
+ w.attr("mixed", "true");
+
+ w.cTag().nl();
+
+ if (! (cm.isMap() || cm.isBean() || cm.hasToObjectMapMethod() || cm.isCollection() || cm.isArray() || (cm.isAbstract() && ! cm.isNumber()) || cm.isObject())) {
+ String base = getXmlAttrType(cm);
+ w.sTag(i+1, "simpleContent").nl();
+ w.oTag(i+2, "extension")
+ .attr("base", base);
+ if (ctx.isAddJsonTypeAttrs() || (ctx.isAddJsonStringTypeAttrs() && base.equals("string"))) {
+ w.cTag().nl();
+ w.oTag(i+3, "attribute")
+ .attr("name", "type")
+ .attr("type", "string")
+ .ceTag().nl();
+ w.eTag(i+2, "extension").nl();
+ } else {
+ w.ceTag().nl();
+ }
+ w.eTag(i+1, "simpleContent").nl();
+
+ } else {
+
+ //----- Bean -----
+ if (cm.isBean()) {
+ BeanMeta<?> bm = cm.getBeanMeta();
+
+ boolean hasChildElements = false;
+
+ for (BeanPropertyMeta<?> pMeta : bm.getPropertyMetas())
+ if (pMeta.getXmlMeta().getXmlFormat() != XmlFormat.ATTR && pMeta.getXmlMeta().getXmlFormat() != XmlFormat.CONTENT)
+ hasChildElements = true;
+
+ if (bm.getXmlMeta().getXmlContentProperty() != null) {
+ w.sTag(i+1, "sequence").nl();
+ w.oTag(i+2, "any")
+ .attr("processContents", "skip")
+ .attr("minOccurs", 0)
+ .ceTag().nl();
+ w.eTag(i+1, "sequence").nl();
+
+ } else if (hasChildElements) {
+ w.sTag(i+1, "sequence").nl();
+
+ boolean hasOtherNsElement = false;
+
+ for (BeanPropertyMeta<?> pMeta : bm.getPropertyMetas()) {
+ XmlBeanPropertyMeta<?> xmlMeta = pMeta.getXmlMeta();
+ if (xmlMeta.getXmlFormat() != XmlFormat.ATTR) {
+ boolean isCollapsed = xmlMeta.getXmlFormat() == COLLAPSED;
+ ClassMeta<?> ct2 = pMeta.getClassMeta();
+ String childName = pMeta.getName();
+ if (isCollapsed) {
+ if (xmlMeta.getChildName() != null)
+ childName = xmlMeta.getChildName();
+ ct2 = pMeta.getClassMeta().getElementType();
+ }
+ Namespace cNs = first(xmlMeta.getNamespace(), ct2.getXmlMeta().getNamespace(), cm.getXmlMeta().getNamespace(), defaultNs);
+ if (xmlMeta.getNamespace() == null) {
+ w.oTag(i+2, "element")
+ .attr("name", XmlUtils.encodeElementName(childName), true)
+ .attr("type", getXmlType(cNs, ct2));
+ if (isCollapsed) {
+ w.attr("minOccurs", 0);
+ w.attr("maxOccurs", "unbounded");
+ } else {
+ if (! ctx.isTrimNulls())
+ w.attr("nillable", true);
+ else
+ w.attr("minOccurs", 0);
+ }
+
+ w.ceTag().nl();
+ } else {
+ // Child element is in another namespace.
+ schemas.queueElement(cNs, pMeta.getName(), ct2);
+ hasOtherNsElement = true;
+ }
+
+ }
+ }
+
+ // If this bean has any child elements in another namespace,
+ // we need to add an <any> element.
+ if (hasOtherNsElement)
+ w.oTag(i+2, "any")
+ .attr("minOccurs", 0)
+ .attr("maxOccurs", "unbounded")
+ .ceTag().nl();
+ w.eTag(i+1, "sequence").nl();
+ }
+
+ for (BeanPropertyMeta<?> pMeta : bm.getXmlMeta().getXmlAttrProperties().values()) {
+ Namespace pNs = pMeta.getXmlMeta().getNamespace();
+ if (pNs == null)
+ pNs = defaultNs;
+
+ // If the bean attribute has a different namespace than the bean, then it needs to
+ // be added as a top-level entry in the appropriate schema file.
+ if (pNs != targetNs) {
+ schemas.queueAttribute(pNs, pMeta.getName(), pMeta.getClassMeta());
+ w.oTag(i+1, "attribute")
+ //.attr("name", pMeta.getName(), true)
+ .attr("ref", pNs.getName() + ':' + pMeta.getName())
+ .ceTag().nl();
+ }
+
+ // Otherwise, it's just a plain attribute of this bean.
+ else {
+ w.oTag(i+1, "attribute")
+ .attr("name", pMeta.getName(), true)
+ .attr("type", getXmlAttrType(pMeta.getClassMeta()))
+ .ceTag().nl();
+ }
+ }
+
+ //----- Collection -----
+ } else if (cm.isCollection() || cm.isArray()) {
+ ClassMeta<?> elementType = cm.getElementType();
+ if (elementType.isObject()) {
+ w.sTag(i+1, "sequence").nl();
+ w.oTag(i+2, "any")
+ .attr("processContents", "skip")
+ .attr("maxOccurs", "unbounded")
+ .attr("minOccurs", "0")
+ .ceTag().nl();
+ w.eTag(i+1, "sequence").nl();
+ } else {
+ Namespace cNs = first(elementType.getXmlMeta().getNamespace(), cm.getXmlMeta().getNamespace(), defaultNs);
+ schemas.queueType(cNs, null, elementType);
+ w.sTag(i+1, "sequence").nl();
+ w.oTag(i+2, "choice")
+ .attr("minOccurs", 0)
+ .attr("maxOccurs", "unbounded")
+ .cTag().nl();
+ w.oTag(i+3, "element")
+ .attr("name", XmlUtils.encodeElementName(getElementName(elementType)))
+ .attr("type", getXmlType(cNs, elementType))
+ .ceTag().nl();
+ w.oTag(i+3, "element")
+ .attr("name", "null")
+ .attr("type", "string")
+ .ceTag().nl();
+ w.eTag(i+2, "choice").nl();
+ w.eTag(i+1, "sequence").nl();
+ }
+
+ //----- Map -----
+ } else if (cm.isMap() || cm.hasToObjectMapMethod() || cm.isAbstract() || cm.isObject()) {
+ w.sTag(i+1, "sequence").nl();
+ w.oTag(i+2, "any")
+ .attr("processContents", "skip")
+ .attr("maxOccurs", "unbounded")
+ .attr("minOccurs", "0")
+ .ceTag().nl();
+ w.eTag(i+1, "sequence").nl();
+ }
+
+ if (ctx.isAddClassAttrs()) {
+ w.oTag(i+1, "attribute")
+ .attr("name", "_class")
+ .attr("type", "string")
+ .ceTag().nl();
+ }
+ if (ctx.isAddJsonTypeAttrs()) {
+ w.oTag(i+1, "attribute")
+ .attr("name", "type")
+ .attr("type", "string")
+ .ceTag().nl();
+ }
+ }
+
+ w.eTag(i, "complexType").nl();
+ schemas.processQueue();
+
+ return true;
+ }
+
+ private String getElementName(ClassMeta<?> cm) {
+ cm = cm.getFilteredClassMeta();
+ String name = cm.getXmlMeta().getElementName();
+
+ if (name == null) {
+ if (cm.isBoolean())
+ name = "boolean";
+ else if (cm.isNumber())
+ name = "number";
+ else if (cm.isArray() || cm.isCollection())
+ name = "array";
+ else if (! (cm.isMap() || cm.hasToObjectMapMethod() || cm.isBean() || cm.isCollection() || cm.isArray() || cm.isObject() || cm.isAbstract()))
+ name = "string";
+ else
+ name = "object";
+ }
+ return name;
+ }
+
+ @Override /* Object */
+ public String toString() {
+ try {
+ w.eTag(ctx.getIndent(), "schema").nl();
+ } catch (IOException e) {
+ throw new RuntimeException(e); // Shouldn't happen.
+ }
+ return sw.toString();
+ }
+
+ private String getXmlType(Namespace currentNs, ClassMeta<?> cm) {
+ String name = null;
+ cm = cm.getFilteredClassMeta();
+ if (currentNs == targetNs && ! ctx.isAddJsonTypeAttrs()) {
+ if (cm.isBoolean())
+ name = "boolean";
+ else if (cm.isNumber()) {
+ if (cm.isDecimal())
+ name = "decimal";
+ else
+ name = "integer";
+ }
+ if (name == null && ! ctx.isAddJsonStringTypeAttrs()) {
+ if (! (cm.isMap() || cm.hasToObjectMapMethod() || cm.isBean() || cm.isCollection() || cm.isArray() || cm.isObject() || cm.isAbstract()))
+ name = "string";
+ }
+ }
+ if (name == null) {
+ name = XmlUtils.encodeElementName(cm.toString());
+ schemas.queueType(currentNs, name, cm);
+ return currentNs.getName() + ":" + name;
+ }
+
+ return name;
+ }
+ }
+
+ private <T> T first(T...tt) {
+ for (T t : tt)
+ if (t != null)
+ return t;
+ return null;
+ }
+
+
+ private static String getXmlAttrType(ClassMeta<?> cm) {
+ if (cm.isBoolean())
+ return "boolean";
+ if (cm.isNumber()) {
+ if (cm.isDecimal())
+ return "decimal";
+ return "integer";
+ }
+ return "string";
+ }
+
+ @Override /* Serializer */
+ public XmlSerializerContext createContext(ObjectMap properties, Method javaMethod) {
+ // This serializer must always have namespaces enabled.
+ if (properties == null)
+ properties = new ObjectMap();
+ properties.put(XmlSerializerProperties.XML_enableNamespaces, true);
+ return new XmlSerializerContext(getBeanContext(), sp, xsp, properties, javaMethod);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$Simple.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$Simple.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$Simple.class
new file mode 100755
index 0000000..bc8d4b1
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$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/XmlSerializer$SimpleSq.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$SimpleSq.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$SimpleSq.class
new file mode 100755
index 0000000..3ddea63
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$SimpleSq.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/XmlSerializer$SimpleXmlJsonSq.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$SimpleXmlJsonSq.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$SimpleXmlJsonSq.class
new file mode 100755
index 0000000..d1b38a7
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$SimpleXmlJsonSq.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/XmlSerializer$Sq.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$Sq.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$Sq.class
new file mode 100755
index 0000000..2db7192
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$Sq.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/XmlSerializer$SqReadable.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$SqReadable.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$SqReadable.class
new file mode 100755
index 0000000..71e44be
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$SqReadable.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/XmlSerializer$XmlJson.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$XmlJson.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$XmlJson.class
new file mode 100755
index 0000000..8d4a34b
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$XmlJson.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/XmlSerializer$XmlJsonSq.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$XmlJsonSq.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$XmlJsonSq.class
new file mode 100755
index 0000000..4264fee
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer$XmlJsonSq.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/XmlSerializer.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer.class
new file mode 100755
index 0000000..221a0e7
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer.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/XmlSerializer.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer.java
new file mode 100755
index 0000000..8b75856
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializer.java
@@ -0,0 +1,725 @@
+/*******************************************************************************
+ * 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.serializer.SerializerProperties.*;
+import static com.ibm.juno.core.xml.XmlSerializerProperties.*;
+import static com.ibm.juno.core.xml.annotation.XmlFormat.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.annotation.*;
+import com.ibm.juno.core.filter.*;
+import com.ibm.juno.core.json.*;
+import com.ibm.juno.core.serializer.*;
+import com.ibm.juno.core.xml.annotation.*;
+
+/**
+ * Serializes POJO models to 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>
+ * See the {@link JsonSerializer} class for details on how Java models map to JSON.
+ * <p>
+ * For example, the following JSON...
+ * <p class='bcode'>
+ * {
+ * name:<js>'John Smith'</js>,
+ * address: {
+ * streetAddress: <js>'21 2nd Street'</js>,
+ * city: <js>'New York'</js>,
+ * state: <js>'NY'</js>,
+ * postalCode: <js>10021</js>
+ * },
+ * phoneNumbers: [
+ * <js>'212 555-1111'</js>,
+ * <js>'212 555-2222'</js>
+ * ],
+ * additionalInfo: <jk>null</jk>,
+ * remote: <jk>false</jk>,
+ * height: <js>62.4</js>,
+ * <js>'fico score'</js>: <js>' > 640'</js>
+ * }
+ * <p>
+ * ...maps to the following XML...
+ * <p class='bcode'>
+ * <xt><object></xt>
+ * <xt><name</xt> <xa>type</xa>=<xs>'string'</xs><xt>></xt>John Smith<xt></name></xt>
+ * <xt><address</xt> <xa>type</xa>=<xs>'object'</xs><xt>></xt>
+ * <xt><streetAddress</xt> <xa>type</xa>=<xs>'string'</xs><xt>></xt>21 2nd Street<xt></streetAddress></xt>
+ * <xt><city</xt> <xa>type</xa>=<xs>'string'</xs><xt>></xt>New York<xt></city></xt>
+ * <xt><state</xt> <xa>type</xa>=<xs>'string'</xs><xt>></xt>NY<xt></state></xt>
+ * <xt><postalCode</xt> <xa>type</xa>=<xs>'number'</xs><xt>></xt>10021<xt></postalCode></xt>
+ * <xt></address></xt>
+ * <xt><phoneNumbers</xt> <xa>type</xa>=<xs>'array'</xs><xt>></xt>
+ * <xt><string></xt>212 555-1111<xt></string></xt>
+ * <xt><string></xt>212 555-2222<xt></string></xt>
+ * <xt></phoneNumbers></xt>
+ * <xt><additionalInfo</xt> <xa>type</xa>=<xs>'null'</xs><xt>></additionalInfo></xt>
+ * <xt><remote</xt> <xa>type</xa>=<xs>'boolean'</xs><xt>></xt>false<xt></remote></xt>
+ * <xt><height</xt> <xa>type</xa>=<xs>'number'</xs><xt>></xt>62.4<xt></height></xt>
+ * <xt><fico_x0020_score</xt> <xa>type</xa>=<xs>'string'</xs><xt>></xt> &gt; 640<xt></fico_x0020_score></xt>
+ * <xt></object></xt>
+ * <p>
+ * This serializer provides several serialization options. Typically, one of the predefined <jsf>DEFAULT</jsf> serializers will be sufficient.
+ * However, custom serializers can be constructed to fine-tune behavior.
+ * <p>
+ * If an attribute name contains any non-valid XML element characters, they will be escaped using standard {@code _x####_} notation.
+ *
+ *
+ * <h6 class='topic'>Configurable properties</h6>
+ * <p>
+ * This class has the following properties associated with it:
+ * <ul>
+ * <li>{@link XmlSerializerProperties}
+ * <li>{@link SerializerProperties}
+ * <li>{@link BeanContextProperties}
+ * </ul>
+ *
+ *
+ * <h6 class='topic'>Behavior-specific subclasses</h6>
+ * <p>
+ * The following direct subclasses are provided for convenience:
+ * <ul>
+ * <li>{@link Sq} - Default serializer, single quotes.
+ * <li>{@link SqReadable} - Default serializer, single quotes, whitespace added.
+ * <li>{@link XmlJson} - Default serializer with JSON attribute tags.
+ * <li>{@link XmlJsonSq} - Default serializer with JSON attribute tags, single quotes.
+ * </ul>
+ *
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+@Produces("text/xml")
+public class XmlSerializer extends WriterSerializer {
+
+ /** Default serializer, all default settings. */
+ public static final XmlSerializer DEFAULT = new XmlSerializer().lock();
+
+ /** Default serializer, single quotes. */
+ public static final XmlSerializer DEFAULT_SQ = new XmlSerializer.Sq().lock();
+
+ /** Default serializer, single quotes, whitespace added. */
+ public static final XmlSerializer DEFAULT_SQ_READABLE = new XmlSerializer.SqReadable().lock();
+
+ /** Default serializer with JSON attribute tags. */
+ public static final XmlSerializer DEFAULT_XMLJSON = new XmlSerializer.XmlJson().lock();
+
+ /** Default serializer with JSON attribute tags, single quotes. */
+ public static final XmlSerializer DEFAULT_XMLJSON_SQ = new XmlSerializer.XmlJsonSq().lock();
+
+ /** Default serializer without namespaces. */
+ public static final XmlSerializer DEFAULT_SIMPLE = new XmlSerializer.Simple().lock();
+
+ /** Default serializer without namespaces, with single quotes. */
+ public static final XmlSerializer DEFAULT_SIMPLE_SQ = new XmlSerializer.SimpleSq().lock();
+
+ /** Default serializer without namespaces, with JSON attribute tags and single quotes. */
+ public static final XmlSerializer DEFAULT_SIMPLE_XMLJSON_SQ = new XmlSerializer.SimpleXmlJsonSq().lock();
+
+
+ /** Default serializer, single quotes. */
+ public static class Sq extends XmlSerializer {
+ /** Constructor */
+ public Sq() {
+ setProperty(SERIALIZER_quoteChar, '\'');
+ }
+ }
+
+ /** Default serializer, single quotes, whitespace added. */
+ public static class SqReadable extends Sq {
+ /** Constructor */
+ public SqReadable() {
+ setProperty(SERIALIZER_useIndentation, true);
+ }
+ }
+
+ /** Default serializer with JSON attribute tags. */
+ @Produces(value="text/xml+json",contentType="text/xml")
+ public static class XmlJson extends XmlSerializer {
+ /** Constructor */
+ public XmlJson() {
+ setProperty(XML_addJsonTypeAttrs, true);
+ }
+ }
+
+ /** Default serializer with JSON attribute tags, single quotes. */
+ public static class XmlJsonSq extends XmlJson {
+ /** Constructor */
+ public XmlJsonSq() {
+ setProperty(SERIALIZER_quoteChar, '\'');
+ }
+ }
+
+ /** Default serializer without namespaces. */
+ @Produces(value="text/xml+simple",contentType="text/xml")
+ public static class Simple extends XmlSerializer {
+ /** Constructor */
+ public Simple() {
+ setProperty(XML_enableNamespaces, false);
+ }
+ }
+
+ /** Default serializer without namespaces, single quotes. */
+ public static class SimpleSq extends Simple {
+ /** Constructor */
+ public SimpleSq() {
+ setProperty(SERIALIZER_quoteChar, '\'');
+ }
+ }
+
+ /** Default serializer with JSON attribute tags, single quotes. */
+ public static class SimpleXmlJsonSq extends SimpleSq {
+ /** Constructor */
+ public SimpleXmlJsonSq() {
+ setProperty(XML_addJsonTypeAttrs, true);
+ }
+ }
+
+ /** XML serializer properties currently set on this serializer. */
+ protected transient XmlSerializerProperties xsp = new XmlSerializerProperties();
+
+
+ /**
+ * Recursively searches for the XML namespaces on the specified POJO and adds them to the serializer context object.
+ *
+ * @param o The POJO to check.
+ * @param ctx The context that exists for the duration of a single serialization.
+ * @throws SerializeException
+ */
+ protected void findNsfMappings(Object o, XmlSerializerContext ctx) throws SerializeException {
+ BeanContext bc = ctx.getBeanContext();
+ ClassMeta<?> aType = null; // The actual type
+ aType = ctx.push(null, o, null);
+
+ if (aType != null) {
+ Namespace ns = aType.getXmlMeta().getNamespace();
+ if (ns != null) {
+ if (ns.uri != null)
+ ctx.addNamespace(ns);
+ else
+ ns = null;
+ }
+ }
+
+ // Handle recursion
+ if (aType != null && ! aType.isPrimitive()) {
+
+ BeanMap bm = null;
+ if (aType.isBeanMap()) {
+ bm = (BeanMap)o;
+ } else if (aType.isBean()) {
+ bm = bc.forBean(o);
+ } else if (aType.isDelegate()) {
+ ClassMeta innerType = ((Delegate)o).getClassMeta();
+ Namespace ns = innerType.getXmlMeta().getNamespace();
+ if (ns != null) {
+ if (ns.uri != null)
+ ctx.addNamespace(ns);
+ else
+ ns = null;
+ }
+
+ if (innerType.isBean()) {
+ for (BeanPropertyMeta bpm : (Collection<BeanPropertyMeta>)innerType.getBeanMeta().getPropertyMetas()) {
+ ns = bpm.getXmlMeta().getNamespace();
+ if (ns != null && ns.uri != null)
+ ctx.addNamespace(ns);
+ }
+
+ } else if (innerType.isMap()) {
+ for (Object o2 : ((Map)o).values())
+ findNsfMappings(o2, ctx);
+ } else if (innerType.isCollection()) {
+ for (Object o2 : ((Collection)o))
+ findNsfMappings(o2, ctx);
+ }
+
+ } else if (aType.isMap()) {
+ for (Object o2 : ((Map)o).values())
+ findNsfMappings(o2, ctx);
+ } else if (aType.isCollection()) {
+ for (Object o2 : ((Collection)o))
+ findNsfMappings(o2, ctx);
+ } else if (aType.isArray() && ! aType.getElementType().isPrimitive()) {
+ for (Object o2 : ((Object[])o))
+ findNsfMappings(o2, ctx);
+ }
+ if (bm != null) {
+ for (BeanMapEntry p : (Set<BeanMapEntry>)bm.entrySet()) {
+
+ Namespace ns = p.getMeta().getXmlMeta().getNamespace();
+ if (ns != null && ns.uri != null)
+ ctx.addNamespace(ns);
+
+ try {
+ findNsfMappings(p.getValue(), ctx);
+ } catch (Throwable x) {
+ // Ignore
+ }
+ }
+ }
+ }
+
+ ctx.pop();
+ }
+
+ /**
+ * Workhorse method.
+ *
+ * @param out The writer to send the output to.
+ * @param o The object to serialize.
+ * @param eType The expected type if this is a bean property value being serialized.
+ * @param ctx The serializer context.
+ * @param elementName The root element name.
+ * @param elementNamespace The namespace of the element.
+ * @param addNamespaceUris Flag indicating that namespace URIs need to be added.
+ * @param format The format to serialize the output to.
+ * @param pMeta The bean property metadata if this is a bean property being serialized.
+ * @return The same writer passed in so that calls to the writer can be chained.
+ * @throws IOException If a problem occurred trying to write to the writer.
+ * @throws SerializeException If a problem occurred trying to convert the output.
+ */
+ protected XmlSerializerWriter serializeAnything(XmlSerializerWriter out, Object o, ClassMeta eType,
+ XmlSerializerContext ctx, String elementName, Namespace elementNamespace, boolean addNamespaceUris,
+ XmlFormat format, BeanPropertyMeta<?> pMeta) throws IOException, SerializeException {
+
+ BeanContext bc = ctx.getBeanContext();
+ String ts = null; // The type string (e.g. <type> or <x x='type'>
+ int indent = ctx.indent; // Current indentation
+ ClassMeta<?> aType = null; // The actual type
+ ClassMeta<?> wType = null; // The wrapped type
+ ClassMeta<?> gType = object(); // The generic type
+
+ aType = ctx.push(elementName, o, eType);
+
+ if (eType == null)
+ eType = object();
+
+ // Handle recursion
+ if (aType == null) {
+ o = null;
+ aType = object();
+ }
+
+ if (o != null) {
+
+ if (aType.isDelegate()) {
+ wType = aType;
+ aType = ((Delegate)o).getClassMeta();
+ }
+
+ gType = aType.getFilteredClassMeta();
+
+ // Filter if necessary
+ PojoFilter filter = aType.getPojoFilter();
+ if (filter != null) {
+ o = filter.filter(o);
+
+ // If the filter's getFilteredClass() method returns Object, we need to figure out
+ // the actual type now.
+ if (gType.isObject())
+ gType = bc.getClassMetaForObject(o);
+ }
+ } else {
+ gType = eType.getFilteredClassMeta();
+ }
+
+ String classAttr = null;
+ if (ctx.isAddClassAttrs()) {
+ if (o != null && ! eType.equals(aType))
+ classAttr = aType.toString();
+ else if (o == null)
+ classAttr = eType.toString();
+ }
+
+ // char '\0' is interpreted as null.
+ if (o != null && gType.isChar() && ((Character)o).charValue() == 0)
+ o = null;
+
+ boolean isCollapsed = false; // If 'true', this is a collection and we're not rendering the outer element.
+
+ // Get the JSON type string.
+ if (gType.isCharSequence() || gType.isChar())
+ ts = "string";
+ else if (gType.isNumber())
+ ts = "number";
+ else if (gType.isBoolean())
+ ts = "boolean";
+ else if (gType.isMap() || gType.isBean() || gType.hasToObjectMapMethod()) {
+ isCollapsed = gType.getXmlMeta().getFormat() == XmlFormat.COLLAPSED;
+ ts = "object";
+ }
+ else if (gType.isCollection() || gType.isArray()) {
+ isCollapsed = (format == COLLAPSED && ! addNamespaceUris);
+ ts = "array";
+ }
+ else
+ ts = "string";
+
+
+ // Is there a name associated with this bean?
+ if (elementName == null)
+ elementName = gType.getXmlMeta().getElementName();
+ if (elementName == null)
+ elementName = aType.getXmlMeta().getElementName();
+
+ // If the value is null then it's either going to be <null/> or <XmlSerializer nil='true'/>
+ // depending on whether the element has a name.
+ boolean isNullTag = (elementName == null && o == null);
+
+ if (isNullTag)
+ ts = "null";
+
+ if (ctx.isEnableNamespaces()) {
+ if (elementNamespace == null)
+ elementNamespace = gType.getXmlMeta().getNamespace();
+ if (elementNamespace == null)
+ elementNamespace = aType.getXmlMeta().getNamespace();
+ if (elementNamespace != null && elementNamespace.uri == null)
+ elementNamespace = null;
+ if (elementNamespace == null)
+ elementNamespace = ctx.getDefaultNamespace();
+ } else {
+ elementNamespace = null;
+ }
+
+ // Do we need a carriage return after the start tag?
+ boolean cr = o != null && (gType.isMap() || gType.isCollection() || gType.isArray() || gType.isBean() || gType.hasToObjectMapMethod());
+
+ String en = (elementName == null ? ts : elementName);
+ boolean encodeEn = elementName != null;
+ String ns = (elementNamespace == null ? null : elementNamespace.name);
+ String xsi = null, dns = null, elementNs = null;
+ if (ctx.isEnableNamespaces()) {
+ xsi = ctx.getXsiNamespace().name;
+ dns = elementName == null && ctx.getDefaultNamespace() != null ? ctx.getDefaultNamespace().name : null;
+ elementNs = elementName == null ? dns : ns;
+ if (elementName == null)
+ elementNamespace = null;
+ }
+
+ // Render the start tag.
+ if (! isCollapsed) {
+ out.oTag(indent, elementNs, en, encodeEn);
+ if (addNamespaceUris) {
+ out.attr((String)null, "xmlns", ctx.getDefaultNamespace().getUri());
+
+ for (Namespace n : ctx.getNamespaces())
+ out.attr("xmlns", n.getName(), n.getUri());
+
+ Namespace xsiNs = ctx.getXsiNamespace();
+ if (xsiNs != null)
+ out.attr("xmlns", xsiNs.name, xsiNs.uri);
+ }
+ if (elementName != null && ctx.isAddJsonTypeAttrs() && (ctx.isAddJsonStringTypeAttrs() || ! ts.equals("string")))
+ out.attr(dns, "type", ts);
+ if (classAttr != null)
+ out.attr(dns, "_class", classAttr);
+ if (o == null) {
+ if (! isNullTag)
+ out.attr(xsi, "nil", "true");
+ if ((gType.isBoolean() || gType.isNumber()) && ! gType.isNullable())
+ o = gType.getPrimitiveDefault();
+ }
+
+ if (o != null && !(gType.isMap() || gType.isBean() || gType.hasToObjectMapMethod()))
+ out.append('>');
+
+ if (cr && !(gType.isMap() || gType.isBean() || gType.hasToObjectMapMethod()))
+ out.nl();
+ }
+
+ boolean hasChildren = true;
+
+ // Render the tag contents.
+ if (o != null) {
+ if (gType.isUri() || (pMeta != null && pMeta.isUri()))
+ out.appendUri(o);
+ else if (gType.isCharSequence() || gType.isChar())
+ out.encodeText(o);
+ else if (gType.isNumber() || gType.isBoolean())
+ out.append(o);
+ else if (gType.isMap() || (wType != null && wType.isMap())) {
+ if (o instanceof BeanMap)
+ hasChildren = serializeBeanMap(out, (BeanMap)o, elementNamespace, ctx, isCollapsed);
+ else
+ hasChildren = serializeMap(out, (Map)o, gType, ctx);
+ }
+ else if (gType.hasToObjectMapMethod())
+ hasChildren = serializeMap(out, gType.toObjectMap(o), gType, ctx);
+ else if (gType.isBean())
+ hasChildren = serializeBeanMap(out, bc.forBean(o), elementNamespace, ctx, isCollapsed);
+ else if (gType.isCollection() || (wType != null && wType.isCollection())) {
+ if (isCollapsed)
+ ctx.indent--;
+ serializeCollection(out, (Collection)o, gType, ctx, pMeta);
+ if (isCollapsed)
+ ctx.indent++;
+ }
+ else if (gType.isArray()) {
+ if (isCollapsed)
+ ctx.indent--;
+ serializeCollection(out, toList(gType.getInnerClass(), o), gType, ctx, pMeta);
+ if (isCollapsed)
+ ctx.indent++;
+ }
+ else
+ out.encodeText(o);
+ }
+
+ ctx.pop();
+
+ // Render the end tag.
+ if (! isCollapsed) {
+ if (o == null || ! hasChildren)
+ out.append('/').append('>').nl();
+ else
+ out.i(cr ? indent : 0).eTag(elementNs, en, encodeEn).nl();
+ }
+
+ return out;
+ }
+
+ private boolean serializeMap(XmlSerializerWriter out, Map m, ClassMeta<?> type, XmlSerializerContext ctx) throws IOException, SerializeException {
+
+ m = sort(ctx, m);
+
+ ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType();
+
+ boolean hasChildren = false;
+ for (Iterator i = m.entrySet().iterator(); i.hasNext();) {
+ Map.Entry e = (Map.Entry)i.next();
+
+ Object k = e.getKey();
+ if (k == null) {
+ k = "\u0000";
+ } else {
+ k = generalize(ctx, k, keyType);
+ }
+
+ Object value = e.getValue();
+
+ if (! hasChildren) {
+ hasChildren = true;
+ out.append('>').nl();
+ }
+ serializeAnything(out, value, valueType, ctx, k.toString(), null, false, NORMAL, null);
+ }
+ return hasChildren;
+ }
+
+ private boolean serializeBeanMap(XmlSerializerWriter out, BeanMap m, Namespace elementNs, XmlSerializerContext ctx, boolean isCollapsed) throws IOException, SerializeException {
+ boolean hasChildren = false;
+ BeanMeta bm = m.getMeta();
+
+ Map<String,BeanPropertyMeta> xmlAttrs = bm.getXmlMeta().getXmlAttrProperties();
+ Object content = null;
+ for (BeanPropertyMeta p : xmlAttrs.values()) {
+
+ String key = p.getName();
+ Object value = null;
+ try {
+ value = p.get(m);
+ } catch (StackOverflowError e) {
+ throw e;
+ } catch (Throwable x) {
+ ctx.addBeanGetterWarning(p, x);
+ }
+
+ if (canIgnoreValue(ctx, p.getClassMeta(), key, value))
+ continue;
+
+ Namespace ns = (ctx.isEnableNamespaces() && p.getXmlMeta().getNamespace() != elementNs ? p.getXmlMeta().getNamespace() : null);
+
+ if (p.isBeanUri() || p.isUri())
+ out.attrUri(ns, key, value);
+ else
+ out.attr(ns, key, value);
+ }
+
+ boolean hasContent = false;
+
+ for (BeanMapEntry p : (Set<BeanMapEntry>)m.entrySet()) {
+ BeanPropertyMeta pMeta = p.getMeta();
+ XmlFormat xf = pMeta.getXmlMeta().getXmlFormat();
+
+ if (xf == CONTENT) {
+ content = p.getValue();
+ hasContent = true;
+ } else if (xf == ATTR) {
+ // Do nothing
+ } else {
+ String key = p.getKey();
+ Object value = null;
+ try {
+ value = p.getValue();
+ } catch (StackOverflowError e) {
+ throw e;
+ } catch (Throwable x) {
+ ctx.addWarning("Could not call getValue() on property ''{0}'', {1}", key, x.getLocalizedMessage());
+ }
+
+ if (canIgnoreValue(ctx, pMeta.getClassMeta(), key, value))
+ continue;
+
+ if (! hasChildren) {
+ hasChildren = true;
+ out.appendIf(! isCollapsed, '>').nl();
+ }
+ serializeAnything(out, value, pMeta.getClassMeta(), ctx, key, pMeta.getXmlMeta().getNamespace(), false, pMeta.getXmlMeta().getXmlFormat(), pMeta);
+ }
+ }
+ if ((! hasContent) || canIgnoreValue(ctx, string(), null, content))
+ return hasChildren;
+ out.append(">").cr(ctx.indent);
+
+ // Serialize XML content.
+ XmlContentHandler h = bm.getXmlMeta().getXmlContentHandler();
+ if (h != null)
+ try {
+ h.serialize(out, m.getBean());
+ } catch (Exception e) {
+ throw new SerializeException(e);
+ }
+ else
+ out.encodeText(content);
+ out.nl();
+ return true;
+ }
+
+ private XmlSerializerWriter serializeCollection(XmlSerializerWriter out, Collection c, ClassMeta<?> type, XmlSerializerContext ctx, BeanPropertyMeta<?> ppMeta) throws IOException, SerializeException {
+
+ c = sort(ctx, c);
+
+ ClassMeta<?> elementType = type.getElementType();
+
+ String eName = null;
+ Namespace eNs = null;
+
+ if (ppMeta != null) {
+ eName = ppMeta.getXmlMeta().getChildName();
+ eNs = ppMeta.getXmlMeta().getNamespace();
+ }
+
+ if (eName == null) {
+ eName = type.getXmlMeta().getChildName();
+ eNs = type.getXmlMeta().getNamespace();
+ }
+
+ if (eName == null && ! elementType.isObject()) {
+ eName = elementType.getXmlMeta().getElementName();
+ eNs = elementType.getXmlMeta().getNamespace();
+ }
+
+ for (Iterator i = c.iterator(); i.hasNext();) {
+ Object value = i.next();
+ serializeAnything(out, value, elementType, ctx, eName, eNs, false, NORMAL, null);
+ }
+ return out;
+ }
+
+ /**
+ * Returns the schema serializer based on the settings of this serializer.
+ * @return The schema serializer.
+ */
+ public XmlSerializer getSchemaSerializer() {
+ XmlSchemaSerializer s = new XmlSchemaSerializer();
+ s.beanContextFactory = this.beanContextFactory;
+ s.sp = this.sp;
+ s.xsp = this.xsp;
+ return s;
+ }
+
+
+ //--------------------------------------------------------------------------------
+ // Overridden methods
+ //--------------------------------------------------------------------------------
+
+ @Override /* Serializer */
+ protected void doSerialize(Object o, Writer out, SerializerContext ctx) throws IOException, SerializeException {
+ XmlSerializerContext xctx = (XmlSerializerContext)ctx;
+ if (xctx.isEnableNamespaces() && xctx.isAutoDetectNamespaces())
+ findNsfMappings(o, xctx);
+ serializeAnything(xctx.getWriter(out), o, null, xctx, null, null, xctx.isEnableNamespaces() && xctx.isAddNamespaceUrlsToRoot(), NORMAL, null);
+ }
+
+ @Override /* Serializer */
+ public XmlSerializerContext createContext(ObjectMap properties, Method javaMethod) {
+ return new XmlSerializerContext(getBeanContext(), sp, xsp, properties, javaMethod);
+ }
+
+ @Override /* CoreApi */
+ public XmlSerializer setProperty(String property, Object value) throws LockedException {
+ checkLock();
+ if (! xsp.setProperty(property, value))
+ super.setProperty(property, value);
+ return this;
+ }
+
+ @Override /* CoreApi */
+ public XmlSerializer setProperties(ObjectMap properties) throws LockedException {
+ for (Map.Entry<String,Object> e : properties.entrySet())
+ setProperty(e.getKey(), e.getValue());
+ return this;
+ }
+
+ @Override /* CoreApi */
+ public XmlSerializer addNotBeanClasses(Class<?>...classes) throws LockedException {
+ super.addNotBeanClasses(classes);
+ return this;
+ }
+
+ @Override /* CoreApi */
+ public XmlSerializer addFilters(Class<?>...classes) throws LockedException {
+ super.addFilters(classes);
+ return this;
+ }
+
+ @Override /* CoreApi */
+ public <T> XmlSerializer addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
+ super.addImplClass(interfaceClass, implClass);
+ return this;
+ }
+
+ @Override /* CoreApi */
+ public XmlSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
+ super.setClassLoader(classLoader);
+ return this;
+ }
+
+ @Override /* Lockable */
+ public XmlSerializer lock() {
+ super.lock();
+ return this;
+ }
+
+ @Override /* Lockable */
+ public XmlSerializer clone() {
+ try {
+ XmlSerializer c = (XmlSerializer)super.clone();
+ c.xsp = xsp.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/XmlSerializerContext.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializerContext.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializerContext.class
new file mode 100755
index 0000000..16e777a
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializerContext.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/XmlSerializerContext.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializerContext.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializerContext.java
new file mode 100755
index 0000000..0ea37fa
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializerContext.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * 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.xml.NamespaceFactory.*;
+import static com.ibm.juno.core.xml.XmlSerializerProperties.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+
+import com.ibm.juno.core.*;
+import com.ibm.juno.core.serializer.*;
+import com.ibm.juno.core.utils.*;
+
+/**
+ * Context object that lives for the duration of a single serialization of the {@link XmlSerializer}.
+ * <p>
+ * See {@link SerializerContext} for details.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+@SuppressWarnings("hiding")
+public class XmlSerializerContext extends SerializerContext {
+
+ private final boolean
+ addJsonTypeAttrs,
+ addJsonStringTypeAttrs,
+ autoDetectNamespaces,
+ enableNamespaces,
+ addNamespaceUrlsToRoot;
+
+ private Namespace
+ defaultNamespace,
+ xsiNamespace,
+ xsNamespace;
+
+ private Namespace[] namespaces = new Namespace[0];
+
+ /**
+ * Constructor.
+ * @param beanContext The bean context being used by the serializer.
+ * @param sp Default general serializer properties.
+ * @param xsp Default XML serializer properties.
+ * @param op Override properties.
+ * @param javaMethod Java method that invoked this serializer.
+ * When using the REST API, this is the Java method invoked by the REST call.
+ * Can be used to access annotations defined on the method or class.
+ */
+ public XmlSerializerContext(BeanContext beanContext, SerializerProperties sp, XmlSerializerProperties xsp, ObjectMap op, Method javaMethod) {
+ super(beanContext, sp, op, javaMethod);
+ if (op == null || op.isEmpty()) {
+ addJsonTypeAttrs = xsp.addJsonTypeAttrs;
+ addJsonStringTypeAttrs = xsp.addJsonStringTypeAttrs;
+ enableNamespaces = xsp.enableNamespaces;
+ autoDetectNamespaces = xsp.autoDetectNamespaces;
+ addNamespaceUrlsToRoot = xsp.addNamespaceUrlsToRoot;
+ addNamespaces(xsp.namespaces);
+ setDefaultNamespace(xsp.defaultNamespace);
+ xsiNamespace = xsp.xsiNamespace;
+ xsNamespace = xsp.xsNamespace;
+ } else {
+ addJsonTypeAttrs = op.getBoolean(XML_addJsonTypeAttrs, xsp.addJsonTypeAttrs);
+ addJsonStringTypeAttrs = op.getBoolean(XML_addJsonStringTypeAttrs, xsp.addJsonStringTypeAttrs);
+ enableNamespaces = op.getBoolean(XML_enableNamespaces, xsp.enableNamespaces);
+ autoDetectNamespaces = op.getBoolean(XML_autoDetectNamespaces, xsp.autoDetectNamespaces);
+ addNamespaceUrlsToRoot = op.getBoolean(XML_addNamespaceUrisToRoot, xsp.addNamespaceUrlsToRoot);
+ namespaces = (op.containsKey(XML_namespaces) ? parseNamespaces(op.get(XML_namespaces)) : xsp.namespaces);
+ setDefaultNamespace(op.containsKey(XML_defaultNamespaceUri) ? op.getString(XML_defaultNamespaceUri) : xsp.defaultNamespace);
+ xsiNamespace = (op.containsKey(XML_xsiNamespace) ? parseNamespace(op.get(XML_xsiNamespace)) : xsp.xsiNamespace);
+ xsNamespace = (op.containsKey(XML_xsNamespace) ? parseNamespace(op.get(XML_xsNamespace)) : xsp.xsNamespace);
+ }
+ }
+
+ private void setDefaultNamespace(String s) {
+ if (s == null)
+ return;
+ if (StringUtils.startsWith(s, '{'))
+ defaultNamespace = parseNamespace(s);
+ else if (! s.startsWith("http://"))
+ defaultNamespace = get(s, "http://unknown");
+ else
+ defaultNamespace = get(null, s);
+ }
+
+ private void addNamespaces(Namespace...namespaces) {
+ for (Namespace ns : namespaces)
+ addNamespace(ns);
+ }
+
+ void addNamespace(Namespace ns) {
+ if (ns == defaultNamespace)
+ return;
+
+ for (Namespace n : namespaces)
+ if (n == ns)
+ return;
+
+ if (defaultNamespace != null && (ns.uri.equals(defaultNamespace.uri) || ns.name.equals(defaultNamespace.name)))
+ defaultNamespace = ns;
+ else
+ namespaces = ArrayUtils.append(namespaces, ns);
+ }
+
+ /**
+ * Returns the list of namespaces being used in the current XML serialization.
+ *
+ * @return The list of namespaces being used in the current XML serialization.
+ */
+ public Namespace[] getNamespaces() {
+ return namespaces;
+ }
+
+ /**
+ * Returns the {@link XmlSerializerProperties#XML_addJsonTypeAttrs} setting value in this context.
+ *
+ * @return The {@link XmlSerializerProperties#XML_addJsonTypeAttrs} setting value in this context.
+ */
+ public final boolean isAddJsonTypeAttrs() {
+ return addJsonTypeAttrs;
+ }
+
+ /**
+ * Returns the {@link XmlSerializerProperties#XML_addJsonStringTypeAttrs} setting value in this context.
+ *
+ * @return The {@link XmlSerializerProperties#XML_addJsonStringTypeAttrs} setting value in this context.
+ */
+ public final boolean isAddJsonStringTypeAttrs() {
+ return addJsonStringTypeAttrs;
+ }
+
+ /**
+ * Returns the {@link XmlSerializerProperties#XML_autoDetectNamespaces} setting value in this context.
+ *
+ * @return The {@link XmlSerializerProperties#XML_autoDetectNamespaces} setting value in this context.
+ */
+ public final boolean isAutoDetectNamespaces() {
+ return enableNamespaces && autoDetectNamespaces;
+ }
+
+ /**
+ * Returns the {@link XmlSerializerProperties#XML_enableNamespaces} setting value in this context.
+ *
+ * @return The {@link XmlSerializerProperties#XML_enableNamespaces} setting value in this context.
+ */
+ public final boolean isEnableNamespaces() {
+ return enableNamespaces;
+ }
+
+ /**
+ * Returns the {@link XmlSerializerProperties#XML_addNamespaceUrisToRoot} setting value in this context.
+ *
+ * @return The {@link XmlSerializerProperties#XML_addNamespaceUrisToRoot} setting value in this context.
+ */
+ public final boolean isAddNamespaceUrlsToRoot() {
+ return addNamespaceUrlsToRoot;
+ }
+
+ /**
+ * Returns the {@link XmlSerializerProperties#XML_defaultNamespaceUri} setting value in this context.
+ *
+ * @return The {@link XmlSerializerProperties#XML_defaultNamespaceUri} setting value in this context.
+ */
+ public final Namespace getDefaultNamespace() {
+ return defaultNamespace;
+ }
+
+ /**
+ * Returns the {@link XmlSerializerProperties#XML_xsiNamespace} setting value in this context.
+ *
+ * @return The {@link XmlSerializerProperties#XML_xsiNamespace} setting value in this context.
+ */
+ public final Namespace getXsiNamespace() {
+ return xsiNamespace;
+ }
+
+ /**
+ * Returns the {@link XmlSerializerProperties#XML_xsNamespace} setting value in this context.
+ *
+ * @return The {@link XmlSerializerProperties#XML_xsNamespace} setting value in this context.
+ */
+ public final Namespace getXsNamespace() {
+ return xsNamespace;
+ }
+
+ /**
+ * Wraps the specified writer in a {@link XmlSerializerWriter} if it is not already an instance of that class.
+ *
+ * @param out The writer being wrapped.
+ * @return The wrapped writer.
+ */
+ public XmlSerializerWriter getWriter(Writer out) {
+ if (out instanceof XmlSerializerWriter)
+ return (XmlSerializerWriter)out;
+ return new XmlSerializerWriter(out, isUseIndentation(), getQuoteChar(), getRelativeUriBase(), getAbsolutePathUriBase(), isEnableNamespaces(), getDefaultNamespace());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializerProperties.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializerProperties.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializerProperties.class
new file mode 100755
index 0000000..1fa4859
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/xml/XmlSerializerProperties.class differ