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     * @param codec The LDAP Service to use
066     */
067    public ModifyRequestDsml( LdapApiService codec )
068    {
069        super( codec, new ModifyRequestImpl() );
070    }
071
072
073    /**
074     * Creates a new getDecoratedMessage() of ModifyRequestDsml.
075     *
076     * @param codec The LDAP Service to use
077     * @param ldapMessage the message to decorate
078     */
079    public ModifyRequestDsml( LdapApiService codec, ModifyRequest ldapMessage )
080    {
081        super( codec, ldapMessage );
082    }
083
084
085    /**
086     * @return the current attribute's type
087     */
088    public String getCurrentAttributeType()
089    {
090        return currentAttribute.getId();
091    }
092
093
094    /**
095     * Store the current operation
096     * 
097     * @param currentOperation The currentOperation to set.
098     */
099    public void setCurrentOperation( int currentOperation )
100    {
101        this.currentOperation = ModificationOperation.getOperation( currentOperation );
102    }
103
104
105    /**
106     * Add a new attributeTypeAndValue
107     * 
108     * @param type The attribute's name
109     */
110    public void addAttributeTypeAndValues( String type )
111    {
112        currentAttribute = new DefaultAttribute( type );
113
114        Modification modification = new DefaultModification( currentOperation, currentAttribute );
115        getDecorated().addModification( modification );
116    }
117
118
119    /**
120     * Add a new value to the current attribute
121     * 
122     * @param value The value to add
123     * @throws LdapException If we can't add a value
124     */
125    public void addAttributeValue( byte[] value ) throws LdapException
126    {
127        currentAttribute.add( value );
128    }
129
130
131    /**
132     * Add a new value to the current attribute
133     * 
134     * @param value The value to add
135     * @throws LdapException If we can't add a value
136     */
137    public void addAttributeValue( String value ) throws LdapException
138    {
139        currentAttribute.add( value );
140    }
141
142
143    /**
144     * {@inheritDoc}
145     */
146    @Override
147    public Element toDsml( Element root )
148    {
149        Element element = super.toDsml( root );
150
151        ModifyRequest request = getDecorated();
152
153        // Dn
154        if ( request.getName() != null )
155        {
156            element.addAttribute( "dn", request.getName().getName() );
157        }
158
159        // Modifications
160        Collection<Modification> modifications = request.getModifications();
161
162        for ( Modification modification : modifications )
163        {
164            Element modElement = element.addElement( "modification" );
165
166            if ( modification.getAttribute() != null )
167            {
168                modElement.addAttribute( "name", modification.getAttribute().getId() );
169
170                for ( Value value : modification.getAttribute() )
171                {
172                    if ( value.getString() != null )
173                    {
174                        if ( ParserUtils.needsBase64Encoding( value.getString() ) )
175                        {
176                            Namespace xsdNamespace = new Namespace( "xsd", ParserUtils.XML_SCHEMA_URI );
177                            Namespace xsiNamespace = new Namespace( "xsi", ParserUtils.XML_SCHEMA_INSTANCE_URI );
178                            element.getDocument().getRootElement().add( xsdNamespace );
179                            element.getDocument().getRootElement().add( xsiNamespace );
180
181                            Element valueElement = modElement.addElement( "value" ).addText(
182                                ParserUtils.base64Encode( value.getString() ) );
183                            valueElement.addAttribute( new QName( "type", xsiNamespace ), "xsd:"
184                                + ParserUtils.BASE64BINARY );
185                        }
186                        else
187                        {
188                            modElement.addElement( "value" ).setText( value.getString() );
189                        }
190                    }
191                }
192            }
193
194            ModificationOperation operation = modification.getOperation();
195
196            if ( operation == ModificationOperation.ADD_ATTRIBUTE )
197            {
198                modElement.addAttribute( "operation", "add" );
199            }
200            else if ( operation == ModificationOperation.REPLACE_ATTRIBUTE )
201            {
202                modElement.addAttribute( "operation", "replace" );
203            }
204            else if ( operation == ModificationOperation.REMOVE_ATTRIBUTE )
205            {
206                modElement.addAttribute( "operation", "delete" );
207            }
208            else if ( operation == ModificationOperation.INCREMENT_ATTRIBUTE )
209            {
210                modElement.addAttribute( "operation", "increment" );
211            }
212        }
213
214        return element;
215    }
216
217
218    //-------------------------------------------------------------------------
219    // The ModifyRequest methods
220    //-------------------------------------------------------------------------
221
222    /**
223     * {@inheritDoc}
224     */
225    @Override
226    public MessageTypeEnum getResponseType()
227    {
228        return getDecorated().getResponseType();
229    }
230
231
232    /**
233     * {@inheritDoc}
234     */
235    @Override
236    public Dn getName()
237    {
238        return getDecorated().getName();
239    }
240
241
242    /**
243     * {@inheritDoc}
244     */
245    @Override
246    public ModifyRequest setName( Dn name )
247    {
248        getDecorated().setName( name );
249
250        return this;
251    }
252
253
254    /**
255     * {@inheritDoc}
256     */
257    @Override
258    public Collection<Modification> getModifications()
259    {
260        return getDecorated().getModifications();
261    }
262
263
264    /**
265     * {@inheritDoc}
266     */
267    @Override
268    public ModifyRequest addModification( Modification mod )
269    {
270        getDecorated().addModification( mod );
271
272        return this;
273    }
274
275
276    /**
277     * {@inheritDoc}
278     */
279    @Override
280    public ModifyRequest removeModification( Modification mod )
281    {
282        getDecorated().removeModification( mod );
283
284        return this;
285    }
286
287
288    /**
289     * {@inheritDoc}
290     */
291    @Override
292    public ModifyRequest remove( String attributeName, String... attributeValue )
293    {
294        getDecorated().remove( attributeName, attributeValue );
295
296        return this;
297    }
298
299
300    /**
301     * {@inheritDoc}
302     */
303    public ModifyRequest remove( String attributeName, byte[]... attributeValue )
304    {
305        getDecorated().remove( attributeName, attributeValue );
306
307        return this;
308    }
309
310
311    /**
312     * {@inheritDoc}
313     */
314    @Override
315    public ModifyRequest remove( Attribute attr )
316    {
317        getDecorated().remove( attr );
318
319        return this;
320    }
321
322
323    /**
324     * {@inheritDoc}
325     */
326    @Override
327    public ModifyRequest remove( String attributeName )
328    {
329        getDecorated().remove( attributeName );
330
331        return this;
332    }
333
334
335    /**
336     * {@inheritDoc}
337     */
338    @Override
339    public ModifyRequest addModification( Attribute attr, ModificationOperation modOp )
340    {
341        getDecorated().addModification( attr, modOp );
342
343        return this;
344    }
345
346
347    /**
348     * {@inheritDoc}
349     */
350    @Override
351    public ModifyRequest add( String attributeName, String... attributeValue )
352    {
353        getDecorated().add( attributeName, attributeValue );
354
355        return this;
356    }
357
358
359    /**
360     * {@inheritDoc}
361     */
362    public ModifyRequest add( String attributeName, byte[]... attributeValue )
363    {
364        getDecorated().add( attributeName, attributeValue );
365
366        return this;
367    }
368
369
370    /**
371     * {@inheritDoc}
372     */
373    @Override
374    public ModifyRequest add( Attribute attr )
375    {
376        getDecorated().add( attr );
377
378        return this;
379    }
380
381
382    /**
383     * {@inheritDoc}
384     */
385    @Override
386    public ModifyRequest replace( String attributeName )
387    {
388        getDecorated().replace( attributeName );
389
390        return this;
391    }
392
393
394    /**
395     * {@inheritDoc}
396     */
397    @Override
398    public ModifyRequest replace( String attributeName, String... attributeValue )
399    {
400        getDecorated().replace( attributeName, attributeValue );
401
402        return this;
403    }
404
405
406    /**
407     * {@inheritDoc}
408     */
409    public ModifyRequest replace( String attributeName, byte[]... attributeValue )
410    {
411        getDecorated().replace( attributeName, attributeValue );
412
413        return this;
414    }
415
416
417    /**
418     * {@inheritDoc}
419     */
420    @Override
421    public ModifyRequest replace( Attribute attr )
422    {
423        getDecorated().replace( attr );
424
425        return this;
426    }
427
428
429    /**
430     * {@inheritDoc}
431     */
432    @Override
433    public ModifyRequest increment( Attribute attributeName )
434    {
435        getDecorated().increment( attributeName );
436
437        return this;
438    }
439
440
441    /**
442     * {@inheritDoc}
443     */
444    @Override
445    public ModifyRequest increment( Attribute attributeName, int increment )
446    {
447        getDecorated().increment( attributeName, increment );
448
449        return this;
450    }
451
452
453    /**
454     * {@inheritDoc}
455     */
456    @Override
457    public ModifyRequest increment( String attr )
458    {
459        getDecorated().increment( attr );
460
461        return this;
462    }
463
464
465    /**
466     * {@inheritDoc}
467     */
468    @Override
469    public ModifyRequest increment( String attr, int increment )
470    {
471        getDecorated().increment( attr, increment );
472
473        return this;
474    }
475
476
477    /**
478     * {@inheritDoc}
479     */
480    @Override
481    public ModifyRequest setMessageId( int messageId )
482    {
483        super.setMessageId( messageId );
484
485        return this;
486    }
487
488
489    /**
490     * {@inheritDoc}
491     */
492    @Override
493    public ModifyRequest addControl( Control control )
494    {
495        return ( ModifyRequest ) super.addControl( control );
496    }
497
498
499    /**
500     * {@inheritDoc}
501     */
502    @Override
503    public ModifyRequest addAllControls( Control[] controls )
504    {
505        return ( ModifyRequest ) super.addAllControls( controls );
506    }
507
508
509    /**
510     * {@inheritDoc}
511     */
512    @Override
513    public ModifyRequest removeControl( Control control )
514    {
515        return ( ModifyRequest ) super.removeControl( control );
516    }
517}