Skip to content
Commits on Source (6)
......@@ -21,4 +21,5 @@ SnakeYAML is a YAML processor for the Java Virtual Machine.
* Mercurial DVCS is used to dance with the [source code](https://bitbucket.org/asomov/snakeyaml/src).
* If you find a bug in SnakeYAML, please [file a bug report](https://bitbucket.org/asomov/snakeyaml/issues?status=new&status=open).
* You may discuss SnakeYAML at
[the mailing list](http://groups.google.com/group/snakeyaml-core).
\ No newline at end of file
[the mailing list](http://groups.google.com/group/snakeyaml-core).
* Feel free to join the [YAML-dev Telegram group](https://t.me/joinchat/A6K7rhBzRfHcP-0XnTxnhA)
\ No newline at end of file
......@@ -3,10 +3,12 @@
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: maven:3-jdk-9
image: maven:3-jdk-9-slim
pipelines:
default:
- step:
caches:
- maven
script: # Modify the commands below to build your repository.
- mvn -Pwith-java9-tests clean install
- mvn -V -B -Pwith-java9-tests clean install
snakeyaml (1.21-1) unstable; urgency=medium
* Team upload.
* New upstream release.
* Bump Standards-Version to 4.1.4. No changes were required.
* Migrate Vcs-* URLs to salsa.d.o.
-- Miguel Landaeta <nomadium@debian.org> Sun, 03 Jun 2018 17:02:57 +0100
snakeyaml (1.20-1) unstable; urgency=medium
* Team upload.
......
......@@ -15,9 +15,9 @@ Build-Depends:
libspring-context-java,
maven-debian-helper (>= 1.6.5),
velocity
Standards-Version: 4.1.3
Vcs-Git: https://anonscm.debian.org/git/pkg-java/snakeyaml.git
Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/snakeyaml.git
Standards-Version: 4.1.4
Vcs-Git: https://salsa.debian.org/java-team/snakeyaml.git
Vcs-Browser: https://salsa.debian.org/java-team/snakeyaml
Homepage: https://bitbucket.org/asomov/snakeyaml
Package: libyaml-snake-java
......
#!/usr/bin/env bash
./docker-run.sh 9 -Pwith-java9-tests
./docker-run.sh 9-slim -Pwith-java9-tests
......@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.20</version>
<version>1.21</version>
<packaging>bundle</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......@@ -42,7 +42,7 @@
<connection>scm:hg:http://bitbucket.org/asomov/snakeyaml</connection>
<developerConnection>scm:hg:ssh://hg@bitbucket.org/asomov/snakeyaml</developerConnection>
<url>https://bitbucket.org/asomov/snakeyaml/src</url>
<tag>snakeyaml-1.20</tag>
<tag>snakeyaml-1.21</tag>
</scm>
<licenses>
<license>
......@@ -266,7 +266,7 @@
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<links>
<link>http://java.sun.com/javase/6/docs/api/</link>
<link>https://docs.oracle.com/javase/6/docs/api/</link>
</links>
</configuration>
<executions>
......
......@@ -5,7 +5,25 @@
<title>YAML 1.1 parser and emitter</title>
</properties>
<body>
<release version="1.20-SNAPSHOT" date="in Mercurial" description="Maintenance">
<release version="1.21" date="2018-04-13" description="Maintenance">
<action dev="asomov" type="update">
Scanner throws IndexOutOfBoundsException if no more token left but getToken()
or peekToken() called (2018-04-10)
</action>
<action dev="asomov" type="update">
Enhance output of token IDs (2018-04-06)
</action>
<action dev="asomov" type="add">
Mark: expose buffer and pointer (2018-04-06)
</action>
<action dev="asomov" type="fix" issue="401">
Restore index in Mark - it is used in JRuby (2018-03-26)
</action>
<action dev="asomov" type="fix" issue="397">
Plain scalars with colons in flow sequences/mappings are valid YAML (2018-03-03)
</action>
</release>
<release version="1.20-SNAPSHOT" date="2018-02-28" description="Maintenance">
<action dev="maslovalex" type="fix" issue="393">
Improve reflective access operation to avoid warning under Java 9 (2018-02-24)
</action>
......
......@@ -374,11 +374,11 @@ public class TypeDescription {
}
/**
* This method should be overriden for TypeDescription implementations that are supposed to implement
* This method should be overridden for TypeDescription implementations that are supposed to implement
* instantiation logic that is different from default one as implemented in YAML constructors.
* Note that even if you override this method, default filling of fields with
* variables from parsed YAML will still occur later.
* @param node - node to contruct the instance from
* @param node - node to construct the instance from
* @return new instance
*/
public Object newInstance(Node node) {
......
......@@ -607,7 +607,6 @@ public class Yaml {
*/
public Node compose(Reader yaml) {
Composer composer = new Composer(new ParserImpl(new StreamReader(yaml)), resolver);
constructor.setComposer(composer);
return composer.getSingleNode();
}
......@@ -622,7 +621,6 @@ public class Yaml {
*/
public Iterable<Node> composeAll(Reader yaml) {
final Composer composer = new Composer(new ParserImpl(new StreamReader(yaml)), resolver);
constructor.setComposer(composer);
Iterator<Node> result = new Iterator<Node>() {
@Override
public boolean hasNext() {
......
......@@ -22,7 +22,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.events.AliasEvent;
import org.yaml.snakeyaml.events.Event;
import org.yaml.snakeyaml.events.MappingStartEvent;
......@@ -77,15 +76,18 @@ public class Composer {
* Reads and composes the next document.
*
* @return The root node of the document or <code>null</code> if no more
* documents are available.
* documents are available.
*/
public Node getNode() {
// Get the root node of the next document.
if (!parser.checkEvent(Event.ID.StreamEnd)) {
return composeDocument();
} else {
return null;
}
// Drop the DOCUMENT-START event.
parser.getEvent();
// Compose the root node.
Node node = composeNode(null);
// Drop the DOCUMENT-END event.
parser.getEvent();
this.anchors.clear();
recursiveNodes.clear();
return node;
}
/**
......@@ -95,7 +97,7 @@ public class Composer {
* </p>
*
* @return The root node of the document or <code>null</code> if no document
* is available.
* is available.
*/
public Node getSingleNode() {
// Drop the STREAM-START event.
......@@ -103,7 +105,7 @@ public class Composer {
// Compose a document if the stream is not empty.
Node document = null;
if (!parser.checkEvent(Event.ID.StreamEnd)) {
document = composeDocument();
document = getNode();
}
// Ensure that the stream contains no more documents.
if (!parser.checkEvent(Event.ID.StreamEnd)) {
......@@ -116,21 +118,9 @@ public class Composer {
return document;
}
private Node composeDocument() {
// Drop the DOCUMENT-START event.
parser.getEvent();
// Compose the root node.
Node node = composeNode(null);
// Drop the DOCUMENT-END event.
parser.getEvent();
this.anchors.clear();
recursiveNodes.clear();
return node;
}
private Node composeNode(Node parent) {
recursiveNodes.add(parent);
Node node = null;
if (parent != null) recursiveNodes.add(parent);
final Node node;
if (parser.checkEvent(Event.ID.Alias)) {
AliasEvent event = (AliasEvent) parser.getEvent();
String anchor = event.getAnchor();
......@@ -144,8 +134,7 @@ public class Composer {
}
} else {
NodeEvent event = (NodeEvent) parser.peekEvent();
String anchor = null;
anchor = event.getAnchor();
String anchor = event.getAnchor();
// the check for duplicate anchors has been removed (issue 174)
if (parser.checkEvent(Event.ID.Scalar)) {
node = composeScalarNode(anchor);
......
......@@ -97,7 +97,7 @@ public abstract class BaseConstructor {
typeDefinitions.put(SortedSet.class, new TypeDescription(SortedSet.class, Tag.SET,
TreeSet.class));
}
public void setComposer(Composer composer) {
this.composer = composer;
}
......@@ -132,8 +132,7 @@ public abstract class BaseConstructor {
*
* @param type the class of the instance being created
* @return constructed instance
* @throws ComposerException
* in case there are more documents in the stream
* @throws ComposerException in case there are more documents in the stream
*/
public Object getSingleData(Class<?> type) {
// Ensure that the stream contains a single document and construct it
......@@ -153,8 +152,7 @@ public abstract class BaseConstructor {
* Construct complete YAML document. Call the second step in case of
* recursive structures. At the end cleans all the state.
*
* @param node
* root Node
* @param node root Node
* @return Java instance
*/
protected final Object constructDocument(Node node) {
......@@ -185,8 +183,7 @@ public abstract class BaseConstructor {
* Construct object from the specified Node. Return existing instance if the
* node is already constructed.
*
* @param node
* Node to be constructed
* @param node Node to be constructed
* @return Java instance
*/
protected Object constructObject(Node node) {
......@@ -220,9 +217,8 @@ public abstract class BaseConstructor {
* runtime class is known a dedicated Construct implementation is used.
* Otherwise the constructor is chosen by the tag.
*
* @param node
* Node to be constructed
* @return Construct implementation for the specified node
* @param node {@link Node} to construct an instance from
* @return {@link Construct} implementation for the specified node
*/
protected Construct getConstructor(Node node) {
if (node.useClassConstructor()) {
......@@ -241,7 +237,7 @@ public abstract class BaseConstructor {
}
}
protected Object constructScalar(ScalarNode node) {
protected String constructScalar(ScalarNode node) {
return node.getValue();
}
......@@ -254,14 +250,9 @@ public abstract class BaseConstructor {
return new LinkedHashSet<Object>(initSize);
}
protected Map<Object, Object> createDefaultMap() {
// respect order from YAML document
return new LinkedHashMap<Object, Object>();
}
protected Set<Object> createDefaultSet() {
protected Map<Object, Object> createDefaultMap(int initSize) {
// respect order from YAML document
return new LinkedHashSet<Object>();
return new LinkedHashMap<Object, Object>(initSize);
}
protected Object createArray(Class<?> type, int size) {
......@@ -345,7 +336,7 @@ public abstract class BaseConstructor {
try {
return (Map<Object, Object>) newInstance(Map.class, node);
} catch (InstantiationException e) {
return createDefaultMap();
return createDefaultMap(node.getValue().size());
}
}
......@@ -538,10 +529,9 @@ public abstract class BaseConstructor {
* assigned in constructor then the 'root' property of this definition is
* respected.
*
* @param definition
* to be added to the Constructor
* @param definition to be added to the Constructor
* @return the previous value associated with <tt>definition</tt>, or
* <tt>null</tt> if there was no mapping for <tt>definition</tt>.
* <tt>null</tt> if there was no mapping for <tt>definition</tt>.
*/
public TypeDescription addTypeDescription(TypeDescription definition) {
if (definition == null) {
......
......@@ -305,16 +305,14 @@ public class Constructor extends SafeConstructor {
}
public Object construct(Node node) {
Object result = null;
try {
result = getConstructor(node).construct(node);
return getConstructor(node).construct(node);
} catch (ConstructorException e) {
throw e;
} catch (Exception e) {
throw new ConstructorException(null, null, "Can't construct a java object for "
+ node.getTag() + "; exception=" + e.getMessage(), node.getStartMark(), e);
}
return result;
}
public void construct2ndStep(Node node, Object object) {
......
......@@ -426,7 +426,6 @@ public class SafeConstructor extends BaseConstructor {
}
}
// Note: the same code as `construct_yaml_omap`.
public class ConstructYamlPairs extends AbstractConstruct {
@Override
public Object construct(Node node) {
......@@ -466,7 +465,7 @@ public class SafeConstructor extends BaseConstructor {
public Object construct(Node node) {
if (node.isTwoStepsConstruction()) {
return (constructedObjects.containsKey(node) ? constructedObjects.get(node)
: createDefaultSet());
: createDefaultSet(((MappingNode) node).getValue().size()));
} else {
return constructSet((MappingNode) node);
}
......@@ -515,10 +514,11 @@ public class SafeConstructor extends BaseConstructor {
public class ConstructYamlMap implements Construct {
@Override
public Object construct(Node node) {
MappingNode mnode = (MappingNode) node;
if (node.isTwoStepsConstruction()) {
return createDefaultMap();
return createDefaultMap(mnode.getValue().size());
} else {
return constructMapping((MappingNode) node);
return constructMapping(mnode);
}
}
......
......@@ -25,6 +25,7 @@ import org.yaml.snakeyaml.scanner.Constant;
*/
public final class Mark implements Serializable {
private String name;
private int index;
private int line;
private int column;
private int[] buffer;
......@@ -40,13 +41,14 @@ public final class Mark implements Serializable {
return codePoints;
}
public Mark(String name, int line, int column, char[] str, int pointer) {
this(name, line, column, toCodePoints(str), pointer);
public Mark(String name, int index, int line, int column, char[] str, int pointer) {
this(name, index, line, column, toCodePoints(str), pointer);
}
public Mark(String name, int line, int column, int[] buffer, int pointer) {
public Mark(String name, int index, int line, int column, int[] buffer, int pointer) {
super();
this.name = name;
this.index = index;
this.line = line;
this.column = column;
this.buffer = buffer;
......@@ -138,4 +140,19 @@ public final class Mark implements Serializable {
return column;
}
/**
* starts with 0
* @return character number
*/
public int getIndex() {
return index;
}
public int[] getBuffer() {
return buffer;
}
public int getPointer() {
return pointer;
}
}
......@@ -178,7 +178,7 @@ public class CompactConstructor extends Constructor {
* compact object's representation (@see getConstructor(Node) above)
*/
public Object construct(Node node) {
ScalarNode tmpNode = null;
ScalarNode tmpNode;
if (node instanceof MappingNode) {
// Compact Object Notation may contain only one entry
MappingNode mnode = (MappingNode) node;
......
......@@ -85,7 +85,7 @@ public abstract class Node {
}
/**
* Two Nodes are never equal.
* Node is only equal to itself
*/
@Override
public final boolean equals(Object obj) {
......
......@@ -222,8 +222,8 @@ public class ParserImpl implements Parser {
Mark startMark = token.getStartMark();
VersionTagsTuple tuple = processDirectives();
if (!scanner.checkToken(Token.ID.DocumentStart)) {
throw new ParserException(null, null, "expected '<document start>', but found "
+ scanner.peekToken().getTokenId(), scanner.peekToken().getStartMark());
throw new ParserException(null, null, "expected '<document start>', but found '"
+ scanner.peekToken().getTokenId() + "'", scanner.peekToken().getStartMark());
}
token = scanner.getToken();
Mark endMark = token.getEndMark();
......@@ -478,7 +478,7 @@ public class ParserImpl implements Parser {
}
Token token = scanner.peekToken();
throw new ParserException("while parsing a " + node + " node", startMark,
"expected the node content, but found " + token.getTokenId(),
"expected the node content, but found '" + token.getTokenId() + "'",
token.getStartMark());
}
}
......@@ -512,7 +512,7 @@ public class ParserImpl implements Parser {
if (!scanner.checkToken(Token.ID.BlockEnd)) {
Token token = scanner.peekToken();
throw new ParserException("while parsing a block collection", marks.pop(),
"expected <block end>, but found " + token.getTokenId(),
"expected <block end>, but found '" + token.getTokenId() + "'",
token.getStartMark());
}
Token token = scanner.getToken();
......@@ -568,7 +568,7 @@ public class ParserImpl implements Parser {
if (!scanner.checkToken(Token.ID.BlockEnd)) {
Token token = scanner.peekToken();
throw new ParserException("while parsing a block mapping", marks.pop(),
"expected <block end>, but found " + token.getTokenId(),
"expected <block end>, but found '" + token.getTokenId() + "'",
token.getStartMark());
}
Token token = scanner.getToken();
......
......@@ -95,7 +95,7 @@ public class StreamReader {
}
public Mark getMark() {
return new Mark(name, this.line, this.column, this.dataWindow, this.pointer);
return new Mark(name, this.index, this.line, this.column, this.dataWindow, this.pointer);
}
public void forward() {
......
......@@ -101,7 +101,7 @@ public class Resolver {
public Tag resolve(NodeId kind, String value, boolean implicit) {
if (kind == NodeId.scalar && implicit) {
List<ResolverTuple> resolvers = null;
final List<ResolverTuple> resolvers;
if (value.length() == 0) {
resolvers = yamlImplicitResolvers.get('\0');
} else {
......
......@@ -24,14 +24,14 @@ import org.yaml.snakeyaml.tokens.Token;
* process (see chapter 3.1 of the <a href="http://yaml.org/spec/1.1/">YAML
* Specification</a>).
* </p>
*
*
* @see org.yaml.snakeyaml.tokens.Token
*/
public interface Scanner {
/**
* Check if the next token is one of the given types.
*
*
* @param choices
* token IDs.
* @return <code>true</code> if the next token can be assigned to a variable
......@@ -44,11 +44,11 @@ public interface Scanner {
/**
* Return the next token, but do not delete it from the stream.
*
* @return The token that will be returned on the next call to
* {@link #getToken}
* @throws ScannerException
* Thrown in case of malformed input.
* The method must be called only after {@link #checkToken}.
*
* @return The token that will be returned on the next call to {@link #getToken}
* @throws ScannerException Thrown in case of malformed input.
* @throws IndexOutOfBoundsException if no more token left
*/
Token peekToken();
......@@ -56,10 +56,12 @@ public interface Scanner {
* Returns the next token.
* <p>
* The token will be removed from the stream.
* (Every invocation of this method must happen after calling {@link #checkToken}.
* </p>
*
* @return the coming token
* @throws ScannerException
* Thrown in case of malformed input.
* @throws ScannerException Thrown in case of malformed input.
* @throws IndexOutOfBoundsException if no more token left
*/
Token getToken();
}