All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.cq.commerce.common.ValueMapDecorator Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2013 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/

package com.adobe.cq.commerce.common;

import org.apache.jackrabbit.util.ISO8601;
import org.apache.sling.api.resource.ValueMap;

import java.lang.reflect.Array;
import java.util.Calendar;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * ValueMapDecorator decorates another {@link Map} to provide a basic implementation
 * for the additional methods of a {@link org.apache.sling.api.resource.ValueMap}.
 *
 * This class is similar to {@link org.apache.sling.api.wrappers.ValueMapDecorator}, but provides
 * {@link javax.jcr.Value} semantics for dates.
 */
public class ValueMapDecorator implements ValueMap {

    /**
     * underlying map
     */
    private final Map base;

    /**
     * Creates a new wrapper around a given map.
     * @param base wrapped object
     */
    public ValueMapDecorator(Map base) {
        this.base = base;
    }

    /**
     * {@inheritDoc}
     */
    public  T get(String name, Class type) {
        return convert(get(name), type);
    }

    /**
     * Converts the object to the given type.
     * @param obj object
     * @param type type
     * @return the converted object
     */
    @SuppressWarnings("unchecked")
    private  T convert(Object obj, Class type) {
        // todo: do smarter checks
        try {
            if (obj == null) {
                return null;
            } else if (type.isAssignableFrom(obj.getClass())) {
                return (T) obj;
            } else if (type.isArray()) {
                return (T) convertToArray(obj, type.getComponentType());
            } else if (type == String.class) {
                if (obj instanceof Calendar) {
                    return (T) ISO8601.format((Calendar) obj);
                } else {
                    return (T) String.valueOf(obj);
                }
            } else if (type == Integer.class) {
                return (T) (Integer) Integer.parseInt(obj.toString());
            } else if (type == Long.class) {
                return (T) (Long) Long.parseLong(obj.toString());
            } else if (type == Double.class) {
                return (T) (Double) Double.parseDouble(obj.toString());
            } else if (type == Boolean.class) {
                return (T) (Boolean) Boolean.parseBoolean(obj.toString());
            } else {
                return null;
            }
        } catch (NumberFormatException e) {
            return null;
        }
    }

    /**
     * Converts the object to an array of the given type
     * @param obj the object or object array
     * @param type the component type of the array
     * @return and array of type T
     */
    private  T[] convertToArray(Object obj, Class type) {
        if (obj.getClass().isArray()) {
            final Object[] array = (Object[]) obj;
            @SuppressWarnings("unchecked")
            final T[] result = (T[]) Array.newInstance(type, array.length);
            for (int i = 0; i < array.length; i++) {
                result[i] = convert(array[i], type);
            }
            return result;
        } else {
            @SuppressWarnings("unchecked")
            final T[] result = (T[]) Array.newInstance(type, 1);
            result[0] = convert(obj, type);
            return result;
        }
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public  T get(String name, T defaultValue) {
        if ( defaultValue == null ) {
            return (T)get(name);
        }
        T value = get(name, (Class) defaultValue.getClass());
        return value == null ? defaultValue : value;
    }

    /**
     * {@inheritDoc}
     */
    public int size() {
        return base.size();
    }

    /**
     * {@inheritDoc}
     */
    public boolean isEmpty() {
        return base.isEmpty();
    }

    /**
     * {@inheritDoc}
     */
    public boolean containsKey(Object key) {
        return base.containsKey(key);
    }

    /**
     * {@inheritDoc}
     */
    public boolean containsValue(Object value) {
        return base.containsValue(value);
    }

    /**
     * {@inheritDoc}
     */
    public Object get(Object key) {
        return base.get(key);
    }

    /**
     * {@inheritDoc}
     */
    public Object put(String key, Object value) {
        return base.put(key, value);
    }

    /**
     * {@inheritDoc}
     */
    public Object remove(Object key) {
        return base.remove(key);
    }

    /**
     * {@inheritDoc}
     */
    public void putAll(Map t) {
        base.putAll(t);
    }

    /**
     * {@inheritDoc}
     */
    public void clear() {
        base.clear();
    }

    /**
     * {@inheritDoc}
     */
    public Set keySet() {
        return base.keySet();
    }

    /**
     * {@inheritDoc}
     */
    public Collection values() {
        return base.values();
    }

    /**
     * {@inheritDoc}
     */
    public Set> entrySet() {
        return base.entrySet();
    }

    @Override
    public String toString() {
        return super.toString() + " : " + this.base.toString();
    }
}