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    public Element toDsml( Element root )
147    {
148        Element element = super.toDsml( root );
149
150        ModifyRequest request = getDecorated();
151
152        // Dn
153        if ( request.getName() != null )
154        {
155            element.addAttribute( "dn", request.getName().getName() );
156        }
157
158        // Modifications
159        Collection<Modification> modifications = request.getModifications();
160
161        for ( Modification modification : modifications )
162        {
163            Element modElement = element.addElement( "modification" );
164
165            if ( modification.getAttribute() != null )
166            {
167                modElement.addAttribute( "name", modification.getAttribute().getId() );
168
169                for ( Value<?> value : modification.getAttribute() )
170                {
171                    if ( value.getValue() != null )
172                    {
173                        if ( ParserUtils.needsBase64Encoding( value.getValue() ) )
174                        {
175                            Namespace xsdNamespace = new Namespace( "xsd", ParserUtils.XML_SCHEMA_URI );
176                            Namespace xsiNamespace = new Namespace( "xsi", ParserUtils.XML_SCHEMA_INSTANCE_URI );
177                            element.getDocument().getRootElement().add( xsdNamespace );
178                            element.getDocument().getRootElement().add( xsiNamespace );
179
180                            Element valueElement = modElement.addElement( "value" ).addText(
181                                ParserUtils.base64Encode( value.getValue() ) );
182                            valueElement.addAttribute( new QName( "type", xsiNamespace ), "xsd:"
183                                + ParserUtils.BASE64BINARY );
184                        }
185                        else
186                        {
187                            modElement.addElement( "value" ).setText( value.getString() );
188                        }
189                    }
190                }
191            }
192
193            ModificationOperation operation = modification.getOperation();
194
195            if ( operation == ModificationOperation.ADD_ATTRIBUTE )
196            {
197                modElement.addAttribute( "operation", "add" );
198            }
199            else if ( operation == ModificationOperation.REPLACE_ATTRIBUTE )
200            {
201                modElement.addAttribute( "operation", "replace" );
202            }
203            else if ( operation == ModificationOperation.REMOVE_ATTRIBUTE )
204            {
205                modElement.addAttribute( "operation", "delete" );
206            }
207        }
208
209        return element;
210    }
211
212
213    //-------------------------------------------------------------------------
214    // The ModifyRequest methods
215    //-------------------------------------------------------------------------
216
217    /**
218     * {@inheritDoc}
219     */
220    public MessageTypeEnum getResponseType()
221    {
222        return getDecorated().getResponseType();
223    }
224
225
226    /**
227     * {@inheritDoc}
228     */
229    public Dn getName()
230    {
231        return getDecorated().getName();
232    }
233
234
235    /**
236     * {@inheritDoc}
237     */
238    public ModifyRequest setName( Dn name )
239    {
240        getDecorated().setName( name );
241
242        return this;
243    }
244
245
246    /**
247     * {@inheritDoc}
248     */
249    public Collection<Modification> getModifications()
250    {
251        return getDecorated().getModifications();
252    }
253
254
255    /**
256     * {@inheritDoc}
257     */
258    public ModifyRequest addModification( Modification mod )
259    {
260        getDecorated().addModification( mod );
261
262        return this;
263    }
264
265
266    /**
267     * {@inheritDoc}
268     */
269    public ModifyRequest removeModification( Modification mod )
270    {
271        getDecorated().removeModification( mod );
272
273        return this;
274    }
275
276
277    /**
278     * {@inheritDoc}
279     */
280    public ModifyRequest remove( String attributeName, String... attributeValue )
281    {
282        getDecorated().remove( attributeName, attributeValue );
283
284        return this;
285    }
286
287
288    /**
289     * {@inheritDoc}
290     */
291    public ModifyRequest remove( String attributeName, byte[]... attributeValue )
292    {
293        getDecorated().remove( attributeName, attributeValue );
294
295        return this;
296    }
297
298
299    /**
300     * {@inheritDoc}
301     */
302    public ModifyRequest remove( Attribute attr )
303    {
304        getDecorated().remove( attr );
305
306        return this;
307    }
308
309
310    /**
311     * {@inheritDoc}
312     */
313    public ModifyRequest remove( String attributeName )
314    {
315        getDecorated().remove( attributeName );
316
317        return this;
318    }
319
320
321    /**
322     * {@inheritDoc}
323     */
324    public ModifyRequest addModification( Attribute attr, ModificationOperation modOp )
325    {
326        getDecorated().addModification( attr, modOp );
327
328        return this;
329    }
330
331
332    /**
333     * {@inheritDoc}
334     */
335    public ModifyRequest add( String attributeName, String... attributeValue )
336    {
337        getDecorated().add( attributeName, attributeValue );
338
339        return this;
340    }
341
342
343    /**
344     * {@inheritDoc}
345     */
346    public ModifyRequest add( String attributeName, byte[]... attributeValue )
347    {
348        getDecorated().add( attributeName, attributeValue );
349
350        return this;
351    }
352
353
354    /**
355     * {@inheritDoc}
356     */
357    public ModifyRequest add( Attribute attr )
358    {
359        getDecorated().add( attr );
360
361        return this;
362    }
363
364
365    /**
366     * {@inheritDoc}
367     */
368    public ModifyRequest replace( String attributeName )
369    {
370        getDecorated().replace( attributeName );
371
372        return this;
373    }
374
375
376    /**
377     * {@inheritDoc}
378     */
379    public ModifyRequest replace( String attributeName, String... attributeValue )
380    {
381        getDecorated().replace( attributeName, attributeValue );
382
383        return this;
384    }
385
386
387    /**
388     * {@inheritDoc}
389     */
390    public ModifyRequest replace( String attributeName, byte[]... attributeValue )
391    {
392        getDecorated().replace( attributeName, attributeValue );
393
394        return this;
395    }
396
397
398    /**
399     * {@inheritDoc}
400     */
401    public ModifyRequest replace( Attribute attr )
402    {
403        getDecorated().replace( attr );
404
405        return this;
406    }
407
408
409    /**
410     * {@inheritDoc}
411     */
412    public ModifyRequest setMessageId( int messageId )
413    {
414        super.setMessageId( messageId );
415
416        return this;
417    }
418
419
420    /**
421     * {@inheritDoc}
422     */
423    public ModifyRequest addControl( Control control )
424    {
425        return ( ModifyRequest ) super.addControl( control );
426    }
427
428
429    /**
430     * {@inheritDoc}
431     */
432    public ModifyRequest addAllControls( Control[] controls )
433    {
434        return ( ModifyRequest ) super.addAllControls( controls );
435    }
436
437
438    /**
439     * {@inheritDoc}
440     */
441    public ModifyRequest removeControl( Control control )
442    {
443        return ( ModifyRequest ) super.removeControl( control );
444    }
445}