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 java.util.Collection;
024
025import org.apache.directory.api.dsmlv2.ParserUtils;
026import org.apache.directory.api.ldap.codec.api.LdapApiService;
027import org.apache.directory.api.ldap.model.entry.Attribute;
028import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
029import org.apache.directory.api.ldap.model.entry.DefaultModification;
030import org.apache.directory.api.ldap.model.entry.Modification;
031import org.apache.directory.api.ldap.model.entry.ModificationOperation;
032import org.apache.directory.api.ldap.model.entry.Value;
033import org.apache.directory.api.ldap.model.exception.LdapException;
034import org.apache.directory.api.ldap.model.message.Control;
035import org.apache.directory.api.ldap.model.message.MessageTypeEnum;
036import org.apache.directory.api.ldap.model.message.ModifyRequest;
037import org.apache.directory.api.ldap.model.message.ModifyRequestImpl;
038import org.apache.directory.api.ldap.model.message.ModifyResponse;
039import org.apache.directory.api.ldap.model.name.Dn;
040import org.dom4j.Element;
041import org.dom4j.Namespace;
042import org.dom4j.QName;
043
044
045/**
046 * DSML Decorator for ModifyRequest
047 *
048 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
049 */
050public class ModifyRequestDsml
051    extends AbstractResultResponseRequestDsml<ModifyRequest, ModifyResponse>
052    implements ModifyRequest
053{
054
055    /** The current attribute being decoded */
056    private Attribute currentAttribute;
057
058    /** A local storage for the operation */
059    private ModificationOperation currentOperation;
060
061
062    /**
063     * Creates a new getDecoratedMessage() of ModifyRequestDsml.
064     */
065    public ModifyRequestDsml( LdapApiService codec )
066    {
067        super( codec, new ModifyRequestImpl() );
068    }
069
070
071    /**
072     * Creates a new getDecoratedMessage() of ModifyRequestDsml.
073     *
074     * @param ldapMessage
075     *      the message to decorate
076     */
077    public ModifyRequestDsml( LdapApiService codec, ModifyRequest ldapMessage )
078    {
079        super( codec, ldapMessage );
080    }
081
082
083    /**
084     * Return the current attribute's type
085     */
086    public String getCurrentAttributeType()
087    {
088        return currentAttribute.getId();
089    }
090
091
092    /**
093     * Store the current operation
094     * 
095     * @param currentOperation The currentOperation to set.
096     */
097    public void setCurrentOperation( int currentOperation )
098    {
099        this.currentOperation = ModificationOperation.getOperation( currentOperation );
100    }
101
102
103    /**
104     * Add a new attributeTypeAndValue
105     * 
106     * @param type The attribute's name
107     */
108    public void addAttributeTypeAndValues( String type )
109    {
110        currentAttribute = new DefaultAttribute( type );
111
112        Modification modification = new DefaultModification( currentOperation, currentAttribute );
113        getDecorated().addModification( modification );
114    }
115
116
117    /**
118     * Add a new value to the current attribute
119     * 
120     * @param value The value to add
121     */
122    public void addAttributeValue( byte[] value ) throws LdapException
123    {
124        currentAttribute.add( value );
125    }
126
127
128    /**
129     * Add a new value to the current attribute
130     * 
131     * @param value The value to add
132     */
133    public void addAttributeValue( String value ) throws LdapException
134    {
135        currentAttribute.add( value );
136    }
137
138
139    /**
140     * {@inheritDoc}
141     */
142    public Element toDsml( Element root )
143    {
144        Element element = super.toDsml( root );
145
146        ModifyRequest request = getDecorated();
147
148        // Dn
149        if ( request.getName() != null )
150        {
151            element.addAttribute( "dn", request.getName().getName() );
152        }
153
154        // Modifications
155        Collection<Modification> modifications = request.getModifications();
156
157        for ( Modification modification : modifications )
158        {
159            Element modElement = element.addElement( "modification" );
160
161            if ( modification.getAttribute() != null )
162            {
163                modElement.addAttribute( "name", modification.getAttribute().getId() );
164
165                for ( Value<?> value : modification.getAttribute() )
166                {
167                    if ( value.getValue() != null )
168                    {
169                        if ( ParserUtils.needsBase64Encoding( value.getValue() ) )
170                        {
171                            Namespace xsdNamespace = new Namespace( "xsd", ParserUtils.XML_SCHEMA_URI );
172                            Namespace xsiNamespace = new Namespace( "xsi", ParserUtils.XML_SCHEMA_INSTANCE_URI );
173                            element.getDocument().getRootElement().add( xsdNamespace );
174                            element.getDocument().getRootElement().add( xsiNamespace );
175
176                            Element valueElement = modElement.addElement( "value" ).addText(
177                                ParserUtils.base64Encode( value.getValue() ) );
178                            valueElement.addAttribute( new QName( "type", xsiNamespace ), "xsd:"
179                                + ParserUtils.BASE64BINARY );
180                        }
181                        else
182                        {
183                            modElement.addElement( "value" ).setText( value.getString() );
184                        }
185                    }
186                }
187            }
188
189            ModificationOperation operation = modification.getOperation();
190
191            if ( operation == ModificationOperation.ADD_ATTRIBUTE )
192            {
193                modElement.addAttribute( "operation", "add" );
194            }
195            else if ( operation == ModificationOperation.REPLACE_ATTRIBUTE )
196            {
197                modElement.addAttribute( "operation", "replace" );
198            }
199            else if ( operation == ModificationOperation.REMOVE_ATTRIBUTE )
200            {
201                modElement.addAttribute( "operation", "delete" );
202            }
203        }
204
205        return element;
206    }
207
208
209    //-------------------------------------------------------------------------
210    // The ModifyRequest methods
211    //-------------------------------------------------------------------------
212
213    /**
214     * {@inheritDoc}
215     */
216    public MessageTypeEnum getResponseType()
217    {
218        return getDecorated().getResponseType();
219    }
220
221
222    /**
223     * {@inheritDoc}
224     */
225    public Dn getName()
226    {
227        return getDecorated().getName();
228    }
229
230
231    /**
232     * {@inheritDoc}
233     */
234    public ModifyRequest setName( Dn name )
235    {
236        getDecorated().setName( name );
237
238        return this;
239    }
240
241
242    /**
243     * {@inheritDoc}
244     */
245    public Collection<Modification> getModifications()
246    {
247        return getDecorated().getModifications();
248    }
249
250
251    /**
252     * {@inheritDoc}
253     */
254    public ModifyRequest addModification( Modification mod )
255    {
256        getDecorated().addModification( mod );
257
258        return this;
259    }
260
261
262    /**
263     * {@inheritDoc}
264     */
265    public ModifyRequest removeModification( Modification mod )
266    {
267        getDecorated().removeModification( mod );
268
269        return this;
270    }
271
272
273    /**
274     * {@inheritDoc}
275     */
276    public ModifyRequest remove( String attributeName, String... attributeValue )
277    {
278        getDecorated().remove( attributeName, attributeValue );
279
280        return this;
281    }
282
283
284    /**
285     * {@inheritDoc}
286     */
287    public ModifyRequest remove( String attributeName, byte[]... attributeValue )
288    {
289        getDecorated().remove( attributeName, attributeValue );
290
291        return this;
292    }
293
294
295    /**
296     * {@inheritDoc}
297     */
298    public ModifyRequest remove( Attribute attr )
299    {
300        getDecorated().remove( attr );
301
302        return this;
303    }
304
305
306    /**
307     * {@inheritDoc}
308     */
309    public ModifyRequest addModification( Attribute attr, ModificationOperation modOp )
310    {
311        getDecorated().addModification( attr, modOp );
312
313        return this;
314    }
315
316
317    /**
318     * {@inheritDoc}
319     */
320    public ModifyRequest add( String attributeName, String... attributeValue )
321    {
322        getDecorated().add( attributeName, attributeValue );
323
324        return this;
325    }
326
327
328    /**
329     * {@inheritDoc}
330     */
331    public ModifyRequest add( String attributeName, byte[]... attributeValue )
332    {
333        getDecorated().add( attributeName, attributeValue );
334
335        return this;
336    }
337
338
339    /**
340     * {@inheritDoc}
341     */
342    public ModifyRequest add( Attribute attr )
343    {
344        getDecorated().add( attr );
345
346        return this;
347    }
348
349
350    /**
351     * {@inheritDoc}
352     */
353    public ModifyRequest replace( String attributeName )
354    {
355        getDecorated().replace( attributeName );
356
357        return this;
358    }
359
360
361    /**
362     * {@inheritDoc}
363     */
364    public ModifyRequest replace( String attributeName, String... attributeValue )
365    {
366        getDecorated().replace( attributeName, attributeValue );
367
368        return this;
369    }
370
371
372    /**
373     * {@inheritDoc}
374     */
375    public ModifyRequest replace( String attributeName, byte[]... attributeValue )
376    {
377        getDecorated().replace( attributeName, attributeValue );
378
379        return this;
380    }
381
382
383    /**
384     * {@inheritDoc}
385     */
386    public ModifyRequest replace( Attribute attr )
387    {
388        getDecorated().replace( attr );
389
390        return this;
391    }
392
393
394    /**
395     * {@inheritDoc}
396     */
397    public ModifyRequest setMessageId( int messageId )
398    {
399        super.setMessageId( messageId );
400
401        return this;
402    }
403
404
405    /**
406     * {@inheritDoc}
407     */
408    public ModifyRequest addControl( Control control )
409    {
410        return ( ModifyRequest ) super.addControl( control );
411    }
412
413
414    /**
415     * {@inheritDoc}
416     */
417    public ModifyRequest addAllControls( Control[] controls )
418    {
419        return ( ModifyRequest ) super.addAllControls( controls );
420    }
421
422
423    /**
424     * {@inheritDoc}
425     */
426    public ModifyRequest removeControl( Control control )
427    {
428        return ( ModifyRequest ) super.removeControl( control );
429    }
430}