001: /***** BEGIN LICENSE BLOCK *****
002: * Version: CPL 1.0/GPL 2.0/LGPL 2.1
003: *
004: * The contents of this file are subject to the Common Public
005: * License Version 1.0 (the "License"); you may not use this file
006: * except in compliance with the License. You may obtain a copy of
007: * the License at http://www.eclipse.org/legal/cpl-v10.html
008: *
009: * Software distributed under the License is distributed on an "AS
010: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
011: * implied. See the License for the specific language governing
012: * rights and limitations under the License.
013: *
014: * Copyright (C) 2007 Ola Bini <ola@ologix.com>
015: *
016: * Alternatively, the contents of this file may be used under the terms of
017: * either of the GNU General Public License Version 2 or later (the "GPL"),
018: * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
019: * in which case the provisions of the GPL or the LGPL are applicable instead
020: * of those above. If you wish to allow use of your version of this file only
021: * under the terms of either the GPL or the LGPL, and not to allow others to
022: * use your version of this file under the terms of the CPL, indicate your
023: * decision by deleting the provisions above and replace them with the notice
024: * and other provisions required by the GPL or the LGPL. If you do not delete
025: * the provisions above, a recipient may use your version of this file under
026: * the terms of any one of the CPL, the GPL or the LGPL.
027: ***** END LICENSE BLOCK *****/package org.jvyamlb;
028:
029: import java.io.FileInputStream;
030: import java.io.InputStream;
031:
032: import java.util.HashMap;
033: import java.util.Iterator;
034: import java.util.List;
035: import java.util.ArrayList;
036: import java.util.Map;
037:
038: import org.jvyamlb.events.AliasEvent;
039: import org.jvyamlb.events.Event;
040: import org.jvyamlb.events.NodeEvent;
041: import org.jvyamlb.events.MappingEndEvent;
042: import org.jvyamlb.events.MappingStartEvent;
043: import org.jvyamlb.events.ScalarEvent;
044: import org.jvyamlb.events.SequenceStartEvent;
045: import org.jvyamlb.events.SequenceEndEvent;
046: import org.jvyamlb.events.StreamStartEvent;
047: import org.jvyamlb.events.StreamEndEvent;
048:
049: import org.jvyamlb.nodes.Node;
050: import org.jvyamlb.nodes.ScalarNode;
051: import org.jvyamlb.nodes.SequenceNode;
052: import org.jvyamlb.nodes.MappingNode;
053:
054: import org.jruby.util.ByteList;
055:
056: /**
057: * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
058: */
059: public class ComposerImpl implements Composer {
060: private Parser parser;
061: private Resolver resolver;
062: private Map anchors;
063:
064: public ComposerImpl(final Parser parser, final Resolver resolver) {
065: this .parser = parser;
066: this .resolver = resolver;
067: this .anchors = new HashMap();
068: }
069:
070: public boolean checkNode() {
071: return !(parser.peekEvent() instanceof StreamEndEvent);
072: }
073:
074: public Node getNode() {
075: return checkNode() ? composeDocument() : (Node) null;
076: }
077:
078: private class NodeIterator implements Iterator {
079: public boolean hasNext() {
080: return checkNode();
081: }
082:
083: public Object next() {
084: return getNode();
085: }
086:
087: public void remove() {
088: }
089: }
090:
091: public Iterator eachNode() {
092: return new NodeIterator();
093: }
094:
095: public Iterator iterator() {
096: return eachNode();
097: }
098:
099: public Node composeDocument() {
100: if (parser.peekEvent() instanceof StreamStartEvent) {
101: //Drop STREAM-START event
102: parser.getEvent();
103: }
104: //Drop DOCUMENT-START event
105: parser.getEvent();
106: final Node node = composeNode(null, null);
107: //Drop DOCUMENT-END event
108: parser.getEvent();
109: this .anchors.clear();
110: return node;
111: }
112:
113: private final static boolean[] FALS = new boolean[] { false };
114: private final static boolean[] TRU = new boolean[] { true };
115:
116: public Node composeNode(final Node parent, final Object index) {
117: if (parser.peekEvent() instanceof AliasEvent) {
118: final AliasEvent event = (AliasEvent) parser.getEvent();
119: final String anchor = event.getAnchor();
120: if (!anchors.containsKey(anchor)) {
121: throw new ComposerException(null,
122: "found undefined alias " + anchor, null);
123: }
124: return (Node) anchors.get(anchor);
125: }
126: final Event event = parser.peekEvent();
127: String anchor = null;
128: if (event instanceof NodeEvent) {
129: anchor = ((NodeEvent) event).getAnchor();
130: }
131: resolver.descendResolver(parent, index);
132: Node node = null;
133: if (event instanceof ScalarEvent) {
134: final ScalarEvent ev = (ScalarEvent) parser.getEvent();
135: String tag = ev.getTag();
136: if (tag == null || tag.equals("!")) {
137: tag = resolver.resolve(ScalarNode.class, ev.getValue(),
138: ev.getImplicit());
139: }
140: node = new ScalarNode(tag, ev.getValue(), ev.getStyle());
141: if (null != anchor) {
142: anchors.put(anchor, node);
143: }
144: } else if (event instanceof SequenceStartEvent) {
145: final SequenceStartEvent start = (SequenceStartEvent) parser
146: .getEvent();
147: String tag = start.getTag();
148: if (tag == null || tag.equals("!")) {
149: tag = resolver.resolve(SequenceNode.class, null, start
150: .getImplicit() ? TRU : FALS);
151: }
152: node = new SequenceNode(tag, new ArrayList(), start
153: .getFlowStyle());
154: if (null != anchor) {
155: anchors.put(anchor, node);
156: }
157: int ix = 0;
158: while (!(parser.peekEvent() instanceof SequenceEndEvent)) {
159: ((List) node.getValue()).add(composeNode(node,
160: new Integer(ix++)));
161: }
162: parser.getEvent();
163: } else if (event instanceof MappingStartEvent) {
164: final MappingStartEvent start = (MappingStartEvent) parser
165: .getEvent();
166: String tag = start.getTag();
167: if (tag == null || tag.equals("!")) {
168: tag = resolver.resolve(MappingNode.class, null, start
169: .getImplicit() ? TRU : FALS);
170: }
171: node = new MappingNode(tag, new HashMap(), start
172: .getFlowStyle());
173: if (null != anchor) {
174: anchors.put(anchor, node);
175: }
176: while (!(parser.peekEvent() instanceof MappingEndEvent)) {
177: final Event key = parser.peekEvent();
178: final Node itemKey = composeNode(node, null);
179: if (((Map) node.getValue()).containsKey(itemKey)) {
180: composeNode(node, itemKey);
181: } else {
182: ((Map) node.getValue()).put(itemKey, composeNode(
183: node, itemKey));
184: }
185: }
186: parser.getEvent();
187: }
188: resolver.ascendResolver();
189: return node;
190: }
191:
192: public static void main(final String[] args) throws Exception {
193: final String filename = args[0];
194: System.out.println("Reading of file: \"" + filename + "\"");
195:
196: final ByteList input = new ByteList(1024);
197: final InputStream reader = new FileInputStream(filename);
198: byte[] buff = new byte[1024];
199: int read = 0;
200: while (true) {
201: read = reader.read(buff);
202: input.append(buff, 0, read);
203: if (read < 1024) {
204: break;
205: }
206: }
207: reader.close();
208: final long before = System.currentTimeMillis();
209: for (int i = 0; i < 1; i++) {
210: final Composer cmp = new ComposerImpl(new ParserImpl(
211: new ScannerImpl(input)), new ResolverImpl());
212: for (final Iterator iter = cmp.eachNode(); iter.hasNext();) {
213: iter.next();
214: // System.out.println(iter.next());
215: }
216: }
217: final long after = System.currentTimeMillis();
218: final long time = after - before;
219: final double timeS = (after - before) / 1000.0;
220: System.out.println("Walking through the nodes for the file: "
221: + filename + " took " + time + "ms, or " + timeS
222: + " seconds");
223: }
224: }// ComposerImpl
|