All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jaxio.jpa.querybyexample.JpaUtil Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
/*
 * Copyright 2015 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 com.jaxio.jpa.querybyexample;

import org.apache.commons.beanutils.MethodUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.WordUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.i18n.LocaleContextHolder;

import javax.inject.Named;
import javax.inject.Singleton;
import javax.persistence.*;
import javax.persistence.criteria.*;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Predicates.notNull;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.toArray;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static java.lang.reflect.Modifier.isPublic;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.hibernate.proxy.HibernateProxyHelper.getClassWithoutInitializingProxy;

@Named
@Singleton
@Lazy(false)
public class JpaUtil {

    private Map, String> compositePkCache = newHashMap();
    private static JpaUtil instance;

    public static JpaUtil getInstance() {
        return instance;
    }

    public JpaUtil() {
        instance = this;
    }

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

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

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

        return method.getAnnotation(EmbeddedId.class) != null;
    }

    public Predicate concatPredicate(SearchParameters sp, CriteriaBuilder builder, Predicate... predicatesNullAllowed) {
        return concatPredicate(sp, builder, newArrayList(predicatesNullAllowed));
    }

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

    public Predicate andPredicate(CriteriaBuilder builder, Predicate... predicatesNullAllowed) {
        return andPredicate(builder, newArrayList(predicatesNullAllowed));
    }

    public Predicate orPredicate(CriteriaBuilder builder, Predicate... predicatesNullAllowed) {
        return orPredicate(builder, newArrayList(predicatesNullAllowed));
    }

    public Predicate andPredicate(CriteriaBuilder builder, Iterable predicatesNullAllowed) {
        List predicates = newArrayList(filter(predicatesNullAllowed, notNull()));
        if (predicates == null || predicates.isEmpty()) {
            return null;
        } else if (predicates.size() == 1) {
            return predicates.get(0);
        } else {
            return builder.and(toArray(predicates, Predicate.class));
        }
    }

    public Predicate orPredicate(CriteriaBuilder builder, Iterable predicatesNullAllowed) {
        List predicates = newArrayList(filter(predicatesNullAllowed, notNull()));
        if (predicates == null || predicates.isEmpty()) {
            return null;
        } else if (predicates.size() == 1) {
            return predicates.get(0);
        } else {
            return builder.or(toArray(predicates, Predicate.class));
        }
    }

    public  Predicate stringPredicate(Expression path, Object attrValue, SearchMode searchMode, SearchParameters sp, CriteriaBuilder builder) {
        if (sp.isCaseInsensitive()) {
            path = builder.lower(path);
            attrValue = ((String) attrValue).toLowerCase(LocaleContextHolder.getLocale());
        }

        switch (searchMode != null ? searchMode : 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!");
        }
    }

    public  Predicate stringPredicate(Expression path, Object attrValue, SearchParameters sp, CriteriaBuilder builder) {
        return stringPredicate(path, attrValue, null, sp, builder);
    }

    /*
     * Convert the passed propertyPath into a JPA path.
     * 

* Note: JPA will do joins if the property is in an associated entity. */ @SuppressWarnings("unchecked") public Path getPath(Root root, List> attributes) { Path path = root; for (Attribute attribute : attributes) { boolean found = false; if (path instanceof FetchParent) { for (Fetch fetch : ((FetchParent) path).getFetches()) { if (attribute.getName().equals(fetch.getAttribute().getName()) && (fetch instanceof Join)) { path = (Join) fetch; found = true; break; } } } if (!found) { if (attribute instanceof PluralAttribute) { path = ((From) path).join(attribute.getName(), JoinType.LEFT); } else { path = path.get(attribute.getName()); } } } return (Path) path; } public void verifyPath(Attribute... path) { verifyPath(newArrayList(path)); } public void verifyPath(List> path) { List> attributes = newArrayList(path); Class from = null; if (attributes.get(0).isCollection()) { from = ((PluralAttribute) attributes.get(0)).getElementType().getJavaType(); } else { from = attributes.get(0).getJavaType(); } attributes.remove(0); for (Attribute attribute : attributes) { if (!attribute.getDeclaringType().getJavaType().isAssignableFrom(from)) { throw new IllegalStateException("Wrong path."); } from = attribute.getJavaType(); } } public > String compositePkPropertyName(T entity) { Class entityClass = entity.getClass(); if (compositePkCache.containsKey(entityClass)) { return compositePkCache.get(entityClass); } for (Method m : entity.getClass().getMethods()) { if (m.getAnnotation(EmbeddedId.class) != null) { String propertyName = methodToProperty(m); compositePkCache.put(entityClass, propertyName); return propertyName; } } for (Field f : entity.getClass().getFields()) { if (f.getAnnotation(EmbeddedId.class) != null) { String propertyName = f.getName(); compositePkCache.put(entityClass, propertyName); return propertyName; } } compositePkCache.put(entityClass, null); return null; } public boolean isPk(ManagedType mt, SingularAttribute attr) { try { Method m = MethodUtils.getAccessibleMethod(mt.getJavaType(), "get" + WordUtils.capitalize(attr.getName()), (Class) null); if (m != null && m.getAnnotation(Id.class) != null) { return true; } Field field = mt.getJavaType().getField(attr.getName()); return field.getAnnotation(Id.class) != null; } catch (Exception e) { return false; } } public Object getValue(T example, Attribute attr) { try { if (attr.getJavaMember() instanceof Method) { return ((Method) attr.getJavaMember()).invoke(example); } else { return ((Field) attr.getJavaMember()).get(example); } } catch (Exception e) { throw propagate(e); } } public SingularAttribute attribute(ManagedType mt, Attribute attr) { return mt.getSingularAttribute(attr.getName(), attr.getJavaType()); } public SingularAttribute stringAttribute(ManagedType mt, Attribute attr) { return mt.getSingularAttribute(attr.getName(), String.class); } public > boolean hasSimplePk(T entity) { for (Method m : entity.getClass().getMethods()) { if (m.getAnnotation(Id.class) != null) { return true; } } for (Field f : entity.getClass().getFields()) { if (f.getAnnotation(Id.class) != null) { return true; } } return false; } public String[] toNames(Attribute... attributes) { return toNamesList(newArrayList(attributes)).toArray(new String[0]); } public List toNamesList(List> attributes) { List ret = newArrayList(); for (Attribute attribute : attributes) { ret.add(attribute.getName()); } return ret; } public String getEntityName(Identifiable entity) { Entity entityAnnotation = entity.getClass().getAnnotation(Entity.class); if (isBlank(entityAnnotation.name())) { return getClassWithoutInitializingProxy(entity).getSimpleName(); } return entityAnnotation.name(); } public String methodToProperty(Method m) { PropertyDescriptor[] pds = PropertyUtils.getPropertyDescriptors(m.getDeclaringClass()); for (PropertyDescriptor pd : pds) { if (m.equals(pd.getReadMethod()) || m.equals(pd.getWriteMethod())) { return pd.getName(); } } return null; } public Object getValueFromField(Field field, Object object) { boolean accessible = field.isAccessible(); try { return getField(field, object); } finally { field.setAccessible(accessible); } } public void applyPagination(Query query, SearchParameters sp) { if (sp.getFirst() > 0) { query.setFirstResult(sp.getFirst()); } if (sp.getPageSize() > 0) { query.setMaxResults(sp.getPageSize()); } else if (sp.getMaxResults() > 0) { query.setMaxResults(sp.getMaxResults()); } } @SuppressWarnings("unchecked") private T getField(Field field, Object target) { try { return (T) field.get(target); } catch (Exception e) { throw new RuntimeException(e); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy