1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.talika.tarsis.security.memory;
24
25 import java.io.InputStream;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.Stack;
32 import java.util.StringTokenizer;
33
34 import org.talika.tarsis.security.RoleImpl;
35 import org.xml.sax.Attributes;
36 import org.xml.sax.InputSource;
37 import org.xml.sax.SAXException;
38 import org.xml.sax.SAXParseException;
39 import org.xml.sax.helpers.AttributesImpl;
40 import org.xml.sax.helpers.DefaultHandler;
41
42 /**
43 * Implementation of SAX handlers for Tarsis MVC Users XML files.
44 *
45 * @author Jose M. Palomar
46 * @version $Revision: 125 $
47 */
48 public final class XmlUsersHandler extends DefaultHandler {
49
50
51 /**
52 * <tarsis-users> tag.
53 */
54 public static final String USERS_TAG = "tarsis-users";
55
56 /**
57 * <user> tag.
58 */
59 public static final String USER_TAG = "user";
60
61 /**
62 * Name attribute.
63 */
64 public static final String NAME_ATTR = "name";
65
66 /**
67 * Password attribute.
68 */
69 public static final String PASSWORD_ATTR = "password";
70
71 /**
72 * Roles attribute.
73 */
74 public static final String ROLES_ATTR = "roles";
75
76 /**
77 * Roles separator.
78 */
79 public static final String ROLES_SEPARATOR = ",";
80
81 /**
82 * DTD public id.
83 */
84 public static final String DTD_PUBLICID = "-//Talika Open Source Group//Users DTD 1.0//ES";
85 /**
86 * DTD class path.
87 */
88 public static final String DTD_CLASSPATH = "/org/talika/dtds/tarsis-users_1_0.dtd";
89
90
91 /**
92 * Users map.
93 */
94 private Map users = new HashMap();
95
96 /**
97 * Tag attributes stack.
98 */
99 private Stack stAtts = new Stack();
100
101 /**
102 * Map of parameters.
103 */
104 private Map auxParams = new HashMap();
105
106
107 /**
108 * Creates a new <code>XmlUsersHandler</code>.
109 */
110 public XmlUsersHandler() {
111 }
112
113
114
115 /**
116 * Receive notification of the beginning of a document.
117 *
118 * @throws SAXException Any SAX exception, possibly wrapping another exception.
119 * @see org.xml.sax.ContentHandler#startDocument()
120 */
121 public void startDocument() throws SAXException {
122
123 }
124
125 /**
126 * Receive notification of the end of a document.
127 *
128 * @throws SAXException Any SAX exception, possibly wrapping another exception.
129 * @see org.xml.sax.ContentHandler#endDocument()
130 */
131 public void endDocument() throws SAXException {
132
133 }
134
135 /**
136 * Receive notification of the beginning of an element.
137 *
138 * @param namespaceURI String The Namespace URI, or the empty string if the
139 * element has no Namespace URI or if Namespace processing is not being performed.
140 * @param localName String The local name (without prefix), or the empty string
141 * if Namespace processing is not being performed.
142 * @param name String The qualified name (with prefix), or the empty string if
143 * qualified names are not available.
144 * @param atts Attributes The attributes attached to the element. If there are no
145 * attributes, it shall be an empty Attributes object.
146 * @throws SAXException Any SAX exception, possibly wrapping another exception.
147 * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
148 */
149 public void startElement(String namespaceURI, String localName, String name, Attributes atts) throws SAXException {
150 stAtts.push(new AttributesImpl(atts));
151 }
152
153 /**
154 * Receive notification of the end of an element.
155 *
156 * @param namespaceURI String The Namespace URI, or the empty string if the
157 * element has no Namespace URI or if Namespace processing is not being performed.
158 * @param localName String The local name (without prefix), or the empty string
159 * if Namespace processing is not being performed.
160 * @param name String The qualified name (with prefix), or the empty string if
161 * qualified names are not available.
162 * @throws SAXException Any SAX exception, possibly wrapping another exception.
163 * @see org.xml.sax.ContentHandler#endElement(String, String, String)
164 */
165 public void endElement(String namespaceURI, String localName, String name) throws SAXException {
166
167 Attributes atts = (Attributes) stAtts.pop();
168
169 if (name.equals(USERS_TAG)) {
170
171 }
172 else if (name.equals(USER_TAG)) {
173 processUserTag(atts);
174 }
175
176 }
177
178
179 /**
180 * Allow the application to resolve external entities.
181 *
182 * @param publicId String The public identifier of the external entity being
183 * referenced, or <code>null</code> if none was supplied.
184 * @param systemId String The system identifier of the external entity being
185 * referenced.
186 * @return InputSource A Java-specific IO exception, possibly the result of
187 * creating a new <code>InputStream</code> or <code>Reader</code> for the
188 * <code>InputSource</code>.
189 * @see org.xml.sax.EntityResolver#resolveEntity(String, String)
190 */
191 public InputSource resolveEntity (String publicId, String systemId) {
192
193 if (publicId.equals(DTD_PUBLICID)) {
194
195 InputStream is = this.getClass().getResourceAsStream(DTD_CLASSPATH);
196 if (is != null) {
197 return new InputSource(is);
198 }
199
200 }
201
202 return null;
203
204 }
205
206
207 /**
208 * Receive notification of a warning.
209 *
210 * @param spe SAXParseException The warning information encapsulated in a SAX
211 * parse exception.
212 * @throws SAXException Any SAX exception, possibly wrapping another exception.
213 * @see org.xml.sax.ErrorHandler#warning(SAXParseException)
214 */
215 public void warning(SAXParseException spe) throws SAXException {
216 }
217
218 /**
219 * Receive notification of a recoverable error.
220 *
221 * @param spe SAXParseException The error information encapsulated in a SAX parse
222 * exception.
223 * @throws SAXException Any SAX exception, possibly wrapping another exception.
224 * @see org.xml.sax.ErrorHandler#error(SAXParseException)
225 */
226 public void error(SAXParseException spe) throws SAXException {
227 throw new SAXException("** Users parse error\n" +
228 " at [" + spe.getLineNumber() +
229 ":" + spe.getColumnNumber() +
230 "] in " + spe.getSystemId(), spe);
231 }
232
233 /**
234 * Receive notification of a non-recoverable error.
235 *
236 * @param spe SAXParseException The error information encapsulated in a SAX parse
237 * exception.
238 * @throws SAXException Any SAX exception, possibly wrapping another exception.
239 * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException)
240 */
241 public void fatalError(SAXParseException spe) throws SAXException {
242 throw new SAXException("** Users parse error\n" +
243 " at [" + spe.getLineNumber() +
244 ":" + spe.getColumnNumber() +
245 "] in " + spe.getSystemId(), spe);
246 }
247
248
249 /**
250 * Returns parsed users map.
251 *
252 * @return Map parsed users map.
253 */
254 public Map getUsers() {
255 return Collections.unmodifiableMap(users);
256 }
257
258
259 /**
260 * Process <user> tag.
261 *
262 * @param atts Attributes tag attributes.
263 * @throws SAXException if there is an error while processing tag.
264 */
265 protected void processUserTag(Attributes atts) throws SAXException {
266
267 String name = atts.getValue(NAME_ATTR);
268 String password = atts.getValue(PASSWORD_ATTR);
269 String rolesStr = atts.getValue(ROLES_ATTR);
270
271 Set roles = parseRoles(rolesStr);
272
273 this.users.put(name, new MemoryUserImpl(name, name, password, roles));
274
275 }
276
277 /**
278 * Returns a <code>Set</code> of roles parsed from string.
279 *
280 * @param rolesStr String string to be parsed.
281 * @return Set a <code>Set</code> of roles parsed from string.
282 */
283 protected Set parseRoles(String rolesStr) {
284
285 StringTokenizer st = new StringTokenizer(rolesStr, ROLES_SEPARATOR);
286
287 Set roles = new HashSet();
288 while (st.hasMoreTokens()) {
289 String roleName = st.nextToken().trim();
290 roles.add(new RoleImpl(roleName));
291 }
292
293 return roles;
294 }
295
296 }