001: /* ====================================================================
002: The Jicarilla Software License
003:
004: Copyright (c) 2003 Leo Simons.
005: All rights reserved.
006:
007: Permission is hereby granted, free of charge, to any person obtaining
008: a copy of this software and associated documentation files (the
009: "Software"), to deal in the Software without restriction, including
010: without limitation the rights to use, copy, modify, merge, publish,
011: distribute, sublicense, and/or sell copies of the Software, and to
012: permit persons to whom the Software is furnished to do so, subject to
013: the following conditions:
014:
015: The above copyright notice and this permission notice shall be
016: included in all copies or substantial portions of the Software.
017:
018: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
019: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
020: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
021: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
022: CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
023: TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
024: SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
025: ==================================================================== */
026: package org.jicarilla.collections;
027:
028: import java.io.Serializable;
029: import java.util.ArrayList;
030: import java.util.Collection;
031: import java.util.HashMap;
032: import java.util.Iterator;
033: import java.util.List;
034: import java.util.Map;
035: import java.util.Set;
036:
037: /**
038: * An implementation of Node which is backed by a List. When you
039: * don't provide a backing list, an ArrayList will be used.
040: *
041: * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
042: * @version $Id: DefaultNode.java,v 1.3 2004/02/26 16:51:54 lsimons Exp $
043: */
044: public class DefaultNode implements Node, Cloneable, Serializable {
045: // ----------------------------------------------------------------------
046: // Properties
047: // ----------------------------------------------------------------------
048: private String m_name;
049: private Object m_contents;
050:
051: private Map m_attributes;
052: private List m_children;
053:
054: // ----------------------------------------------------------------------
055: // Constructors
056: // ----------------------------------------------------------------------
057:
058: public DefaultNode(final String name) {
059: this (name, null);
060: }
061:
062: public DefaultNode(final String name, final List children) {
063: this (name, children, null);
064: }
065:
066: public DefaultNode(final String name, final List children,
067: final Map attributes) {
068: if (children == null)
069: m_children = new ArrayList();
070: else
071: m_children = children;
072:
073: if (attributes == null)
074: m_attributes = new HashMap();
075: else
076: m_attributes = attributes;
077:
078: m_name = name;
079: }
080:
081: // ----------------------------------------------------------------------
082: // Class: Object
083: // ----------------------------------------------------------------------
084:
085: public int hashCode() {
086: String name = getName();
087: if (name == null)
088: name = "null";
089: Object contents = getContents();
090: if (contents == null)
091: contents = "null";
092:
093: return name.hashCode() + contents.hashCode()
094: + m_children.hashCode() + m_attributes.hashCode();
095: }
096:
097: public boolean equals(final Object o) {
098: try {
099: // basics
100: if (o == this )
101: return true;
102: if (!(o instanceof Node))
103: return false;
104: final Node n = (Node) o;
105:
106: // complex
107: if (!equalSizes(n) || !equalContents(n) || !equalNames(n)
108: || !equalChildren(n) || !equalAttributes(n))
109: return false;
110:
111: return true;
112: } catch (ClassCastException cce) {
113: return false;
114: } catch (NullPointerException npe) {
115: return false;
116: }
117: }
118:
119: protected boolean equalAttributes(final Node n) {
120: if (entrySet().size() != n.entrySet().size())
121: return false;
122:
123: final Iterator it = entrySet().iterator();
124: while (it.hasNext()) {
125: final Map.Entry entry = (Map.Entry) it.next();
126: final Object value = entry.getValue();
127: final Object key = entry.getKey();
128:
129: if (value != null) {
130: if (!value.equals(n.get(key)))
131: return false;
132: } else {
133: //if( !(n.containsKey(key) && n.get(key) == null) )
134: if (!(n.get(key) == null))
135: return false;
136: }
137: }
138:
139: return true;
140: }
141:
142: protected boolean equalChildren(final Node n) {
143: final List myChildren = childrenToList();
144: final List otherChildren = n.childrenToList();
145:
146: /* this is equalSizes()!
147: final boolean equalSizes = (myChildren.size() == otherChildren.size());
148: if( !equalSizes )
149: return false;*/
150:
151: final boolean equalLists = (myChildren.equals(otherChildren));
152: if (!equalLists)
153: return false;
154:
155: return true;
156: }
157:
158: protected boolean equalNames(final Node n) {
159: boolean result = true;
160:
161: if (getName() != null) {
162: if (!getName().equals(n.getName()))
163: result = false;
164: } else {
165: if (n.getName() != null)
166: result = false;
167: }
168: return result;
169: }
170:
171: protected boolean equalContents(final Node n) {
172: boolean result = true;
173: if (getContents() != null) {
174: if (!getContents().equals(n.getContents()))
175: result = false;
176: } else {
177: if (n.getContents() != null)
178: result = false;
179: }
180: return result;
181: }
182:
183: protected boolean equalSizes(final Node n) {
184: return n.size() == size();
185: }
186:
187: // ----------------------------------------------------------------------
188: // Interface: Node / Map
189: // ----------------------------------------------------------------------
190:
191: public int size() {
192: return m_children.size();
193: }
194:
195: public boolean isEmpty() {
196: return m_attributes.isEmpty() && m_children.isEmpty();
197: }
198:
199: public void clear() {
200: m_attributes.clear();
201: m_children.clear();
202: m_name = null;
203: m_contents = null;
204: }
205:
206: // ----------------------------------------------------------------------
207: // Interface: Node
208: // ----------------------------------------------------------------------
209:
210: public String getName() {
211: return m_name;
212: }
213:
214: public String setName(final String s) {
215: final String old = getName();
216: m_name = s;
217: return old;
218: }
219:
220: public Object getContents() {
221: return m_contents;
222: }
223:
224: public Object setContents(final Object o) {
225: final Object old = getContents();
226: m_contents = o;
227: return old;
228: }
229:
230: // ----------------------------------------------------------------------
231: // Interface: Node / List
232: // ----------------------------------------------------------------------
233:
234: public boolean addChild(final Node n) {
235: return m_children.add(n);
236: }
237:
238: public boolean addChildren(final Collection c) {
239: return m_children.addAll(c);
240: }
241:
242: public boolean containsChild(final Node n) {
243: return m_children.contains(n);
244: }
245:
246: public boolean containsChildren(final Collection c) {
247: return m_children.containsAll(c);
248: }
249:
250: public Node[] childrenToArray() {
251: return (Node[]) m_children.toArray(new Node[m_children.size()]);
252: }
253:
254: public Node[] childrenToArray(final Object[] o) {
255: return (Node[]) m_children.toArray(o);
256: }
257:
258: public List childrenToList() {
259: return m_children;
260: }
261:
262: public Iterator iterator() {
263: return m_children.iterator();
264: }
265:
266: public boolean removeChild(final Node n) {
267: return m_children.remove(n);
268: }
269:
270: public boolean removeChildren(final Collection c) {
271: return m_children.removeAll(c);
272: }
273:
274: // ----------------------------------------------------------------------
275: // Interface: Map
276: // ----------------------------------------------------------------------
277:
278: public boolean containsKey(final Object key) {
279: return m_attributes.containsKey(key);
280: }
281:
282: public boolean containsValue(final Object value) {
283: return m_attributes.containsValue(value);
284: }
285:
286: public Object get(final Object key) {
287: return m_attributes.get(key);
288: }
289:
290: public Object put(final Object key, final Object value) {
291: return m_attributes.put(key, value);
292: }
293:
294: public Object remove(final Object key) {
295: return m_attributes.remove(key);
296: }
297:
298: public void putAll(final Map t) {
299: m_attributes.putAll(t);
300: }
301:
302: public Set keySet() {
303: return m_attributes.keySet();
304: }
305:
306: public Collection values() {
307: return m_attributes.values();
308: }
309:
310: public Set entrySet() {
311: return m_attributes.entrySet();
312: }
313:
314: }
|