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 */ 020 package org.apache.directory.shared.ldap.codec.controls; 021 022 023 import java.nio.BufferOverflowException; 024 import java.nio.ByteBuffer; 025 026 import org.apache.directory.shared.asn1.AbstractAsn1Object; 027 import org.apache.directory.shared.asn1.ber.tlv.TLV; 028 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; 029 import org.apache.directory.shared.asn1.ber.tlv.Value; 030 import org.apache.directory.shared.asn1.codec.EncoderException; 031 import org.apache.directory.shared.i18n.I18n; 032 import org.apache.directory.shared.ldap.message.control.Control; 033 import org.apache.directory.shared.ldap.util.StringTools; 034 035 036 /** 037 * A Asn1Object to store a Control. 038 * 039 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 040 * @version $Rev: 912399 $, $Date: 2010-02-21 21:52:31 +0100 (Sun, 21 Feb 2010) $, 041 */ 042 public abstract class AbstractControl extends AbstractAsn1Object implements Control, CodecControl 043 { 044 // ~ Instance fields 045 // ---------------------------------------------------------------------------- 046 /** The control type */ 047 private String oid; 048 049 /** The criticality (default value is false) */ 050 private boolean criticality = false; 051 052 /** Optional control value */ 053 protected byte[] value; 054 055 /** The encoded value length */ 056 protected int valueLength; 057 058 /** The control length */ 059 private int controlLength; 060 061 protected ControlDecoder decoder; 062 063 // ~ Methods 064 // ------------------------------------------------------------------------------------ 065 066 /** 067 * Default constructor. 068 */ 069 public AbstractControl( String oid ) 070 { 071 this.oid = oid; 072 } 073 074 /** 075 * Get the OID 076 * 077 * @return A string which represent the control oid 078 */ 079 public String getOid() 080 { 081 return oid == null ? "" : oid; 082 } 083 084 085 /** 086 * Get the control value 087 * 088 * @return The control value 089 */ 090 public byte[] getValue() 091 { 092 return value; 093 } 094 095 096 /** 097 * Set the encoded control value 098 * 099 * @param encodedValue The encoded control value to store 100 */ 101 public void setValue( byte[] value ) 102 { 103 if ( value != null ) 104 { 105 this.value = new byte[ value.length ]; 106 System.arraycopy( value, 0, this.value, 0, value.length ); 107 } 108 else 109 { 110 this.value = null; 111 } 112 } 113 114 115 /** 116 * Get the criticality 117 * 118 * @return <code>true</code> if the criticality flag is true. 119 */ 120 public boolean isCritical() 121 { 122 return criticality; 123 } 124 125 126 /** 127 * Set the criticality 128 * 129 * @param criticality The criticality value 130 */ 131 public void setCritical( boolean criticality ) 132 { 133 this.criticality = criticality; 134 } 135 136 137 /** 138 * {@inheritDoc} 139 */ 140 public int computeLength() 141 { 142 return 0; 143 } 144 145 146 /** 147 * {@inheritDoc} 148 */ 149 public int computeLength( int valueLength ) 150 { 151 // The OID 152 int oidLengh = StringTools.getBytesUtf8( oid ).length; 153 controlLength = 1 + TLV.getNbBytes( oidLengh ) + oidLengh; 154 155 // The criticality, only if true 156 if ( criticality ) 157 { 158 controlLength += 1 + 1 + 1; // Always 3 for a boolean 159 } 160 161 this.valueLength = valueLength; 162 163 if ( valueLength != 0 ) 164 { 165 controlLength += 1 + TLV.getNbBytes( valueLength ) + valueLength; 166 } 167 168 return 1 + TLV.getNbBytes( controlLength ) + controlLength; 169 } 170 171 172 /** 173 * {@inheritDoc} 174 */ 175 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 176 { 177 if ( buffer == null ) 178 { 179 throw new EncoderException( I18n.err( I18n.ERR_04023 ) ); 180 } 181 182 try 183 { 184 // The LdapMessage Sequence 185 buffer.put( UniversalTag.SEQUENCE_TAG ); 186 187 // The length has been calculated by the computeLength method 188 buffer.put( TLV.getBytes( controlLength ) ); 189 } 190 catch ( BufferOverflowException boe ) 191 { 192 throw new EncoderException( I18n.err( I18n.ERR_04005 ) ); 193 } 194 195 // The control type 196 Value.encode( buffer, getOid().getBytes() ); 197 198 // The control criticality, if true 199 if ( criticality ) 200 { 201 Value.encode( buffer, criticality ); 202 } 203 204 return buffer; 205 } 206 207 208 /** 209 * {@inheritDoc} 210 */ 211 public boolean hasValue() 212 { 213 return value != null; 214 } 215 216 217 public ControlDecoder getDecoder() 218 { 219 return decoder; 220 } 221 222 223 /** 224 * Return a String representing a Control 225 */ 226 public String toString() 227 { 228 StringBuffer sb = new StringBuffer(); 229 230 sb.append( " Control\n" ); 231 sb.append( " Control oid : '" ).append( oid ).append( 232 "'\n" ); 233 sb.append( " Criticality : '" ).append( criticality ).append( "'\n" ); 234 235 if ( value != null ) 236 { 237 sb.append( " Control value : '" ).append( StringTools.dumpBytes( value ) ) 238 .append( "'\n" ); 239 } 240 241 return sb.toString(); 242 } 243 }