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