com.zauberlabs.commons.mom.NaiveProperties.java Source code

Java tutorial

Introduction

Here is the source code for com.zauberlabs.commons.mom.NaiveProperties.java

Source

/**
 * Copyright (c) 2009-2012 Zauber S.A. <http://www.zaubersoftware.com/>
 *
 * 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.zauberlabs.commons.mom;

import java.lang.reflect.Method;

import net.sf.staccatocommons.check.Ensure;
import net.sf.staccatocommons.collections.stream.Streams;
import net.sf.staccatocommons.defs.predicate.Predicate;
import net.sf.staccatocommons.lang.SoftException;
import net.sf.staccatocommons.lang.function.AbstractFunction;
import net.sf.staccatocommons.lang.predicate.AbstractPredicate;
import net.sf.staccatocommons.lang.predicate.Predicates;
import net.sf.staccatocommons.restrictions.Constant;
import net.sf.staccatocommons.restrictions.check.NonNull;
import net.sf.staccatocommons.restrictions.check.NotEmpty;
import net.sf.staccatocommons.restrictions.processing.IgnoreRestrictions;
import net.sf.staccatocommons.util.Strings;

import org.apache.commons.lang.StringUtils;

/**
 * Utility class for accessing and updating bean-style properties. It is similar
 * in intent to Apache's PropertyUtils, but drops support for special properties
 * bean utils adds and indexed properties, and relax signature constraints - for
 * example, accepts non-void setters
 * 
 * @author flbulgarelli
 */
public class NaiveProperties {

    /**
     * Answers the getter of a given property and class, or null, if such
     * property is not readable or inexistent
     */
    public static Method getterOrNull(@NonNull final Class<?> clazz, @NotEmpty final String propertyName) {
        String capitalizedName = StringUtils.capitalize(propertyName);
        return findMethodOrNull(clazz, 0, Strings.matches("(get|is)" + capitalizedName));
    }

    /**
     * Answers the getter of a given property and class. Throws an
     * {@link IllegalArgumentException}, if such property is not readable or
     * inexistent
     */
    @IgnoreRestrictions
    public static Method getter(@NonNull final Class<?> clazz, @NotEmpty final String propertyName) {
        Method getter = getterOrNull(clazz, propertyName);
        Ensure.that(getter != null, "Property %s in class %s is not readable", propertyName, clazz);
        return getter;
    }

    /**
     * Answers the setter of a given property and class, or null, if such
     * property is not writable or inexistent
     */
    public static Method setterOrNull(@NonNull final Class<?> clazz, @NotEmpty final String propertyName) {
        String capitalizedName = StringUtils.capitalize(propertyName);
        return findMethodOrNull(clazz, 1, Predicates.equal("set" + capitalizedName));
    }

    /**
     * Answers the setter of a given property and class. Throws an
     * {@link IllegalArgumentException}, if such property is not writable or
     * inexistent
     */
    @IgnoreRestrictions
    public static Method setter(@NonNull final Class<?> clazz, final String propertyName) {
        Method setter = setterOrNull(clazz, propertyName);
        Ensure.that(setter != null, "Property %s in class %s is not writable", propertyName, clazz);
        return setter;
    }

    public static Method findMethodOrNull(@NonNull final Class<?> clazz, final int argsCount,
            final Predicate<String> namePredicate) {
        return Streams //
                .cons(clazz.getMethods()) //
                .findOrNull(signature(argsCount, namePredicate));
    }

    /**
     * @param argsCount
     * @param namePredicate
     * @return
     */
    public static Predicate<Method> signature(final int argsCount, final Predicate<String> namePredicate) {
        return argCount(argsCount).and(namePredicate.of(methodName()));
    }

    public static <T> T get(@NonNull final Object destination, @NotEmpty final String propertyName) {
        try {
            return (T) getter(destination.getClass(), propertyName).invoke(destination);
        } catch (Exception e) {
            throw SoftException.soften(e);
        }
    }

    public static void set(@NonNull final Object destination, @NotEmpty final String propertyName,
            final Object propertyValue) {
        try {
            setter(destination.getClass(), propertyName).invoke(destination, propertyValue);
        } catch (Exception e) {
            throw SoftException.soften(e);
        }
    }

    /** function that answers method arguments count */
    @Constant
    public static AbstractPredicate<Method> argCount(final int argsCount) {
        return new AbstractPredicate<Method>() {
            @Override
            public boolean eval(final Method arg0) {
                return arg0.getParameterTypes().length == argsCount;
            }
        };
    }

    /** function that answers method name */
    @Constant
    public static AbstractFunction<Method, String> methodName() {
        return new AbstractFunction<Method, String>() {
            public String apply(final Method arg0) {
                return arg0.getName();
            }
        };
    }

}