1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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
53
54
55 public class SearchDescriptor extends HandlerBase implements Serializable {
56
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
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
223
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
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