package org.opennms.core.criteria; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.opennms.core.criteria.Alias.JoinType; import org.opennms.core.criteria.Fetch.FetchType; import org.opennms.core.criteria.restrictions.Restriction; import org.opennms.core.criteria.restrictions.Restrictions; import org.opennms.core.utils.LogUtils; public class CriteriaBuilder { private Class<?> m_class; private OrderBuilder m_orderBuilder = new OrderBuilder(); private Set<Fetch> m_fetch = new LinkedHashSet<Fetch>(); private AliasBuilder m_aliasBuilder = new AliasBuilder(); private boolean m_distinct = false; private Set<Restriction> m_restrictions = new LinkedHashSet<Restriction>(); private boolean m_negateNext = false; private Integer m_limit = null; private Integer m_offset = null; private String m_matchType = "all"; private static final Restriction[] EMPTY_RESTRICTION_ARRAY = new Restriction[0]; public CriteriaBuilder(final Class<?> clazz) { m_class = clazz; } public Criteria toCriteria() { final Criteria criteria = new Criteria(m_class); criteria.setOrders(m_orderBuilder.getOrderCollection()); criteria.setAliases(m_aliasBuilder.getAliasCollection()); criteria.setFetchTypes(m_fetch); criteria.setDistinct(m_distinct); criteria.setLimit(m_limit); criteria.setOffset(m_offset); if ("any".equals(m_matchType)) { criteria.setRestrictions(Collections.singleton(Restrictions.any(m_restrictions.toArray(EMPTY_RESTRICTION_ARRAY)))); } else { criteria.setRestrictions(m_restrictions); } return criteria; } public CriteriaBuilder match(final String type) { if ("all".equals(type) || "any".equals(type)) { m_matchType = type; } else { throw new IllegalArgumentException("match type must be 'all' or 'any'"); } return this; } public CriteriaBuilder fetch(final String attribute) { m_fetch.add(new Fetch(attribute)); return this; } public CriteriaBuilder fetch(final String attribute, final FetchType type) { m_fetch.add(new Fetch(attribute, type)); return this; } public CriteriaBuilder join(final String associationPath, final String alias) { return alias(associationPath, alias, JoinType.LEFT_JOIN); } public CriteriaBuilder alias(final String associationPath, final String alias) { return alias(associationPath, alias, JoinType.LEFT_JOIN); } public CriteriaBuilder join(final String associationPath, final String alias, final JoinType type) { return alias(associationPath, alias, type); } public CriteriaBuilder alias(final String associationPath, final String alias, final JoinType type) { m_aliasBuilder.alias(associationPath, alias, type); return this; } public CriteriaBuilder limit(final Integer limit) { m_limit = ((limit == null || limit == 0)? null : limit); return this; } public CriteriaBuilder offset(final Integer offset) { m_offset = ((offset == null || offset == 0)? null : offset); return this; } public CriteriaBuilder clearOrder() { m_orderBuilder.clear(); return this; } public CriteriaBuilder orderBy(final String attribute) { return orderBy(attribute, true); } public CriteriaBuilder orderBy(final String attribute, final boolean ascending) { m_orderBuilder.append(new Order(attribute, ascending)); return this; } public CriteriaBuilder asc() { m_orderBuilder.asc(); return this; } public CriteriaBuilder desc() { m_orderBuilder.desc(); return this; } public CriteriaBuilder distinct() { m_distinct = true; return this; } public CriteriaBuilder count() { m_orderBuilder.clear(); m_limit = null; m_offset = null; return this; } public CriteriaBuilder distinct(final boolean isDistinct) { m_distinct = isDistinct; return this; } private boolean addRestriction(final Restriction restriction) { if (m_negateNext) { m_negateNext = false; return m_restrictions.add(Restrictions.not(restriction)); } else { return m_restrictions.add(restriction); } } public CriteriaBuilder isNull(final String attribute) { addRestriction(Restrictions.isNull(attribute)); return this; } public CriteriaBuilder isNotNull(final String attribute) { addRestriction(Restrictions.isNotNull(attribute)); return this; } public CriteriaBuilder id(final Integer id) { addRestriction(Restrictions.id(id)); return this; } public CriteriaBuilder eq(final String attribute, final Object comparator) { addRestriction(Restrictions.eq(attribute, comparator)); return this; } public CriteriaBuilder ne(final String attribute, final Object comparator) { if (m_negateNext) { m_negateNext = false; addRestriction(Restrictions.eq(attribute, comparator)); } else { addRestriction(Restrictions.not(Restrictions.eq(attribute, comparator))); } return this; } public CriteriaBuilder gt(final String attribute, final Object comparator) { addRestriction(Restrictions.gt(attribute, comparator)); return this; } public CriteriaBuilder ge(final String attribute, final Object comparator) { addRestriction(Restrictions.ge(attribute, comparator)); return this; } public CriteriaBuilder lt(final String attribute, final Object comparator) { addRestriction(Restrictions.lt(attribute, comparator)); return this; } public CriteriaBuilder le(final String attribute, final Object comparator) { addRestriction(Restrictions.le(attribute, comparator)); return this; } public CriteriaBuilder like(final String attribute, final Object comparator) { addRestriction(Restrictions.like(attribute, comparator)); return this; } public CriteriaBuilder ilike(final String attribute, final Object comparator) { addRestriction(Restrictions.ilike(attribute, comparator)); return this; } public CriteriaBuilder iplike(final String attribute, final Object comparator) { addRestriction(Restrictions.iplike(attribute, comparator)); return this; } public CriteriaBuilder contains(final String attribute, final Object comparator) { addRestriction(Restrictions.ilike(attribute, "%" + comparator + "%")); return this; } public CriteriaBuilder in(final String attribute, final List<?> list) { addRestriction(Restrictions.in(attribute, list)); return this; } public CriteriaBuilder between(final String attribute, final Object begin, final Object end) { addRestriction(Restrictions.between(attribute, begin, end)); return this; } public CriteriaBuilder sql(final Object sql) { if (sql instanceof String) { addRestriction(Restrictions.sql((String)sql)); } else { LogUtils.warnf(this, "sql(): " + sql.getClass().getName() + " is not a string type, can't add"); } return this; } public CriteriaBuilder not() { m_negateNext = true; return this; } public CriteriaBuilder and(final Restriction lhs, final Restriction rhs) { addRestriction(Restrictions.and(lhs, rhs)); return this; } public CriteriaBuilder or(final Restriction lhs, final Restriction rhs) { final Restriction restriction = Restrictions.or(lhs, rhs); addRestriction(restriction); return this; } }