Java tutorial
/* * Copyright 2011-2013 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 kr.debop4j.data.hibernate.tools; import com.google.common.collect.Sets; import kr.debop4j.core.Function1; import kr.debop4j.core.IDataObject; import kr.debop4j.core.json.GsonSerializer; import kr.debop4j.core.json.IJsonSerializer; import kr.debop4j.core.parallelism.Parallels; import kr.debop4j.core.tools.MapperTool; import kr.debop4j.core.tools.StringTool; import kr.debop4j.data.hibernate.HibernateParameter; import kr.debop4j.data.hibernate.repository.IHibernateDao; import kr.debop4j.data.hibernate.repository.impl.HibernateDao; import kr.debop4j.data.model.*; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.hibernate.Session; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.type.LocaleType; import org.hibernate.type.ObjectType; import org.hibernate.type.StringType; import javax.annotation.Nullable; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Locale; import static kr.debop4j.core.Guard.shouldNotBeNull; import static kr.debop4j.core.Guard.shouldNotBeWhiteSpace; /** * Hibernate Utility Class . * * @author ? ( sunghyouk.bae@gmail.com ) * @since 12. 9. 24 */ @Slf4j @SuppressWarnings("unchecked") public class EntityTool { private EntityTool() { } /** The constant PROPERTY_ANCESTORS. */ public static final String PROPERTY_ANCESTORS = "ancestors"; /** The constant PROPERTY_DESCENDENTS. */ public static final String PROPERTY_DESCENDENTS = "descendents"; @Getter(lazy = true) private static final IJsonSerializer gsonSerializer = new GsonSerializer(); /** * Entity to string. * * @param entity the entity * @return the string */ public static String entityToString(IDataObject entity) { return (entity != null) ? StringTool.objectToString(entity) : StringTool.NULL_STR; } /** * As gson text. * * @param entity the entity * @return the string * @throws Exception the exception */ public static String asGsonText(IDataObject entity) throws Exception { return getGsonSerializer().serializeToText(entity); } // region << Hierarchy >> /** * Assert not circular hierarchy. * * @param child the child * @param parent the parent */ public static <T extends IHierarchyEntity<T>> void assertNotCircularHierarchy(T child, T parent) { if (child == parent) throw new IllegalArgumentException("Child and Parent are same."); if (child.getDescendents().contains(parent)) throw new IllegalArgumentException("child parent ? ?? ."); if (Sets.intersection(parent.getAncestors(), child.getDescendents()).size() > 0) throw new IllegalArgumentException( "parent? ? child? ?? ? ? ?."); } /** * Sets hierarchy. * * @param child the child * @param oldParent the old parent * @param newParent the new parent */ public static <T extends IHierarchyEntity<T>> void setHierarchy(T child, T oldParent, T newParent) { shouldNotBeNull(child, "child"); log.trace( " ? , ... child=[{}], oldParent=[{}], newParent=[{}]", child, oldParent, newParent); if (oldParent != null) removeHierarchy(child, oldParent); if (newParent != null) setHierarchy(child, newParent); } /** * Sets hierarchy. * * @param child the child * @param parent the parent */ public static <T extends IHierarchyEntity<T>> void setHierarchy(T child, T parent) { if (parent == null || child == null) return; log.trace("? ? ?? . child=[{}], parent=[{}]", child, parent); parent.getDescendents().add(child); parent.getDescendents().addAll(child.getDescendents()); for (T ancestor : parent.getAncestors()) { ancestor.getDescendents().add(child); ancestor.getDescendents().addAll(child.getDescendents()); } child.getAncestors().add(parent); child.getAncestors().addAll(parent.getAncestors()); } /** * Remove hierarchy. * * @param child the child * @param parent the parent */ public static <T extends IHierarchyEntity<T>> void removeHierarchy(T child, T parent) { if (parent == null) return; shouldNotBeNull(child, "child"); log.trace("? ? ?? . child=[{}], parent=[{}]", child, parent); child.getAncestors().remove(parent); child.getAncestors().removeAll(parent.getAncestors()); for (T ancestor : parent.getAncestors()) { ancestor.getDescendents().remove(child); ancestor.getDescendents().removeAll(child.getDescendents()); } for (T descendent : child.getDescendents()) { descendent.getAncestors().remove(parent); descendent.getAncestors().removeAll(parent.getAncestors()); } } /** * Get ancestors criteria. * * @param entity the entity * @param session the session * @param entityClass the entity class * @return the detached criteria */ public static <T extends IHierarchyEntity<T> & IEntity<TId>, TId extends Serializable> DetachedCriteria getAncestorsCriteria( T entity, Session session, Class<T> entityClass) { return DetachedCriteria.forClass(entityClass).createAlias(PROPERTY_DESCENDENTS, "des") .add(Restrictions.eq("des.id", entity.getId())); } /** * Get descendents criteria. * * @param entity the entity * @param session the session * @param entityClass the entity class * @return the detached criteria */ public static <T extends IHierarchyEntity<T> & IEntity<TId>, TId extends Serializable> DetachedCriteria getDescendentsCriteria( T entity, Session session, Class<T> entityClass) { return DetachedCriteria.forClass(entityClass).createAlias(PROPERTY_ANCESTORS, "ans") .add(Restrictions.eq("ans.id", entity.getId())); } /** * Get ancestors id criteria. * * @param entity the entity * @param session the session * @param entityClass the entity class * @return the detached criteria */ public static <T extends IHierarchyEntity<T> & IEntity<TId>, TId extends Serializable> DetachedCriteria getAncestorsIdCriteria( T entity, Session session, Class<T> entityClass) { return getAncestorsCriteria(entity, session, entityClass) .setProjection(Projections.distinct(Projections.id())); } /** * Get descendents id criteria. * * @param entity the entity * @param session the session * @param entityClass the entity class * @return the detached criteria */ public static <T extends IHierarchyEntity<T> & IEntity<TId>, TId extends Serializable> DetachedCriteria getDescendentsIdCriteria( T entity, Session session, Class<T> entityClass) { return getDescendentsCriteria(entity, session, entityClass) .setProjection(Projections.distinct(Projections.id())); } // endregion // region << ILocaleEntity >> /** ? HQL . */ public static final String GET_LIST_BY_LOCALE_KEY = "select distinct loen from %s loen where :key in indices (loen.localeMap)"; /** ? ?? HQL . */ public static final String GET_LIST_BY_LOCALE_PROPERTY = "select distinct loen from %s loen join loen.localeMap locale where locale.%s = :%s"; /** * Copy locale. * * @param source the source * @param destination the destination */ public static <T extends ILocaleEntity<TLocaleValue>, TLocaleValue extends ILocaleValue> void CopyLocale( T source, T destination) { for (Locale locale : source.getLocales()) destination.addLocaleValue(locale, source.getLocaleValue(locale)); } /** * Contains locale. * * @param entityClass the entity class * @param locale the locale * @return the list */ public static <T extends ILocaleEntity<TLocaleValue>, TLocaleValue extends ILocaleValue> List<T> containsLocale( Class<T> entityClass, Locale locale) { String hql = String.format(GET_LIST_BY_LOCALE_KEY, entityClass.getName()); if (log.isDebugEnabled()) log.debug("IEntity [{}] ? Locale[{}] hql=[{}]", entityClass.getName(), locale, hql); IHibernateDao dao = new HibernateDao(); return dao.find(entityClass, hql, new HibernateParameter("key", locale, LocaleType.INSTANCE)); } /** * Contains locale. * * @param entityClass the entity class * @param propertyName the property name * @param value the value * @param type the type * @return the list */ public static <T extends ILocaleEntity<TLocaleValue>, TLocaleValue extends ILocaleValue> List<T> containsLocale( final Class<T> entityClass, final String propertyName, final Object value, final org.hibernate.type.Type type) { final String hql = String.format(GET_LIST_BY_LOCALE_PROPERTY, entityClass.getName(), propertyName, propertyName); if (log.isDebugEnabled()) log.debug( "IEntity [{}] ? Locale ?[{}]? ? [{}] ? . hql=[{}]", entityClass.getName(), propertyName, value, hql); IHibernateDao dao = new HibernateDao(); return dao.find(entityClass, hql, new HibernateParameter(propertyName, value, ObjectType.INSTANCE)); } // endregion // region << IMetaEntity >> private static final String GET_LIST_BY_META_KEY = "select distinct me from %s me where :key in indices(me.metaMap)"; public static final String GET_LIST_BY_META_VALUE = "select distinct me from %s me join me.metaMap meta where meta.value = :value"; /** * Contains meta key. * * @param entityClass the entity class * @param key the key * @return the list */ public static <T extends IMetaEntity> List<T> containsMetaKey(Class<T> entityClass, String key) { shouldNotBeWhiteSpace(key, "key"); String hql = String.format(GET_LIST_BY_META_KEY, entityClass.getName()); if (log.isDebugEnabled()) log.debug(" [{}]? ?? [{}] hql=[{}]", entityClass.getName(), key, hql); IHibernateDao dao = new HibernateDao(); return dao.find(entityClass, hql, new HibernateParameter("key", key, StringType.INSTANCE)); } /** * Contains meta value. * * @param entityClass the entity class * @param value the value * @return the list */ public static <T extends IMetaEntity> List<T> containsMetaValue(final Class<T> entityClass, final String value) { shouldNotBeWhiteSpace(value, "value"); String hql = String.format(GET_LIST_BY_META_VALUE, entityClass.getName()); if (log.isDebugEnabled()) log.debug("?? value[{}] hql=[{}]", value, hql); IHibernateDao dao = new HibernateDao(); return dao.find(entityClass, hql, new HibernateParameter("value", value, StringType.INSTANCE)); } // endregion // region << IEntity Mapper >> /** * ? ? ? ? ? ? . * * @param source the source * @param target the target * @return target entity */ public static <S, T> T mapEntity(S source, T target) { MapperTool.map(source, target); return target; } /** * Map entity. * * @param source the source * @param targetClass the target class * @return target entity */ public static <S, T> T mapEntity(S source, Class<T> targetClass) { shouldNotBeNull(source, "source"); return MapperTool.map(source, targetClass); } /** * ? ? ? . {@link kr.debop4j.core.tools.MapperTool} ? . * * @param sources the sources * @param targets the targets * @return the list */ public static <S, T> List<T> mapEntities(List<S> sources, List<T> targets) { shouldNotBeNull(sources, "sources"); shouldNotBeNull(targets, "targets"); int size = Math.min(sources.size(), targets.size()); for (int i = 0; i < size; i++) { MapperTool.map(sources.get(i), targets.get(i)); } return targets; } /** * ? ? ? . ? DTO ? . * * @param sources the sources * @param targetClass the target class * @return the list */ public static <S, T> List<T> mapEntitiesAsParallel(final List<S> sources, final Class<T> targetClass) { if (sources == null || sources.size() == 0) return new ArrayList<>(); return Parallels.runEach(sources, new Function1<S, T>() { @Override public T execute(@Nullable S input) { return MapperTool.map(input, targetClass); } }); } // endregion // region << TreeNode >> /** * Update tree node position. * * @param entity the entity */ public static <T extends ITreeEntity<T>> void updateTreeNodePosition(T entity) { shouldNotBeNull(entity, "entity"); log.trace("update tree node position... entity=[{}]", entity); TreeNodePosition nodePosition = entity.getNodePosition(); if (entity.getParent() != null) { nodePosition.setLevel(entity.getParent().getNodePosition().getLevel() + 1); if (!entity.getParent().getChildren().contains(entity)) nodePosition.setOrder(entity.getParent().getChildren().size()); } else { nodePosition.setLevel(0); nodePosition.setOrder(0); } } /** * ? ?? . * * @param entity the entity * @return the child count */ public static <T extends ITreeEntity<T>> Long getChildCount(T entity) { log.trace("tree entity? ?? ? . entity=[{}]", entity); DetachedCriteria dc = HibernateTool.createDetachedCriteria(entity.getClass()); dc.add(Restrictions.eq("parent", entity)); IHibernateDao dao = new HibernateDao(); return dao.count(entity.getClass(), dc); } /** * Has children. * * @param entity the entity * @return the boolean */ public static <T extends ITreeEntity<T>> Boolean hasChildren(T entity) { log.trace("tree entity ??? . entity=[{}]", entity); DetachedCriteria dc = HibernateTool.createDetachedCriteria(entity.getClass()); dc.add(Restrictions.eq("parent", entity)); IHibernateDao dao = new HibernateDao(); return dao.exists(entity.getClass(), dc); } // endregion }