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

org.navimatrix.commons.data.DataUtil Maven / Gradle / Ivy

There is a newer version: 1.0.5
Show newest version
package org.navimatrix.commons.data;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.navimatrix.commons.data.sdoimpl.BasicDataObject;
import org.navimatrix.commons.data.sdoimpl.BasicDataObjectImpl;
import org.navimatrix.commons.data.util.Base16;

public class DataUtil {

    public static String resource2String(URL res) throws IOException {

        if (res == null) return null;

        InputStream is = res.openStream();
        InputStreamReader isr = new InputStreamReader(is, "8859_1");
        StringBuffer sb = new StringBuffer();

        while (isr.ready()) {
            char b = (char) isr.read();
            sb.append(b);
        }
        isr.close();

        String ret = sb.toString();
        return ret;
    }

    public static String resource2String(Class cl, String url, String file) throws IOException {
        if (file == null) return null;
        URL res;
        if (url != null)
            res = cl.getResource(url + file);
        else
            res = cl.getResource(file);

        return resource2String(res);
    }

    /**
     * get a bunch of resources turned to strings.  key for Data returned
     * is the files[i] content.
     * 
     * @param cl     the url+files[i] name is relative to this class's classloader source.
     * @param url    1st part of the filename or null.  when files[0] = mytable.sql,
     *               usually a dir name and/or a filename prefix, like resources/ for
     *               a full url of resources/mytable.sql.
     *               
     *               or if the url is resources/hsqldb_ the full url is
     *               resources/hsqldb_mytable.sql.
     *               
     *               "/" is NOT inserted.  so url isn't so accurate a name as prefix.
     * @param files
     * 
     * @return 
     * @exception IOException
     */
    public static Data resource2String(Class cl, String url, String[] files) throws IOException {
        if (files == null) return null;
        Data data = DataFactory.createData();
        for (int i = 0; i < files.length; i++) {
            data.put(files[i], resource2String(cl, url, files[i]));
        }
        return data;
    }

    public static String[] getStringFields(Object object, String prefix) {

        if (object == null) return null;

        Class cl = object.getClass();

        Field[] fields = cl.getFields();
        if (fields == null) return null;
        Set set = new HashSet();
        for (int i = 0; i < fields.length; i++) {
            if (fields[i].getName().startsWith(prefix)) {
                set.add(fields[i]);
            }
        }

        String[] ret = new String[set.size()];

        Iterator iter = set.iterator();

        for (int i = 0; iter.hasNext(); i++) {
            Field f = (Field) iter.next();
            try {
                ret[i] = (String) f.get(object);
            } catch (Exception e) {
                throw new java.lang.UnsupportedOperationException("can not reflect"); //i18n
            }
        }

        return ret;
    }

    //
    // todo: test.  presumes that instanceof checks are faster than to/from String
    //  and constructing numbers from String arg
    //

    public static Integer getInteger(Object o) {
        if (o == null) return null;
        if (o instanceof Integer) {
            return(Integer) o;
        }
        if (o instanceof BasicDataObject) {
            return getInteger(((BasicDataObject)o).getValue());
        }

        try {
            return new Integer(o.toString());
        } catch (java.lang.NumberFormatException nfe) {
            if (o.toString().endsWith(".0")) {
                return new Integer(o.toString().substring(0, o.toString().length() - 2));
            }
            throw nfe;
        }
    }

    public static Long getLong(Object o) {
        if (o == null) return null;
        if (o instanceof Long) {
            return(Long) o;
        }
        if (o instanceof BasicDataObject) {
            return getLong(((BasicDataObject)o).getValue());
        }
        try {
            return new Long(o.toString());
        } catch (java.lang.NumberFormatException nfe) {
            if (o.toString().endsWith(".0")) {
                return new Long(o.toString().substring(0, o.toString().length() - 2));
            }
            throw nfe;
        }
    }

    public static Double getDouble(Object o) {
        if (o == null) return null;
        if (o instanceof Double) {
            return(Double) o;
        }
        if (o instanceof BasicDataObject) {
            return getDouble(((BasicDataObject)o).getValue());
        }
        return new Double(o.toString());
    }

    public static BigDecimal getBigDecimal(Object o) {
        if (o == null) return null;
        if (o instanceof BigDecimal) {
            return(BigDecimal) o;
        }
        if (o instanceof BasicDataObject) {
            return getBigDecimal(((BasicDataObject)o).getValue());
        }
        return new BigDecimal(o.toString());
    }

    public static BigInteger getBigInteger(Object o) {
        if (o == null) return null;
        if (o instanceof BigInteger) {
            return(BigInteger) o;
        }
        if (o instanceof BasicDataObject) {
            return getBigInteger(((BasicDataObject)o).getValue());
        }
        return new BigInteger(o.toString());
    }

