org.springjutsu.validation.util.PathUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.springjutsu.validation.util.PathUtils.java

Source

/*
 * Copyright 2010-2013 Duplichien, Wicksell, Springjutsu.org
 *
 * 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 org.springjutsu.validation.util;

import java.beans.PropertyDescriptor;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.util.ReflectionUtils;

/**
 * Provides several utility methods for manipulating
 * period-delimited bean property paths
 * @author Clark Duplichien
 *
 */
public class PathUtils {

    /**
     * Conjoins several individual segments into a single path
     * @param pathSegments the segments to join
     * @return The joined path
     */
    public static String appendPath(String... pathSegments) {
        String joinedPath = StringUtils.join(pathSegments, ".");
        return removeExtraneousPathSeparators(joinedPath);
    }

    /**
     * Joins multiple path segments into a single path.
     * @param pathSegments individual path segments
     * @return joined path.
     */
    public static String joinPathSegments(Collection<String> pathSegments) {
        String joinedPath = StringUtils.join(pathSegments, ".");
        return removeExtraneousPathSeparators(joinedPath);
    }

    /**
     * Removes any extraneous or duplicate period path separators
     * inadvertently created during the path joining process,
     * for example if one of the given path segments for an append
     * already contained a period. 
     * @param path The path to clean
     * @return The cleaned path.
     */
    public static String removeExtraneousPathSeparators(String path) {
        return path == null ? null : path.replaceAll("\\.+", "\\.").replaceAll("^\\.|\\.$", "").trim();
    }

    /**
     * Determine if a path exists on the given class.
     * @param clazz Class to check 
     * @param path Path to check
     * @return true if path exists.
     */
    public static boolean pathExists(Class<?> clazz, String path) {
        Class<?> pathClass = getClassForPath(clazz, path, true);
        return pathClass != null;
    }

    /**
     * Determine the class of the selected path on the target class. 
     * @param clazz Class to check 
     * @param path Path to check
     * @param unwrapFinalCollectionType if true returns the parameterized collection type
     * @return class for path.
     */
    public static Class<?> getClassForPath(Class<?> clazz, String path, boolean unwrapFinalCollectionType) {
        if (path == null || path.isEmpty()) {
            return clazz;
        }
        Class<?>[] pathClasses = getClassesForPathTokens(clazz, path, unwrapFinalCollectionType);
        return pathClasses == null ? null : pathClasses[pathClasses.length - 1];
    }

    /**
     * Determine the class of each step in the selected path on the target class. 
     * @param clazz Class to check 
     * @param path Path to check
     * @param unwrapCollectionTypes if true returns the parameterized collection type
     * @return array of classes for each step of path.
     */
    public static Class<?>[] getClassesForPathTokens(Class<?> clazz, String path, boolean unwrapCollectionTypes) {
        if (path == null || path.trim().isEmpty()) {
            return null;
        }
        Class<?> intermediateClass = clazz;
        String[] pathTokens = path.split("\\.");
        Class<?>[] pathClasses = new Class<?>[pathTokens.length];

        for (int i = 0; i < pathTokens.length; i++) {
            String token = pathTokens[i];
            token = token.replaceAll("\\[[^\\]]+\\]$", "");
            PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(intermediateClass, token);
            if (descriptor == null) {
                return null;
            } else if (List.class.isAssignableFrom(descriptor.getPropertyType())) {
                intermediateClass = TypeDescriptor.nested(ReflectionUtils.findField(intermediateClass, token), 1)
                        .getObjectType();
            } else if (descriptor.getPropertyType().isArray()) {
                intermediateClass = descriptor.getPropertyType().getComponentType();
            } else {
                intermediateClass = descriptor.getPropertyType();
            }
            if (unwrapCollectionTypes) {
                pathClasses[i] = intermediateClass;
            } else {
                pathClasses[i] = descriptor.getPropertyType();
            }
        }
        return pathClasses;
    }

    /**
     * Get a path constructed specified set of subpath segments from a path.
     * @param path the original path
     * @param startToken The first token index, inclusive: if null, the first token.
     * @param endToken The last token index, inclusive: if null, the last token.
     * @return The extracted subpath.
     */
    public static String subPath(String path, Integer startToken, Integer endToken) {
        String[] tokens = path.trim().split("\\.");
        int firstToken = startToken == null ? 0 : startToken;
        int lastToken = endToken == null ? tokens.length - 1 : endToken;
        String subPath = null;
        for (int i = firstToken; i <= lastToken; i++) {
            subPath = appendPath(subPath, tokens[i]);
        }
        return subPath;
    }

    /**
     * Use to determine if a path contains an ${EL} fragment.
     * @param path Path to check for EL fragments
     * @return true if the path contains an EL fragment.
     */
    public static boolean containsEL(String path) {
        return path.matches(".*\\$\\{.+\\}.*");
    }

    /**
     * Use to determine if a an entire path is an EL expression.
     * @param path Path to check for an EL expression
     * @return true if the path contains an EL expression.
     */
    public static boolean isEL(String path) {
        return path.matches("\\$\\{.+\\}");
    }
}