net.sf.companymanager.qbe.JpaUtil.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.companymanager.qbe.JpaUtil.java

Source

/*******************************************************************************
 * Copyright (c) 2014 antoniomariasanchez at gmail.com.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     antoniomaria - initial API and implementation
 ******************************************************************************/
/*
 * Copyright 2012 JAXIO http://www.jaxio.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 net.sf.companymanager.qbe;

import static java.lang.reflect.Modifier.isPublic;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import javax.persistence.EmbeddedId;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.Attribute;

import org.apache.commons.lang3.StringUtils;

public class JpaUtil {

    public static Predicate andPredicate(final CriteriaBuilder builder,
            final Iterable<Predicate> predicatesNullAllowed) {
        List<Predicate> predicates = withoutNullEntries(predicatesNullAllowed);
        if (predicates.isEmpty()) {
            return null;
        } else if (predicates.size() == 1) {
            return predicates.get(0);
        } else {
            return builder.and(predicates.toArray(new Predicate[predicates.size()]));
        }
    }

    public static Predicate andPredicate(final CriteriaBuilder builder, final Predicate... predicatesNullAllowed) {
        return andPredicate(builder, Arrays.asList(predicatesNullAllowed));
    }

    public static <E> List<Order> buildJpaOrders(final Iterable<OrderBy> orders, final Root<E> root,
            final CriteriaBuilder builder) {
        List<Order> jpaOrders = new ArrayList<Order>();

        for (OrderBy ob : orders) {
            Path<?> path = getPropertyPath(root, ob.getProperty());

            if (ob.isOrderDesc()) {
                jpaOrders.add(builder.desc(path));
            } else {
                jpaOrders.add(builder.asc(path));
            }
        }
        return jpaOrders;
    }

    public static boolean isEntityIdManuallyAssigned(final Class<?> type) {
        for (Method method : type.getMethods()) {
            if (isPrimaryKey(method)) {
                return isManuallyAssigned(method);
            }
        }
        return false; // no pk found, should not happen
    }

    public static Predicate concatPredicate(SearchParameters sp, CriteriaBuilder builder,
            Predicate... predicatesNullAllowed) {
        List<Predicate> predicatesNullAllowedList = new ArrayList<Predicate>();
        for (Predicate predicate : predicatesNullAllowed) {
            predicatesNullAllowedList.add(predicate);
        }
        return concatPredicate(sp, builder, predicatesNullAllowedList);
    }

    public static Predicate concatPredicate(SearchParameters sp, CriteriaBuilder builder,
            Iterable<Predicate> predicatesNullAllowed) {
        if (sp.isAndMode()) {
            return andPredicate(builder, predicatesNullAllowed);
        } else {
            return orPredicate(builder, predicatesNullAllowed);
        }
    }

    public static Predicate orPredicate(final CriteriaBuilder builder,
            final Iterable<Predicate> predicatesNullAllowed) {
        List<Predicate> predicates = withoutNullEntries(predicatesNullAllowed);
        if (predicates.isEmpty()) {
            return null;
        } else if (predicates.size() == 1) {
            return predicates.get(0);
        } else {
            return builder.or(predicates.toArray(new Predicate[predicates.size()]));
        }
    }

    public static <E> Predicate stringPredicate(Expression<String> path, Object attrValue,
            final SearchParameters sp, final CriteriaBuilder builder) {
        if (sp.isCaseInsensitive()) {
            path = builder.lower(path);
            attrValue = ((String) attrValue).toLowerCase(Locale.ENGLISH);
        }

        switch (sp.getSearchMode()) {
        case EQUALS:
            return builder.equal(path, attrValue);
        case ENDING_LIKE:
            return builder.like(path, "%" + attrValue);
        case STARTING_LIKE:
            return builder.like(path, attrValue + "%");
        case ANYWHERE:
            return builder.like(path, "%" + attrValue + "%");
        case LIKE:
            return builder.like(path, (String) attrValue); // assume user
                                                           // provide the wild
                                                           // cards
        default:
            throw new IllegalStateException("expecting a search mode!");
        }
    }

    /**
     * Convert the passed propertyPath into a JPA path. Note: JPA will do joins
     * if the property is in an associated
     * entity.
     */
    private static <E> Path<?> getPropertyPath(final Path<E> root, final String propertyPath) {
        String[] pathItems = StringUtils.split(propertyPath, ".");

        Path<?> path = root.get(pathItems[0]);
        for (int i = 1; i < pathItems.length; i++) {
            path = path.get(pathItems[i]);
        }
        return path;
    }

    private static boolean isManuallyAssigned(final Method method) {
        if (method.getAnnotation(Id.class) != null) {
            return method.getAnnotation(GeneratedValue.class) == null;
        } else if (method.getAnnotation(EmbeddedId.class) != null) {
            return true;
        } else {
            return true;
        }
    }

    private static boolean isPrimaryKey(final Method method) {
        return isPublic(method.getModifiers())
                && (method.getAnnotation(Id.class) != null || method.getAnnotation(EmbeddedId.class) != null);
    }

    private static <T> List<T> withoutNullEntries(final Iterable<T> input) {
        List<T> output = new ArrayList<T>();
        for (T element : input) {
            if (element != null) {
                output.add(element);
            }
        }
        return output;
    }

    public static String getPath(List<Attribute<?, ?>> attributes) {
        StringBuilder builder = new StringBuilder();
        for (Attribute<?, ?> attribute : attributes) {
            builder.append(attribute.getName()).append(".");
        }
        return builder.substring(0, builder.length() - 1);
    }

    /**
     * Convert the passed propertyPath into a JPA path.
     * <p>
     * Note: JPA will do joins if the property is in an associated entity.
     */
    @SuppressWarnings("unchecked")
    public static <E, F> Path<F> getPath(Root<E> root, List<Attribute<?, ?>> attributes) {
        Path<?> path = root;
        for (Attribute<?, ?> attribute : attributes) {
            boolean found = false;
            // handle case when order on already fetched attribute
            for (Fetch<E, ?> fetch : root.getFetches()) {
                if (attribute.getName().equals(fetch.getAttribute().getName()) && (fetch instanceof Join<?, ?>)) {
                    path = (Join<E, ?>) fetch;
                    found = true;
                    break;
                }
            }
            for (Join<E, ?> join : root.getJoins()) {
                if (attribute.getName().equals(join.getAttribute().getName())) {
                    path = join;
                    found = true;
                    break;
                }
            }
            if (!found) {
                path = path.get(attribute.getName());
            }
        }
        return (Path<F>) path;
    }

    public static <E> Predicate stringPredicate(Expression<String> path, Object attrValue, SearchMode searchMode,
            SearchParameters sp, CriteriaBuilder builder) {
        if (!sp.isCaseSensitive()) {
            path = builder.lower(path);
            //   attrValue = ((String) attrValue).toLowerCase(LocaleContextHolder.getLocale());
            attrValue = ((String) attrValue).toLowerCase();
        }
        switch (searchMode != null ? searchMode : sp.getSearchMode()) {
        case EQUALS:
            return builder.equal(path, attrValue);
        case NOT_EQUALS:
            return builder.notEqual(path, attrValue);
        case ENDING_LIKE:
            return builder.like(path, "%" + attrValue);
        case STARTING_LIKE:
            return builder.like(path, attrValue + "%");
        case ANYWHERE:
            return builder.like(path, "%" + attrValue + "%");
        case LIKE:
            return builder.like(path, (String) attrValue); // assume user
                                                           // provide the wild
                                                           // cards
        default:
            throw new IllegalStateException("expecting a search mode!");
        }
    }

}