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.codec.controls.proxiedauthz;
021
022
023import java.nio.ByteBuffer;
024
025import org.apache.directory.api.asn1.Asn1Object;
026import org.apache.directory.api.asn1.DecoderException;
027import org.apache.directory.api.asn1.EncoderException;
028import org.apache.directory.api.asn1.ber.tlv.BerValue;
029import org.apache.directory.api.i18n.I18n;
030import org.apache.directory.api.ldap.codec.api.ControlDecorator;
031import org.apache.directory.api.ldap.codec.api.LdapApiService;
032import org.apache.directory.api.ldap.model.message.controls.ProxiedAuthz;
033import org.apache.directory.api.ldap.model.message.controls.ProxiedAuthzImpl;
034import org.apache.directory.api.util.Strings;
035
036
037/**
038 * An ProxiedAuthz implementation, that wraps and decorates the Control with codec
039 * specific functionality.
040 *
041 *
042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
043 */
044public class ProxiedAuthzDecorator extends ControlDecorator<ProxiedAuthz> implements ProxiedAuthz
045{
046    /** A temporary storage for the authzId */
047    private byte[] authzIdBytes = null;
048
049
050    /**
051     * Creates a new instance of ProxiedAuthzDecoder wrapping a newly created
052     * ProxiedAuthz Control object.
053     * 
054     * @param codec The LDAP service instance
055     */
056    public ProxiedAuthzDecorator( LdapApiService codec )
057    {
058        super( codec, new ProxiedAuthzImpl() );
059    }
060
061
062    /**
063     * Creates a new instance of ProxiedAuthzDecorator wrapping the supplied
064     * ProxiedAuthz Control.
065     *
066     * @param codec The LDAP service instance
067     * @param control The ProxiedAuthz Control to be decorated.
068     */
069    public ProxiedAuthzDecorator( LdapApiService codec, ProxiedAuthz control )
070    {
071        super( codec, control );
072    }
073
074
075    /**
076     * Internally used to not have to cast the decorated Control.
077     *
078     * @return the decorated Control.
079     */
080    private ProxiedAuthz getProxiedAuthz()
081    {
082        return getDecorated();
083    }
084
085
086    /**
087     * Compute the ProxiedAuthzControl length 
088     * <pre>
089     *  0x04 L1 authzId]
090     * </pre>
091     *  
092     * @return the control length.
093     */
094    @Override
095    public int computeLength()
096    {
097        int valueLength = 0;
098
099        if ( getAuthzId() != null )
100        {
101            authzIdBytes = Strings.getBytesUtf8( getAuthzId() );
102            valueLength = authzIdBytes.length;
103        }
104
105        return valueLength;
106    }
107
108
109    /**
110     * Encodes the ProxiedAuthz control.
111     * 
112     * @param buffer The encoded sink
113     * @return A ByteBuffer that contains the encoded PDU
114     * @throws EncoderException If anything goes wrong.
115     */
116    @Override
117    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
118    {
119        if ( buffer == null )
120        {
121            throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
122        }
123
124        if ( getAuthzId() != null )
125        {
126            buffer.put( authzIdBytes );
127        }
128
129        return buffer;
130    }
131
132
133    /**
134     * {@inheritDoc}
135     */
136    @Override
137    public byte[] getValue()
138    {
139        if ( value == null )
140        {
141            try
142            {
143                computeLength();
144                ByteBuffer buffer = ByteBuffer.allocate( valueLength );
145
146                if ( authzIdBytes != null )
147                {
148                    BerValue.encode( buffer, authzIdBytes );
149                }
150                else
151                {
152                    BerValue.encode( buffer, Strings.EMPTY_BYTES );
153                }
154
155                value = buffer.array();
156            }
157            catch ( Exception e )
158            {
159                return null;
160            }
161        }
162
163        return value;
164    }
165
166
167    /**
168     * {@inheritDoc}
169     */
170    @Override
171    public String getAuthzId()
172    {
173        return getProxiedAuthz().getAuthzId();
174    }
175
176
177    /**
178     * {@inheritDoc}
179     */
180    @Override
181    public void setAuthzId( String authzId )
182    {
183        getProxiedAuthz().setAuthzId( authzId );
184    }
185
186
187    /**
188     * {@inheritDoc}
189     */
190    @Override
191    public Asn1Object decode( byte[] controlBytes ) throws DecoderException
192    {
193        getProxiedAuthz().setAuthzId( Strings.utf8ToString( controlBytes ) );
194
195        return this;
196    }
197}