001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *  
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *  
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License. 
018 *  
019 */
020package org.apache.directory.shared.ldap.codec.api;
021
022
023import org.apache.directory.shared.asn1.AbstractAsn1Object;
024import org.apache.directory.shared.ldap.model.message.Control;
025
026
027/**
028 * Decorates Control objects by wrapping them, and enabling them as CodecControls
029 * so the codec to store transient information associated with the Control in the
030 * decorator while processing.
031 * 
032 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
033 * @param <E>
034 */
035public abstract class ControlDecorator<E extends Control> extends AbstractAsn1Object implements CodecControl<E>
036{
037    /** The decorated Control */
038    private E decorated;
039
040    /** The encoded value length */
041    protected int valueLength;
042
043    /** The encoded value of the control. */
044    protected byte[] value;
045    
046    /** The codec service responsible for encoding decoding this object */
047    private LdapApiService codec;
048
049    
050    /**
051     * Creates a ControlDecorator to codec enable it.
052     *
053     * @param decoratedControl The Control to decorate.
054     */
055    public ControlDecorator( LdapApiService codec, E decoratedControl )
056    {
057        this.decorated = decoratedControl;
058        this.codec = codec;
059    }
060
061
062    /**
063     * {@inheritDoc}
064     */
065    public E getDecorated()
066    {
067        return decorated;
068    }
069
070    
071    /**
072     * {@inheritDoc}
073     */
074    public void setDecorated( E decorated )
075    {
076        this.decorated = decorated;
077    }
078
079    
080    /**
081     * {@inheritDoc}
082     */
083    public LdapApiService getCodecService()
084    {
085        return codec;
086    }
087    
088
089    // ------------------------------------------------------------------------
090    // Control Methods
091    // ------------------------------------------------------------------------
092    
093    
094    /**
095     * Get the OID
096     * 
097     * @return A string which represent the control oid
098     */
099    public String getOid()
100    {
101        return decorated.getOid();
102    }
103
104
105    /**
106     * {@inheritDoc}
107     */
108    public boolean hasValue()
109    {
110        return value != null;
111    }
112
113
114    /**
115     * Get the control value
116     * 
117     * @return The control value
118     */
119    public byte[] getValue()
120    {
121        return value;
122    }
123
124
125    /**
126     * Set the encoded control value
127     * 
128     * @param value The encoded control value to store
129     */
130    public void setValue( byte[] value )
131    {
132        if ( value != null )
133        {
134            byte[] copy = new byte[ value.length ];
135            System.arraycopy( value, 0, copy, 0, value.length );
136            this.value = copy;
137        } 
138        else 
139        {
140            this.value = null;
141        }
142    }
143
144
145    /**
146     * Get the criticality
147     * 
148     * @return <code>true</code> if the criticality flag is true.
149     */
150    public boolean isCritical()
151    {
152        return decorated.isCritical();
153    }
154
155
156    /**
157     * Set the criticality
158     * 
159     * @param criticality The criticality value
160     */
161    public void setCritical( boolean criticality )
162    {
163        decorated.setCritical( criticality );
164    }
165
166    
167    // ------------------------------------------------------------------------
168    // CodecControl Methods
169    // ------------------------------------------------------------------------
170    
171    
172    /**
173     * {@inheritDoc}
174     */
175    public int computeLength()
176    {
177        return 0;
178    }
179
180
181    // ------------------------------------------------------------------------
182    // Object Method Overrides
183    // ------------------------------------------------------------------------
184    
185    
186    /**
187     * @see Object#hashCode()
188     */
189    public int hashCode()
190    {
191        return decorated.hashCode();
192    }
193
194    /**
195     * @see Object#equals(Object)
196     */
197    public boolean equals( Object o )
198    {
199        if ( decorated == null )
200        {
201            return o == null;
202        }
203        else
204        {
205            return decorated.equals( o );
206        }
207    }
208
209
210    /**
211     * Return a String representing a Control
212     */
213    public String toString()
214    {
215        return decorated.toString();
216    }
217}