summaryrefslogtreecommitdiff
path: root/ext/java
diff options
context:
space:
mode:
authorCharles Oliver Nutter <headius@headius.com>2015-01-09 09:56:35 -0600
committerCharles Oliver Nutter <headius@headius.com>2015-01-09 10:05:43 -0600
commitea50d0179c51d271c9fead299e9bf6dd06fe9689 (patch)
tree039230edbd981782e00795d338989187077e27ed /ext/java
parentb6050d58f0fa8826353bde3d8d2de4428d80dadc (diff)
downloadpsych-ea50d0179c51d271c9fead299e9bf6dd06fe9689.tar.gz
Update to latest code from JRuby master.
Diffstat (limited to 'ext/java')
-rw-r--r--ext/java/PsychEmitter.java88
-rw-r--r--ext/java/PsychLibrary.java39
-rw-r--r--ext/java/PsychParser.java401
-rw-r--r--ext/java/PsychToRuby.java54
-rw-r--r--ext/java/PsychYamlTree.java17
5 files changed, 345 insertions, 254 deletions
diff --git a/ext/java/PsychEmitter.java b/ext/java/PsychEmitter.java
index 2a28872..d9f3231 100644
--- a/ext/java/PsychEmitter.java
+++ b/ext/java/PsychEmitter.java
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
- * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ * Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
- * The contents of this file are subject to the Common Public
+ * The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
- * the License at http://www.eclipse.org/legal/cpl-v10.html
+ * the License at http://www.eclipse.org/legal/epl-v10.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -19,19 +19,21 @@
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the CPL, indicate your
+ * use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
- * the terms of any one of the CPL, the GPL or the LGPL.
+ * the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/
-package psych;
+package org.jruby.ext.psych;
import java.io.IOException;
import java.io.OutputStreamWriter;
-import java.util.Collections;
+import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
+
+import org.jcodings.Encoding;
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
@@ -44,7 +46,6 @@ import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.IOOutputStream;
-import org.jruby.util.TypeConverter;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.emitter.Emitter;
import org.yaml.snakeyaml.emitter.EmitterException;
@@ -61,11 +62,13 @@ import org.yaml.snakeyaml.events.SequenceEndEvent;
import org.yaml.snakeyaml.events.SequenceStartEvent;
import org.yaml.snakeyaml.events.StreamEndEvent;
import org.yaml.snakeyaml.events.StreamStartEvent;
+
import static org.jruby.runtime.Visibility.*;
public class PsychEmitter extends RubyObject {
public static void initPsychEmitter(Ruby runtime, RubyModule psych) {
- RubyClass psychEmitter = runtime.defineClassUnder("Emitter", runtime.getObject(), new ObjectAllocator() {
+ RubyClass psychHandler = runtime.defineClassUnder("Handler", runtime.getObject(), runtime.getObject().getAllocator(), psych);
+ RubyClass psychEmitter = runtime.defineClassUnder("Emitter", psychHandler, new ObjectAllocator() {
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
return new PsychEmitter(runtime, klazz);
}
@@ -82,7 +85,25 @@ public class PsychEmitter extends RubyObject {
public IRubyObject initialize(ThreadContext context, IRubyObject io) {
options = new DumperOptions();
options.setIndent(2);
- emitter = new Emitter(new OutputStreamWriter(new IOOutputStream(io)), options);
+
+ this.io = io;
+
+ return context.nil;
+ }
+
+ @JRubyMethod(visibility = PRIVATE)
+ public IRubyObject initialize(ThreadContext context, IRubyObject io, IRubyObject rbOptions) {
+ IRubyObject width = rbOptions.callMethod(context, "line_width");
+ IRubyObject canonical = rbOptions.callMethod(context, "canonical");
+ IRubyObject level = rbOptions.callMethod(context, "indentation");
+
+ options = new DumperOptions();
+
+ options.setCanonical(canonical.isTrue());
+ options.setIndent((int)level.convertToInteger().getLongValue());
+ options.setWidth((int)width.convertToInteger().getLongValue());
+
+ this.io = io;
return context.nil;
}
@@ -92,10 +113,13 @@ public class PsychEmitter extends RubyObject {
if (!(encoding instanceof RubyFixnum)) {
throw context.runtime.newTypeError(encoding, context.runtime.getFixnum());
}
-
- // TODO: do something with encoding? perhaps at the stream level?
+
+ initEmitter(context, encoding);
+
StreamStartEvent event = new StreamStartEvent(NULL_MARK, NULL_MARK);
+
emit(context, event);
+
return this;
}
@@ -107,16 +131,26 @@ public class PsychEmitter extends RubyObject {
}
@JRubyMethod
- public IRubyObject start_document(ThreadContext context, IRubyObject version, IRubyObject tags, IRubyObject implicit) {
- Integer[] versionInts = null;
+ public IRubyObject start_document(ThreadContext context, IRubyObject _version, IRubyObject tags, IRubyObject implicit) {
+ DumperOptions.Version version = null;
boolean implicitBool = implicit.isTrue();
- Map<String, String> tagsMap = Collections.EMPTY_MAP;
+ Map<String, String> tagsMap = null;
- RubyArray versionAry = version.convertToArray();
+ RubyArray versionAry = _version.convertToArray();
if (versionAry.size() == 2) {
- versionInts = new Integer[] {1, 1};
- versionInts[0] = (int)versionAry.eltInternal(0).convertToInteger().getLongValue();
- versionInts[1] = (int)versionAry.eltInternal(1).convertToInteger().getLongValue();
+ int versionInt0 = (int)versionAry.eltInternal(0).convertToInteger().getLongValue();
+ int versionInt1 = (int)versionAry.eltInternal(1).convertToInteger().getLongValue();
+
+ if (versionInt0 == 1) {
+ if (versionInt1 == 0) {
+ version = DumperOptions.Version.V1_0;
+ } else if (versionInt1 == 1) {
+ version = DumperOptions.Version.V1_1;
+ }
+ }
+ if (version == null) {
+ throw context.runtime.newArgumentError("invalid YAML version: " + versionAry);
+ }
}
RubyArray tagsAry = tags.convertToArray();
@@ -135,14 +169,14 @@ public class PsychEmitter extends RubyObject {
}
}
- DocumentStartEvent event = new DocumentStartEvent(NULL_MARK, NULL_MARK, implicitBool, versionInts, tagsMap);
+ DocumentStartEvent event = new DocumentStartEvent(NULL_MARK, NULL_MARK, !implicitBool, version, tagsMap);
emit(context, event);
return this;
}
@JRubyMethod
public IRubyObject end_document(ThreadContext context, IRubyObject implicit) {
- DocumentEndEvent event = new DocumentEndEvent(NULL_MARK, NULL_MARK, implicit.isTrue());
+ DocumentEndEvent event = new DocumentEndEvent(NULL_MARK, NULL_MARK, !implicit.isTrue());
emit(context, event);
return this;
}
@@ -273,6 +307,8 @@ public class PsychEmitter extends RubyObject {
private void emit(ThreadContext context, Event event) {
try {
+ if (emitter == null) throw context.runtime.newRuntimeError("uninitialized emitter");
+
emitter.emit(event);
} catch (IOException ioe) {
throw context.runtime.newIOErrorFromException(ioe);
@@ -281,8 +317,18 @@ public class PsychEmitter extends RubyObject {
}
}
+ private void initEmitter(ThreadContext context, IRubyObject _encoding) {
+ if (emitter != null) throw context.runtime.newRuntimeError("already initialized emitter");
+
+ Encoding encoding = PsychLibrary.YAMLEncoding.values()[(int)_encoding.convertToInteger().getLongValue()].encoding;
+ Charset charset = context.runtime.getEncodingService().charsetForEncoding(encoding);
+
+ emitter = new Emitter(new OutputStreamWriter(new IOOutputStream(io, encoding), charset), options);
+ }
+
Emitter emitter;
DumperOptions options = new DumperOptions();
+ IRubyObject io;
private static final Mark NULL_MARK = new Mark(null, 0, 0, 0, null, 0);
diff --git a/ext/java/PsychLibrary.java b/ext/java/PsychLibrary.java
index 864a4f4..2d2141b 100644
--- a/ext/java/PsychLibrary.java
+++ b/ext/java/PsychLibrary.java
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
- * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ * Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
- * The contents of this file are subject to the Common Public
+ * The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
- * the License at http://www.eclipse.org/legal/cpl-v10.html
+ * the License at http://www.eclipse.org/legal/epl-v10.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -19,14 +19,18 @@
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the CPL, indicate your
+ * use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
- * the terms of any one of the CPL, the GPL or the LGPL.
+ * the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/
-package psych;
+package org.jruby.ext.psych;
+import org.jcodings.Encoding;
+import org.jcodings.specific.UTF16BEEncoding;
+import org.jcodings.specific.UTF16LEEncoding;
+import org.jcodings.specific.UTF8Encoding;
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyModule;
@@ -38,16 +42,18 @@ import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.load.Library;
public class PsychLibrary implements Library {
+ // NOTE: we add the last .0 for format compat with libyaml version numbers
+ // TODO: This should always reflect the SnakeYAML version
+ private static final String SNAKEYAML_VERSION = "1.13.0";
public void load(final Ruby runtime, boolean wrap) {
RubyModule psych = runtime.defineModule("Psych");
- RubyString version = runtime.newString("0.1.4");
+ RubyString version = runtime.newString(SNAKEYAML_VERSION);
version.setFrozen(true);
- final RubyArray versionElements = runtime.newArray(runtime.newFixnum(0), runtime.newFixnum(1), runtime.newFixnum(4));
+ final RubyArray versionElements = runtime.newArray(runtime.newFixnum(1), runtime.newFixnum(13), runtime.newFixnum(0));
versionElements.setFrozen(true);
-
- psych.setConstant("LIBYAML_VERSION", runtime.newString("0.1.4"));
+
psych.getSingletonClass().addMethod("libyaml_version", new JavaMethodZero(psych, Visibility.PUBLIC) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name) {
@@ -60,4 +66,17 @@ public class PsychLibrary implements Library {
PsychToRuby.initPsychToRuby(runtime, psych);
PsychYamlTree.initPsychYamlTree(runtime, psych);
}
+
+ public enum YAMLEncoding {
+ YAML_ANY_ENCODING(UTF8Encoding.INSTANCE),
+ YAML_UTF8_ENCODING(UTF8Encoding.INSTANCE),
+ YAML_UTF16LE_ENCODING(UTF16LEEncoding.INSTANCE),
+ YAML_UTF16BE_ENCODING(UTF16BEEncoding.INSTANCE);
+
+ YAMLEncoding(Encoding encoding) {
+ this.encoding = encoding;
+ }
+
+ public final Encoding encoding;
+ }
}
diff --git a/ext/java/PsychParser.java b/ext/java/PsychParser.java
index 25d8636..6bb7612 100644
--- a/ext/java/PsychParser.java
+++ b/ext/java/PsychParser.java
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
- * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ * Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
- * The contents of this file are subject to the Common Public
+ * The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
- * the License at http://www.eclipse.org/legal/cpl-v10.html
+ * the License at http://www.eclipse.org/legal/epl-v10.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -19,37 +19,41 @@
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the CPL, indicate your
+ * use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
- * the terms of any one of the CPL, the GPL or the LGPL.
+ * the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/
-package psych;
+package org.jruby.ext.psych;
+import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
-import java.io.StringReader;
+import java.nio.charset.Charset;
import java.util.Map;
-import org.jcodings.specific.UTF16BEEncoding;
-import org.jcodings.specific.UTF16LEEncoding;
+
+import org.jcodings.Encoding;
import org.jcodings.specific.UTF8Encoding;
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
import org.jruby.RubyEncoding;
-import org.jruby.RubyException;
import org.jruby.RubyIO;
import org.jruby.RubyKernel;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
import org.jruby.RubyString;
import org.jruby.anno.JRubyMethod;
+import static org.jruby.ext.psych.PsychLibrary.YAMLEncoding.*;
import org.jruby.runtime.Block;
+import org.jruby.runtime.Helpers;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.IOInputStream;
-import org.jruby.util.unsafe.UnsafeFactory;
+import org.jruby.util.log.Logger;
+import org.jruby.util.log.LoggerFactory;
+import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.error.Mark;
import org.yaml.snakeyaml.error.MarkedYAMLException;
import org.yaml.snakeyaml.events.AliasEvent;
@@ -66,14 +70,12 @@ import org.yaml.snakeyaml.parser.ParserImpl;
import org.yaml.snakeyaml.reader.ReaderException;
import org.yaml.snakeyaml.reader.StreamReader;
import org.yaml.snakeyaml.scanner.ScannerException;
-import static org.jruby.javasupport.util.RuntimeHelpers.invoke;
+import static org.jruby.runtime.Helpers.invoke;
+import org.jruby.util.ByteList;
public class PsychParser extends RubyObject {
- public static final int YAML_ANY_ENCODING = 0;
- public static final int YAML_UTF8_ENCODING = UTF8Encoding.INSTANCE.getIndex();
- public static final int YAML_UTF16LE_ENCODING = UTF16LEEncoding.INSTANCE.getIndex();
- public static final int YAML_UTF16BE_ENCODING = UTF16BEEncoding.INSTANCE.getIndex();
+ private static final Logger LOG = LoggerFactory.getLogger("PsychParser");
public static void initPsychParser(Ruby runtime, RubyModule psych) {
RubyClass psychParser = runtime.defineClassUnder("Parser", runtime.getObject(), new ObjectAllocator() {
@@ -82,14 +84,14 @@ public class PsychParser extends RubyObject {
}
}, psych);
- psychParser.defineConstant("ANY", runtime.newFixnum(YAML_ANY_ENCODING));
- psychParser.defineConstant("UTF8", runtime.newFixnum(YAML_UTF8_ENCODING));
- psychParser.defineConstant("UTF16LE", runtime.newFixnum(YAML_UTF16LE_ENCODING));
- psychParser.defineConstant("UTF16BE", runtime.newFixnum(YAML_UTF16BE_ENCODING));
+ RubyKernel.require(runtime.getNil(),
+ runtime.newString("psych/syntax_error"), Block.NULL_BLOCK);
+ psychParser.defineConstant("ANY", runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
+ psychParser.defineConstant("UTF8", runtime.newFixnum(YAML_UTF8_ENCODING.ordinal()));
+ psychParser.defineConstant("UTF16LE", runtime.newFixnum(YAML_UTF16LE_ENCODING.ordinal()));
+ psychParser.defineConstant("UTF16BE", runtime.newFixnum(YAML_UTF16BE_ENCODING.ordinal()));
psychParser.defineAnnotatedMethods(PsychParser.class);
-
- psych.defineClassUnder("SyntaxError", runtime.getSyntaxError(), RubyException.EXCEPTION_ALLOCATOR);
}
public PsychParser(Ruby runtime, RubyClass klass) {
@@ -100,26 +102,72 @@ public class PsychParser extends RubyObject {
public IRubyObject parse(ThreadContext context, IRubyObject yaml) {
Ruby runtime = context.runtime;
- return parse(context, yaml, RubyString.newString(runtime, "<unknown>"));
+ return parse(context, yaml, runtime.getNil());
+ }
+
+ private IRubyObject stringOrNilFor(Ruby runtime, String value, boolean tainted) {
+ if (value == null) return runtime.getNil(); // No need to taint nil
+
+ return stringFor(runtime, value, tainted);
+ }
+
+ private RubyString stringFor(Ruby runtime, String value, boolean tainted) {
+ Encoding encoding = runtime.getDefaultInternalEncoding();
+ if (encoding == null) {
+ encoding = UTF8Encoding.INSTANCE;
+ }
+
+ Charset charset = RubyEncoding.UTF8;
+ if (encoding.getCharset() != null) {
+ charset = encoding.getCharset();
+ }
+
+ ByteList bytes = new ByteList(value.getBytes(charset), encoding);
+ RubyString string = RubyString.newString(runtime, bytes);
+
+ string.setTaint(tainted);
+
+ return string;
+ }
+
+ private StreamReader readerFor(ThreadContext context, IRubyObject yaml) {
+ Ruby runtime = context.runtime;
+
+ if (yaml instanceof RubyString) {
+ ByteList byteList = ((RubyString)yaml).getByteList();
+ ByteArrayInputStream bais = new ByteArrayInputStream(byteList.getUnsafeBytes(), byteList.getBegin(), byteList.getRealSize());
+
+ Charset charset = byteList.getEncoding().getCharset();
+ if (charset == null) charset = Charset.defaultCharset();
+
+ InputStreamReader isr = new InputStreamReader(bais, charset);
+
+ return new StreamReader(isr);
+ }
+
+ // fall back on IOInputStream, using default charset
+ if (yaml.respondsTo("read")) {
+ Charset charset = (yaml instanceof RubyIO)
+ ? ((RubyIO)yaml).getReadEncoding().getCharset()
+ : Charset.defaultCharset();
+ return new StreamReader(new InputStreamReader(new IOInputStream(yaml), charset));
+ } else {
+ throw runtime.newTypeError(yaml, runtime.getIO());
+ }
}
@JRubyMethod
public IRubyObject parse(ThreadContext context, IRubyObject yaml, IRubyObject path) {
Ruby runtime = context.runtime;
- boolean tainted = yaml.isTaint();
-
- // FIXME? only supports Unicode, since we have to produces strings...
+ boolean tainted = yaml.isTaint() || yaml instanceof RubyIO;
+
try {
- StreamReader reader;
- if (yaml.respondsTo("read")) {
- reader = new StreamReader(new InputStreamReader(new IOInputStream(yaml), RubyEncoding.UTF8));
- if (yaml instanceof RubyIO) {
- tainted = true;
- }
- } else {
- reader = new StreamReader(new StringReader(yaml.convertToString().asJavaString()));
+ parser = new ParserImpl(readerFor(context, yaml));
+
+ if (path.isNil() && yaml.respondsTo("path")) {
+ path = yaml.callMethod(context, "path");
}
- parser = new ParserImpl(reader);
+
IRubyObject handler = getInstanceVariable("@handler");
while (true) {
@@ -127,184 +175,158 @@ public class PsychParser extends RubyObject {
// 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));
+ invoke(context, handler, "start_stream", runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
} else if (event.is(ID.DocumentStart)) {
- DocumentStartEvent dse = (DocumentStartEvent)event;
-
- Integer[] versionInts = dse.getVersion();
- IRubyObject version = versionInts == null ?
- RubyArray.newArray(runtime) :
- 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()) {
- RubyString key = RubyString.newString(runtime, tag.getKey());
- RubyString value = RubyString.newString(runtime, tag.getValue());
- key.setTaint(tainted);
- value.setTaint(tainted);
-
- tags.append(RubyArray.newArray(
- runtime,
- key,
- value));
- }
- }
-
- invoke(
- context,
- handler,
- "start_document",
- version,
- tags,
- runtime.newBoolean(!dse.getExplicit()));
+ handleDocumentStart(context, (DocumentStartEvent) event, tainted, handler);
} else if (event.is(ID.DocumentEnd)) {
- DocumentEndEvent dee = (DocumentEndEvent)event;
- invoke(
- context,
- handler,
- "end_document",
- runtime.newBoolean(!dee.getExplicit()));
+ IRubyObject notExplicit = runtime.newBoolean(!((DocumentEndEvent) event).getExplicit());
+
+ invoke(context, handler, "end_document", notExplicit);
} else if (event.is(ID.Alias)) {
- AliasEvent ae = (AliasEvent)event;
- IRubyObject alias = runtime.getNil();
- if (ae.getAnchor() != null) {
- alias = RubyString.newString(runtime, ae.getAnchor());
- alias.setTaint(tainted);
- }
-
- invoke(
- context,
- handler,
- "alias",
- alias);
+ IRubyObject alias = stringOrNilFor(runtime, ((AliasEvent)event).getAnchor(), tainted);
+
+ 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().canOmitTagInPlainScalar());
- IRubyObject quoted_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInNonPlainScalar());
- IRubyObject style = runtime.newFixnum(translateStyle(se.getStyle()));
- IRubyObject val = RubyString.newString(runtime, se.getValue());
-
- val.setTaint(tainted);
- anchor.setTaint(tainted);
- tag.setTaint(tainted);
-
- invoke(
- context,
- handler,
- "scalar",
- val,
- anchor,
- tag,
- plain_implicit,
- quoted_implicit,
- style);
+ handleScalar(context, (ScalarEvent) event, tainted, handler);
} 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(translateFlowStyle(sse.getFlowStyle()));
-
- anchor.setTaint(tainted);
- tag.setTaint(tainted);
-
- invoke(
- context,
- handler,
- "start_sequence",
- anchor,
- tag,
- implicit,
- style);
+ handleSequenceStart(context,(SequenceStartEvent) event, tainted, handler);
} else if (event.is(ID.SequenceEnd)) {
- invoke(
- context,
- handler,
- "end_sequence");
+ 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(translateFlowStyle(mse.getFlowStyle()));
-
- anchor.setTaint(tainted);
- tag.setTaint(tainted);
-
- invoke(
- context,
- handler,
- "start_mapping",
- anchor,
- tag,
- implicit,
- style);
+ handleMappingStart(context, (MappingStartEvent) event, tainted, handler);
} else if (event.is(ID.MappingEnd)) {
- invoke(
- context,
- handler,
- "end_mapping");
+ invoke(context, handler, "end_mapping");
} else if (event.is(ID.StreamEnd)) {
- invoke(
- context,
- handler,
- "end_stream");
+ invoke(context, handler, "end_stream");
+
break;
}
}
} catch (ParserException pe) {
parser = null;
- RubyKernel.raise(context, runtime.getKernel(),
- new IRubyObject[] {runtime.getModule("Psych").getConstant("SyntaxError"), runtime.newString(syntaxError(context, yaml, pe))},
- Block.NULL_BLOCK);
+ raiseParserException(context, yaml, pe, path);
+
} catch (ScannerException se) {
parser = null;
StringBuilder message = new StringBuilder("syntax error");
if (se.getProblemMark() != null) {
message.append(se.getProblemMark().toString());
}
- throw runtime.newArgumentError(message.toString());
+ raiseParserException(context, yaml, se, path);
+
} catch (ReaderException re) {
parser = null;
- RubyKernel.raise(context, runtime.getKernel(),
- new IRubyObject[] {runtime.getModule("Psych").getConstant("SyntaxError"), runtime.newString(re.getLocalizedMessage())},
- Block.NULL_BLOCK);
+ raiseParserException(context, yaml, re, path);
+
} catch (Throwable t) {
- UnsafeFactory.getUnsafe().throwException(t);
+ Helpers.throwException(t);
return this;
}
return this;
}
-
- private static String syntaxError(ThreadContext context, IRubyObject yaml, MarkedYAMLException mye) {
- String path;
- if (yaml.respondsTo("path")) {
- path = yaml.callMethod(context, "path").toString();
- } else {
- path = "<unknown>";
+
+ private void handleDocumentStart(ThreadContext context, DocumentStartEvent dse, boolean tainted, IRubyObject handler) {
+ Ruby runtime = context.runtime;
+ DumperOptions.Version _version = dse.getVersion();
+ Integer[] versionInts = _version == null ? null : _version.getArray();
+ IRubyObject version = versionInts == null ?
+ RubyArray.newArray(runtime) :
+ RubyArray.newArray(runtime, runtime.newFixnum(versionInts[0]), runtime.newFixnum(versionInts[1]));
+
+ Map<String, String> tagsMap = dse.getTags();
+ RubyArray tags = RubyArray.newArray(runtime);
+ if (tagsMap != null && tagsMap.size() > 0) {
+ for (Map.Entry<String, String> tag : tagsMap.entrySet()) {
+ IRubyObject key = stringFor(runtime, tag.getKey(), tainted);
+ IRubyObject value = stringFor(runtime, tag.getValue(), tainted);
+
+ tags.append(RubyArray.newArray(runtime, key, value));
+ }
}
- return path + ": couldn't parse YAML at line " + mye.getProblemMark().getLine() + " column " + mye.getProblemMark().getColumn();
+ IRubyObject notExplicit = runtime.newBoolean(!dse.getExplicit());
+
+ invoke(context, handler, "start_document", version, tags, notExplicit);
+ }
+
+ private void handleMappingStart(ThreadContext context, MappingStartEvent mse, boolean tainted, IRubyObject handler) {
+ Ruby runtime = context.runtime;
+ IRubyObject anchor = stringOrNilFor(runtime, mse.getAnchor(), tainted);
+ IRubyObject tag = stringOrNilFor(runtime, mse.getTag(), tainted);
+ IRubyObject implicit = runtime.newBoolean(mse.getImplicit());
+ IRubyObject style = runtime.newFixnum(translateFlowStyle(mse.getFlowStyle()));
+
+ invoke(context, handler, "start_mapping", anchor, tag, implicit, style);
+ }
+
+ private void handleScalar(ThreadContext context, ScalarEvent se, boolean tainted, IRubyObject handler) {
+ Ruby runtime = context.runtime;
+ IRubyObject anchor = stringOrNilFor(runtime, se.getAnchor(), tainted);
+ IRubyObject tag = stringOrNilFor(runtime, se.getTag(), tainted);
+ IRubyObject plain_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInPlainScalar());
+ IRubyObject quoted_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInNonPlainScalar());
+ IRubyObject style = runtime.newFixnum(translateStyle(se.getStyle()));
+ IRubyObject val = stringFor(runtime, se.getValue(), tainted);
+
+ invoke(context, handler, "scalar", val, anchor, tag, plain_implicit,
+ quoted_implicit, style);
+ }
+
+ private void handleSequenceStart(ThreadContext context, SequenceStartEvent sse, boolean tainted, IRubyObject handler) {
+ Ruby runtime = context.runtime;
+ IRubyObject anchor = stringOrNilFor(runtime, sse.getAnchor(), tainted);
+ IRubyObject tag = stringOrNilFor(runtime, sse.getTag(), tainted);
+ IRubyObject implicit = runtime.newBoolean(sse.getImplicit());
+ IRubyObject style = runtime.newFixnum(translateFlowStyle(sse.getFlowStyle()));
+
+ invoke(context, handler, "start_sequence", anchor, tag, implicit, style);
+ }
+
+ private static void raiseParserException(ThreadContext context, IRubyObject yaml, ReaderException re, IRubyObject rbPath) {
+ Ruby runtime;
+ RubyClass se;
+ IRubyObject exception;
+
+ runtime = context.runtime;
+ se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
+
+ exception = se.newInstance(context,
+ new IRubyObject[] {
+ rbPath,
+ runtime.newFixnum(0),
+ runtime.newFixnum(0),
+ runtime.newFixnum(re.getPosition()),
+ (null == re.getName() ? runtime.getNil() : runtime.newString(re.getName())),
+ (null == re.toString() ? runtime.getNil() : runtime.newString(re.toString()))
+ },
+ Block.NULL_BLOCK);
+
+ RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
+ }
+
+ private static void raiseParserException(ThreadContext context, IRubyObject yaml, MarkedYAMLException mye, IRubyObject rbPath) {
+ Ruby runtime;
+ Mark mark;
+ RubyClass se;
+ IRubyObject exception;
+
+ runtime = context.runtime;
+ se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
+
+ mark = mye.getProblemMark();
+
+ exception = se.newInstance(context,
+ new IRubyObject[] {
+ rbPath,
+ runtime.newFixnum(mark.getLine() + 1),
+ runtime.newFixnum(mark.getColumn() + 1),
+ runtime.newFixnum(mark.getIndex()),
+ (null == mye.getProblem() ? runtime.getNil() : runtime.newString(mye.getProblem())),
+ (null == mye.getContext() ? runtime.getNil() : runtime.newString(mye.getContext()))
+ },
+ Block.NULL_BLOCK);
+
+ RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
}
private static int translateStyle(Character style) {
@@ -335,9 +357,8 @@ public class PsychParser extends RubyObject {
if (parser != null) {
event = parser.peekEvent();
- if (event == null) {
- event = this.event;
- }
+
+ if (event == null) event = this.event;
}
if (event == null) {
@@ -361,12 +382,6 @@ public class PsychParser extends RubyObject {
);
}
- @JRubyMethod(name = "external_encoding=")
- public IRubyObject external_encoding_set(ThreadContext context, IRubyObject encoding) {
- // stubbed
- return encoding;
- }
-
private Parser parser;
private Event event;
}
diff --git a/ext/java/PsychToRuby.java b/ext/java/PsychToRuby.java
index c60a913..39f7c42 100644
--- a/ext/java/PsychToRuby.java
+++ b/ext/java/PsychToRuby.java
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
- * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ * Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
- * The contents of this file are subject to the Common Public
+ * The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
- * the License at http://www.eclipse.org/legal/cpl-v10.html
+ * the License at http://www.eclipse.org/legal/epl-v10.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -19,18 +19,19 @@
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the CPL, indicate your
+ * use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
- * the terms of any one of the CPL, the GPL or the LGPL.
+ * the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/
-package psych;
+package org.jruby.ext.psych;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
+import org.jruby.RubyException;
import org.jruby.anno.JRubyMethod;
import org.jruby.exceptions.RaiseException;
import org.jruby.runtime.ThreadContext;
@@ -39,33 +40,40 @@ import static org.jruby.runtime.Visibility.*;
public class PsychToRuby {
public static void initPsychToRuby(Ruby runtime, RubyModule psych) {
+ RubyClass classLoader = runtime.defineClassUnder("ClassLoader", runtime.getObject(), RubyObject.OBJECT_ALLOCATOR, psych);
+
RubyModule visitors = runtime.defineModuleUnder("Visitors", psych);
RubyClass visitor = runtime.defineClassUnder("Visitor", runtime.getObject(), runtime.getObject().getAllocator(), visitors);
RubyClass psychToRuby = runtime.defineClassUnder("ToRuby", visitor, RubyObject.OBJECT_ALLOCATOR, visitors);
- psychToRuby.defineAnnotatedMethods(PsychToRuby.class);
+ psychToRuby.defineAnnotatedMethods(ToRuby.class);
+ classLoader.defineAnnotatedMethods(ClassLoader.class);
}
- @JRubyMethod(visibility = PRIVATE)
- public static IRubyObject build_exception(ThreadContext context, IRubyObject self, IRubyObject klass, IRubyObject message) {
- if (klass instanceof RubyClass) {
- IRubyObject exception = ((RubyClass)klass).allocate();
- exception.getInternalVariables().setInternalVariable("mesg", message);
- return exception;
- } else {
- throw context.runtime.newTypeError(klass, context.runtime.getClassClass());
+ public static class ToRuby {
+ @JRubyMethod(visibility = PRIVATE)
+ public static IRubyObject build_exception(ThreadContext context, IRubyObject self, IRubyObject klass, IRubyObject message) {
+ if (klass instanceof RubyClass) {
+ IRubyObject exception = ((RubyClass)klass).allocate();
+ ((RubyException)exception).message = message;
+ return exception;
+ } else {
+ throw context.runtime.newTypeError(klass, context.runtime.getClassClass());
+ }
}
}
- @JRubyMethod(visibility = PRIVATE)
- public static IRubyObject path2class(ThreadContext context, IRubyObject self, IRubyObject path) {
- try {
- return context.runtime.getClassFromPath(path.asJavaString());
- } catch (RaiseException re) {
- if (re.getException().getMetaClass() == context.runtime.getNameError()) {
- throw context.runtime.newArgumentError("undefined class/module " + path);
+ public static class ClassLoader {
+ @JRubyMethod(visibility = PRIVATE)
+ public static IRubyObject path2class(ThreadContext context, IRubyObject self, IRubyObject path) {
+ try {
+ return context.runtime.getClassFromPath(path.asJavaString());
+ } catch (RaiseException re) {
+ if (re.getException().getMetaClass() == context.runtime.getNameError()) {
+ throw context.runtime.newArgumentError("undefined class/module " + path);
+ }
+ throw re;
}
- throw re;
}
}
}
diff --git a/ext/java/PsychYamlTree.java b/ext/java/PsychYamlTree.java
index d22148b..fdd16df 100644
--- a/ext/java/PsychYamlTree.java
+++ b/ext/java/PsychYamlTree.java
@@ -1,10 +1,10 @@
/***** BEGIN LICENSE BLOCK *****
- * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ * Version: EPL 1.0/GPL 2.0/LGPL 2.1
*
- * The contents of this file are subject to the Common Public
+ * The contents of this file are subject to the Eclipse Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
- * the License at http://www.eclipse.org/legal/cpl-v10.html
+ * the License at http://www.eclipse.org/legal/epl-v10.html
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
@@ -19,13 +19,13 @@
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the CPL, indicate your
+ * use your version of this file under the terms of the EPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
- * the terms of any one of the CPL, the GPL or the LGPL.
+ * the terms of any one of the EPL, the GPL or the LGPL.
***** END LICENSE BLOCK *****/
-package psych;
+package org.jruby.ext.psych;
import org.jruby.Ruby;
import org.jruby.RubyClass;
@@ -47,6 +47,9 @@ public class PsychYamlTree {
@JRubyMethod(visibility = PRIVATE)
public static IRubyObject private_iv_get(ThreadContext context, IRubyObject self, IRubyObject target, IRubyObject prop) {
- return target.getInstanceVariables().getInstanceVariable(prop.asJavaString());
+ IRubyObject obj = (IRubyObject)target.getInternalVariables().getInternalVariable(prop.asJavaString());
+ if (obj == null) obj = context.nil;
+
+ return obj;
}
}