/*
* 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.schema.processor;
import com.evolveum.midpoint.prism.ComplexTypeDefinitionImpl;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType;
import org.jetbrains.annotations.NotNull;
import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.stream.Collectors;
/**
* @author semancik
*
*/
public class ObjectClassComplexTypeDefinitionImpl extends ComplexTypeDefinitionImpl implements ObjectClassComplexTypeDefinition {
private static final long serialVersionUID = 1L;
@NotNull private final Collection<ResourceAttributeDefinition<?>> identifiers = new ArrayList<>(1);
@NotNull private final Collection<ResourceAttributeDefinition<?>> secondaryIdentifiers = new ArrayList<>(1);
private ResourceAttributeDefinition descriptionAttribute;
private ResourceAttributeDefinition displayNameAttribute;
private ResourceAttributeDefinition namingAttribute;
private boolean defaultInAKind = false;
private ShadowKindType kind;
private String intent;
private String nativeObjectClass;
private boolean auxiliary;
public ObjectClassComplexTypeDefinitionImpl(QName typeName, PrismContext prismContext) {
super(typeName, prismContext);
}
@NotNull
@Override
public Collection<? extends ResourceAttributeDefinition<?>> getAttributeDefinitions() {
return Collections.unmodifiableList(
getDefinitions().stream()
.map(def -> (ResourceAttributeDefinition<?>) def)
.collect(Collectors.toList()));
}
@Override
public void add(ItemDefinition<?> definition) {
if (ResourceAttributeDefinition.class.isAssignableFrom(definition.getClass())) {
super.add(definition);
} else {
throw new IllegalArgumentException("Only ResourceAttributeDefinitions should be put into"
+ " a ObjectClassComplexTypeDefinition. Item definition = " + definition + ","
+ " ObjectClassComplexTypeDefinition = " + this);
}
}
@NotNull
@Override
public Collection<? extends ResourceAttributeDefinition<?>> getPrimaryIdentifiers() {
return identifiers;
}
public void addPrimaryIdentifier(ResourceAttributeDefinition<?> identifier) {
identifiers.add(identifier);
}
@NotNull
@Override
public Collection<? extends ResourceAttributeDefinition<?>> getSecondaryIdentifiers() {
return secondaryIdentifiers;
}
public void addSecondaryIdentifier(ResourceAttributeDefinition<?> identifier) {
secondaryIdentifiers.add(identifier);
}
@Override
public <X> ResourceAttributeDefinition<X> getDescriptionAttribute() {
return descriptionAttribute;
}
void setDescriptionAttribute(ResourceAttributeDefinition<?> descriptionAttribute) {
this.descriptionAttribute = descriptionAttribute;
}
@Override
public <X> ResourceAttributeDefinition<X> getNamingAttribute() {
return namingAttribute;
}
public void setNamingAttribute(ResourceAttributeDefinition<?> namingAttribute) {
this.namingAttribute = namingAttribute;
}
public void setNamingAttribute(QName namingAttribute) {
setNamingAttribute(findAttributeDefinition(namingAttribute));
}
@Override
public String getNativeObjectClass() {
return nativeObjectClass;
}
public void setNativeObjectClass(String nativeObjectClass) {
this.nativeObjectClass = nativeObjectClass;
}
@Override
public boolean isAuxiliary() {
return auxiliary;
}
public void setAuxiliary(boolean auxiliary) {
this.auxiliary = auxiliary;
}
@Override
public ShadowKindType getKind() {
return kind;
}
public void setKind(ShadowKindType kind) {
this.kind = kind;
}
@Override
public boolean isDefaultInAKind() {
return defaultInAKind;
}
public void setDefaultInAKind(boolean defaultAccountType) {
this.defaultInAKind = defaultAccountType;
}
@Override
public String getIntent() {
return intent;
}
public void setIntent(String intent) {
this.intent = intent;
}
@Override
public ResourceAttributeDefinition<?> getDisplayNameAttribute() {
return displayNameAttribute;
}
public void setDisplayNameAttribute(ResourceAttributeDefinition<?> displayName) {
this.displayNameAttribute = displayName;
}
/**
* TODO
*
* Convenience method. It will internally look up the correct definition.
*/
public void setDisplayNameAttribute(QName displayName) {
setDisplayNameAttribute(findAttributeDefinition(displayName));
}
public <X> ResourceAttributeDefinitionImpl<X> createAttributeDefinition(QName name, QName typeName) {
ResourceAttributeDefinitionImpl<X> propDef = new ResourceAttributeDefinitionImpl<>(name, typeName, prismContext);
add(propDef);
return propDef;
}
public <X> ResourceAttributeDefinitionImpl<X> createAttributeDefinition(String localName, QName typeName) {
QName name = new QName(getSchemaNamespace(),localName);
return createAttributeDefinition(name,typeName);
}
public <X> ResourceAttributeDefinition<X> createAttributeDefinition(String localName, String localTypeName) {
QName name = new QName(getSchemaNamespace(),localName);
QName typeName = new QName(getSchemaNamespace(),localTypeName);
return createAttributeDefinition(name,typeName);
}
/**
* This may not be really "clean" as it actually does two steps instead of one. But it is useful.
*/
@Override
public ResourceAttributeContainer instantiate(QName elementName) {
return instantiate(elementName, this);
}
public static ResourceAttributeContainer instantiate(QName elementName, ObjectClassComplexTypeDefinition ocdef) {
ResourceAttributeContainerDefinition racDef = ocdef.toResourceAttributeContainerDefinition(elementName);
return new ResourceAttributeContainer(elementName, racDef, ocdef.getPrismContext());
}
@NotNull
@Override
public ObjectClassComplexTypeDefinitionImpl clone() {
ObjectClassComplexTypeDefinitionImpl clone = new ObjectClassComplexTypeDefinitionImpl(
getTypeName(), prismContext);
copyDefinitionData(clone);
return clone;
}
protected void copyDefinitionData(ObjectClassComplexTypeDefinitionImpl clone) {
super.copyDefinitionData(clone);
clone.kind = this.kind;
clone.intent = this.intent;
clone.defaultInAKind = this.defaultInAKind;
clone.descriptionAttribute = this.descriptionAttribute;
clone.displayNameAttribute = this.displayNameAttribute;
clone.identifiers.addAll(this.identifiers);
clone.namingAttribute = this.namingAttribute;
clone.nativeObjectClass = this.nativeObjectClass;
clone.secondaryIdentifiers.addAll(this.secondaryIdentifiers);
clone.auxiliary = this.auxiliary;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + (auxiliary ? 1231 : 1237);
result = prime * result + (defaultInAKind ? 1231 : 1237);
result = prime * result + ((descriptionAttribute == null) ? 0 : descriptionAttribute.hashCode());
result = prime * result + ((displayNameAttribute == null) ? 0 : displayNameAttribute.hashCode());
result = prime * result + identifiers.hashCode();
result = prime * result + ((intent == null) ? 0 : intent.hashCode());
result = prime * result + ((kind == null) ? 0 : kind.hashCode());
result = prime * result + ((namingAttribute == null) ? 0 : namingAttribute.hashCode());
result = prime * result + ((nativeObjectClass == null) ? 0 : nativeObjectClass.hashCode());
result = prime * result + secondaryIdentifiers.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;
}
ObjectClassComplexTypeDefinitionImpl other = (ObjectClassComplexTypeDefinitionImpl) obj;
if (auxiliary != other.auxiliary) {
return false;
}
if (defaultInAKind != other.defaultInAKind) {
return false;
}
if (descriptionAttribute == null) {
if (other.descriptionAttribute != null) {
return false;
}
} else if (!descriptionAttribute.equals(other.descriptionAttribute)) {
return false;
}
if (displayNameAttribute == null) {
if (other.displayNameAttribute != null) {
return false;
}
} else if (!displayNameAttribute.equals(other.displayNameAttribute)) {
return false;
}
if (!identifiers.equals(other.identifiers)) {
return false;
}
if (intent == null) {
if (other.intent != null) {
return false;
}
} else if (!intent.equals(other.intent)) {
return false;
}
if (kind != other.kind) {
return false;
}
if (namingAttribute == null) {
if (other.namingAttribute != null) {
return false;
}
} else if (!namingAttribute.equals(other.namingAttribute)) {
return false;
}
if (nativeObjectClass == null) {
if (other.nativeObjectClass != null) {
return false;
}
} else if (!nativeObjectClass.equals(other.nativeObjectClass)) {
return false;
}
if (!secondaryIdentifiers.equals(other.secondaryIdentifiers)) {
return false;
}
return true;
}
@Override
protected String getDebugDumpClassName() {
return "OCD";
}
@Override
protected void extendDumpHeader(StringBuilder sb) {
super.extendDumpHeader(sb);
if (defaultInAKind) {
sb.append(" def");
}
if (auxiliary) {
sb.append(" aux");
}
if (kind != null) {
sb.append(" ").append(kind.value());
}
if (intent != null) {
sb.append(" intent=").append(intent);
}
}
@Override
protected void extendDumpDefinition(StringBuilder sb, ItemDefinition<?> def) {
super.extendDumpDefinition(sb, def);
if (getPrimaryIdentifiers().contains(def)) {
sb.append(",primID");
}
if (getSecondaryIdentifiers().contains(def)) {
sb.append(",secID");
}
}
}