/* * Copyright 2007 The Fornax Project Team, including the original * author or authors. * * 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.sculptor.framework.accessimpl.jpa; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Tuple; import javax.persistence.TupleElement; import javax.persistence.metamodel.SingularAttribute; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Utility class for JPA. * * @author Oliver Ringel */ public class JpaHelper { private static final Logger log = LoggerFactory.getLogger(JpaHelper.class); /** * Converts a collection with IN parameters to a plain string representation * * @param parameters * collection with IN parameters * @return plain string representation */ public static String convertToString(Collection<? extends Object> parameters) { if (parameters == null || parameters.isEmpty()) return ""; StringBuilder result = new StringBuilder(); for (Object param : parameters) { if (param instanceof String) param = "'" + param + "'"; if (result.length() != 0) result.append(","); result.append(param); } log.debug("restriction list converted to {}", result); return result.toString(); } public static boolean isJpaProviderHibernate(EntityManager entityManager) { return entityManager.getDelegate().getClass().getName().toLowerCase().contains("hibernate"); } public static boolean isJpaProviderEclipselink(EntityManager entityManager) { return entityManager.getDelegate().getClass().getName().toLowerCase().contains("eclipse"); } public static boolean isJpaProviderOpenJpa(EntityManager entityManager) { return entityManager.getDelegate().getClass().getName().toLowerCase().contains("openjpa"); } public static boolean isJpaProviderDataNucleus(EntityManager entityManager) { return entityManager.getDelegate().getClass().getName().toLowerCase().contains("datanucleus"); } /** * lists all fields of a given class * * @param clazz type * @return */ public static List<Field> listFields(Class<?> clazz) { assert clazz != null; Class<?> entityClass = clazz; List<Field> list = new ArrayList<Field>(); while (!Object.class.equals(entityClass) && entityClass != null) { list.addAll(Arrays.asList(entityClass.getDeclaredFields())); entityClass = entityClass.getSuperclass(); } return list; } /** * tries to find a field by a field name * * @param clazz type * @param name name of the field * @return */ public static Field findField(Class<?> clazz, String name) { Class<?> entityClass = clazz; while (!Object.class.equals(entityClass) && entityClass != null) { Field[] fields = entityClass.getDeclaredFields(); for (Field field : fields) { if (name.equals(field.getName())) { return field; } } entityClass = entityClass.getSuperclass(); } return null; } /** * tries to find a property method by name * * @param clazz type * @param name name of the property * @return */ public static Method findProperty(Class<?> clazz, String name) { assert clazz != null; assert name != null; Class<?> entityClass = clazz; while (entityClass != null) { Method[] methods = (entityClass.isInterface() ? entityClass.getMethods() : entityClass.getDeclaredMethods()); for (Method method : methods) { if (method.getName().equals("get"+ StringUtils.capitalize(name)) || method.getName().equals("is"+ StringUtils.capitalize(name))) { return method; } } entityClass = entityClass.getSuperclass(); } return null; } /** * tries to get the value from a field or a getter property for a given object instance * * @param instance the object instance * @param name name of the property or field * @return * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InvocationTargetException */ public static Object getValue(Object instance, String name) { assert instance != null; assert name != null; try { Class<?> clazz = instance.getClass(); Object value = null; Method property = findProperty(clazz, name); if (property != null) { value = property.invoke(instance); } else { Field field = findField(clazz, name); if (field != null) { value = field.get(instance); } } log.debug("Value for field/property '{}' is: '{}'", name, value); return value; } catch (Exception e) { log.error("Could not get a value for field/property '" + name + "'", e); return null; } } public static void setValue(Object instance, String name) { assert instance != null; assert name != null; try { Class<?> clazz = instance.getClass(); Object value = null; Method property = findProperty(clazz, name); if (property != null) { value = property.invoke(instance); } else { Field field = findField(clazz, name); if (field != null) { value = field.get(instance); } } log.debug("Value for field/property '{}' is: '{}'", name, value); } catch (Exception e) { log.error("Could not get a value for field/property '" + name + "'", e); } } @SuppressWarnings({ "rawtypes" }) public static Object getValue(Object entity, SingularAttribute attribute) { try { return getValue(entity, attribute.getName()); } catch (Exception e) { e.printStackTrace(); } return null; } /** * get a named query from an entity * * @param type * @param name * @return */ public static NamedQuery findNamedQuery(Class<?> type, String name) { NamedQuery annotatedNamedQuery = (NamedQuery) type.getAnnotation(NamedQuery.class); if (annotatedNamedQuery != null) { return annotatedNamedQuery; } NamedQueries annotatedNamedQueries = (NamedQueries) type.getAnnotation(NamedQueries.class); if (annotatedNamedQueries != null) { NamedQuery[] namedQueries = annotatedNamedQueries.value(); if (namedQueries != null) { for (NamedQuery namedQuery : namedQueries) { if (namedQuery.name().equalsIgnoreCase(name)) { return namedQuery; } } } } // no named query with that name log.debug("No NamedQuery with name '{}' exists for type '{}'", name, type); return null; } /** * Build a query based on the original query to count results * * @param query * @return */ public static String createResultCountQuery(String query) { String resultCountQueryString = null; int select = query.toLowerCase().indexOf("select"); int from = query.toLowerCase().indexOf("from"); if (select == -1 || from == -1) { return null; } resultCountQueryString = "select count(" + query.substring(select + 6, from).trim() + ") " + query.substring(from); // remove order by // TODO: remove more parts if (resultCountQueryString.toLowerCase().contains("order by")) { resultCountQueryString = resultCountQueryString.substring(0, resultCountQueryString.toLowerCase().indexOf("order by")); } log.debug("Created query for counting results '{}'", resultCountQueryString); return resultCountQueryString; } /** * build a single String from a List of objects with a given separator * * @param values * @param separator * @return */ public static String toSeparatedString(List<?> values, String separator) { return toSeparatedString(values, separator, null); } /** * build a single String from a List of objects with a given separator and prefix * * @param values * @param separator * @param prefix * @return */ public static String toSeparatedString(List<?> values, String separator, String prefix) { StringBuilder result = new StringBuilder(); for (Object each : values) { if (each == null) { continue; } if (result.length() > 0) { result.append(separator); } if (prefix != null) { result.append(String.valueOf(each)); } else { result.append(prefix + String.valueOf(each)); } } return result.toString(); } /** * * @param <T> * @param tuple * @param object * @return */ public static <T> T mapTupleToObject(Tuple tuple, T object) throws IllegalAccessException, InvocationTargetException { assert tuple != null; assert object != null; try { for (TupleElement<?> element : tuple.getElements()) { if (element.getAlias() != null) { BeanUtils.setProperty( object, element.getAlias(), tuple.get(element.getAlias())); } } return object; } catch (Exception e) { log.error("mapTupleToObject not successful", e); throw new QueryConfigException("mapTupleToObject not successful"); } } /** * * @param <T> * @param tuple * @param type * @return */ public static <T> T mapTupleToObject(Tuple tuple, Class<T> type) { assert tuple != null; assert type != null; try { return mapTupleToObject(tuple, type.newInstance()); } catch (Exception e) { log.error("mapTupleToObject not successful", e); throw new QueryConfigException("mapTupleToObject not successful"); } } }