OSDN Git Service

SilkWriter
authorleo <leo@ae02f08e-27ec-0310-ae8c-8ba02fe2eafd>
Fri, 31 Jul 2009 05:34:34 +0000 (05:34 +0000)
committerleo <leo@ae02f08e-27ec-0310-ae8c-8ba02fe2eafd>
Fri, 31 Jul 2009 05:34:34 +0000 (05:34 +0000)
git-svn-id: http://www.xerial.org/svn/project/XerialJ/trunk/xerial-core@3503 ae02f08e-27ec-0310-ae8c-8ba02fe2eafd

src/main/java/org/xerial/lens/XMLSilkLens.java
src/main/java/org/xerial/silk/SilkPullParser.java
src/main/java/org/xerial/silk/SilkWriter.java
src/main/java/org/xerial/silk/impl/SilkNodeParser.java
src/test/java/org/xerial/lens/XMLSilkLensTest.java
src/test/java/org/xerial/silk/SilkWriterTest.java
src/test/java/org/xerial/silk/TreeWalkLog.java

index e4c859a..38ad521 100644 (file)
@@ -61,6 +61,12 @@ public class XMLSilkLens {
                 this.tagName = tagName;\r
                 this.attribute = attribute;\r
             }\r
+\r
+            @Override\r
+            public String toString() {\r
+                return String.format("%s (%s) : %s", tagName, attribute.toXMLString(), textBuf\r
+                        .toString());\r
+            }\r
         }\r
 \r
         private ArrayDeque<TagContext> contextStack = new ArrayDeque<TagContext>();\r
@@ -71,8 +77,8 @@ public class XMLSilkLens {
         }\r
 \r
         public void characters(char[] ch, int start, int length) throws SAXException {\r
-            TagContext tc = contextStack.isEmpty() ? unopendContextStack.getLast() : contextStack\r
-                    .getLast();\r
+            TagContext tc = unopendContextStack.isEmpty() ? contextStack.getLast()\r
+                    : unopendContextStack.getLast();\r
             tc.textBuf.append(ch, start, length);\r
 \r
         }\r
index 2830a87..72cd156 100644 (file)
@@ -49,12 +49,12 @@ import org.xerial.util.tree.TreeStreamReader;
  * @author leo\r
  * \r
  */\r
