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.dsmlv2;
021
022
023import java.util.HashMap;
024import java.util.Map;
025
026import org.apache.directory.api.ldap.codec.api.LdapApiService;
027import org.apache.directory.api.ldap.model.message.Control;
028import org.apache.directory.api.ldap.model.message.Message;
029import org.apache.directory.api.ldap.model.message.MessageTypeEnum;
030
031
032/**
033 * An abstract DSML Message decorator base class.
034 *
035 * @param <M> The message to decorate
036 *
037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
038 */
039public abstract class AbstractDsmlMessageDecorator<M extends Message>
040    implements DsmlDecorator<M>, Message
041{
042    /** The LDAP message codec */
043    private final LdapApiService codec;
044
045    /** The LDAP message */
046    private final M message;
047
048    /** Map of message controls using OID Strings for keys and Control values */
049    private final Map<String, Control> controls;
050
051    /** The current control */
052    private DsmlControl<? extends Control> currentControl;
053
054
055    /**
056     * Create a new instance of AbstractDsmlMessageDecorator
057     * 
058     * @param codec The codec to use
059     * @param message The message to decorate
060     */
061    public AbstractDsmlMessageDecorator( LdapApiService codec, M message )
062    {
063        this.codec = codec;
064        this.message = message;
065        controls = new HashMap<String, Control>();
066    }
067
068
069    /**
070     * Get the current Control Object
071     * 
072     * @return The current Control Object
073     */
074    public DsmlControl<? extends Control> getCurrentControl()
075    {
076        return currentControl;
077    }
078
079
080    /**
081     * @return The codec to use to encode or decode this message
082     */
083    public LdapApiService getCodecService()
084    {
085        return codec;
086    }
087
088
089    /**
090     * {@inheritDoc}
091     */
092    public MessageTypeEnum getType()
093    {
094        return message.getType();
095    }
096
097
098    /**
099     * {@inheritDoc}
100     */
101    public Map<String, Control> getControls()
102    {
103        return controls;
104    }
105
106
107    /**
108     * {@inheritDoc}
109     */
110    public Control getControl( String oid )
111    {
112        return controls.get( oid );
113    }
114
115
116    /**
117     * {@inheritDoc}
118     */
119    public boolean hasControl( String oid )
120    {
121        return controls.containsKey( oid );
122    }
123
124
125    /**
126     * {@inheritDoc}
127     */
128    public Message addControl( Control control )
129    {
130        Control decorated;
131        DsmlControl<? extends Control> decorator;
132
133        if ( control instanceof DsmlControl )
134        {
135            decorator = ( DsmlControl<?> ) control;
136            decorated = decorator.getDecorated();
137        }
138        else
139        {
140            decorator = new DsmlControl<Control>( codec, codec.newControl( control ) );
141            decorated = control;
142        }
143
144        message.addControl( decorated );
145        controls.put( control.getOid(), decorator );
146        currentControl = decorator;
147
148        return this;
149    }
150
151
152    /**
153     * {@inheritDoc}
154     */
155    public Message addAllControls( Control[] controls )
156    {
157        for ( Control control : controls )
158        {
159            addControl( control );
160        }
161
162        return this;
163    }
164
165
166    /**
167     * {@inheritDoc}
168     */
169    public Message removeControl( Control control )
170    {
171        controls.remove( control.getOid() );
172        message.removeControl( control );
173
174        return this;
175    }
176
177
178    /**
179     * {@inheritDoc}
180     */
181    public int getMessageId()
182    {
183        return message.getMessageId();
184    }
185
186
187    /**
188     * {@inheritDoc}
189     */
190    public Object get( Object key )
191    {
192        return message.get( key );
193    }
194
195
196    /**
197     * {@inheritDoc}
198     */
199    public Object put( Object key, Object value )
200    {
201        return message.put( key, value );
202    }
203
204
205    /**
206     * {@inheritDoc}
207     */
208    public Message setMessageId( int messageId )
209    {
210        message.setMessageId( messageId );
211
212        return this;
213    }
214
215
216    /**
217     * {@inheritDoc}
218     */
219    public M getDecorated()
220    {
221        return message;
222    }
223}