Repository: incubator-juneau Updated Branches: refs/heads/master 88d1d38ca -> 21fcc1197
Eliminate support for toObjectMap() method on classes. Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/21fcc119 Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/21fcc119 Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/21fcc119 Branch: refs/heads/master Commit: 21fcc1197e3d954ebb0fa60b895f43e347b6b19f Parents: 88d1d38 Author: JamesBognar <[email protected]> Authored: Sun Feb 5 12:48:40 2017 -0500 Committer: JamesBognar <[email protected]> Committed: Sun Feb 5 12:48:40 2017 -0500 ---------------------------------------------------------------------- .../java/org/apache/juneau/jena/RdfParser.java | 2 +- .../org/apache/juneau/jena/RdfSerializer.java | 5 - .../a/rttests/RoundTripToObjectMapsTest.java | 2 +- .../juneau/dto/html5/HtmlTemplatesTest.java | 19 +-- .../java/org/apache/juneau/BeanSession.java | 2 +- .../main/java/org/apache/juneau/ClassMeta.java | 102 ++++++-------- .../java/org/apache/juneau/html/HtmlParser.java | 2 +- .../org/apache/juneau/html/HtmlSerializer.java | 4 - .../java/org/apache/juneau/json/JsonParser.java | 2 +- .../org/apache/juneau/json/JsonSerializer.java | 2 - .../apache/juneau/msgpack/MsgPackParser.java | 2 +- .../juneau/msgpack/MsgPackSerializer.java | 2 - .../apache/juneau/urlencoding/UonParser.java | 2 +- .../juneau/urlencoding/UonSerializer.java | 2 - .../juneau/urlencoding/UrlEncodingParser.java | 2 +- .../urlencoding/UrlEncodingSerializer.java | 2 - .../java/org/apache/juneau/xml/XmlParser.java | 2 +- .../apache/juneau/xml/XmlSchemaSerializer.java | 6 +- .../org/apache/juneau/xml/XmlSerializer.java | 10 +- juneau-core/src/main/javadoc/overview.html | 141 ++++++++++++++++++- 20 files changed, 206 insertions(+), 107 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java ---------------------------------------------------------------------- diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java index 26a9697..b18ab15 100644 --- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java +++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java @@ -329,7 +329,7 @@ public class RdfParser extends ReaderParser { return null; Map m = new ObjectMap(session); parseIntoMap(session, r, m, eType.getKeyType(), eType.getValueType()); - o = sType.newInstanceFromObjectMap(outer, (ObjectMap)m); + o = sType.newInstanceFromObjectMap(session, outer, (ObjectMap)m); } else if (sType.canCreateNewBean(outer)) { Resource r = n.asResource(); if (session.wasAlreadyProcessed(r)) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java index c579001..461decb 100644 --- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java +++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java @@ -225,11 +225,6 @@ public class RdfSerializer extends WriterSerializer { serializeMap(session, m2, (Resource)n, sType); } - } else if (sType.hasToObjectMapMethod()) { - Map m2 = sType.toObjectMap(o); - n = m.createResource(); - serializeMap(session, m2, (Resource)n, sType); - } else if (sType.isBean()) { BeanMap bm = session.toBeanMap(o); Object uri = null; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java ---------------------------------------------------------------------- diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java index 4a9ada9..3c7b33a 100755 --- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java +++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java @@ -69,7 +69,7 @@ public class RoundTripToObjectMapsTest extends RoundTripTest { this.f1 = m.getString("f1"); this.f2 = m.getInt("f2"); } - public ObjectMap toObjectMap() { + public ObjectMap swap(BeanSession session) { return new ObjectMap().append("f1",f1).append("f2",f2); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/HtmlTemplatesTest.java ---------------------------------------------------------------------- diff --git a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/HtmlTemplatesTest.java b/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/HtmlTemplatesTest.java index 93073bc..6606228 100644 --- a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/HtmlTemplatesTest.java +++ b/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/HtmlTemplatesTest.java @@ -48,11 +48,11 @@ public class HtmlTemplatesTest { return Arrays.asList(new Object[][] { { "FormTemplate-1", - new FormTemplate("myaction", "foo", "bar"), - "<form action='myaction'><input type='text' name='v1' value='foo'/><input type='text' name='v2' value='bar'/></form>", - "<form action='myaction'><input type='text' name='v1' value='foo'/><input type='text' name='v2' value='bar'/></form>\n", - "<form action='myaction'><input type='text' name='v1' value='foo'/><input type='text' name='v2' value='bar'/></form>", - "<form action='myaction'><input type='text' name='v1' value='foo'/><input type='text' name='v2' value='bar'/></form>\n", + new FormTemplate("myaction", 123, true), + "<form action='myaction'><input type='text' name='v1' value='123'/><input type='text' name='v2' value='true'/></form>", + "<form action='myaction'><input type='text' name='v1' value='123'/><input type='text' name='v2' value='true'/></form>\n", + "<form action='myaction'><input type='text' name='v1' value='123'/><input type='text' name='v2' value='true'/></form>", + "<form action='myaction'><input type='text' name='v1' value='123'/><input type='text' name='v2' value='true'/></form>\n", }, }); } @@ -62,15 +62,16 @@ public class HtmlTemplatesTest { public static class FormTemplate { private String action; - private String value1, value2; + private int value1; + private boolean value2; public FormTemplate(Form f) { this.action = f.getAttr("action"); - this.value1 = ((Input)f.getChildren().get(0)).getAttr("value"); - this.value2 = ((Input)f.getChildren().get(1)).getAttr("value"); + this.value1 = f.getChild(Input.class, 0).getAttr(int.class, "value"); + this.value2 = f.getChild(Input.class, 1).getAttr(boolean.class, "value"); } - public FormTemplate(String action, String value1, String value2) { + public FormTemplate(String action, int value1, boolean value2) { this.action = action; this.value1 = value1; this.value2 = value2; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/BeanSession.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java index 2f01534..e7a405d 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java @@ -555,7 +555,7 @@ public class BeanSession extends Session { return newBeanMap(tc).load((Map<?,?>) value).getBean(); if (type.canCreateNewInstanceFromObjectMap(outer) && value instanceof ObjectMap) - return type.newInstanceFromObjectMap(outer, (ObjectMap)value); + return type.newInstanceFromObjectMap(this, outer, (ObjectMap)value); if (type.canCreateNewInstanceFromNumber(outer) && value instanceof Number) return type.newInstanceFromNumber(this, outer, (Number)value); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java index fe22629..74027e6 100644 --- a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java @@ -67,14 +67,13 @@ public final class ClassMeta<T> implements Type { private final Constructor<T> stringConstructor, // The X(String) constructor (if it has one). numberConstructor, // The X(Number) constructor (if it has one). - swapConstructor, // The X(Swappable) constructor (if it has one). - objectMapConstructor; // The X(ObjectMap) constructor (if it has one). + swapConstructor; // The X(Swappable) constructor (if it has one). private final Class<?> swapMethodType, // The class type of the object in the number constructor. numberConstructorType; private final Method - toObjectMapMethod, // The toObjectMap() method (if it has one). swapMethod, // The swap() method (if it has one). + unswapMethod, // The unswap() method (if it has one). namePropertyMethod, // The method to set the name on an object (if it has one). parentPropertyMethod; // The method to set the parent on an object (if it has one). private final boolean @@ -139,7 +138,7 @@ public final class ClassMeta<T> implements Type { // We always immediately add this class meta to the bean context cache so that we can resolve recursive references. if (beanContext != null && beanContext.cmCache != null) - beanContext.cmCache.putIfAbsent(innerClass, this); + beanContext.cmCache.put(innerClass, this); this.implClass = implClass; this.childPojoSwaps = childPojoSwaps; @@ -151,14 +150,13 @@ public final class ClassMeta<T> implements Type { boolean _isDelegate = false; Method _fromStringMethod = null, - _toObjectMapMethod = null, _swapMethod = null, + _unswapMethod = null, _parentPropertyMethod = null, _namePropertyMethod = null; Constructor<T> _noArgConstructor = null, _stringConstructor = null, - _objectMapConstructor = null, _swapConstructor = null, _numberConstructor = null; Class<?> @@ -272,17 +270,13 @@ public final class ClassMeta<T> implements Type { _fromStringMethod = LocaleAsString.class.getMethod("fromString", String.class); } catch (NoSuchMethodException e1) {} - // Find toObjectMap() method if present. + // Find swap() method if present. for (Method m : c.getMethods()) { if (isPublic(m) && isNotDeprecated(m) && ! isStatic(m)) { String mName = m.getName(); - if (mName.equals("toObjectMap")) { - if (m.getParameterTypes().length == 0 && m.getReturnType() == ObjectMap.class) { - _toObjectMapMethod = m; - break; - } - } else if (mName.equals("swap")) { - if (m.getParameterTypes().length == 1 && m.getParameterTypes()[0] == BeanSession.class) { + if (mName.equals("swap")) { + Class<?>[] pt = m.getParameterTypes(); + if (pt.length == 1 && pt[0] == BeanSession.class) { _swapMethod = m; _swapMethodType = m.getReturnType(); break; @@ -290,6 +284,21 @@ public final class ClassMeta<T> implements Type { } } } + // Find unswap() method if present. + if (_swapMethod != null) { + for (Method m : c.getMethods()) { + if (isPublic(m) && isNotDeprecated(m) && isStatic(m)) { + String mName = m.getName(); + if (mName.equals("unswap")) { + Class<?>[] pt = m.getParameterTypes(); + if (pt.length == 2 && pt[0] == BeanSession.class && pt[1] == _swapMethodType) { + _unswapMethod = m; + break; + } + } + } + } + } // Find @NameProperty and @ParentProperty methods if present. for (Method m : c.getDeclaredMethods()) { @@ -316,8 +325,6 @@ public final class ClassMeta<T> implements Type { Class<?> arg = args[(isMemberClass ? 1 : 0)]; if (arg == String.class) _stringConstructor = cs; - else if (ObjectMap.class.isAssignableFrom(arg)) - _objectMapConstructor = cs; else if (_swapMethodType != null && _swapMethodType.isAssignableFrom(arg)) _swapConstructor = cs; else if (_cc != NUMBER && (Number.class.isAssignableFrom(arg) || (arg.isPrimitive() && (arg == int.class || arg == short.class || arg == long.class || arg == float.class || arg == double.class)))) { @@ -388,11 +395,14 @@ public final class ClassMeta<T> implements Type { beanFilter = findBeanFilter(); if (_swapMethod != null) { + final Method fSwapMethod = _swapMethod; + final Method fUnswapMethod = _unswapMethod; + final Constructor<T> fSwapConstructor = _swapConstructor; _pojoSwap = new PojoSwap<T,Object>(c, _swapMethod.getReturnType()) { @Override public Object swap(BeanSession session, Object o) throws SerializeException { try { - return swapMethod.invoke(o, session); + return fSwapMethod.invoke(o, session); } catch (Exception e) { throw new SerializeException(e); } @@ -400,8 +410,10 @@ public final class ClassMeta<T> implements Type { @Override public T unswap(BeanSession session, Object f, ClassMeta<?> hint) throws ParseException { try { - if (swapConstructor != null) - return swapConstructor.newInstance(f); + if (fUnswapMethod != null) + return (T)fUnswapMethod.invoke(null, session, f); + if (fSwapConstructor != null) + return fSwapConstructor.newInstance(f); return super.unswap(session, f, hint); } catch (Exception e) { throw new ParseException(e); @@ -484,14 +496,13 @@ public final class ClassMeta<T> implements Type { this.cc = _cc; this.isDelegate = _isDelegate; this.fromStringMethod = _fromStringMethod; - this.toObjectMapMethod = _toObjectMapMethod; this.swapMethod = _swapMethod; + this.unswapMethod = _unswapMethod; this.swapMethodType = _swapMethodType; this.parentPropertyMethod = _parentPropertyMethod; this.namePropertyMethod =_namePropertyMethod; this.noArgConstructor = _noArgConstructor; this.stringConstructor = _stringConstructor; - this.objectMapConstructor =_objectMapConstructor; this.swapConstructor = _swapConstructor; this.numberConstructor = _numberConstructor; this.numberConstructorType = _numberConstructorType; @@ -529,11 +540,10 @@ public final class ClassMeta<T> implements Type { this.stringConstructor = mainType.stringConstructor; this.numberConstructor = mainType.numberConstructor; this.swapConstructor = mainType.swapConstructor; - this.objectMapConstructor = mainType.objectMapConstructor; this.swapMethodType = mainType.swapMethodType; this.numberConstructorType = mainType.numberConstructorType; - this.toObjectMapMethod = mainType.toObjectMapMethod; this.swapMethod = mainType.swapMethod; + this.unswapMethod = mainType.unswapMethod; this.namePropertyMethod = mainType.namePropertyMethod; this.parentPropertyMethod = mainType.parentPropertyMethod; this.isDelegate = mainType.isDelegate; @@ -1204,24 +1214,16 @@ public final class ClassMeta<T> implements Type { * @return <jk>true</jk> if this class has a no-arg constructor or invocation handler. */ public boolean canCreateNewInstanceFromObjectMap(Object outer) { - if (objectMapConstructor != null) { + // TODO - Get rid of? + if (swapMethodType == ObjectMap.class && (swapConstructor != null || unswapMethod != null)) { if (isMemberClass) - return outer != null && objectMapConstructor.getParameterTypes()[0] == outer.getClass(); + return outer != null && swapConstructor.getParameterTypes()[0] == outer.getClass(); return true; } return false; } /** - * Returns <jk>true</jk> if this class has an <code>ObjectMap toObjectMap()</code> method. - * - * @return <jk>true</jk> if class has a <code>toObjectMap()</code> method. - */ - public boolean hasToObjectMapMethod() { - return toObjectMapMethod != null; - } - - /** * Returns the method annotated with {@link NameProperty @NameProperty}. * * @return The method annotated with {@link NameProperty @NameProperty} or <jk>null</jk> if method does not exist. @@ -1240,23 +1242,6 @@ public final class ClassMeta<T> implements Type { } /** - * Converts an instance of this class to an {@link ObjectMap}. - * - * @param t The object to convert to a map. - * @return The converted object, or <jk>null</jk> if method does not have a <code>toObjectMap()</code> method. - * @throws BeanRuntimeException Thrown by <code>toObjectMap()</code> method invocation. - */ - public ObjectMap toObjectMap(Object t) throws BeanRuntimeException { - try { - if (toObjectMapMethod != null) - return (ObjectMap)toObjectMapMethod.invoke(t); - return null; - } catch (Exception e) { - throw new BeanRuntimeException(e); - } - } - - /** * Returns the reason why this class is not a bean, or <jk>null</jk> if it is a bean. * * @return The reason why this class is not a bean, or <jk>null</jk> if it is a bean. @@ -1363,6 +1348,7 @@ public final class ClassMeta<T> implements Type { * <li><code><jk>public</jk> T(ObjectMap in);</code> * </ul> * + * @param session The current bean session. * @param outer The outer class object for non-static member classes. Can be <jk>null</jk> for non-member or static classes. * @param arg The input argument value. * @return A new instance of the object. @@ -1372,12 +1358,16 @@ public final class ClassMeta<T> implements Type { * does not have one of the methods described above. * @throws InvocationTargetException If the underlying constructor throws an exception. */ - public T newInstanceFromObjectMap(Object outer, ObjectMap arg) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException { - Constructor<T> c = objectMapConstructor; - if (c != null) { + @SuppressWarnings("unchecked") + public T newInstanceFromObjectMap(BeanSession session, Object outer, ObjectMap arg) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException { + // TODO - Get rid of? + if (swapConstructor != null) { if (isMemberClass) - return c.newInstance(outer, arg); - return c.newInstance(arg); + return swapConstructor.newInstance(outer, arg); + return swapConstructor.newInstance(arg); + } + if (unswapMethod != null) { + return (T)unswapMethod.invoke(null, session, arg); } throw new InstantiationError("No map constructor method found for class '"+getInnerClass().getName()+"'"); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java index 1a88144..7757386 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java @@ -177,7 +177,7 @@ public final class HtmlParser extends XmlParser { } else if (sType.canCreateNewInstanceFromObjectMap(outer)) { ObjectMap m = new ObjectMap(session); parseIntoMap(session, r, m, string(), object(), pMeta); - o = sType.newInstanceFromObjectMap(outer, m); + o = sType.newInstanceFromObjectMap(session, outer, m); } else if (sType.canCreateNewBean(outer)) { BeanMap m = session.newBeanMap(outer, sType.getInnerClass()); o = parseIntoBean(session, r, m).getBean(); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java index 995015a..8828409 100644 --- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java @@ -261,10 +261,6 @@ public class HtmlSerializer extends XmlSerializer { out.sTag("boolean").append(o).eTag("boolean"); cr = CR_SIMPLE; - } else if (sType.hasToObjectMapMethod()) { - out.nlIf(! isRoot); - serializeMap(session, out, sType.toObjectMap(o), sType, null, null, typeName, pMeta); - } else if (sType.isMap() || (wType != null && wType.isMap())) { out.nlIf(! isRoot); if (o instanceof BeanMap) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java index e141dd0..3289abe 100644 --- a/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java +++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java @@ -166,7 +166,7 @@ public final class JsonParser extends ReaderParser { } else if (sType.canCreateNewInstanceFromObjectMap(outer)) { ObjectMap m = new ObjectMap(session); parseIntoMap2(session, r, m, string(), object(), pMeta); - o = sType.newInstanceFromObjectMap(outer, m); + o = sType.newInstanceFromObjectMap(session, outer, m); } else if (sType.canCreateNewBean(outer)) { BeanMap m = session.newBeanMap(outer, sType.getInnerClass()); o = parseIntoBeanMap2(session, r, m).getBean(); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java index 43ba2b5..3559590 100644 --- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java @@ -200,8 +200,6 @@ public class JsonSerializer extends WriterSerializer { out.append("null"); else if (sType.isNumber() || sType.isBoolean()) out.append(o); - else if (sType.hasToObjectMapMethod()) - serializeMap(session, out, sType.toObjectMap(o), sType); else if (sType.isBean()) serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty); else if (sType.isUri() || (pMeta != null && pMeta.isUri())) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java index a3f731a..acb5a3c 100644 --- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java +++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java @@ -109,7 +109,7 @@ public final class MsgPackParser extends InputStreamParser { ObjectMap m = new ObjectMap(session); for (int i = 0; i < length; i++) m.put(parseAnything(session, string(), is, outer, pMeta), parseAnything(session, object(), is, m, pMeta)); - o = sType.newInstanceFromObjectMap(outer, m); + o = sType.newInstanceFromObjectMap(session, outer, m); } else if (sType.canCreateNewBean(outer)) { if (dt == MAP) { BeanMap m = session.newBeanMap(outer, sType.getInnerClass()); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java index 93fa938..4e4ed0d 100644 --- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java @@ -91,8 +91,6 @@ public class MsgPackSerializer extends OutputStreamSerializer { out.appendBoolean((Boolean)o); else if (sType.isNumber()) out.appendNumber((Number)o); - else if (sType.hasToObjectMapMethod()) - serializeMap(session, out, sType.toObjectMap(o), sType); else if (sType.isBean()) serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty); else if (sType.isUri() || (pMeta != null && pMeta.isUri())) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/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 79feb29..c6a3b97 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 @@ -157,7 +157,7 @@ public class UonParser extends ReaderParser { } else if (sType.canCreateNewInstanceFromObjectMap(outer)) { ObjectMap m = new ObjectMap(session); parseIntoMap(session, r, m, string(), object(), pMeta); - o = sType.newInstanceFromObjectMap(outer, m); + o = sType.newInstanceFromObjectMap(session, outer, m); } else if (sType.canCreateNewBean(outer)) { BeanMap m = session.newBeanMap(outer, sType.getInnerClass()); m = parseIntoBeanMap(session, r, m); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/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 c65f674..9c752f2 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 @@ -280,8 +280,6 @@ 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); - else if (sType.hasToObjectMapMethod()) - serializeMap(session, out, sType.toObjectMap(o), eType); else if (sType.isBean()) serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty); else if (sType.isUri() || (pMeta != null && pMeta.isUri())) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/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 fac17c9..acb6827 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 @@ -91,7 +91,7 @@ public class UrlEncodingParser extends UonParser { } else if (sType.canCreateNewInstanceFromObjectMap(outer)) { ObjectMap m = new ObjectMap(session); parseIntoMap(session, r, m, string(), object()); - o = sType.newInstanceFromObjectMap(outer, m); + o = sType.newInstanceFromObjectMap(session, outer, m); } else if (sType.canCreateNewBean(outer)) { BeanMap m = session.newBeanMap(outer, sType.getInnerClass()); m = parseIntoBeanMap(session, r, m); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/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 99862d0..e96ef9b 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 @@ -249,8 +249,6 @@ public class UrlEncodingSerializer extends UonSerializer { serializeBeanMap(session, out, (BeanMap)o, addTypeProperty); else serializeMap(session, out, (Map)o, sType); - } else if (sType.hasToObjectMapMethod()) { - serializeMap(session, out, sType.toObjectMap(o), sType); } else if (sType.isBean()) { serializeBeanMap(session, out, session.toBeanMap(o), addTypeProperty); } else if (sType.isCollection()) { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java index b5ec875..0e39e89 100644 --- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java +++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java @@ -144,7 +144,7 @@ public class XmlParser extends ReaderParser { } else if (sType.canCreateNewInstanceFromObjectMap(outer)) { ObjectMap m = new ObjectMap(session); parseIntoMap(session, r, m, string(), object(), pMeta); - o = sType.newInstanceFromObjectMap(outer, m); + o = sType.newInstanceFromObjectMap(session, outer, m); } else if (sType.canCreateNewBean(outer)) { if (sType.getExtendedMeta(XmlClassMeta.class).getFormat() == COLLAPSED) { String fieldName = r.getLocalName(); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java index 3d9782e..35effd0 100644 --- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java @@ -341,7 +341,7 @@ public class XmlSchemaSerializer extends XmlSerializer { w.cTag().nl(); - if (! (cm.isMapOrBean() || cm.hasToObjectMapMethod() || cm.isCollectionOrArray() || (cm.isAbstract() && ! cm.isNumber()) || cm.isObject())) { + if (! (cm.isMapOrBean() || cm.isCollectionOrArray() || (cm.isAbstract() && ! cm.isNumber()) || cm.isObject())) { w.oTag(i+1, "attribute").attr("name", session.getBeanTypePropertyName()).attr("type", "string").ceTag().nl(); } else { @@ -479,7 +479,7 @@ public class XmlSchemaSerializer extends XmlSerializer { } //----- Map ----- - } else if (cm.isMap() || cm.hasToObjectMapMethod() || cm.isAbstract() || cm.isObject()) { + } else if (cm.isMap() || cm.isAbstract() || cm.isObject()) { w.sTag(i+1, "sequence").nl(); w.oTag(i+2, "any") .attr("processContents", "skip") @@ -512,7 +512,7 @@ public class XmlSchemaSerializer extends XmlSerializer { name = "number"; else if (cm.isCollectionOrArray()) name = "array"; - else if (! (cm.isMapOrBean() || cm.hasToObjectMapMethod() || cm.isCollectionOrArray() || cm.isObject() || cm.isAbstract())) + else if (! (cm.isMapOrBean() || cm.isCollectionOrArray() || cm.isObject() || cm.isAbstract())) name = "string"; else name = "object"; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java index 006b32d..e8e0bbf 100644 --- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java @@ -373,7 +373,7 @@ public class XmlSerializer extends WriterSerializer { type = NUMBER; } else if (sType.isBoolean()) { type = BOOLEAN; - } else if (sType.isMapOrBean() || sType.hasToObjectMapMethod()) { + } else if (sType.isMapOrBean()) { isCollapsed = sType.getExtendedMeta(XmlClassMeta.class).getFormat() == COLLAPSED; type = OBJECT; } else if (sType.isCollectionOrArray()) { @@ -406,7 +406,7 @@ public class XmlSerializer extends WriterSerializer { } // Do we need a carriage return after the start tag? - boolean cr = o != null && (sType.isMapOrBean() || sType.isCollectionOrArray() || sType.hasToObjectMapMethod()) && ! isMixed; + boolean cr = o != null && (sType.isMapOrBean() || sType.isCollectionOrArray()) && ! isMixed; String en = elementName; if (en == null) { @@ -443,10 +443,10 @@ public class XmlSerializer extends WriterSerializer { o = sType.getPrimitiveDefault(); } - if (o != null && ! (sType.isMapOrBean() || sType.hasToObjectMapMethod())) + if (o != null && ! (sType.isMapOrBean())) out.append('>'); - if (cr && ! (sType.isMapOrBean() || sType.hasToObjectMapMethod())) + if (cr && ! (sType.isMapOrBean())) out.nl(); } @@ -468,8 +468,6 @@ public class XmlSerializer extends WriterSerializer { rc = serializeBeanMap(session, out, (BeanMap)o, elementNamespace, isCollapsed, isMixed); else rc = serializeMap(session, out, (Map)o, sType, eType.getKeyType(), eType.getValueType(), isMixed); - } else if (sType.hasToObjectMapMethod()) { - rc = serializeMap(session, out, sType.toObjectMap(o), sType, null, null, isMixed); } else if (sType.isBean()) { rc = serializeBeanMap(session, out, session.toBeanMap(o), elementNamespace, isCollapsed, isMixed); } else if (sType.isCollection() || (wType != null && wType.isCollection())) { http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/21fcc119/juneau-core/src/main/javadoc/overview.html ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html index 10431b6..b91970d 100644 --- a/juneau-core/src/main/javadoc/overview.html +++ b/juneau-core/src/main/javadoc/overview.html @@ -77,6 +77,7 @@ <li><p><a class='doclink' href='#Core.Transforms'>Transforms</a></p> <ol> <li><p><a class='doclink' href='#Core.PojoSwaps'>PojoSwaps</a></p> + <li><p><a class='doclink' href='#Core.SwapMethods'>Swap methods</a></p> <li><p><a class='doclink' href='#Core.BeanFilters'>BeanFilters and @Bean annotations</a></p> </ol> <li><p><a class='doclink' href='#Core.BeanDictionaries'>Bean Name and Dictionaries</a></p> @@ -742,8 +743,131 @@ </div> <!-- ======================================================================================================== --> + <a id="Core.SwapMethods"></a> + <h4 class='topic' onclick='toggle(this)'>2.6.2 - Swap methods</h4> + <div class='topic'> + <p> + Various methods can be defined on a class directly to affect how it gets serialized. + </p> + <p> + Objects normally serialized to <code>Strings</code> can be parsed back into their original objects by implementing + one of the following methods on the class: + </p> + <ul> + <li><code><jk>public static</jk> T fromString(String)</code> method.<br> + Any of the following method names also work: + <ul> + <li><code>valueOf(String)</code> + <li><code>parse(String)</code> + <li><code>parseString(String)</code> + <li><code>forName(String)</code> + <li><code>forString(String)</code> + </ul> + <li><code><jk>public</jk> T(String)</code> constructor. + </ul> + <p> + Note that these methods cover conversion from several built-in Java types, meaning these can be constructed directly by the parser from strings: + </p> + <ul> + <li><code>fromString(String)</code> - {@link java.util.UUID} + <li><code>valueOf(String)</code> - {@link java.lang.Boolean}, {@link java.lang.Byte}, {@link java.lang.Double}, {@link java.lang.Float}, + {@link java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Short}, {@link java.sql.Date}, {@link java.sql.Time}, {@link java.sql.Timestamp} + <li><code>parse(String)</code> - {@link java.text.DateFormat}, {@link java.text.MessageFormat}, {@link java.text.NumberFormat}, {@link java.util.Date}, {@link java.util.logging.Level} + <li><code>parseString(String)</code> - {@link javax.xml.bind.DatatypeConverter} + <li><code>forName(String)</code> - {@link java.lang.Class} + </ul> + <p> + If you want to force a bean-like class to be serialized as a string, you can use the {@link org.apache.juneau.annotation.BeanIgnore @BeanIgnore} + annotation on the class to force it to be serialized to a string using the <code>toString()</code> method. + </p> + <p> + Serializing to other intermediate objects can be accomplished by defining a swap method directly on the class: + </p> + <ul> + <li><code><jk>public</jk> X swap(BeanSession)</code> method, where <code>X</code> is any serializable object. + </ul> + <p> + The <code>BeanSession</code> parameter allows you access to various information about the current serialization session. + For example, you could provide customized results based on the media type being produced ({@link org.apache.juneau.BeanSession#getMediaType()}). + </p> + <p> + The following example shows how an HTML5 form template object can be created that gets serialized as a populated HTML5 {@link org.apache.juneau.dto.html5.Form} bean. + </p> + <p class='bcode'> + <jk>import static</jk> org.apache.juneau.dto.html5.HtmlBuilder.*; + + <jd>/** + * A simple HTML form template whose serialized form is an HTML5 Form object. + */</jd> + <jk>public class</jk> FormTemplate { + + <jk>private</jk> String <jf>action</jf>; + <jk>private int</jk> <jf>value1</jf>; + <jk>private boolean</jk> <jf>value2</jf>; + + <jk>public</jk> FormTemplate(String action, <jk>int</jk> value1, <jk>boolean</jk> value2) { + <jk>this</jk>.<jf>action</jf> = action; + <jk>this</jk>.<jf>value1</jf> = value1; + <jk>this</jk>.<jf>value2</jf> = value2; + } + + <jk>public</jk> Form swap(BeanSession session) { + <jk>return</jk> <jsm>form</jsm>(<jf>action</jf>, + <jsm>input</jsm>(<js>"text"</js>).name(<js>"v1"</js>).value(<jf>value1</jf>), + <jsm>input</jsm>(<js>"text"</js>).name(<js>"v2"</js>).value(<jf>value2</jf>) + ); + } + } + </p> + <p> + Swapped objects can be converted back into their original form by the parsers by specifying one of the following methods: + </p> + <ul> + <li><code><jk>public static</jk> T unswap(BeanSession, X)</code> method where <code>X</code> is the swap class type. + <li><code><jk>public</jk> T(X)</code> constructor where <code>X</code> is the swap class type. + </ul> + <p> + The following shows how our form template class can be modified to allow the parsers to reconstruct our original object: + </p> + <p class='bcode'> + <jk>import static</jk> org.apache.juneau.dto.html5.HtmlBuilder.*; + + <jd>/** + * A simple HTML form template whose serialized form is an HTML5 Form object. + * This time with parsing support. + */</jd> + <ja>@Bean</ja>(beanDictionary=HtmlBeanDictionary.<jk>class</jk>) + <jk>public class</jk> FormTemplate { + + <jk>private</jk> String <jf>action</jf>; + <jk>private int</jk> <jf>value1</jf>; + <jk>private boolean</jk> <jf>value2</jf>; + + <jc>// Our 'unswap' constructor</jc> + <jk>public</jk> FormTemplate(Form f) { + <jk>this</jk>.<jf>action</jf> = f.getAttr(<js>"action"</js>); + <jk>this</jk>.<jf>value1</jf> = f.getChild(Input.<jk>class</jk>, 0).getAttr(<jk>int</jk>.<jk>class</jk>, <js>"value"</js>); + <jk>this</jk>.<jf>value2</jf> = f.getChild(Input.<jk>class</jk>, 1).getAttr(<jk>boolean</jk>.<jk>class</jk>, <js>"value"</js>); + } + + <jk>public</jk> FormTemplate(String action, <jk>int</jk> value1, <jk>boolean</jk> value2) { + <jk>this</jk>.<jf>action</jf> = action; + <jk>this</jk>.<jf>value1</jf> = value1; + <jk>this</jk>.<jf>value2</jf> = value2; + } + + <jk>public</jk> Form swap(BeanSession session) { + <jk>return</jk> <jsm>form</jsm>(<jf>action</jf>, + <jsm>input</jsm>(<js>"text"</js>).name(<js>"v1"</js>).value(<jf>value1</jf>), + <jsm>input</jsm>(<js>"text"</js>).name(<js>"v2"</js>).value(<jf>value2</jf>) + ); + } + } + </div> + + <!-- ======================================================================================================== --> <a id="Core.BeanFilters"></a> - <h4 class='topic' onclick='toggle(this)'>2.6.2 - BeanFilters and @Bean annotations</h4> + <h4 class='topic' onclick='toggle(this)'>2.6.3 - BeanFilters and @Bean annotations</h4> <div class='topic'> <p> {@link org.apache.juneau.transform.BeanFilter BeanFilters} are used to control aspects of how beans are handled during serialization and parsing. @@ -1127,10 +1251,10 @@ <tr class='light bb' style='background-color:lightyellow'> <td style='text-align:center'>5b</td> <td> - <b>Objects with standardized <code>static T valueOf(ObjectMap)</code>/<code>static T fromObjectMap(ObjectMap)</code> methods, or constructors with an <code>ObjectMap</code> argument, - and having a <code>toObjectMap()</code> method.</b><br> - During serialization, objects are converted to {@link org.apache.juneau.ObjectMap ObjectMaps} using the <code>toObjectMap()</code> method. - During parsing, maps are converted to objects using one of these static methods or constructors. + <b>Objects with standardized <code>Object swap(BeanSession)</code>/<code>static T unswap(BeanSession,Object)</code> methods, or constructors with an <code>Object</code> argument + where the objects are any object on this list.</b><br> + During serialization, normal objects are converted to swapped objects using the <code>swap()</code> method. + During parsing, swapped objects are converted to normal objects using the static method or constructor. </td> <td> </td> <td style='background-color:lightgreen;text-align:center'><b>yes</b></td> @@ -5344,6 +5468,9 @@ <li>{@link org.apache.juneau.transform.PojoSwap#swap(BeanSession,Object)} <li>{@link org.apache.juneau.transform.PojoSwap#unswap(BeanSession,Object,ClassMeta)} </ul> + <li>Replaced support for <code>toObjectMap()</code> and <code>fromObjectMap()/T(ObjectMap)</code> methods with + generalized <code>swap(BeanSession)</code>/<code>unswap(BeanSession,X)</code>/<code>T(BeanSession,X)</code> methods.<br> + See new section <a class='doclink' href='#Core.SwapMethods'>Swap methods</a> for information. <li>Session-level media type now available through {@link org.apache.juneau.BeanSession#getMediaType()} method. Allows for swaps and serializer/parser behavior to be tailored to individual media types. <li>Several new {@link java.util.Calendar} and {@link java.util.Date} swaps: @@ -6994,7 +7121,7 @@ <h6 class='topic'>Other changes</h6> <ul class='spaced-list'> <li>Various new methods added to {@link org.apache.juneau.internal.StringUtils} and {@link org.apache.juneau.internal.ClassUtils}. - <li>Improved support on {@link org.apache.juneau.BeanContext#getClassMetaFromString(String)}.<br> + <li>Improved support on <code><del>BeanContext.getClassMetaFromString(String)</del></code>.<br> Now supports resolving <code>"long[]"</code>, and so forth. <li>{@link org.apache.juneau.rest.labels.ResourceDescription} name parameter is now automatically URL-encoded in links. <li>{@link org.apache.juneau.rest.RestRequest} now correctly handles cases involving URL-encoded characters in the @@ -7028,7 +7155,7 @@ <li>Support for URL-matching and path info containing encoded characters (e.g. <js>'/'</js>) now supported. <li>Removed some lazy-initialization of bean information in {@link org.apache.juneau.ClassMeta} that allowed the removal of some synchronized blocks. - <li>Improved support of {@link org.apache.juneau.BeanContext#getClassMetaFromString(String)}. + <li>Improved support of <code><del>BeanContext.getClassMetaFromString(String)</del></code>. Now supports primitive arrays such as <js>"long[]"</js> in addition to the previous support for the equivalent <js>"[J"</js>. <li>Various new convenience methods added to {@link org.apache.juneau.internal.StringUtils} and {@link org.apache.juneau.internal.ClassUtils}. </ul>