    public static Boolean getBoolean(Object o) {
        if (o == null) return null;
        if (o instanceof Boolean) {
            return(Boolean) o;
        }
        if (o instanceof Byte) {
            if (((Byte) o).byteValue() == 0 ) {
                return new Boolean(false);
            } else {
                return new Boolean(true);
            }
        }
        if (o instanceof BasicDataObject) {
            return getBoolean(((BasicDataObject)o).getValue());
        }
        return Boolean.valueOf(o.toString());
    }

    public static Byte getByte(Object o) {
        if (o == null) return null;
        if (o instanceof Byte) {
            return(Byte) o;
        }
        if (o instanceof Boolean) {
            Boolean bool = (Boolean) o;
            if (bool.booleanValue()) {
                return new Byte((byte)1);
            } else {
                return new Byte((byte)0);
            }
        }
        if (o instanceof BasicDataObject) {
            return getByte(((BasicDataObject)o).getValue());
        }
        return new Byte(o.toString());
    }

    public static Float getFloat(Object o) {
        if (o == null) return null;
        if (o instanceof Float) {
            return(Float) o;
        }
        if (o instanceof BasicDataObject) {
            return getFloat(((BasicDataObject)o).getValue());
        }
        return new Float(o.toString());
    }

    public static Character getCharacter(Object o) {
        if (o == null) return null;
        if (o instanceof Character) {
            return(Character) o;
        }
        if (o instanceof BasicDataObject) {
            return getCharacter(((BasicDataObject)o).getValue());
        }
        //improbable
        return new Character(o.toString().charAt(0));
    }

    public static Short getShort(Object o) {
        if (o == null) return null;
        if (o instanceof Short) {
            return(Short) o;
        }
        if (o instanceof BasicDataObject) {
            return getShort(((BasicDataObject)o).getValue());
        }
        return new Short(o.toString());
    }

    public static Date getDate(Object o) {
        if (o == null) return null;
        if (o instanceof Date) {
            return(Date) o;
        }
        if (o instanceof BasicDataObject) {
            return getDate(((BasicDataObject)o).getValue());
        }
        return new Date(getLong(o).longValue());
    }

    public static byte[] getBytes(Object o) {
        if (o == null) return null;
        if (o instanceof byte[]) {
            return(byte[]) o;
        }
        if (o instanceof BasicDataObject) {
            return getBytes(((BasicDataObject)o).getValue());
        }
        if (o instanceof String) {
            //assume Base16
            return Base16.decode((String) o);
        }
        if (o instanceof char[]) {
            return(byte[]) o;
        }
        return o.toString().getBytes(); //i18n?? need a lookup of default charset?
    }

    public static String getString(Object o) {
        if (o == null) return null;
        if (o instanceof BasicDataObject) {
            //return getString(((BasicDataObject)o).getValue());
            Object newo = ((BasicDataObject)o).getValue();
            if (newo instanceof BasicDataObject) {
                BasicDataObject newdo = (BasicDataObject) newo;
                throw new java.lang.IllegalArgumentException("error.  value is a BasicDataObject,  should be primitive.  recursive error warning.  type: " + newdo.getType().getName());
            } else {
                return getString(newo);
            }
        }
        if (o instanceof byte[]) {
            return new String((byte[]) o); //i18n
        }
        //todo: what else?
        return o.toString();
    }

    //
    // begin DataUtil utils
    //

    public static boolean isAttribute(Object data) {
        if (data instanceof DataObject) {
            DataObject dataobj = (DataObject) data;

            String type_name = dataobj.getType().getName();

            if (type_name == null || type_name.length() == 0) {
                return false;
            }

            boolean attr = dataobj.getType().getName().charAt(0) == '@';

            return attr;
        }
        return false;
    }

    public static boolean hasProperty(Object data, String propertyName) {
        if (data instanceof DataObject) {
            DataObject dataobj = (DataObject) data;
            return dataobj.isSet(propertyName);
        }
        return false;
    }

    public static DataObject getRoot(Object data) {
        if (data instanceof DataObject) {
            DataObject dataobj = (DataObject) data;
            return dataobj.getDataGraph().getRootObject();
        }
        return null;
    }
    public static DataObject getParent(Object data) {
        if (data instanceof DataObject) {
            DataObject dataobj = (DataObject) data;
            return dataobj.getContainer();
        }
        return null;
    }
    public static String getAttributeName(Object data) {
        String name = getName(data);

        if (name != null && (name.length() != 0) && name.charAt(0) == '@') {
            return name.substring(1, name.length());
        }
        return name;
    }
    public static String getName(Object data) {
        if (data instanceof DataObject) {
            DataObject dataobj = (DataObject) data;
            return dataobj.getType().getName();
        }
        return null;
    }
    public static String getURI(Object data) { 
        if (data instanceof DataObject) {
            DataObject dataobj = (DataObject) data;
            return dataobj.getType().getURI();
        }
        return null;
    }

    //single object iterator
    public static Iterator getIterator(final Object object) {

        if (object instanceof List) {
            return((List) object).iterator();
        }

        if (object instanceof Collection) {
            return((Collection) object).iterator();
        }

        return new Iterator() {
            boolean hasNext = true;
            public boolean hasNext() {
                if (object == null) {
                    return false;
                }
                return hasNext;
            }
            public Object next() {
                if (object == null || !hasNext) {
                    throw new java.util.NoSuchElementException();
                }
                hasNext = false;
                return object;
            }
            public void remove() {
                //noop
            }
        };
    }

