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.request;
021
022
023import org.apache.directory.api.dsmlv2.ParserUtils;
024import org.apache.directory.api.ldap.codec.api.LdapApiService;
025import org.apache.directory.api.ldap.model.entry.Attribute;
026import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
027import org.apache.directory.api.ldap.model.entry.Entry;
028import org.apache.directory.api.ldap.model.entry.Value;
029import org.apache.directory.api.ldap.model.exception.LdapException;
030import org.apache.directory.api.ldap.model.message.AddRequest;
031import org.apache.directory.api.ldap.model.message.AddRequestImpl;
032import org.apache.directory.api.ldap.model.message.AddResponse;
033import org.apache.directory.api.ldap.model.message.Control;
034import org.apache.directory.api.ldap.model.message.MessageTypeEnum;
035import org.apache.directory.api.ldap.model.name.Dn;
036import org.dom4j.Element;
037import org.dom4j.Namespace;
038import org.dom4j.QName;
039
040
041/**
042 * DSML Decorator for AddRequest
043 *
044 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
045 */
046public class AddRequestDsml
047    extends AbstractResultResponseRequestDsml<AddRequest, AddResponse>
048    implements AddRequest
049{
050
051    /** The current attribute being decoded */
052    private Attribute currentAttribute;
053
054
055    /**
056     * Creates a new getDecoratedMessage() of AddRequestDsml.
057     * 
058     * @param codec The LDAP Service to use
059     */
060    public AddRequestDsml( LdapApiService codec )
061    {
062        super( codec, new AddRequestImpl() );
063    }
064
065
066    /**
067     * Creates a new getDecoratedMessage() of AddRequestDsml.
068    *
069     * @param codec The LDAP Service to use
070    * @param ldapMessage the message to decorate
071    */
072    public AddRequestDsml( LdapApiService codec, AddRequest ldapMessage )
073    {
074        super( codec, ldapMessage );
075    }
076
077
078    /**
079     * Create a new attributeValue
080     * 
081     * @param type The attribute's name (called 'type' in the grammar)
082     * @throws LdapException If we can't add the type
083     */
084    public void addAttributeType( String type ) throws LdapException
085    {
086        // do not create a new attribute if we have seen this attributeType before
087        if ( getDecorated().getEntry().get( type ) != null )
088        {
089            currentAttribute = getDecorated().getEntry().get( type );
090            return;
091        }
092
093        // fix this to use AttributeImpl(type.getString().toLowerCase())
094        currentAttribute = new DefaultAttribute( type );
095        getDecorated().getEntry().put( currentAttribute );
096    }
097
098
099    /**
100     * @return Returns the currentAttribute type.
101     */
102    public String getCurrentAttributeType()
103    {
104        return currentAttribute.getId();
105    }
106
107
108    /**
109     * Add a new value to the current attribute
110     * 
111     * @param value The value to add
112     * @throws LdapException If we can't add a new value
113     */
114    public void addAttributeValue( String value ) throws LdapException
115    {
116        currentAttribute.add( value );
117    }
118
119
120    /**
121     * Add a new value to the current attribute
122     * 
123     * @param value The value to add
124     * @throws LdapException If we can't add a new value
125     */
126    public void addAttributeValue( Value value ) throws LdapException
127    {
128        currentAttribute.add( value );
129    }
130
131
132    /**
133     * Add a new value to the current attribute
134     * 
135     * @param value The value to add
136     * @throws LdapException If we can't add a new value
137     */
138    public void addAttributeValue( byte[] value ) throws LdapException
139    {
140        currentAttribute.add( value );
141    }
142
143
144    /**
145     * {@inheritDoc}
146     */
147    @Override
148    public MessageTypeEnum getType()
149    {
150        return getDecorated().getType();
151    }
152
153
154    /**
155     * {@inheritDoc}
156     */
157    @Override
158    public Element toDsml( Element root )
159    {
160        Element element = super.toDsml( root );
161
162        // Dn
163        if ( getDecorated().getEntry() != null )
164        {
165            element.addAttribute( "dn", getDecorated().getEntry().getDn().getName() );
166        }
167
168        // Attributes
169        Entry entry = getDecorated().getEntry();
170        if ( entry != null )
171        {
172            for ( Attribute attribute : entry )
173            {
174                Element attributeElement = element.addElement( "attr" );
175                attributeElement.addAttribute( "name", attribute.getId() );
176                // Looping on Values
177                for ( Value value : attribute )
178                {
179                    if ( ParserUtils.needsBase64Encoding( value.getString() ) )
180                    {
181                        Namespace xsdNamespace = new Namespace( "xsd", ParserUtils.XML_SCHEMA_URI );
182                        Namespace xsiNamespace = new Namespace( "xsi", ParserUtils.XML_SCHEMA_INSTANCE_URI );
183                        attributeElement.getDocument().getRootElement().add( xsdNamespace );
184                        attributeElement.getDocument().getRootElement().add( xsiNamespace );
185
186                        Element valueElement = attributeElement.addElement( "value" ).addText(
187                            ParserUtils.base64Encode( value.getString() ) );
188                        valueElement
189                            .addAttribute( new QName( "type", xsiNamespace ), "xsd:" + ParserUtils.BASE64BINARY );
190                    }
191                    else
192                    {
193                        attributeElement.addElement( "value" ).addText( value.getString() );
194                    }
195                }
196            }
197        }
198
199        return element;
200    }
201
202
203    /**
204     * Initialize the Entry.
205     */
206    public void initEntry()
207    {
208    }
209
210
211    /**
212     * Get the entry with its attributes.
213     * 
214     * @return Returns the entry.
215     */
216    @Override
217    public Entry getEntry()
218    {
219        return getDecorated().getEntry();
220    }
221
222
223    /**
224     * Add a new value to the current attribute
225     * 
226     * @param value The value to be added
227     * @throws LdapException If we can't add a new value
228     */
229    public void addAttributeValue( Object value ) throws LdapException
230    {
231        if ( value instanceof Value )
232        {
233            ( ( AddRequestDsml ) getDecorated() ).addAttributeValue( ( Value ) value );
234        }
235        else if ( value instanceof String )
236        {
237            ( ( AddRequestDsml ) getDecorated() ).addAttributeValue( ( String ) value );
238        }
239        else if ( value instanceof byte[] )
240        {
241            ( ( AddRequestDsml ) getDecorated() ).addAttributeValue( ( byte[] ) value );
242        }
243    }
244
245
246    /**
247     * Get the added Dn
248     * 
249     * @return Returns the entry Dn.
250     */
251    @Override
252    public Dn getEntryDn()
253    {
254        return getDecorated().getEntryDn();
255    }
256
257
258    /**
259     * {@inheritDoc}
260     */
261    @Override
262    public AddRequest setEntryDn( Dn entryDn )
263    {
264        getDecorated().setEntryDn( entryDn );
265
266        return this;
267    }
268
269
270    /**
271     * {@inheritDoc}
272     */
273    @Override
274    public AddRequest setEntry( Entry entry )
275    {
276        getDecorated().setEntry( entry );
277
278        return this;
279    }
280
281
282    /**
283     * {@inheritDoc}
284     */
285    @Override
286    public AddRequest setMessageId( int messageId )
287    {
288        super.setMessageId( messageId );
289
290        return this;
291    }
292
293
294    /**
295     * {@inheritDoc}
296     */
297    @Override
298    public AddRequest addControl( Control control )
299    {
300        return ( AddRequest ) super.addControl( control );
301    }
302
303
304    /**
305     * {@inheritDoc}
306     */
307    @Override
308    public AddRequest addAllControls( Control[] controls )
309    {
310        return ( AddRequest ) super.addAllControls( controls );
311    }
312
313
314    /**
315     * {@inheritDoc}
316     */
317    @Override
318    public AddRequest removeControl( Control control )
319    {
320        return ( AddRequest ) super.removeControl( control );
321    }
322
323
324    /**
325     * {@inheritDoc}
326     */
327    @Override
328    public MessageTypeEnum getResponseType()
329    {
330        return getDecorated().getResponseType();
331    }
332}