1 28 package org.jvyamlb; 29 30 import java.io.FileInputStream ; 31 import java.io.InputStream ; 32 33 import java.util.HashMap ; 34 import java.util.Iterator ; 35 import java.util.List ; 36 import java.util.ArrayList ; 37 import java.util.Map ; 38 39 import org.jvyamlb.events.AliasEvent; 40 import org.jvyamlb.events.Event; 41 import org.jvyamlb.events.NodeEvent; 42 import org.jvyamlb.events.MappingEndEvent; 43 import org.jvyamlb.events.MappingStartEvent; 44 import org.jvyamlb.events.ScalarEvent; 45 import org.jvyamlb.events.SequenceStartEvent; 46 import org.jvyamlb.events.SequenceEndEvent; 47 import org.jvyamlb.events.StreamStartEvent; 48 import org.jvyamlb.events.StreamEndEvent; 49 50 import org.jvyamlb.nodes.Node; 51 import org.jvyamlb.nodes.ScalarNode; 52 import org.jvyamlb.nodes.SequenceNode; 53 import org.jvyamlb.nodes.MappingNode; 54 55 import org.jruby.util.ByteList; 56 57 60 public class ComposerImpl implements Composer { 61 private Parser parser; 62 private Resolver resolver; 63 private Map anchors; 64 65 public ComposerImpl(final Parser parser, final Resolver resolver) { 66 this.parser = parser; 67 this.resolver = resolver; 68 this.anchors = new HashMap (); 69 } 70 71 public boolean checkNode() { 72 return !(parser.peekEvent() instanceof StreamEndEvent); 73 } 74 75 public Node getNode() { 76 return checkNode() ? composeDocument() : (Node)null; 77 } 78 79 private class NodeIterator implements Iterator { 80 public boolean hasNext() {return checkNode();} 81 public Object next() {return getNode();} 82 public void remove() {} 83 } 84 85 public Iterator eachNode() { 86 return new NodeIterator(); 87 } 88 89 public Iterator iterator() { 90 return eachNode(); 91 } 92 93 public Node composeDocument() { 94 if(parser.peekEvent() instanceof StreamStartEvent) { 95 parser.getEvent(); 97 } 98 parser.getEvent(); 100 final Node node = composeNode(null,null); 101 parser.getEvent(); 103 this.anchors.clear(); 104 return node; 105 } 106 107 private final static boolean[] FALS = new boolean[]{false}; 108 private final static boolean[] TRU = new boolean[]{true}; 109 110 public Node composeNode(final Node parent, final Object index) { 111 if(parser.peekEvent() instanceof AliasEvent) { 112 final AliasEvent event = (AliasEvent)parser.getEvent(); 113 final String anchor = event.getAnchor(); 114 if(!anchors.containsKey(anchor)) { 115 System.err.println(" for aliasEvent: " + event); 116 throw new ComposerException(null,"found undefined alias " + anchor,null); 117 } 118 return (Node)anchors.get(anchor); 119 } 120 final Event event = parser.peekEvent(); 121 String anchor = null; 122 if(event instanceof NodeEvent) { 123 anchor = ((NodeEvent)event).getAnchor(); 124 } 125 if(null != anchor) { 126 if(anchors.containsKey(anchor)) { 127 throw new ComposerException("found duplicate anchor "+anchor+"; first occurence",null,null); 128 } 129 } 130 resolver.descendResolver(parent,index); 131 Node node = null; 132 if(event instanceof ScalarEvent) { 133 final ScalarEvent ev = (ScalarEvent)parser.getEvent(); 134 String tag = ev.getTag(); 135 if(tag == null || tag.equals("!")) { 136 tag = resolver.resolve(ScalarNode.class,ev.getValue(),ev.getImplicit()); 137 } 138 node = new ScalarNode(tag,ev.getValue(),ev.getStyle()); 139 if(null != anchor) { 140 anchors.put(anchor,node); 141 } 142 } else if(event instanceof SequenceStartEvent) { 143 final SequenceStartEvent start = (SequenceStartEvent)parser.getEvent(); 144 String tag = start.getTag(); 145 if(tag == null || tag.equals("!")) { 146 tag = resolver.resolve(SequenceNode.class,null,start.getImplicit() ? TRU : FALS); 147 } 148 node = new SequenceNode(tag,new ArrayList (),start.getFlowStyle()); 149 if(null != anchor) { 150 anchors.put(anchor,node); 151 } 152 int ix = 0; 153 while(!(parser.peekEvent() instanceof SequenceEndEvent)) { 154 ((List )node.getValue()).add(composeNode(node,new Integer (ix++))); 155 } 156 parser.getEvent(); 157 } else if(event instanceof MappingStartEvent) { 158 final MappingStartEvent start = (MappingStartEvent)parser.getEvent(); 159 String tag = start.getTag(); 160 if(tag == null || tag.equals("!")) { 161 tag = resolver.resolve(MappingNode.class,null, start.getImplicit() ? TRU : FALS); 162 } 163 node = new MappingNode(tag, new HashMap (), start.getFlowStyle()); 164 if(null != anchor) { 165 anchors.put(anchor,node); 166 } 167 while(!(parser.peekEvent() instanceof MappingEndEvent)) { 168 final Event key = parser.peekEvent(); 169 final Node itemKey = composeNode(node,null); 170 if(((Map )node.getValue()).containsKey(itemKey)) { 171 composeNode(node,itemKey); 172 } else { 173 ((Map )node.getValue()).put(itemKey,composeNode(node,itemKey)); 174 } 175 } 176 parser.getEvent(); 177 } 178 resolver.ascendResolver(); 179 return node; 180 } 181 182 public static void main(final String [] args) throws Exception { 183 final String filename = args[0]; 184 System.out.println("Reading of file: \"" + filename + "\""); 185 186 final ByteList input = new ByteList(1024); 187 final InputStream reader = new FileInputStream (filename); 188 byte[] buff = new byte[1024]; 189 int read = 0; 190 while(true) { 191 read = reader.read(buff); 192 input.append(buff,0,read); 193 if(read < 1024) { 194 break; 195 } 196 } 197 reader.close(); 198 final long before = System.currentTimeMillis(); 199 for(int i=0;i<1;i++) { 200 final Composer cmp = new ComposerImpl(new ParserImpl(new ScannerImpl(input)),new ResolverImpl()); 201 for(final Iterator iter = cmp.eachNode();iter.hasNext();) { 202 iter.next(); 203 } 205 } 206 final long after = System.currentTimeMillis(); 207 final long time = after-before; 208 final double timeS = (after-before)/1000.0; 209 System.out.println("Walking through the nodes for the file: " + filename + " took " + time + "ms, or " + timeS + " seconds"); 210 } 211 } | Popular Tags |