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 2010 Sun Microsystems, Inc.
015 * Portions copyright 2012-2016 ForgeRock AS.
016 */
017package org.forgerock.opendj.ldap.controls;
018
019import org.forgerock.opendj.ldap.ByteString;
020
021import org.forgerock.util.Reject;
022
023/**
024 * A generic control which can be used to represent arbitrary raw request and
025 * response controls.
026 */
027public final class GenericControl implements Control {
028
029    /**
030     * Creates a new control having the same OID, criticality, and value as the
031     * provided control.
032     *
033     * @param control
034     *            The control to be copied.
035     * @return The new control.
036     * @throws NullPointerException
037     *             If {@code control} was {@code null}.
038     */
039    public static GenericControl newControl(final Control control) {
040        Reject.ifNull(control);
041
042        if (control instanceof GenericControl) {
043            return (GenericControl) control;
044        }
045
046        return new GenericControl(control.getOID(), control.isCritical(), control.getValue());
047    }
048
049    /**
050     * Creates a new non-critical control having the provided OID and no value.
051     *
052     * @param oid
053     *            The numeric OID associated with this control.
054     * @return The new control.
055     * @throws NullPointerException
056     *             If {@code oid} was {@code null}.
057     */
058    public static GenericControl newControl(final String oid) {
059        return new GenericControl(oid, false, null);
060    }
061
062    /**
063     * Creates a new control having the provided OID and criticality, but no
064     * value.
065     *
066     * @param oid
067     *            The numeric OID associated with this control.
068     * @param isCritical
069     *            {@code true} if it is unacceptable to perform the operation
070     *            without applying the semantics of this control, or
071     *            {@code false} if it can be ignored.
072     * @return The new control.
073     * @throws NullPointerException
074     *             If {@code oid} was {@code null}.
075     */
076    public static GenericControl newControl(final String oid, final boolean isCritical) {
077        return new GenericControl(oid, isCritical, null);
078    }
079
080    /**
081     * Creates a new control having the provided OID, criticality, and value.
082     * <p>
083     * If {@code value} is not an instance of {@code ByteString} then it will be
084     * converted using the {@link ByteString#valueOfObject(Object)} method.
085     *
086     * @param oid
087     *            The numeric OID associated with this control.
088     * @param isCritical
089     *            {@code true} if it is unacceptable to perform the operation
090     *            without applying the semantics of this control, or
091     *            {@code false} if it can be ignored.
092     * @param value
093     *            The value associated with this control, or {@code null} if
094     *            there is no value. Its format is defined by the specification
095     *            of this control.
096     * @return The new control.
097     * @throws NullPointerException
098     *             If {@code oid} was {@code null}.
099     */
100    public static GenericControl newControl(final String oid, final boolean isCritical,
101            final Object value) {
102        return new GenericControl(oid, isCritical, (value == null) ? null : ByteString
103                .valueOfObject(value));
104    }
105
106    private final String oid;
107
108    private final boolean isCritical;
109
110    private final ByteString value;
111
112    /** Prevent direct instantiation. */
113    private GenericControl(final String oid, final boolean isCritical, final ByteString value) {
114        Reject.ifNull(oid);
115        this.oid = oid;
116        this.isCritical = isCritical;
117        this.value = value;
118    }
119
120    @Override
121    public String getOID() {
122        return oid;
123    }
124
125    @Override
126    public ByteString getValue() {
127        return value;
128    }
129
130    @Override
131    public boolean hasValue() {
132        return value != null;
133    }
134
135    @Override
136    public boolean isCritical() {
137        return isCritical;
138    }
139
140    @Override
141    public String toString() {
142        final StringBuilder builder = new StringBuilder();
143        builder.append("Control(oid=");
144        builder.append(getOID());
145        builder.append(", criticality=");
146        builder.append(isCritical());
147        if (value != null) {
148            builder.append(", value=");
149            builder.append(value.toHexPlusAsciiString(4));
150        }
151        builder.append(")");
152        return builder.toString();
153    }
154
155}