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.reponse;
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.MessageTypeEnum;
031import org.apache.directory.api.ldap.model.message.SearchResultEntry;
032import org.apache.directory.api.ldap.model.message.SearchResultEntryImpl;
033import org.apache.directory.api.ldap.model.name.Dn;
034import org.dom4j.Document;
035import org.dom4j.Element;
036import org.dom4j.Namespace;
037import org.dom4j.QName;
038import org.dom4j.tree.DefaultElement;
039
040
041/**
042 * DSML Decorator for SearchResultEntry
043 *
044 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
045 */
046public class SearchResultEntryDsml
047    extends AbstractResponseDsml<SearchResultEntry>
048    implements SearchResultEntry
049{
050
051    private static final String SEARCH_RESULT_ENTRY_TAG = "searchResultEntry";
052
053    /** The current attribute being processed */
054    private Attribute currentAttribute;
055
056
057    /**
058     * Creates a new getDecoratedMessage() of SearchResultEntryDsml.
059     */
060    public SearchResultEntryDsml( LdapApiService codec )
061    {
062        super( codec, new SearchResultEntryImpl() );
063    }
064
065
066    /**
067     * Creates a new getDecoratedMessage() of SearchResultEntryDsml.
068     *
069     * @param ldapMessage
070     *      the message to decorate
071     */
072    public SearchResultEntryDsml( LdapApiService codec, SearchResultEntry ldapMessage )
073    {
074        super( codec, ldapMessage );
075    }
076
077
078    public Attribute getCurrentAttribute()
079    {
080        return currentAttribute;
081    }
082
083
084    /**
085     * Create a new attribute
086     * 
087     * @param type The attribute's type
088     */
089    public void addAttribute( String type ) throws LdapException
090    {
091        currentAttribute = new DefaultAttribute( type );
092
093        getDecorated().getEntry().put( currentAttribute );
094    }
095
096
097    /**
098     * Add a new value to the current attribute
099     * 
100     * @param value The added value
101     */
102    public void addAttributeValue( Object value ) throws LdapException
103    {
104        if ( value instanceof String )
105        {
106            currentAttribute.add( ( String ) value );
107        }
108        else
109        {
110            currentAttribute.add( ( byte[] ) value );
111        }
112    }
113
114
115    /**
116     * {@inheritDoc}
117     */
118    public MessageTypeEnum getType()
119    {
120        return getDecorated().getType();
121    }
122
123
124    /**
125     * {@inheritDoc}
126     */
127    public Element toDsml( Element root )
128    {
129        Element element = null;
130
131        if ( root != null )
132        {
133            element = root.addElement( SEARCH_RESULT_ENTRY_TAG );
134        }
135        else
136        {
137            element = new DefaultElement( SEARCH_RESULT_ENTRY_TAG );
138        }
139
140        SearchResultEntry searchResultEntry = ( SearchResultEntry ) getDecorated();
141        element.addAttribute( "dn", searchResultEntry.getObjectName().getName() );
142
143        Entry entry = searchResultEntry.getEntry();
144        for ( Attribute attribute : entry )
145        {
146
147            Element attributeElement = element.addElement( "attr" );
148            attributeElement.addAttribute( "name", attribute.getUpId() );
149
150            for ( Value<?> value : attribute )
151            {
152                if ( ParserUtils.needsBase64Encoding( value.getValue() ) )
153                {
154                    Namespace xsdNamespace = new Namespace( ParserUtils.XSD, ParserUtils.XML_SCHEMA_URI );
155                    Namespace xsiNamespace = new Namespace( ParserUtils.XSI, ParserUtils.XML_SCHEMA_INSTANCE_URI );
156                    Document doc = attributeElement.getDocument();
157
158                    if ( doc != null )
159                    {
160                        Element docRoot = doc.getRootElement();
161                        docRoot.add( xsdNamespace );
162                        docRoot.add( xsiNamespace );
163                    }
164
165                    Element valueElement = attributeElement.addElement( "value" ).addText(
166                        ParserUtils.base64Encode( value.getValue() ) );
167                    valueElement.addAttribute( new QName( "type", xsiNamespace ), ParserUtils.XSD + ":"
168                        + ParserUtils.BASE64BINARY );
169                }
170                else
171                {
172                    attributeElement.addElement( "value" ).addText( value.getString() );
173                }
174            }
175        }
176
177        return element;
178    }
179
180
181    /**
182     * Get the entry Dn
183     * 
184     * @return Returns the objectName.
185     */
186    public Dn getObjectName()
187    {
188        return getDecorated().getObjectName();
189    }
190
191
192    /**
193     * Set the entry Dn
194     * 
195     * @param objectName The objectName to set.
196     */
197    public void setObjectName( Dn objectName )
198    {
199        getDecorated().setObjectName( objectName );
200    }
201
202
203    /**
204     * Get the entry.
205     * 
206     * @return Returns the entry.
207     */
208    public Entry getEntry()
209    {
210        return getDecorated().getEntry();
211    }
212
213
214    /**
215     * Initialize the entry.
216     * 
217     * @param entry the entry
218     */
219    public void setEntry( Entry entry )
220    {
221        getDecorated().setEntry( entry );
222    }
223}