001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008 Sun Microsystems, Inc.
015 * Portions Copyright 2016 ForgeRock AS.
016 */
017
018package org.forgerock.opendj.config;
019
020import org.forgerock.util.Reject;
021
022import java.util.EnumSet;
023
024import org.forgerock.opendj.ldap.DN;
025
026/** DN property definition. */
027public final class DNPropertyDefinition extends PropertyDefinition<DN> {
028
029    /** Optional base DN which all valid values must be immediately subordinate to. */
030    private final DN baseDN;
031
032    /** An interface for incrementally constructing DN property definitions. */
033    public static final class Builder extends AbstractBuilder<DN, DNPropertyDefinition> {
034
035        /** Optional base DN which all valid values must be immediately subordinate to. */
036        private DN baseDN;
037
038        /** Private constructor. */
039        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
040            super(d, propertyName);
041        }
042
043        /**
044         * Set the base DN which all valid values must be immediately
045         * subordinate to. By default there is no based DN.
046         *
047         * @param baseDN
048         *            The string representation of the base DN.
049         * @throws IllegalArgumentException
050         *             If the provided string is not a valid DN string
051         *             representation.
052         */
053        public void setBaseDN(String baseDN) {
054            setBaseDN(baseDN != null ? DN.valueOf(baseDN) : null);
055        }
056
057        /**
058         * Set the base DN which all valid values must be immediately
059         * subordinate to. By default there is no based DN.
060         *
061         * @param baseDN
062         *            The base DN.
063         */
064        public void setBaseDN(DN baseDN) {
065            this.baseDN = baseDN;
066        }
067
068        @Override
069        protected DNPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
070            EnumSet<PropertyOption> options, AdministratorAction adminAction,
071            DefaultBehaviorProvider<DN> defaultBehavior) {
072            return new DNPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, baseDN);
073        }
074    }
075
076    /**
077     * Create a DN property definition builder.
078     *
079     * @param d
080     *            The managed object definition associated with this property
081     *            definition.
082     * @param propertyName
083     *            The property name.
084     * @return Returns the new boolean property definition builder.
085     */
086    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
087        return new Builder(d, propertyName);
088    }
089
090    /** Private constructor. */
091    private DNPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
092        EnumSet<PropertyOption> options, AdministratorAction adminAction,
093        DefaultBehaviorProvider<DN> defaultBehavior, DN baseDN) {
094        super(d, DN.class, propertyName, options, adminAction, defaultBehavior);
095        this.baseDN = baseDN;
096    }
097
098    /**
099     * Get the base DN which all valid values must be immediately subordinate
100     * to, or <code>null</code> if there is no based DN.
101     *
102     * @return Returns the base DN which all valid values must be immediately
103     *         subordinate to.
104     */
105    public DN getBaseDN() {
106        return baseDN;
107    }
108
109    @Override
110    public void validateValue(DN value) {
111        Reject.ifNull(value);
112
113        if (baseDN != null) {
114            DN parent = value.parent();
115
116            if (parent == null) {
117                parent = DN.rootDN();
118            }
119
120            if (!parent.equals(baseDN)) {
121                throw PropertyException.illegalPropertyValueException(this, value);
122            }
123        }
124    }
125
126    @Override
127    public DN decodeValue(String value) {
128        Reject.ifNull(value);
129
130        try {
131            DN dn = DN.valueOf(value);
132            validateValue(dn);
133            return dn;
134        } catch (PropertyException e) {
135            throw PropertyException.illegalPropertyValueException(this, value);
136        }
137    }
138
139    @Override
140    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
141        return v.visitDN(this, p);
142    }
143
144    @Override
145    public <R, P> R accept(PropertyValueVisitor<R, P> v, DN value, P p) {
146        return v.visitDN(this, value, p);
147    }
148
149    @Override
150    public int compare(DN o1, DN o2) {
151        return o1.compareTo(o2);
152    }
153}