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 2009 Sun Microsystems, Inc.
025 *      Portions copyright 2011-2012 ForgeRock AS
026 */
027
028package org.forgerock.opendj.ldap;
029
030import org.forgerock.opendj.ldap.schema.Schema;
031
032import org.forgerock.util.Reject;
033
034/**
035 * Decode options allow applications to control how requests and responses are
036 * decoded. In particular:
037 * <ul>
038 * <li>The strategy for selecting which {@code Schema} should be used for
039 * decoding distinguished names, attribute descriptions, and other objects which
040 * require a schema in order to be decoded.
041 * <li>The {@code Attribute} implementation which should be used when decoding
042 * attributes.
043 * <li>The {@code Entry} implementation which should be used when decoding
044 * entries or entry like objects.
045 * </ul>
046 */
047public final class DecodeOptions {
048    private static final class FixedSchemaResolver implements SchemaResolver {
049        private final Schema schema;
050
051        private FixedSchemaResolver(final Schema schema) {
052            this.schema = schema;
053        }
054
055        /** {@inheritDoc} */
056        public Schema resolveSchema(final String dn) {
057            return schema;
058        }
059
060    }
061
062    private SchemaResolver schemaResolver;
063
064    private EntryFactory entryFactory;
065
066    private AttributeFactory attributeFactory;
067
068    /**
069     * Creates a new set of decode options which will always use the default
070     * schema returned by {@link Schema#getDefaultSchema()},
071     * {@link LinkedAttribute}, and {@link LinkedHashMapEntry}.
072     */
073    public DecodeOptions() {
074        this.attributeFactory = LinkedAttribute.FACTORY;
075        this.entryFactory = LinkedHashMapEntry.FACTORY;
076        this.schemaResolver = SchemaResolver.DEFAULT;
077    }
078
079    /**
080     * Creates a new set of decode options having the same initial set of
081     * options as the provided set of decode options.
082     *
083     * @param options
084     *            The set of decode options to be copied.
085     */
086    public DecodeOptions(final DecodeOptions options) {
087        this.attributeFactory = options.attributeFactory;
088        this.entryFactory = options.entryFactory;
089        this.schemaResolver = options.schemaResolver;
090    }
091
092    /**
093     * Returns the {@code AttributeFactory} which will be used for creating new
094     * {@code Attribute} instances when decoding attributes.
095     *
096     * @return The {@code AttributeFactory} which will be used for creating new
097     *         {@code Attribute} instances when decoding attributes.
098     */
099    public final AttributeFactory getAttributeFactory() {
100        return attributeFactory;
101    }
102
103    /**
104     * Returns the {@code EntryFactory} which will be used for creating new
105     * {@code Entry} instances when decoding entries.
106     *
107     * @return The {@code EntryFactory} which will be used for creating new
108     *         {@code Entry} instances when decoding entries.
109     */
110    public final EntryFactory getEntryFactory() {
111        return entryFactory;
112    }
113
114    /**
115     * Returns the strategy for selecting which {@code Schema} should be used
116     * for decoding distinguished names, attribute descriptions, and other
117     * objects which require a {@code Schema} in order to be decoded.
118     *
119     * @return The schema resolver which will be used for decoding.
120     */
121    public final SchemaResolver getSchemaResolver() {
122        return schemaResolver;
123    }
124
125    /**
126     * Sets the {@code AttributeFactory} which will be used for creating new
127     * {@code Attribute} instances when decoding attributes.
128     *
129     * @param factory
130     *            The {@code AttributeFactory} which will be used for creating
131     *            new {@code Attribute} instances when decoding attributes.
132     * @return A reference to this set of decode options.
133     * @throws NullPointerException
134     *             If {@code factory} was {@code null}.
135     */
136    public final DecodeOptions setAttributeFactory(final AttributeFactory factory) {
137        Reject.ifNull(factory);
138        this.attributeFactory = factory;
139        return this;
140    }
141
142    /**
143     * Sets the {@code EntryFactory} which will be used for creating new
144     * {@code Entry} instances when decoding entries.
145     *
146     * @param factory
147     *            The {@code EntryFactory} which will be used for creating new
148     *            {@code Entry} instances when decoding entries.
149     * @return A reference to this set of decode options.
150     * @throws NullPointerException
151     *             If {@code factory} was {@code null}.
152     */
153    public final DecodeOptions setEntryFactory(final EntryFactory factory) {
154        Reject.ifNull(factory);
155        this.entryFactory = factory;
156        return this;
157    }
158
159    /**
160     * Sets the {@code Schema} which will be used for decoding distinguished
161     * names, attribute descriptions, and other objects which require a schema
162     * in order to be decoded. This setting overrides the currently active
163     * schema resolver set using {@link #setSchemaResolver}.
164     *
165     * @param schema
166     *            The {@code Schema} which will be used for decoding.
167     * @return A reference to this set of decode options.
168     * @throws NullPointerException
169     *             If {@code schema} was {@code null}.
170     */
171    public final DecodeOptions setSchema(final Schema schema) {
172        Reject.ifNull(schema);
173        this.schemaResolver = new FixedSchemaResolver(schema);
174        return this;
175    }
176
177    /**
178     * Sets the strategy for selecting which {@code Schema} should be used for
179     * decoding distinguished names, attribute descriptions, and other objects
180     * which require a {@code Schema} in order to be decoded. This setting
181     * overrides the currently active schema set using {@link #setSchema}.
182     *
183     * @param resolver
184     *            The {@code SchemaResolver} which will be used for decoding.
185     * @return A reference to this set of decode options.
186     * @throws NullPointerException
187     *             If {@code resolver} was {@code null}.
188     */
189    public final DecodeOptions setSchemaResolver(final SchemaResolver resolver) {
190        Reject.ifNull(resolver);
191        this.schemaResolver = resolver;
192        return this;
193    }
194}