private Node composeNode(Node parent) { this.recursiveNodes.add(parent); if (this.parser.checkEvent(Event.ID.Alias)) { AliasEvent event = (AliasEvent) this.parser.getEvent(); String anchor = event.getAnchor(); if (!this.anchors.containsKey(anchor)) { throw new ComposerException( null, null, "found undefined alias " + anchor, event.getStartMark()); } Node result = (Node) this.anchors.get(anchor); if (this.recursiveNodes.remove(result)) { result.setTwoStepsConstruction(true); } return result; } NodeEvent event = (NodeEvent) this.parser.peekEvent(); String anchor = null; anchor = event.getAnchor(); Node node = null; if (this.parser.checkEvent(Event.ID.Scalar)) { node = composeScalarNode(anchor); } else if (this.parser.checkEvent(Event.ID.SequenceStart)) { node = composeSequenceNode(anchor); } else { node = composeMappingNode(anchor); } this.recursiveNodes.remove(parent); return node; }
@JRubyMethod public IRubyObject parse(ThreadContext context, IRubyObject target) { Ruby runtime = context.runtime; // FIXME? only supports Unicode, since we have to produces strings... StreamReader reader; if (target.respondsTo("read")) { reader = new StreamReader(new InputStreamReader(new IOInputStream(target))); } else { reader = new StreamReader(new StringReader(target.convertToString().asJavaString())); } Parser parser = new ParserImpl(reader); IRubyObject handler = getInstanceVariable("@handler"); Event event; while (true) { try { event = parser.getEvent(); // FIXME: Event should expose a getID, so it can be switched if (event.is(ID.StreamStart)) { invoke(context, handler, "start_stream", runtime.newFixnum(YAML_ANY_ENCODING)); } else if (event.is(ID.DocumentStart)) { DocumentStartEvent dse = (DocumentStartEvent) event; Integer[] versionInts = dse.getVersion(); IRubyObject version = versionInts == null ? runtime.getNil() : RubyArray.newArray( runtime, runtime.newFixnum(versionInts[0]), runtime.newFixnum(versionInts[1])); Map<String, String> tagsMap = dse.getTags(); RubyArray tags = RubyArray.newArray(runtime); if (tags.size() > 0) { for (Map.Entry<String, String> tag : tagsMap.entrySet()) { tags.append( RubyArray.newArray( runtime, RubyString.newString(runtime, tag.getKey()), RubyString.newString(runtime, tag.getValue()))); } } invoke( context, handler, "start_document", version, tags, runtime.newBoolean(dse.getExplicit())); } else if (event.is(ID.DocumentEnd)) { DocumentEndEvent dee = (DocumentEndEvent) event; invoke(context, handler, "end_document", runtime.newBoolean(dee.getExplicit())); } else if (event.is(ID.Alias)) { AliasEvent ae = (AliasEvent) event; IRubyObject alias = runtime.getNil(); if (ae.getAnchor() != null) { alias = RubyString.newString(runtime, ae.getAnchor()); } invoke(context, handler, "alias", alias); } else if (event.is(ID.Scalar)) { ScalarEvent se = (ScalarEvent) event; IRubyObject anchor = se.getAnchor() == null ? runtime.getNil() : RubyString.newString(runtime, se.getAnchor()); IRubyObject tag = se.getTag() == null ? runtime.getNil() : RubyString.newString(runtime, se.getTag()); IRubyObject plain_implicit = runtime.newBoolean(se.getImplicit().isFirst()); IRubyObject quoted_implicit = runtime.newBoolean(se.getImplicit().isSecond()); IRubyObject style = runtime.newFixnum(se.getStyle()); IRubyObject val = RubyString.newString(runtime, se.getValue()); invoke( context, handler, "scalar", val, anchor, tag, plain_implicit, quoted_implicit, style); } else if (event.is(ID.SequenceStart)) { SequenceStartEvent sse = (SequenceStartEvent) event; IRubyObject anchor = sse.getAnchor() == null ? runtime.getNil() : RubyString.newString(runtime, sse.getAnchor()); IRubyObject tag = sse.getTag() == null ? runtime.getNil() : RubyString.newString(runtime, sse.getTag()); IRubyObject implicit = runtime.newBoolean(sse.getImplicit()); IRubyObject style = runtime.newFixnum(sse.getFlowStyle() ? 1 : 0); invoke(context, handler, "start_sequence", anchor, tag, implicit, style); } else if (event.is(ID.SequenceEnd)) { invoke(context, handler, "end_sequence"); } else if (event.is(ID.MappingStart)) { MappingStartEvent mse = (MappingStartEvent) event; IRubyObject anchor = mse.getAnchor() == null ? runtime.getNil() : RubyString.newString(runtime, mse.getAnchor()); IRubyObject tag = mse.getTag() == null ? runtime.getNil() : RubyString.newString(runtime, mse.getTag()); IRubyObject implicit = runtime.newBoolean(mse.getImplicit()); IRubyObject style = runtime.newFixnum(mse.getFlowStyle() ? 1 : 0); invoke(context, handler, "start_mapping", anchor, tag, implicit, style); } else if (event.is(ID.MappingEnd)) { invoke(context, handler, "end_mapping"); } else if (event.is(ID.StreamEnd)) { invoke(context, handler, "end_stream"); break; } } catch (ParserException pe) { parser = null; RubyKernel.raise( context, runtime.getModule("Psych").getConstant("SyntaxError"), new IRubyObject[] {runtime.newString(pe.getLocalizedMessage())}, Block.NULL_BLOCK); } } return this; }