Repository: incubator-juneau Updated Branches: refs/heads/master 9caef98a9 -> 068a03346
DynaBean support - checkpoint Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/068a0334 Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/068a0334 Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/068a0334 Branch: refs/heads/master Commit: 068a033466e2b2d315cb51d27e965cb8c6e34119 Parents: 9caef98 Author: JamesBognar <[email protected]> Authored: Wed May 3 12:06:22 2017 -0400 Committer: JamesBognar <[email protected]> Committed: Wed May 3 12:06:22 2017 -0400 ---------------------------------------------------------------------- .../java/org/apache/juneau/jena/RdfParser.java | 4 +- .../org/apache/juneau/jena/RdfSerializer.java | 4 +- .../main/java/org/apache/juneau/BeanMap.java | 38 ++-- .../java/org/apache/juneau/BeanMapEntry.java | 9 +- .../main/java/org/apache/juneau/BeanMeta.java | 14 +- .../org/apache/juneau/BeanPropertyMeta.java | 183 ++++++++++--------- .../org/apache/juneau/BeanPropertyValue.java | 7 +- .../org/apache/juneau/csv/CsvSerializer.java | 3 +- .../java/org/apache/juneau/html/HtmlParser.java | 4 +- .../apache/juneau/internal/DelegateBeanMap.java | 2 +- .../java/org/apache/juneau/json/JsonParser.java | 2 +- .../apache/juneau/msgpack/MsgPackParser.java | 2 +- .../juneau/serializer/SerializerSession.java | 2 +- .../java/org/apache/juneau/uon/UonParser.java | 4 +- .../juneau/urlencoding/UrlEncodingParser.java | 4 +- .../java/org/apache/juneau/xml/XmlParser.java | 18 +- 16 files changed, 162 insertions(+), 138 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/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 ffe2453..91842e6 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 @@ -231,7 +231,7 @@ public class RdfParser extends ReaderParser { BeanMeta<T> bm = m.getMeta(); RdfBeanMeta rbm = bm.getExtendedMeta(RdfBeanMeta.class); if (rbm.hasBeanUri() && r2.getURI() != null) - rbm.getBeanUriProperty().set(m, r2.getURI()); + rbm.getBeanUriProperty().set(m, null, r2.getURI()); for (StmtIterator i = r2.listProperties(); i.hasNext();) { Statement st = i.next(); Property p = st.getPredicate(); @@ -249,7 +249,7 @@ public class RdfParser extends ReaderParser { } else { Object value = parseAnything(session, cm, o, m.getBean(false), pMeta); setName(cm, value, key); - pMeta.set(m, value); + pMeta.set(m, key, value); } } else if (! (p.equals(session.getRootProperty()) || p.equals(session.getTypeProperty()))) { onUnknownProperty(session, key, m, -1, -1); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/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 ecbc618..37b7d2c 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 @@ -279,7 +279,7 @@ public class RdfSerializer extends WriterSerializer { Object uri = null; RdfBeanMeta rbm = (RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class); if (rbm.hasBeanUri()) - uri = rbm.getBeanUriProperty().get(bm); + uri = rbm.getBeanUriProperty().get(bm, null); String uri2 = getUri(session, uri, null); n = m.createResource(uri2); serializeBeanMap(session, bm, (Resource)n, typeName); @@ -294,7 +294,7 @@ public class RdfSerializer extends WriterSerializer { Object uri = null; RdfBeanMeta rbm = (RdfBeanMeta)bm.getMeta().getExtendedMeta(RdfBeanMeta.class); if (rbm.hasBeanUri()) - uri = rbm.getBeanUriProperty().get(bm); + uri = rbm.getBeanUriProperty().get(bm, null); String uri2 = getUri(session, uri, null); n = m.createResource(uri2); serializeBeanMap(session, bm, (Resource)n, typeName); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/juneau-core/src/main/java/org/apache/juneau/BeanMap.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java index 6318255..f74a099 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java @@ -17,6 +17,7 @@ import java.lang.reflect.*; import java.util.*; import org.apache.juneau.annotation.*; +import org.apache.juneau.internal.*; import org.apache.juneau.parser.*; import org.apache.juneau.transform.*; import org.apache.juneau.xml.annotation.*; @@ -213,7 +214,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T if (meta.beanFilter != null) if (meta.beanFilter.writeProperty(this.bean, property, value)) return null; - return p.set(this, value); + return p.set(this, property, value); } /** @@ -272,12 +273,13 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T */ @Override /* Map */ public Object get(Object property) { - BeanPropertyMeta p = meta.properties.get(property); + String pName = StringUtils.toString(property); + BeanPropertyMeta p = getPropertyMeta(pName); if (p == null) return null; - if (meta.beanFilter != null && property != null) - return meta.beanFilter.readProperty(this.bean, property.toString(), p.get(this)); - return p.get(this); + if (meta.beanFilter != null) + return meta.beanFilter.readProperty(this.bean, pName, p.get(this, pName)); + return p.get(this, pName); } /** @@ -336,6 +338,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T */ @Override /* Map */ public Set<String> keySet() { + // TODO - DynaBean return meta.properties.keySet(); } @@ -353,10 +356,10 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T * @return The bean property, or null if the bean has no such property. */ public BeanMapEntry getProperty(String propertyName) { - BeanPropertyMeta p = meta.properties.get(propertyName); + BeanPropertyMeta p = getPropertyMeta(propertyName); if (p == null) return null; - return new BeanMapEntry(this, p); + return new BeanMapEntry(this, p, propertyName); } /** @@ -366,7 +369,10 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T * @return Metadata on the specified property, or <jk>null</jk> if that property does not exist. */ public BeanPropertyMeta getPropertyMeta(String propertyName) { - return meta.properties.get(propertyName); + BeanPropertyMeta bpMeta = meta.properties.get(propertyName); + if (bpMeta == null) + bpMeta = meta.dynaProperty; + return bpMeta; } /** @@ -400,14 +406,19 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T l.add(v); for (BeanPropertyMeta bpm : properties) { try { - Object val = bpm.get(this); - if (val != null || ! ignoreNulls) - l.add(new BeanPropertyValue(bpm, val, null)); + if (bpm.isDyna()) { + for (Map.Entry<String,Object> e : bpm.getDynaMap(this).entrySet()) + l.add(new BeanPropertyValue(bpm, e.getKey(), e.getValue(), null)); + } else { + Object val = bpm.get(this, null); + if (val != null || ! ignoreNulls) + l.add(new BeanPropertyValue(bpm, bpm.getName(), val, null)); + } } catch (Error e) { // Errors should always be uncaught. throw e; } catch (Throwable t) { - l.add(new BeanPropertyValue(bpm, null, t)); + l.add(new BeanPropertyValue(bpm, bpm.getName(), null, t)); } } return l; @@ -454,7 +465,8 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T @Override /* Iterator */ public Map.Entry<String, Object> next() { - return new BeanMapEntry(BeanMap.this, pIterator.next()); + // TODO - DynaBean + return new BeanMapEntry(BeanMap.this, pIterator.next(), null); } @Override /* Iterator */ http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/juneau-core/src/main/java/org/apache/juneau/BeanMapEntry.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMapEntry.java b/juneau-core/src/main/java/org/apache/juneau/BeanMapEntry.java index 9871930..ea5482a 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanMapEntry.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanMapEntry.java @@ -43,16 +43,19 @@ import org.apache.juneau.transform.*; public class BeanMapEntry implements Map.Entry<String,Object> { private final BeanMap<?> beanMap; private final BeanPropertyMeta meta; + private final String pName; /** * Constructor. * * @param beanMap The bean map that this entry belongs to. * @param property The bean property. + * @param pName The bean property name. */ - protected BeanMapEntry(BeanMap<?> beanMap, BeanPropertyMeta property) { + protected BeanMapEntry(BeanMap<?> beanMap, BeanPropertyMeta property, String pName) { this.beanMap = beanMap; this.meta = property; + this.pName = pName; } @Override /* Map.Entry */ @@ -72,7 +75,7 @@ public class BeanMapEntry implements Map.Entry<String,Object> { */ @Override /* Map.Entry */ public Object getValue() { - return meta.get(this.beanMap); + return meta.get(this.beanMap, pName); } /** @@ -93,7 +96,7 @@ public class BeanMapEntry implements Map.Entry<String,Object> { */ @Override /* Map.Entry */ public Object setValue(Object value) { - return meta.set(this.beanMap, value); + return meta.set(this.beanMap, pName, value); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java index a5a894f..ca2cfc6 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java @@ -89,7 +89,7 @@ public class BeanMeta<T> { // Other fields final String typePropertyName; // "_type" property actual name. private final BeanPropertyMeta typeProperty; // "_type" mock bean property. - final BeanPropertyMeta extrasProperty; // "extras" property. + final BeanPropertyMeta dynaProperty; // "extras" property. private final String dictionaryName; // The @Bean.typeName() annotation defined on this bean class. final String notABeanReason; // Readable string explaining why this class wasn't a bean. final BeanRegistry beanRegistry; @@ -115,7 +115,7 @@ public class BeanMeta<T> { this.properties = b.properties == null ? null : Collections.unmodifiableMap(b.properties); this.getterProps = Collections.unmodifiableMap(b.getterProps); this.setterProps = Collections.unmodifiableMap(b.setterProps); - this.extrasProperty = b.extrasProperty; + this.dynaProperty = b.dynaProperty; this.typeVarImpls = b.typeVarImpls == null ? null : Collections.unmodifiableMap(b.typeVarImpls); this.constructor = b.constructor; this.constructorArgs = b.constructorArgs; @@ -133,7 +133,7 @@ public class BeanMeta<T> { Map<String,BeanPropertyMeta> properties; Map<Method,String> getterProps = new HashMap<Method,String>(); Map<Method,String> setterProps = new HashMap<Method,String>(); - BeanPropertyMeta extrasProperty; + BeanPropertyMeta dynaProperty; Map<Class<?>,Class<?>[]> typeVarImpls; Constructor<T> constructor; @@ -351,10 +351,10 @@ public class BeanMeta<T> { dictionaryName = findDictionaryName(this.classMeta); for (Map.Entry<String,BeanPropertyMeta.Builder> e : normalProps.entrySet()) { - if ("*".equals(e.getValue().name)) - extrasProperty = e.getValue().build(); - else - properties.put(e.getKey(), e.getValue().build()); + BeanPropertyMeta pMeta = e.getValue().build(); + if (pMeta.isDyna()) + dynaProperty = pMeta; + properties.put(e.getKey(), pMeta); } // If a beanFilter is defined, look for inclusion and exclusion lists. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java index 99f834c..7aefde7 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java @@ -49,7 +49,7 @@ public class BeanPropertyMeta { private final Field field; // The bean property field (if it has one). private final Method getter, setter; // The bean property getter and setter. private final boolean isUri; // True if this is a URL/URI or annotated with @URI. - private final boolean isPropertyMap; + private final boolean isDyna; // This is a dyna property (i.e. name="*") private final ClassMeta<?> rawTypeMeta, // The real class type of the bean property. @@ -73,7 +73,7 @@ public class BeanPropertyMeta { String name; Field field; Method getter, setter; - private boolean isConstructorArg, isUri; + private boolean isConstructorArg, isUri, isDyna; private ClassMeta<?> rawTypeMeta, typeMeta; private String[] properties; private PojoSwap swap; @@ -164,26 +164,24 @@ public class BeanPropertyMeta { this.beanRegistry = new BeanRegistry(beanContext, parentBeanRegistry, bdClasses.toArray(new Class<?>[0])); - boolean isAnyProperty = "*".equals(name); + isDyna = "*".equals(name); // Do some annotation validation. Class<?> c = rawTypeMeta.getInnerClass(); if (getter != null) { - if (! isParentClass(getter.getReturnType(), c)) - return false; - Class<?>[] pt = getter.getParameterTypes(); - if (isAnyProperty) { - if (pt.length != 1) + if (isDyna) { + if (! isParentClass(Map.class, c)) return false; - if (! pt[0].equals(String.class)) + } else { + if (! isParentClass(getter.getReturnType(), c)) return false; } } if (setter != null) { Class<?>[] pt = setter.getParameterTypes(); - if (pt.length != (isAnyProperty ? 2 : 1)) + if (pt.length != (isDyna ? 2 : 1)) return false; - if (isAnyProperty) { + if (isDyna) { if (pt[0].equals(String.class)) return false; if (! isParentClass(pt[1], c)) @@ -194,8 +192,8 @@ public class BeanPropertyMeta { } } if (field != null) { - if (isAnyProperty) { - if (! isParentClass(field.getType(), Map.class)) + if (isDyna) { + if (! isParentClass(Map.class, field.getType())) return false; } else { if (! isParentClass(field.getType(), c)) @@ -278,34 +276,7 @@ public class BeanPropertyMeta { this.overrideValue = b.overrideValue; this.delegateFor = b.delegateFor; this.extMeta = b.extMeta; - this.isPropertyMap = false; - } - - /** - * Creates a BeanPropertyMeta for an "extras" property. - * <p> - * An extras property is one defined with <code><ja>@BeanProperty</ja>(name=<js>"*"</js>)</code> - * - * @param name The bean property name (e.g. the key if this is a Map field, or the value passed to the getter/setter as the property name). - * @param b The real bean property. - */ - protected BeanPropertyMeta(String name, BeanPropertyMeta b) { - this.field = b.field; - this.getter = b.getter; - this.setter = b.setter; - this.isUri = false; - this.beanMeta = b.beanMeta; - this.beanContext = b.beanContext; - this.name = name; - this.rawTypeMeta = b.rawTypeMeta; - this.typeMeta = b.typeMeta; - this.properties = b.properties; - this.swap = b.swap; - this.beanRegistry = b.beanRegistry; - this.overrideValue = b.overrideValue; - this.delegateFor = b.delegateFor; - this.extMeta = b.extMeta; - this.isPropertyMap = true; + this.isDyna = b.isDyna; } /** @@ -359,7 +330,7 @@ public class BeanPropertyMeta { * <p> * If this property or the property type class has a {@link PojoSwap} associated with it, this * method returns the transformed class meta. - * This matches the class type that is used by the {@link #get(BeanMap)} and {@link #set(BeanMap, Object)} methods. + * This matches the class type that is used by the {@link #get(BeanMap,String)} and {@link #set(BeanMap,String,Object)} methods. * * @return The {@link ClassMeta} of the class of this property. */ @@ -397,6 +368,14 @@ public class BeanPropertyMeta { } /** + * Returns <jk>true</jk> if this bean property is named <js>"*"</js>. + * @return <jk>true</jk> if this bean property is named <js>"*"</js>. + */ + public boolean isDyna() { + return isDyna; + } + + /** * Returns the override list of properties defined through a {@link BeanProperty#properties()} annotation * on this property. * @@ -422,9 +401,10 @@ public class BeanPropertyMeta { * Equivalent to calling {@link BeanMap#get(Object)}, but is faster since it avoids looking up the property meta. * * @param m The bean map to get the transformed value from. + * @param pName The property name. * @return The property value. */ - public Object get(BeanMap<?> m) { + public Object get(BeanMap<?> m, String pName) { try { if (overrideValue != null) return overrideValue; @@ -440,9 +420,9 @@ public class BeanPropertyMeta { throw new BeanRuntimeException(beanMeta.c, "Getter or public field not defined on property ''{0}''", name); if (getter != null) - o = invokeGetter(bean); + o = invokeGetter(bean, pName); else if (field != null) - o = invokeGetField(bean); + o = invokeGetField(bean, pName); return toSerializedForm(m.getBeanSession(), o); @@ -495,11 +475,12 @@ public class BeanPropertyMeta { * looking up the property meta. * * @param m The bean map to set the property value on. + * @param pName The property name. * @param value The value to set. * @return The previous property value. * @throws BeanRuntimeException If property could not be set. */ - public Object set(BeanMap<?> m, Object value) throws BeanRuntimeException { + public Object set(BeanMap<?> m, String pName, Object value) throws BeanRuntimeException { try { BeanSession session = m.getBeanSession(); @@ -529,15 +510,15 @@ public class BeanPropertyMeta { try { - Object r = beanContext.beanMapPutReturnsOldValue || isMap || isCollection ? get(m) : null; + Object r = beanContext.beanMapPutReturnsOldValue || isMap || isCollection ? get(m, pName) : null; Class<?> propertyClass = rawTypeMeta.getInnerClass(); if (value == null && (isMap || isCollection)) { if (setter != null) { - invokeSetter(bean, null); + invokeSetter(bean, pName, null); return r; } else if (field != null) { - invokeSetField(bean, null); + invokeSetField(bean, pName, null); return r; } throw new BeanRuntimeException(beanMeta.c, "Cannot set property ''{0}'' to null because no setter or public field is defined", name); @@ -572,9 +553,9 @@ public class BeanPropertyMeta { } } if (setter != null) - invokeSetter(bean, valueMap); + invokeSetter(bean, pName, valueMap); else - invokeSetField(bean, valueMap); + invokeSetField(bean, pName, valueMap); return r; } throw new BeanRuntimeException(beanMeta.c, "Cannot set property ''{0}'' of type ''{2}'' to object of type ''{2}'' because the assigned map cannot be converted to the specified type because the property type is abstract, and the property value is currently null", name, propertyClass.getName(), findClassName(value)); @@ -583,9 +564,9 @@ public class BeanPropertyMeta { if (propMap == null) { propMap = (Map)propertyClass.newInstance(); if (setter != null) - invokeSetter(bean, propMap); + invokeSetter(bean, pName, propMap); else if (field != null) - invokeSetField(bean, propMap); + invokeSetField(bean, pName, propMap); else throw new BeanRuntimeException(beanMeta.c, "Cannot set property ''{0}'' of type ''{1}'' to object of type ''{2}'' because no setter or public field is defined on this property, and the existing property value is null", name, propertyClass.getName(), findClassName(value)); } else { @@ -634,9 +615,9 @@ public class BeanPropertyMeta { valueList = l; } if (setter != null) - invokeSetter(bean, valueList); + invokeSetter(bean, pName, valueList); else - invokeSetField(bean, valueList); + invokeSetField(bean, pName, valueList); return r; } throw new BeanRuntimeException(beanMeta.c, "Cannot set property ''{0}'' of type ''{1}'' to object of type ''{2}'' because the assigned map cannot be converted to the specified type because the property type is abstract, and the property value is currently null", name, propertyClass.getName(), findClassName(value)); @@ -646,9 +627,9 @@ public class BeanPropertyMeta { if (propList == null) { propList = (Collection)propertyClass.newInstance(); if (setter != null) - invokeSetter(bean, propList); + invokeSetter(bean, pName, propList); else if (field != null) - invokeSetField(bean, propList); + invokeSetField(bean, pName, propList); else throw new BeanRuntimeException(beanMeta.c, "Cannot set property ''{0}'' of type ''{1}'' to object of type ''{2}'' because no setter is defined on this property, and the existing property value is null", name, propertyClass.getName(), findClassName(value)); } else { @@ -670,9 +651,9 @@ public class BeanPropertyMeta { value = session.convertToType(value, rawTypeMeta); } if (setter != null) - invokeSetter(bean, value); + invokeSetter(bean, pName, value); else if (field != null) - invokeSetField(bean, value); + invokeSetField(bean, pName, value); } return r; @@ -693,39 +674,58 @@ public class BeanPropertyMeta { } } - private Object invokeGetter(Object bean) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { - if (isPropertyMap) - return getter.invoke(bean, name); + private Object invokeGetter(Object bean, String pName) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { + if (isDyna) { + Map m = (Map)getter.invoke(bean); + return (m == null ? null : m.get(pName)); + } return getter.invoke(bean); } - private Object invokeSetter(Object bean, Object val) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { - if (isPropertyMap) - return setter.invoke(bean, name, val); + private Object invokeSetter(Object bean, String pName, Object val) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { + if (isDyna) + return setter.invoke(bean, pName, val); return setter.invoke(bean, val); } - private Object invokeGetField(Object bean) throws IllegalArgumentException, IllegalAccessException { - if (isPropertyMap) { + private Object invokeGetField(Object bean, String pName) throws IllegalArgumentException, IllegalAccessException { + if (isDyna) { Map m = (Map)field.get(bean); - if (m != null) - return m.get(name); - return null; + return (m == null ? null : m.get(pName)); } return field.get(bean); } - private void invokeSetField(Object bean, Object val) throws IllegalArgumentException, IllegalAccessException { - if (isPropertyMap) { + private void invokeSetField(Object bean, String pName, Object val) throws IllegalArgumentException, IllegalAccessException { + if (isDyna) { Map m = (Map)field.get(bean); if (m != null) - m.put(name, val); + m.put(pName, val); } else { field.set(bean, val); } } /** + * Returns the {@link Map} object returned by the DynaBean getter. + * <p> + * The DynaBean property is the property whose name is <js>"*"</js> and returns a map of "extra" properties on the bean. + * + * @param bean The bean. + * @return The map returned by the getter, or an empty map if the getter returned <jk>null</jk> or this isn't a DynaBean property. + * @throws IllegalArgumentException Thrown by method invocation. + * @throws IllegalAccessException Thrown by method invocation. + * @throws InvocationTargetException Thrown by method invocation. + */ + public Map<String,Object> getDynaMap(Object bean) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { + if (isDyna) { + Map<String,Object> m = (Map<String,Object>)getter.invoke(bean); + return m == null ? Collections.EMPTY_MAP : m; + } + return Collections.EMPTY_MAP; + } + + /** * Sets an array field on this bean. * Works on both <code>Object</code> and primitive arrays. * @@ -736,11 +736,12 @@ public class BeanPropertyMeta { * @throws InvocationTargetException Thrown by method invocation. */ protected void setArray(Object bean, List l) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { + String pName = name; // TODO DynaBean Object array = ArrayUtils.toArray(l, this.rawTypeMeta.getElementType().getInnerClass()); if (setter != null) - invokeSetter(bean, array); + invokeSetter(bean, pName, array); else if (field != null) - invokeSetField(bean, array); + invokeSetField(bean, pName, array); else throw new BeanRuntimeException(beanMeta.c, "Attempt to initialize array property ''{0}'', but no setter or field defined.", name); } @@ -756,6 +757,8 @@ public class BeanPropertyMeta { */ public void add(BeanMap<?> m, Object value) throws BeanRuntimeException { + String pName = name; // TODO DynaBean + // Read-only beans get their properties stored in a cache. if (m.bean == null) { if (! m.propertyCache.containsKey(name)) @@ -782,9 +785,9 @@ public class BeanPropertyMeta { if (isCollection) { Collection c = null; if (getter != null) { - c = (Collection)invokeGetter(bean); + c = (Collection)invokeGetter(bean, pName); } else if (field != null) { - c = (Collection)invokeGetField(bean); + c = (Collection)invokeGetField(bean, pName); } else { throw new BeanRuntimeException(beanMeta.c, "Attempt to append to collection property ''{0}'', but no getter or field defined.", name); } @@ -802,9 +805,9 @@ public class BeanPropertyMeta { c.add(v); if (setter != null) - invokeSetter(bean, c); + invokeSetter(bean, pName, c); else if (field != null) - invokeSetField(bean, c); + invokeSetField(bean, pName, c); else throw new BeanRuntimeException(beanMeta.c, "Attempt to initialize collection property ''{0}'', but no setter or field defined.", name); @@ -821,9 +824,9 @@ public class BeanPropertyMeta { // Copy any existing array values into the temporary list. Object oldArray; if (getter != null) - oldArray = invokeGetter(bean); + oldArray = invokeGetter(bean, pName); else if (field != null) - oldArray = invokeGetField(bean); + oldArray = invokeGetField(bean, pName); else throw new BeanRuntimeException(beanMeta.c, "Attempt to append to array property ''{0}'', but no getter or field defined.", name); ArrayUtils.copyToList(oldArray, l); @@ -850,6 +853,8 @@ public class BeanPropertyMeta { */ public void add(BeanMap<?> m, String key, Object value) throws BeanRuntimeException { + String pName = name; // TODO DynaBean + // Read-only beans get their properties stored in a cache. if (m.bean == null) { if (! m.propertyCache.containsKey(name)) @@ -876,9 +881,9 @@ public class BeanPropertyMeta { if (isMap) { Map map = null; if (getter != null) { - map = (Map)invokeGetter(bean); + map = (Map)invokeGetter(bean, pName); } else if (field != null) { - map = (Map)invokeGetField(bean); + map = (Map)invokeGetField(bean, pName); } else { throw new BeanRuntimeException(beanMeta.c, "Attempt to append to map property ''{0}'', but no getter or field defined.", name); } @@ -896,9 +901,9 @@ public class BeanPropertyMeta { map.put(key, v); if (setter != null) - invokeSetter(bean, map); + invokeSetter(bean, pName, map); else if (field != null) - invokeSetField(bean, map); + invokeSetField(bean, pName, map); else throw new BeanRuntimeException(beanMeta.c, "Attempt to initialize map property ''{0}'', but no setter or field defined.", name); @@ -906,9 +911,9 @@ public class BeanPropertyMeta { Object b = null; if (getter != null) { - b = invokeGetter(bean); + b = invokeGetter(bean, pName); } else if (field != null) { - b = invokeGetField(bean); + b = invokeGetField(bean, pName); } else { throw new BeanRuntimeException(beanMeta.c, "Attempt to append to bean property ''{0}'', but no getter or field defined.", name); } @@ -926,9 +931,9 @@ public class BeanPropertyMeta { } if (setter != null) - invokeSetter(bean, b); + invokeSetter(bean, pName, b); else if (field != null) - invokeSetField(bean, b); + invokeSetField(bean, pName, b); else throw new BeanRuntimeException(beanMeta.c, "Attempt to initialize bean property ''{0}'', but no setter or field defined.", name); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/juneau-core/src/main/java/org/apache/juneau/BeanPropertyValue.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyValue.java b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyValue.java index 89b2fcc..de9d796 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyValue.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyValue.java @@ -19,6 +19,7 @@ package org.apache.juneau; public class BeanPropertyValue { private final BeanPropertyMeta pMeta; + private final String name; private final Object value; private final Throwable thrown; @@ -26,11 +27,13 @@ public class BeanPropertyValue { * Constructor. * * @param pMeta The bean property metadata. + * @param name The bean property name. * @param value The bean property value. * @param thrown The exception thrown by calling the property getter. */ - public BeanPropertyValue(BeanPropertyMeta pMeta, Object value, Throwable thrown) { + public BeanPropertyValue(BeanPropertyMeta pMeta, String name, Object value, Throwable thrown) { this.pMeta = pMeta; + this.name = name; this.value = value; this.thrown = thrown; } @@ -56,7 +59,7 @@ public class BeanPropertyValue { * @return The bean property name. */ public final String getName() { - return pMeta.getName(); + return name; } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializer.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializer.java index c2a21df..3578b9f 100644 --- a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializer.java +++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializer.java @@ -57,6 +57,7 @@ public final class CsvSerializer extends WriterSerializer { } else { l = (Collection)o; } + // TODO - Doesn't support DynaBeans. if (l.size() > 0) { ClassMeta entryType = session.getClassMetaForObject(l.iterator().next()); if (entryType.isBean()) { @@ -74,7 +75,7 @@ public final class CsvSerializer extends WriterSerializer { for (BeanPropertyMeta pm : bm.getPropertyMetas()) { if (i++ > 0) out.append(','); - append(out, pm.get(bean)); + append(out, pm.get(bean, pm.getName())); } out.append('\n'); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/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 2095968..3d80c7b 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 @@ -405,7 +405,7 @@ public class HtmlParser extends XmlParser { ClassMeta<?> cm = bpm.getClassMeta(); Object value = parseAnything(session, cm, r, m.getBean(false), false, bpm); setName(cm, value, key); - bpm.set(m, value); + bpm.set(m, key, value); } } l.add(m == null ? null : (E)m.getBean()); @@ -467,7 +467,7 @@ public class HtmlParser extends XmlParser { ClassMeta<?> cm = pMeta.getClassMeta(); Object value = parseAnything(session, cm, r, m.getBean(false), false, pMeta); setName(cm, value, key); - pMeta.set(m, value); + pMeta.set(m, key, value); } } nextTag(r, xTR); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/juneau-core/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java b/juneau-core/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java index e490535..65a204b 100644 --- a/juneau-core/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java +++ b/juneau-core/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java @@ -128,7 +128,7 @@ public class DelegateBeanMap<T> extends BeanMap<T> { Object value; private BeanMapEntryOverride(BeanMap<?> bm, BeanPropertyMeta bpm, Object value) { - super(bm, bpm); + super(bm, bpm, bpm.getName()); this.value = value; } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/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 c07c8b7..92ab945 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 @@ -504,7 +504,7 @@ public class JsonParser extends ReaderParser { ClassMeta<?> cm = pMeta.getClassMeta(); Object value = parseAnything(session, cm, r.unread(), m.getBean(false), pMeta); setName(cm, value, currAttr); - pMeta.set(m, value); + pMeta.set(m, currAttr, value); } session.setCurrentProperty(null); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/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 bd9128c..51ec189 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 @@ -136,7 +136,7 @@ public class MsgPackParser extends InputStreamParser { ClassMeta<?> cm = bpm.getClassMeta(); Object value = parseAnything(session, cm, is, m.getBean(false), bpm); setName(cm, value, pName); - bpm.set(m, value); + bpm.set(m, pName, value); } } o = m.getBean(); http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java index 8164c3c..bbe17fc 100644 --- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java +++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java @@ -691,7 +691,7 @@ public class SerializerSession extends BeanSession { */ public BeanPropertyValue createBeanTypeNameProperty(BeanMap<?> m, String typeName) { BeanMeta<?> bm = m.getMeta(); - return new BeanPropertyValue(bm.getTypeProperty(), typeName, null); + return new BeanPropertyValue(bm.getTypeProperty(), bm.getTypeProperty().getName(), typeName, null); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java index c852379..020a2f4 100644 --- a/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java +++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java @@ -461,7 +461,7 @@ public class UonParser extends ReaderParser { onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol); } else { Object value = session.convertToType("", pMeta.getClassMeta()); - pMeta.set(m, value); + pMeta.set(m, currAttr, value); } } if (c == -1 || c == ')' || c == AMP) @@ -478,7 +478,7 @@ public class UonParser extends ReaderParser { ClassMeta<?> cm = pMeta.getClassMeta(); Object value = parseAnything(session, cm, r.unread(), m.getBean(false), false, pMeta); setName(cm, value, currAttr); - pMeta.set(m, value); + pMeta.set(m, currAttr, value); session.setCurrentProperty(null); } } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/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 119c9c1..eb8c083 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 @@ -276,7 +276,7 @@ public class UrlEncodingParser extends UonParser { // Otherwise, leave it null. ClassMeta<?> cm = pMeta.getClassMeta(); if (cm.canCreateNewInstance()) - pMeta.set(m, cm.newInstance()); + pMeta.set(m, currAttr, cm.newInstance()); session.setCurrentProperty(null); } } @@ -300,7 +300,7 @@ public class UrlEncodingParser extends UonParser { ClassMeta<?> cm = pMeta.getClassMeta(); Object value = parseAnything(session, cm, r.unread(), m.getBean(false), true, pMeta); setName(cm, value, currAttr); - pMeta.set(m, value); + pMeta.set(m, currAttr, value); } session.setCurrentProperty(null); } http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/068a0334/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 5213c9c..3d38abc 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 @@ -165,7 +165,7 @@ public class XmlParser extends ReaderParser { ClassMeta<?> cm = m.getMeta().getClassMeta(); Object value = parseAnything(session, cm, currAttr, r, m.getBean(false), false, null); setName(cm, value, currAttr); - bpm.set(m, value); + bpm.set(m, currAttr, value); o = m.getBean(); } else { BeanMap m = session.newBeanMap(outer, sType.getInnerClass()); @@ -284,7 +284,7 @@ public class XmlParser extends ReaderParser { onUnknownProperty(session, key, m, l.getLineNumber(), l.getColumnNumber()); } } else { - bpm.set(m, val); + bpm.set(m, key, val); } } @@ -309,7 +309,7 @@ public class XmlParser extends ReaderParser { l = new LinkedList<Object>(); l.add(session.getText(r, false)); } else { - cp.set(m, session.getText(r, trim)); + cp.set(m, null, session.getText(r, trim)); } } else if (cpf != ELEMENTS) { String s = session.getText(r, trim); @@ -342,7 +342,7 @@ public class XmlParser extends ReaderParser { l = new LinkedList<Object>(); l.add(session.parseWhitespaceElement(r)); } else { - cp.set(m, session.parseWhitespaceElement(r)); + cp.set(m, null, session.parseWhitespaceElement(r)); } } else { if (cpcm.isCollectionOrArray()) { @@ -350,7 +350,7 @@ public class XmlParser extends ReaderParser { l = new LinkedList<Object>(); l.add(parseAnything(session, cpcm.getElementType(), cp.getName(), r, m.getBean(false), false, cp)); } else { - cp.set(m, parseAnything(session, cpcm, cp.getName(), r, m.getBean(false), false, cp)); + cp.set(m, null, parseAnything(session, cpcm, cp.getName(), r, m.getBean(false), false, cp)); } } } else if (cp != null && cpf == ELEMENTS) { @@ -371,13 +371,13 @@ public class XmlParser extends ReaderParser { setName(et, value, currAttr); pMeta.add(m, value); } else if (xf == ATTR) { - pMeta.set(m, session.getAttributeValue(r, 0)); + pMeta.set(m, currAttr, session.getAttributeValue(r, 0)); r.nextTag(); } else { ClassMeta<?> cm = pMeta.getClassMeta(); Object value = parseAnything(session, cm, currAttr, r, m.getBean(false), false, pMeta); setName(cm, value, currAttr); - pMeta.set(m, value); + pMeta.set(m, currAttr, value); } session.setCurrentProperty(null); } @@ -399,9 +399,9 @@ public class XmlParser extends ReaderParser { } while (depth >= 0); if (sb != null && cp != null) - cp.set(m, sb.toString()); + cp.set(m, null, sb.toString()); else if (l != null && cp != null) - cp.set(m, XmlUtils.collapseTextNodes(l)); + cp.set(m, null, XmlUtils.collapseTextNodes(l)); session.returnStringBuilder(sb); return m;
