/* * Copyright (c) 2010-2016 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.prism; import java.util.Collection; import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.util.DisplayableValue; import org.jetbrains.annotations.NotNull; /** * Property Definition. * <p/> * Property is a basic unit of information in midPoint. This class provides * definition of property type, multiplicity and so on. * <p/> * Property is a specific characteristic of an object. It may be considered * object "attribute" or "field". For example User has fullName property that * contains string value of user's full name. * <p/> * Properties may be single-valued or multi-valued * <p/> * Properties may contain primitive types or complex types (defined by XSD * schema) * <p/> * Property values are unordered, implementation may change the order of values * <p/> * Duplicate values of properties should be silently removed by implementations, * but clients must be able tolerate presence of duplicate values. * <p/> * Operations that modify the objects work with the granularity of properties. * They add/remove/replace the values of properties, but do not "see" inside the * property. * <p/> * This class represents schema definition for property. See {@link Definition} * for more details. * * @author Radovan Semancik */ public class PrismPropertyDefinitionImpl<T> extends ItemDefinitionImpl<PrismProperty<T>> implements PrismPropertyDefinition<T> { private static final long serialVersionUID = 7259761997904371009L; private QName valueType; private Collection<? extends DisplayableValue<T>> allowedValues; private Boolean indexed = null; private T defaultValue; private QName matchingRuleQName = null; public PrismPropertyDefinitionImpl(QName elementName, QName typeName, PrismContext prismContext) { super(elementName, typeName, prismContext); } public PrismPropertyDefinitionImpl(QName elementName, QName typeName, PrismContext prismContext, Collection<? extends DisplayableValue<T>> allowedValues, T defaultValue) { super(elementName, typeName, prismContext); this.allowedValues = allowedValues; this.defaultValue = defaultValue; } /** * Returns allowed values for this property. * * @return Object array. May be null. */ @Override public Collection<? extends DisplayableValue<T>> getAllowedValues() { return allowedValues; } @Override public T defaultValue(){ return defaultValue; } @Override public QName getValueType() { return valueType; } /** * This is XSD annotation that specifies whether a property should * be indexed in the storage. It can only apply to properties. It * has following meaning: * * true: the property must be indexed. If the storage is not able to * index the value, it should indicate an error. * * false: the property should not be indexed. * * null: data store decides whether to index the property or * not. */ @Override public Boolean isIndexed() { return indexed; } public void setIndexed(Boolean indexed) { this.indexed = indexed; } /** * Returns matching rule name. Matching rules are algorithms that specify * how to compare, normalize and/or order the values. E.g. there are matching * rules for case insensitive string comparison, for LDAP DNs, etc. * * @return matching rule name */ @Override public QName getMatchingRuleQName() { return matchingRuleQName; } public void setMatchingRuleQName(QName matchingRuleQName) { this.matchingRuleQName = matchingRuleQName; } @NotNull @Override public PrismProperty<T> instantiate() { return instantiate(getName()); } @NotNull @Override public PrismProperty<T> instantiate(QName name) { name = addNamespaceIfApplicable(name); return new PrismProperty<>(name, this, prismContext); } @Override public PropertyDelta<T> createEmptyDelta(ItemPath path) { return new PropertyDelta<T>(path, this, prismContext); } @NotNull @Override public PrismPropertyDefinition<T> clone() { PrismPropertyDefinitionImpl<T> clone = new PrismPropertyDefinitionImpl<T>(getName(), getTypeName(), getPrismContext()); copyDefinitionData(clone); return clone; } protected void copyDefinitionData(PrismPropertyDefinitionImpl<T> clone) { super.copyDefinitionData(clone); clone.indexed = this.indexed; clone.defaultValue = this.defaultValue; clone.allowedValues = this.allowedValues; clone.valueType = this.valueType; } @Override protected void extendToString(StringBuilder sb) { super.extendToString(sb); if (indexed != null && indexed) { sb.append(",I"); } if (allowedValues != null && !allowedValues.isEmpty()) { sb.append(",AVals:").append(allowedValues.size()); } } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((allowedValues == null) ? 0 : allowedValues.hashCode()); result = prime * result + ((defaultValue == null) ? 0 : defaultValue.hashCode()); result = prime * result + ((indexed == null) ? 0 : indexed.hashCode()); result = prime * result + ((valueType == null) ? 0 : valueType.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; PrismPropertyDefinitionImpl other = (PrismPropertyDefinitionImpl) obj; if (allowedValues == null) { if (other.allowedValues != null) return false; } else if (!allowedValues.equals(other.allowedValues)) return false; if (defaultValue == null) { if (other.defaultValue != null) return false; } else if (!defaultValue.equals(other.defaultValue)) return false; if (indexed == null) { if (other.indexed != null) return false; } else if (!indexed.equals(other.indexed)) return false; if (valueType == null) { if (other.valueType != null) return false; } else if (!valueType.equals(other.valueType)) return false; return true; } /** * Return a human readable name of this class suitable for logs. */ @Override protected String getDebugDumpClassName() { return "PPD"; } @Override public String getDocClassName() { return "property"; } }