/* * Copyright (c) 2010-2015 Evolveum * * 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.evolveum.midpoint.repo.sql.query2.matcher; import com.evolveum.midpoint.repo.sql.query.QueryException; import com.evolveum.midpoint.repo.sql.query2.hqm.RootHibernateQuery; import com.evolveum.midpoint.repo.sql.query2.hqm.condition.Condition; import com.evolveum.midpoint.repo.sql.query2.restriction.ItemRestrictionOperation; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import org.apache.commons.lang.Validate; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.MatchMode; import javax.xml.namespace.QName; import java.util.List; import java.util.Map; /** * @author lazyman */ public abstract class Matcher<T> { private static final Trace LOGGER = TraceManager.getTrace(Matcher.class); /** * Create hibernate {@link Criterion} based on matcher defined in filter. * * * @param hibernateQuery * @param operation * @param propertyPath * @param value * @param matcher Now type of {@link String}, but will be updated to {@link javax.xml.namespace.QName} * type after query-api update * @return * @throws QueryException */ public abstract Condition match(RootHibernateQuery hibernateQuery, ItemRestrictionOperation operation, String propertyPath, T value, String matcher) throws QueryException; protected Condition basicMatch(RootHibernateQuery hibernateQuery, ItemRestrictionOperation operation, String propertyPath, Object value, boolean ignoreCase) throws QueryException { Validate.notNull(hibernateQuery, "hibernateQuery"); if (ignoreCase && !(value instanceof String)) { LOGGER.warn("Ignoring ignoreCase setting for non-string value of {}", value); ignoreCase = false; } Condition condition; switch (operation) { case EQ: if (value == null) { condition = hibernateQuery.createIsNull(propertyPath); } else { condition = hibernateQuery.createEq(propertyPath, value, ignoreCase); } break; case GT: case GE: case LT: case LE: condition = hibernateQuery.createSimpleComparisonCondition(propertyPath, value, operation.symbol(), ignoreCase); break; case NOT_NULL: condition = hibernateQuery.createIsNotNull(propertyPath); break; case NULL: condition = hibernateQuery.createIsNull(propertyPath); break; case STARTS_WITH: condition = hibernateQuery.createLike(propertyPath, (String) value, MatchMode.START, ignoreCase); break; case ENDS_WITH: condition = hibernateQuery.createLike(propertyPath, (String) value, MatchMode.END, ignoreCase); break; case SUBSTRING: condition = hibernateQuery.createLike(propertyPath, (String) value, MatchMode.ANYWHERE, ignoreCase); break; default: throw new QueryException("Unknown operation '" + operation + "'."); } return condition; } static QName getApproximateSupportedMatchingRule(QName originalMatchingRule, List<QName> supportedMatchingRules, Map<QName, QName> matchingRulesConvergenceMap) { if (originalMatchingRule == null || supportedMatchingRules.contains(originalMatchingRule)) { return originalMatchingRule; } return matchingRulesConvergenceMap.entrySet().stream() .filter(entry -> QNameUtil.match(entry.getKey(), originalMatchingRule)) .map(Map.Entry::getValue) .findFirst() // if nothing applicable we return the original one - query interpreter will take care of it // (logging error or throwing an exception) ... TODO rethink this .orElse(originalMatchingRule); } }