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