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.shared.dsmlv2.reponse;
021
022
023import org.apache.directory.shared.dsmlv2.ParserUtils;
024import org.apache.directory.shared.ldap.codec.api.LdapApiService;
025import org.apache.directory.shared.ldap.model.entry.Attribute;
026import org.apache.directory.shared.ldap.model.entry.DefaultAttribute;
027import org.apache.directory.shared.ldap.model.entry.Entry;
028import org.apache.directory.shared.ldap.model.entry.Value;
029import org.apache.directory.shared.ldap.model.exception.LdapException;
030import org.apache.directory.shared.ldap.model.message.MessageTypeEnum;
031import org.apache.directory.shared.ldap.model.message.SearchResultEntry;
032import org.apache.directory.shared.ldap.model.message.SearchResultEntryImpl;
033import org.apache.directory.shared.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    
079    
080    public Attribute getCurrentAttribute()
081    {
082        return currentAttribute;
083    }
084
085
086    /**
087     * Create a new attribute
088     * 
089     * @param type The attribute's type
090     */
091    public void addAttribute( String type ) throws LdapException
092    {
093        currentAttribute = new DefaultAttribute( type );
094
095        getDecorated().getEntry().put( currentAttribute );
096    }
097
098
099    /**
100     * Add a new value to the current attribute
101     * 
102     * @param value The added value
103     */
104    public void addAttributeValue( Object value ) throws LdapException
105    {
106        if ( value instanceof String )
107        {
108            currentAttribute.add( ( String ) value );
109        }
110        else
111        {
112            currentAttribute.add( ( byte[] ) value );
113        }
114    }
115    
116
117    /**
118     * {@inheritDoc}
119     */
120    public MessageTypeEnum getType()
121    {
122        return getDecorated().getType();
123    }
124
125
126    /**
127     * {@inheritDoc}
128     */
129    public Element toDsml( Element root )
130    {
131        Element element = null;
132
133        if ( root != null )
134        {
135            element = root.addElement( SEARCH_RESULT_ENTRY_TAG );
136        }
137        else
138        {
139            element = new DefaultElement( SEARCH_RESULT_ENTRY_TAG );
140        }
141
142        SearchResultEntry searchResultEntry = ( SearchResultEntry ) getDecorated();
143        element.addAttribute( "dn", searchResultEntry.getObjectName().getName() );
144
145        Entry entry = searchResultEntry.getEntry();
146        for ( Attribute attribute : entry )
147        {
148
149            Element attributeElement = element.addElement( "attr" );
150            attributeElement.addAttribute( "name", attribute.getUpId() );
151
152            for ( Value<?> value : attribute )
153            {
154                if ( ParserUtils.needsBase64Encoding( value.getValue() ) )
155                {
156                    Namespace xsdNamespace = new Namespace( ParserUtils.XSD, ParserUtils.XML_SCHEMA_URI );
157                    Namespace xsiNamespace = new Namespace( ParserUtils.XSI, ParserUtils.XML_SCHEMA_INSTANCE_URI );
158                    Document doc = attributeElement.getDocument();
159                    
160                    if ( doc !=null )
161                    {
162                        Element docRoot = doc.getRootElement();
163                        docRoot.add( xsdNamespace );
164                        docRoot.add( xsiNamespace );
165                    }
166
167                    Element valueElement = attributeElement.addElement( "value" ).addText(
168                        ParserUtils.base64Encode( value.getValue() ) );
169                    valueElement.addAttribute( new QName( "type", xsiNamespace ), ParserUtils.XSD + ":"
170                        + ParserUtils.BASE64BINARY );
171                }
172                else
173                {
174                    attributeElement.addElement( "value" ).addText( value.getString() );
175                }
176            }
177        }
178
179        return element;
180    }
181
182
183    /**
184     * Get the entry Dn
185     * 
186     * @return Returns the objectName.
187     */
188    public Dn getObjectName()
189    {
190        return getDecorated().getObjectName();
191    }
192
193
194    /**
195     * Set the entry Dn
196     * 
197     * @param objectName The objectName to set.
198     */
199    public void setObjectName( Dn objectName )
200    {
201        getDecorated().setObjectName( objectName );
202    }
203
204
205    /**
206     * Get the entry.
207     * 
208     * @return Returns the entry.
209     */
210    public Entry getEntry()
211    {
212        return getDecorated().getEntry();
213    }
214
215
216    /**
217     * Initialize the entry.
218     * 
219     * @param entry the entry
220     */
221    public void setEntry( Entry entry )
222    {
223        getDecorated().setEntry( entry );
224    }
225}