Introduce LoaderOptions to be able to specify configuration while loading
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 5a719b6..bf5cc46 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -7,6 +7,9 @@
</properties>
<body>
<release version="1.8-SNAPSHOT" date="in Mercurial" description="Performance improvement">
+ <action dev="py4fun" type="update" issue="79">
+ Introduce LoaderOptions to be able to specify configuration while loading (2010-09-03)
+ </action>
<action dev="py4fun" type="fix" issue="81">
Representer.representJavaBeanProperty() is given the wrong tag. Instead of the property tag,
the tag for the JavaBean itself is provided. (2010-09-01)
diff --git a/src/main/java/org/yaml/snakeyaml/LoaderOptions.java b/src/main/java/org/yaml/snakeyaml/LoaderOptions.java
new file mode 100644
index 0000000..c19c7b8
--- /dev/null
+++ b/src/main/java/org/yaml/snakeyaml/LoaderOptions.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2008-2010, http://code.google.com/p/snakeyaml/
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.yaml.snakeyaml;
+
+public class LoaderOptions {
+ private final Mode mode;
+
+ public enum Mode {
+ /**
+ * Store context with a Mark to have a better error message. Loader
+ * works 40% slower and it consumes much more memory (default=false)
+ */
+ CONTEXT_MARK(1),
+ /**
+ * Disable implicit types when JavaBean is loaded (default=true). When
+ * this is present then USE_IMPLICIT_TYPES is ignored.
+ */
+ DYNAMIC_IMPLICIT_TYPES(2),
+ /**
+ * When DYNAMIC_IMPLICIT_TYPES is 'false' defines whether to apply the
+ * regular expressions. When implicit types are not used all the scalars
+ * are Strings. Enable this when JavaBean has a property which is a
+ * generic collections like Map<String, Integer>
+ */
+ USE_IMPLICIT_TYPES(4),
+ /**
+ * Enable compact format for JavaBeans
+ */
+ COMPACT_FORMAT(8);
+
+ private final int mask;
+
+ private Mode(int mask) {
+ this.mask = mask;
+ }
+
+ public boolean hasMode(Mode mode) {
+ return (mode.mask & this.mask) == mode.mask;
+ }
+ }
+
+ public LoaderOptions(Mode mode) {
+ this.mode = mode;
+ }
+
+ public LoaderOptions() {
+ this(Mode.DYNAMIC_IMPLICIT_TYPES);
+ }
+
+ public boolean hasMode(Mode mode) {
+ return this.mode.hasMode(mode);
+ }
+}
diff --git a/src/main/java/org/yaml/snakeyaml/Yaml.java b/src/main/java/org/yaml/snakeyaml/Yaml.java
index de69427..f500894 100644
--- a/src/main/java/org/yaml/snakeyaml/Yaml.java
+++ b/src/main/java/org/yaml/snakeyaml/Yaml.java
@@ -52,7 +52,7 @@
protected BaseConstructor constructor;
protected Representer representer;
protected DumperOptions options;
- protected boolean attachBufferToMark = true;
+ protected LoaderOptions loaderOptions = new LoaderOptions();
/**
* Create Yaml instance. It is safe to create a few instances and use them
@@ -62,6 +62,11 @@
this(new Constructor(), new Representer(), new DumperOptions(), new Resolver());
}
+ public Yaml(LoaderOptions loaderOptions) {
+ this(new Constructor(), loaderOptions, new Representer(), new DumperOptions(),
+ new Resolver());
+ }
+
/**
* Create Yaml instance.
*
@@ -150,12 +155,33 @@
*/
public Yaml(BaseConstructor constructor, Representer representer, DumperOptions options,
Resolver resolver) {
+ this(constructor, new LoaderOptions(), representer, options, resolver);
+ }
+
+ /**
+ * Create Yaml instance. It is safe to create a few instances and use them
+ * in different Threads.
+ *
+ * @param constructor
+ * BaseConstructor to construct incoming documents
+ * @param loaderOptions
+ * LoaderOptions to control construction process
+ * @param representer
+ * Representer to emit outgoing objects
+ * @param options
+ * DumperOptions to configure outgoing objects
+ * @param resolver
+ * Resolver to detect implicit type
+ */
+ public Yaml(BaseConstructor constructor, LoaderOptions loaderOptions, Representer representer,
+ DumperOptions options, Resolver resolver) {
if (!constructor.isExplicitPropertyUtils()) {
constructor.setPropertyUtils(representer.getPropertyUtils());
} else if (!representer.isExplicitPropertyUtils()) {
representer.setPropertyUtils(constructor.getPropertyUtils());
}
this.constructor = constructor;
+ this.loaderOptions = loaderOptions;
representer.setDefaultFlowStyle(options.getDefaultFlowStyle());
representer.setDefaultScalarStyle(options.getDefaultScalarStyle());
representer.getPropertyUtils().setAllowReadOnlyProperties(
@@ -260,8 +286,8 @@
* @return parsed object
*/
public Object load(Reader io) {
- Composer composer = new Composer(new ParserImpl(new StreamReader(io, attachBufferToMark)),
- resolver);
+ Composer composer = new Composer(new ParserImpl(new StreamReader(io, loaderOptions
+ .hasMode(LoaderOptions.Mode.CONTEXT_MARK))), resolver);
constructor.setComposer(composer);
return constructor.getSingleData();
}
@@ -276,8 +302,8 @@
* sequence
*/
public Iterable<Object> loadAll(Reader yaml) {
- Composer composer = new Composer(
- new ParserImpl(new StreamReader(yaml, attachBufferToMark)), resolver);
+ Composer composer = new Composer(new ParserImpl(new StreamReader(yaml, loaderOptions
+ .hasMode(LoaderOptions.Mode.CONTEXT_MARK))), resolver);
constructor.setComposer(composer);
Iterator<Object> result = new Iterator<Object>() {
public boolean hasNext() {
@@ -343,8 +369,8 @@
* @return parsed root Node for the specified YAML document
*/
public Node compose(Reader yaml) {
- Composer composer = new Composer(
- new ParserImpl(new StreamReader(yaml, attachBufferToMark)), resolver);
+ Composer composer = new Composer(new ParserImpl(new StreamReader(yaml, loaderOptions
+ .hasMode(LoaderOptions.Mode.CONTEXT_MARK))), resolver);
constructor.setComposer(composer);
return composer.getSingleNode();
}
@@ -358,8 +384,8 @@
* @return parsed root Nodes for all the specified YAML documents
*/
public Iterable<Node> composeAll(Reader yaml) {
- final Composer composer = new Composer(new ParserImpl(new StreamReader(yaml,
- attachBufferToMark)), resolver);
+ final Composer composer = new Composer(new ParserImpl(new StreamReader(yaml, loaderOptions
+ .hasMode(LoaderOptions.Mode.CONTEXT_MARK))), resolver);
constructor.setComposer(composer);
Iterator<Node> result = new Iterator<Node>() {
public boolean hasNext() {
@@ -457,7 +483,8 @@
* @return parsed events
*/
public Iterable<Event> parse(Reader yaml) {
- final Parser parser = new ParserImpl(new StreamReader(yaml, attachBufferToMark));
+ final Parser parser = new ParserImpl(new StreamReader(yaml, loaderOptions
+ .hasMode(LoaderOptions.Mode.CONTEXT_MARK)));
Iterator<Event> result = new Iterator<Event>() {
public boolean hasNext() {
return parser.peekEvent() != null;
@@ -491,10 +518,6 @@
representer.getPropertyUtils().setBeanAccess(beanAccess);
}
- public void setAttachBufferToMark(boolean attachBufferToMark) {
- this.attachBufferToMark = attachBufferToMark;
- }
-
// deprecated
/**
* @deprecated use with Constructor instead of Loader
diff --git a/src/test/java/org/yaml/snakeyaml/LoaderOptionsTest.java b/src/test/java/org/yaml/snakeyaml/LoaderOptionsTest.java
new file mode 100644
index 0000000..b12e0cd
--- /dev/null
+++ b/src/test/java/org/yaml/snakeyaml/LoaderOptionsTest.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2008-2010, http://code.google.com/p/snakeyaml/
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.yaml.snakeyaml;
+
+import junit.framework.TestCase;
+
+public class LoaderOptionsTest extends TestCase {
+
+ public void testGetMode() {
+ LoaderOptions defaultOptions = new LoaderOptions();
+ assertTrue(defaultOptions.hasMode(LoaderOptions.Mode.DYNAMIC_IMPLICIT_TYPES));
+ assertFalse(defaultOptions.hasMode(LoaderOptions.Mode.CONTEXT_MARK));
+ assertFalse(defaultOptions.hasMode(LoaderOptions.Mode.USE_IMPLICIT_TYPES));
+ assertFalse(defaultOptions.hasMode(LoaderOptions.Mode.COMPACT_FORMAT));
+ }
+}
diff --git a/src/test/java/org/yaml/snakeyaml/LoaderTest.java b/src/test/java/org/yaml/snakeyaml/LoaderTest.java
index 651b842..daec735 100644
--- a/src/test/java/org/yaml/snakeyaml/LoaderTest.java
+++ b/src/test/java/org/yaml/snakeyaml/LoaderTest.java
@@ -53,7 +53,7 @@
}
public void testCompose2() {
- Yaml loader = new Yaml();
+ Yaml loader = new Yaml(new LoaderOptions(LoaderOptions.Mode.CONTEXT_MARK));
String yaml = "3";
ScalarNode node = (ScalarNode) loader.compose(new StringReader(yaml));
assertEquals(Tag.INT, node.getTag());
@@ -71,9 +71,7 @@
}
public void testCompose3() {
- Yaml loader = new Yaml();
- // switch off the context for snippet
- loader.setAttachBufferToMark(false);
+ Yaml loader = new Yaml();// switch off the context for snippet
String yaml = "3";
ScalarNode node = (ScalarNode) loader.compose(new StringReader(yaml));
Mark mark = node.getStartMark();
diff --git a/src/test/java/org/yaml/snakeyaml/ParallelTest.java b/src/test/java/org/yaml/snakeyaml/ParallelTest.java
index ebb640f..b6b71ae 100644
--- a/src/test/java/org/yaml/snakeyaml/ParallelTest.java
+++ b/src/test/java/org/yaml/snakeyaml/ParallelTest.java
@@ -57,7 +57,6 @@
public void run() {
System.out.println("Started: " + id);
Yaml yaml = new Yaml(new Constructor(Invoice.class));
- yaml.setAttachBufferToMark(false);
long time1 = System.nanoTime();
int cycles = 200;
for (int i = 0; i < cycles; i++) {
diff --git a/src/test/java/org/yaml/snakeyaml/StressTest.java b/src/test/java/org/yaml/snakeyaml/StressTest.java
index 3ff3e60..ecdcc7d 100644
--- a/src/test/java/org/yaml/snakeyaml/StressTest.java
+++ b/src/test/java/org/yaml/snakeyaml/StressTest.java
@@ -37,7 +37,6 @@
System.out.println("Init was " + duration + " ms.");
Yaml yaml = new Yaml(new Constructor(Invoice.class));
- yaml.setAttachBufferToMark(false);
time1 = System.nanoTime();
yaml.load(doc);
time2 = System.nanoTime();
@@ -45,7 +44,6 @@
System.out.println("\nSingle load was " + duration + " ms.");
yaml = new Yaml(new Constructor(Invoice.class));
- yaml.setAttachBufferToMark(false);
int[] range = new int[] { 1000, 2000 };
System.out.println("\nOne instance.");
for (int number : range) {
@@ -68,7 +66,6 @@
time1 = System.nanoTime();
for (int i = 0; i < number; i++) {
yaml = new Yaml(new Constructor(Invoice.class));
- yaml.setAttachBufferToMark(false);
yaml.load(doc);
}
time2 = System.nanoTime();
diff --git a/src/test/java/org/yaml/snakeyaml/issues/issue67/NonAsciiCharsInClassNameTest.java b/src/test/java/org/yaml/snakeyaml/issues/issue67/NonAsciiCharsInClassNameTest.java
index 0fb4aa3..34291c7 100644
--- a/src/test/java/org/yaml/snakeyaml/issues/issue67/NonAsciiCharsInClassNameTest.java
+++ b/src/test/java/org/yaml/snakeyaml/issues/issue67/NonAsciiCharsInClassNameTest.java
@@ -18,6 +18,7 @@
import junit.framework.TestCase;
+import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Util;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Tag;
@@ -57,7 +58,7 @@
public void testLoadInvalidPatternTooShort() {
try {
- Yaml yaml = new Yaml();
+ Yaml yaml = new Yaml(new LoaderOptions(LoaderOptions.Mode.CONTEXT_MARK));
yaml.load(PREFIX + "Acad%9%A9mico {id: 3, name: Foo bar}");
fail("Illegal hex characters in escape (%) pattern must not be accepted.");
} catch (ScannerException e) {
@@ -70,7 +71,7 @@
public void testLoadInvalidUtf8() {
try {
- Yaml yaml = new Yaml();
+ Yaml yaml = new Yaml(new LoaderOptions(LoaderOptions.Mode.CONTEXT_MARK));
yaml.load(PREFIX + "Acad%C0mico {id: 3, name: Foo bar}");
fail("Illegal UTF-8 must not be accepted.");
} catch (ScannerException e) {