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