/* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2015-2016 ForgeRock AS. */ package org.opends.server.schema; import static org.opends.server.util.ServerConstants.*; import java.util.Arrays; import java.util.List; import java.util.Map; import org.forgerock.opendj.ldap.schema.AttributeType; import org.forgerock.opendj.ldap.schema.Schema; import org.forgerock.opendj.ldap.schema.SchemaBuilder; import org.opends.server.config.ConfigConstants; import org.opends.server.core.ServerContext; import org.opends.server.types.CommonSchemaElements; import org.opends.server.types.ObjectClass; import org.opends.server.types.SchemaFileElement; import org.opends.server.util.RemoveOnceSDKSchemaIsUsed; import org.opends.server.util.ServerConstants; /** * Represents a schema element which is either a SDK attribute type or an objectclass from the server. *

* In absence of a common interface, this class allows to process all elements in the same way, * and to provide useful server-oriented methods like {@code getSchemaFile()} or * {@code getOrigin()}. */ @RemoveOnceSDKSchemaIsUsed("This class is a temporary mechanism" + " to manage in the same way SDK and server schema element classes") public class SomeSchemaElement implements SchemaFileElement { private final ObjectClass objectClass; private AttributeType attributeType; /** * Builds SomeSchemaElement. * * @param objectClass * the common schema element to wrap */ public SomeSchemaElement(ObjectClass objectClass) { this.objectClass = objectClass; this.attributeType = null; } /** * Builds SomeSchemaElement. * * @param attributeType * the attribute type element to wrap */ public SomeSchemaElement(AttributeType attributeType) { this.objectClass = null; this.attributeType = attributeType; } /** * Returns the wrapped schema element as an object class. * * @return the wrapped object class */ public ObjectClass getObjectClass() { return objectClass; } /** * Returns the wrapped schema element as an attribute type. * * @return the wrapped attribute type */ public AttributeType getAttributeType() { return attributeType; } /** * Returns whether the wrapped element is an attribute type. * * @return {@code true} when the wrapped element is an attribute type, {@code false} otherwise */ public boolean isAttributeType() { return attributeType != null; } /** * Returns whether the wrapped element is an object class. * * @return {@code true} when the wrapped element is an object class, {@code false} otherwise */ public boolean isObjectClass() { return objectClass != null; } /** * Returns the OID of the wrapped element. * * @return the OID of the wrapped element. */ public String getOID() { return attributeType != null ? attributeType.getOID() : objectClass.getOID(); } /** * Returns the name or OID of the wrapped element. * * @return the name or OID of the wrapped element. */ public String getNameOrOID() { return attributeType != null ? attributeType.getNameOrOID() : objectClass.getNameOrOID(); } /** * Returns the names of the wrapped element. * * @return the names of the wrapped element. */ public Iterable getNames() { return attributeType != null ? attributeType.getNames() : objectClass.getNormalizedNames(); } @Override public Map> getExtraProperties() { return attributeType != null ? attributeType.getExtraProperties() : objectClass.getExtraProperties(); } @Override public String toString() { return attributeType != null ? attributeType.toString() : objectClass.toString(); } /** * Retrieves the definition string used to create this attribute * type and including the X-SCHEMA-FILE extension. * * @return The definition string used to create this attribute * type including the X-SCHEMA-FILE extension. */ public String getDefinitionWithFileName() { final String schemaFile = getSchemaFile(); final String definition = toString(); if (schemaFile != null) { int pos = definition.lastIndexOf(')'); return definition.substring(0, pos).trim() + " " + SCHEMA_PROPERTY_FILENAME + " '" + schemaFile + "' )"; } return definition; } /** * Returns the name of the schema file that contains the definition of the wrapped element. * * @return the name of the schema file that contains the definition of the wrapped element. */ public String getSchemaFile() { return getExtraPropertySingleValue(ServerConstants.SCHEMA_PROPERTY_FILENAME); } /** * Sets the name of the schema file that contains the definition of the wrapped element. * * @param serverContext * the server context * @param schemaFile * the name of the schema file that contains the definition of the wrapped element. */ public void setSchemaFile(ServerContext serverContext, String schemaFile) { setExtraPropertySingleValue(serverContext, SCHEMA_PROPERTY_FILENAME, schemaFile); } /** * Returns the origin of the provided schema element. * @return the origin of the provided schema element. */ public String getOrigin() { return getExtraPropertySingleValue(ServerConstants.SCHEMA_PROPERTY_ORIGIN); } private String getExtraPropertySingleValue(String schemaPropertyOrigin) { if (objectClass != null) { return CommonSchemaElements.getSingleValueProperty(objectClass, schemaPropertyOrigin); } List values = attributeType.getExtraProperties().get(schemaPropertyOrigin); return values != null && !values.isEmpty() ? values.get(0) : null; } /** * Returns the attribute name of the wrapped element. * @return the attribute name of the wrapped element. */ public String getAttributeName() { return attributeType!= null ? ConfigConstants.ATTR_ATTRIBUTE_TYPES : ConfigConstants.ATTR_OBJECTCLASSES; } /** * Sets a single-valued extra property on the wrapped element. * * @param serverContext * the server context * @param property * the property to set * @param value * the value to set */ public void setExtraPropertySingleValue(ServerContext serverContext, String property, String value) { if (attributeType != null) { List values = value != null ? Arrays.asList(value) : null; setExtraPropertyMultipleValues(serverContext, property, values); } else { CommonSchemaElements.setExtraProperty(objectClass, property, value); } } /** * Sets a multi-valued extra property on the wrapped element. * * @param serverContext * the server context * @param property * the property to set * @param values * the values to set */ public void setExtraPropertyMultipleValues(ServerContext serverContext, String property, List values) { if (attributeType != null) { SchemaBuilder schemaBuilder = serverContext != null ? new SchemaBuilder(serverContext.getSchemaNG()) : new SchemaBuilder(Schema.getDefaultSchema()); AttributeType.Builder builder = schemaBuilder.buildAttributeType(attributeType).removeExtraProperty(property, (String) null); if (values != null && !values.isEmpty()) { builder.extraProperties(property, values); } attributeType = builder.addToSchemaOverwrite().toSchema().getAttributeType(attributeType.getNameOrOID()); } else { objectClass.setExtraProperty(property, values); } } /** * Returns a copy of the provided attribute type, changing the superior attribute type. * * @param attributeType * the attribute type for which a modified copy must be built * @param newSuperiorType * the new superior attribute type to set, {@code null} means remove the superior type * @return an attribute type builder to build an updated copy of the provided attribute type */ public static AttributeType changeSuperiorType(AttributeType attributeType, AttributeType newSuperiorType) { String superiorTypeOID = newSuperiorType != null ? newSuperiorType.getNameOrOID() : null; Schema schema = new SchemaBuilder() .buildAttributeType(attributeType) .superiorType(superiorTypeOID) .addToSchemaOverwrite() .toSchema(); return schema.getAttributeType(attributeType.getNameOrOID()); } }