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