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.api.ldap.model.ldif;
021
022
023import java.io.Externalizable;
024import java.io.IOException;
025import java.io.ObjectInput;
026import java.io.ObjectOutput;
027
028import org.apache.directory.api.ldap.model.message.Control;
029import org.apache.directory.api.util.Strings;
030
031
032/**
033 * The LdifControl class stores a control defined for an entry found in a LDIF
034 * file.
035 *
036 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
037 */
038public class LdifControl implements Control, Externalizable
039{
040    /** The control type */
041    private String oid;
042
043    /** The criticality (default value is false) */
044    private boolean criticality = false;
045
046    /** Optional control value */
047    protected byte[] value;
048
049
050    /**
051     * Create a new Control
052     */
053    public LdifControl()
054    {
055    }
056
057
058    /**
059     * Create a new Control
060     * 
061     * @param oid OID of the created control
062     */
063    public LdifControl( String oid )
064    {
065        this.oid = oid;
066    }
067
068
069    /**
070     * {@inheritDoc}
071     */
072    @Override
073    public String toString()
074    {
075        return "LdifControl : {" + getOid() + ", " + isCritical() + ", " + Strings.dumpBytes( getValue() ) + "}";
076    }
077
078
079    /**
080     * {@inheritDoc}
081     */
082    @Override
083    public String getOid()
084    {
085        return oid;
086    }
087
088
089    /**
090     * {@inheritDoc}
091     */
092    @Override
093    public boolean isCritical()
094    {
095        return criticality;
096    }
097
098
099    /**
100     * {@inheritDoc}
101     */
102    @Override
103    public void setCritical( boolean criticality )
104    {
105        this.criticality = criticality;
106    }
107
108
109    /**
110     * Get back the control value
111     * 
112     * @return The control's value
113     */
114    public byte[] getValue()
115    {
116        return value;
117    }
118
119
120    /**
121     * Store the control value
122     * 
123     * @param value The value to store
124     */
125    public void setValue( byte[] value )
126    {
127        this.value = value;
128    }
129
130
131    /**
132     * @return <t>TRUE</t> if the control has a value
133     */
134    public boolean hasValue()
135    {
136        return value != null;
137    }
138
139
140    /**
141     * {@inheritDoc}
142     */
143    @Override
144    public void writeExternal( ObjectOutput out ) throws IOException
145    {
146        out.writeUTF( oid );
147        out.writeBoolean( criticality );
148
149        if ( hasValue() )
150        {
151            out.writeBoolean( true );
152            out.writeInt( value.length );
153
154            if ( value.length > 0 )
155            {
156                out.write( value );
157            }
158        }
159        else
160        {
161            out.writeBoolean( false );
162        }
163
164        out.flush();
165    }
166
167
168    /**
169     * {@inheritDoc}
170     */
171    @Override
172    public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException
173    {
174        oid = in.readUTF();
175        criticality = in.readBoolean();
176
177        if ( in.readBoolean() )
178        {
179            int valueLength = in.readInt();
180
181            if ( valueLength > 0 )
182            {
183                value = new byte[valueLength];
184                in.readFully( value );
185            }
186        }
187    }
188
189
190    /**
191     * @see Object#hashCode()
192     */
193    @Override
194    public int hashCode()
195    {
196        int h = 17;
197        h = h * 37 + ( criticality ? 1 : 0 );
198        h = h * 37 + ( oid == null ? 0 : oid.hashCode() );
199
200        if ( value != null )
201        {
202            for ( byte v : value )
203            {
204                h = h * 37 + v;
205            }
206        }
207
208        return h;
209    }
210
211
212    /**
213     * @see Object#equals(Object)
214     */
215    @Override
216    public boolean equals( Object o )
217    {
218        if ( o == this )
219        {
220            return true;
221        }
222
223        if ( o == null )
224        {
225            return false;
226        }
227
228        if ( !( o instanceof Control ) )
229        {
230            return false;
231        }
232
233        Control otherControl = ( Control ) o;
234
235        if ( !oid.equalsIgnoreCase( otherControl.getOid() ) )
236        {
237            return false;
238        }
239
240        return criticality == otherControl.isCritical();
241    }
242}