Skip to content

Instantly share code, notes, and snippets.

@anshdivu
Last active September 20, 2016 14:02
Show Gist options
  • Save anshdivu/0b012631466f9c0ba076 to your computer and use it in GitHub Desktop.
Save anshdivu/0b012631466f9c0ba076 to your computer and use it in GitHub Desktop.
package com.cerner.discovere.xml;
import java.util.Iterator;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* This class is very lightweight wrapper for {@link NodeList} to make it {@link Iterable} so that it can be used with
* the java's for-each loop. Also, it can implicitly convert objects stored in the {@code NodeList} to any class that
* extends {@link Node}.
*
* @author Diviyansh Bhatnagar
*
* @param <T>
* can be any class extending {@link Node}
*/
public class Nodes<T extends Node> implements Iterator<T>, Iterable<T> {
private NodeList nodeList;
private int position;
private int size;
private Nodes(NodeList list) {
this.position = 0;
this.nodeList = list;
this.size = list == null ? 0 : list.getLength();
}
/**
* This method creates a new Nodes object with NodeList as its underlying structure. <br/>
* It safely accepts a null NodeList object and calling the {@link #hasNext()} would return false every time for such
* an object.
*/
public static final <T extends Node> Nodes<T> of(NodeList list) {
return new Nodes<T>(list);
}
public boolean hasNext() {
return size > position;
}
/**
* Returns the next element in the collection. This method should only be called after a call to the
* {@link #hasNext()} method returns true.<br/>
* NOTE: This method internally casts the objects returned by {@link NodeList} to the type of this {@link Nodes}
* object; therefore, it can throw {@link ClassCastException} in case the objects of {@code NodeList} are not
* compatible with the generic type of the {@code Nodes} object.
*
* @throws ClassCastException
* (as explained above)
*/
@SuppressWarnings("unchecked")
public T next() {
if (null == nodeList) {
return null;
}
return (T) nodeList.item(position++);
}
/**
* Every call to this method would throw a {@link UnsupportedOperationException}
*
* @throws UnsupportedOperationException
*/
public void remove() {
throw new UnsupportedOperationException("This class's underlying stucture (i.e. NodeList) does not support remove");
}
public Iterator<T> iterator() {
return this;
}
/**
* @return the size of the underlying {@link NodeList}. Returns 0 if {@link NodeList} is null.
*/
public int size() {
return size;
}
/**
* @return the {@link NodeList} object used to create this object.
*/
public NodeList getNodeList() {
return nodeList;
}
@Override
public String toString() {
return "Nodes [nodeList=" + nodeList + ", position=" + position + ", size=" + size + "]";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment