package com.revolsys.record.io.format.json; import java.io.Closeable; import java.io.IOException; import java.io.Reader; import java.util.Iterator; import java.util.NoSuchElementException; import com.revolsys.collection.map.MapEx; import com.revolsys.record.io.format.json.JsonParser.EventType; public class JsonMapIterator implements Iterator<MapEx>, Closeable { /** The current record. */ private MapEx currentObject; /** Flag indicating if there are more records to be read. */ private boolean hasNext = false; private final JsonParser parser; public JsonMapIterator(final Reader in) throws IOException { this(in, false); } public JsonMapIterator(final Reader in, final boolean single) throws IOException { this.parser = new JsonParser(in); if (single) { this.hasNext = true; readNextRecord(); } else if (this.parser.hasNext()) { EventType event = this.parser.next(); if (event == EventType.startDocument) { if (this.parser.hasNext()) { event = this.parser.next(); if (event == EventType.startObject) { this.parser.getString(); if (this.parser.hasNext()) { event = this.parser.next(); if (event == EventType.colon) { if (this.parser.hasNext()) { event = this.parser.next(); if (event == EventType.startArray) { this.hasNext = true; readNextRecord(); } } } } } else if (event == EventType.startArray) { this.hasNext = true; readNextRecord(); } } } } if (!this.hasNext) { close(); } } @Override public void close() { this.parser.close(); } /** * Returns <tt>true</tt> if the iteration has more elements. * * @return <tt>true</tt> if the iterator has more elements. */ @Override public boolean hasNext() { return this.hasNext; } /** * Return the next record from the iterator. * * @return The record */ @Override public MapEx next() { if (!this.hasNext) { throw new NoSuchElementException("No more elements"); } else { final MapEx object = this.currentObject; readNextRecord(); return object; } } /** * Reads the next line from the buffer and converts to a string array. * * @return a string array with each comma-separated element as a separate * entry. * @throws IOException if bad things happen during the read */ private MapEx readNextRecord() { if (this.hasNext && this.parser.hasNext()) { final EventType event = this.parser.next(); if (event == EventType.endArray || event == EventType.endDocument) { this.hasNext = false; close(); return null; } else { this.currentObject = this.parser.getMap(); return this.currentObject; } } else { this.hasNext = false; close(); return null; } } /** * Removing items from the iterator is not supported. */ @Override public void remove() { throw new UnsupportedOperationException(); } }