Package org.boris.xlloop.util

Source Code of org.boris.xlloop.util.XLoperObjectConverter

/*******************************************************************************
* This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
*     Peter Smith
*******************************************************************************/
package org.boris.xlloop.util;

import java.lang.reflect.Array;

import org.boris.xlloop.xloper.XLArray;
import org.boris.xlloop.xloper.XLBool;
import org.boris.xlloop.xloper.XLError;
import org.boris.xlloop.xloper.XLInt;
import org.boris.xlloop.xloper.XLNil;
import org.boris.xlloop.xloper.XLNum;
import org.boris.xlloop.xloper.XLString;
import org.boris.xlloop.xloper.XLoper;

/**
* Used to map arguments to objects.
*/
public class XLoperObjectConverter
{
    public static final Integer IZERO = new Integer(0);
    public static final Double DZERO = new Double(0);
    public static final Long LZERO = new Long(0);
    private ObjectRegistry registry = new ObjectRegistry();

    /**
     * Clear out the internal registry to release memory.
     */
    public void clearRegistry() {
        registry.clear();
    }

    /**
     * Get the size of the registry.
     *
     * @return int.
     */
    public int getRegistrySize() {
        return registry.size();
    }

    /**
     * Creates an Variant from a java object (best attempt).
     *
     * @param obj.
     *
     * @return XLObject.
     */
    public XLoper createFrom(Object obj) {
        if (obj instanceof String) {
            return new XLString((String) obj);
        } else if (obj instanceof Boolean) {
            return new XLBool(((Boolean) obj).booleanValue());
        } else if (obj instanceof Integer) {
            return new XLNum(((Integer) obj).intValue());
        } else if (obj instanceof Long) {
            return new XLNum(((Long) obj).longValue());
        } else if (obj instanceof Float) {
            return new XLNum(((Float) obj).floatValue());
        } else if (obj instanceof Double) {
            return new XLNum(((Double) obj).doubleValue());
        } else if (obj instanceof String[]) {
            String[] arr = (String[]) obj;
            XLoper[] array = new XLoper[arr.length];
            for (int i = 0; i < arr.length; i++) {
                array[i] = new XLString(arr[i]);
            }

            return new XLArray(array, arr.length, 1);
        } else if (obj instanceof String[][]) {
            String[][] arr = (String[][]) obj;
            if (arr.length == 0 || arr[0] == null)
                return XLError.NA;
            XLArray array = new XLArray(arr.length, arr[0].length);

            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[0].length && j < arr[i].length; j++) {
                    array.set(i, j, arr[i][j]);
                }
            }

