From 9b97d11e5f1e87a136067aa185e526d06cb14f75 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 8 Apr 2009 06:03:23 +0000 Subject: [PATCH] SilkStreamReader done. git-svn-id: http://www.xerial.org/svn/project/XerialJ/trunk/xerial-core@3177 ae02f08e-27ec-0310-ae8c-8ba02fe2eafd --- .../java/org/xerial/json/JSONStreamReader.java | 51 +++++++++++++------ src/main/java/org/xerial/silk/SilkEnv.java | 5 ++ .../java/org/xerial/silk/SilkStreamReader.java | 29 +++++++++++ src/main/java/org/xerial/silk/plugin/Import.java | 57 +++++++++++++++++++--- .../org/xerial/silk/plugin/SilkFunctionPlugin.java | 12 +---- .../org/xerial/util/tree/TreeStreamReader.java | 8 +++ .../java/org/xerial/util/tree/TreeWalkerImpl.java | 12 ++--- .../java/org/xerial/util/xml/DOMStreamReader.java | 24 +++++++++ .../java/org/xerial/util/xml/XMLStreamReader.java | 15 ++++++ .../org/xerial/util/xml/impl/TreeEventQueue.java | 5 ++ 10 files changed, 181 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/xerial/json/JSONStreamReader.java b/src/main/java/org/xerial/json/JSONStreamReader.java index f5588fd..8db6840 100644 --- a/src/main/java/org/xerial/json/JSONStreamReader.java +++ b/src/main/java/org/xerial/json/JSONStreamReader.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.io.Reader; import org.xerial.core.XerialException; +import org.xerial.util.ArrayDeque; import org.xerial.util.log.Logger; import org.xerial.util.tree.TreeEvent; import org.xerial.util.tree.TreeStreamReader; @@ -48,18 +49,33 @@ public class JSONStreamReader implements TreeStreamReader private final TreeEventQueue eventQueue = new TreeEventQueue(); private JSONEvent lastEvent = null; + private ArrayDeque pendingEventQueue = new ArrayDeque(); + public JSONStreamReader(Reader jsonStream) throws IOException { jsonPullParser = new JSONPullParser(jsonStream); } + public TreeEvent peekNext() throws XerialException + { + if (!eventQueue.isEmpty()) + { + return eventQueue.peekFirst(); + } + + if (lastEvent == JSONEvent.EndJSON) + return null; + + readNext(); + + return peekNext(); + } + public TreeEvent next() throws XerialException { if (!eventQueue.isEmpty()) { TreeEvent e = eventQueue.pop(); - // if (_logger.isTraceEnabled()) - // _logger.trace(e); return e; } @@ -69,6 +85,14 @@ public class JSONStreamReader implements TreeStreamReader readNext(); return next(); + + } + + private void flushPendingEvent() + { + while (!pendingEventQueue.isEmpty()) + eventQueue.push(pendingEventQueue.removeFirst()); + } private void readNext() throws XerialException @@ -81,12 +105,15 @@ public class JSONStreamReader implements TreeStreamReader { case StartObject: { + flushPendingEvent(); + String key = jsonPullParser.getKeyName(); - eventQueue.push(TreeEvent.newVisitEvent(key, null)); + pendingEventQueue.addLast(TreeEvent.newVisitEvent(key, null)); break; } case EndObject: { + flushPendingEvent(); String key = jsonPullParser.getKeyName(); eventQueue.push(TreeEvent.newLeaveEvent(key)); break; @@ -95,32 +122,28 @@ public class JSONStreamReader implements TreeStreamReader case Integer: case Double: case Boolean: + case Null: { String key = jsonPullParser.getKeyName(); - String value = jsonPullParser.getText(); + String value = lastEvent != JSONEvent.Null ? jsonPullParser.getText() : null; // if first child element is value attribute - if (key.equals("value") && !eventQueue.isEmpty()) + if (key.equals("value") && !pendingEventQueue.isEmpty()) { - TreeEvent e = eventQueue.peekLast(); + TreeEvent e = pendingEventQueue.peekLast(); if (e.event == EventType.VISIT) { - eventQueue.replaceLast(TreeEvent.newVisitEvent(e.nodeName, value)); + pendingEventQueue.removeLast(); + pendingEventQueue.addLast(TreeEvent.newVisitEvent(e.nodeName, value)); break; } } + flushPendingEvent(); eventQueue.push(TreeEvent.newVisitEvent(key, value)); eventQueue.push(TreeEvent.newLeaveEvent(key)); break; } - case Null: - { - String key = jsonPullParser.getKeyName(); - eventQueue.push(TreeEvent.newVisitEvent(key, null)); - eventQueue.push(TreeEvent.newLeaveEvent(key)); - break; - } case StartArray: case EndArray: case EndJSON: diff --git a/src/main/java/org/xerial/silk/SilkEnv.java b/src/main/java/org/xerial/silk/SilkEnv.java index ff42f9b..6b4b1b6 100644 --- a/src/main/java/org/xerial/silk/SilkEnv.java +++ b/src/main/java/org/xerial/silk/SilkEnv.java @@ -202,4 +202,9 @@ public class SilkEnv return contextNodeStack.getLast().contextNode; } + public TreeEvent peekFirstEvent() + { + return eventQueue.peekFirst(); + } + } diff --git a/src/main/java/org/xerial/silk/SilkStreamReader.java b/src/main/java/org/xerial/silk/SilkStreamReader.java index dfe2db9..f044f5d 100644 --- a/src/main/java/org/xerial/silk/SilkStreamReader.java +++ b/src/main/java/org/xerial/silk/SilkStreamReader.java @@ -165,6 +165,30 @@ public class SilkStreamReader implements TreeStreamReader this.parseContext = SilkEnv.newEnv(env, resourceBasePath); } + public TreeEvent peekNext() throws XerialException + { + if (readerStack.isEmpty()) + { + if (hasNext()) + return parseContext.peekFirstEvent(); + else + return null; + } + else + { + TreeStreamReader reader = readerStack.peekLast(); + TreeEvent e = reader.peekNext(); + if (e == null) + { + readerStack.removeLast(); + return peekNext(); + } + else + return e; + } + + } + public TreeEvent next() throws XerialException { if (readerStack.isEmpty()) @@ -364,6 +388,11 @@ public class SilkStreamReader implements TreeStreamReader this.plugin = plugin; } + public TreeEvent peekNext() throws XerialException + { + return plugin.peekNext(); + } + public TreeEvent next() throws XerialException { return plugin.next(); diff --git a/src/main/java/org/xerial/silk/plugin/Import.java b/src/main/java/org/xerial/silk/plugin/Import.java index c4110a3..d935540 100644 --- a/src/main/java/org/xerial/silk/plugin/Import.java +++ b/src/main/java/org/xerial/silk/plugin/Import.java @@ -56,10 +56,32 @@ public class Import implements SilkFunctionPlugin private TreeStreamReader reader = null; private SilkEnv env; + private static class EmptyReader implements TreeStreamReader + { + + public TreeEvent next() throws XerialException + { + return null; + } + + public TreeEvent peekNext() throws XerialException + { + return null; + } + + } + public void init(SilkEnv env) throws XerialException { this.env = env; + if (filePath == null) + { + env.getLogger().warn("no file path is specified"); + reader = new EmptyReader(); + return; + } + try { String url = env.getResourceBasePath(); @@ -104,20 +126,25 @@ public class Import implements SilkFunctionPlugin } - public TreeEvent next() throws XerialException + private void validate() { if (env == null) throw new XerialError(XerialErrorCode.INVALID_STATE, "env is null"); - if (filePath == null) - { - env.getLogger().warn("no file path is specified"); - return null; - } - if (reader == null) throw new XerialError(XerialErrorCode.NOT_INITIALIZED); + } + + public TreeEvent peekNext() throws XerialException + { + validate(); + return reader.peekNext(); + } + + public TreeEvent next() throws XerialException + { + validate(); return reader.next(); } @@ -152,6 +179,22 @@ public class Import implements SilkFunctionPlugin } } + public TreeEvent peekNext() throws XerialException + { + if (eventQueue.isEmpty()) + { + if (hasFinished) + return null; + + fillQueue(); + return peekNext(); + } + else + { + return eventQueue.peekFirst(); + } + } + public TreeEvent next() throws XerialException { if (eventQueue.isEmpty()) diff --git a/src/main/java/org/xerial/silk/plugin/SilkFunctionPlugin.java b/src/main/java/org/xerial/silk/plugin/SilkFunctionPlugin.java index b8f690a..68d22e5 100644 --- a/src/main/java/org/xerial/silk/plugin/SilkFunctionPlugin.java +++ b/src/main/java/org/xerial/silk/plugin/SilkFunctionPlugin.java @@ -26,7 +26,7 @@ package org.xerial.silk.plugin; import org.xerial.core.XerialException; import org.xerial.silk.SilkEnv; -import org.xerial.util.tree.TreeEvent; +import org.xerial.util.tree.TreeStreamReader; /** * The common interface of pluggable functions that can be used in Silk format. @@ -34,7 +34,7 @@ import org.xerial.util.tree.TreeEvent; * @author leo * */ -public interface SilkFunctionPlugin +public interface SilkFunctionPlugin extends TreeStreamReader { /** * @param env @@ -43,12 +43,4 @@ public interface SilkFunctionPlugin */ public void init(SilkEnv env) throws XerialException; - /** - * Retrieves a next stream event. - * - * @return next tree event, or null when no more events - * @throws XerialException - */ - public TreeEvent next() throws XerialException; - } diff --git a/src/main/java/org/xerial/util/tree/TreeStreamReader.java b/src/main/java/org/xerial/util/tree/TreeStreamReader.java index 7f00c3c..ece0f9d 100644 --- a/src/main/java/org/xerial/util/tree/TreeStreamReader.java +++ b/src/main/java/org/xerial/util/tree/TreeStreamReader.java @@ -46,6 +46,14 @@ import org.xerial.core.XerialException; public interface TreeStreamReader { /** + * Peek the next event from the tree stream without moving the cursor + * + * @return next event + * @throws XerialException + */ + public TreeEvent peekNext() throws XerialException; + + /** * Fetches the next event from the tree stream * * @return next event or null if no more event exists diff --git a/src/main/java/org/xerial/util/tree/TreeWalkerImpl.java b/src/main/java/org/xerial/util/tree/TreeWalkerImpl.java index 9b2de15..088a186 100644 --- a/src/main/java/org/xerial/util/tree/TreeWalkerImpl.java +++ b/src/main/java/org/xerial/util/tree/TreeWalkerImpl.java @@ -95,7 +95,7 @@ public class TreeWalkerImpl implements TreeWalker TreeBuilder builder = new TreeBuilder(last); TreeEvent e = null; - while ((e = walker.next()) != null) + while ((e = walker.peekNext()) != null) { switch (e.event) { @@ -104,18 +104,18 @@ public class TreeWalkerImpl implements TreeWalker builder.startNode(e); break; case LEAVE: - builder.endNode(e); currentLevel--; - if (currentLevel == base) - { + if (currentLevel < base) return builder.root; - } - + else + builder.endNode(e); break; case TEXT: builder.text(e); break; } + + walker.next(); } return builder.root; diff --git a/src/main/java/org/xerial/util/xml/DOMStreamReader.java b/src/main/java/org/xerial/util/xml/DOMStreamReader.java index 4b31479..6e081f0 100644 --- a/src/main/java/org/xerial/util/xml/DOMStreamReader.java +++ b/src/main/java/org/xerial/util/xml/DOMStreamReader.java @@ -107,6 +107,30 @@ public class DOMStreamReader implements TreeStreamReader contextStack.addLast(new Context(element)); } + public TreeEvent peekNext() throws XerialException + { + if (!eventQueue.isEmpty()) + { + return eventQueue.peekFirst(); + } + + if (contextStack.isEmpty()) + return null; + + if (!contextStack.isEmpty()) + { + Context context = contextStack.getLast(); + if (context.hasFinished()) + { + contextStack.removeLast(); + return peekNext(); + } + parse(context); + } + + return peekNext(); + } + public TreeEvent next() throws XerialException { if (!eventQueue.isEmpty()) diff --git a/src/main/java/org/xerial/util/xml/XMLStreamReader.java b/src/main/java/org/xerial/util/xml/XMLStreamReader.java index 945376f..03592a4 100644 --- a/src/main/java/org/xerial/util/xml/XMLStreamReader.java +++ b/src/main/java/org/xerial/util/xml/XMLStreamReader.java @@ -67,6 +67,21 @@ public class XMLStreamReader implements TreeStreamReader } + public TreeEvent peekNext() throws XerialException + { + if (!eventQueue.isEmpty()) + { + return eventQueue.peekFirst(); + } + + if (parseState == END_DOCUMENT) + return null; + + readNext(); + + return peekNext(); + } + public TreeEvent next() throws XerialException { if (!eventQueue.isEmpty()) diff --git a/src/main/java/org/xerial/util/xml/impl/TreeEventQueue.java b/src/main/java/org/xerial/util/xml/impl/TreeEventQueue.java index 2c07480..6e027c2 100644 --- a/src/main/java/org/xerial/util/xml/impl/TreeEventQueue.java +++ b/src/main/java/org/xerial/util/xml/impl/TreeEventQueue.java @@ -59,6 +59,11 @@ public class TreeEventQueue eventQueue.addLast(e); } + public TreeEvent peekFirst() + { + return eventQueue.peekFirst(); + } + public TreeEvent peekLast() { return eventQueue.peekLast(); -- 2.11.0