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 2017/02/15 20:50:42 UTC
[3/8] incubator-juneau git commit: Modification to UON spec. Remove
bean subtype support.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
index 510078a..21227c7 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
@@ -53,13 +53,10 @@ public class UonParser extends ReaderParser {
/** Reusable instance of {@link UonParser.Decoding}. */
public static final UonParser DEFAULT_DECODING = new Decoding().lock();
- /** Reusable instance of {@link UonParser}, all default settings, whitespace-aware. */
- public static final UonParser DEFAULT_WS_AWARE = new UonParser().setWhitespaceAware(true).lock();
-
// Characters that need to be preceeded with an escape character.
- private static final AsciiSet escapedChars = new AsciiSet(",()~=$\u0001\u0002");
+ private static final AsciiSet escapedChars = new AsciiSet("~'\u0001\u0002");
- private static final char NUL='\u0000', AMP='\u0001', EQ='\u0002'; // Flags set in reader to denote & and = characters.
+ private static final char AMP='\u0001', EQ='\u0002'; // Flags set in reader to denote & and = characters.
/**
* Equivalent to <code><jk>new</jk> UrlEncodingParser().setProperty(UonParserContext.<jsf>UON_decodeChars</jsf>,<jk>true</jk>);</code>.
@@ -89,14 +86,10 @@ public class UonParser extends ReaderParser {
eType = (ClassMeta<T>)object();
PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap();
ClassMeta<?> sType = eType.getSerializedClassMeta();
- BeanRegistry breg = (pMeta == null ? session.getBeanRegistry() : pMeta.getBeanRegistry());
Object o = null;
- // Parse type flag '$x'
- char flag = readFlag(session, r, (char)0);
-
- int c = r.peek();
+ int c = r.peekSkipWs();
if (c == -1 || c == AMP) {
// If parameter is blank and it's an array or collection, return an empty list.
@@ -108,21 +101,25 @@ public class UonParser extends ReaderParser {
o = sType.getPrimitiveDefault();
// Otherwise, leave null.
} else if (sType.isObject()) {
- if (flag == 0 || flag == 's') {
- o = parseString(session, r, isUrlParamValue);
- } else if (flag == 'b') {
- o = parseBoolean(session, r);
- } else if (flag == 'n') {
- o = parseNumber(session, r, null);
- } else if (flag == 'o') {
+ if (c == '(') {
ObjectMap m = new ObjectMap(session);
parseIntoMap(session, r, m, string(), object(), pMeta);
- o = breg.cast(m);
- } else if (flag == 'a') {
+ o = session.cast(m, pMeta, eType);
+ } else if (c == '@') {
Collection l = new ObjectList(session);
o = parseIntoCollection(session, r, l, sType.getElementType(), isUrlParamValue, pMeta);
} else {
- throw new ParseException(session, "Unexpected flag character ''{0}''.", flag);
+ String s = parseString(session, r, isUrlParamValue);
+ if (c != '\'') {
+ if ("true".equals(s) || "false".equals(s))
+ o = Boolean.valueOf(s);
+ else if (StringUtils.isNumeric(s))
+ o = StringUtils.parseNumber(s, Number.class);
+ else
+ o = s;
+ } else {
+ o = s;
+ }
}
} else if (sType.isBoolean()) {
o = parseBoolean(session, r);
@@ -137,12 +134,12 @@ public class UonParser extends ReaderParser {
Map m = (sType.canCreateNewInstance(outer) ? (Map)sType.newInstance(outer) : new ObjectMap(session));
o = parseIntoMap(session, r, m, sType.getKeyType(), sType.getValueType(), pMeta);
} else if (sType.isCollection()) {
- if (flag == 'o') {
+ if (c == '(') {
ObjectMap m = new ObjectMap(session);
parseIntoMap(session, r, m, string(), object(), pMeta);
// Handle case where it's a collection, but serialized as a map with a _type or _value key.
if (m.containsKey(session.getBeanTypePropertyName()))
- o = breg.cast(m);
+ o = session.cast(m, pMeta, eType);
// Handle case where it's a collection, but only a single value was specified.
else {
Collection l = (sType.canCreateNewInstance(outer) ? (Collection)sType.newInstance(outer) : new ObjectList(session));
@@ -164,12 +161,12 @@ public class UonParser extends ReaderParser {
} else if (sType.canCreateNewInstanceFromNumber(outer)) {
o = sType.newInstanceFromNumber(session, outer, parseNumber(session, r, sType.getNewInstanceFromNumberClass()));
} else if (sType.isArray()) {
- if (flag == 'o') {
+ if (c == '(') {
ObjectMap m = new ObjectMap(session);
parseIntoMap(session, r, m, string(), object(), pMeta);
// Handle case where it's an array, but serialized as a map with a _type or _value key.
if (m.containsKey(session.getBeanTypePropertyName()))
- o = breg.cast(m);
+ o = session.cast(m, pMeta, eType);
// Handle case where it's an array, but only a single value was specified.
else {
ArrayList l = new ArrayList(1);
@@ -180,12 +177,12 @@ public class UonParser extends ReaderParser {
ArrayList l = (ArrayList)parseIntoCollection(session, r, new ArrayList(), sType.getElementType(), isUrlParamValue, pMeta);
o = session.toArray(sType, l);
}
- } else if (flag == 'o') {
+ } else if (c == '(') {
// It could be a non-bean with _type attribute.
ObjectMap m = new ObjectMap(session);
parseIntoMap(session, r, m, string(), object(), pMeta);
if (m.containsKey(session.getBeanTypePropertyName()))
- o = breg.cast(m);
+ o = session.cast(m, pMeta, eType);
else
throw new ParseException(session, "Class ''{0}'' could not be instantiated. Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
} else {
@@ -207,8 +204,10 @@ public class UonParser extends ReaderParser {
keyType = (ClassMeta<K>)string();
int c = r.read();
- if (c == -1 || c == NUL || c == AMP)
+ if (c == -1 || c == AMP)
return null;
+ if (c == 'n')
+ return (Map<K,V>)parseNull(session, r);
if (c != '(')
throw new ParseException(session, "Expected '(' at beginning of object.");
@@ -226,12 +225,12 @@ public class UonParser extends ReaderParser {
if (state == S1) {
if (c == ')')
return m;
- if ((c == '\n' || c == '\r') && session.isWhitespaceAware())
+ if (Character.isWhitespace(c))
skipSpace(r);
else {
r.unread();
Object attr = parseAttr(session, r, session.isDecodeChars());
- currAttr = session.trim((attr == null ? null : session.convertToType(attr, keyType)));
+ currAttr = attr == null ? null : convertAttrToType(session, m, session.trim(attr.toString()), keyType);
state = S2;
c = 0; // Avoid isInEscape if c was '\'
}
@@ -287,18 +286,23 @@ public class UonParser extends ReaderParser {
private <E> Collection<E> parseIntoCollection(UonParserSession session, ParserReader r, Collection<E> l, ClassMeta<E> elementType, boolean isUrlParamValue, BeanPropertyMeta pMeta) throws Exception {
- int c = r.read();
- if (c == -1 || c == NUL || c == AMP)
+ int c = r.readSkipWs();
+ if (c == -1 || c == AMP)
return null;
+ if (c == 'n')
+ return (Collection<E>)parseNull(session, r);
// If we're parsing a top-level parameter, we're allowed to have comma-delimited lists outside parenthesis (e.g. "&foo=1,2,3&bar=a,b,c")
// This is not allowed at lower levels since we use comma's as end delimiters.
- boolean isInParens = (c == '(');
- if (! isInParens)
+ boolean isInParens = (c == '@');
+ if (! isInParens) {
if (isUrlParamValue)
r.unread();
else
throw new ParseException(session, "Could not find '(' marking beginning of collection.");
+ } else {
+ r.read();
+ }
if (isInParens) {
final int S1=1; // Looking for starting of first entry.
@@ -315,7 +319,7 @@ public class UonParser extends ReaderParser {
r.read();
}
return l;
- } else if ((c == '\n' || c == '\r') && session.isWhitespaceAware()) {
+ } else if (Character.isWhitespace(c)) {
skipSpace(r);
} else {
l.add(parseAnything(session, elementType, r.unread(), l, false, pMeta));
@@ -342,7 +346,7 @@ public class UonParser extends ReaderParser {
while (c != -1 && c != AMP) {
c = r.read();
if (state == S1) {
- if ((c == '\n' || c == '\r') && session.isWhitespaceAware()) {
+ if (Character.isWhitespace(c)) {
skipSpace(r);
} else {
l.add(parseAnything(session, elementType, r.unread(), l, false, pMeta));
@@ -351,7 +355,7 @@ public class UonParser extends ReaderParser {
} else if (state == S2) {
if (c == ',') {
state = S1;
- } else if ((c == '\n' || c == '\r') && session.isWhitespaceAware()) {
+ } else if (Character.isWhitespace(c)) {
skipSpace(r);
} else if (c == AMP || c == -1) {
r.unread();
@@ -366,9 +370,11 @@ public class UonParser extends ReaderParser {
private <T> BeanMap<T> parseIntoBeanMap(UonParserSession session, ParserReader r, BeanMap<T> m) throws Exception {
- int c = r.read();
- if (c == -1 || c == NUL || c == AMP)
+ int c = r.readSkipWs();
+ if (c == -1 || c == AMP)
return null;
+ if (c == 'n')
+ return (BeanMap<T>)parseNull(session, r);
if (c != '(')
throw new ParseException(session, "Expected '(' at beginning of object.");
@@ -388,7 +394,7 @@ public class UonParser extends ReaderParser {
if (c == ')' || c == -1 || c == AMP) {
return m;
}
- if ((c == '\n' || c == '\r') && session.isWhitespaceAware())
+ if (Character.isWhitespace(c))
skipSpace(r);
else {
r.unread();
@@ -413,11 +419,7 @@ public class UonParser extends ReaderParser {
if (! currAttr.equals(session.getBeanTypePropertyName())) {
BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
if (pMeta == null) {
- if (m.getMeta().isSubTyped()) {
- m.put(currAttr, "");
- } else {
- onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
- }
+ onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
} else {
Object value = session.convertToType("", pMeta.getClassMeta());
pMeta.set(m, value);
@@ -430,13 +432,8 @@ public class UonParser extends ReaderParser {
if (! currAttr.equals(session.getBeanTypePropertyName())) {
BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
if (pMeta == null) {
- if (m.getMeta().isSubTyped()) {
- Object value = parseAnything(session, object(), r.unread(), m.getBean(false), false, null);
- m.put(currAttr, value);
- } else {
- onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
- parseAnything(session, object(), r.unread(), m.getBean(false), false, null); // Read content anyway to ignore it
- }
+ onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
+ parseAnything(session, object(), r.unread(), m.getBean(false), false, null); // Read content anyway to ignore it
} else {
session.setCurrentProperty(pMeta);
ClassMeta<?> cm = pMeta.getClassMeta();
@@ -470,32 +467,26 @@ public class UonParser extends ReaderParser {
return null; // Unreachable.
}
+ Object parseNull(UonParserSession session, ParserReader r) throws Exception {
+ String s = parseString(session, r, false);
+ if ("ull".equals(s))
+ return null;
+ throw new ParseException(session, "Unexpected character sequence: ''{0}''", s);
+ }
+
Object parseAttr(UonParserSession session, ParserReader r, boolean encoded) throws Exception {
Object attr;
- int c = r.peek();
- if (c == '$') {
- char f = readFlag(session, r, (char)0);
- if (f == 'b')
- attr = parseBoolean(session, r);
- else if (f == 'n')
- attr = parseNumber(session, r, null);
- else
- attr = parseAttrName(session, r, encoded);
- } else {
- attr = parseAttrName(session, r, encoded);
- }
+ attr = parseAttrName(session, r, encoded);
return attr;
}
String parseAttrName(UonParserSession session, ParserReader r, boolean encoded) throws Exception {
- // If string is of form '(xxx)', we're looking for ')' at the end.
- // Otherwise, we're looking for '&' or '=' or -1 denoting the end of this string.
+ // If string is of form 'xxx', we're looking for ' at the end.
+ // Otherwise, we're looking for '&' or '=' or WS or -1 denoting the end of this string.
- int c = r.peek();
- if (c == '$')
- readFlag(session, r, 's');
- if (c == '(')
+ int c = r.peekSkipWs();
+ if (c == '\'')
return parsePString(session, r);
r.mark();
@@ -504,11 +495,11 @@ public class UonParser extends ReaderParser {
while (c != -1) {
c = r.read();
if (! isInEscape) {
- if (c == AMP || c == EQ || c == -1) {
+ if (c == AMP || c == EQ || c == -1 || Character.isWhitespace(c)) {
if (c != -1)
r.unread();
String s = r.getMarked();
- return (s.equals("\u0000") ? null : s);
+ return ("null".equals(s) ? null : s);
}
}
else if (c == AMP)
@@ -521,11 +512,11 @@ public class UonParser extends ReaderParser {
while (c != -1) {
c = r.read();
if (! isInEscape) {
- if (c == '=' || c == -1) {
+ if (c == '=' || c == -1 || Character.isWhitespace(c)) {
if (c != -1)
r.unread();
String s = r.getMarked();
- return (s.equals("\u0000") ? null : session.trim(s));
+ return ("null".equals(s) ? null : session.trim(s));
}
}
isInEscape = isInEscape(c, r, isInEscape);
@@ -556,11 +547,11 @@ public class UonParser extends ReaderParser {
String parseString(UonParserSession session, ParserReader r, boolean isUrlParamValue) throws Exception {
- // If string is of form '(xxx)', we're looking for ')' at the end.
+ // If string is of form 'xxx', we're looking for ' at the end.
// Otherwise, we're looking for ',' or ')' or -1 denoting the end of this string.
- int c = r.peek();
- if (c == '(')
+ int c = r.peekSkipWs();
+ if (c == '\'')
return parsePString(session, r);
r.mark();
@@ -581,7 +572,7 @@ public class UonParser extends ReaderParser {
s = r.getMarked();
else if (c == EQ)
r.replace('=');
- else if ((c == '\n' || c == '\r') && session.isWhitespaceAware()) {
+ else if (Character.isWhitespace(c)) {
s = r.getMarked(0, -1);
skipSpace(r);
c = -1;
@@ -589,19 +580,19 @@ public class UonParser extends ReaderParser {
isInEscape = isInEscape(c, r, isInEscape);
}
- return (s == null || s.equals("\u0000") ? null : session.trim(s));
+ return ("null".equals(s) ? null : session.trim(s));
}
private static final AsciiSet endCharsParam = new AsciiSet(""+AMP), endCharsNormal = new AsciiSet(",)"+AMP);
/**
- * Parses a string of the form "(foo)"
+ * Parses a string of the form "'foo'"
* All whitespace within parenthesis are preserved.
*/
static String parsePString(UonParserSession session, ParserReader r) throws Exception {
- r.read(); // Skip first parenthesis.
+ r.read(); // Skip first quote.
r.mark();
int c = 0;
@@ -609,7 +600,7 @@ public class UonParser extends ReaderParser {
while (c != -1) {
c = r.read();
if (! isInEscape) {
- if (c == ')')
+ if (c == '\'')
return session.trim(r.getMarked(0, -1));
}
if (c == EQ)
@@ -620,9 +611,8 @@ public class UonParser extends ReaderParser {
}
private Boolean parseBoolean(UonParserSession session, ParserReader r) throws Exception {
- readFlag(session, r, 'b');
String s = parseString(session, r, false);
- if (s == null)
+ if (s == null || s.equals("null"))
return null;
if (s.equals("true"))
return true;
@@ -632,7 +622,6 @@ public class UonParser extends ReaderParser {
}
private Number parseNumber(UonParserSession session, ParserReader r, Class<? extends Number> c) throws Exception {
- readFlag(session, r, 'n');
String s = parseString(session, r, false);
if (s == null)
return null;
@@ -644,29 +633,13 @@ public class UonParser extends ReaderParser {
* remainder in the input, that it consists only of whitespace and comments.
*/
private void validateEnd(UonParserSession session, ParserReader r) throws Exception {
- int c = r.read();
- if (c != -1)
- throw new ParseException(session, "Remainder after parse: ''{0}''.", (char)c);
- }
-
- /**
- * Reads flag character from "$x(" construct if flag is present.
- * Returns 0 if no flag is present.
- */
- static char readFlag(UonParserSession session, ParserReader r, char expected) throws Exception {
- char c = (char)r.peek();
- if (c == '$') {
- r.read();
- char f = (char)r.read();
- if (expected != 0 && f != expected)
- throw new ParseException(session, "Unexpected flag character: ''{0}''. Expected ''{1}''.", f, expected);
- c = (char)r.peek();
- // Type flag must be followed by '('
- if (c != '(')
- throw new ParseException(session, "Unexpected character following flag: ''{0}''.", c);
- return f;
+ while (true) {
+ int c = r.read();
+ if (c == -1)
+ return;
+ if (! Character.isWhitespace(c))
+ throw new ParseException(session, "Remainder after parse: ''{0}''.", (char)c);
}
- return 0;
}
private Object[] parseArgs(UonParserSession session, ParserReader r, ClassMeta<?>[] argTypes) throws Exception {
@@ -677,11 +650,12 @@ public class UonParser extends ReaderParser {
Object[] o = new Object[argTypes.length];
int i = 0;
- int c = r.read();
+ int c = r.readSkipWs();
if (c == -1 || c == AMP)
return null;
- if (c != '(')
- throw new ParseException(session, "Expected '(' at beginning of args array.");
+ if (c != '@')
+ throw new ParseException(session, "Expected '@' at beginning of args array.");
+ c = r.read();
int state = S1;
while (c != -1 && c != AMP) {
@@ -707,7 +681,7 @@ public class UonParser extends ReaderParser {
private static void skipSpace(ParserReader r) throws Exception {
int c = 0;
while ((c = r.read()) != -1) {
- if (c > ' ' || c <= 2) {
+ if (c <= 2 || ! Character.isWhitespace(c)) {
r.unread();
return;
}
@@ -741,7 +715,6 @@ public class UonParser extends ReaderParser {
protected <K,V> Map<K,V> doParseIntoMap(ParserSession session, Map<K,V> m, Type keyType, Type valueType) throws Exception {
UonParserSession s = (UonParserSession)session;
UonReader r = s.getReader();
- readFlag(s, r, 'o');
m = parseIntoMap(s, r, m, (ClassMeta<K>)session.getClassMeta(keyType), (ClassMeta<V>)session.getClassMeta(valueType), null);
validateEnd(s, r);
return m;
@@ -751,7 +724,6 @@ public class UonParser extends ReaderParser {
protected <E> Collection<E> doParseIntoCollection(ParserSession session, Collection<E> c, Type elementType) throws Exception {
UonParserSession s = (UonParserSession)session;
UonReader r = s.getReader();
- readFlag(s, r, 'a');
c = parseIntoCollection(s, r, c, (ClassMeta<E>)session.getClassMeta(elementType), false, null);
validateEnd(s, r);
return c;
@@ -761,7 +733,6 @@ public class UonParser extends ReaderParser {
protected Object[] doParseArgs(ParserSession session, ClassMeta<?>[] argTypes) throws Exception {
UonParserSession s = (UonParserSession)session;
UonReader r = s.getReader();
- readFlag(s, r, 'a');
Object[] a = parseArgs(s, r, argTypes);
return a;
}
@@ -798,32 +769,6 @@ public class UonParser extends ReaderParser {
return setProperty(UON_decodeChars, value);
}
- /**
- * <b>Configuration property:</b> Whitespace aware.
- * <p>
- * <ul>
- * <li><b>Name:</b> <js>"UonParser.whitespaceAware"</js>
- * <li><b>Data type:</b> <code>Boolean</code>
- * <li><b>Default:</b> <jk>false</jk>
- * <li><b>Session-overridable:</b> <jk>true</jk>
- * </ul>
- * <p>
- * Expect input to contain readable whitespace characters from using the {@link UonSerializerContext#UON_useWhitespace} setting.
- * <p>
- * <h5 class='section'>Notes:</h5>
- * <ul>
- * <li>This is equivalent to calling <code>setProperty(<jsf>UON_whitespaceAware</jsf>, value)</code>.
- * </ul>
- *
- * @param value The new value for this property.
- * @return This object (for method chaining).
- * @throws LockedException If {@link #lock()} was called on this class.
- * @see UonParserContext#UON_whitespaceAware
- */
- public UonParser setWhitespaceAware(boolean value) throws LockedException {
- return setProperty(UON_whitespaceAware, value);
- }
-
@Override /* Parser */
public UonParser setTrimStrings(boolean value) throws LockedException {
super.setTrimStrings(value);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserContext.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserContext.java
index f1f65bb..2cc5745 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserContext.java
@@ -48,24 +48,8 @@ public class UonParserContext extends ParserContext {
*/
public static final String UON_decodeChars = "UonParser.decodeChars";
- /**
- * <b>Configuration property:</b> Whitespace aware.
- * <p>
- * <ul>
- * <li><b>Name:</b> <js>"UonParser.whitespaceAware"</js>
- * <li><b>Data type:</b> <code>Boolean</code>
- * <li><b>Default:</b> <jk>false</jk>
- * <li><b>Session-overridable:</b> <jk>true</jk>
- * </ul>
- * <p>
- * Expect input to contain readable whitespace characters from using the {@link UonSerializerContext#UON_useWhitespace} setting.
- */
- public static final String UON_whitespaceAware = "UonParser.whitespaceAware";
-
-
final boolean
- decodeChars,
- whitespaceAware;
+ decodeChars;
/**
* Constructor.
@@ -77,7 +61,6 @@ public class UonParserContext extends ParserContext {
public UonParserContext(ContextFactory cf) {
super(cf);
this.decodeChars = cf.getProperty(UON_decodeChars, boolean.class, false);
- this.whitespaceAware = cf.getProperty(UON_whitespaceAware, boolean.class, false);
}
@Override /* Context */
@@ -85,7 +68,6 @@ public class UonParserContext extends ParserContext {
return super.asMap()
.append("UonParserContext", new ObjectMap()
.append("decodeChars", decodeChars)
- .append("whitespaceAware", whitespaceAware)
);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
index c2ea7da..54b8927 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
@@ -28,7 +28,7 @@ import org.apache.juneau.parser.*;
*/
public class UonParserSession extends ParserSession {
- private final boolean decodeChars, whitespaceAware;
+ private final boolean decodeChars;
private UonReader reader;
/**
@@ -58,10 +58,8 @@ public class UonParserSession extends ParserSession {
super(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
if (op == null || op.isEmpty()) {
decodeChars = ctx.decodeChars;
- whitespaceAware = ctx.whitespaceAware;
} else {
decodeChars = op.getBoolean(UON_decodeChars, ctx.decodeChars);
- whitespaceAware = op.getBoolean(UON_whitespaceAware, ctx.whitespaceAware);
}
}
@@ -83,7 +81,6 @@ public class UonParserSession extends ParserSession {
public UonParserSession(UonParserContext ctx, Object input) {
super(ctx, null, input, null, null, null, null, null);
decodeChars = false;
- whitespaceAware = ctx.whitespaceAware;
}
/**
@@ -95,15 +92,6 @@ public class UonParserSession extends ParserSession {
return decodeChars;
}
- /**
- * Returns the {@link UonParserContext#UON_whitespaceAware} setting value for this session.
- *
- * @return The {@link UonParserContext#UON_whitespaceAware} setting value for this session.
- */
- public final boolean isWhitespaceAware() {
- return whitespaceAware;
- }
-
@Override /* ParserSession */
public UonReader getReader() throws Exception {
if (reader == null) {
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
index 8c7848f..9fae479 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
@@ -73,49 +73,23 @@ import org.apache.juneau.transform.*;
* UON notation would be as follows:
* </p>
* <p class='bcode'>
- * $o(
- * <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>=(
+ * <ua>id</ua>=<un>1</un>,
+ * <ua>name</ua>=<us>'John+Smith'</us>,
+ * <ua>uri</ua>=<us>http://sample/addressBook/person/1</us>,
+ * <ua>addressBookUri</ua>=<us>http://sample/addressBook</us>,
+ * <ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>,
+ * <ua>otherIds</ua>=<uk>null</uk>,
+ * <ua>addresses</ua>=@(
* (
- * <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>
+ * <ua>uri</ua>=<us>http://sample/addressBook/address/1</us>,
+ * <ua>personUri</ua>=<us>http://sample/addressBook/person/1</us>,
+ * <ua>id</ua>=<un>1</un>,
+ * <ua>street</ua>=<us>'100+Main+Street'</us>,
+ * <ua>city</ua>=<us>Anywhereville</us>,
+ * <ua>state</ua>=<us>NY</us>,
+ * <ua>zip</ua>=<un>12345</un>,
+ * <ua>isCurrent</ua>=<uk>true</uk>
* )
* )
* )
@@ -127,13 +101,9 @@ import org.apache.juneau.transform.*;
* 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 "$o(a=b,c=$n(1),d=$b(false),e=$a(f,$n(1),$b(false)),g=$o(h=i))"</jc>
+ * <jc>// Produces "(a=b,c=1,d=false,e=@(f,1,false),g=(h=i))"</jc>
* String s = UonSerializer.<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 = UonSerializer.<jsf>DEFAULT_SIMPLE</jsf>.serialize(s);
- *
* <jc>// Serialize a bean</jc>
* <jk>public class</jk> Person {
* <jk>public</jk> Person(String s);
@@ -152,11 +122,8 @@ import org.apache.juneau.transform.*;
*
* 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 "$o(name=John Doe,age=23,address=$o(street=123 Main St,city=Anywhere,state=NY,zip=$n(12345)),deceased=$b(false))"</jc>
+ * <jc>// Produces "(name='John Doe',age=23,address=(street='123 Main St',city=Anywhere,state=NY,zip=12345),deceased=false)"</jc>
* String s = UonSerializer.<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 = UonSerializer.<jsf>DEFAULT_SIMPLE</jsf>.serialize(s);
* </p>
*/
@Produces("text/uon")
@@ -165,29 +132,12 @@ public class UonSerializer extends WriterSerializer {
/** Reusable instance of {@link UonSerializer}, all default settings. */
public static final UonSerializer DEFAULT = new UonSerializer().lock();
- /** Reusable instance of {@link UonSerializer.Simple}. */
- public static final UonSerializer DEFAULT_SIMPLE = new Simple().lock();
-
/** Reusable instance of {@link UonSerializer.Readable}. */
public static final UonSerializer DEFAULT_READABLE = new Readable().lock();
/** Reusable instance of {@link UonSerializer.Encoding}. */
public static final UonSerializer DEFAULT_ENCODING = new Encoding().lock();
- /** Reusable instance of {@link UonSerializer.SimpleEncoding}. */
- public static final UonSerializer DEFAULT_SIMPLE_ENCODING = new SimpleEncoding().lock();
-
- /**
- * Equivalent to <code><jk>new</jk> UonSerializer().setSimpleMode(<jk>true</jk>);</code>.
- */
- @Produces(value="text/uon-simple",contentType="text/uon")
- public static class Simple extends UonSerializer {
- /** Constructor */
- public Simple() {
- setSimpleMode(true);
- }
- }
-
/**
* Equivalent to <code><jk>new</jk> UonSerializer().setUseWhitespace(<jk>true</jk>).setUseIndentation(<jk>true</jk>);</code>.
*/
@@ -195,7 +145,6 @@ public class UonSerializer extends WriterSerializer {
/** Constructor */
public Readable() {
setUseWhitespace(true);
- setUseIndentation(true);
}
}
@@ -210,19 +159,6 @@ public class UonSerializer extends WriterSerializer {
}
/**
- * Equivalent to <code><jk>new</jk> UonSerializer().setSimpleMode(<jk>true</jk>).setEncodeChars(<jk>true</jk>);</code>.
- */
- @Produces(value="text/uon-simple",contentType="text/uon")
- public static class SimpleEncoding extends UonSerializer {
- /** Constructor */
- public SimpleEncoding() {
- setSimpleMode(true);
- setEncodeChars(true);
- }
- }
-
-
- /**
* Workhorse method. Determines the type of object, and then calls the
* appropriate type-specific serialization method.
* @param session The context that exist for the duration of a serialize.
@@ -231,25 +167,22 @@ public class UonSerializer extends WriterSerializer {
* @param eType The expected type of the object if this is a bean property.
* @param attrName The bean property name if this is a bean property. <jk>null</jk> if this isn't a bean property being serialized.
* @param pMeta The bean property metadata.
- * @param quoteEmptyStrings <jk>true</jk> if this is the first entry in an array.
- * @param isTop If we haven't recursively called this method.
*
* @return The same writer passed in.
* @throws Exception
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected SerializerWriter serializeAnything(UonSerializerSession session, UonWriter out, Object o, ClassMeta<?> eType,
- String attrName, BeanPropertyMeta pMeta, boolean quoteEmptyStrings, boolean isTop) throws Exception {
+ String attrName, BeanPropertyMeta pMeta) throws Exception {
if (o == null) {
- out.appendObject(null, false, false, isTop);
+ out.appendObject(null, false);
return out;
}
if (eType == null)
eType = object();
- boolean addTypeProperty; // Add "_type" attribute to element?
ClassMeta<?> aType; // The actual type
ClassMeta<?> sType; // The serialized type
@@ -263,7 +196,7 @@ public class UonSerializer extends WriterSerializer {
}
sType = aType.getSerializedClassMeta();
- addTypeProperty = (session.isAddBeanTypeProperties() && ! eType.equals(aType));
+ String typeName = session.getBeanTypeName(eType, aType, pMeta);
// Swap if necessary
PojoSwap swap = aType.getPojoSwap();
@@ -278,14 +211,18 @@ public class UonSerializer extends WriterSerializer {
// '\0' characters are considered null.
if (o == null || (sType.isChar() && ((Character)o).charValue() == 0))
- out.appendObject(null, false, false, isTop);
+ out.appendObject(null, false);
+ else if (sType.isBoolean())
+ out.appendBoolean(o);
+ else if (sType.isNumber())
+ out.appendNumber(o);
else if (sType.isBean())
- serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty);
+ serializeBeanMap(session, out, session.toBeanMap(o), typeName);
else if (sType.isUri() || (pMeta != null && pMeta.isUri()))
- out.appendUri(o, isTop);
+ out.appendUri(o);
else if (sType.isMap()) {
if (o instanceof BeanMap)
- serializeBeanMap(session, out, (BeanMap)o, addTypeProperty);
+ serializeBeanMap(session, out, (BeanMap)o, typeName);
else
serializeMap(session, out, (Map)o, eType);
}
@@ -296,7 +233,7 @@ public class UonSerializer extends WriterSerializer {
serializeCollection(session, out, toList(sType.getInnerClass(), o), eType);
}
else {
- out.appendObject(o, quoteEmptyStrings, false, isTop);
+ out.appendObject(o, false);
}
if (! isRecursion)
@@ -312,7 +249,7 @@ public class UonSerializer extends WriterSerializer {
ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType();
int depth = session.getIndent();
- out.startFlag('o');
+ out.append('(');
Iterator mapEntries = m.entrySet().iterator();
@@ -320,8 +257,8 @@ public class UonSerializer extends WriterSerializer {
Map.Entry e = (Map.Entry) mapEntries.next();
Object value = e.getValue();
Object key = session.generalize(e.getKey(), keyType);
- out.cr(depth).appendObject(key, session.isUseWhitespace(), false, false).append('=');
- serializeAnything(session, out, value, valueType, (key == null ? null : session.toString(key)), null, session.isUseWhitespace(), false);
+ out.cr(depth).appendObject(key, false).append('=');
+ serializeAnything(session, out, value, valueType, (key == null ? null : session.toString(key)), null);
if (mapEntries.hasNext())
out.append(',');
}
@@ -333,14 +270,14 @@ public class UonSerializer extends WriterSerializer {
return out;
}
- private SerializerWriter serializeBeanMap(UonSerializerSession session, UonWriter out, BeanMap<?> m, boolean addTypeProperty) throws Exception {
+ private SerializerWriter serializeBeanMap(UonSerializerSession session, UonWriter out, BeanMap<?> m, String typeName) throws Exception {
int depth = session.getIndent();
- out.startFlag('o');
+ out.append('(');
boolean addComma = false;
- for (BeanPropertyValue p : m.getValues(session.isTrimNulls(), addTypeProperty ? session.createBeanTypeNameProperty(m) : null)) {
+ for (BeanPropertyValue p : m.getValues(session.isTrimNulls(), typeName != null ? session.createBeanTypeNameProperty(m, typeName) : null)) {
BeanPropertyMeta pMeta = p.getMeta();
ClassMeta<?> cMeta = p.getClassMeta();
@@ -356,9 +293,9 @@ public class UonSerializer extends WriterSerializer {
if (addComma)
out.append(',');
- out.cr(depth).appendObject(key, false, false, false).append('=');
+ out.cr(depth).appendObject(key, false).append('=');
- serializeAnything(session, out, value, cMeta, key, pMeta, false, false);
+ serializeAnything(session, out, value, cMeta, key, pMeta);
addComma = true;
}
@@ -377,14 +314,13 @@ public class UonSerializer extends WriterSerializer {
c = session.sort(c);
- out.startFlag('a');
+ out.append('@').append('(');
int depth = session.getIndent();
- boolean quoteEmptyString = (c.size() == 1 || session.isUseWhitespace());
for (Iterator i = c.iterator(); i.hasNext();) {
out.cr(depth);
- serializeAnything(session, out, i.next(), elementType, "<iterator>", null, quoteEmptyString, false);
+ serializeAnything(session, out, i.next(), elementType, "<iterator>", null);
if (i.hasNext())
out.append(',');
}
@@ -409,7 +345,7 @@ public class UonSerializer extends WriterSerializer {
@Override /* Serializer */
protected void doSerialize(SerializerSession session, Object o) throws Exception {
UonSerializerSession s = (UonSerializerSession)session;
- serializeAnything(s, s.getWriter(), o, null, "root", null, false, true);
+ serializeAnything(s, s.getWriter(), o, null, "root", null);
}
@@ -418,106 +354,6 @@ public class UonSerializer extends WriterSerializer {
//--------------------------------------------------------------------------------
/**
- * <b>Configuration property:</b> Use simplified output.
- * <p>
- * <ul>
- * <li><b>Name:</b> <js>"UonSerializer.simpleMode"</js>
- * <li><b>Data type:</b> <code>Boolean</code>
- * <li><b>Default:</b> <jk>false</jk>
- * <li><b>Session-overridable:</b> <jk>true</jk>
- * </ul>
- * <p>
- * If <jk>true</jk>, type flags will not be prepended to values in most cases.
- * <p>
- * Use this setting if the data types of the values (e.g. object/array/boolean/number/string)
- * is known on the receiving end.
- * <p>
- * It should be noted that the default behavior produces a data structure that can
- * be losslessly converted into JSON, and any JSON can be losslessly represented
- * in a URL-encoded value. However, this strict equivalency does not exist
- * when simple mode is used.
- * <p>
- * <table class='styled'>
- * <tr>
- * <th>Input (in JSON)</th>
- * <th>Normal mode output</th>
- * <th>Simple mode output</th>
- * </tr>
- * <tr>
- * <td class='code'>{foo:'bar',baz:'bing'}</td>
- * <td class='code'>$o(foo=bar,baz=bing)</td>
- * <td class='code'>(foo=bar,baz=bing)</td>
- * </tr>
- * <tr>
- * <td class='code'>{foo:{bar:'baz'}}</td>
- * <td class='code'>$o(foo=$o(bar=baz))</td>
- * <td class='code'>(foo=(bar=baz))</td>
- * </tr>
- * <tr>
- * <td class='code'>['foo','bar']</td>
- * <td class='code'>$a(foo,bar)</td>
- * <td class='code'>(foo,bar)</td>
- * </tr>
- * <tr>
- * <td class='code'>['foo',['bar','baz']]</td>
- * <td class='code'>$a(foo,$a(bar,baz))</td>
- * <td class='code'>(foo,(bar,baz))</td>
- * </tr>
- * <tr>
- * <td class='code'>true</td>
- * <td class='code'>$b(true)</td>
- * <td class='code'>true</td>
- * </tr>
- * <tr>
- * <td class='code'>123</td>
- * <td class='code'>$n(123)</td>
- * <td class='code'>123</td>
- * </tr>
- * </table>
- * <p>
- * <h5 class='section'>Notes:</h5>
- * <ul>
- * <li>This is equivalent to calling <code>setProperty(<jsf>UON_simpleMode</jsf>, value)</code>.
- * <li>This introduces a slight performance penalty.
- * </ul>
- *
- * @param value The new value for this property.
- * @return This object (for method chaining).
- * @throws LockedException If {@link #lock()} was called on this class.
- * @see UonSerializerContext#UON_simpleMode
- */
- public UonSerializer setSimpleMode(boolean value) throws LockedException {
- return setProperty(UON_simpleMode, value);
- }
-
- /**
- * <b>Configuration property:</b> Use whitespace.
- * <p>
- * <ul>
- * <li><b>Name:</b> <js>"UonSerializer.useWhitespace"</js>
- * <li><b>Data type:</b> <code>Boolean</code>
- * <li><b>Default:</b> <jk>false</jk>
- * <li><b>Session-overridable:</b> <jk>true</jk>
- * </ul>
- * <p>
- * If <jk>true</jk>, whitespace is added to the output to improve readability.
- * <p>
- * <h5 class='section'>Notes:</h5>
- * <ul>
- * <li>This is equivalent to calling <code>setProperty(<jsf>UON_useWhitespace</jsf>, value)</code>.
- * <li>This introduces a slight performance penalty.
- * </ul>
- *
- * @param value The new value for this property.
- * @return This object (for method chaining).
- * @throws LockedException If {@link #lock()} was called on this class.
- * @see UonSerializerContext#UON_useWhitespace
- */
- public UonSerializer setUseWhitespace(boolean value) throws LockedException {
- return setProperty(UON_useWhitespace, value);
- }
-
- /**
* <b>Configuration property:</b> Encode non-valid URI characters.
* <p>
* <ul>
@@ -573,8 +409,8 @@ public class UonSerializer extends WriterSerializer {
}
@Override /* Serializer */
- public UonSerializer setUseIndentation(boolean value) throws LockedException {
- super.setUseIndentation(value);
+ public UonSerializer setUseWhitespace(boolean value) throws LockedException {
+ super.setUseWhitespace(value);
return this;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerContext.java
index db0cb2f..65867a5 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerContext.java
@@ -34,80 +34,6 @@ import org.apache.juneau.serializer.*;
public class UonSerializerContext extends SerializerContext {
/**
- * <b>Configuration property:</b> Use simplified output.
- * <p>
- * <ul>
- * <li><b>Name:</b> <js>"UonSerializer.simpleMode"</js>
- * <li><b>Data type:</b> <code>Boolean</code>
- * <li><b>Default:</b> <jk>false</jk>
- * <li><b>Session-overridable:</b> <jk>true</jk>
- * </ul>
- * <p>
- * If <jk>true</jk>, type flags will not be prepended to values in most cases.
- * <p>
- * Use this setting if the data types of the values (e.g. object/array/boolean/number/string)
- * is known on the receiving end.
- * <p>
- * It should be noted that the default behavior produces a data structure that can
- * be losslessly converted into JSON, and any JSON can be losslessly represented
- * in a URL-encoded value. However, this strict equivalency does not exist
- * when simple mode is used.
- * <p>
- * <table class='styled'>
- * <tr>
- * <th>Input (in JSON)</th>
- * <th>Normal mode output</th>
- * <th>Simple mode output</th>
- * </tr>
- * <tr>
- * <td class='code'>{foo:'bar',baz:'bing'}</td>
- * <td class='code'>$o(foo=bar,baz=bing)</td>
- * <td class='code'>(foo=bar,baz=bing)</td>
- * </tr>
- * <tr>
- * <td class='code'>{foo:{bar:'baz'}}</td>
- * <td class='code'>$o(foo=$o(bar=baz))</td>
- * <td class='code'>(foo=(bar=baz))</td>
- * </tr>
- * <tr>
- * <td class='code'>['foo','bar']</td>
- * <td class='code'>$a(foo,bar)</td>
- * <td class='code'>(foo,bar)</td>
- * </tr>
- * <tr>
- * <td class='code'>['foo',['bar','baz']]</td>
- * <td class='code'>$a(foo,$a(bar,baz))</td>
- * <td class='code'>(foo,(bar,baz))</td>
- * </tr>
- * <tr>
- * <td class='code'>true</td>
- * <td class='code'>$b(true)</td>
- * <td class='code'>true</td>
- * </tr>
- * <tr>
- * <td class='code'>123</td>
- * <td class='code'>$n(123)</td>
- * <td class='code'>123</td>
- * </tr>
- * </table>
- */
- public static final String UON_simpleMode = "UonSerializer.simpleMode";
-
- /**
- * <b>Configuration property:</b> Use whitespace.
- * <p>
- * <ul>
- * <li><b>Name:</b> <js>"UonSerializer.useWhitespace"</js>
- * <li><b>Data type:</b> <code>Boolean</code>
- * <li><b>Default:</b> <jk>false</jk>
- * <li><b>Session-overridable:</b> <jk>true</jk>
- * </ul>
- * <p>
- * If <jk>true</jk>, whitespace is added to the output to improve readability.
- */
- public static final String UON_useWhitespace = "UonSerializer.useWhitespace";
-
- /**
* <b>Configuration property:</b> Encode non-valid URI characters.
* <p>
* <ul>
@@ -127,8 +53,6 @@ public class UonSerializerContext extends SerializerContext {
final boolean
- simpleMode,
- useWhitespace,
encodeChars;
/**
@@ -140,8 +64,6 @@ public class UonSerializerContext extends SerializerContext {
*/
public UonSerializerContext(ContextFactory cf) {
super(cf);
- simpleMode = cf.getProperty(UON_simpleMode, boolean.class, false);
- useWhitespace = cf.getProperty(UON_useWhitespace, boolean.class, false);
encodeChars = cf.getProperty(UON_encodeChars, boolean.class, false);
}
@@ -149,8 +71,6 @@ public class UonSerializerContext extends SerializerContext {
public ObjectMap asMap() {
return super.asMap()
.append("UonSerializerContext", new ObjectMap()
- .append("simpleMode", simpleMode)
- .append("useWhitespace", useWhitespace)
.append("encodeChars", encodeChars)
);
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
index f758b99..b10f68e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
@@ -28,7 +28,7 @@ import org.apache.juneau.serializer.*;
*/
public class UonSerializerSession extends SerializerSession {
- private final boolean simpleMode, useWhitespace, encodeChars;
+ private final boolean encodeChars;
/**
* Create a new session using properties specified in the context.
@@ -48,12 +48,8 @@ public class UonSerializerSession extends SerializerSession {
protected UonSerializerSession(UonSerializerContext ctx, ObjectMap op, Object output, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
super(ctx, op, output, javaMethod, locale, timeZone, mediaType);
if (op == null || op.isEmpty()) {
- simpleMode = ctx.simpleMode;
- useWhitespace = ctx.useWhitespace;
encodeChars = ctx.encodeChars;
} else {
- simpleMode = op.getBoolean(UON_simpleMode, ctx.simpleMode);
- useWhitespace = op.getBoolean(UON_useWhitespace, ctx.useWhitespace);
encodeChars = op.getBoolean(UON_encodeChars, ctx.encodeChars);
}
}
@@ -63,25 +59,7 @@ public class UonSerializerSession extends SerializerSession {
Object output = getOutput();
if (output instanceof UonWriter)
return (UonWriter)output;
- return new UonWriter(this, super.getWriter(), useWhitespace, isSimpleMode(), isEncodeChars(), isTrimStrings(), getRelativeUriBase(), getAbsolutePathUriBase());
- }
-
- /**
- * Returns the {@link UonSerializerContext#UON_useWhitespace} setting value for this session.
- *
- * @return The {@link UonSerializerContext#UON_useWhitespace} setting value for this session.
- */
- public final boolean isUseWhitespace() {
- return useWhitespace;
- }
-
- /**
- * Returns the {@link UonSerializerContext#UON_simpleMode} setting value for this session.
- *
- * @return The {@link UonSerializerContext#UON_simpleMode} setting value for this session.
- */
- public final boolean isSimpleMode() {
- return simpleMode;
+ return new UonWriter(this, super.getWriter(), isUseWhitespace(), isEncodeChars(), isTrimStrings(), getRelativeUriBase(), getAbsolutePathUriBase());
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonWriter.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonWriter.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonWriter.java
index 7025620..bfbe5e0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonWriter.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonWriter.java
@@ -28,7 +28,7 @@ import org.apache.juneau.serializer.*;
public final class UonWriter extends SerializerWriter {
private final UonSerializerSession session;
- private final boolean simpleMode, encodeChars;
+ private final boolean encodeChars;
// Characters that do not need to be URL-encoded in strings.
private static final AsciiSet unencodedChars = new AsciiSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;/?:@-_.!*'$(),~=");
@@ -38,10 +38,11 @@ public final class UonWriter extends SerializerWriter {
private static final AsciiSet unencodedCharsAttrName = new AsciiSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;/?:@-_.!*'$(),~");
// Characters that need to be preceeded with an escape character.
- private static final AsciiSet escapedChars = new AsciiSet(",()~=");
+ private static final AsciiSet escapedChars = new AsciiSet("~'");
- // AsciiSet that maps no characters.
- private static final AsciiSet emptyCharSet = new AsciiSet("");
+ private static final AsciiSet needsQuoteChars = new AsciiSet("),=\n\t\r\b\f ");
+
+ private static final AsciiSet maybeNeedsQuotesFirstChar = new AsciiSet("),=\n\t\r\b\f tfn+-.#0123456789");
private static char[] hexArray = "0123456789ABCDEF".toCharArray();
@@ -50,17 +51,15 @@ public final class UonWriter extends SerializerWriter {
*
* @param session The session that created this writer.
* @param out The writer being wrapped.
- * @param useIndentation If <jk>true</jk>, tabs will be used in output.
- * @param simpleMode If <jk>true</jk>, type flags will not be generated in output.
+ * @param useWhitespace If <jk>true</jk>, tabs will be used in output.
* @param encodeChars If <jk>true</jk>, special characters should be encoded.
* @param trimStrings If <jk>true</jk>, strings should be trimmed before they're serialized.
* @param relativeUriBase The base (e.g. <js>https://localhost:9443/contextPath"</js>) for relative URIs (e.g. <js>"my/path"</js>).
* @param absolutePathUriBase The base (e.g. <js>https://localhost:9443"</js>) for relative URIs with absolute paths (e.g. <js>"/contextPath/my/path"</js>).
*/
- protected UonWriter(UonSerializerSession session, Writer out, boolean useIndentation, boolean simpleMode, boolean encodeChars, boolean trimStrings, String relativeUriBase, String absolutePathUriBase) {
- super(out, useIndentation, false, trimStrings, '\'', relativeUriBase, absolutePathUriBase);
+ protected UonWriter(UonSerializerSession session, Writer out, boolean useWhitespace, boolean encodeChars, boolean trimStrings, String relativeUriBase, String absolutePathUriBase) {
+ super(out, useWhitespace, trimStrings, '\'', relativeUriBase, absolutePathUriBase);
this.session = session;
- this.simpleMode = simpleMode;
this.encodeChars = encodeChars;
}
@@ -68,46 +67,43 @@ public final class UonWriter extends SerializerWriter {
* Serializes the specified simple object as a UON string value.
*
* @param o The object being serialized.
- * @param quoteEmptyStrings Special case where we're serializing an array containing an empty string.
* @param isTopAttrName If this is a top-level attribute name we're serializing.
- * @param isTop If this is a top-level value we're serializing.
* @return This object (for method chaining).
* @throws IOException Should never happen.
*/
- protected UonWriter appendObject(Object o, boolean quoteEmptyStrings, boolean isTopAttrName, boolean isTop) throws IOException {
-
- char typeFlag = 0;
+ protected UonWriter appendObject(Object o, boolean isTopAttrName) throws IOException {
+ if (o instanceof Boolean)
+ return appendBoolean(o);
+ if (o instanceof Number)
+ return appendNumber(o);
if (o == null)
- o = "\u0000";
- else if (o.equals("\u0000"))
- typeFlag = 's';
+ return append("null");
String s = session.toString(o);
-// if (trimStrings)
-// s = s.trim();
- if (s.isEmpty()) {
- if (quoteEmptyStrings)
- typeFlag = 's';
- } else if (s.charAt(0) == '(' || s.charAt(0) == '$') {
- typeFlag = 's';
- } else if (useIndentation && (s.indexOf('\n') != -1 || (s.charAt(0) <= ' ' && s.charAt(0) != 0))) {
- // Strings containing newline characters must always be quoted so that they're not confused with whitespace.
- // Also, strings starting with whitespace must be quoted so that the contents are not ignored when whitespace is ignored.
- typeFlag = 's';
- } else if (! simpleMode) {
- if (o instanceof Boolean)
- typeFlag = 'b';
- else if (o instanceof Number)
- typeFlag = 'n';
- }
-
- if (typeFlag != 0)
- startFlag(typeFlag);
+ char c0 = s.isEmpty() ? 0 : s.charAt(0);
+
+ boolean needsQuotes =
+ s.isEmpty()
+ || c0 == '@'
+ || c0 == '('
+ || needsQuoteChars.contains(s)
+ || (
+ maybeNeedsQuotesFirstChar.contains(c0)
+ && (
+ "true".equals(s)
+ || "false".equals(s)
+ || "null".equals(s)
+ || StringUtils.isNumeric(s)
+ )
+ )
+ ;
AsciiSet unenc = (isTopAttrName ? unencodedCharsAttrName : unencodedChars);
- AsciiSet esc = (isTop && typeFlag == 0 ? emptyCharSet : escapedChars);
+ AsciiSet esc = escapedChars;
+ if (needsQuotes)
+ append('\'');
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (esc.contains(c))
@@ -135,24 +131,33 @@ public final class UonWriter extends SerializerWriter {
}
}
}
+ if (needsQuotes)
+ append('\'');
- if (typeFlag != 0)
- append(')');
+ return this;
+ }
+ /**
+ * Appends a boolean value to the output.
+ *
+ * @param o The boolean value to append to the output.
+ * @return This object (for method chaining).
+ * @throws IOException
+ */
+ protected UonWriter appendBoolean(Object o) throws IOException {
+ append(o.toString());
return this;
}
/**
- * Prints <code>$f(</code> in normal mode, and <code>(</code> in simple mode.
+ * Appends a numeric value to the output.
*
- * @param f The flag character.
+ * @param o The numeric value to append to the output.
* @return This object (for method chaining).
* @throws IOException
*/
- protected UonWriter startFlag(char f) throws IOException {
- if (f != 's' && ! simpleMode)
- append('$').append(f);
- append('(');
+ protected UonWriter appendNumber(Object o) throws IOException {
+ append(o.toString());
return this;
}
@@ -170,11 +175,11 @@ public final class UonWriter extends SerializerWriter {
* Appends a URI to the output.
*
* @param uri The URI to append to the output.
- * @param isTop If this is a top-level value we're serializing.
* @return This object (for method chaining).
* @throws IOException
*/
- public SerializerWriter appendUri(Object uri, boolean isTop) throws IOException {
+ @Override
+ public SerializerWriter appendUri(Object uri) throws IOException {
String s = uri.toString();
if (s.indexOf("://") == -1) {
if (StringUtils.startsWith(s, '/')) {
@@ -185,11 +190,10 @@ public final class UonWriter extends SerializerWriter {
append(relativeUriBase);
if (! relativeUriBase.equals("/"))
append("/");
-
}
}
}
- return appendObject(s, false, false, isTop);
+ return appendObject(s, false);
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index 460e919..99e28d1 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -53,9 +53,6 @@ public class UrlEncodingParser extends UonParser {
/** Reusable instance of {@link UrlEncodingParser}. */
public static final UrlEncodingParser DEFAULT = new UrlEncodingParser().lock();
- /** Reusable instance of {@link UrlEncodingParser}. */
- public static final UrlEncodingParser DEFAULT_WS_AWARE = new UrlEncodingParser().setWhitespaceAware(true).lock();
-
/**
* Constructor.
*/
@@ -69,9 +66,8 @@ public class UrlEncodingParser extends UonParser {
eType = (ClassMeta<T>)object();
PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap();
ClassMeta<?> sType = eType.getSerializedClassMeta();
- BeanRegistry breg = session.getBeanRegistry();
- int c = r.peek();
+ int c = r.peekSkipWs();
if (c == '?')
r.read();
@@ -83,7 +79,7 @@ public class UrlEncodingParser extends UonParser {
if (m.containsKey("_value"))
o = m.get("_value");
else
- o = breg.cast(m);
+ o = session.cast(m, null, eType);
} else if (sType.isMap()) {
Map m = (sType.canCreateNewInstance() ? (Map)sType.newInstance() : new ObjectMap(session));
o = parseIntoMap(session, r, m, sType.getKeyType(), sType.getValueType());
@@ -97,7 +93,7 @@ public class UrlEncodingParser extends UonParser {
ClassMeta<Object> valueType = object();
parseIntoMap(session, r, m, string(), valueType);
if (m.containsKey(session.getBeanTypePropertyName()))
- o = breg.cast(m);
+ o = session.cast(m, null, eType);
else if (m.containsKey("_value"))
o = session.convertToType(m.get("_value"), sType);
else if (sType.isCollection()) {
@@ -132,7 +128,7 @@ public class UrlEncodingParser extends UonParser {
if (keyType == null)
keyType = (ClassMeta<K>)string();
- int c = r.peek();
+ int c = r.peekSkipWs();
if (c == -1)
return m;
@@ -152,7 +148,7 @@ public class UrlEncodingParser extends UonParser {
return m;
r.unread();
Object attr = parseAttr(session, r, true);
- currAttr = session.trim(session.convertToType(attr, keyType));
+ currAttr = attr == null ? null : convertAttrToType(session, m, session.trim(attr.toString()), keyType);
state = S2;
c = 0; // Avoid isInEscape if c was '\'
} else if (state == S2) {
@@ -213,7 +209,7 @@ public class UrlEncodingParser extends UonParser {
private <T> BeanMap<T> parseIntoBeanMap(UrlEncodingParserSession session, ParserReader r, BeanMap<T> m) throws Exception {
- int c = r.peek();
+ int c = r.peekSkipWs();
if (c == -1)
return m;
@@ -254,11 +250,7 @@ public class UrlEncodingParser extends UonParser {
if (! currAttr.equals(session.getBeanTypePropertyName())) {
BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
if (pMeta == null) {
- if (m.getMeta().isSubTyped()) {
- m.put(currAttr, "");
- } else {
- onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
- }
+ onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
} else {
session.setCurrentProperty(pMeta);
// In cases of "&foo=", create an empty instance of the value if createable.
@@ -276,13 +268,8 @@ public class UrlEncodingParser extends UonParser {
if (! currAttr.equals(session.getBeanTypePropertyName())) {
BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
if (pMeta == null) {
- if (m.getMeta().isSubTyped()) {
- Object value = parseAnything(session, object(), r.unread(), m.getBean(false), true, null);
- m.put(currAttr, value);
- } else {
- onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
- parseAnything(session, object(), r.unread(), m.getBean(false), true, null); // Read content anyway to ignore it
- }
+ onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
+ parseAnything(session, object(), r.unread(), m.getBean(false), true, null); // Read content anyway to ignore it
} else {
session.setCurrentProperty(pMeta);
if (session.shouldUseExpandedParams(pMeta)) {
@@ -345,7 +332,7 @@ public class UrlEncodingParser extends UonParser {
final int S4=4; // Found valStart, looking for & or end.
try {
- int c = r.peek();
+ int c = r.peekSkipWs();
if (c == '?')
r.read();
@@ -531,7 +518,7 @@ public class UrlEncodingParser extends UonParser {
protected <K,V> Map<K,V> doParseIntoMap(ParserSession session, Map<K,V> m, Type keyType, Type valueType) throws Exception {
UrlEncodingParserSession s = (UrlEncodingParserSession)session;
UonReader r = s.getReader();
- if (r.peek() == '?')
+ if (r.peekSkipWs() == '?')
r.read();
m = parseIntoMap(s, r, m, (ClassMeta<K>)session.getClassMeta(keyType), (ClassMeta<V>)session.getClassMeta(valueType));
return m;
@@ -598,12 +585,6 @@ public class UrlEncodingParser extends UonParser {
return this;
}
- @Override /* UonParser */
- public UrlEncodingParser setWhitespaceAware(boolean value) throws LockedException {
- super.setWhitespaceAware(value);
- return this;
- }
-
@Override /* Parser */
public UrlEncodingParser setTrimStrings(boolean value) throws LockedException {
super.setTrimStrings(value);
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index 232ce6b..04b64d6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -76,46 +76,22 @@ import org.apache.juneau.transform.*;
* 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>=(
+ * <ua>id</ua>=<un>1</un>
+ * &<ua>name</ua>=<us>'John+Smith'</us>,
+ * &<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>,
+ * &<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>,
+ * &<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>,
+ * &<ua>otherIds</ua>=<uk>null</uk>,
+ * &<ua>addresses</ua>=@(
* (
- * <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>
+ * <ua>uri</ua>=<us>http://sample/addressBook/address/1</us>,
+ * <ua>personUri</ua>=<us>http://sample/addressBook/person/1</us>,
+ * <ua>id</ua>=<un>1</un>,
+ * <ua>street</ua>=<us>'100+Main+Street'</us>,
+ * <ua>city</ua>=<us>Anywhereville</us>,
+ * <ua>state</ua>=<us>NY</us>,
+ * <ua>zip</ua>=<un>12345</un>,
+ * <ua>isCurrent</ua>=<uk>true</uk>
* )
* )
* </p>
@@ -126,13 +102,9 @@ import org.apache.juneau.transform.*;
* 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>
+ * <jc>// Produces "a=b&c=1&d=false&e=@(f,1,false)&g=(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);
@@ -151,11 +123,8 @@ import org.apache.juneau.transform.*;
*
* 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>
+ * <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</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>
*/
@Produces("application/x-www-form-urlencoded")
@@ -165,11 +134,8 @@ 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.Expanded}. */
+ public static final UrlEncodingSerializer DEFAULT_EXPANDED = new Expanded().lock();
/** Reusable instance of {@link UrlEncodingSerializer.Readable}. */
public static final UrlEncodingSerializer DEFAULT_READABLE = new Readable().lock();
@@ -182,23 +148,12 @@ public class UrlEncodingSerializer extends UonSerializer {
}
/**
- * Equivalent to <code><jk>new</jk> UrlEncodingSerializer().setSimpleMode(<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() {
- setSimpleMode(true);
- }
- }
-
- /**
* Equivalent to <code><jk>new</jk> UrlEncodingSerializer().setSimpleMode(<jk>true</jk>).setExpandedParams(<jk>true</jk>);</code>.
*/
- @Produces(value="application/x-www-form-urlencoded-simple",contentType="application/x-www-form-urlencoded")
- public static class SimpleExpanded extends Simple {
+ @Produces(value="application/x-www-form-urlencoded",contentType="application/x-www-form-urlencoded")
+ public static class Expanded extends UrlEncodingSerializer {
/** Constructor */
- public SimpleExpanded() {
+ public Expanded() {
setExpandedParams(true);
}
}
@@ -220,7 +175,6 @@ public class UrlEncodingSerializer extends UonSerializer {
@SuppressWarnings({ "rawtypes", "unchecked" })
private SerializerWriter serializeAnything(UrlEncodingSerializerSession session, UonWriter out, Object o) throws Exception {
- boolean addTypeProperty; // Add "_type" attribute to element?
ClassMeta<?> aType; // The actual type
ClassMeta<?> sType; // The serialized type
@@ -230,7 +184,7 @@ public class UrlEncodingSerializer extends UonSerializer {
aType = object();
sType = aType.getSerializedClassMeta();
- addTypeProperty = (session.isAddBeanTypeProperties());
+ String typeName = session.getBeanTypeName(session.object(), aType, null);
// Swap if necessary
PojoSwap swap = aType.getPojoSwap();
@@ -245,18 +199,18 @@ public class UrlEncodingSerializer extends UonSerializer {
if (sType.isMap()) {
if (o instanceof BeanMap)
- serializeBeanMap(session, out, (BeanMap)o, addTypeProperty);
+ serializeBeanMap(session, out, (BeanMap)o, typeName);
else
serializeMap(session, out, (Map)o, sType);
} else if (sType.isBean()) {
- serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty);
+ serializeBeanMap(session, out, session.toBeanMap(o), typeName);
} else if (sType.isCollection()) {
serializeMap(session, out, getCollectionMap((Collection)o), session.getClassMeta(Map.class, Integer.class, sType.getElementType()));
} 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(session, out, o, null, null, null, false, true);
+ super.serializeAnything(session, out, o, null, null, null);
}
session.pop();
@@ -294,15 +248,15 @@ public class UrlEncodingSerializer extends UonSerializer {
while (i.hasNext()) {
if (addAmp)
out.cr(depth).append('&');
- out.appendObject(key, false, true, true).append('=');
- super.serializeAnything(session, out, i.next(), null, (key == null ? null : key.toString()), null, false, true);
+ out.appendObject(key, true).append('=');
+ super.serializeAnything(session, out, i.next(), null, (key == null ? null : key.toString()), null);
addAmp = true;
}
} else {
if (addAmp)
out.cr(depth).append('&');
- out.appendObject(key, false, true, true).append('=');
- super.serializeAnything(session, out, value, valueType, (key == null ? null : key.toString()), null, false, true);
+ out.appendObject(key, true).append('=');
+ super.serializeAnything(session, out, value, valueType, (key == null ? null : key.toString()), null);
addAmp = true;
}
}
@@ -311,12 +265,12 @@ public class UrlEncodingSerializer extends UonSerializer {
}
@SuppressWarnings({ "rawtypes" })
- private SerializerWriter serializeBeanMap(UrlEncodingSerializerSession session, UonWriter out, BeanMap<?> m, boolean addTypeProperty) throws Exception {
+ private SerializerWriter serializeBeanMap(UrlEncodingSerializerSession session, UonWriter out, BeanMap<?> m, String typeName) throws Exception {
int depth = session.getIndent();
boolean addAmp = false;
- for (BeanPropertyValue p : m.getValues(session.isTrimNulls(), addTypeProperty ? session.createBeanTypeNameProperty(m) : null)) {
+ for (BeanPropertyValue p : m.getValues(session.isTrimNulls(), typeName != null ? session.createBeanTypeNameProperty(m, typeName) : null)) {
BeanPropertyMeta pMeta = p.getMeta();
ClassMeta<?> cMeta = p.getClassMeta();
@@ -337,9 +291,9 @@ public class UrlEncodingSerializer extends UonSerializer {
if (addAmp)
out.cr(depth).append('&');
- out.appendObject(key, false, true, true).append('=');
+ out.appendObject(key, true).append('=');
- super.serializeAnything(session, out, i.next(), cMeta.getElementType(), key, pMeta, false, true);
+ super.serializeAnything(session, out, i.next(), cMeta.getElementType(), key, pMeta);
addAmp = true;
}
@@ -347,9 +301,9 @@ public class UrlEncodingSerializer extends UonSerializer {
if (addAmp)
out.cr(depth).append('&');
- out.appendObject(key, false, true, true).append('=');
+ out.appendObject(key, true).append('=');
- super.serializeAnything(session, out, value, cMeta, key, pMeta, false, true);
+ super.serializeAnything(session, out, value, cMeta, key, pMeta);
addAmp = true;
}
@@ -461,18 +415,6 @@ public class UrlEncodingSerializer extends UonSerializer {
}
@Override /* UonSerializer */
- public UrlEncodingSerializer setSimpleMode(boolean value) throws LockedException {
- super.setSimpleMode(value);
- return this;
- }
-
- @Override /* UonSerializer */
- public UrlEncodingSerializer setUseWhitespace(boolean value) throws LockedException {
- super.setUseWhitespace(value);
- return this;
- }
-
- @Override /* UonSerializer */
public UrlEncodingSerializer setEncodeChars(boolean value) throws LockedException {
super.setEncodeChars(value);
return this;
@@ -503,8 +445,8 @@ public class UrlEncodingSerializer extends UonSerializer {
}
@Override /* Serializer */
- public UrlEncodingSerializer setUseIndentation(boolean value) throws LockedException {
- super.setUseIndentation(value);
+ public UrlEncodingSerializer setUseWhitespace(boolean value) throws LockedException {
+ super.setUseWhitespace(value);
return this;
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/Example_HTML.png
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/Example_HTML.png b/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/Example_HTML.png
index ab74763..04dcf41 100644
Binary files a/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/Example_HTML.png and b/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/Example_HTML.png differ
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/Example_UrlEncoding.png
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/Example_UrlEncoding.png b/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/Example_UrlEncoding.png
deleted file mode 100644
index 34de8a7..0000000
Binary files a/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/Example_UrlEncoding.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/097b8103/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/rfc_uon.txt
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/rfc_uon.txt b/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/rfc_uon.txt
index 116a509..a78153f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/rfc_uon.txt
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/doc-files/rfc_uon.txt
@@ -1,7 +1,7 @@
Network Working Group J. Bognar
-Request for Comments: 9999 C. Chaney
-Category: Informational IBM
- Jan 2014
+Request for Comments: 9999
+Category: Informational Salesforce
+ Feb 2017
***DRAFT***
URI Object Notation (UON): Generic Syntax
@@ -38,7 +38,8 @@ Abstract
(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
+ syntax that allows for array and map structures to be
+ 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.
@@ -77,32 +78,17 @@ Abstract
]
}
- Using the "strict" syntax defined in this document, the equivalent
+ Using the 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/
+ 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
@@ -137,146 +123,97 @@ Abstract
2.1. Objects
Objects are values consisting of one or more child name/value pairs.
- The $o() construct is used to define an object.
+ The (...) construct is used to define an object.
Example: A simple map with two key/value pairs:
- a1=$o(b1=x1,b2=x2)
+ a1=(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))
+ 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.
+ The @(...) construct is used to define an array.
Example: An array of two string values:
- a1=$a(x1,x2)
+ a1=@(x1,x2)
Example: A 2-dimensional array:
- a1=$a($a(x1,x2),$a(x3,x4))
+ a1=@(@(x1,x2),@(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))
+ 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.
+ Numbers are represented without constructs.
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
+ Strings are encapsulated in single quote (') characters.
- 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:
+ Example: Simple string values:
- $ , ( ) ~ =
+ a1='foobar'&a2='123'&a3='true'
+
+ The quotes are optional when the string cannot be confused
+ with one of the constructs listed above (i.e. objects/arrays/
+ booleans/numbers/null).
- For example, the string literal "$o(b1=x)" should be
- represented as follows:
+ Example: A simple string value, unquoted:
- 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)
+
+ Strings must be quoted for the following cases:
- Using parentheses, the following construct can be used to represent
- an empty string:
-
- a1=()
+ - The string can be confused with a boolean or number.
+ - The string is empty.
+ - The string contains one or more whitespace characters.
+ - The string starts with one of the following characters:
+ @ (
+ - The string contains any of the following characters:
+ ) , =
- 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
+ For example, the string literal "(b1=x)" should be
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()
+ a1='(b1=x)'
+
+ The tilde character (~) is used for escaping characters to prevent
+ them from being confused with syntax characters.
- 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:
+ The following characters must be escaped in string literals:
- a1=$a(,)
+ ' ~
+
+ Example: The string "foo'bar~baz"
+ a1='foo~'bar~~baz'
+
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:
+ Nulls are represented by the keyword 'null':
- a1=(%00)
+ a1=null
2.8. Top-level attribute names
@@ -301,7 +238,7 @@ Abstract
The following query strings are fully equivalent in structure:
- a1=$o(b1=x1,b2=x2)
+ a1=(b1='x1',b2='x2')
%61%31=%24%6F%28%62%31%3D%78%31%2C%62%32%3D%78%32%29
@@ -313,22 +250,12 @@ Abstract
attrname = (string | null)
value = (var | string | null)
- string = ("(" litchar* ")") | litchar*
+ 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
+ var = ovar | avar | nvar | boolean | number
+ ovar = "(" [pairs] ")"
+ avar = "@(" [values] ")"
pairs = pair ["," pairs]
pair = key "=" value
@@ -345,7 +272,7 @@ Abstract
exp = "e" [("+" | "-")] digit+
litchar = unencoded | encode_seq | escape_seq
- escaped = "$" | "," | "(" | ")" | "~" | "="
+ escaped = "@" | "," | "(" | ")" | "~" | "="
unencoded = alpha | digit |
";" | "/" | "?" | ":" | "@" |
"-" | "_" | "." | "!" | "*" | "'"