Repository: incubator-juneau Updated Branches: refs/heads/master eb90dd512 -> 88d1d38ca
HTML5 DTO template support. Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/88d1d38c Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/88d1d38c Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/88d1d38c Branch: refs/heads/master Commit: 88d1d38ca9e097ba8a53dfcce2a402f5b0fc52c4 Parents: eb90dd5 Author: JamesBognar <[email protected]> Authored: Sun Feb 5 10:50:52 2017 -0500 Committer: JamesBognar <[email protected]> Committed: Sun Feb 5 10:50:52 2017 -0500 ---------------------------------------------------------------------- .../apache/juneau/dto/html5/HtmlElement.java | 18 +- .../juneau/dto/html5/HtmlElementContainer.java | 24 +++ .../juneau/dto/html5/HtmlElementMixed.java | 24 +++ .../org/apache/juneau/utils/ObjectUtils.java | 175 +++++++++++++++++-- 4 files changed, 223 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/88d1d38c/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java index 69a2023..96ddbcb 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElement.java @@ -17,7 +17,7 @@ import static org.apache.juneau.xml.annotation.XmlFormat.*; import java.util.*; import org.apache.juneau.html.*; -import org.apache.juneau.internal.*; +import org.apache.juneau.utils.*; import org.apache.juneau.xml.annotation.*; /** @@ -70,9 +70,19 @@ public abstract class HtmlElement { * @return The attribute value, or <jk>null</jk> if the named attribute does not exist. */ public String getAttr(String key) { - if (attrs == null) - return null; - return StringUtils.toString(attrs.get(key)); + return getAttr(String.class, key); + } + + /** + * Returns the attribute with the specified name converted to the specified class type. + * + * @param type The class type to convert this class to. + * See {@link ObjectUtils} for a list of supported conversion types. + * @param key The attribute name. + * @return The attribute value, or <jk>null</jk> if the named attribute does not exist. + */ + public <T> T getAttr(Class<T> type, String key) { + return attrs == null ? null : ObjectUtils.convertToType(attrs.get(key), type); } /** http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/88d1d38c/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementContainer.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementContainer.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementContainer.java index 11dd1a4..9878c40 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementContainer.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementContainer.java @@ -16,7 +16,9 @@ import static org.apache.juneau.xml.annotation.XmlFormat.*; import java.util.*; +import org.apache.juneau.*; import org.apache.juneau.annotation.*; +import org.apache.juneau.utils.*; import org.apache.juneau.xml.annotation.*; /** @@ -47,6 +49,28 @@ public class HtmlElementContainer extends HtmlElement { } /** + * Returns the child node at the specified index. + * + * @param index The index of the node in the list of children. + * @return The child node, or <jk>null</jk> if it doesn't exist. + */ + public Object getChild(int index) { + return (children == null || children.size() <= index || index < 0 ? null : children.get(index)); + } + + /** + * Returns the child node at the specified index. + * + * @param type The class type of the node. + * @param index The index of the node in the list of children. + * @return The child node, or <jk>null</jk> if it doesn't exist. + * @throws InvalidDataConversionException If node is not the expected type. + */ + public <T> T getChild(Class<T> type, int index) { + return (children == null || children.size() <= index || index < 0 ? null : ObjectUtils.convertToType(children.get(index), type)); + } + + /** * Adds one or more child elements to this element. * @param children The children to add as child elements. * @return This object (for method chaining). http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/88d1d38c/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementMixed.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementMixed.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementMixed.java index d1b2b8f..0890bc9 100644 --- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementMixed.java +++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementMixed.java @@ -16,7 +16,9 @@ import static org.apache.juneau.xml.annotation.XmlFormat.*; import java.util.*; +import org.apache.juneau.*; import org.apache.juneau.annotation.*; +import org.apache.juneau.utils.*; import org.apache.juneau.xml.annotation.*; /** @@ -48,6 +50,28 @@ public class HtmlElementMixed extends HtmlElement { } /** + * Returns the child node at the specified index. + * + * @param index The index of the node in the list of children. + * @return The child node, or <jk>null</jk> if it doesn't exist. + */ + public Object getChild(int index) { + return (children == null || children.size() <= index || index < 0 ? null : children.get(index)); + } + + /** + * Returns the child node at the specified index. + * + * @param type The class type of the node. + * @param index The index of the node in the list of children. + * @return The child node, or <jk>null</jk> if it doesn't exist. + * @throws InvalidDataConversionException If node is not the expected type. + */ + public <T> T getChild(Class<T> type, int index) { + return (children == null || children.size() <= index || index < 0 ? null : ObjectUtils.convertToType(children.get(index), type)); + } + + /** * Adds one or more child elements to this element. * @param children The children to add as child elements. * Can be a mixture of strings and {@link HtmlElement} objects. http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/88d1d38c/juneau-core/src/main/java/org/apache/juneau/utils/ObjectUtils.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/ObjectUtils.java b/juneau-core/src/main/java/org/apache/juneau/utils/ObjectUtils.java index 7cd68fe..1e55ec7 100644 --- a/juneau-core/src/main/java/org/apache/juneau/utils/ObjectUtils.java +++ b/juneau-core/src/main/java/org/apache/juneau/utils/ObjectUtils.java @@ -12,21 +12,168 @@ // *************************************************************************************************************************** package org.apache.juneau.utils; +import org.apache.juneau.*; +import org.apache.juneau.transform.*; + /** - * TODO + * Utility class for efficiently converting objects between types. + * <p> + * If the value isn't an instance of the specified type, then converts + * the value if possible.<br> + * <p> + * The following conversions are valid: + * <table class='styled'> + * <tr><th>Convert to type</th><th>Valid input value types</th><th>Notes</th></tr> + * <tr> + * <td> + * A class that is the normal type of a registered {@link PojoSwap}. + * </td> + * <td> + * A value whose class matches the transformed type of that registered {@link PojoSwap}. + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * A class that is the transformed type of a registered {@link PojoSwap}. + * </td> + * <td> + * A value whose class matches the normal type of that registered {@link PojoSwap}. + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * {@code Number} (e.g. {@code Integer}, {@code Short}, {@code Float},...)<br> + * <code>Number.<jsf>TYPE</jsf></code> (e.g. <code>Integer.<jsf>TYPE</jsf></code>, <code>Short.<jsf>TYPE</jsf></code>, <code>Float.<jsf>TYPE</jsf></code>,...) + * </td> + * <td> + * {@code Number}, {@code String}, <jk>null</jk> + * </td> + * <td> + * For primitive {@code TYPES}, <jk>null</jk> returns the JVM default value for that type. + * </td> + * </tr> + * <tr> + * <td> + * {@code Map} (e.g. {@code Map}, {@code HashMap}, {@code TreeMap}, {@code ObjectMap}) + * </td> + * <td> + * {@code Map} + * </td> + * <td> + * If {@code Map} is not constructible, a {@code ObjectMap} is created. + * </td> + * </tr> + * <tr> + * <td> + * {@code Collection} (e.g. {@code List}, {@code LinkedList}, {@code HashSet}, {@code ObjectList}) + * </td> + * <td> + * {@code Collection<Object>}<br> + * {@code Object[]} + * </td> + * <td> + * If {@code Collection} is not constructible, a {@code ObjectList} is created. + * </td> + * </tr> + * <tr> + * <td> + * {@code X[]} (array of any type X)<br> + * </td> + * <td> + * {@code List<X>}<br> + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * {@code X[][]} (multi-dimensional arrays)<br> + * </td> + * <td> + * {@code List<List<X>>}<br> + * {@code List<X[]>}<br> + * {@code List[]<X>}<br> + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * {@code Enum}<br> + * </td> + * <td> + * {@code String}<br> + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * Bean<br> + * </td> + * <td> + * {@code Map}<br> + * </td> + * <td> </td> + * </tr> + * <tr> + * <td> + * {@code String}<br> + * </td> + * <td> + * Anything<br> + * </td> + * <td> + * Arrays are converted to JSON arrays<br> + * </td> + * </tr> + * <tr> + * <td> + * Anything with one of the following methods:<br> + * <code><jk>public static</jk> T fromString(String)</code><br> + * <code><jk>public static</jk> T valueOf(String)</code><br> + * <code><jk>public</jk> T(String)</code><br> + * </td> + * <td> + * <code>String</code><br> + * </td> + * <td> + * <br> + * </td> + * </tr> + * </table> */ public class ObjectUtils { -// -// private static final ConcurrentHashMap<Class<?>,ClassMetaSimple> metaCache = new ConcurrentHashMap<Class<?>,ClassMetaSimple>(); -// -// public static <T> T convertToType(Class<T> c, Object value, Object outer) { -// return null; -// -// ClassMetaSimple<T> type = metaCache.get(c); -// if (type == null) { -// metaCache.putIfAbsent(c, new ClassMetaSimple<T>(c)); -// type = metaCache.get(c); -// } -// -// } + + // Session objects are usually not thread safe, but we're not using any feature + // of bean sessions that would cause thread safety issues. + private static final BeanSession session = BeanContext.DEFAULT.createSession(); + + /** + * Converts the specified object to the specified type. + * + * @param <T> The class type to convert the value to. + * @param value The value to convert. + * @param type The class type to convert the value to. + * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type. + * @return The converted value. + */ + public static <T> T convertToType(Object value, Class<T> type) { + return session.convertToType(value, type); + } + + /** + * Converts the specified object to the specified type. + * + * @param <T> The class type to convert the value to. + * @param outer If class is a member class, this is the instance of the containing class. + * Should be <jk>null</jk> if not a member class. + * @param value The value to convert. + * @param type The class type to convert the value to. + * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type. + * @return The converted value. + */ + public static <T> T convertToType(Object outer, Object value, Class<T> type) { + return session.convertToType(outer, value, type); + } + }
