View Javadoc
1   /**
2    * Redistribution and use of this software and associated documentation ("Software"), with or
3    * without modification, are permitted provided that the following conditions are met:
4    *
5    * 1. Redistributions of source code must retain copyright statements and notices. Redistributions
6    * must also contain a copy of this document.
7    *
8    * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
9    * conditions and the following disclaimer in the documentation and/or other materials provided with
10   * the distribution.
11   *
12   * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
13   * without prior written permission of Intalio, Inc. For written permission, please contact
14   * info@exolab.org.
15   *
16   * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
17   * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
18   * Intalio, Inc.
19   *
20   * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
21   *
22   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR
23   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS
25   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29   * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   *
31   * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  
36  package org.exolab.castor.dsml;
37  
38  import java.io.Serializable;
39  import java.util.Enumeration;
40  import java.util.Collections;
41  import java.util.Vector;
42  import org.xml.sax.DocumentHandler;
43  import org.xml.sax.AttributeList;
44  import org.xml.sax.SAXException;
45  import org.xml.sax.HandlerBase;
46  import org.xml.sax.helpers.AttributeListImpl;
47  import org.castor.core.util.Messages;
48  
49  /**
50   *
51   *
52   * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
53   * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $
54   */
55  public class SearchDescriptor extends HandlerBase implements Serializable {
56    /** SerialVersionUID. */
57    private static final long serialVersionUID = -6614367393322175115L;
58  
59    public static class Scope {
60      public static final int ONE_LEVEL = 0;
61      public static final int BASE = 1;
62      public static final int SUB_TREE = 3;
63    }
64  
65    static class Names {
66      static class Element {
67        public static final String SEARCH = "search";
68        public static final String RETURN_ATTRIBUTE = "return-attr";
69      }
70  
71      static class Attribute {
72        public static final String ATTRIBUTE_NAME = "name";
73        public static final String BASE_DN = "base";
74        public static final String SCOPE = "scope";
75        public static final String FILTER = "filter";
76        public static final String SCOPE_ONE_LEVEL = "onelevel";
77        public static final String SCOPE_BASE = "base";
78        public static final String SCOPE_SUB_TREE = "subtree";
79      }
80    }
81  
82    private int _scope = Scope.BASE;
83  
84    private String _baseDN;
85  
86    private String _filter;
87  
88    private Vector<String> _returnAttrs;
89  
90    private StringBuffer _attrName;
91  
92    private boolean _insideRoot;
93  
94    public SearchDescriptor() {}
95  
96    public int getScope() {
97      return _scope;
98    }
99  
100   public void setScope(final int scope) {
101     _scope = scope;
102   }
103 
104   public String getBaseDN() {
105     return _baseDN;
106   }
107 
108   public void setBaseDN(final String baseDN) {
109     _baseDN = baseDN;
110   }
111 
112   public String getFilter() {
113     return _filter;
114   }
115 
116   public void setFilter(final String filter) {
117     _filter = filter;
118   }
119 
120   public String[] getReturnAttrs() {
121     if (_returnAttrs == null) {
122       return null;
123     }
124     return _returnAttrs.toArray(new String[_returnAttrs.size()]);
125   }
126 
127   public Enumeration<String> listReturnAttrs() {
128     if (_returnAttrs == null) {
129       return Collections.emptyEnumeration();
130     }
131     return _returnAttrs.elements();
132   }
133 
134   public void addReturnAttr(final String attrName) {
135     if (_returnAttrs == null) {
136       _returnAttrs = new Vector<>();
137     }
138     if (!_returnAttrs.contains(attrName)) {
139       _returnAttrs.add(attrName);
140     }
141   }
142 
143 
144   public void produce(final DocumentHandler docHandler) throws SAXException {
145     AttributeListImpl attrList = new AttributeListImpl();
146     docHandler.startElement(XML.Namespace.ROOT, attrList);
147 
148     attrList = new AttributeListImpl();
149     if (_baseDN != null) {
150       attrList.addAttribute(Names.Attribute.BASE_DN, "CDATA", _baseDN);
151     }
152     if (_filter != null) {
153       attrList.addAttribute(Names.Attribute.FILTER, "CDATA", _filter);
154     }
155     switch (_scope) {
156       case Scope.ONE_LEVEL:
157         attrList.addAttribute(Names.Attribute.SCOPE, null, Names.Attribute.SCOPE_ONE_LEVEL);
158         break;
159       case Scope.BASE:
160         attrList.addAttribute(Names.Attribute.SCOPE, null, Names.Attribute.SCOPE_BASE);
161         break;
162       case Scope.SUB_TREE:
163         attrList.addAttribute(Names.Attribute.SCOPE, null, Names.Attribute.SCOPE_SUB_TREE);
164         break;
165     }
166     docHandler.startElement(Names.Element.SEARCH, attrList);
167 
168     if (_returnAttrs != null) {
169       Enumeration<String> enumeration = _returnAttrs.elements();
170       while (enumeration.hasMoreElements()) {
171         attrList = new AttributeListImpl();
172         attrList.addAttribute(Names.Attribute.ATTRIBUTE_NAME, "NMTOKEN", enumeration.nextElement());
173         docHandler.startElement(Names.Element.RETURN_ATTRIBUTE, attrList);
174         docHandler.endElement(Names.Element.RETURN_ATTRIBUTE);
175       }
176     }
177 
178     docHandler.endElement(Names.Element.SEARCH);
179     docHandler.endElement(XML.Namespace.ROOT);
180   }
181 
182   public void startElement(final String tagName, final AttributeList attr) throws SAXException {
183     String value;
184 
185     if (tagName.equals(XML.Namespace.ROOT)) {
186       // Flag when entering (and leaving) the root element.
187       if (_insideRoot) {
188         throw new SAXException(Messages.format("dsml.elementNested", XML.Namespace.ROOT));
189       }
190       _insideRoot = true;
191     } else {
192       if (!_insideRoot) {
193         throw new SAXException(
194             Messages.format("dsml.expectingOpeningTag", XML.Namespace.ROOT, tagName));
195       }
196 
197       if (tagName.equals(Names.Element.SEARCH)) {
198         _baseDN = attr.getValue(Names.Attribute.BASE_DN);
199         if (_baseDN == null) {
200           throw new SAXException(Messages.format("dsml.missingAttribute", Names.Element.SEARCH,
201               Names.Attribute.BASE_DN));
202         }
203         _filter = attr.getValue(Names.Attribute.FILTER);
204         value = attr.getValue(Names.Attribute.SCOPE);
205         if (value != null) {
206           if (value.equals(Names.Attribute.SCOPE_ONE_LEVEL)) {
207             _scope = Scope.ONE_LEVEL;
208           } else if (value.equals(Names.Attribute.SCOPE_BASE)) {
209             _scope = Scope.BASE;
210           } else if (value.equals(Names.Attribute.SCOPE_SUB_TREE)) {
211             _scope = Scope.SUB_TREE;
212           } else {
213             throw new SAXException(
214                 Messages.format("dsml.invalidValue", Names.Attribute.SCOPE, value));
215           }
216         }
217       } else if (tagName.equals(Names.Element.RETURN_ATTRIBUTE)) {
218         if (_baseDN == null) {
219           throw new SAXException(
220               Messages.format("dsml.expectingOpeningTag", Names.Element.SEARCH, tagName));
221         }
222         // Create a string buffer, characters() will fill it up,
223         // endElement() will add it to the list.
224         _attrName = new StringBuffer();
225       } else {
226         throw new SAXException(
227             Messages.format("dsml.expectingOpeningTag", Names.Element.SEARCH, tagName));
228       }
229     }
230   }
231 
232   public void endElement(final String tagName) throws SAXException {
233     if (tagName.equals(XML.Namespace.ROOT)) {
234       if (_insideRoot) {
235         _insideRoot = false;
236       } else {
237         throw new SAXException(Messages.format("dsml.closingOutsideRoot", tagName));
238       }
239     } else {
240       if (!_insideRoot) {
241         throw new SAXException(Messages.format("dsml.closingOutsideRoot", tagName));
242       }
243       if (tagName.equals(Names.Element.SEARCH)) {
244         // Nothing to do hare
245       } else if (tagName.equals(Names.Element.RETURN_ATTRIBUTE)) {
246         if (_attrName.length() > 0) {
247           addReturnAttr(_attrName.toString());
248           _attrName = null;
249         }
250       } else {
251         throw new SAXException(
252             Messages.format("dsml.expectingClosingTag", Names.Element.SEARCH, tagName));
253       }
254     }
255   }
256 
257   public void characters(final char[] ch, final int offset, final int length) {
258     if (_attrName != null) {
259       _attrName.append(ch, offset, length);
260     }
261   }
262 }
263 
264