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 */
016
017package org.forgerock.opendj.config;
018
019import org.forgerock.util.Reject;
020
021import java.util.EnumSet;
022
023import org.forgerock.opendj.ldap.DN;
024
025/**
026 * DN property definition.
027 */
028public final class DNPropertyDefinition extends PropertyDefinition<DN> {
029
030    /**
031     * Optional base DN which all valid values must be immediately
032     * subordinate to.
033     */
034    private final DN baseDN;
035
036    /** An interface for incrementally constructing DN property definitions. */
037    public static final class Builder extends AbstractBuilder<DN, DNPropertyDefinition> {
038
039        /**
040         * Optional base DN which all valid values must be immediately
041         * subordinate to.
042         */
043        private DN baseDN;
044
045        /** Private constructor. */
046        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
047            super(d, propertyName);
048        }
049
050        /**
051         * Set the base DN which all valid values must be immediately
052         * subordinate to. By default there is no based DN.
053         *
054         * @param baseDN
055         *            The string representation of the base DN.
056         * @throws IllegalArgumentException
057         *             If the provided string is not a valid DN string
058         *             representation.
059         */
060        public void setBaseDN(String baseDN) {
061            setBaseDN(baseDN != null ? DN.valueOf(baseDN) : null);
062        }
063
064        /**
065         * Set the base DN which all valid values must be immediately
066         * subordinate to. By default there is no based DN.
067         *
068         * @param baseDN
069         *            The base DN.
070         */
071        public void setBaseDN(DN baseDN) {
072            this.baseDN = baseDN;
073        }
074
075        /** {@inheritDoc} */
076        @Override
077        protected DNPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
078            EnumSet<PropertyOption> options, AdministratorAction adminAction,
079            DefaultBehaviorProvider<DN> defaultBehavior) {
080            return new DNPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, baseDN);
081        }
082    }
083
084    /**
085     * Create a DN property definition builder.
086     *
087     * @param d
088     *            The managed object definition associated with this property
089     *            definition.
090     * @param propertyName
091     *            The property name.
092     * @return Returns the new boolean property definition builder.
093     */
094    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
095        return new Builder(d, propertyName);
096    }
097
098    /** Private constructor. */
099    private DNPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
100        EnumSet<PropertyOption> options, AdministratorAction adminAction,
101        DefaultBehaviorProvider<DN> defaultBehavior, DN baseDN) {
102        super(d, DN.class, propertyName, options, adminAction, defaultBehavior);
103        this.baseDN = baseDN;
104    }
105
106    /**
107     * Get the base DN which all valid values must be immediately subordinate
108     * to, or <code>null</code> if there is no based DN.
109     *
110     * @return Returns the base DN which all valid values must be immediately
111     *         subordinate to.
112     */
113    public DN getBaseDN() {
114        return baseDN;
115    }
116
117    /** {@inheritDoc} */
118    @Override
119    public void validateValue(DN value) {
120        Reject.ifNull(value);
121
122        if (baseDN != null) {
123            DN parent = value.parent();
124
125            if (parent == null) {
126                parent = DN.rootDN();
127            }
128
129            if (!parent.equals(baseDN)) {
130                throw PropertyException.illegalPropertyValueException(this, value);
131            }
132        }
133    }
134
135    /** {@inheritDoc} */
136    @Override
137    public DN decodeValue(String value) {
138        Reject.ifNull(value);
139
140        try {
141            DN dn = DN.valueOf(value);
142            validateValue(dn);
143            return dn;
144        } catch (PropertyException e) {
145            throw PropertyException.illegalPropertyValueException(this, value);
146        }
147    }
148
149    /** {@inheritDoc} */
150    @Override
151    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
152        return v.visitDN(this, p);
153    }
154
155    /** {@inheritDoc} */
156    @Override
157    public <R, P> R accept(PropertyValueVisitor<R, P> v, DN value, P p) {
158        return v.visitDN(this, value, p);
159    }
160
161    /** {@inheritDoc} */
162    @Override
163    public int compare(DN o1, DN o2) {
164        return o1.compareTo(o2);
165    }
166}