org.nuxeo.ecm.platform.el.FieldAdapterManager.java Source code

Java tutorial

Introduction

Here is the source code for org.nuxeo.ecm.platform.el.FieldAdapterManager.java

Source

/*
 * (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     Nuxeo - initial API and implementation
 *
 * $Id: FieldAdapterManager.java 28460 2008-01-03 15:34:05Z sfermigier $
 */

package org.nuxeo.ecm.platform.el;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * The FieldAdapterManager fills the gap between the storage and the display structures.
 * <p>
 * The Display representation of a DataModel is a set of JSF Beans There are mainly 3 cases:
 * <p>
 * 1 - Perfect match: the JSF components generate a bean that can be directly stored ie: String ...
 * <p>
 * 2 - Type Mismatch: The JSF component generate a bean that is not of the right type ie: The JSF generate a Date
 * whereas the Core expect a Calendar type.
 * <p>
 * 3 - Structure Mismatch: The JSF bean must be split in several fields ie: The uploaded file is one object, but the
 * core expect at least 2 separate fields (filename and content)
 *
 * @author Thierry Delprat
 */
public final class FieldAdapterManager {

    @SuppressWarnings("unused")
    private static final Log log = LogFactory.getLog(FieldAdapterManager.class);

    // Utility class.
    private FieldAdapterManager() {
    }

    /**
     * Sets value adapting it for storage.
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static Object getValueForStorage(Object value) {
        if (value instanceof Date) {
            value = getDateAsCalendar((Date) value);
        } else if (value instanceof BigDecimal) {
            value = getBigDecimalAsLong((BigDecimal) value);
        } else if (value instanceof Object[]) {
            Object[] array = (Object[]) value;
            Class<?> oldType = array.getClass().getComponentType();
            Class<?> newType = getComponentTypeForStorage(oldType);
            Object[] newArray = (Object[]) Array.newInstance(newType, array.length);
            for (int i = 0; i < array.length; i++) {
                newArray[i] = getValueForStorage(array[i]);
            }
            value = newArray;
        } else if (value instanceof List) {
            List list = (List) value;
            for (int i = 0; i < list.size(); i++) {
                list.set(i, getValueForStorage(list.get(i)));
            }
        } else if (value instanceof Map) {
            Map<Object, Object> map = (Map) value;
            Map<Object, Object> newMap = new HashMap<Object, Object>();
            for (Map.Entry<Object, Object> entry : map.entrySet()) {
                newMap.put(entry.getKey(), getValueForStorage(entry.getValue()));
            }
            value = newMap;
        }
        // TODO: maybe handle list diffs (?)
        return value;
    }

    /**
     * Returns component type that will be used to store objects of given component type.
     */
    public static Class<?> getComponentTypeForStorage(Class<?> componentType) {
        Class<?> newType = componentType;
        if (componentType.equals(Date.class)) {
            newType = Calendar.class;
        }
        return newType;
    }

    /**
     * Gets value adapting it for display.
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static Object getValueForDisplay(Object value) {
        if (value instanceof Calendar) {
            value = getCalendarAsDate((Calendar) value);
        } else if (value instanceof Object[]) {
            Object[] array = (Object[]) value;
            Class<?> oldType = array.getClass().getComponentType();
            Class<?> newType = getComponentTypeForDisplay(oldType);
            Object[] newArray = (Object[]) Array.newInstance(newType, array.length);
            for (int i = 0; i < array.length; i++) {
                newArray[i] = getValueForDisplay(array[i]);
            }
            value = newArray;
        } else if (value instanceof List) {
            List list = (List) value;
            for (int i = 0; i < list.size(); i++) {
                list.set(i, getValueForDisplay(list.get(i)));
            }
        } else if (value instanceof Map) {
            Map<Object, Object> map = (Map) value;
            Map<Object, Object> newMap = new HashMap<Object, Object>();
            for (Map.Entry<Object, Object> entry : map.entrySet()) {
                newMap.put(entry.getKey(), getValueForDisplay(entry.getValue()));
            }
            value = newMap;
        }
        return value;
    }

    /**
     * Returns component type that will be used to display objects of given component type.
     */
    public static Class<?> getComponentTypeForDisplay(Class<?> componentType) {
        Class<?> newType = componentType;
        if (componentType.equals(Calendar.class)) {
            newType = Date.class;
        }
        return newType;
    }

    // Fake converters for now
    // XXX make an extension point to register Adapters
    // XXX update TypeManager to handle Adapter configuration

    private static Calendar getDateAsCalendar(Date value) {
        Calendar calValue = Calendar.getInstance();
        calValue.setTime(value);
        return calValue;
    }

    private static Date getCalendarAsDate(Calendar value) {
        return value.getTime();
    }

    /**
     * @since 7.1
     */
    private static Long getBigDecimalAsLong(BigDecimal value) {
        return value.longValueExact();
    }

}