co.jirm.core.util.ObjectMapUtils.java Source code

Java tutorial

Introduction

Here is the source code for co.jirm.core.util.ObjectMapUtils.java

Source

/**
 * Copyright (C) 2012 the original author or authors.
 *
 * 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.
 */
package co.jirm.core.util;

import static co.jirm.core.util.JirmPrecondition.check;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import org.joda.time.DateTime;

import co.jirm.core.JirmIllegalArgumentException;

import com.google.common.collect.Maps;
import com.google.common.primitives.Ints;

public class ObjectMapUtils {

    public static StringBuilder toStringList(StringBuilder sb, List<?> objects, int length) {
        sb.append("[");
        boolean first = true;
        for (Object o : objects) {
            if (first) {
                first = false;
            } else {
                sb.append(", ");
            }
            final String s;
            if (o instanceof Calendar) {
                s = new DateTime(o).toString();
            } else {
                s = o.toString();
            }
            if (length < s.length())
                sb.append(s, 0, length).append("...");
            else
                sb.append(s);
        }
        sb.append("]");
        return sb;
    }

    //TODO cache
    private static Enum<?>[] _enumValues(Class<?> enumClass) throws SecurityException, NoSuchMethodException,
            IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Method m = enumClass.getMethod("values");
        return (Enum<?>[]) m.invoke((Object) null);
    }

    public static Enum<?>[] enumValues(Class<?> enumClass) {
        try {
            return _enumValues(enumClass);
        } catch (Exception e) {
            throw new JirmIllegalArgumentException("Cannot dynamically resolve enum values for:" + enumClass, e);
        }
    }

    public static Enum<?> enumFrom(Class<?> enumClass, int oridinal) {
        return enumValues(enumClass)[oridinal];
    }

    public static Enum<?> enumFrom(Class<?> enumClass, String name) {
        Enum<?>[] enums = enumValues(enumClass);
        for (Enum<?> e : enums) {
            if (e.name().equals(name)) {
                return e;
            }
        }
        throw check.argumentInvalid("name: {} is not valid for: {}", name, enumClass);
    }

    @SuppressWarnings("unchecked")
    public static void pushPath(final Map<String, Object> m, List<String> names, Object value) {
        Map<String, Object> current = m;
        int j = 0;
        for (String n : names) {
            j++;
            if (j == names.size()) {
                current.put(n, value);
                break;
            }
            Object o = current.get(n);
            if (o == null) {
                Map<String, Object> sub = Maps.newLinkedHashMap();
                current.put(n, sub);
                current = sub;
            } else if (o instanceof Map) {
                current = (Map<String, Object>) o;
            } else {
                throw new IllegalArgumentException("Cannot set value to " + names);
            }
        }
    }

    public static <T> NestedKeyValue<T> getNestedKeyValue(Map<?, ?> m, Object... keys) {
        return _getNestedKeyValue(m, null, null, keys);
    }

    @SuppressWarnings("unchecked")
    private static <T> NestedKeyValue<T> _getNestedKeyValue(final Map<?, ?> m, final List<?> l, final Class<T> c,
            Object... keys) {
        Object t = null;
        check.argument(m == null || l == null, "Either m or l should be null");
        Map<?, ?> tm = m;
        List<?> tl = l;

        int i = 0;
        for (Object k : keys) {
            if (tm != null && tm.containsKey(k)) {
                t = tm.get(k);
            } else if (tl != null && k instanceof Number) {
                t = tl.get(((Number) k).intValue());
            } else if (tl != null && k instanceof String && !((String) k).isEmpty()
                    && Ints.tryParse((String) k) != null) {
                t = tl.get(Integer.parseInt(k.toString()));
            } else {
                t = null;
                break;
            }

            if (t instanceof Map) {
                tm = (Map<?, ?>) t;
                tl = null;
            } else if (t instanceof List) {
                tl = (List<?>) t;
                tm = null;
            } else if (t == null) {
                break;
            }
            i++;
        }
        boolean conflict = t != null && c != null && !c.isInstance(t);
        T object = conflict ? null : (T) t;

        return new NestedKeyValue<T>(object, keys, i, conflict);

    }

    public static class NestedKeyValue<T> {
        public final T object;
        public final int depthStopped;
        public final Object[] keys;
        public final boolean conflict;

        private NestedKeyValue(T object, Object[] keys, int depthStopped, boolean conflict) {
            super();
            this.object = object;
            this.keys = keys;
            this.depthStopped = depthStopped;
            this.conflict = conflict;
        }

        public boolean isPresent() {
            return depthStopped == keys.length;
        }
    }

}