-public class SilkPullParser implements TreeStreamReader\r
-{\r
+public class SilkPullParser implements TreeStreamReader {\r
     private static Logger _logger = Logger.getLogger(SilkPullParser.class);\r
 \r
     private final SilkParser parser;\r
-    private final ArrayBlockingQueue<TreeEvent> eventQueue = new ArrayBlockingQueue<TreeEvent>(10000);\r
+    private final ArrayBlockingQueue<TreeEvent> eventQueue = new ArrayBlockingQueue<TreeEvent>(\r
+            10000);\r
     private final ArrayDeque<TreeEvent> prefetchedEventQueue = new ArrayDeque<TreeEvent>();\r
 \r
     private long numReadLine = 0;\r
@@ -68,8 +68,7 @@ public class SilkPullParser implements TreeStreamReader
      * @param input\r
      *            `@throws IOException\r
      */\r
-    protected SilkPullParser(InputStream input) throws IOException\r
-    {\r
+    protected SilkPullParser(InputStream input) throws IOException {\r
         this(new InputStreamReader(input));\r
     }\r
 \r
@@ -79,13 +78,11 @@ public class SilkPullParser implements TreeStreamReader
      * @param input\r
      * @throws IOException\r
      */\r
-    protected SilkPullParser(Reader input) throws IOException\r
-    {\r
+    protected SilkPullParser(Reader input) throws IOException {\r
         this(input, SilkEnv.newEnv(), new SilkParserConfig());\r
     }\r
 \r
-    public SilkPullParser(Reader input, SilkEnv env) throws IOException\r
-    {\r
+    public SilkPullParser(Reader input, SilkEnv env) throws IOException {\r
         this(input, env, new SilkParserConfig());\r
     }\r
 \r
@@ -96,8 +93,7 @@ public class SilkPullParser implements TreeStreamReader
      * @param env\r
      * @throws IOException\r
      */\r
-    public SilkPullParser(Reader input, SilkEnv env, SilkParserConfig config) throws IOException\r
-    {\r
+    public SilkPullParser(Reader input, SilkEnv env, SilkParserConfig config) throws IOException {\r
         this.parser = new SilkParser(input, env, config);\r
 \r
         this.threadManager = Executors.newFixedThreadPool(1);\r
@@ -112,10 +108,10 @@ public class SilkPullParser implements TreeStreamReader
      * @param resourceName\r
      * @throws IOException\r
      */\r
-    public SilkPullParser(String resourceBasePath, String resourceName) throws IOException\r
-    {\r
-        this(new BufferedReader(new InputStreamReader(SilkWalker.class.getResourceAsStream(SilkParser.getResourcePath(\r
-                resourceBasePath, resourceName)))), SilkEnv.newEnv(resourceBasePath));\r
+    public SilkPullParser(String resourceBasePath, String resourceName) throws IOException {\r
+        this(new BufferedReader(new InputStreamReader(SilkWalker.class\r
+                .getResourceAsStream(SilkParser.getResourcePath(resourceBasePath, resourceName)))),\r
+                SilkEnv.newEnv(resourceBasePath));\r
     }\r
 \r
     /**\r
@@ -124,85 +120,73 @@ public class SilkPullParser implements TreeStreamReader
      * @param resourcePath\r
      * @throws IOException\r
      */\r
-    public SilkPullParser(URL resourcePath) throws IOException\r
-    {\r
+    public SilkPullParser(URL resourcePath) throws IOException {\r
         this(resourcePath, SilkEnv.newEnv());\r
     }\r
 \r
-    public SilkPullParser(URL resource, SilkEnv env) throws IOException\r
-    {\r
-        this(new BufferedReader(new InputStreamReader(resource.openStream())), SilkEnv.newEnv(env, SilkParser\r
-                .getResourceBasePath(resource)));\r
+    public SilkPullParser(URL resource, SilkEnv env) throws IOException {\r
+        this(new BufferedReader(new InputStreamReader(resource.openStream())), SilkEnv.newEnv(env,\r
+                SilkParser.getResourceBasePath(resource)));\r
     }\r
 \r
-    public SilkPullParser(URL resource, SilkEnv env, SilkParserConfig config) throws IOException\r
-    {\r
-        this(new BufferedReader(new InputStreamReader(resource.openStream())), SilkEnv.newEnv(env, SilkParser\r
-                .getResourceBasePath(resource)), config);\r
+    public SilkPullParser(URL resource, SilkEnv env, SilkParserConfig config) throws IOException {\r
+        this(new BufferedReader(new InputStreamReader(resource.openStream())), SilkEnv.newEnv(env,\r
+                SilkParser.getResourceBasePath(resource)), config);\r
     }\r
 \r
-    public SilkPullParser(URL resource, SilkParserConfig config) throws IOException\r
-    {\r
+    public SilkPullParser(URL resource, SilkParserConfig config) throws IOException {\r
         this(resource, SilkEnv.newEnv(), config);\r
     }\r
 \r
-    private class BackgroundParser implements Callable<Void>\r
-    {\r
+    private class BackgroundParser implements Callable<Void> {\r
 \r
-        public Void call() throws Exception\r
-        {\r
-            try\r
-            {\r
+        public Void call() throws Exception {\r
+            try {\r
                 parser.parse(new TreeEventHandler() {\r
-                    public void finish() throws Exception\r
-                    {\r
+                    public void finish() throws Exception {\r
                         hasParsingFinished = true;\r
                     }\r
 \r
-                    public void init() throws Exception\r
-                    {\r
+                    public void init() throws Exception {\r
                         hasParsingFinished = false;\r
                     }\r
 \r
-                    public void leaveNode(String nodeName) throws Exception\r
-                    {\r
+                    public void leaveNode(String nodeName) throws Exception {\r
                         eventQueue.put(TreeEvent.newLeaveEvent(nodeName));\r
                     }\r
 \r
-                    public void text(String nodeName, String textDataFragment) throws Exception\r
-                    {\r
+                    public void text(String nodeName, String textDataFragment) throws Exception {\r
                         eventQueue.put(TreeEvent.newTextEvent(nodeName, textDataFragment));\r
                     }\r
 \r
-                    public void visitNode(String nodeName, String immediateNodeValue) throws Exception\r
-                    {\r
+                    public void visitNode(String nodeName, String immediateNodeValue)\r
+                            throws Exception {\r
                         eventQueue.put(TreeEvent.newVisitEvent(nodeName, immediateNodeValue));\r
 \r
                     }\r
                 });\r
-\r
                 return null;\r
             }\r
-            finally\r
-            {\r
+            catch (Exception e) {\r
+                hasParsingFinished = true;\r
+                throw e;\r
+            }\r
+            finally {\r
                 threadManager.shutdown();\r
             }\r
         }\r
 \r
     }\r
 \r
-    public TreeEvent peekNext() throws XerialException\r
-    {\r
+    public TreeEvent peekNext() throws XerialException {\r
         if (hasNext())\r
             return prefetchedEventQueue.getFirst();\r
         else\r
             return null;\r
     }\r
 \r
-    public TreeEvent next() throws XerialException\r
-    {\r
-        if (hasNext())\r
-        {\r
+    public TreeEvent next() throws XerialException {\r
+        if (hasNext()) {\r
             TreeEvent e = prefetchedEventQueue.removeFirst();\r
             return e;\r
         }\r
@@ -222,45 +206,38 @@ public class SilkPullParser implements TreeStreamReader
      * @return true if there are remaining events, otherwise fales\r
      * @throws XerialException\r
      */\r
-    private boolean hasNext() throws XerialException\r
-    {\r
+    private boolean hasNext() throws XerialException {\r
         if (!prefetchedEventQueue.isEmpty())\r
             return true;\r
 \r
         if (hasPrefetchFinished)\r
             return false;\r
 \r
-        if (hasParsingFinished)\r
-        {\r
+        if (hasParsingFinished) {\r
             int count = eventQueue.drainTo(prefetchedEventQueue);\r
             hasPrefetchFinished = true;\r
             return hasNext();\r
         }\r
 \r
-        try\r
-        {\r
+        try {\r
             TreeEvent e = null;\r
-            while (!hasParsingFinished && (e = eventQueue.poll(1, TimeUnit.SECONDS)) == null)\r
-            {}\r
+            while (!hasParsingFinished && (e = eventQueue.poll(1, TimeUnit.SECONDS)) == null) {}\r
 \r
-            if (e != null)\r
-            {\r
+            if (e != null) {\r
                 prefetchedEventQueue.addLast(e);\r
                 return true;\r
             }\r
 \r
             return hasNext();\r
         }\r
-        catch (InterruptedException e)\r
-        {\r
+        catch (InterruptedException e) {\r
 \r
         }\r
 \r
         return false;\r
     }\r
 \r
-    public long getNumReadLine()\r
-    {\r
+    public long getNumReadLine() {\r
         return numReadLine;\r
     }\r
 \r
index 38991b7..d5c6365 100644 (file)
@@ -71,7 +71,23 @@ public class SilkWriter {
 
         // colon
         public boolean insertSpaceBeforeColon = false;
-        public boolean insertSpaceAfterColon = false;
+        public boolean insertSpaceAfterColon = true;
+        /**
+         * insert tab after colon symbol (intermediate node only)
+         */
+        public boolean insertTagAfterColon = false;
+
+        // colon (inline-node)
+        public boolean insertSpaceBeforeAttributeColon = false;
+        public boolean insertSpaceAfterAttributeColon = false;
+        public boolean insertTagAfterAttributeColon = false;
+
+        // preamble
+        public boolean insertSpaceAfterPreambleSymbol = true;
+
+        // parenthesis 
+        public boolean insertSpaceOutsideOfParen = false;
+        public boolean insertSpaceInsideOfParen = false;
     }
 
     private FormatConfig formatConfig = new FormatConfig();
@@ -98,6 +114,14 @@ public class SilkWriter {
         this.out = parent.out;
         this.levelOffset = parent.levelOffset + 1;
         this.contextNodeName = contextNodeName;
+        this.formatConfig = parent.formatConfig;
+    }
+
+    public void setFormatConfig(FormatConfig config) {
+        if (config == null)
+            throw new NullPointerException("config is null");
+
+        this.formatConfig = config;
     }
 
     /**
@@ -119,7 +143,6 @@ public class SilkWriter {
 
     public void endDocument() {
         attributeParenCloseCheck(true);
-        out.println();
         flush();
     }
 
@@ -132,7 +155,15 @@ public class SilkWriter {
     }
 
     public SilkWriter preamble() {
-        out.println("%silk(version:1.0)");
+        out.print("%");
+        if (formatConfig.insertSpaceAfterPreambleSymbol)
+            out.print(" ");
+        out.print("silk");
+
+        openParen();
+        keyAndValue("version", "1.0");
+        closeParen();
+
         return this;
     }
 
@@ -144,11 +175,13 @@ public class SilkWriter {
      */
     public SilkWriter commentLine(String comment) {
 
+        usabilityCheck();
         // before generating comment line, close the opened attribute parenthesis
         attributeParenCloseCheck(true);
 
         String[] comments = comment.split("(\\r\\n|\\r|\\n)");
 
+        int index = 0;
         for (String each : comments) {
             if (formatConfig.indentCommentLine)
                 printIndent();
@@ -158,7 +191,11 @@ public class SilkWriter {
             if (formatConfig.insertSpaceAfterCommentSymbol)
                 out.print(" ");
 
-            out.println(each);
+            if (index < comments.length - 1)
+                out.println(each);
+            else
+                out.print(each);
+            index++;
         }
         return this;
     }
@@ -180,6 +217,7 @@ public class SilkWriter {
     }
 
     private void invalidate() {
+        attributeParenCloseCheck(false);
         this.isUsable = false;
     }
 
@@ -190,9 +228,26 @@ public class SilkWriter {
         invalidateChildWriters();
     }
 
+    private void openParen() {
+        if (formatConfig.insertSpaceOutsideOfParen)
+            out.print(" ");
+        out.print("(");
+        if (formatConfig.insertSpaceInsideOfParen)
+            out.print(" ");
+    }
+
+    private void closeParen() {
+        if (formatConfig.insertSpaceInsideOfParen)
+            out.print(" ");
+        out.print(")");
+        if (formatConfig.insertSpaceOutsideOfParen)
+            out.print(" ");
+    }
+
     private void attributeParenCloseCheck(boolean insertNewline) {
         if (numAttribute > 0) {
-            out.print(")");
+
+            closeParen();
 
             switch (nodeValueSyntaxType) {
             case SEQUENCE:
@@ -230,6 +285,18 @@ public class SilkWriter {
         return child;
     }
 
+    public SilkWriter tabDataSchema(String nodeName) {
+        SilkWriter child = node(nodeName);
+        child.setNodeValueSyntax(SyntaxType.TAB);
+        return child;
+    }
+
+    public SilkWriter multilineData(String nodeName) {
+        SilkWriter child = node(nodeName);
+        child.setNodeValueSyntax(SyntaxType.SEQUENCE);
+        return child;
+    }
+
     public static enum SyntaxType {
         DEFAULT, TAB, SEQUENCE
     }
@@ -252,18 +319,21 @@ public class SilkWriter {
         return attribute(nodeName, null);
     }
 
+    private void keyAndValue(String key, String value) {
+        out.print(key);
+        colonAndNodeValueForInlineNode(value);
+    }
+
     public SilkWriter attribute(String nodeName, String nodeValue) {
         usabilityCheck();
 
         if (numAttribute == 0) {
-            out.print("(");
+            openParen();
         }
         else
             comma();
 
-        out.print(nodeName);
-
-        colonAndNodeValue(nodeValue);
+        keyAndValue(nodeName, nodeValue);
 
         numAttribute++;
         return this;
@@ -301,6 +371,19 @@ public class SilkWriter {
             out.print(" ");
     }
 
+    void colonAndNodeValueForInlineNode(String nodeValue) {
+        if (nodeValue != null) {
+            if (formatConfig.insertSpaceBeforeAttributeColon)
+                out.print(" ");
+            out.print(":");
+            if (formatConfig.insertSpaceAfterAttributeColon)
+                out.print(" ");
+            if (formatConfig.insertTagAfterAttributeColon)
+                out.print("\t");
+            out.print(nodeValue);
+        }
+    }
+
     void colonAndNodeValue(String nodeValue) {
         if (nodeValue != null) {
             if (formatConfig.insertSpaceBeforeColon)
@@ -308,6 +391,8 @@ public class SilkWriter {
             out.print(":");
             if (formatConfig.insertSpaceAfterColon)
                 out.print(" ");
+            if (formatConfig.insertTagAfterColon)
+                out.print("\t");
             out.print(nodeValue);
         }
     }
@@ -320,7 +405,7 @@ public class SilkWriter {
         if (formatConfig.indentBeforeDataLine)
             printIndent();
 
-        out.println(escapeDataLine(dataLine));
+        out.print(escapeDataLine(dataLine));
 
         return this;
     }
index fec26e4..bae5f22 100644 (file)
@@ -42,19 +42,15 @@ import org.xerial.util.StringUtil;
  * @author leo
  * 
  */
-public class SilkNodeParser
-{
+public class SilkNodeParser {
     private CommonTokenStream tokenStream;
 
-    public SilkNodeParser(CommonTokenStream tokenStream)
-    {
+    public SilkNodeParser(CommonTokenStream tokenStream) {
         this.tokenStream = tokenStream;
     }
 
-    public SilkElement parse() throws XerialException
-    {
-        switch (tokenStream.LA(1))
-        {
+    public SilkElement parse() throws XerialException {
+        switch (tokenStream.LA(1)) {
         case NodeIndent:
             if (tokenStream.LA(2) == At)
                 return parseFunction();
@@ -68,24 +64,20 @@ public class SilkNodeParser
         }
     }
 
-    private Token getToken(int index)
-    {
+    private Token getToken(int index) {
         Token t = tokenStream.LT(index);
         return t;
     }
 
-    private void consume()
-    {
+    private void consume() {
         tokenStream.consume();
     }
 
-    public SilkNode parseSilkNode() throws XerialException
-    {
+    public SilkNode parseSilkNode() throws XerialException {
         return parseSilkNode(new SilkNode());
     }
 
-    private SilkNode parseSilkNode(SilkNode node) throws XerialException
-    {
+    private SilkNode parseSilkNode(SilkNode node) throws XerialException {
         if (!nextTokenIs(NodeIndent))
             throw new XerialException(XerialErrorCode.PARSE_ERROR, "expected a node indent, but "
                     + toString(tokenStream.LT(1)));
@@ -94,15 +86,13 @@ public class SilkNodeParser
         node.setNodeIndent(indent.getText());
         consume();
 
-        switch (tokenStream.LA(1))
-        {
+        switch (tokenStream.LA(1)) {
         case LParen:
             consume();
             parseAttributeList(node);
             testAndConsume(RParen);
             break;
-        default:
-        {
+        default: {
             parseNodeItem(node);
             break;
         }
@@ -110,14 +100,12 @@ public class SilkNodeParser
         return node;
     }
 
-    private SilkNode parseNodeItem() throws XerialException
-    {
+    private SilkNode parseNodeItem() throws XerialException {
         SilkNode newNode = new SilkNode();
         return parseNodeItem(newNode);
     }
 
-    private SilkNode parseNodeItem(SilkNode contextNode) throws XerialException
-    {
+    private SilkNode parseNodeItem(SilkNode contextNode) throws XerialException {
         // node name
         String nodeName = parseNodeName();
         contextNode.setName(nodeName);
@@ -133,8 +121,7 @@ public class SilkNodeParser
         return contextNode;
     }
 
-    private void parseNodeValueOpt(SilkNode node) throws XerialException
-    {
+    private void parseNodeValueOpt(SilkNode node) throws XerialException {
         if (!nextTokenIs(Colon))
             return;
 
@@ -143,26 +130,22 @@ public class SilkNodeParser
         parseNodeValue(node);
     }
 
-    private void parseNodeValue(SilkNode node) throws XerialException
-    {
+    private void parseNodeValue(SilkNode node) throws XerialException {
         int nextToken = tokenStream.LA(1);
 
-        switch (nextToken)
-        {
+        switch (nextToken) {
         case At:
             SilkFunction func = parseFunctionInternal(new SilkFunction());
             node.setFunction(func);
             break;
         case PlainOneLine:
-        case String:
-        {
+        case String: {
             Token t = getToken(1);
             consume();
             node.setValue(t.getText());
             break;
         }
-        case JSON:
-        {
+        case JSON: {
             Token t = getToken(1);
             consume();
             node.setJSON(t.getText());
@@ -174,19 +157,17 @@ public class SilkNodeParser
 
     }
 
-    private String parseNodeValue() throws XerialException
-    {
+    private String parseNodeValue() throws XerialException {
         int nextToken = tokenStream.LA(1);
 
-        switch (nextToken)
-        {
+        switch (nextToken) {
         case At:
             // TODO
-            throw new XerialException(XerialErrorCode.PARSE_ERROR, "nested function is not yet supported");
+            throw new XerialException(XerialErrorCode.PARSE_ERROR,
+                    "nested function is not yet supported");
         case PlainOneLine:
         case String:
-        case JSON:
-        {
+        case JSON: {
             Token t = getToken(1);
             consume();
             return t.getText();
@@ -197,11 +178,9 @@ public class SilkNodeParser
 
     }
 
-    private void parsePlural(SilkNode node)
-    {
+    private void parsePlural(SilkNode node) {
         int nextTokenType = tokenStream.LA(1);
-        switch (nextTokenType)
-        {
+        switch (nextTokenType) {
         case Star:
             node.setOccurrence(SilkNodeOccurrence.ZERO_OR_MORE);
             consume();
@@ -215,14 +194,12 @@ public class SilkNodeParser
             consume();
             break;
         case Seq:
-            if (tokenStream.LA(2) == Seq)
-            {
+            if (tokenStream.LA(2) == Seq) {
                 node.setOccurrence(SilkNodeOccurrence.MULTILINE_SEQUENCE);
                 consume();
                 break;
             }
-            else
-            {
+            else {
                 node.setOccurrence(SilkNodeOccurrence.SEQUENCE);
                 consume();
                 break;
@@ -238,8 +215,7 @@ public class SilkNodeParser
 
     }
 
-    private void parseNodeItemAttr(SilkNode node) throws XerialException
-    {
+    private void parseNodeItemAttr(SilkNode node) throws XerialException {
         if (!nextTokenIs(LParen))
             return;
 
@@ -251,13 +227,11 @@ public class SilkNodeParser
 
     }
 
-    private void parseAttributeList(SilkNode contextNode) throws XerialException
-    {
+    private void parseAttributeList(SilkNode contextNode) throws XerialException {
         SilkNode attributeNode = parseNodeItem();
         contextNode.addSilkNode(attributeNode);
 
-        while (nextTokenIs(Comma))
-        {
+        while (nextTokenIs(Comma)) {
             consume();
             attributeNode = parseNodeItem();
             contextNode.addSilkNode(attributeNode);
@@ -273,16 +247,13 @@ public class SilkNodeParser
      * @return matched token
      * @throws XerialException
      */
-    private Token testAndConsume(int tokenType) throws XerialException
-    {
+    private Token testAndConsume(int tokenType) throws XerialException {
         Token t = getToken(1);
-        if (t.getType() == tokenType)
-        {
+        if (t.getType() == tokenType) {
             consume();
             return t;
         }
-        else
-        {
+        else {
             throw unexpectedToken(t, tokenType);
         }
     }
@@ -292,13 +263,11 @@ public class SilkNodeParser
      * @return true when the next token has the specified token type, otherwise
      *         false
      */
-    private boolean nextTokenIs(int tokenType)
-    {
+    private boolean nextTokenIs(int tokenType) {
         return tokenStream.LA(1) == tokenType;
     }
 
-    private void parseDataType(SilkNode node) throws XerialException
-    {
+    private void parseDataType(SilkNode node) throws XerialException {
         if (!nextTokenIs(LBracket))
             return;
 
@@ -314,11 +283,9 @@ public class SilkNodeParser
 
     }
 
-    private String parseNodeName() throws XerialException
-    {
+    private String parseNodeName() throws XerialException {
         Token t = getToken(1);
-        switch (tokenStream.LA(1))
-        {
+        switch (tokenStream.LA(1)) {
         case PlainOneLine:
         case String:
             consume();
@@ -328,21 +295,17 @@ public class SilkNodeParser
         }
     }
 
-    private SilkFunction parseFunction() throws XerialException
-    {
+    private SilkFunction parseFunction() throws XerialException {
         SilkFunction func = new SilkFunction();
-        switch (tokenStream.LA(1))
-        {
-        case NodeIndent:
-        {
+        switch (tokenStream.LA(1)) {
+        case NodeIndent: {
             Token t = getToken(1);
             func.setNodeIndent(t.getText());
             consume();
             parseFunctionInternal(func);
             return func;
         }
-        case FunctionIndent:
-        {
+        case FunctionIndent: {
             Token t = getToken(1); // function indent
             func.setNodeIndent(t.getText());
             consume();
@@ -361,14 +324,11 @@ public class SilkNodeParser
 
     }
 
-    private void parseFunctionArgs(SilkFunction func) throws XerialException
-    {
+    private void parseFunctionArgs(SilkFunction func) throws XerialException {
         testAndConsume(LParen);
-        if (!nextTokenIs(RParen))
-        {
+        if (!nextTokenIs(RParen)) {
             parseFunctionArg(func);
-            while (nextTokenIs(Comma))
-            {
+            while (nextTokenIs(Comma)) {
                 consume();
                 parseFunctionArg(func);
             }
@@ -378,12 +338,9 @@ public class SilkNodeParser
 
     }
 
-    private void parseFunctionArg(SilkFunction func) throws XerialException
-    {
-        if (nextTokenIs(String) || nextTokenIs(PlainOneLine))
-        {
-            if (tokenStream.LA(2) == Colon)
-            {
+    private void parseFunctionArg(SilkFunction func) throws XerialException {
+        if (nextTokenIs(String) || nextTokenIs(PlainOneLine)) {
+            if (tokenStream.LA(2) == Colon) {
                 Token key = getToken(1);
                 consume();
                 consume();
@@ -397,8 +354,7 @@ public class SilkNodeParser
         func.addArgument(value);
     }
 
-    private SilkFunction parseFunctionInternal(SilkFunction func) throws XerialException
-    {
+    private SilkFunction parseFunctionInternal(SilkFunction func) throws XerialException {
         testAndConsume(At);
         Token funcName = testAndConsume(PlainOneLine);
         func.setName(funcName.getText().trim());
@@ -408,29 +364,29 @@ public class SilkNodeParser
         return func;
     }
 
-    private XerialException unexpectedToken(Token t) throws XerialException
-    {
-        return new XerialException(XerialErrorCode.PARSE_ERROR, java.lang.String.format("unexpected token %s",
-                SilkLineParser.tokenNames[t.getType()], toString(t)));
+    private XerialException unexpectedToken(Token t) throws XerialException {
+        return new XerialException(XerialErrorCode.PARSE_ERROR, java.lang.String.format(
+                "unexpected token %s", SilkLineParser.tokenNames[t.getType()], toString(t)));
 
     }
 
-    private XerialException unexpectedToken(Token t, Integer... expectedTokenTypes)
-    {
-        List<String> expectedTokenNames = CollectionUtil.collect(expectedTokenTypes, new Functor<Integer, String>() {
-            public String apply(Integer input)
-            {
-                return SilkLineParser.tokenNames[input.intValue()];
-            }
-        });
+    private XerialException unexpectedToken(Token t, Integer... expectedTokenTypes) {
+        List<String> expectedTokenNames = CollectionUtil.collect(expectedTokenTypes,
+                new Functor<Integer, String>() {
+                    public String apply(Integer input) {
+                        return SilkLineParser.tokenNames[input.intValue()];
+                    }
+                });
 
-        return new XerialException(XerialErrorCode.PARSE_ERROR, java.lang.String.format("expected %s, but %s",
-                StringUtil.join(expectedTokenNames, " or "), toString(t)));
+        return new XerialException(XerialErrorCode.PARSE_ERROR, java.lang.String.format(
+                "expected %s, but %s", StringUtil.join(expectedTokenNames, " or "), toString(t)));
     }
 
-    private String toString(Token t)
-    {
-        return java.lang.String.format("[%s at char %d: %s]", SilkLineParser.tokenNames[t.getType()], t
-                .getCharPositionInLine(), t.getText());
+    private String toString(Token t) {
+
+        int type = t.getType();
+        return java.lang.String.format("[%s at char %d: %s]", type >= 0
+                && type < SilkLineParser.tokenNames.length ? SilkLineParser.tokenNames[type]
+                : "unknown token type: " + type, t.getCharPositionInLine(), t.getText());
     }
 }
index 39a58d2..56ff2d6 100644 (file)
@@ -58,10 +58,9 @@ public class XMLSilkLensTest {
 \r
         XMLTreeWalker x = new XMLTreeWalker(FileResource.open(XMLSilkLensTest.class,\r
                 "track-config.xml"));\r
-        SilkWalker s = new SilkWalker(new StringReader(silk));\r
-\r
+        SilkWalker sw = new SilkWalker(new StringReader(silk));\r
         x.walk(l1);\r
-        s.walk(l2);\r
+        sw.walk(l2);\r
 \r
         boolean doesMatch = TreeWalkLog.compare(l1, l2);\r
         assertTrue(doesMatch);\r
index 843d49c..43b7f37 100644 (file)
@@ -29,6 +29,7 @@ import java.io.StringWriter;
 import org.junit.After;\r
 import org.junit.Before;\r
 import org.junit.Test;\r
+import org.xerial.silk.SilkWriter.FormatConfig;\r
 import org.xerial.util.log.Logger;\r
 \r
 public class SilkWriterTest {\r
@@ -44,7 +45,10 @@ public class SilkWriterTest {
     public void toSilk() throws Exception {\r
         StringWriter buf = new StringWriter();\r
         SilkWriter w = new SilkWriter(buf);\r
-        //w.addSchema("config(version)");\r
+\r
+        FormatConfig fc = new FormatConfig();\r
+        fc.insertSpaceAfterColon = true;\r
+        w.setFormatConfig(fc);\r
 \r
         w.commentLine("utgb config format");\r
         SilkWriter config = w.node("config").attribute("version", "1.0");\r
@@ -56,6 +60,10 @@ public class SilkWriterTest {
         SilkWriter dbNode = w.node("database").attribute("dbms", "sqlite");\r
         dbNode.leaf("address", "db/sample.db");\r
 \r
+        SilkWriter t = w.tabDataSchema("gene").attribute("id").attribute("start").attribute("end");\r
+        t.dataLine("g1\t10\t20000");\r
+        t.dataLine("g2\t1000\t30000");\r
+\r
         w.endDocument();\r
 \r
         _logger.info(buf.toString());\r
index 9a01802..52f465c 100644 (file)
@@ -42,38 +42,32 @@ import org.xerial.util.tree.TreeWalker;
  * @author leo
  * 
  */
-public class TreeWalkLog implements TreeVisitor
-{
+public class TreeWalkLog implements TreeVisitor {
     private static Logger _logger = Logger.getLogger(TreeWalkLog.class);
 
     public static enum Event {
         INIT, FINISH, VISIT, LEAVE
     }
 
-    public static class EventLog
-    {
+    public static class EventLog {
         Event event;
         String nodeName = null;
         String value = null;
 
-        public EventLog(Event event)
-        {
+        public EventLog(Event event) {
             this.event = event;
         }
 
-        public EventLog(Event event, String nodeName, String value)
-        {
+        public EventLog(Event event, String nodeName, String value) {
             this.event = event;
             this.nodeName = nodeName;
             this.value = value;
         }
 
-        public static boolean strCmp(String a, String b)
-        {
+        public static boolean strCmp(String a, String b) {
             if (a == null)
                 return b == null;
-            else
-            {
+            else {
                 if (b == null)
                     return false;
 
@@ -82,8 +76,7 @@ public class TreeWalkLog implements TreeVisitor
         }
 
         @Override
-        public boolean equals(Object o)
-        {
+        public boolean equals(Object o) {
             EventLog other = (EventLog) o;
             if (event != other.event)
                 return false;
@@ -95,17 +88,14 @@ public class TreeWalkLog implements TreeVisitor
         }
 
         @Override
-        public String toString()
-        {
-            if (nodeName != null)
-            {
+        public String toString() {
+            if (nodeName != null) {
                 if (value != null)
                     return String.format("%s:%s=%s", event, nodeName, value);
                 else
                     return String.format("%s:%s", event, nodeName);
             }
-            else
-            {
+            else {
                 if (value != null)
                     return String.format("%s:%s", event, value);
                 else
@@ -120,19 +110,16 @@ public class TreeWalkLog implements TreeVisitor
     private final StringBuilder EMPTY_BUFFER = new StringBuilder(0);
     private String pendingVisitNode = null;
 
-    public void finish(TreeWalker walker) throws XerialException
-    {
+    public void finish(TreeWalker walker) throws XerialException {
         log.add(new EventLog(Event.FINISH));
     }
 
-    public void init(TreeWalker walker) throws XerialException
-    {
+    public void init(TreeWalker walker) throws XerialException {
         log.add(new EventLog(Event.INIT));
         textStack.addLast(EMPTY_BUFFER);
     }
 
-    public void leaveNode(String nodeName, TreeWalker walker) throws XerialException
-    {
+    public void leaveNode(String nodeName, TreeWalker walker) throws XerialException {
         if (nodeName == null)
             return; // skip empty node leave (e.g. JSON Object root bracket)
 
@@ -142,22 +129,21 @@ public class TreeWalkLog implements TreeVisitor
         textStack.removeLast();
     }
 
-    public void text(String nodeName, String textDataFragment, TreeWalker walker) throws XerialException
-    {
-        if (textStack.peekLast() == EMPTY_BUFFER)
-        {
+    public void text(String nodeName, String textDataFragment, TreeWalker walker)
+            throws XerialException {
+        if (textStack.peekLast() == EMPTY_BUFFER) {
             textStack.removeLast();
             textStack.addLast(new StringBuilder());
         }
         textStack.peekLast().append(textDataFragment);
     }
 
-    private void popPendingNode()
-    {
-        if (pendingVisitNode != null)
-        {
+    private void popPendingNode() {
+        if (pendingVisitNode != null) {
             if (textStack.peekLast() != EMPTY_BUFFER)
-                log.add(new EventLog(Event.VISIT, pendingVisitNode, textStack.peekLast().toString()));
+                log
+                        .add(new EventLog(Event.VISIT, pendingVisitNode, textStack.peekLast()
+                                .toString()));
             else
                 log.add(new EventLog(Event.VISIT, pendingVisitNode, null));
 
@@ -165,8 +151,8 @@ public class TreeWalkLog implements TreeVisitor
         }
     }
 
-    public void visitNode(String nodeName, String immediateNodeValue, TreeWalker walker) throws XerialException
-    {
+    public void visitNode(String nodeName, String immediateNodeValue, TreeWalker walker)
+            throws XerialException {
         popPendingNode();
 
         if (nodeName == null)
@@ -180,19 +166,16 @@ public class TreeWalkLog implements TreeVisitor
             textStack.addLast(EMPTY_BUFFER);
     }
 
-    public List<EventLog> getLog()
-    {
+    public List<EventLog> getLog() {
         return log;
     }
 
     @Override
-    public String toString()
-    {
+    public String toString() {
         return StringUtil.join(log, "\n");
     }
 
-    public static boolean compare(TreeWalkLog a, TreeWalkLog b)
-    {
+    public static boolean compare(TreeWalkLog a, TreeWalkLog b) {
         List<EventLog> l1 = a.getLog();
         List<EventLog> l2 = b.getLog();
 
@@ -201,15 +184,13 @@ public class TreeWalkLog implements TreeVisitor
 
         boolean doComparison = true;
 
-        while (i1.hasNext() && i2.hasNext())
-        {
+        while (i1.hasNext() && i2.hasNext()) {
             EventLog e1 = i1.next();
             EventLog e2 = i2.next();
 
             _logger.debug(String.format("compare: %-20s %-20s", e1, e2));
-            if (!e1.equals(e2) && doComparison)
-            {
-                _logger.warn("--- do not match");
+            if (!e1.equals(e2) && doComparison) {
+                _logger.warn(String.format("----- mismatch: %-20s %-20s", e1, e2));
                 doComparison = false;
             }
         }