/*
* 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.model.impl.lens.projector;
import javax.xml.namespace.QName;
import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.delta.PropertyDelta;
import com.evolveum.midpoint.prism.match.MatchingRule;
import com.evolveum.midpoint.prism.match.MatchingRuleRegistry;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
/**
* @author semancik
*
*/
public class ValueMatcher<T> {
private static final Trace LOGGER = TraceManager.getTrace(ValueMatcher.class);
MatchingRule<T> matchingRule;
public ValueMatcher(MatchingRule<T> matchingRule) {
this.matchingRule = matchingRule;
}
public static <T> ValueMatcher<T> createMatcher(RefinedAttributeDefinition rAttrDef, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException {
QName matchingRuleQName = rAttrDef.getMatchingRuleQName();
MatchingRule<T> matchingRule;
try {
matchingRule = matchingRuleRegistry.getMatchingRule(matchingRuleQName, rAttrDef.getTypeName());
} catch (SchemaException e) {
throw new SchemaException(e.getMessage()+", defined for attribute "+rAttrDef.getName(), e);
}
return new ValueMatcher<T>(matchingRule);
}
public static <T> ValueMatcher<T> createDefaultMatcher(QName type, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException {
MatchingRule<Object> matchingRule = matchingRuleRegistry.getMatchingRule(null, type);
return new ValueMatcher<T>((MatchingRule<T>) matchingRule);
}
public boolean match(T realA, T realB) throws SchemaException {
return matchingRule.match(realA, realB);
}
public boolean matches(T realValue, String regex) throws SchemaException{
return matchingRule.matchRegex(realValue, regex);
}
public boolean hasRealValue(PrismProperty<T> property, PrismPropertyValue<T> pValue) {
for (T existingRealValue: property.getRealValues()) {
try {
if (matchingRule.match(existingRealValue, pValue.getValue())) {
// LOGGER.trace("MATCH: {} ({}) <-> {} ({}) (rule: {})", new Object[]{
// existingRealValue, existingRealValue.getClass(), pValue.getValue(), pValue.getValue().getClass(), matchingRule});
return true;
}
// LOGGER.trace("NO match: {} ({}) <-> {} ({}) (rule: {})", new Object[]{
// existingRealValue, existingRealValue.getClass(), pValue.getValue(), pValue.getValue().getClass(), matchingRule});
} catch (SchemaException e) {
// At least one of the values is invalid. But we do not want to throw exception from
// a comparison operation. That will make the system very fragile. Let's fall back to
// ordinary equality mechanism instead.
if (existingRealValue.equals(pValue.getValue())) {
return true;
}
}
}
return false;
}
public boolean isRealValueToAdd(PropertyDelta<T> delta, PrismPropertyValue<T> pValue) {
if (delta.getValuesToAdd() == null){
return false;
}
for (PrismPropertyValue<T> existingPValue: delta.getValuesToAdd()) {
try {
if (matchingRule.match(existingPValue.getValue(), pValue.getValue())) {
// LOGGER.trace("MATCH: {} ({}) <-> {} ({}) (rule: {})", new Object[]{
// existingPValue.getValue(), existingPValue.getValue().getClass(), pValue.getValue(), pValue.getValue().getClass(), matchingRule});
return true;
}
// LOGGER.trace("NO match: {} ({}) <-> {} ({}) (rule: {})", new Object[]{
// existingPValue.getValue(), existingPValue.getValue().getClass(), pValue.getValue(), pValue.getValue().getClass(), matchingRule});
} catch (SchemaException e) {
// At least one of the values is invalid. But we do not want to throw exception from
// a comparison operation. That will make the system very fragile. Let's fall back to
// ordinary equality mechanism instead.
if (existingPValue.getValue().equals(pValue.getValue())) {
return true;
}
}
}
return false;
}
@Override
public String toString() {
return "ValueMatcher(" + matchingRule + ")";
}
}