package gr.ntua.ivml.mint.xml; import gr.ntua.ivml.mint.persistent.DataUpload; import gr.ntua.ivml.mint.persistent.Publication; import gr.ntua.ivml.mint.persistent.Transformation; import gr.ntua.ivml.mint.persistent.XMLNode; import gr.ntua.ivml.mint.persistent.XmlObject; import gr.ntua.ivml.mint.persistent.XmlSchema; import gr.ntua.ivml.mint.persistent.XpathHolder; import java.util.Iterator; import java.util.List; public class PathIterator implements Iterator<XMLNode> { private static final XMLNode[] templatePage = new XMLNode[0]; Iterator<XmlObject> iterXmlObj; XmlObject currentXmlObj; String path; XpathHolder currentHolder; XMLNode nextItem; XMLNode[] page; int nextInPage; // Helper. Not strictly needed here public static PathIterator fromTransformations( List<Transformation> l, String path ) { final Iterator<Transformation> iterTransformation = l.iterator(); Iterator<XmlObject> iterXml = new Iterator<XmlObject>() { @Override public boolean hasNext() { return iterTransformation.hasNext(); } @Override public XmlObject next() { Transformation t = iterTransformation.next(); return t.getParsedOutput(); } @Override public void remove() { throw new UnsupportedOperationException(); } }; return new PathIterator( iterXml, path ); } // create an iterator over the items for an upload public static PathIterator fromUpload( DataUpload du ) { final XmlObject obj = du.getXmlObject(); String path = du.getItemXpath().getXpath(); Iterator<XmlObject> iter = new Iterator<XmlObject>() { boolean hasNext = true; @Override public boolean hasNext() { return hasNext; } @Override public XmlObject next() { if( hasNext ) { hasNext = false; return obj; } return null; } @Override public void remove() { throw new UnsupportedOperationException(); } }; return new PathIterator( iter, path ); } // create an iterator over the items for a transformation public static PathIterator fromTransform( Transformation t , XmlSchema xsch) { final XmlObject obj = t.getParsedOutput(); String path = xsch.getItemPath(); Iterator<XmlObject> iter = new Iterator<XmlObject>() { boolean hasNext = true; @Override public boolean hasNext() { return hasNext; } @Override public XmlObject next() { if( hasNext ) { hasNext = false; return obj; } return null; } @Override public void remove() { throw new UnsupportedOperationException(); } }; return new PathIterator( iter, path ); } public PathIterator( Iterator<XmlObject> iter, String path ) { this.iterXmlObj = iter; this.path = path; next(); } public PathIterator( List<XmlObject> l, String path ) { iterXmlObj = l.iterator(); this.path = path; next(); } @Override public boolean hasNext() { return nextItem != null; } private boolean nextHolder() { if( iterXmlObj.hasNext() ) { currentXmlObj = iterXmlObj.next(); currentHolder = currentXmlObj.getRoot().getByRelativePath(path); if( currentHolder != null ) Publication.log.debug( "Current transformation has " + currentHolder.getCount() + " items." ); } else { currentHolder = null; } return currentHolder != null; } /** * Retrieve next page from current holder or first from next * @return if there is stuff left */ private boolean nextPage() { List<XMLNode> l = null; if( page != null ) l= currentHolder.getNodes( page[page.length-1], 100); if(( page== null ) || ( l.size() == 0 )) { nextHolder(); if( currentHolder == null ) return false; l= currentHolder.getNodes( 0, 100); if( l.size() == 0 ) throw new RuntimeException( "Unexpected result, should have nodes"); } page = l.toArray(templatePage); nextInPage = 0; return true; } private XMLNode nextInPage() { XMLNode result=null; if(( page==null ) || ( nextInPage==page.length )) { if( ! nextPage()) return null; } result = page[nextInPage]; nextInPage+=1; return result; } @Override public XMLNode next() { XMLNode result = nextItem; nextItem = nextInPage(); return result; } @Override public void remove() { throw new UnsupportedOperationException(); } }