1 /*
2 * The SmartConfig Library
3 * Copyright (C) 2004-2006
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * For further informations on the SmartConfig Library please visit
20 *
21 * http://smartconfig.sourceforge.net
22 */
23 package net.smartlab.config;
24
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Iterator;
29 import java.util.Map;
30 import java.util.StringTokenizer;
31
32 /**
33 * This class identifies a configuration element which can in turn contains
34 * other configuration elements. An element is composed by a name, a set of
35 * attributes which can be empty and, optionally, by its contents.
36 *
37 * @author rlogiacco
38 */
39 abstract public class Element {
40
41 /**
42 * The containing node.
43 */
44 protected Node parent;
45
46 /**
47 * The element name.
48 *
49 * @uml.property name="name"
50 */
51 protected String name;
52
53
54 /**
55 * Constructs an element with a givenparent node and name.
56 *
57 * @param parent the node containing the element.
58 * @param name the element name.
59 */
60 protected Element(Node parent, String name) {
61 this.parent = parent;
62 this.name = name;
63 }
64
65 /**
66 * Returns the name of this configuration element.
67 *
68 * @return a <code>String</code> representing the name of this
69 * configuration element.
70 * @uml.property name="name"
71 */
72 public String getName() {
73 return name;
74 }
75
76 /**
77 * Returns the unique identifier associated with this element.
78 *
79 * @return the unique identifier associated with this element.
80 */
81 public abstract String getId();
82
83 /**
84 * Returns all the contained elements.
85 *
86 * @return an unmodifiable <code>Collection</code> which enumerates the
87 * contained elements.
88 * @throws ConfigurationException if something wrong occurs during the
89 * operation.
90 */
91 public abstract Collection getElements() throws ConfigurationException;
92
93 /**
94 * Returns all the contained elements which name equals the given one.
95 *
96 * @param name the name of the elements to search for.
97 * @return an unmodifiable <code>Collection</code> which enumerates the
98 * contained elements which name equals the given one.
99 * @throws ConfigurationException if something wrong occurs during the
100 * operation.
101 */
102 public abstract Collection getElements(String name) throws ConfigurationException;
103
104 /**
105 * Returns the first contained element whose name equals the given one.
106 *
107 * @param name the name of the element to search for.
108 * @return the contained <code>Element</code> or <code>null</code> if
109 * the search fails.
110 * @throws ConfigurationException if something wrong occurs during the
111 * operation.
112 */
113 public Element getElement(String name) throws ConfigurationException {
114 return this.getElement(name, null, null);
115 }
116
117 /**
118 * Returns the first contained element whose name equals the given one and
119 * whose attribute list contains the given one.
120 *
121 * @param name the name of the element to search for.
122 * @param attribute the name of the attribute which must be defined on the
123 * element.
124 * @return the contained <code>Element</code> or <code>null</code> if
125 * the search fails.
126 * @throws ConfigurationException if something wrong occurs during the
127 * operation.
128 */
129 public Element getElement(String name, String attribute) throws ConfigurationException {
130 return this.getElement(name, attribute, null);
131 }
132
133 /**
134 * Returns the first contained element whose name equals the given one and
135 * whose attribute list defines an attribute whose name and values matches
136 * the given parameters.
137 *
138 * @param name the name of the element to search for.
139 * @param attribute attribute the name of the attribute which must be
140 * defined on the element.
141 * @param value the value the attribute must match.
142 * @return the contained <code>Element</code> or <code>null</code> if
143 * the search fails.
144 * @throws ConfigurationException if something wrong occurs during the
145 * operation.
146 */
147 public abstract Element getElement(String name, String attribute, String value) throws ConfigurationException;
148
149 /**
150 * Returns all the attributes names of this element.
151 *
152 * @return an unmodifiable <code>Collection</code> which enumerates the
153 * attributes of this element.
154 * @throws ConfigurationException if something wrong occurs during the
155 * operation.
156 */
157 public abstract Collection getAttributeNames() throws ConfigurationException;
158
159 /**
160 * Returns the value of the attribute whose name equals the specified one or
161 * <code>null</code> if the element doesn't contain a such named
162 * attribute.
163 *
164 * @param name the name of the attribute to get.
165 * @return a <code>String</code> instance representing the attribute value
166 * or <code>null</code> if no attribute with the specified name
167 * was found.
168 * @throws ConfigurationException if something wrong occurs during the
169 * operation.
170 */
171 public abstract String getAttribute(String name) throws ConfigurationException;
172
173 /**
174 * Returns all the attributes of this element.
175 *
176 * @return an unmodifiable <code>Collection</code> which enumerates the
177 * attributes of this element.
178 * @throws ConfigurationException if something wrong occurs during the
179 * operation.
180 */
181 public abstract Collection getAttributes() throws ConfigurationException;
182
183 /**
184 * Returns an unmodifiable <code>Collection</code> build on the attribute
185 * value parsed as a comma separated list.
186 *
187 * @param name the name of the attribute whose value will be parsed as a
188 * comma separated list.
189 * @return an unmodifiable <code>Collection</code> which enumerates the
190 * attribute values parsed as a comma separated list.
191 * @throws ConfigurationException if something wrong occurs during the
192 * operation.
193 */
194 public Collection getAttributeValues(String name) throws ConfigurationException {
195 String values = this.getAttribute(name);
196 if (values == null) {
197 return Collections.EMPTY_LIST;
198 } else {
199 Collection list = new ArrayList();
200 StringTokenizer tokenizer = new StringTokenizer(values, ",");
201 while (tokenizer.hasMoreTokens()) {
202 list.add(tokenizer.nextToken().trim());
203 }
204 return list;
205 }
206 }
207
208 /**
209 * Returns the element content as a string.
210 *
211 * @return the characters contained between the tag boundaries.
212 * @throws ConfigurationException if the content couldn't be retrieved.
213 */
214 public abstract String getContent() throws ConfigurationException;
215
216 /**
217 * Resolves the element reference.
218 *
219 * @throws ConfigurationException if something wrong occurs during the
220 * operation.
221 */
222 public abstract void resolve() throws ConfigurationException;
223
224 /**
225 * @see java.lang.Object#toString()
226 */
227 public String toString() {
228 try {
229 StringBuffer result = new StringBuffer();
230 result.append('<');
231 result.append(this.name);
232 Iterator attributes = this.getAttributes().iterator();
233 while (attributes.hasNext()) {
234 Map.Entry entry = (Map.Entry)attributes.next();
235 result.append(' ');
236 result.append(entry.getKey());
237 result.append("='");
238 result.append(entry.getValue());
239 result.append("'");
240 }
241 result.append(">");
242 String content = this.getContent();
243 if (content != null) {
244 result.append(content);
245 }
246 Iterator elements = this.getElements().iterator();
247 while (elements.hasNext()) {
248 result.append(elements.next().toString());
249 }
250 result.append("</");
251 result.append(this.name);
252 result.append(">");
253 return result.toString();
254 } catch (ConfigurationException ce) {
255 return ce.toString();
256 }
257 }
258 }