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 *     https://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<>();
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    @Override
093    public MessageTypeEnum getType()
094    {
095        return message.getType();
096    }
097
098
099    /**
100     * {@inheritDoc}
101     */
102    @Override
103    public Map<String, Control> getControls()
104    {
105        return controls;
106    }
107
108
109    /**
110     * {@inheritDoc}
111     */
112    @Override
113    public Control getControl( String oid )
114    {
115        return controls.get( oid );
116    }
117
118
119    /**
120     * {@inheritDoc}
121     */
122    @Override
123    public boolean hasControl( String oid )
124    {
125        return controls.containsKey( oid );
126    }
127
128
129    /**
130     * {@inheritDoc}
131     */
132    @Override
133    public Message addControl( Control control )
134    {
135        Control decorated;
136        DsmlControl<? extends Control> decorator;
137
138        if ( control instanceof DsmlControl )
139        {
140            decorator = ( DsmlControl<?> ) control;
141            decorated = decorator.getDecorated();
142        }
143        else
144        {
145            decorator = new DsmlControl( codec, control );
146            decorated = control;
147        }
148
149        message.addControl( decorated );
150        controls.put( control.getOid(), decorator );
151        currentControl = decorator;
152
153        return this;
154    }
155
156
157    /**
158     * {@inheritDoc}
159     */
160    @Override
161    public Message addAllControls( Control[] controlsToAdd )
162    {
163        for ( Control control : controlsToAdd )
164        {
165            addControl( control );
166        }
167
168        return this;
169    }
170
171
172    /**
173     * {@inheritDoc}
174     */
175    @Override
176    public Message removeControl( Control control )
177    {
178        controls.remove( control.getOid() );
179        message.removeControl( control );
180
181        return this;
182    }
183
184
185    /**
186     * {@inheritDoc}
187     */
188    @Override
189    public int getMessageId()
190    {
191        return message.getMessageId();
192    }
193
194
195    /**
196     * {@inheritDoc}
197     */
198    @Override
199    public Object get( Object key )
200    {
201        return message.get( key );
202    }
203
204
205    /**
206     * {@inheritDoc}
207     */
208    @Override
209    public Object put( Object key, Object value )
210    {
211        return message.put( key, value );
212    }
213
214
215    /**
216     * {@inheritDoc}
217     */
218    @Override
219    public Message setMessageId( int messageId )
220    {
221        message.setMessageId( messageId );
222
223        return this;
224    }
225
226
227    /**
228     * {@inheritDoc}
229     */
230    @Override
231    public M getDecorated()
232    {
233        return message;
234    }
235}