View Javadoc

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.HashMap;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Map;
32  
33  import org.xml.sax.Attributes;
34  
35  /**
36   * @author rlogiacco
37   */
38  public class Node extends Element {
39  
40  	/**
41  	 * The node sub elements.
42  	 * 
43  	 * @link aggregation
44  	 * @associates <{Element}>
45  	 */
46  	protected List children;
47  
48  	/**
49  	 * The node attributes.
50  	 * 
51  	 * @link aggregation
52  	 * @associates <{Attribute}>
53  	 */
54  	protected Map attributes = new HashMap();
55  
56  	/**
57  	 * The node direct contents.
58  	 * 
59  	 * @uml.property name="content"
60  	 */
61  	protected String content;
62  
63  	/**
64  	 * Marks this node as already resolved for references.
65  	 */
66  	protected boolean resolved;
67  
68  
69  	/**
70  	 * Constructs a generic empty node.
71  	 * 
72  	 * @param parent the node containing this node.
73  	 * @param name a name associated to this node.
74  	 * @param attributes a set of attributes associated with this node.
75  	 */
76  	protected Node(Node parent, String name, Attributes attributes) {
77  		super(parent, name);
78  		this.children = new ArrayList();
79  		if (attributes != null) {
80  			for (int i = 0; i < attributes.getLength(); i++) {
81  				this.attributes.put(attributes.getQName(i), attributes.getValue(i));
82  			}
83  		}
84  	}
85  
86  	/**
87  	 * @see net.smartlab.config.Element#getId()
88  	 */
89  	public String getId() {
90  		return (String)attributes.get(Reference.IDENTIFIER);
91  	}
92  
93  	/**
94  	 * @see net.smartlab.config.Element#getElements()
95  	 */
96  	public Collection getElements() {
97  		return Collections.unmodifiableCollection(children);
98  	}
99  
100 	/**
101 	 * @see net.smartlab.config.Element#getElements(java.lang.String)
102 	 */
103 	public Collection getElements(String name) {
104 		List result = new ArrayList();
105 		if (name != null) {
106 			Iterator children = this.children.iterator();
107 			while (children.hasNext()) {
108 				Element child = (Element)children.next();
109 				if (name.equals(child.getName())) {
110 					result.add(child);
111 				}
112 			}
113 		}
114 		return Collections.unmodifiableCollection(result);
115 	}
116 
117 	/**
118 	 * @see net.smartlab.config.Element#getElement(java.lang.String,
119 	 *      java.lang.String, java.lang.String)
120 	 */
121 	public Element getElement(String name, String attribute, String value) throws ConfigurationException {
122 		Iterator children = this.children.iterator();
123 		while (children.hasNext()) {
124 			Element child = (Element)children.next();
125 			if (name != null && name.equals(child.name)) {
126 				if (attribute != null) {
127 					String found = child.getAttribute(attribute);
128 					if (found != null) {
129 						if (value != null) {
130 							if (value.equals(found)) {
131 								return child;
132 							}
133 						} else {
134 							return child;
135 						}
136 					}
137 				} else {
138 					return child;
139 				}
140 			}
141 		}
142 		return null;
143 	}
144 
145 	/**
146 	 * @see net.smartlab.config.Element#getAttributeNames()
147 	 */
148 	public Collection getAttributeNames() {
149 		return Collections.unmodifiableCollection(attributes.keySet());
150 	}
151 
152 	/**
153 	 * @see net.smartlab.config.Element#getAttributes()
154 	 */
155 	public Collection getAttributes() {
156 		return Collections.unmodifiableCollection(attributes.entrySet());
157 	}
158 
159 	/**
160 	 * @see net.smartlab.config.Element#getAttribute(java.lang.String)
161 	 */
162 	public String getAttribute(String name) {
163 		return (String)attributes.get(name);
164 	}
165 
166 	/**
167 	 * @see net.smartlab.config.Element#getContent()
168 	 * @uml.property name="content"
169 	 */
170 	public String getContent() {
171 		return content;
172 	}
173 
174 	/**
175 	 * Sets the content.
176 	 * 
177 	 * @param content the content to set
178 	 */
179 	protected void setContent(String content) {
180 		if (content.replace('\n', ' ').replace('\t', ' ').trim().length() > 0) {
181 			this.content = content;
182 		}
183 	}
184 
185 	/**
186 	 * @see net.smartlab.config.Element#resolve()
187 	 */
188 	public void resolve() throws ConfigurationException {
189 		if (!resolved) {
190 			Iterator elements = children.iterator();
191 			while (elements.hasNext()) {
192 				((Element)elements.next()).resolve();
193 			}
194 			resolved = true;
195 		}
196 	}
197 
198 	/**
199 	 * Resolves the requested reference through its children nodes or,
200 	 * recursively in the parent node children.
201 	 * 
202 	 * @param name the referenced element name.
203 	 * @param id the referenced element identifier.
204 	 * @return the referenced element.
205 	 * @throws ConfigurationException if the referenced element cannot be found
206 	 *         in the wntire configuration tree.
207 	 */
208 	protected Node resolve(String name, String id) throws ConfigurationException {
209 		Iterator children = this.children.iterator();
210 		while (children.hasNext()) {
211 			Element child = (Element)children.next();
212 			if (child instanceof Node && name.equals(child.name) && id.equals(child.getId())) {
213 				return (Node)child;
214 			}
215 		}
216 		return parent.resolve(name, id);
217 	}
218 }