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.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    public MessageTypeEnum getType()
148    {
149        return getDecorated().getType();
150    }
151
152
153    /**
154     * {@inheritDoc}
155     */
156    public Element toDsml( Element root )
157    {
158        Element element = super.toDsml( root );
159
160        // Dn
161        if ( getDecorated().getEntry() != null )
162        {
163            element.addAttribute( "dn", getDecorated().getEntry().getDn().getName() );
164        }
165
166        // Attributes
167        Entry entry = getDecorated().getEntry();
168        if ( entry != null )
169        {
170            for ( Attribute attribute : entry )
171            {
172                Element attributeElement = element.addElement( "attr" );
173                attributeElement.addAttribute( "name", attribute.getId() );
174                // Looping on Values
175                for ( Value<?> value : attribute )
176                {
177                    if ( ParserUtils.needsBase64Encoding( value.getValue() ) )
178                    {
179                        Namespace xsdNamespace = new Namespace( "xsd", ParserUtils.XML_SCHEMA_URI );
180                        Namespace xsiNamespace = new Namespace( "xsi", ParserUtils.XML_SCHEMA_INSTANCE_URI );
181                        attributeElement.getDocument().getRootElement().add( xsdNamespace );
182                        attributeElement.getDocument().getRootElement().add( xsiNamespace );
183
184                        Element valueElement = attributeElement.addElement( "value" ).addText(
185                            ParserUtils.base64Encode( value.getValue() ) );
186                        valueElement
187                            .addAttribute( new QName( "type", xsiNamespace ), "xsd:" + ParserUtils.BASE64BINARY );
188                    }
189                    else
190                    {
191                        attributeElement.addElement( "value" ).addText( value.getString() );
192                    }
193                }
194            }
195        }
196
197        return element;
198    }
199
200
201    /**
202     * Initialize the Entry.
203     */
204    public void initEntry()
205    {
206    }
207
208
209    /**
210     * Get the entry with its attributes.
211     * 
212     * @return Returns the entry.
213     */
214    public Entry getEntry()
215    {
216        return getDecorated().getEntry();
217    }
218
219
220    /**
221     * Add a new value to the current attribute
222     * 
223     * @param value The value to be added
224     * @throws LdapException If we can't add a new value
225     */
226    public void addAttributeValue( Object value ) throws LdapException
227    {
228        if ( value instanceof Value<?> )
229        {
230            ( ( AddRequestDsml ) getDecorated() ).addAttributeValue( ( Value<?> ) value );
231        }
232        else if ( value instanceof String )
233        {
234            ( ( AddRequestDsml ) getDecorated() ).addAttributeValue( ( String ) value );
235        }
236        else if ( value instanceof byte[] )
237        {
238            ( ( AddRequestDsml ) getDecorated() ).addAttributeValue( ( byte[] ) value );
239        }
240    }
241
242
243    /**
244     * Get the added Dn
245     * 
246     * @return Returns the entry Dn.
247     */
248    public Dn getEntryDn()
249    {
250        return getDecorated().getEntryDn();
251    }
252
253
254    /**
255     * {@inheritDoc}
256     */
257    public AddRequest setEntryDn( Dn entryDn )
258    {
259        getDecorated().setEntryDn( entryDn );
260
261        return this;
262    }
263
264
265    /**
266     * {@inheritDoc}
267     */
268    public AddRequest setEntry( Entry entry )
269    {
270        getDecorated().setEntry( entry );
271
272        return this;
273    }
274
275
276    /**
277     * {@inheritDoc}
278     */
279    public AddRequest setMessageId( int messageId )
280    {
281        super.setMessageId( messageId );
282
283        return this;
284    }
285
286
287    /**
288     * {@inheritDoc}
289     */
290    public AddRequest addControl( Control control )
291    {
292        return ( AddRequest ) super.addControl( control );
293    }
294
295
296    /**
297     * {@inheritDoc}
298     */
299    public AddRequest addAllControls( Control[] controls )
300    {
301        return ( AddRequest ) super.addAllControls( controls );
302    }
303
304
305    /**
306     * {@inheritDoc}
307     */
308    public AddRequest removeControl( Control control )
309    {
310        return ( AddRequest ) super.removeControl( control );
311    }
312
313
314    /**
315     * {@inheritDoc}
316     */
317    public MessageTypeEnum getResponseType()
318    {
319        return getDecorated().getResponseType();
320    }
321}