// 
// The Waveset SPML General License 
// 
// Version 0.1, April 2003
// Copyright (C) 2003 Waveset Technologies, Inc..
// 6034 West Courtyard Drive, Suite 210, Austin, Texas 78730
// All rights reserved.
// 
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// 
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions, and the disclaimers in Sections 6
//    and 7 below.
// 
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the disclaimers in Sections 6
//    and 7 below in the documentation and/or other materials provided
//    with the distribution.
// 
// 3. The end-user documentation included with the redistribution, if
//    any, must include the following acknowledgment:
// 
//    "This product includes software developed by 
//     Waveset Technologies, Inc. (www.waveset.com)."
// 
//    Alternately, this acknowledgment may appear in the software itself, if
//    and wherever such third-party acknowledgments normally appear.
//  
// 4. The names "Waveset" and "Waveset Technologies, Inc." must not be
//    used to endorse or promote products derived from this software
//    without the prior written permission of Waveset. For written
//    permission, please contact www.waveset.com.
//  
// 5. Products derived from this software may not be called "Waveset",
//    nor may "Waveset" appear in their name, without the prior written
//    permission of Waveset.
//  
// 6. NO WARRANTY 
// 
//    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED
//    OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//    DISCLAIMED.
// 
// 7.  LIMITATION OF LIABILITY
// 
//    IN NO EVENT SHALL THE WAVESET OR ITS LICENSORS BE LIABLE FOR ANY
//    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
//    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
//    GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
//    IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
//    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//    ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// 
// End of Terms and Conditions
// ====================================================================
//
// Component Name: org.openspml.message.SearchRequest
//
// Author(s): Jeff Larson
//
// Description:
//
// Memory representation for a <searchRequest> element.
//
//

package org.openspml.message;

import java.util.*;

import org.openspml.util.*;

/**
 * A class used to represent a <code>searchRequest</code> element.
 * <p>
 * This includes a <i>search base</i> to constrain the search, 
 * a <i>filter</i> to further constraint the search, and a set
 * of <i>attributes</i> to return from objects that match the
 * search criteria.
 */
public class SearchRequest extends SpmlRequest {

    //////////////////////////////////////////////////////////////////////
    //
    // Fields
    //
    //////////////////////////////////////////////////////////////////////

    static final String ELEMENT = "searchRequest";
    public static final String EL_SEARCH_BASE = "searchBase";

    /**
     * Optional base for the search.  This may for example be
     * an LDAP base context, or a domain name.
     */
    Identifier _searchBase;

    /**
     * Search filter.  Currently the same as DMSL.
     */
    Filter _filter;

    /**
     * Names of attributes to return.
     */
    List _attributes;

    //////////////////////////////////////////////////////////////////////
    //
    // Constructors
    //
    //////////////////////////////////////////////////////////////////////

    public SearchRequest() {
    }

    SearchRequest(XmlElement e) {
	parseXml(e);
    }

    public SpmlResponse createResponse() {
        return new SearchResponse();
    }

    public void setSearchBase(Identifier i) {
        _searchBase = i;
    }

    public void setSearchBase(String s) {
        if (s == null)
            _searchBase = null;
        else 
            _searchBase = new Identifier(s);
    }

    public void setFilter(Filter f) {
        _filter = f;
    }

    public void setAttributes(List l) {
        if (l != null && l.size() > 0)
            _attributes = l;
        else
            _attributes = null;
    }

    public void addAttribute(String s) {
        if (s != null) {
            if (_attributes == null)
                _attributes = new ArrayList();
            _attributes.add(s);
        }
    }

    /**
     * Convenience method to add a common equality comparison.
     */
    public void addCondition(String attname, String value) {

	FilterTerm term = new FilterTerm();
	term.setOperation(FilterTerm.OP_EQUAL);
	term.setName(attname);
	term.setValue(value);

        addFilterTerm(term);
    }

    /**
     * Convenience method to add a filter term.
     */
    public void addFilterTerm(FilterTerm term) {
	if (_filter == null)
	    _filter = new Filter();
        _filter.addTerm(term);
    }

    //////////////////////////////////////////////////////////////////////
    //
    // Accessors
    //
    //////////////////////////////////////////////////////////////////////

    public Identifier getSearchBase() {
        return _searchBase;
    }

    public Filter getFilter() {
        return _filter;
    }

    public List getAttributes() {
        return _attributes;
    }

    //////////////////////////////////////////////////////////////////////
    //
    // XML
    //
    //////////////////////////////////////////////////////////////////////

    public String getElementName() {
        return ELEMENT;
    }

    void addSubclassElements(SpmlBuffer b) {

        if (_searchBase != null)
            _searchBase.toXml(b, EL_SEARCH_BASE);

        if (_filter != null)
            _filter.toXml(b);

        if (_attributes != null) {
            b.addStartTag("attributes");
            b.incIndent();
            
            Iterator it = _attributes.iterator();
            while (it.hasNext()) {
                String name = (String)it.next();
		// these are defined by dsml so they must be qualified
                b.addOpenStartTag("dsml", "attribute");
                b.addAttribute("name", name);
                b.closeEmptyElement();
            }

            b.decIndent();
            b.addEndTag("attributes");
        }
    }

    void parseXml(XmlElement e) {

        super.parseXml(e);

	for (XmlElement child = e.getChildElement() ; 
	     child != null ; child = child.next()) {
	    String tag = child.getLocalName();

            if (tag.equals(EL_SEARCH_BASE))
                _searchBase = new Identifier(child);
 
            else if (tag.equals(Filter.ELEMENT))
                _filter = new Filter(child);
            
            else if (tag.equals("attributes")) {
                for (XmlElement attel = child.getChildElement() ; 
                     attel != null ; attel = attel.next()) {

                    addAttribute(attel.getAttribute("name"));
                }
            }
	}
    }

}
