com.lowereast.guiceymongo.util.DBObjectUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.lowereast.guiceymongo.util.DBObjectUtil.java

Source

/**
 *      Copyright (C) 2010 Lowereast Software
 *
 *   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 com.lowereast.guiceymongo.util;

import java.util.Arrays;
import java.util.List;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

public final class DBObjectUtil {
    private DBObjectUtil() {
    }

    private static <T> T checkArgNull(T obj, String name) throws IllegalArgumentException {
        if (obj == null)
            throw new IllegalArgumentException("The argument '" + name + "' was null.");
        return obj;
    }

    public static <E extends Enum<E>> E valueOfEnum(Class<E> enumClass, String value, E defaultValue) {
        try {
            if (value != null) {
                return Enum.valueOf(enumClass, value);
            }
        } catch (Exception e) {
            // log?
        }
        return defaultValue;
    }

    private static Object navigateNext(List<?> current, String key, boolean create) {
        Object next = null;
        try {
            int index = Integer.parseInt(key);
            next = current.get(index);
        } catch (NumberFormatException e) {
            throw new IllegalStateException(
                    "Navigation error: When the current object is a list, the key must be a number", e);
        }

        return next;
    }

    private static Object navigateNext(DBObject current, String key, boolean create) {
        Object next = current.get(key);
        if (next == null && create) {
            next = new BasicDBObject();
            current.put(key, next);
        }
        return next;
    }

    private static Object navigateToSubObject(DBObject dbObject, String[] property) {
        return navigateToSubObject(dbObject, property, false);
    }

    private static Object navigateToSubObject(DBObject dbObject, String[] property, boolean create) {
        Object current = dbObject;
        for (String key : property) {
            Object next = null;

            if (current instanceof List<?>) {
                next = navigateNext((List<?>) current, key, create);
            } else if (current instanceof DBObject) {
                next = navigateNext((DBObject) current, key, create);
            } else {
                throw new IllegalStateException("This shouldn't happen...  find me and fix me now!");
            }

            if (next == null)
                return null;
            current = next;
        }
        return current;
    }

    private static Object setPropertyValue(Object object, String key, Object value) {
        if (value instanceof Enum<?>)
            value = ((Enum<?>) value).name();

        if (object instanceof List<?>) {
            // not sure yet
        } else if (object instanceof DBObject) {
            return ((DBObject) object).put(key, value);
        }
        throw new IllegalStateException();
    }

    private static Object removePropertyValue(Object object, String key) {
        if (object instanceof List<?>) {
            // not sure yet
        } else if (object instanceof DBObject) {
            return ((DBObject) object).removeField(key);
        }
        throw new IllegalStateException();
    }

    public static boolean containsProperty(DBObject dbObject, String property) {
        checkArgNull(dbObject, "dbObject");
        String[] pieces = checkArgNull(property, "property").split("[.]");
        return navigateToSubObject(dbObject, pieces) != null;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getProperty(DBObject dbObject, String property) {
        checkArgNull(dbObject, "dbObject");
        String[] pieces = checkArgNull(property, "property").split("[.]");
        return (T) navigateToSubObject(dbObject, pieces);
    }

    @SuppressWarnings("unchecked")
    public static <T> T getProperty(DBObject dbObject, String property, T defaultValue) {
        checkArgNull(dbObject, "dbObject");
        String[] pieces = checkArgNull(property, "property").split("[.]");
        Object value = navigateToSubObject(dbObject, pieces);
        return value == null ? defaultValue : (T) value;
    }

    @SuppressWarnings("unchecked")
    public static <T> T getProperty(DBObject dbObject, String property, T defaultValue, boolean saveIfDefault) {
        checkArgNull(dbObject, "dbObject");
        String[] pieces = checkArgNull(property, "property").split("[.]");
        Object value = navigateToSubObject(dbObject, pieces);
        if (value != null)
            return (T) value;
        if (saveIfDefault)
            setProperty(dbObject, property, defaultValue);
        return defaultValue;
    }

    public static <T extends Enum<T>> T getEnumProperty(DBObject dbObject, Class<T> enumClass, String property,
            T defaultValue) {
        checkArgNull(dbObject, "dbObject");
        checkArgNull(enumClass, "enumClass");
        String[] pieces = checkArgNull(property, "property").split("[.]");
        Object value = navigateToSubObject(dbObject, pieces);
        return valueOfEnum(enumClass, (String) value, defaultValue);
    }

    public static <T> T setProperty(DBObject dbObject, String property, T value) {
        checkArgNull(dbObject, "dbObject");
        String[] pieces = checkArgNull(property, "property").split("[.]");
        checkArgNull(value, "value");

        if (pieces.length == 0)
            throw new IllegalArgumentException("");
        for (String key : pieces) {
            if (key == null)
                throw new IllegalArgumentException("");
        }

        Object object = dbObject;
        if (pieces.length > 1)
            object = navigateToSubObject(dbObject, Arrays.copyOf(pieces, pieces.length - 1), true);
        return (T) setPropertyValue(object, pieces[pieces.length - 1], value);
    }

    public static <T> T removeProperty(DBObject dbObject, String property) {
        checkArgNull(dbObject, "dbObject");
        String[] pieces = checkArgNull(property, "property").split("[.]");

        if (pieces.length == 0)
            throw new IllegalArgumentException("");
        for (String key : pieces) {
            if (key == null)
                throw new IllegalArgumentException("");
        }

        Object object = dbObject;
        if (pieces.length > 1)
            object = navigateToSubObject(dbObject, Arrays.copyOf(pieces, pieces.length - 1), true);
        return (T) removePropertyValue(object, pieces[pieces.length - 1]);
    }

    public static String encodeKey(String key) {
        return key.replace("_", "_" + (int) '_').replace(".", "_" + (int) '.');
    }

    public static String decodeKey(String key) {
        return key.replace("_" + (int) '.', ".").replace("_" + (int) '_', "_");
    }
}