    //
    // sort
    //
    public static List sortByNumbers(List list, String path) {

        Comparator comparator = new DataObjectComparator(path, true);

        return sort(list,comparator);
    }

    public static List sortByStrings(List list, String path) {

        Comparator comparator = new DataObjectComparator(path, false);

        return sort(list,comparator);
    }

    private static List sort(List list, Comparator comparator) {

        //Object[] items = list.toArray(); //does this always work?

        Object[] items = new Object[list.size()];

        for (int i = 0; i < items.length; i++) {

            items[i] = list.get(i);
        }

        Arrays.sort(items, comparator);

        List ret = new ArrayList();

        for (int i = 0; i < items.length; i++) {

            ret.add(items[i]);
        }

        return ret;
    }

    private static class DataObjectComparator implements Comparator {

        private final String m_path;

        private final boolean m_numeric;

        private Comparator m_string_comparator;

        public DataObjectComparator(String path, boolean numeric) { 

            m_path = path;

            m_numeric = numeric;

            if (!numeric) {
                m_string_comparator = java.text.Collator.getInstance();
            }
        }

        /**
         * Compares its two arguments for order.  Returns a negative integer,
         * zero, or a positive integer as the first argument is less than, equal
         * to, or greater than the second.

* * The implementor must ensure that sgn(compare(x, y)) == * -sgn(compare(y, x)) for all x and y. (This * implies that compare(x, y) must throw an exception if and only * if compare(y, x) throws an exception.)

* * The implementor must also ensure that the relation is transitive: * ((compare(x, y)>0) && (compare(y, z)>0)) implies * compare(x, z)>0.

* * Finally, the implementer must ensure that compare(x, y)==0 * implies that sgn(compare(x, z))==sgn(compare(y, z)) for all * z.

* * It is generally the case, but not strictly required that * (compare(x, y)==0) == (x.equals(y)). Generally speaking, * any comparator that violates this condition should clearly indicate * this fact. The recommended language is "Note: this comparator * imposes orderings that are inconsistent with equals." * * @param o1 the first object to be compared. * @param o2 the second object to be compared. * @return a negative integer, zero, or a positive integer as the * first argument is less than, equal to, or greater than the * second. * @throws ClassCastException if the arguments' types prevent them from * being compared by this Comparator. */ public int compare(Object o1, Object o2) { if (!(o1 instanceof DataObject) || !(o2 instanceof DataObject)) throw new java.lang.IllegalArgumentException("sort array must be all DataObjects"); DataObject data1 = (DataObject) o1; DataObject data2 = (DataObject) o2; String s1 = data1.getString(m_path); String s2 = data2.getString(m_path); //put nulls at the end if (s1 == null && s2 == null) return 0; if (s1 == null) return +1; if (s2 == null) return +1; if (m_numeric) { if (s1 == null && s2 == null) return 0; if (s1 == null) return +1; if (s2 == null) return +1; double n1 = 0; double n2 = 0; try { n1 = Double.valueOf(s1).doubleValue(); } catch (Exception e) { } try { n2 = Double.valueOf(s2).doubleValue(); } catch (Exception e) { } if (n1 == n2) return 0; if (n1 < n2) return -1; return 1; } else { return m_string_comparator.compare(s1, s2); } } /** * * Indicates whether some other object is "equal to" this * Comparator. This method must obey the general contract of * Object.equals(Object). Additionally, this method can return * true only if the specified Object is also a comparator * and it imposes the same ordering as this comparator. Thus, * comp1.equals(comp2) implies that sgn(comp1.compare(o1, * o2))==sgn(comp2.compare(o1, o2)) for every object reference * o1 and o2.

* * Note that it is always safe not to override * Object.equals(Object). However, overriding this method may, * in some cases, improve performance by allowing programs to determine * that two distinct Comparators impose the same order. * * @param obj the reference object with which to compare. * @return true only if the specified object is also * a comparator and it imposes the same ordering as this * comparator. * @see java.lang.Object#equals(java.lang.Object) * @see java.lang.Object#hashCode() */ public boolean equals(Object obj) { return super.equals(obj); //trick? } } //use this to copy fields from one data object to another public static void copyDataObject(DataObject source, DataObject target) { for (Iterator iter = source.getType().getProperties().iterator(); iter.hasNext();) { Property property = (Property) iter.next(); target.set("/" + property.toString(), source.getDataObject(property).clone()); //update / overwrite } } public static boolean isXPath(String path) { if (path == null) return false; if (path.charAt(0) == '/') return true; if (path.charAt(0) == '.') return true; //if (path.charAt(0) == '@') return true; //THIS CAUSES STACK OVERFLOW! int last = path.length() - 1; if (path.charAt(last) == ')') return true; if (path.charAt(last) == ']') return true; return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy