001 /* 002 * Common usable utilities 003 * 004 * Copyright (c) 2006 Petr Hadraba <hadrabap@gmail.com> 005 * 006 * Author: Petr Hadraba 007 * 008 * -- 009 * 010 * XML Utilities 011 */ 012 013 package global.sandbox.xmlutilities; 014 015 import java.util.ArrayList; 016 import java.util.Collection; 017 import java.util.Collections; 018 import java.util.Iterator; 019 import java.util.List; 020 import java.util.ListIterator; 021 import java.util.logging.Level; 022 import java.util.logging.Logger; 023 import org.w3c.dom.Node; 024 import org.w3c.dom.NodeList; 025 026 /** 027 * {@link ArrayList ArrayList} like implementation for {@link NodeList NodeList} which is unmodifiable, not serializable 028 * and exposes access to original {@link NodeList NodeList}. The under-layering implementation is based on a copy, 029 * modifications made to the original {@link NodeList NodeList} have no effect to iterators. 030 * 031 * The name of this class has been chosen in respect to possible collision with {@link NodeList org.w3c.dom.NodeList} 032 * which may occur during import. 033 * 034 * @param <E> element type 035 * 036 * @author Petr Hadraba 037 * 038 * @version 1.2 039 */ 040 public class NodeListCollection<E extends Node> implements List<E> { 041 042 /** 043 * Logger. 044 */ 045 private static final Logger LOGGER = Logger.getLogger(XmlUtilities.XMLUTILITIES_LOGGER_NAME); 046 047 /** 048 * Class type of elements. 049 */ 050 private final Class<E> elementType; 051 052 /** 053 * Original {@link NodeList NodeList}. 054 */ 055 private final NodeList nodeList; 056 057 /** 058 * Unmodifiable implementation. 059 */ 060 private final List<E> nodes; 061 062 /** 063 * Creates new instance from {@link NodeList NodeList}. The under-layering implementation is constant, read only, 064 * unmodifiable. The implementation is intentionally not serializable. 065 * 066 * @param nodeList under-layering {@link NodeList NodeList} 067 * @param elementType class type of element 068 * 069 * @throws XmlUtilitiesException on error (casting, data type conversion) 070 */ 071 @SuppressWarnings("unchecked") 072 public NodeListCollection(NodeList nodeList, Class<E> elementType) throws XmlUtilitiesException { 073 this.elementType = elementType; 074 this.nodeList = nodeList; 075 076 if (nodeList != null && nodeList.getLength() > 0) { 077 List<E> _nodes = new ArrayList<E>(); 078 for (int i = 0; i < nodeList.getLength(); i++) { 079 final Node node = nodeList.item(i); 080 final E element; 081 try { 082 element = elementType.cast(node); 083 } catch (ClassCastException ex) { 084 final String message = String.format("Failed to cast element at index %d from %s to %s.", i, node.getClass(), elementType); 085 LOGGER.log(Level.SEVERE, message, ex); 086 throw new XmlUtilitiesException(message, ex); 087 } 088 _nodes.add(element); 089 } 090 this.nodes = Collections.unmodifiableList(_nodes); 091 } else { 092 this.nodes = Collections.unmodifiableList(Collections.EMPTY_LIST); 093 } 094 } 095 096 /** 097 * Returns class type of element. 098 * 099 * @return class type of element 100 */ 101 public Class<E> getElementType() { 102 return elementType; 103 } 104 105 /** 106 * Returns under-layering {@link NodeList NodeList}. 107 * 108 * @return under-layering {@link NodeList NodeList} 109 */ 110 public NodeList getNodeList() { 111 return nodeList; 112 } 113 114 /** 115 * {@inheritDoc} 116 */ 117 @Override 118 public int size() { 119 return nodes.size(); 120 } 121 122 /** 123 * {@inheritDoc} 124 */ 125 @Override 126 public boolean isEmpty() { 127 return nodes.isEmpty(); 128 } 129 130 /** 131 * {@inheritDoc} 132 */ 133 @Override 134 public boolean contains(Object o) { 135 return nodes.contains(o); 136 } 137 138 /** 139 * {@inheritDoc} 140 */ 141 @Override 142 public Iterator<E> iterator() { 143 return nodes.iterator(); 144 } 145 146 /** 147 * {@inheritDoc} 148 */ 149 @Override 150 public Object[] toArray() { 151 return nodes.toArray(); 152 } 153 154 /** 155 * {@inheritDoc} 156 */ 157 @Override 158 public <T> T[] toArray(T[] a) { 159 return nodes.<T>toArray(a); 160 } 161 162 /** 163 * {@inheritDoc} 164 */ 165 @Override 166 public boolean add(E e) { 167 return nodes.add(e); 168 } 169 170 /** 171 * {@inheritDoc} 172 */ 173 @Override 174 public boolean remove(Object o) { 175 return nodes.remove(o); 176 } 177 178 /** 179 * {@inheritDoc} 180 */ 181 @Override 182 public boolean containsAll(Collection<?> c) { 183 return nodes.containsAll(c); 184 } 185 186 /** 187 * {@inheritDoc} 188 */ 189 @Override 190 public boolean addAll(Collection<? extends E> c) { 191 return nodes.addAll(c); 192 } 193 194 /** 195 * {@inheritDoc} 196 */ 197 @Override 198 public boolean addAll(int index, Collection<? extends E> c) { 199 return nodes.addAll(index, c); 200 } 201 202 /** 203 * {@inheritDoc} 204 */ 205 @Override 206 public boolean removeAll(Collection<?> c) { 207 return nodes.removeAll(c); 208 } 209 210 /** 211 * {@inheritDoc} 212 */ 213 @Override 214 public boolean retainAll(Collection<?> c) { 215 return nodes.retainAll(c); 216 } 217 218 /** 219 * {@inheritDoc} 220 */ 221 @Override 222 public void clear() { 223 nodes.clear(); 224 } 225 226 /** 227 * {@inheritDoc} 228 */ 229 @Override 230 public E get(int index) { 231 return nodes.get(index); 232 } 233 234 /** 235 * {@inheritDoc} 236 */ 237 @Override 238 public E set(int index, E element) { 239 return nodes.set(index, element); 240 } 241 242 /** 243 * {@inheritDoc} 244 */ 245 @Override 246 public void add(int index, E element) { 247 nodes.add(index, element); 248 } 249 250 /** 251 * {@inheritDoc} 252 */ 253 @Override 254 public E remove(int index) { 255 return nodes.remove(index); 256 } 257 258 /** 259 * {@inheritDoc} 260 */ 261 @Override 262 public int indexOf(Object o) { 263 return nodes.indexOf(o); 264 } 265 266 /** 267 * {@inheritDoc} 268 */ 269 @Override 270 public int lastIndexOf(Object o) { 271 return nodes.lastIndexOf(o); 272 } 273 274 /** 275 * {@inheritDoc} 276 */ 277 @Override 278 public ListIterator<E> listIterator() { 279 return nodes.listIterator(); 280 } 281 282 /** 283 * {@inheritDoc} 284 */ 285 @Override 286 public ListIterator<E> listIterator(int index) { 287 return nodes.listIterator(index); 288 } 289 290 /** 291 * {@inheritDoc} 292 */ 293 @Override 294 public List<E> subList(int fromIndex, int toIndex) { 295 return nodes.subList(fromIndex, toIndex); 296 } 297 298 /** 299 * {@inheritDoc} 300 */ 301 @Override 302 public boolean equals(Object obj) { 303 return obj == this || nodes.equals(obj); 304 } 305 306 /** 307 * {@inheritDoc} 308 */ 309 @Override 310 public int hashCode() { 311 return nodes.hashCode(); 312 } 313 314 /** 315 * {@inheritDoc} 316 */ 317 @Override 318 public String toString() { 319 return nodes.toString(); 320 } 321 322 }