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:58 UTC
[09/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/urlencoding/UrlEncodingSerializer.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/UrlEncodingSerializer.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/UrlEncodingSerializer.java
new file mode 100755
index 0000000..e4894df
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/UrlEncodingSerializer.java
@@ -0,0 +1,515 @@
+/*******************************************************************************
+ * 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.urlencoding;
+
+import static com.ibm.juno.core.urlencoding.UonSerializerProperties.*;
+import static com.ibm.juno.core.urlencoding.UrlEncodingProperties.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.*;
+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.serializer.*;
+import com.ibm.juno.core.utils.*;
+
+/**
+ * Serializes POJO models to URL-encoded notation with UON-encoded values (a notation for URL-encoded query paramter values).
+ *
+ *
+ * <h6 class='topic'>Media types</h6>
+ * <p>
+ * Handles <code>Accept</code> types: <code>application/x-www-form-urlencoded</code>
+ * <p>
+ * Produces <code>Content-Type</code> types: <code>application/x-www-form-urlencoded</code>
+ *
+ *
+ * <h6 class='topic'>Description</h6>
+ * <p>
+ * This serializer provides several serialization options. Typically, one of the predefined DEFAULT serializers will be sufficient.
+ * However, custom serializers can be constructed to fine-tune behavior.
+ *
+ *
+ * <h6 class='topic'>Configurable properties</h6>
+ * <p>
+ * This class has the following properties associated with it:
+ * <ul>
+ * <li>{@link UonSerializerProperties}
+ * <li>{@link SerializerProperties}
+ * <li>{@link BeanContextProperties}
+ * </ul>
+ * <p>
+ * The following shows a sample object defined in Javascript:
+ * </p>
+ * <p class='bcode'>
+ * {
+ * id: 1,
+ * name: <js>'John Smith'</js>,
+ * uri: <js>'http://sample/addressBook/person/1'</js>,
+ * addressBookUri: <js>'http://sample/addressBook'</js>,
+ * birthDate: <js>'1946-08-12T00:00:00Z'</js>,
+ * otherIds: <jk>null</jk>,
+ * addresses: [
+ * {
+ * uri: <js>'http://sample/addressBook/address/1'</js>,
+ * personUri: <js>'http://sample/addressBook/person/1'</js>,
+ * id: 1,
+ * street: <js>'100 Main Street'</js>,
+ * city: <js>'Anywhereville'</js>,
+ * state: <js>'NY'</js>,
+ * zip: 12345,
+ * isCurrent: <jk>true</jk>,
+ * }
+ * ]
+ * }
+ * </p>
+ * <p>
+ * Using the "strict" syntax defined in this document, the equivalent
+ * URL-encoded notation would be as follows:
+ * </p>
+ * <p class='bcode'>
+ * <xa>id</xa>=$n(<xs>1</xs>)
+ * &<xa>name</xa>=<xs>John+Smith</xs>,
+ * &<xa>uri</xa>=<xs>http://sample/addressBook/person/1</xs>,
+ * &<xa>addressBookUri</xa>=<xs>http://sample/addressBook</xs>,
+ * &<xa>birthDate</xa>=<xs>1946-08-12T00:00:00Z</xs>,
+ * &<xa>otherIds</xa>=<xs>%00</xs>,
+ * &<xa>addresses</xa>=$a(
+ * $o(
+ * <xa>uri</xa>=<xs>http://sample/addressBook/address/1</xs>,
+ * <xa>personUri</xa>=<xs>http://sample/addressBook/person/1</xs>,
+ * <xa>id</xa>=$n(<xs>1</xs>),
+ * <xa>street</xa>=<xs>100+Main+Street</xs>,
+ * <xa>city</xa>=<xs>Anywhereville</xs>,
+ * <xa>state</xa>=<xs>NY</xs>,
+ * <xa>zip</xa>=$n(<xs>12345</xs>),
+ * <xa>isCurrent</xa>=$b(<xs>true</xs>)
+ * )
+ * )
+ * </p>
+ * <p>
+ * A secondary "lax" syntax is available when the data type of the
+ * values are already known on the receiving end of the transmission:
+ * </p>
+ * <p class='bcode'>
+ * <xa>id</xa>=<xs>1</xs>,
+ * &<xa>name</xa>=<xs>John+Smith</xs>,
+ * &<xa>uri</xa>=<xs>http://sample/addressBook/person/1</xs>,
+ * &<xa>addressBookUri</xa>=<xs>http://sample/addressBook</xs>,
+ * &<xa>birthDate</xa>=<xs>1946-08-12T00:00:00Z</xs>,
+ * &<xa>otherIds</xa>=<xs>%00</xs>,
+ * &<xa>addresses</xa>=(
+ * (
+ * <xa>uri</xa>=<xs>http://sample/addressBook/address/1</xs>,
+ * <xa>personUri</xa>=<xs>http://sample/addressBook/person/1</xs>,
+ * <xa>id</xa>=<xs>1</xs>,
+ * <xa>street</xa>=<xs>100+Main+Street</xs>,
+ * <xa>city</xa>=<xs>Anywhereville</xs>,
+ * <xa>state</xa>=<xs>NY</xs>,
+ * <xa>zip</xa>=<xs>12345</xs>,
+ * <xa>isCurrent</xa>=<xs>true</xs>
+ * )
+ * )
+ * </p>
+ *
+ *
+ * <h6 class='topic'>Examples</h6>
+ * <p class='bcode'>
+ * <jc>// Serialize a Map</jc>
+ * Map m = <jk>new</jk> ObjectMap(<js>"{a:'b',c:1,d:false,e:['f',1,false],g:{h:'i'}}"</js>);
+ *
+ * <jc>// Serialize to value equivalent to JSON.</jc>
+ * <jc>// Produces "a=b&c=$n(1)&d=$b(false)&e=$a(f,$n(1),$b(false))&g=$o(h=i)"</jc>
+ * String s = UrlEncodingSerializer.<jsf>DEFAULT</jsf>.serialize(s);
+ *
+ * <jc>// Serialize to simplified value (for when data type is already known by receiver).</jc>
+ * <jc>// Produces "a=b&c=1&d=false&e=(f,1,false)&g=(h=i))"</jc>
+ * String s = UrlEncodingSerializer.<jsf>DEFAULT_SIMPLE</jsf>.serialize(s);
+ *
+ * <jc>// Serialize a bean</jc>
+ * <jk>public class</jk> Person {
+ * <jk>public</jk> Person(String s);
+ * <jk>public</jk> String getName();
+ * <jk>public int</jk> getAge();
+ * <jk>public</jk> Address getAddress();
+ * <jk>public boolean</jk> deceased;
+ * }
+ *
+ * <jk>public class</jk> Address {
+ * <jk>public</jk> String getStreet();
+ * <jk>public</jk> String getCity();
+ * <jk>public</jk> String getState();
+ * <jk>public int</jk> getZip();
+ * }
+ *
+ * Person p = <jk>new</jk> Person(<js>"John Doe"</js>, 23, <js>"123 Main St"</js>, <js>"Anywhere"</js>, <js>"NY"</js>, 12345, <jk>false</jk>);
+ *
+ * <jc>// Produces "name=John+Doe&age=23&address=$o(street=123+Main+St,city=Anywhere,state=NY,zip=$n(12345))&deceased=$b(false)"</jc>
+ * String s = UrlEncodingSerializer.<jsf>DEFAULT</jsf>.serialize(s);
+ *
+ * <jc>// Produces "name=John+Doe&age=23&address=(street=123+Main+St,city=Anywhere,state=NY,zip=12345)&deceased=false)"</jc>
+ * String s = UrlEncodingSerializer.<jsf>DEFAULT_SIMPLE</jsf>.serialize(s);
+ * </p>
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+@Produces("application/x-www-form-urlencoded")
+@SuppressWarnings("hiding")
+public class UrlEncodingSerializer extends UonSerializer {
+
+ /** Reusable instance of {@link UrlEncodingSerializer}, all default settings. */
+ public static final UrlEncodingSerializer DEFAULT = new UrlEncodingSerializer().lock();
+
+ /** Reusable instance of {@link UrlEncodingSerializer.Simple}. */
+ public static final UrlEncodingSerializer DEFAULT_SIMPLE = new Simple().lock();
+
+ /** Reusable instance of {@link UrlEncodingSerializer.SimpleExpanded}. */
+ public static final UrlEncodingSerializer DEFAULT_SIMPLE_EXPANDED = new SimpleExpanded().lock();
+
+ /** Reusable instance of {@link UrlEncodingSerializer.Readable}. */
+ public static final UrlEncodingSerializer DEFAULT_READABLE = new Readable().lock();
+
+ /**
+ * Constructor.
+ */
+ public UrlEncodingSerializer() {
+ setProperty(UON_encodeChars, true);
+ }
+
+ /**
+ * Equivalent to <code><jk>new</jk> UrlEncodingSerializer().setProperty(UonSerializerProperties.<jsf>UON_simpleMode</jsf>,<jk>true</jk>);</code>.
+ */
+ @Produces(value={"application/x-www-form-urlencoded-simple"},contentType="application/x-www-form-urlencoded")
+ public static class Simple extends UrlEncodingSerializer {
+ /** Constructor */
+ public Simple() {
+ setProperty(UON_simpleMode, true);
+ }
+ }
+
+ /**
+ * Equivalent to <code><jk>new</jk> UrlEncodingSerializer().setProperty(UonSerializerProperties.<jsf>UON_simpleMode</jsf>,<jk>true</jk>).setProperty(UonSerializerProperties.<jsf>URLENC_expandedParams</jsf>,<jk>true</jk>);</code>.
+ */
+ @Produces(value={"application/x-www-form-urlencoded-simple"},contentType="application/x-www-form-urlencoded")
+ public static class SimpleExpanded extends Simple {
+ /** Constructor */
+ public SimpleExpanded() {
+ setProperty(URLENC_expandedParams, true);
+ }
+ }
+
+ /**
+ * Equivalent to <code><jk>new</jk> UrlEncodingSerializer().setProperty(UonSerializerProperties.<jsf>UON_useWhitespace</jsf>,<jk>true</jk>);</code>.
+ */
+ public static class Readable extends UrlEncodingSerializer {
+ /** Constructor */
+ public Readable() {
+ setProperty(UON_useWhitespace, true);
+ }
+ }
+
+ /**
+ * Workhorse method. Determines the type of object, and then calls the
+ * appropriate type-specific serialization method.
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private SerializerWriter serializeAnything(UonSerializerWriter out, Object o, UonSerializerContext ctx) throws SerializeException {
+ try {
+
+ BeanContext bc = ctx.getBeanContext();
+
+ boolean addClassAttr; // Add "_class" attribute to element?
+ ClassMeta<?> aType; // The actual type
+ ClassMeta<?> gType; // The generic type
+
+ aType = ctx.push("root", o, object());
+ ctx.indent--;
+ if (aType == null)
+ aType = object();
+
+ gType = aType.getFilteredClassMeta();
+ addClassAttr = (ctx.isAddClassAttrs());
+
+ // Filter if necessary
+ PojoFilter filter = aType.getPojoFilter(); // The filter
+ 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);
+ }
+
+ if (gType.isMap()) {
+ if (o instanceof BeanMap)
+ serializeBeanMap(out, (BeanMap)o, addClassAttr, ctx);
+ else
+ serializeMap(out, (Map)o, gType, ctx);
+ } else if (gType.hasToObjectMapMethod()) {
+ serializeMap(out, gType.toObjectMap(o), gType, ctx);
+ } else if (gType.isBean()) {
+ serializeBeanMap(out, bc.forBean(o), addClassAttr, ctx);
+ } else if (gType.isCollection()) {
+ serializeMap(out, getCollectionMap((Collection)o), bc.getMapClassMeta(Map.class, Integer.class, gType.getElementType()), ctx);
+ } else {
+ // All other types can't be serialized as key/value pairs, so we create a
+ // mock key/value pair with a "_value" key.
+ out.append("_value=");
+ super.serializeAnything(out, o, null, ctx, null, null, false, true);
+ }
+
+ ctx.pop();
+ return out;
+ } catch (SerializeException e) {
+ throw e;
+ } catch (StackOverflowError e) {
+ throw e;
+ } catch (Throwable e) {
+ throw new SerializeException("Exception occurred trying to process object of type ''{0}''", (o == null ? null : o.getClass().getName())).initCause(e);
+ }
+ }
+
+ private Map<Integer,Object> getCollectionMap(Collection<?> c) {
+ Map<Integer,Object> m = new TreeMap<Integer,Object>();
+ int i = 0;
+ for (Object o : c)
+ m.put(i++, o);
+ return m;
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private SerializerWriter serializeMap(UonSerializerWriter out, Map m, ClassMeta<?> type, UonSerializerContext ctx) throws IOException, SerializeException {
+
+ m = sort(ctx, m);
+
+ ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType();
+
+ int depth = ctx.getIndent();
+ boolean addAmp = false;
+
+ Iterator mapEntries = m.entrySet().iterator();
+
+ while (mapEntries.hasNext()) {
+ Map.Entry e = (Map.Entry) mapEntries.next();
+ Object value = e.getValue();
+ Object key = generalize(ctx, e.getKey(), keyType);
+
+
+ if (shouldUseExpandedParams(value, ctx)) {
+ Iterator i = value instanceof Collection ? ((Collection)value).iterator() : ArrayUtils.iterator(value);
+ while (i.hasNext()) {
+ if (addAmp)
+ out.cr(depth).append('&');
+ out.appendObject(key, false, true, true).append('=');
+ super.serializeAnything(out, i.next(), null, ctx, (key == null ? null : key.toString()), null, false, true);
+ addAmp = true;
+ }
+ } else {
+ if (addAmp)
+ out.cr(depth).append('&');
+ out.appendObject(key, false, true, true).append('=');
+ super.serializeAnything(out, value, valueType, ctx, (key == null ? null : key.toString()), null, false, true);
+ addAmp = true;
+ }
+ }
+
+ return out;
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ private SerializerWriter serializeBeanMap(UonSerializerWriter out, BeanMap m, boolean addClassAttr, UonSerializerContext ctx) throws IOException, SerializeException {
+ int depth = ctx.getIndent();
+
+ Iterator mapEntries = m.entrySet().iterator();
+
+ // Print out "_class" attribute on this bean if required.
+ if (addClassAttr) {
+ String attr = "_class";
+ out.appendObject(attr, false, false, true).append('=').append(m.getClassMeta().getInnerClass().getName());
+ if (mapEntries.hasNext())
+ out.cr(depth).append('&');
+ }
+
+ boolean addAmp = false;
+
+ while (mapEntries.hasNext()) {
+ BeanMapEntry p = (BeanMapEntry)mapEntries.next();
+ BeanPropertyMeta pMeta = p.getMeta();
+
+ String key = p.getKey();
+ Object value = null;
+ try {
+ value = p.getValue();
+ } catch (StackOverflowError e) {
+ throw e;
+ } catch (Throwable t) {
+ ctx.addBeanGetterWarning(pMeta, t);
+ }
+
+ if (canIgnoreValue(ctx, pMeta.getClassMeta(), key, value))
+ continue;
+
+ if (value != null && shouldUseExpandedParams(pMeta, ctx)) {
+ ClassMeta cm = pMeta.getClassMeta();
+ // Filtered object array bean properties may be filtered resulting in ArrayLists,
+ // so we need to check type if we think it's an array.
+ Iterator i = (cm.isCollection() || value instanceof Collection) ? ((Collection)value).iterator() : ArrayUtils.iterator(value);
+ while (i.hasNext()) {
+ if (addAmp)
+ out.cr(depth).append('&');
+
+ out.appendObject(key, false, true, true).append('=');
+
+ super.serializeAnything(out, i.next(), pMeta.getClassMeta().getElementType(), ctx, key, pMeta, false, true);
+
+ addAmp = true;
+ }
+ } else {
+ if (addAmp)
+ out.cr(depth).append('&');
+
+ out.appendObject(key, false, true, true).append('=');
+
+ super.serializeAnything(out, value, pMeta.getClassMeta(), ctx, key, pMeta, false, true);
+
+ addAmp = true;
+ }
+
+ }
+ return out;
+ }
+
+ /**
+ * Returns true if the specified bean property should be expanded as multiple key-value pairs.
+ */
+ private final boolean shouldUseExpandedParams(BeanPropertyMeta<?> pMeta, UonSerializerContext ctx) {
+ ClassMeta<?> cm = pMeta.getClassMeta();
+ if (cm.isArray() || cm.isCollection()) {
+ if (ctx.isExpandedParams())
+ return true;
+ if (pMeta.getBeanMeta().getClassMeta().getUrlEncodingMeta().isExpandedParams())
+ return true;
+ }
+ return false;
+ }
+
+ private final boolean shouldUseExpandedParams(Object value, UonSerializerContext ctx) {
+ if (value == null)
+ return false;
+ ClassMeta<?> cm = ctx.getBeanContext().getClassMetaForObject(value).getFilteredClassMeta();
+ if (cm.isArray() || cm.isCollection()) {
+ if (ctx.isExpandedParams())
+ return true;
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------------------
+ // Methods for constructing individual parameter values.
+ //--------------------------------------------------------------------------------
+
+ /**
+ * Converts the specified object to a string using this serializers {@link BeanContext#convertToType(Object, Class)} method
+ * and runs {@link URLEncoder#encode(String,String)} against the results.
+ * Useful for constructing URL parts.
+ *
+ * @param o The object to serialize.
+ * @return The serialized object.
+ */
+ public String serializeUrlPart(Object o) {
+ try {
+ // Shortcut for simple types.
+ ClassMeta<?> cm = getBeanContext().getClassMetaForObject(o);
+ if (cm != null)
+ if (cm.isCharSequence() || cm.isNumber() || cm.isBoolean())
+ return o.toString();
+
+ UonSerializerContext uctx = createContext(null, null);
+ StringWriter w = new StringWriter();
+ super.doSerialize(o, w, uctx);
+ return w.toString();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ //--------------------------------------------------------------------------------
+ // Overridden methods
+ //--------------------------------------------------------------------------------
+
+ @Override /* Serializer */
+ public UonSerializerContext createContext(ObjectMap properties, Method javaMethod) {
+ return new UonSerializerContext(getBeanContext(), sp, usp, uep, properties, javaMethod);
+ }
+
+ @Override /* Serializer */
+ protected void doSerialize(Object o, Writer out, SerializerContext ctx) throws IOException, SerializeException {
+ UonSerializerContext uctx = (UonSerializerContext)ctx;
+ serializeAnything(uctx.getWriter(out), o, uctx);
+ }
+
+ @Override /* CoreApi */
+ public UrlEncodingSerializer setProperty(String property, Object value) throws LockedException {
+ checkLock();
+ if (! usp.setProperty(property, value))
+ if (! uep.setProperty(property, value))
+ super.setProperty(property, value);
+ return this;
+ }
+
+ @Override /* CoreApi */
+ public UrlEncodingSerializer setProperties(ObjectMap properties) throws LockedException {
+ for (Map.Entry<String,Object> e : properties.entrySet())
+ setProperty(e.getKey(), e.getValue());
+ return this;
+ }
+
+ @Override /* CoreApi */
+ public UrlEncodingSerializer addNotBeanClasses(Class<?>...classes) throws LockedException {
+ super.addNotBeanClasses(classes);
+ return this;
+ }
+
+ @Override /* CoreApi */
+ public UrlEncodingSerializer addFilters(Class<?>...classes) throws LockedException {
+ super.addFilters(classes);
+ return this;
+ }
+
+ @Override /* CoreApi */
+ public <T> UrlEncodingSerializer addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
+ super.addImplClass(interfaceClass, implClass);
+ return this;
+ }
+
+ @Override /* CoreApi */
+ public UrlEncodingSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
+ super.setClassLoader(classLoader);
+ return this;
+ }
+
+ @Override /* Lockable */
+ public UrlEncodingSerializer lock() {
+ super.lock();
+ return this;
+ }
+
+ @Override /* Lockable */
+ public UrlEncodingSerializer clone() {
+ UrlEncodingSerializer c = (UrlEncodingSerializer)super.clone();
+ c.usp = usp.clone();
+ c.uep = uep.clone();
+ return c;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/UrlEncoding.class
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/UrlEncoding.class b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/UrlEncoding.class
new file mode 100755
index 0000000..84e2638
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/UrlEncoding.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/urlencoding/annotation/UrlEncoding.java
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/UrlEncoding.java b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/UrlEncoding.java
new file mode 100755
index 0000000..d0870ad
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/UrlEncoding.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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.urlencoding.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+import com.ibm.juno.core.urlencoding.*;
+
+/**
+ * Annotation that can be applied to classes, fields, and methods to tweak how
+ * they are handled by {@link UrlEncodingSerializer} and {@link UrlEncodingParser}.
+ *
+ * @author James Bognar (jbognar@us.ibm.com)
+ */
+@Documented
+@Target({TYPE})
+@Retention(RUNTIME)
+@Inherited
+public @interface UrlEncoding {
+
+ /**
+ * When true, bean properties of type array or Collection will be expanded into multiple key=value pairings.
+ * <p>
+ * This annotation is identical in behavior to using the {@link UrlEncodingProperties#URLENC_expandedParams}
+ * property, but applies to only instances of this bean.
+ */
+ boolean expandedParams() default false;
+}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/package.html
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/package.html b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/package.html
new file mode 100755
index 0000000..806eadb
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/annotation/package.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<!--
+ Licensed Materials - Property of IBM
+ (c) Copyright IBM Corporation 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.
+ -->
+<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>URL-Encoding annotations</p>
+</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/urlencoding/doc-files/Example_HTML.png
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/Example_HTML.png b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/Example_HTML.png
new file mode 100755
index 0000000..ab74763
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/Example_HTML.png differ
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/Example_UrlEncoding.png
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/Example_UrlEncoding.png b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/Example_UrlEncoding.png
new file mode 100755
index 0000000..34de8a7
Binary files /dev/null and b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/Example_UrlEncoding.png differ
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/7e4f63e6/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/rfc_uon.txt
----------------------------------------------------------------------
diff --git a/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/rfc_uon.txt b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/rfc_uon.txt
new file mode 100755
index 0000000..c79c9c5
--- /dev/null
+++ b/com.ibm.team.juno.releng/bin/core/com/ibm/juno/core/urlencoding/doc-files/rfc_uon.txt
@@ -0,0 +1,352 @@
+Network Working Group J. Bognar
+Request for Comments: 9999 C. Chaney
+Category: Informational IBM
+ Jan 2014
+
+ ***DRAFT***
+ URI Object Notation (UON): Generic Syntax
+
+
+About this document
+
+ This memo provides information for the Internet community. It does
+ not specify an Internet standard of any kind. Distribution of this
+ memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) IBM Corp. 2014. All Rights Reserved.
+
+Abstract
+
+ This document describes a grammar that builds upon RFC2396
+ (Uniform Resource Identifiers). Its purpose is to define a
+ generalized object notation for URI query parameter values similar in
+ concept to Javascript Object Notation (RFC4627). The goal is a
+ syntax such that any data structure defined in JSON can be losslessly
+ defined in an equivalent URI-based grammar, yet be fully compliant
+ with the RFC2396 specification.
+
+ This grammar provides the ability to construct the following data
+ structures in URL parameter values:
+
+ OBJECT
+ ARRAY
+ NUMBER
+ BOOLEAN
+ STRING
+ NULL
+
+ Example:
+
+ The following shows a sample object defined in Javascript:
+
+ var x = {
+ id: 1,
+ name: 'John Smith',
+ uri: 'http://sample/addressBook/person/1',
+ addressBookUri: 'http://sample/addressBook',
+ birthDate: '1946-08-12T00:00:00Z',
+ otherIds: null,
+ addresses: [
+ {
+ uri: 'http://sample/addressBook/address/1',
+ personUri: 'http://sample/addressBook/person/1',
+ id: 1,
+ street: '100 Main Street',
+ city: 'Anywhereville',
+ state: 'NY',
+ zip: 12345,
+ isCurrent: true,
+ }
+ ]
+ }
+
+ Using the "strict" syntax defined in this document, the equivalent
+ UON notation would be as follows:
+
+ x=$o(id=$n(1),name=John+Smith,uri=http://sample/
+ addressBook/person/1,addressBookUri=http://sample/
+ addressBook,birthDate=1946-08-12T00:00:00Z,otherIds=%00,
+ addresses=$a($o(uri=http://sample/addressBook/
+ address/1,personUri=http://sample/addressBook/
+ person/1,id=$n(1),street=100+Main+Street,city=
+ Anywhereville,state=NY,zip=$n(12345),isCurrent=$b(true))))
+
+ A secondary "lax" syntax is available when the data type of the
+ values are already known on the receiving end of the transmission:
+
+ x=(id=1,name=John+Smith,uri=http://sample/
+ addressBook/person/1,addressBookUri=http://sample/
+ addressBook,birthDate=1946-08-12T00:00:00Z,otherIds=%00,
+ addresses=((uri=http://sample/addressBook/
+ address/1,personUri=http://sample/addressBook/
+ person/1,id=1,street=100+Main+Street,city=
+ Anywhereville,state=NY,zip=12345,isCurrent=true)))
+
+ Values represented in strict mode can be losslessly converted
+ back and forth into a JSON model without any additional
+ information. Values represented in lax mode cannot.
+
+1. Language constraints
+
+ The grammar syntax is constrained to usage of characters allowed by
+ URI notation:
+
+ uric = reserved | unreserved | escaped
+ reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+ "$" | ","
+ unreserved = alphanum | mark
+ mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
+
+ In particular, the URI specification disallows the following
+ characters in unencoded form:
+
+ unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
+ delims = "<" | ">" | "#" | "%" | <">
+
+ The exclusion of {} and [] characters eliminates the possibility of
+ using JSON as parameter values.
+
+
+2. Grammar constructs
+
+ The grammar consists of the following language constructs:
+
+ Objects - Values consisting of one or more child name/value pairs.
+ Arrays - Values consisting of zero or more child values.
+ Booleans - Values consisting of true/false values.
+ Numbers - Decimal and floating point values.
+ Strings - Everything else.
+
+2.1. Objects
+
+ Objects are values consisting of one or more child name/value pairs.
+ The $o() construct is used to define an object.
+
+ Example: A simple map with two key/value pairs:
+
+ a1=$o(b1=x1,b2=x2)
+
+ Example: A nested map:
+
+ a1=$o(b1=$o(c1=x1,c2=x2))
+
+ When the data type is already known to be an object on the receiving
+ end, then the type flag can be removed from the construct to produce
+ a simplified value.
+
+ Example: A nested map using "lax" syntax:
+
+ a1=(b1=(c1=x1,c2=x2))
+
+2.2. Arrays
+
+ Arrays are values consisting of zero or more child values.
+ The $a() construct is used to define an array.
+
+ Example: An array of two string values:
+
+ a1=$a(x1,x2)
+
+ Example: A 2-dimensional array:
+
+ a1=$a($a(x1,x2),$a(x3,x4))
+
+ Example: An array of objects:
+
+ a1=$a($o(b1=x1,b2=x2),$o(c1=x1,c2=x2))
+
+ When the data type is already known to be an array on the receiving
+ end, then the type flag can be removed from the construct to produce
+ a simplified value.
+
+ Example: An array of objects using "lax" syntax:
+
+ a1=((b1=x1,b2=x2),(c1=x1,c2=x2))
+
+2.3. Booleans
+
+ Booleans are values that can only take on values "true" or "false".
+ The $b() construct is used to define a boolean.
+
+ Example: Two boolean values:
+
+ a1=$b(true)&a2=$b(false)
+
+ When the data type is already known to be a boolean on the receiving
+ end, then the type flag and parentheses can be removed from the
+ construct to produce a simplified value.
+
+ Example: Two boolean values using "lax" syntax:
+
+ a1=true&a2=false
+
+2.4. Numbers
+
+ The $n() construct is used to define a number.
+ Both decimal and float numbers are supported.
+
+ Example: Two numerical values, one decimal and one float:
+
+ a1=$n(123)&a2=$n(1.23e1)
+
+ When the data type is already known to be a number on the receiving
+ end, then the type flag and parentheses can be removed from the
+ construct to produce a simplified value.
+
+ Example: Two numerical values using "lax" syntax:
+
+ a1=123&a2=1.23e1
+
+2.5. Strings
+
+ Anything not conforming to one of the constructs described above
+ are treated as simple strings.
+
+ Example: A simple string value:
+
+ a1=foobar
+
+ The tilde character (~) is used for escaping characters to prevent
+ them from being confused with syntax characters.
+
+ The following characters must be escaped in string literals:
+
+ $ , ( ) ~ =
+
+ For example, the string literal "$o(b1=x)" should be
+ represented as follows:
+
+ a1=~$o~(b1~=x~)
+
+ In addition, strings can optionally be enclosed in parentheses
+ when needed to handle ambiguous cases.
+
+ The following two values are equivalent:
+
+ a1=foobar
+ a1=(foobar)
+
+ Using parentheses, the following construct can be used to represent
+ an empty string:
+
+ a1=()
+
+ The purpose for this is to handle a potential ambiguity in the
+ representation of an empty array ([]) vs. an array containing one
+ empty string ([""]). An array containing one empty string is
+ represented as follows:
+
+ a1=$a(())
+
+ Without this construct, there would not be a way to tell the
+ difference between an empty array and an array containing an empty
+ string:
+
+ a1=$a()
+
+ Note that an array consisting of two empty strings does not suffer
+ from this ambiguity, and the use of parenthesis is optional in
+ this case:
+
+ a1=$a(,)
+
+2.7. Null values
+
+ Nulls are represented by ASCII '0' as an escaped hex sequence:
+
+ a1=%00
+
+ Note that a string consisting of a single null character can be
+ represented with the following construct:
+
+ a1=(%00)
+
+2.8. Top-level attribute names
+
+ Top-level attribute names (e.g. "a1" in "&a1=foobar") are treated
+ as strings but for one exception. The '=' character must be
+ encoded so as not to be confused as a key/value separator.
+ Note that the '=' character must also be escaped per the UON
+ notation.
+
+ For example, the UON equivalent of {"a=b":"a=b"} constructed as
+ a top-level query parameter string would be as follows:
+
+ a~%3Db=a~=b
+
+ Note that the '=' character is encoded in the attribute name,
+ but it is not necessary to have it encoded in the attribute value.
+
+2.9. URL-encoded characters
+
+ UON notation allows for any character, even UON grammar
+ characters, to be URL-encoded.
+
+ The following query strings are fully equivalent in structure:
+
+ a1=$o(b1=x1,b2=x2)
+ %61%31=%24%6F%28%62%31%3D%78%31%2C%62%32%3D%78%32%29
+
+
+3. BNF
+
+ The following BNF describes the syntax for top-level URI query
+ parameter values (e.g. ?<attrname>=<value>).
+
+ attrname = (string | null)
+ value = (var | string | null)
+
+ string = ("(" litchar* ")") | litchar*
+ null = "%00"
+
+ var = ovar | avar | nvar | bvar
+ ovar = ovar_strict | ovar_lax
+ avar = avar_strict | avar_lax
+ nvar = nvar_strict | nvar_lax
+ bvar = bvar_strict | bvar_lax
+ ovar_strict = "$o(" [pairs] ")"
+ ovar_lax = "(" [pairs] ")"
+ avar_strict = "$a(" [values] ")"
+ avar_lax = "(" [values] ")"
+ nvar_strict = "$n(" number ")"
+ nvar_lax = number
+ bvar_strict = "$b(" boolean ")"
+ bvar_lax = boolean
+
+ pairs = pair ["," pairs]
+ pair = key "=" value
+ values = value ["," values]
+ key = (string | null)
+ boolean = "true" | "false"
+
+ escape_seq = "~" escaped
+ encode_seq = "%" digithex digithex
+
+ number = [-] (decimal | float) [exp]
+ decimal = "0" | (digit19 digit*)
+ float = decimal "." digit+
+ exp = "e" [("+" | "-")] digit+
+
+ litchar = unencoded | encode_seq | escape_seq
+ escaped = "$" | "," | "(" | ")" | "~" | "="
+ unencoded = alpha | digit |
+ ";" | "/" | "?" | ":" | "@" |
+ "-" | "_" | "." | "!" | "*" | "'"
+ alpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
+ "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
+ "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" |
+ "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
+ "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
+ "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
+ digit = "0" | digit19
+ digit19 = "1" | "2" | "3" | "4" | "5" | "6" | "7" |
+ "8" | "9"
+ digithex = digit |
+ "A" | "B" | "C" | "D" | "E" | "F" |
+ "a" | "b" | "c" | "d" | "e" | "f"
+
+
+
+