            return array;
        } else if (obj instanceof double[]) {
            double[] arr = (double[]) obj;
            XLoper[] array = new XLoper[arr.length];

            for (int i = 0; i < arr.length; i++) {
                array[i] = new XLNum(arr[i]);
            }

            return new XLArray(array, array.length, 1);
        } else if (obj instanceof double[][]) {
            double[][] arr = (double[][]) obj;
            if (arr.length == 0 || arr[0] == null)
                return XLError.NA;
            XLArray array = new XLArray(arr.length, arr[0].length);

            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[0].length && j < arr[i].length; j++) {
                    array.set(i, j, arr[i][j]);
                }
            }

            return array;
        } else if (obj instanceof Double[]) {
            Double[] arr = (Double[]) obj;
            XLoper[] array = new XLoper[arr.length];

            for (int i = 0; i < arr.length; i++) {
                array[i] = arr[i] == null ? (XLoper) XLNil.NIL : new XLNum(
                        arr[i].doubleValue());
            }

            return new XLArray(array, arr.length, 1);
        } else if (obj instanceof Double[][]) {
            Double[][] arr = (Double[][]) obj;
            if (arr.length == 0 || arr[0] == null)
                return XLError.NA;
            XLArray array = new XLArray(arr.length, arr[0].length);

            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[0].length && j < arr[i].length; j++) {
                    array.set(i, j, arr[i][j]);
                }
            }

            return array;
        } else if (obj instanceof int[]) {
            int[] arr = (int[]) obj;
            XLoper[] array = new XLoper[arr.length];

            for (int i = 0; i < arr.length; i++) {
                array[i] = new XLInt(arr[i]);
            }

            return new XLArray(array, arr.length, 1);
        } else if (obj instanceof int[][]) {
            int[][] arr = (int[][]) obj;
            if (arr.length == 0 || arr[0] == null)
                return XLError.NA;
            XLArray array = new XLArray(arr.length, arr[0].length);

            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[0].length && j < arr[i].length; j++) {
                    array.set(i, j, arr[i][j]);
                }
            }

            return array;
        } else if (obj instanceof Integer[]) {
            Integer[] arr = (Integer[]) obj;
            XLoper[] array = new XLoper[arr.length];

            for (int i = 0; i < arr.length; i++) {
                array[i] = arr[i] == null ? (XLoper) XLNil.NIL : new XLInt(
                        arr[i].intValue());
            }

            return new XLArray(array, arr.length, 1);
        } else if (obj instanceof Integer[][]) {
            Integer[][] arr = (Integer[][]) obj;
            if (arr.length == 0 || arr[0] == null)
                return XLError.NA;
            XLArray array = new XLArray(arr.length, arr[0].length);

            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[0].length && j < arr[i].length; j++) {
                    array.set(i, j, arr[i][j]);
                }
            }

            return array;
        } else if (obj instanceof boolean[]) {
            boolean[] arr = (boolean[]) obj;
            XLoper[] array = new XLoper[arr.length];

            for (int i = 0; i < arr.length; i++) {
                array[i] = new XLBool(arr[i]);
            }

            return new XLArray(array, arr.length, 1);
        } else if (obj instanceof boolean[][]) {
            boolean[][] arr = (boolean[][]) obj;
            if (arr.length == 0 || arr[0] == null)
                return XLError.NA;
            XLArray array = new XLArray(arr.length, arr[0].length);

            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[0].length && j < arr[i].length; j++) {
                    array.set(i, j, arr[i][j]);
                }
            }

            return array;
        } else if (obj instanceof Boolean[]) {
            Boolean[] arr = (Boolean[]) obj;
            XLoper[] array = new XLoper[arr.length];

            for (int i = 0; i < arr.length; i++) {
                array[i] = arr[i] == null ? (XLoper) XLNil.NIL : new XLBool(
                        arr[i].booleanValue());
            }

            return new XLArray(array, arr.length, 1);
        } else if (obj instanceof Boolean[][]) {
            Boolean[][] arr = (Boolean[][]) obj;
            if (arr.length == 0 || arr[0] == null)
                return XLError.NA;
            XLArray array = new XLArray(arr.length, arr[0].length);

            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[0].length && j < arr[i].length; j++) {
                    array.set(i, j, arr[i][j]);
                }
            }

            return array;
        } else if (obj instanceof Object[][]) {
            Object[][] arr = (Object[][]) obj;
            if (arr.length == 0 || arr[0] == null)
                return XLError.NA;
            XLArray array = new XLArray(arr.length, arr[0].length);

            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[0].length && j < arr[i].length; j++) {
                    array.set(i, j, createFrom(arr[i][j]));
                }
            }

            return array;
        } else if (obj instanceof Object[]) {
            Object[] arr = (Object[]) obj;
            XLoper[] array = new XLoper[arr.length];

            for (int i = 0; i < arr.length; i++) {
                array[i] = createFrom(arr[i]);
            }

            return new XLArray(array, arr.length, 1);
        } else if (obj instanceof XLoper) {
            return (XLoper) obj;
        } else if (obj != null) {
            return new XLString(registry.put(obj));
        } else {
            return XLNil.NIL;
        }
    }

    /**
     * Creates a java object from an XLObject.
     *
     * @param obj.
     * @param hint.
     *
     * @return Object.
     */
    public Object createFrom(XLoper obj, Class hint) {
        // If Excel passes a single value and the Java code expects an array,
        // try to convert based on the component type, and then create the
        // array.
        if (obj.type != XLoper.xlTypeMulti && hint.isArray()) {
            Object value = doTypeSwitch(obj, hint.getComponentType());
            Object array = Array.newInstance(hint.getComponentType(), 1);
            Array.set(array, 0, value);
            return array;
        } else {
            return doTypeSwitch(obj, hint);
        }
    }

    private Object doTypeSwitch(XLoper obj, Class hint) {
        switch (obj.type) {
        case XLoper.xlTypeStr:
            if (XLString.class.equals(hint)) {
                return obj;
            } else {
                String str = ((XLString) obj).str;
                Object val = registry.get(str);
                if (val != null) {
                    return val;
                } else {
                    return str;
                }
            }
        case XLoper.xlTypeNum:
            if (String.class.equals(hint)) {
                return obj.toString();
            } else if (Integer.class.equals(hint) || int.class.equals(hint)) {
                return new Integer((int) ((XLNum) obj).num);
            } else if (Long.class.equals(hint) || long.class.equals(hint)) {
                return new Long((long) ((XLNum) obj).num);
            } else if (Boolean.class.equals(hint) || boolean.class.equals(hint)) {
                return new Boolean(((int) ((XLNum) obj).num) != 0);
            } else {
                return new Double(((XLNum) obj).num);
            }
        case XLoper.xlTypeMulti:
            return convertArray((XLArray) obj, hint);
        case XLoper.xlTypeBool:
            if (Double.class.equals(hint) || double.class.equals(hint)) {
                return new Double(((XLBool) obj).bool ? 1 : 0);
            } else if (String.class.equals(hint)) {
                return obj.toString();
            } else if (Integer.class.equals(hint) || int.class.equals(hint)) {
                return new Integer(((XLBool) obj).bool ? 1 : 0);
            } else if (Long.class.equals(hint) || long.class.equals(hint)) {
                return new Long(((XLBool) obj).bool ? 1 : 0);
            } else {
                return new Boolean((((XLBool) obj).bool));
            }
        case XLoper.xlTypeInt:
            if (Double.class.equals(hint) || double.class.equals(hint)) {
                return new Double(((XLInt) obj).w);
            } else if (String.class.equals(hint)) {
                return obj.toString();
            } else if (Long.class.equals(hint) || long.class.equals(hint)) {
                return new Long(((XLInt) obj).w);
            } else if (Boolean.class.equals(hint) || boolean.class.equals(hint)) {
                return new Boolean((((XLInt) obj).w != 0));
            } else {
                return new Integer(((XLInt) obj).w);
            }
        case XLoper.xlTypeNil:
        case XLoper.xlTypeMissing:
            if (String.class.equals(hint)) {
                return "";
            } else if (int.class.equals(hint)) {
                return IZERO;
            } else if (long.class.equals(hint)) {
                return LZERO;
            } else if (boolean.class.equals(hint)) {
                return Boolean.FALSE;
            } else if (double.class.equals(hint)) {
                return DZERO;
            } else {
                return null;
            }
        }

        return null;
    }

    private Object convertVector(XLArray arr, Class hint) {
        Object val = null;

        if (Integer.class.equals(hint)) {
            Integer l = arr.length > 0 ? arr.getInteger(0) : null;
            return l == null ? null : new Integer(l.intValue());
        } else if (int.class.equals(hint)) {
            Integer l = arr.length > 0 ? arr.getInteger(0) : null;
            return l == null ? IZERO : new Integer(l.intValue());
        } else if (Double.class.equals(hint)) {
            return arr.length > 0 ? arr.getDouble(0) : null;
        } else if (double.class.equals(hint)) {
            Double d = arr.length > 0 ? arr.getDouble(0) : null;
            return d == null ? DZERO : d;
        } else if (String.class.equals(hint)) {
            return arr.length > 0 ? arr.getString(0) : null;
        } else if (double[].class.equals(hint)) {
            double[] darr = new double[arr.rows];

            for (int i = 0; i < darr.length; i++) {
                Double d = arr.getDouble(i);
                if (d != null) {
                    darr[i] = d.doubleValue();
                }
            }

            val = darr;
        } else if (double[][].class.equals(hint)) {
            double[][] darr = new double[arr.rows][1];

            for (int i = 0; i < arr.rows; i++) {
                Double d = arr.getDouble(i);
                if (d != null) {
                    darr[i][0] = d.doubleValue();
                }
            }

            val = darr;
        } else if (Double[].class.equals(hint)) {
            Double[] darr = new Double[arr.rows];

            for (int i = 0; i < darr.length; i++) {
                darr[i] = arr.getDouble(i);
            }

            val = darr;
        } else if (Double[][].class.equals(hint)) {
            Double[][] darr = new Double[arr.rows][1];

            for (int i = 0; i < arr.rows; i++) {
                darr[i][0] = arr.getDouble(i);
            }

            val = darr;
        } else if (int[].class.equals(hint)) {
            int[] darr = new int[arr.rows];

            for (int i = 0; i < darr.length; i++) {
                Integer l = arr.getInteger(i);
                if (l != null) {
                    darr[i] = l.intValue();
                }
            }

            val = darr;
        } else if (int[][].class.equals(hint)) {
            int[][] darr = new int[arr.rows][1];

            for (int i = 0; i < arr.rows; i++) {
                Integer l = arr.getInteger(i);
                if (l != null) {
                    darr[i][0] = l.intValue();
                }
            }

            val = darr;
        } else if (Integer[].class.equals(hint)) {
            Integer[] darr = new Integer[arr.rows];

            for (int i = 0; i < darr.length; i++) {
                darr[i] = arr.getInteger(i);
            }

            val = darr;
        } else if (Integer[][].class.equals(hint)) {
            Integer[][] darr = new Integer[arr.rows][1];

            for (int i = 0; i < arr.rows; i++) {
                darr[i][0] = arr.getInteger(i);
            }

            val = darr;
        } else if (boolean[].class.equals(hint)) {
            boolean[] darr = new boolean[arr.rows];

            for (int i = 0; i < darr.length; i++) {
                Integer l = arr.getInteger(i);
                if (l != null) {
                    darr[i] = l.intValue() == 1;
                }
            }

            val = darr;
        } else if (boolean[][].class.equals(hint)) {
            boolean[][] darr = new boolean[arr.rows][1];

            for (int i = 0; i < arr.rows; i++) {
                Integer l = arr.getInteger(i);
                if (l != null) {
                    darr[i][0] = l.intValue() == 1;
                }
            }

            val = darr;
        } else if (Boolean[].class.equals(hint)) {
            Boolean[] darr = new Boolean[arr.rows];

            for (int i = 0; i < darr.length; i++) {
                Integer l = arr.getInteger(i);
                if (l != null) {
                    darr[i] = new Boolean(l.intValue() == 1);
                }
            }

            val = darr;
        } else if (Boolean[][].class.equals(hint)) {
            Boolean[][] darr = new Boolean[arr.rows][1];

            for (int i = 0; i < arr.rows; i++) {
                Integer l = arr.getInteger(i);
                if (l != null) {
                    darr[i][0] = new Boolean(l.intValue() == 1);
                }
            }

            val = darr;
        } else if (String[].class.equals(hint)) {
            String[] darr = new String[arr.rows];

            for (int i = 0; i < darr.length; i++) {
                darr[i] = arr.getString(i);
            }

            val = darr;
        } else if (String[][].class.equals(hint)) {
            String[][] darr = new String[arr.rows][1];

            for (int i = 0; i < arr.rows; i++) {
                darr[i][0] = arr.getString(i);
            }

            val = darr;
        } else if (Object[].class.equals(hint)) {
            Object[] darr = new Object[arr.rows];

            for (int i = 0; i < darr.length; i++) {
                darr[i] = createFrom(arr.get(i), Object.class);
            }

            val = darr;
        } else if (Object[][].class.equals(hint)) {
            Object[][] darr = new Object[arr.rows][1];

            for (int i = 0; i < arr.rows; i++) {
                darr[i][0] = createFrom(arr.get(i), Object.class);
            }

            val = darr;
        } else {
            String str = arr.getString(0);
            val = registry.get(str);
        }

        return val;
    }

    /**
     * Convert an array into the desired object.
     *
     * @param arr.
     * @param hint.
     *
     * @return Object.
     */
    private Object convertArray(XLArray arr, Class hint) {
        Object val = null;
        if (arr.columns == 1) {
            return convertVector(arr, hint);
        }

        if (Integer.class.equals(hint) || int.class.equals(hint)) {
            val = arr.getInteger(0);
        } else if (Double.class.equals(hint) || double.class.equals(hint)) {
            val = arr.getDouble(0);
        } else if (String.class.equals(hint)) {
            val = arr.getString(0);
        } else if (double[].class.equals(hint)) {
            double[] darr = new double[arr.rows * arr.columns];

            for (int i = 0; i < darr.length; i++) {
                Double d = arr.getDouble(i);
                if (d != null)
                    darr[i] = d.doubleValue();
            }

            val = darr;
        } else if (double[][].class.equals(hint)) {
            double[][] darr = new double[arr.rows][arr.columns];

            for (int i = 0; i < arr.rows; i++) {
                for (int j = 0; j < arr.columns; j++) {
                    Double d = arr.getDouble(i, j);
                    if (d != null)
                        darr[i][j] = d.doubleValue();
                }
            }

            val = darr;
        } else if (Double[].class.equals(hint)) {
            Double[] darr = new Double[arr.rows * arr.columns];

            for (int i = 0; i < darr.length; i++) {
                darr[i] = arr.getDouble(i);
            }

            val = darr;
        } else if (Double[][].class.equals(hint)) {
            Double[][] darr = new Double[arr.rows][arr.columns];

            for (int i = 0; i < arr.rows; i++) {
                for (int j = 0; j < arr.columns; j++) {
                    darr[i][j] = arr.getDouble(i, j);
                }
            }

            val = darr;
        } else if (int[].class.equals(hint)) {
            int[] darr = new int[arr.rows * arr.columns];

            for (int i = 0; i < darr.length; i++) {
                Integer it = arr.getInteger(i);
                if (it != null)
                    darr[i] = it.intValue();
            }

            val = darr;
        } else if (int[][].class.equals(hint)) {
            int[][] darr = new int[arr.rows][arr.columns];

            for (int i = 0; i < arr.rows; i++) {
                for (int j = 0; j < arr.columns; j++) {
                    Integer it = arr.getInteger(i, j);
                    if (it != null)
                        darr[i][j] = it.intValue();
                }
            }

            val = darr;
        } else if (Integer[].class.equals(hint)) {
            Integer[] darr = new Integer[arr.rows * arr.columns];

            for (int i = 0; i < darr.length; i++) {
                darr[i] = arr.getInteger(i);
            }

            val = darr;
        } else if (Integer[][].class.equals(hint)) {
            Integer[][] darr = new Integer[arr.rows][arr.columns];

            for (int i = 0; i < arr.rows; i++) {
                for (int j = 0; j < arr.columns; j++) {
                    darr[i][j] = arr.getInteger(i, j);
                }
            }

            val = darr;
        } else if (boolean[].class.equals(hint)) {
            boolean[] darr = new boolean[arr.rows * arr.columns];

            for (int i = 0; i < darr.length; i++) {
                Boolean b = arr.getBoolean(i);
                if (b != null)
                    darr[i] = b.booleanValue();
            }

            val = darr;
        } else if (boolean[][].class.equals(hint)) {
            boolean[][] darr = new boolean[arr.rows][arr.columns];

            for (int i = 0; i < arr.rows; i++) {
                for (int j = 0; j < arr.columns; j++) {
                    Boolean b = arr.getBoolean(i, j);
                    if (b != null)
                        darr[i][j] = b.booleanValue();
                }
            }

            val = darr;
        } else if (Boolean[].class.equals(hint)) {
            Boolean[] darr = new Boolean[arr.rows * arr.columns];

            for (int i = 0; i < darr.length; i++) {
                darr[i] = arr.getBoolean(i);
            }

            val = darr;
        } else if (Boolean[][].class.equals(hint)) {
            Boolean[][] darr = new Boolean[arr.rows][arr.columns];

            for (int i = 0; i < arr.rows; i++) {
                for (int j = 0; j < arr.columns; j++) {
                    darr[i][j] = arr.getBoolean(i, j);
                }
            }

            val = darr;
        } else if (String[].class.equals(hint)) {
            String[] darr = new String[arr.rows * arr.columns];

            for (int i = 0; i < darr.length; i++) {
                darr[i] = arr.getString(i);
            }

            val = darr;
        } else if (String[][].class.equals(hint)) {
            String[][] darr = new String[arr.rows][arr.columns];

            for (int i = 0; i < arr.rows; i++) {
                for (int j = 0; j < arr.columns; j++) {
                    darr[i][j] = arr.getString(i, j);
                }
            }

            val = darr;
        } else if (Object[].class.equals(hint)) {
            Object[] darr = new Object[arr.rows * arr.columns];

            for (int i = 0; i < darr.length; i++) {
                darr[i] = createFrom(arr.get(i), Object.class);
            }

            val = darr;
        } else if (Object[][].class.equals(hint)) {
            Object[][] darr = new Object[arr.rows][arr.columns];

            for (int i = 0; i < arr.rows; i++) {
                for (int j = 0; j < arr.columns; j++) {
                    darr[i][j] = createFrom(arr.get(i, j), Object.class);
                }
            }

            val = darr;
        } else if (XLArray.class.equals(hint)) {
            val = arr;
        } else {
            String str = arr.getString(0);
            val = registry.get(str);
            if (val == null)
                val = str;
        }

        return val;
    }

    public Object[] convert(XLoper[] args, Class[] hints) {
        Object[] a = new Object[hints.length];
        int csize = args.length;
        for (int i = 0; i < hints.length; i++) {
            if (i < csize) {
                a[i] = createFrom(args[i], hints[i]);
            } else {
                a[i] = null;
            }
        }
        return a;
    }
}
TOP

Related Classes of org.boris.xlloop.util.XLoperObjectConverter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.