merge snakeyaml into source
This commit is contained in:
parent
4c9cf299e6
commit
18a1a5f940
|
@ -1,9 +0,0 @@
|
|||
<component name="libraryTable">
|
||||
<library name="snakeyaml">
|
||||
<CLASSES>
|
||||
<root url="jar://$GRADLE_REPOSITORY$/org.yaml/snakeyaml/jars/snakeyaml-1.5.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
|
@ -17,7 +17,6 @@
|
|||
<orderEntry type="library" exported="" name="google-collect" level="project" />
|
||||
<orderEntry type="library" exported="" name="joda-time" level="project" />
|
||||
<orderEntry type="library" exported="" name="jackson" level="project" />
|
||||
<orderEntry type="library" exported="" name="snakeyaml" level="project" />
|
||||
<orderEntry type="library" exported="" name="guice" level="project" />
|
||||
<orderEntry type="library" exported="" name="jline" level="project" />
|
||||
<orderEntry type="library" exported="" name="jgroups" level="project" />
|
||||
|
|
|
@ -14,3 +14,6 @@ Written by Cliff Click and released as Public Domain.
|
|||
|
||||
Logging abstraction provided by SLF4J (http://www.slf4j.org).
|
||||
Copyright (c) 2004-2008 QOS.ch
|
||||
|
||||
Yaml support uses SnakeYaml Copyright of Andrey Somov under the
|
||||
Apache 2 License.
|
||||
|
|
|
@ -38,7 +38,6 @@ allprojects {
|
|||
repositories {
|
||||
mavenCentral()
|
||||
mavenRepo urls: 'http://repository.jboss.com/maven2/'
|
||||
mavenRepo urls: 'http://snakeyamlrepo.appspot.com/repository' // for snakeyaml
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
##############################################################################
|
||||
|
||||
# Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together.
|
||||
# GRADLE_OPTS="$GRADLE_OPTS -Xmx512"
|
||||
GRADLE_OPTS="$GRADLE_OPTS -Xmx512m"
|
||||
# JAVA_OPTS="$JAVA_OPTS -Xmx512"
|
||||
|
||||
warn ( ) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together.
|
||||
@rem set GRADLE_OPTS=%GRADLE_OPTS% -Xmx512
|
||||
set GRADLE_OPTS=%GRADLE_OPTS% -Xmx512m
|
||||
@rem set JAVA_OPTS=%JAVA_OPTS% -Xmx512
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
|
|
|
@ -36,8 +36,6 @@ dependencies {
|
|||
compile 'joda-time:joda-time:1.6'
|
||||
compile 'com.google.collections:google-collections:1.0'
|
||||
|
||||
compile 'org.yaml:snakeyaml:1.5'
|
||||
|
||||
compile 'org.codehaus.jackson:jackson-core-asl:1.4.2'
|
||||
compile 'org.codehaus.jackson:jackson-mapper-asl:1.4.2'
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
package org.elasticsearch.util.settings.loader;
|
||||
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.composer.Composer;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.constructor.BaseConstructor;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.constructor.Constructor;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.events.Event;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.Node;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.parser.Parser;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.parser.ParserImpl;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.reader.StreamReader;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.resolver.Resolver;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public class Loader {
|
||||
protected final BaseConstructor constructor;
|
||||
protected Resolver resolver;
|
||||
private boolean attached = false;
|
||||
|
||||
public Loader(BaseConstructor constructor) {
|
||||
super();
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
public Loader() {
|
||||
this(new Constructor());
|
||||
}
|
||||
|
||||
public Object load(Reader io) {
|
||||
Composer composer = new Composer(new ParserImpl(new StreamReader(io)), resolver);
|
||||
constructor.setComposer(composer);
|
||||
return constructor.getSingleData();
|
||||
}
|
||||
|
||||
public Iterable<Object> loadAll(Reader yaml) {
|
||||
Composer composer = new Composer(new ParserImpl(new StreamReader(yaml)), resolver);
|
||||
this.constructor.setComposer(composer);
|
||||
Iterator<Object> result = new Iterator<Object>() {
|
||||
public boolean hasNext() {
|
||||
return constructor.checkData();
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
return constructor.getData();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
return new YamlIterable(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the first YAML document in a stream and produce the corresponding
|
||||
* representation tree.
|
||||
*
|
||||
* @param yaml YAML document
|
||||
* @return parsed root Node for the specified YAML document
|
||||
*/
|
||||
public Node compose(Reader yaml) {
|
||||
Composer composer = new Composer(new ParserImpl(new StreamReader(yaml)), resolver);
|
||||
this.constructor.setComposer(composer);
|
||||
return composer.getSingleNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all YAML documents in a stream and produce corresponding
|
||||
* representation trees.
|
||||
*
|
||||
* @param yaml stream of YAML documents
|
||||
* @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)), resolver);
|
||||
this.constructor.setComposer(composer);
|
||||
Iterator<Node> result = new Iterator<Node>() {
|
||||
public boolean hasNext() {
|
||||
return composer.checkNode();
|
||||
}
|
||||
|
||||
public Node next() {
|
||||
return composer.getNode();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
return new NodeIterable(result);
|
||||
}
|
||||
|
||||
private class NodeIterable implements Iterable<Node> {
|
||||
private Iterator<Node> iterator;
|
||||
|
||||
public NodeIterable(Iterator<Node> iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
public Iterator<Node> iterator() {
|
||||
return iterator;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class YamlIterable implements Iterable<Object> {
|
||||
private Iterator<Object> iterator;
|
||||
|
||||
public YamlIterable(Iterator<Object> iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
public Iterator<Object> iterator() {
|
||||
return iterator;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setResolver(Resolver resolver) {
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Because Loader is stateful it cannot be shared
|
||||
*/
|
||||
void setAttached() {
|
||||
if (!attached) {
|
||||
attached = true;
|
||||
} else {
|
||||
throw new YAMLException("Loader cannot be shared.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a YAML stream and produce parsing events.
|
||||
*
|
||||
* @param yaml YAML document(s)
|
||||
* @return parsed events
|
||||
*/
|
||||
public Iterable<Event> parse(Reader yaml) {
|
||||
final Parser parser = new ParserImpl(new StreamReader(yaml));
|
||||
Iterator<Event> result = new Iterator<Event>() {
|
||||
public boolean hasNext() {
|
||||
return parser.peekEvent() != null;
|
||||
}
|
||||
|
||||
public Event next() {
|
||||
return parser.getEvent();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
return new EventIterable(result);
|
||||
}
|
||||
|
||||
private class EventIterable implements Iterable<Event> {
|
||||
private Iterator<Event> iterator;
|
||||
|
||||
public EventIterable(Iterator<Event> iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
public Iterator<Event> iterator() {
|
||||
return iterator;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.Tag;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides additional runtime information necessary to create a custom Java
|
||||
* instance.
|
||||
*/
|
||||
public final class TypeDescription {
|
||||
private final Class<? extends Object> type;
|
||||
private Tag tag;
|
||||
private boolean root;
|
||||
private Map<String, Class<? extends Object>> listProperties;
|
||||
private Map<String, Class<? extends Object>> keyProperties;
|
||||
private Map<String, Class<? extends Object>> valueProperties;
|
||||
|
||||
public TypeDescription(Class<? extends Object> clazz, Tag tag) {
|
||||
this.type = clazz;
|
||||
this.tag = tag;
|
||||
listProperties = new HashMap<String, Class<? extends Object>>();
|
||||
keyProperties = new HashMap<String, Class<? extends Object>>();
|
||||
valueProperties = new HashMap<String, Class<? extends Object>>();
|
||||
}
|
||||
|
||||
public TypeDescription(Class<? extends Object> clazz, String tag) {
|
||||
this(clazz, new Tag(tag));
|
||||
}
|
||||
|
||||
public TypeDescription(Class<? extends Object> clazz) {
|
||||
this(clazz, (Tag) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tag which shall be used to load or dump the type (class).
|
||||
*
|
||||
* @return tag to be used. It may be a tag for Language-Independent Types
|
||||
* (http://www.yaml.org/type/)
|
||||
*/
|
||||
public Tag getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set tag to be used to load or dump the type (class).
|
||||
*
|
||||
* @param tag local or global tag
|
||||
*/
|
||||
public void setTag(Tag tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
setTag(new Tag(tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get represented type (class)
|
||||
*
|
||||
* @return type (class) to be described.
|
||||
*/
|
||||
public Class<? extends Object> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines whether this type (class) is the root of the YAML document
|
||||
*
|
||||
* @return true if this type shall be used as a root of object hierarchy.
|
||||
*/
|
||||
public boolean isRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether this type (class) should be serve as the root of the YAML
|
||||
* document
|
||||
*
|
||||
* @param root true if this type shall be used as a root of object hierarchy.
|
||||
*/
|
||||
public void setRoot(boolean root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that the property is a type-safe <code>List</code>.
|
||||
*
|
||||
* @param property name of the JavaBean property
|
||||
* @param type class of List values
|
||||
*/
|
||||
public void putListPropertyType(String property, Class<? extends Object> type) {
|
||||
listProperties.put(property, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get class of List values for provided JavaBean property.
|
||||
*
|
||||
* @param property property name
|
||||
* @return class of List values
|
||||
*/
|
||||
public Class<? extends Object> getListPropertyType(String property) {
|
||||
return listProperties.get(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that the property is a type-safe <code>Map</code>.
|
||||
*
|
||||
* @param property property name of this JavaBean
|
||||
* @param key class of keys in Map
|
||||
* @param value class of values in Map
|
||||
*/
|
||||
public void putMapPropertyType(String property, Class<? extends Object> key,
|
||||
Class<? extends Object> value) {
|
||||
keyProperties.put(property, key);
|
||||
valueProperties.put(property, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get keys type info for this JavaBean
|
||||
*
|
||||
* @param property property name of this JavaBean
|
||||
* @return class of keys in the Map
|
||||
*/
|
||||
public Class<? extends Object> getMapKeyType(String property) {
|
||||
return keyProperties.get(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get values type info for this JavaBean
|
||||
*
|
||||
* @param property property name of this JavaBean
|
||||
* @return class of values in the Map
|
||||
*/
|
||||
public Class<? extends Object> getMapValueType(String property) {
|
||||
return valueProperties.get(property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TypeDescription for " + getType() + " (tag='" + getTag() + "')";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.events.Event;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.Node;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.reader.UnicodeReader;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.resolver.Resolver;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
/**
|
||||
* Public YAML interface. Each Thread must have its own instance.
|
||||
*/
|
||||
public class Yaml {
|
||||
private final Loader loader;
|
||||
private final Resolver resolver;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Create Yaml instance. It is safe to create a few instances and use them
|
||||
* in different Threads.
|
||||
*
|
||||
* @param loader Loader to parse incoming documents
|
||||
* @param resolver Resolver to detect implicit type
|
||||
*/
|
||||
public Yaml(Loader loader, Resolver resolver) {
|
||||
this.loader = loader;
|
||||
loader.setAttached();
|
||||
this.resolver = resolver;
|
||||
this.loader.setResolver(resolver);
|
||||
this.name = "Yaml:" + System.identityHashCode(this);
|
||||
}
|
||||
|
||||
public Yaml() {
|
||||
this(new Loader(), new Resolver());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the first YAML document in a String and produce the corresponding
|
||||
* Java object. (Because the encoding in known BOM is not respected.)
|
||||
*
|
||||
* @param yaml YAML data to load from (BOM must not be present)
|
||||
* @return parsed object
|
||||
*/
|
||||
public Object load(String yaml) {
|
||||
return loader.load(new StringReader(yaml));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the first YAML document in a stream and produce the corresponding
|
||||
* Java object.
|
||||
*
|
||||
* @param io data to load from (BOM is respected and removed)
|
||||
* @return parsed object
|
||||
*/
|
||||
public Object load(InputStream io) {
|
||||
return loader.load(new UnicodeReader(io));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the first YAML document in a stream and produce the corresponding
|
||||
* Java object.
|
||||
*
|
||||
* @param io data to load from (BOM must not be present)
|
||||
* @return parsed object
|
||||
*/
|
||||
public Object load(Reader io) {
|
||||
return loader.load(io);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all YAML documents in a String and produce corresponding Java
|
||||
* objects.
|
||||
*
|
||||
* @param yaml YAML data to load from (BOM must not be present)
|
||||
* @return an iterator over the parsed Java objects in this String in proper
|
||||
* sequence
|
||||
*/
|
||||
public Iterable<Object> loadAll(Reader yaml) {
|
||||
return loader.loadAll(yaml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all YAML documents in a String and produce corresponding Java
|
||||
* objects. (Because the encoding in known BOM is not respected.)
|
||||
*
|
||||
* @param yaml YAML data to load from (BOM must not be present)
|
||||
* @return an iterator over the parsed Java objects in this String in proper
|
||||
* sequence
|
||||
*/
|
||||
public Iterable<Object> loadAll(String yaml) {
|
||||
return loadAll(new StringReader(yaml));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all YAML documents in a stream and produce corresponding Java
|
||||
* objects.
|
||||
*
|
||||
* @param yaml YAML data to load from (BOM is respected and ignored)
|
||||
* @return an iterator over the parsed Java objects in this stream in proper
|
||||
* sequence
|
||||
*/
|
||||
public Iterable<Object> loadAll(InputStream yaml) {
|
||||
return loadAll(new UnicodeReader(yaml));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the first YAML document in a stream and produce the corresponding
|
||||
* representation tree.
|
||||
*
|
||||
* @param io stream of a YAML document
|
||||
* @return parsed root Node for the specified YAML document
|
||||
*/
|
||||
public Node compose(Reader io) {
|
||||
return loader.compose(io);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all YAML documents in a stream and produce corresponding
|
||||
* representation trees.
|
||||
*
|
||||
* @param io stream of YAML documents
|
||||
* @return parsed root Nodes for all the specified YAML documents
|
||||
*/
|
||||
public Iterable<Node> composeAll(Reader io) {
|
||||
return loader.composeAll(io);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a meaningful name. It simplifies debugging in a multi-threaded
|
||||
* environment. If nothing is set explicitly the address of the instance is
|
||||
* returned.
|
||||
*
|
||||
* @return human readable name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a meaningful name to be shown in toString()
|
||||
*
|
||||
* @param name human readable name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a YAML stream and produce parsing events.
|
||||
*
|
||||
* @param yaml YAML document(s)
|
||||
* @return parsed events
|
||||
*/
|
||||
public Iterable<Event> parse(Reader yaml) {
|
||||
return loader.parse(yaml);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.composer;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.events.*;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.*;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.parser.Parser;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.resolver.Resolver;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Creates a node graph from parser events.
|
||||
* <p>
|
||||
* Corresponds to the 'Compose' step as described in chapter 3.1 of the <a
|
||||
* href="http://yaml.org/spec/1.1/">YAML Specification</a>.
|
||||
* </p>
|
||||
*/
|
||||
public class Composer {
|
||||
private final Parser parser;
|
||||
private final Resolver resolver;
|
||||
private final Map<String, Node> anchors;
|
||||
private final Set<Node> recursiveNodes;
|
||||
|
||||
public Composer(Parser parser, Resolver resolver) {
|
||||
this.parser = parser;
|
||||
this.resolver = resolver;
|
||||
this.anchors = new HashMap<String, Node>();
|
||||
this.recursiveNodes = new HashSet<Node>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if further documents are available.
|
||||
*
|
||||
* @return <code>true</code> if there is at least one more document.
|
||||
*/
|
||||
public boolean checkNode() {
|
||||
// Drop the STREAM-START event.
|
||||
if (parser.checkEvent(Event.ID.StreamStart)) {
|
||||
parser.getEvent();
|
||||
}
|
||||
// If there are more documents available?
|
||||
return !parser.checkEvent(Event.ID.StreamEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and composes the next document.
|
||||
*
|
||||
* @return The root node of the document or <code>null</code> if no more
|
||||
* documents are available.
|
||||
*/
|
||||
public Node getNode() {
|
||||
// Get the root node of the next document.
|
||||
if (!parser.checkEvent(Event.ID.StreamEnd)) {
|
||||
return composeDocument();
|
||||
} else {
|
||||
return (Node) null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a document from a source that contains only one document.
|
||||
* <p>
|
||||
* If the stream contains more than one document an exception is thrown.
|
||||
* </p>
|
||||
*
|
||||
* @return The root node of the document or <code>null</code> if no document
|
||||
* is available.
|
||||
*/
|
||||
public Node getSingleNode() {
|
||||
// Drop the STREAM-START event.
|
||||
parser.getEvent();
|
||||
// Compose a document if the stream is not empty.
|
||||
Node document = null;
|
||||
if (!parser.checkEvent(Event.ID.StreamEnd)) {
|
||||
document = composeDocument();
|
||||
}
|
||||
// Ensure that the stream contains no more documents.
|
||||
if (!parser.checkEvent(Event.ID.StreamEnd)) {
|
||||
Event event = parser.getEvent();
|
||||
throw new ComposerException("expected a single document in the stream", document
|
||||
.getStartMark(), "but found another document", event.getStartMark());
|
||||
}
|
||||
// Drop the STREAM-END event.
|
||||
parser.getEvent();
|
||||
return document;
|
||||
}
|
||||
|
||||
private Node composeDocument() {
|
||||
// Drop the DOCUMENT-START event.
|
||||
parser.getEvent();
|
||||
// Compose the root node.
|
||||
Node node = composeNode(null, null);
|
||||
// Drop the DOCUMENT-END event.
|
||||
parser.getEvent();
|
||||
this.anchors.clear();
|
||||
recursiveNodes.clear();
|
||||
return node;
|
||||
}
|
||||
|
||||
private Node composeNode(Node parent, Object index) {
|
||||
recursiveNodes.add(parent);
|
||||
if (parser.checkEvent(Event.ID.Alias)) {
|
||||
AliasEvent event = (AliasEvent) parser.getEvent();
|
||||
String anchor = event.getAnchor();
|
||||
if (!anchors.containsKey(anchor)) {
|
||||
throw new ComposerException(null, null, "found undefined alias " + anchor, event
|
||||
.getStartMark());
|
||||
}
|
||||
Node result = (Node) anchors.get(anchor);
|
||||
if (recursiveNodes.remove(result)) {
|
||||
result.setTwoStepsConstruction(true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
NodeEvent event = (NodeEvent) parser.peekEvent();
|
||||
String anchor = null;
|
||||
anchor = event.getAnchor();
|
||||
if (anchor != null && anchors.containsKey(anchor)) {
|
||||
throw new ComposerException("found duplicate anchor " + anchor + "; first occurence",
|
||||
this.anchors.get(anchor).getStartMark(), "second occurence", event
|
||||
.getStartMark());
|
||||
}
|
||||
// resolver.descendResolver(parent, index);
|
||||
Node node = null;
|
||||
if (parser.checkEvent(Event.ID.Scalar)) {
|
||||
node = composeScalarNode(anchor);
|
||||
} else if (parser.checkEvent(Event.ID.SequenceStart)) {
|
||||
node = composeSequenceNode(anchor);
|
||||
} else {
|
||||
node = composeMappingNode(anchor);
|
||||
}
|
||||
// resolver.ascendResolver();
|
||||
recursiveNodes.remove(parent);
|
||||
return node;
|
||||
}
|
||||
|
||||
private Node composeScalarNode(String anchor) {
|
||||
ScalarEvent ev = (ScalarEvent) parser.getEvent();
|
||||
String tag = ev.getTag();
|
||||
boolean resolved = false;
|
||||
Tag nodeTag;
|
||||
if (tag == null || tag.equals("!")) {
|
||||
nodeTag = resolver.resolve(NodeId.scalar, ev.getValue(), ev.getImplicit().isFirst());
|
||||
resolved = true;
|
||||
} else {
|
||||
nodeTag = new Tag(tag);
|
||||
}
|
||||
Node node = new ScalarNode(nodeTag, resolved, ev.getValue(), ev.getStartMark(), ev
|
||||
.getEndMark(), ev.getStyle());
|
||||
if (anchor != null) {
|
||||
anchors.put(anchor, node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
private Node composeSequenceNode(String anchor) {
|
||||
SequenceStartEvent startEvent = (SequenceStartEvent) parser.getEvent();
|
||||
String tag = startEvent.getTag();
|
||||
Tag nodeTag;
|
||||
boolean resolved = false;
|
||||
if (tag == null || tag.equals("!")) {
|
||||
nodeTag = resolver.resolve(NodeId.sequence, null, startEvent.getImplicit());
|
||||
resolved = true;
|
||||
} else {
|
||||
nodeTag = new Tag(tag);
|
||||
}
|
||||
SequenceNode node = new SequenceNode(nodeTag, resolved, new ArrayList<Node>(), startEvent
|
||||
.getStartMark(), null, startEvent.getFlowStyle());
|
||||
if (anchor != null) {
|
||||
anchors.put(anchor, node);
|
||||
}
|
||||
int index = 0;
|
||||
while (!parser.checkEvent(Event.ID.SequenceEnd)) {
|
||||
(node.getValue()).add(composeNode(node, index));
|
||||
index++;
|
||||
}
|
||||
Event endEvent = parser.getEvent();
|
||||
node.setEndMark(endEvent.getEndMark());
|
||||
return node;
|
||||
}
|
||||
|
||||
private Node composeMappingNode(String anchor) {
|
||||
MappingStartEvent startEvent = (MappingStartEvent) parser.getEvent();
|
||||
String tag = startEvent.getTag();
|
||||
Tag nodeTag;
|
||||
boolean resolved = false;
|
||||
if (tag == null || tag.equals("!")) {
|
||||
nodeTag = resolver.resolve(NodeId.mapping, null, startEvent.getImplicit());
|
||||
resolved = true;
|
||||
} else {
|
||||
nodeTag = new Tag(tag);
|
||||
}
|
||||
MappingNode node = new MappingNode(nodeTag, resolved, new ArrayList<NodeTuple>(),
|
||||
startEvent.getStartMark(), null, startEvent.getFlowStyle());
|
||||
if (anchor != null) {
|
||||
anchors.put(anchor, node);
|
||||
}
|
||||
while (!parser.checkEvent(Event.ID.MappingEnd)) {
|
||||
Node itemKey = composeNode(node, null);
|
||||
Node itemValue = composeNode(node, itemKey);
|
||||
node.getValue().add(new NodeTuple(itemKey, itemValue));
|
||||
}
|
||||
Event endEvent = parser.getEvent();
|
||||
node.setEndMark(endEvent.getEndMark());
|
||||
return node;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.composer;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.MarkedYAMLException;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public class ComposerException extends MarkedYAMLException {
|
||||
private static final long serialVersionUID = 2146314636913113935L;
|
||||
|
||||
protected ComposerException(String context, Mark contextMark, String problem, Mark problemMark) {
|
||||
super(context, contextMark, problem, problemMark);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.constructor;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.Node;
|
||||
|
||||
/**
|
||||
* Because recursive structures are not very common we provide a way to save
|
||||
* some typing when extending a constructor
|
||||
*/
|
||||
public abstract class AbstractConstruct implements Construct {
|
||||
|
||||
/**
|
||||
* Fail with a reminder to provide the seconds step for a recursive
|
||||
* structure
|
||||
*
|
||||
* @see org.elasticsearch.util.yaml.snakeyaml.constructor.Construct#construct2ndStep(org.elasticsearch.util.yaml.snakeyaml.nodes.Node,
|
||||
* java.lang.Object)
|
||||
*/
|
||||
public void construct2ndStep(Node node, Object data) {
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
throw new IllegalStateException("Not Implemented in " + getClass().getName());
|
||||
} else {
|
||||
throw new YAMLException("Unexpected recursive structure for Node: " + node);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.constructor;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.composer.Composer;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.composer.ComposerException;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public abstract class BaseConstructor {
|
||||
/**
|
||||
* It maps the node kind to the the Construct implementation. When the
|
||||
* runtime class is known then the implicit tag is ignored.
|
||||
*/
|
||||
protected final Map<NodeId, Construct> yamlClassConstructors = new EnumMap<NodeId, Construct>(
|
||||
NodeId.class);
|
||||
/**
|
||||
* It maps the (explicit or implicit) tag to the Construct implementation.
|
||||
* It is used: <br/>
|
||||
* 1) explicit tag - if present. <br/>
|
||||
* 2) implicit tag - when the runtime class of the instance is unknown (the
|
||||
* node has the Object.class)
|
||||
*/
|
||||
protected final Map<Tag, Construct> yamlConstructors = new HashMap<Tag, Construct>();
|
||||
/**
|
||||
* It maps the (explicit or implicit) tag to the Construct implementation.
|
||||
* It is used when no exact match found.
|
||||
*/
|
||||
protected final Map<String, Construct> yamlMultiConstructors = new HashMap<String, Construct>();
|
||||
|
||||
private Composer composer;
|
||||
private final Map<Node, Object> constructedObjects;
|
||||
private final Set<Node> recursiveObjects;
|
||||
private final ArrayList<RecursiveTuple<Map<Object, Object>, RecursiveTuple<Object, Object>>> maps2fill;
|
||||
private final ArrayList<RecursiveTuple<Set<Object>, Object>> sets2fill;
|
||||
|
||||
protected Tag rootTag;
|
||||
|
||||
public BaseConstructor() {
|
||||
constructedObjects = new HashMap<Node, Object>();
|
||||
recursiveObjects = new HashSet<Node>();
|
||||
maps2fill = new ArrayList<RecursiveTuple<Map<Object, Object>, RecursiveTuple<Object, Object>>>();
|
||||
sets2fill = new ArrayList<RecursiveTuple<Set<Object>, Object>>();
|
||||
rootTag = null;
|
||||
}
|
||||
|
||||
public void setComposer(Composer composer) {
|
||||
this.composer = composer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if more documents available
|
||||
*
|
||||
* @return true when there are more YAML documents in the stream
|
||||
*/
|
||||
public boolean checkData() {
|
||||
// If there are more documents available?
|
||||
return composer.checkNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct and return the next document
|
||||
*
|
||||
* @return constructed instance
|
||||
*/
|
||||
public Object getData() {
|
||||
// Construct and return the next document.
|
||||
composer.checkNode();
|
||||
Node node = composer.getNode();
|
||||
if (rootTag != null) {
|
||||
node.setTag(rootTag);
|
||||
}
|
||||
return constructDocument(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the stream contains a single document and construct it
|
||||
*
|
||||
* @return constructed instance
|
||||
* @throws ComposerException in case there are more documents in the stream
|
||||
*/
|
||||
public Object getSingleData() {
|
||||
// Ensure that the stream contains a single document and construct it
|
||||
Node node = composer.getSingleNode();
|
||||
if (node != null) {
|
||||
if (rootTag != null) {
|
||||
node.setTag(rootTag);
|
||||
}
|
||||
return constructDocument(node);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct complete YAML document. Call the second step in case of
|
||||
* recursive structures. At the end cleans all the state.
|
||||
*
|
||||
* @param node root Node
|
||||
* @return Java instance
|
||||
*/
|
||||
private Object constructDocument(Node node) {
|
||||
Object data = constructObject(node);
|
||||
fillRecursive();
|
||||
constructedObjects.clear();
|
||||
recursiveObjects.clear();
|
||||
return data;
|
||||
}
|
||||
|
||||
private void fillRecursive() {
|
||||
if (!maps2fill.isEmpty()) {
|
||||
for (RecursiveTuple<Map<Object, Object>, RecursiveTuple<Object, Object>> entry : maps2fill) {
|
||||
RecursiveTuple<Object, Object> key_value = entry._2();
|
||||
entry._1().put(key_value._1(), key_value._2());
|
||||
}
|
||||
maps2fill.clear();
|
||||
}
|
||||
if (!sets2fill.isEmpty()) {
|
||||
for (RecursiveTuple<Set<Object>, Object> value : sets2fill) {
|
||||
value._1().add(value._2());
|
||||
}
|
||||
sets2fill.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct object from the specified Node. Return existing instance if the
|
||||
* node is already constructed.
|
||||
*
|
||||
* @param node Node to be constructed
|
||||
* @return Java instance
|
||||
*/
|
||||
protected Object constructObject(Node node) {
|
||||
if (constructedObjects.containsKey(node)) {
|
||||
return constructedObjects.get(node);
|
||||
}
|
||||
if (recursiveObjects.contains(node)) {
|
||||
throw new ConstructorException(null, null, "found unconstructable recursive node", node
|
||||
.getStartMark());
|
||||
}
|
||||
recursiveObjects.add(node);
|
||||
Construct constructor = getConstructor(node);
|
||||
Object data = constructor.construct(node);
|
||||
constructedObjects.put(node, data);
|
||||
recursiveObjects.remove(node);
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
constructor.construct2ndStep(node, data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the constructor to construct the Node. For implicit tags if the
|
||||
* 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
|
||||
*/
|
||||
protected Construct getConstructor(Node node) {
|
||||
if (node.useClassConstructor()) {
|
||||
return yamlClassConstructors.get(node.getNodeId());
|
||||
} else {
|
||||
Construct constructor = yamlConstructors.get(node.getTag());
|
||||
if (constructor == null) {
|
||||
for (String prefix : yamlMultiConstructors.keySet()) {
|
||||
if (node.getTag().startsWith(prefix)) {
|
||||
return yamlMultiConstructors.get(prefix);
|
||||
}
|
||||
}
|
||||
return yamlConstructors.get(null);
|
||||
}
|
||||
return constructor;
|
||||
}
|
||||
}
|
||||
|
||||
protected Object constructScalar(ScalarNode node) {
|
||||
return node.getValue();
|
||||
}
|
||||
|
||||
protected List<Object> createDefaultList(int initSize) {
|
||||
return new ArrayList<Object>(initSize);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<? extends Object> constructSequence(SequenceNode node) {
|
||||
List<Object> result;
|
||||
if (List.class.isAssignableFrom(node.getType()) && !node.getType().isInterface()) {
|
||||
// the root class may be defined (Vector for instance)
|
||||
try {
|
||||
result = (List<Object>) node.getType().newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new YAMLException(e);
|
||||
}
|
||||
} else {
|
||||
result = createDefaultList(node.getValue().size());
|
||||
}
|
||||
constructSequenceStep2(node, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void constructSequenceStep2(SequenceNode node, List<Object> list) {
|
||||
for (Node child : node.getValue()) {
|
||||
list.add(constructObject(child));
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<Object, Object> createDefaultMap() {
|
||||
// respect order from YAML document
|
||||
return new LinkedHashMap<Object, Object>();
|
||||
}
|
||||
|
||||
protected Set<Object> createDefaultSet() {
|
||||
// respect order from YAML document
|
||||
return new LinkedHashSet<Object>();
|
||||
}
|
||||
|
||||
protected Set<Object> constructSet(MappingNode node) {
|
||||
Set<Object> set = createDefaultSet();
|
||||
constructSet2ndStep(node, set);
|
||||
return set;
|
||||
}
|
||||
|
||||
protected Map<Object, Object> constructMapping(MappingNode node) {
|
||||
Map<Object, Object> mapping = createDefaultMap();
|
||||
constructMapping2ndStep(node, mapping);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
protected void constructMapping2ndStep(MappingNode node, Map<Object, Object> mapping) {
|
||||
List<NodeTuple> nodeValue = (List<NodeTuple>) node.getValue();
|
||||
for (NodeTuple tuple : nodeValue) {
|
||||
Node keyNode = tuple.getKeyNode();
|
||||
Node valueNode = tuple.getValueNode();
|
||||
Object key = constructObject(keyNode);
|
||||
if (key != null) {
|
||||
try {
|
||||
key.hashCode();// check circular dependencies
|
||||
} catch (Exception e) {
|
||||
throw new ConstructorException("while constructing a mapping", node
|
||||
.getStartMark(), "found unacceptable key " + key, tuple.getKeyNode()
|
||||
.getStartMark(), e);
|
||||
}
|
||||
}
|
||||
Object value = constructObject(valueNode);
|
||||
if (keyNode.isTwoStepsConstruction()) {
|
||||
/*
|
||||
* if keyObject is created it 2 steps we should postpone putting
|
||||
* it in map because it may have different hash after
|
||||
* initialization compared to clean just created one. And map of
|
||||
* course does not observe key hashCode changes.
|
||||
*/
|
||||
maps2fill.add(0,
|
||||
new RecursiveTuple<Map<Object, Object>, RecursiveTuple<Object, Object>>(
|
||||
mapping, new RecursiveTuple<Object, Object>(key, value)));
|
||||
} else {
|
||||
mapping.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void constructSet2ndStep(MappingNode node, Set<Object> set) {
|
||||
List<NodeTuple> nodeValue = (List<NodeTuple>) node.getValue();
|
||||
for (NodeTuple tuple : nodeValue) {
|
||||
Node keyNode = tuple.getKeyNode();
|
||||
Object key = constructObject(keyNode);
|
||||
if (key != null) {
|
||||
try {
|
||||
key.hashCode();// check circular dependencies
|
||||
} catch (Exception e) {
|
||||
throw new ConstructorException("while constructing a Set", node.getStartMark(),
|
||||
"found unacceptable key " + key, tuple.getKeyNode().getStartMark(), e);
|
||||
}
|
||||
}
|
||||
if (keyNode.isTwoStepsConstruction()) {
|
||||
/*
|
||||
* if keyObject is created it 2 steps we should postpone putting
|
||||
* it into the set because it may have different hash after
|
||||
* initialization compared to clean just created one. And set of
|
||||
* course does not observe value hashCode changes.
|
||||
*/
|
||||
sets2fill.add(0, new RecursiveTuple<Set<Object>, Object>(set, key));
|
||||
} else {
|
||||
set.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO protected List<Object[]> constructPairs(MappingNode node) {
|
||||
// List<Object[]> pairs = new LinkedList<Object[]>();
|
||||
// List<Node[]> nodeValue = (List<Node[]>) node.getValue();
|
||||
// for (Iterator<Node[]> iter = nodeValue.iterator(); iter.hasNext();) {
|
||||
// Node[] tuple = iter.next();
|
||||
// Object key = constructObject(Object.class, tuple[0]);
|
||||
// Object value = constructObject(Object.class, tuple[1]);
|
||||
// pairs.add(new Object[] { key, value });
|
||||
// }
|
||||
// return pairs;
|
||||
// }
|
||||
|
||||
private static class RecursiveTuple<T, K> {
|
||||
private final T _1;
|
||||
private final K _2;
|
||||
|
||||
public RecursiveTuple(T _1, K _2) {
|
||||
this._1 = _1;
|
||||
this._2 = _2;
|
||||
}
|
||||
|
||||
public K _2() {
|
||||
return _2;
|
||||
}
|
||||
|
||||
public T _1() {
|
||||
return _1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.constructor;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.Node;
|
||||
|
||||
/**
|
||||
* Provide a way to construct a Java instance out of the composed Node. Support
|
||||
* recursive objects if it is required. (create Native Data Structure out of
|
||||
* Node Graph)
|
||||
*
|
||||
* @see http://yaml.org/spec/1.1/#id859109
|
||||
*/
|
||||
public interface Construct {
|
||||
/**
|
||||
* Construct a Java instance with all the properties injected when it is
|
||||
* possible.
|
||||
*
|
||||
* @param node composed Node
|
||||
* @return a complete Java instance
|
||||
*/
|
||||
public Object construct(Node node);
|
||||
|
||||
/**
|
||||
* Apply the second step when constructing recursive structures. Because the
|
||||
* instance is already created it can assign a reference to itself.
|
||||
*
|
||||
* @param node composed Node
|
||||
* @param object the instance constructed earlier by
|
||||
* <code>construct(Node node)</code> for the provided Node
|
||||
*/
|
||||
public void construct2ndStep(Node node, Object object);
|
||||
}
|
|
@ -0,0 +1,608 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.constructor;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.TypeDescription;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.introspector.FieldProperty;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.introspector.MethodProperty;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.introspector.Property;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.*;
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Construct a custom Java instance.
|
||||
*/
|
||||
public class Constructor extends SafeConstructor {
|
||||
private final Map<Tag, Class<? extends Object>> typeTags;
|
||||
private final Map<Class<? extends Object>, TypeDescription> typeDefinitions;
|
||||
|
||||
public Constructor() {
|
||||
this(Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Constructor for the specified class as the root.
|
||||
*
|
||||
* @param theRoot - the class (usually JavaBean) to be constructed
|
||||
*/
|
||||
public Constructor(Class<? extends Object> theRoot) {
|
||||
if (theRoot == null) {
|
||||
throw new NullPointerException("Root type must be provided.");
|
||||
}
|
||||
this.yamlConstructors.put(null, new ConstructYamlObject());
|
||||
if (!Object.class.equals(theRoot)) {
|
||||
rootTag = new Tag(theRoot);
|
||||
}
|
||||
typeTags = new HashMap<Tag, Class<? extends Object>>();
|
||||
typeDefinitions = new HashMap<Class<? extends Object>, TypeDescription>();
|
||||
yamlClassConstructors.put(NodeId.scalar, new ConstructScalar());
|
||||
yamlClassConstructors.put(NodeId.mapping, new ConstructMapping());
|
||||
yamlClassConstructors.put(NodeId.sequence, new ConstructSequence());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Constructor for a class which does not have to be in the classpath
|
||||
* or for a definition from a Spring ApplicationContext.
|
||||
*
|
||||
* @param theRoot fully qualified class name of the root class (usually
|
||||
* JavaBean)
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public Constructor(String theRoot) throws ClassNotFoundException {
|
||||
this(Class.forName(check(theRoot)));
|
||||
}
|
||||
|
||||
private static final String check(String s) {
|
||||
if (s == null) {
|
||||
throw new NullPointerException("Root type must be provided.");
|
||||
}
|
||||
if (s.trim().length() == 0) {
|
||||
throw new YAMLException("Root type must be provided.");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make YAML aware how to parse a custom Class. If there is no root Class
|
||||
* assigned in constructor then the 'root' property of this definition is
|
||||
* respected.
|
||||
*
|
||||
* @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>.
|
||||
*/
|
||||
public TypeDescription addTypeDescription(TypeDescription definition) {
|
||||
if (definition == null) {
|
||||
throw new NullPointerException("TypeDescription is required.");
|
||||
}
|
||||
if (rootTag == null && definition.isRoot()) {
|
||||
rootTag = new Tag(definition.getType());
|
||||
}
|
||||
Tag tag = definition.getTag();
|
||||
typeTags.put(tag, definition.getType());
|
||||
return typeDefinitions.put(definition.getType(), definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct mapping instance (Map, JavaBean) when the runtime class is
|
||||
* known.
|
||||
*/
|
||||
private class ConstructMapping implements Construct {
|
||||
private final Map<Class<? extends Object>, Map<String, Property>> propertiesCache = new HashMap<Class<? extends Object>, Map<String, Property>>();
|
||||
|
||||
/**
|
||||
* Construct JavaBean. If type safe collections are used please look at
|
||||
* <code>TypeDescription</code>.
|
||||
*
|
||||
* @param node node where the keys are property names (they can only be
|
||||
* <code>String</code>s) and values are objects to be created
|
||||
* @return constructed JavaBean
|
||||
*/
|
||||
public Object construct(Node node) {
|
||||
MappingNode mnode = (MappingNode) node;
|
||||
if (Properties.class.isAssignableFrom(node.getType())) {
|
||||
Properties properties = new Properties();
|
||||
if (!node.isTwoStepsConstruction()) {
|
||||
constructMapping2ndStep(mnode, (Map<Object, Object>) properties);
|
||||
} else {
|
||||
throw new YAMLException("Properties must not be recursive.");
|
||||
}
|
||||
return properties;
|
||||
} else if (SortedMap.class.isAssignableFrom(node.getType())) {
|
||||
SortedMap<Object, Object> map = new TreeMap<Object, Object>();
|
||||
if (!node.isTwoStepsConstruction()) {
|
||||
constructMapping2ndStep(mnode, map);
|
||||
}
|
||||
return map;
|
||||
} else if (Map.class.isAssignableFrom(node.getType())) {
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
return createDefaultMap();
|
||||
} else {
|
||||
return constructMapping(mnode);
|
||||
}
|
||||
} else if (SortedSet.class.isAssignableFrom(node.getType())) {
|
||||
SortedSet<Object> set = new TreeSet<Object>();
|
||||
if (!node.isTwoStepsConstruction()) {
|
||||
constructSet2ndStep(mnode, set);
|
||||
}
|
||||
return set;
|
||||
} else if (Set.class.isAssignableFrom(node.getType())) {
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
return createDefaultSet();
|
||||
} else {
|
||||
return constructSet(mnode);
|
||||
}
|
||||
} else {
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
return createEmptyJavaBean(mnode);
|
||||
} else {
|
||||
return constructJavaBean2ndStep(mnode, createEmptyJavaBean(mnode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void construct2ndStep(Node node, Object object) {
|
||||
if (Map.class.isAssignableFrom(node.getType())) {
|
||||
constructMapping2ndStep((MappingNode) node, (Map<Object, Object>) object);
|
||||
} else if (Set.class.isAssignableFrom(node.getType())) {
|
||||
constructSet2ndStep((MappingNode) node, (Set<Object>) object);
|
||||
} else {
|
||||
constructJavaBean2ndStep((MappingNode) node, object);
|
||||
}
|
||||
}
|
||||
|
||||
private Object createEmptyJavaBean(MappingNode node) {
|
||||
try {
|
||||
Class<? extends Object> type = node.getType();
|
||||
if (Modifier.isAbstract(type.getModifiers())) {
|
||||
node.setType(getClassForNode(node));
|
||||
}
|
||||
/**
|
||||
* Using only default constructor. Everything else will be
|
||||
* initialized on 2nd step. If we do here some partial
|
||||
* initialization, how do we then track what need to be done on
|
||||
* 2nd step? I think it is better to get only object here (to
|
||||
* have it as reference for recursion) and do all other thing on
|
||||
* 2nd step.
|
||||
*/
|
||||
return node.getType().newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new YAMLException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new YAMLException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object constructJavaBean2ndStep(MappingNode node, Object object) {
|
||||
Class<? extends Object> beanType = node.getType();
|
||||
List<NodeTuple> nodeValue = (List<NodeTuple>) node.getValue();
|
||||
for (NodeTuple tuple : nodeValue) {
|
||||
ScalarNode keyNode;
|
||||
if (tuple.getKeyNode() instanceof ScalarNode) {
|
||||
// key must be scalar
|
||||
keyNode = (ScalarNode) tuple.getKeyNode();
|
||||
} else {
|
||||
throw new YAMLException("Keys must be scalars but found: " + tuple.getKeyNode());
|
||||
}
|
||||
Node valueNode = tuple.getValueNode();
|
||||
// keys can only be Strings
|
||||
keyNode.setType(String.class);
|
||||
String key = (String) constructObject(keyNode);
|
||||
boolean isArray = false;
|
||||
try {
|
||||
Property property = getProperty(beanType, key);
|
||||
valueNode.setType(property.getType());
|
||||
if (property.getType().isArray()) {
|
||||
isArray = true;
|
||||
}
|
||||
TypeDescription memberDescription = typeDefinitions.get(beanType);
|
||||
boolean typeDetected = false;
|
||||
if (memberDescription != null) {
|
||||
switch (valueNode.getNodeId()) {
|
||||
case sequence:
|
||||
SequenceNode snode = (SequenceNode) valueNode;
|
||||
Class<? extends Object> memberType = memberDescription
|
||||
.getListPropertyType(key);
|
||||
if (memberType != null) {
|
||||
snode.setListType(memberType);
|
||||
typeDetected = true;
|
||||
} else if (property.getType().isArray()) {
|
||||
isArray = true;
|
||||
snode.setListType(property.getType().getComponentType());
|
||||
typeDetected = true;
|
||||
}
|
||||
break;
|
||||
case mapping:
|
||||
MappingNode mnode = (MappingNode) valueNode;
|
||||
Class<? extends Object> keyType = memberDescription.getMapKeyType(key);
|
||||
if (keyType != null) {
|
||||
mnode.setKeyType(keyType);
|
||||
mnode.setValueType(memberDescription.getMapValueType(key));
|
||||
typeDetected = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!typeDetected && valueNode.getNodeId() != NodeId.scalar) {
|
||||
// only if there is no explicit TypeDescription
|
||||
Type[] arguments = property.getActualTypeArguments();
|
||||
if (arguments != null) {
|
||||
// type safe (generic) collection may contain the
|
||||
// proper class
|
||||
if (valueNode.getNodeId() == NodeId.sequence) {
|
||||
Class t = (Class) arguments[0];
|
||||
SequenceNode snode = (SequenceNode) valueNode;
|
||||
snode.setListType(t);
|
||||
} else if (valueNode.getTag().equals(Tag.SET)) {
|
||||
Class t = (Class) arguments[0];
|
||||
MappingNode mnode = (MappingNode) valueNode;
|
||||
mnode.setKeyType(t);
|
||||
mnode.setUseClassConstructor(true);
|
||||
} else if (valueNode.getNodeId() == NodeId.mapping) {
|
||||
Class ketType = (Class) arguments[0];
|
||||
Class valueType = (Class) arguments[1];
|
||||
MappingNode mnode = (MappingNode) valueNode;
|
||||
mnode.setKeyType(ketType);
|
||||
mnode.setValueType(valueType);
|
||||
mnode.setUseClassConstructor(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Object value = constructObject(valueNode);
|
||||
if (isArray && value instanceof List) {
|
||||
List<Object> list = (List<Object>) value;
|
||||
value = list.toArray(createArray(property.getType()));
|
||||
}
|
||||
property.set(object, value);
|
||||
} catch (Exception e) {
|
||||
throw new YAMLException("Cannot create property=" + key + " for JavaBean="
|
||||
+ object + "; " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T[] createArray(Class<T> type) {
|
||||
return (T[]) Array.newInstance(type.getComponentType(), 0);
|
||||
}
|
||||
|
||||
private Property getProperty(Class<? extends Object> type, String name)
|
||||
throws IntrospectionException {
|
||||
// check cache
|
||||
Map<String, Property> properties = propertiesCache.get(type);
|
||||
if (properties == null) {
|
||||
properties = new HashMap<String, Property>();
|
||||
propertiesCache.put(type, properties);
|
||||
for (PropertyDescriptor property : Introspector.getBeanInfo(type)
|
||||
.getPropertyDescriptors()) {
|
||||
String methodName = property.getName();
|
||||
if (property.getWriteMethod() != null) {
|
||||
properties.put(methodName, new MethodProperty(property));
|
||||
}
|
||||
}
|
||||
for (Field field : type.getFields()) {
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers)) {
|
||||
continue;
|
||||
}
|
||||
properties.put(field.getName(), new FieldProperty(field));
|
||||
}
|
||||
}
|
||||
// take from cache
|
||||
Property property = properties.get(name);
|
||||
if (property == null) {
|
||||
throw new YAMLException("Unable to find property '" + name + "' on class: "
|
||||
+ type.getName());
|
||||
} else {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance when the runtime class is not known but a global
|
||||
* tag with a class name is defined. It delegates the construction to the
|
||||
* appropriate constructor based on the node kind (scalar, sequence,
|
||||
* mapping)
|
||||
*/
|
||||
private class ConstructYamlObject implements Construct {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Construct getConstructor(Node node) {
|
||||
Class cl = getClassForNode(node);
|
||||
node.setType(cl);
|
||||
// call the constructor as if the runtime class is defined
|
||||
Construct constructor = yamlClassConstructors.get(node.getNodeId());
|
||||
return constructor;
|
||||
}
|
||||
|
||||
public Object construct(Node node) {
|
||||
Object result = null;
|
||||
try {
|
||||
result = getConstructor(node).construct(node);
|
||||
} 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) {
|
||||
try {
|
||||
getConstructor(node).construct2ndStep(node, object);
|
||||
} catch (Exception e) {
|
||||
throw new ConstructorException(null, null,
|
||||
"Can't construct a second step for a java object for " + node.getTag()
|
||||
+ "; exception=" + e.getMessage(), node.getStartMark(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct scalar instance when the runtime class is known. Recursive
|
||||
* structures are not supported.
|
||||
*/
|
||||
protected class ConstructScalar extends AbstractConstruct {
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object construct(Node nnode) {
|
||||
ScalarNode node = (ScalarNode) nnode;
|
||||
Class type = node.getType();
|
||||
Object result;
|
||||
if (type.isPrimitive() || type == String.class || Number.class.isAssignableFrom(type)
|
||||
|| type == Boolean.class || Date.class.isAssignableFrom(type)
|
||||
|| type == Character.class || type == BigInteger.class
|
||||
|| type == BigDecimal.class || Enum.class.isAssignableFrom(type)
|
||||
|| Tag.BINARY.equals(node.getTag()) || Calendar.class.isAssignableFrom(type)) {
|
||||
// standard classes created directly
|
||||
result = constructStandardJavaInstance(type, node);
|
||||
} else {
|
||||
// there must be only 1 constructor with 1 argument
|
||||
java.lang.reflect.Constructor[] javaConstructors = type.getConstructors();
|
||||
int oneArgCount = 0;
|
||||
java.lang.reflect.Constructor javaConstructor = null;
|
||||
for (java.lang.reflect.Constructor c : javaConstructors) {
|
||||
if (c.getParameterTypes().length == 1) {
|
||||
oneArgCount++;
|
||||
javaConstructor = c;
|
||||
}
|
||||
}
|
||||
Object argument;
|
||||
if (javaConstructor == null) {
|
||||
throw new YAMLException("No single argument constructor found for " + type);
|
||||
} else if (oneArgCount == 1) {
|
||||
argument = constructStandardJavaInstance(
|
||||
javaConstructor.getParameterTypes()[0], node);
|
||||
} else {
|
||||
// TODO it should be possible to use implicit types instead
|
||||
// of forcing String. Resolver must be available here to
|
||||
// obtain the implicit tag. Then we can set the tag and call
|
||||
// callConstructor(node) to create the argument instance.
|
||||
// On the other hand it may be safer to require a custom
|
||||
// constructor to avoid guessing the argument class
|
||||
argument = constructScalar(node);
|
||||
try {
|
||||
javaConstructor = type.getConstructor(String.class);
|
||||
} catch (Exception e) {
|
||||
throw new ConstructorException(null, null,
|
||||
"Can't construct a java object for scalar " + node.getTag()
|
||||
+ "; No String constructor found. Exception="
|
||||
+ e.getMessage(), node.getStartMark(), e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
result = javaConstructor.newInstance(argument);
|
||||
} catch (Exception e) {
|
||||
throw new ConstructorException(null, null,
|
||||
"Can't construct a java object for scalar " + node.getTag()
|
||||
+ "; exception=" + e.getMessage(), node.getStartMark(), e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object constructStandardJavaInstance(Class type, ScalarNode node) {
|
||||
Object result;
|
||||
if (type == String.class) {
|
||||
Construct stringConstructor = yamlConstructors.get(Tag.STR);
|
||||
result = stringConstructor.construct((ScalarNode) node);
|
||||
} else if (type == Boolean.class || type == Boolean.TYPE) {
|
||||
Construct boolConstructor = yamlConstructors.get(Tag.BOOL);
|
||||
result = boolConstructor.construct((ScalarNode) node);
|
||||
} else if (type == Character.class || type == Character.TYPE) {
|
||||
Construct charConstructor = yamlConstructors.get(Tag.STR);
|
||||
String ch = (String) charConstructor.construct((ScalarNode) node);
|
||||
if (ch.length() == 0) {
|
||||
result = null;
|
||||
} else if (ch.length() != 1) {
|
||||
throw new YAMLException("Invalid node Character: '" + ch + "'; length: "
|
||||
+ ch.length());
|
||||
} else {
|
||||
result = new Character(ch.charAt(0));
|
||||
}
|
||||
} else if (Date.class.isAssignableFrom(type)) {
|
||||
Construct dateConstructor = yamlConstructors.get(Tag.TIMESTAMP);
|
||||
Date date = (Date) dateConstructor.construct((ScalarNode) node);
|
||||
if (type == Date.class) {
|
||||
result = date;
|
||||
} else {
|
||||
try {
|
||||
java.lang.reflect.Constructor<?> constr = type.getConstructor(long.class);
|
||||
result = constr.newInstance(date.getTime());
|
||||
} catch (Exception e) {
|
||||
throw new YAMLException("Cannot construct: '" + type + "'");
|
||||
}
|
||||
}
|
||||
} else if (type == Float.class || type == Double.class || type == Float.TYPE
|
||||
|| type == Double.TYPE || type == BigDecimal.class) {
|
||||
if (type == BigDecimal.class) {
|
||||
result = new BigDecimal(node.getValue());
|
||||
} else {
|
||||
Construct doubleConstructor = yamlConstructors.get(Tag.FLOAT);
|
||||
result = doubleConstructor.construct(node);
|
||||
if (type == Float.class || type == Float.TYPE) {
|
||||
result = new Float((Double) result);
|
||||
}
|
||||
}
|
||||
} else if (type == Byte.class || type == Short.class || type == Integer.class
|
||||
|| type == Long.class || type == BigInteger.class || type == Byte.TYPE
|
||||
|| type == Short.TYPE || type == Integer.TYPE || type == Long.TYPE) {
|
||||
Construct intConstructor = yamlConstructors.get(Tag.INT);
|
||||
result = intConstructor.construct(node);
|
||||
if (type == Byte.class || type == Byte.TYPE) {
|
||||
result = new Byte(result.toString());
|
||||
} else if (type == Short.class || type == Short.TYPE) {
|
||||
result = new Short(result.toString());
|
||||
} else if (type == Integer.class || type == Integer.TYPE) {
|
||||
result = new Integer(result.toString());
|
||||
} else if (type == Long.class || type == Long.TYPE) {
|
||||
result = new Long(result.toString());
|
||||
} else {
|
||||
// only BigInteger left
|
||||
result = new BigInteger(result.toString());
|
||||
}
|
||||
} else if (Enum.class.isAssignableFrom(type)) {
|
||||
String enumValueName = node.getValue();
|
||||
try {
|
||||
result = Enum.valueOf(type, enumValueName);
|
||||
} catch (Exception ex) {
|
||||
throw new YAMLException("Unable to find enum value '" + enumValueName
|
||||
+ "' for enum class: " + type.getName());
|
||||
}
|
||||
} else if (Calendar.class.isAssignableFrom(type)) {
|
||||
ConstructYamlTimestamp contr = new ConstructYamlTimestamp();
|
||||
contr.construct(node);
|
||||
result = contr.getCalendar();
|
||||
} else {
|
||||
throw new YAMLException("Unsupported class: " + type);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct sequence (List, Array, or immutable object) when the runtime
|
||||
* class is known.
|
||||
*/
|
||||
private class ConstructSequence implements Construct {
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object construct(Node node) {
|
||||
SequenceNode snode = (SequenceNode) node;
|
||||
if (List.class.isAssignableFrom(node.getType()) || node.getType().isArray()) {
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
return createDefaultList(snode.getValue().size());
|
||||
} else {
|
||||
return constructSequence(snode);
|
||||
}
|
||||
} else {
|
||||
// create immutable object
|
||||
List<java.lang.reflect.Constructor> possibleConstructors = new ArrayList<java.lang.reflect.Constructor>(
|
||||
snode.getValue().size());
|
||||
for (java.lang.reflect.Constructor constructor : node.getType().getConstructors()) {
|
||||
if (snode.getValue().size() == constructor.getParameterTypes().length) {
|
||||
possibleConstructors.add(constructor);
|
||||
}
|
||||
}
|
||||
if (possibleConstructors.isEmpty()) {
|
||||
throw new YAMLException("No constructors with "
|
||||
+ String.valueOf(snode.getValue().size()) + " arguments found for "
|
||||
+ node.getType());
|
||||
}
|
||||
List<Object> argumentList;
|
||||
if (possibleConstructors.size() == 1) {
|
||||
argumentList = new ArrayList<Object>(snode.getValue().size());
|
||||
java.lang.reflect.Constructor c = possibleConstructors.get(0);
|
||||
int index = 0;
|
||||
for (Node argumentNode : snode.getValue()) {
|
||||
Class type = c.getParameterTypes()[index];
|
||||
// set runtime classes for arguments
|
||||
argumentNode.setType(type);
|
||||
Object argumentValue = constructObject(argumentNode);
|
||||
argumentList.add(argumentValue);
|
||||
index++;
|
||||
}
|
||||
} else {
|
||||
// use BaseConstructor
|
||||
argumentList = (List<Object>) constructSequence(snode);
|
||||
}
|
||||
Class[] parameterTypes = new Class[argumentList.size()];
|
||||
int index = 0;
|
||||
for (Object parameter : argumentList) {
|
||||
parameterTypes[index] = parameter.getClass();
|
||||
index++;
|
||||
}
|
||||
java.lang.reflect.Constructor javaConstructor;
|
||||
try {
|
||||
Class cl = node.getType();
|
||||
javaConstructor = cl.getConstructor(parameterTypes);
|
||||
Object[] initargs = argumentList.toArray();
|
||||
return javaConstructor.newInstance(initargs);
|
||||
} catch (Exception e) {
|
||||
throw new YAMLException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void construct2ndStep(Node node, Object object) {
|
||||
SequenceNode snode = (SequenceNode) node;
|
||||
List<Object> list = (List<Object>) object;
|
||||
if (List.class.isAssignableFrom(node.getType())) {
|
||||
constructSequenceStep2(snode, list);
|
||||
} else {
|
||||
throw new YAMLException("Immutable objects cannot be recursive.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Class<?> getClassForNode(Node node) {
|
||||
Class<? extends Object> classForTag = typeTags.get(node.getTag());
|
||||
if (classForTag == null) {
|
||||
String name = node.getTag().getClassName();
|
||||
Class<?> cl;
|
||||
try {
|
||||
cl = getClassForName(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new YAMLException("Class not found: " + name);
|
||||
}
|
||||
typeTags.put(node.getTag(), cl);
|
||||
return cl;
|
||||
} else {
|
||||
return classForTag;
|
||||
}
|
||||
}
|
||||
|
||||
protected Class<?> getClassForName(String name) throws ClassNotFoundException {
|
||||
return Class.forName(name);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.constructor;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.MarkedYAMLException;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public class ConstructorException extends MarkedYAMLException {
|
||||
private static final long serialVersionUID = -8816339931365239910L;
|
||||
|
||||
protected ConstructorException(String context, Mark contextMark, String problem,
|
||||
Mark problemMark, Throwable cause) {
|
||||
super(context, contextMark, problem, problemMark, cause);
|
||||
}
|
||||
|
||||
protected ConstructorException(String context, Mark contextMark, String problem,
|
||||
Mark problemMark) {
|
||||
this(context, contextMark, problem, problemMark, null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.constructor;
|
||||
|
||||
/**
|
||||
* Construct instances with a custom Class Loader.
|
||||
*/
|
||||
public class CustomClassLoaderConstructor extends Constructor {
|
||||
private ClassLoader loader = CustomClassLoaderConstructor.class.getClassLoader();
|
||||
|
||||
public CustomClassLoaderConstructor(ClassLoader cLoader) {
|
||||
this(Object.class, cLoader);
|
||||
}
|
||||
|
||||
public CustomClassLoaderConstructor(Class<? extends Object> theRoot, ClassLoader theLoader) {
|
||||
super(theRoot);
|
||||
if (theLoader == null) {
|
||||
throw new NullPointerException("Loader must be provided.");
|
||||
}
|
||||
this.loader = theLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getClassForName(String name) throws ClassNotFoundException {
|
||||
return Class.forName(name, true, loader);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.constructor;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.*;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.util.Base64Coder;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Construct standard Java classes
|
||||
*
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public class SafeConstructor extends BaseConstructor {
|
||||
|
||||
public static ConstructUndefined undefinedConstructor = new ConstructUndefined();
|
||||
|
||||
public SafeConstructor() {
|
||||
this.yamlConstructors.put(Tag.NULL, new ConstructYamlNull());
|
||||
this.yamlConstructors.put(Tag.BOOL, new ConstructYamlBool());
|
||||
this.yamlConstructors.put(Tag.INT, new ConstructYamlInt());
|
||||
this.yamlConstructors.put(Tag.FLOAT, new ConstructYamlFloat());
|
||||
this.yamlConstructors.put(Tag.BINARY, new ConstructYamlBinary());
|
||||
this.yamlConstructors.put(Tag.TIMESTAMP, new ConstructYamlTimestamp());
|
||||
this.yamlConstructors.put(Tag.OMAP, new ConstructYamlOmap());
|
||||
this.yamlConstructors.put(Tag.PAIRS, new ConstructYamlPairs());
|
||||
this.yamlConstructors.put(Tag.SET, new ConstructYamlSet());
|
||||
this.yamlConstructors.put(Tag.STR, new ConstructYamlStr());
|
||||
this.yamlConstructors.put(Tag.SEQ, new ConstructYamlSeq());
|
||||
this.yamlConstructors.put(Tag.MAP, new ConstructYamlMap());
|
||||
this.yamlConstructors.put(null, undefinedConstructor);
|
||||
this.yamlClassConstructors.put(NodeId.scalar, undefinedConstructor);
|
||||
this.yamlClassConstructors.put(NodeId.sequence, undefinedConstructor);
|
||||
this.yamlClassConstructors.put(NodeId.mapping, undefinedConstructor);
|
||||
}
|
||||
|
||||
private void flattenMapping(MappingNode node) {
|
||||
List<NodeTuple> merge = new ArrayList<NodeTuple>();
|
||||
int index = 0;
|
||||
List<NodeTuple> nodeValue = (List<NodeTuple>) node.getValue();
|
||||
while (index < nodeValue.size()) {
|
||||
Node keyNode = nodeValue.get(index).getKeyNode();
|
||||
Node valueNode = nodeValue.get(index).getValueNode();
|
||||
if (keyNode.getTag().equals(Tag.MERGE)) {
|
||||
nodeValue.remove(index);
|
||||
switch (valueNode.getNodeId()) {
|
||||
case mapping:
|
||||
MappingNode mn = (MappingNode) valueNode;
|
||||
flattenMapping(mn);
|
||||
merge.addAll(mn.getValue());
|
||||
break;
|
||||
case sequence:
|
||||
List<List<NodeTuple>> submerge = new ArrayList<List<NodeTuple>>();
|
||||
SequenceNode sn = (SequenceNode) valueNode;
|
||||
List<Node> vals = sn.getValue();
|
||||
for (Node subnode : vals) {
|
||||
if (!(subnode instanceof MappingNode)) {
|
||||
throw new ConstructorException("while constructing a mapping", node
|
||||
.getStartMark(), "expected a mapping for merging, but found "
|
||||
+ subnode.getNodeId(), subnode.getStartMark());
|
||||
}
|
||||
MappingNode mnode = (MappingNode) subnode;
|
||||
flattenMapping(mnode);
|
||||
submerge.add(mnode.getValue());
|
||||
}
|
||||
Collections.reverse(submerge);
|
||||
for (List<NodeTuple> value : submerge) {
|
||||
merge.addAll(value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new ConstructorException("while constructing a mapping", node
|
||||
.getStartMark(),
|
||||
"expected a mapping or list of mappings for merging, but found "
|
||||
+ valueNode.getNodeId(), valueNode.getStartMark());
|
||||
}
|
||||
} else if (keyNode.getTag().equals(Tag.VALUE)) {
|
||||
keyNode.setTag(Tag.STR);
|
||||
index++;
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
if (!merge.isEmpty()) {
|
||||
merge.addAll(nodeValue);
|
||||
((MappingNode) node).setValue(merge);
|
||||
}
|
||||
}
|
||||
|
||||
protected void constructMapping2ndStep(MappingNode node, Map<Object, Object> mapping) {
|
||||
flattenMapping(node);
|
||||
super.constructMapping2ndStep(node, mapping);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void constructSet2ndStep(MappingNode node, java.util.Set<Object> set) {
|
||||
flattenMapping(node);
|
||||
super.constructSet2ndStep(node, set);
|
||||
}
|
||||
|
||||
private class ConstructYamlNull extends AbstractConstruct {
|
||||
public Object construct(Node node) {
|
||||
constructScalar((ScalarNode) node);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final static Map<String, Boolean> BOOL_VALUES = new HashMap<String, Boolean>();
|
||||
|
||||
static {
|
||||
BOOL_VALUES.put("yes", Boolean.TRUE);
|
||||
BOOL_VALUES.put("no", Boolean.FALSE);
|
||||
BOOL_VALUES.put("true", Boolean.TRUE);
|
||||
BOOL_VALUES.put("false", Boolean.FALSE);
|
||||
BOOL_VALUES.put("on", Boolean.TRUE);
|
||||
BOOL_VALUES.put("off", Boolean.FALSE);
|
||||
}
|
||||
|
||||
private class ConstructYamlBool extends AbstractConstruct {
|
||||
public Object construct(Node node) {
|
||||
String val = (String) constructScalar((ScalarNode) node);
|
||||
return BOOL_VALUES.get(val.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
private class ConstructYamlInt extends AbstractConstruct {
|
||||
public Object construct(Node node) {
|
||||
String value = constructScalar((ScalarNode) node).toString().replaceAll("_", "");
|
||||
int sign = +1;
|
||||
char first = value.charAt(0);
|
||||
if (first == '-') {
|
||||
sign = -1;
|
||||
value = value.substring(1);
|
||||
} else if (first == '+') {
|
||||
value = value.substring(1);
|
||||
}
|
||||
int base = 10;
|
||||
if ("0".equals(value)) {
|
||||
return new Integer(0);
|
||||
} else if (value.startsWith("0b")) {
|
||||
value = value.substring(2);
|
||||
base = 2;
|
||||
} else if (value.startsWith("0x")) {
|
||||
value = value.substring(2);
|
||||
base = 16;
|
||||
} else if (value.startsWith("0")) {
|
||||
value = value.substring(1);
|
||||
base = 8;
|
||||
} else if (value.indexOf(':') != -1) {
|
||||
String[] digits = value.split(":");
|
||||
int bes = 1;
|
||||
int val = 0;
|
||||
for (int i = 0, j = digits.length; i < j; i++) {
|
||||
val += (Long.parseLong(digits[(j - i) - 1]) * bes);
|
||||
bes *= 60;
|
||||
}
|
||||
return createNumber(sign, String.valueOf(val), 10);
|
||||
} else {
|
||||
return createNumber(sign, value, 10);
|
||||
}
|
||||
return createNumber(sign, value, base);
|
||||
}
|
||||
}
|
||||
|
||||
private Number createNumber(int sign, String number, int radix) {
|
||||
Number result;
|
||||
if (sign < 0) {
|
||||
number = "-" + number;
|
||||
}
|
||||
try {
|
||||
result = Integer.valueOf(number, radix);
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
result = Long.valueOf(number, radix);
|
||||
} catch (NumberFormatException e1) {
|
||||
result = new BigInteger(number, radix);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private class ConstructYamlFloat extends AbstractConstruct {
|
||||
public Object construct(Node node) {
|
||||
String value = constructScalar((ScalarNode) node).toString().replaceAll("_", "");
|
||||
int sign = +1;
|
||||
char first = value.charAt(0);
|
||||
if (first == '-') {
|
||||
sign = -1;
|
||||
value = value.substring(1);
|
||||
} else if (first == '+') {
|
||||
value = value.substring(1);
|
||||
}
|
||||
String valLower = value.toLowerCase();
|
||||
if (".inf".equals(valLower)) {
|
||||
return new Double(sign == -1 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY);
|
||||
} else if (".nan".equals(valLower)) {
|
||||
return new Double(Double.NaN);
|
||||
} else if (value.indexOf(':') != -1) {
|
||||
String[] digits = value.split(":");
|
||||
int bes = 1;
|
||||
double val = 0.0;
|
||||
for (int i = 0, j = digits.length; i < j; i++) {
|
||||
val += (Double.parseDouble(digits[(j - i) - 1]) * bes);
|
||||
bes *= 60;
|
||||
}
|
||||
return new Double(sign * val);
|
||||
} else {
|
||||
Double d = Double.valueOf(value);
|
||||
return new Double(d.doubleValue() * sign);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ConstructYamlBinary extends AbstractConstruct {
|
||||
public Object construct(Node node) {
|
||||
byte[] decoded = Base64Coder.decode(constructScalar((ScalarNode) node).toString()
|
||||
.toCharArray());
|
||||
return decoded;
|
||||
}
|
||||
}
|
||||
|
||||
private final static Pattern TIMESTAMP_REGEXP = Pattern
|
||||
.compile("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ \t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \t]*(?:Z|([-+][0-9][0-9]?)(?::([0-9][0-9])?)?))?)?$");
|
||||
private final static Pattern YMD_REGEXP = Pattern
|
||||
.compile("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)$");
|
||||
|
||||
protected class ConstructYamlTimestamp extends AbstractConstruct {
|
||||
private Calendar calendar;
|
||||
|
||||
public Calendar getCalendar() {
|
||||
return calendar;
|
||||
}
|
||||
|
||||
public Object construct(Node node) {
|
||||
ScalarNode scalar = (ScalarNode) node;
|
||||
String nodeValue = scalar.getValue();
|
||||
Matcher match = YMD_REGEXP.matcher(nodeValue);
|
||||
if (match.matches()) {
|
||||
String year_s = match.group(1);
|
||||
String month_s = match.group(2);
|
||||
String day_s = match.group(3);
|
||||
calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||
calendar.clear();
|
||||
calendar.set(Calendar.YEAR, Integer.parseInt(year_s));
|
||||
// Java's months are zero-based...
|
||||
calendar.set(Calendar.MONTH, Integer.parseInt(month_s) - 1); // x
|
||||
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day_s));
|
||||
return calendar.getTime();
|
||||
} else {
|
||||
match = TIMESTAMP_REGEXP.matcher(nodeValue);
|
||||
if (!match.matches()) {
|
||||
throw new YAMLException("Unexpected timestamp: " + nodeValue);
|
||||
}
|
||||
String year_s = match.group(1);
|
||||
String month_s = match.group(2);
|
||||
String day_s = match.group(3);
|
||||
String hour_s = match.group(4);
|
||||
String min_s = match.group(5);
|
||||
String sec_s = match.group(6);
|
||||
String fract_s = match.group(7);
|
||||
String timezoneh_s = match.group(8);
|
||||
String timezonem_s = match.group(9);
|
||||
|
||||
int usec = 0;
|
||||
if (fract_s != null) {
|
||||
usec = Integer.parseInt(fract_s);
|
||||
if (usec != 0) {
|
||||
while (10 * usec < 1000) {
|
||||
usec *= 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
TimeZone timeZone;
|
||||
if (timezoneh_s != null) {
|
||||
String time = timezonem_s != null ? ":" + timezonem_s : "00";
|
||||
timeZone = TimeZone.getTimeZone("GMT" + timezoneh_s + time);
|
||||
} else {
|
||||
// no time zone provided
|
||||
timeZone = TimeZone.getTimeZone("UTC");
|
||||
}
|
||||
calendar = Calendar.getInstance(timeZone);
|
||||
calendar.set(Calendar.YEAR, Integer.parseInt(year_s));
|
||||
// Java's months are zero-based...
|
||||
calendar.set(Calendar.MONTH, Integer.parseInt(month_s) - 1);
|
||||
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day_s));
|
||||
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hour_s));
|
||||
calendar.set(Calendar.MINUTE, Integer.parseInt(min_s));
|
||||
calendar.set(Calendar.SECOND, Integer.parseInt(sec_s));
|
||||
calendar.set(Calendar.MILLISECOND, usec);
|
||||
return calendar.getTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ConstructYamlOmap extends AbstractConstruct {
|
||||
public Object construct(Node node) {
|
||||
// Note: we do not check for duplicate keys, because it's too
|
||||
// CPU-expensive.
|
||||
Map<Object, Object> omap = new LinkedHashMap<Object, Object>();
|
||||
if (!(node instanceof SequenceNode)) {
|
||||
throw new ConstructorException("while constructing an ordered map", node
|
||||
.getStartMark(), "expected a sequence, but found " + node.getNodeId(), node
|
||||
.getStartMark());
|
||||
}
|
||||
SequenceNode snode = (SequenceNode) node;
|
||||
for (Node subnode : snode.getValue()) {
|
||||
if (!(subnode instanceof MappingNode)) {
|
||||
throw new ConstructorException("while constructing an ordered map", node
|
||||
.getStartMark(), "expected a mapping of length 1, but found "
|
||||
+ subnode.getNodeId(), subnode.getStartMark());
|
||||
}
|
||||
MappingNode mnode = (MappingNode) subnode;
|
||||
if (mnode.getValue().size() != 1) {
|
||||
throw new ConstructorException("while constructing an ordered map", node
|
||||
.getStartMark(), "expected a single mapping item, but found "
|
||||
+ mnode.getValue().size() + " items", mnode.getStartMark());
|
||||
}
|
||||
Node keyNode = mnode.getValue().get(0).getKeyNode();
|
||||
Node valueNode = mnode.getValue().get(0).getValueNode();
|
||||
Object key = constructObject(keyNode);
|
||||
Object value = constructObject(valueNode);
|
||||
omap.put(key, value);
|
||||
}
|
||||
return omap;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: the same code as `construct_yaml_omap`.
|
||||
|
||||
private class ConstructYamlPairs extends AbstractConstruct {
|
||||
public Object construct(Node node) {
|
||||
// Note: we do not check for duplicate keys, because it's too
|
||||
// CPU-expensive.
|
||||
if (!(node instanceof SequenceNode)) {
|
||||
throw new ConstructorException("while constructing pairs", node.getStartMark(),
|
||||
"expected a sequence, but found " + node.getNodeId(), node.getStartMark());
|
||||
}
|
||||
SequenceNode snode = (SequenceNode) node;
|
||||
List<Object[]> pairs = new ArrayList<Object[]>(snode.getValue().size());
|
||||
for (Node subnode : snode.getValue()) {
|
||||
if (!(subnode instanceof MappingNode)) {
|
||||
throw new ConstructorException("while constructingpairs", node.getStartMark(),
|
||||
"expected a mapping of length 1, but found " + subnode.getNodeId(),
|
||||
subnode.getStartMark());
|
||||
}
|
||||
MappingNode mnode = (MappingNode) subnode;
|
||||
if (mnode.getValue().size() != 1) {
|
||||
throw new ConstructorException("while constructing pairs", node.getStartMark(),
|
||||
"expected a single mapping item, but found " + mnode.getValue().size()
|
||||
+ " items", mnode.getStartMark());
|
||||
}
|
||||
Node keyNode = mnode.getValue().get(0).getKeyNode();
|
||||
Node valueNode = mnode.getValue().get(0).getValueNode();
|
||||
Object key = constructObject(keyNode);
|
||||
Object value = constructObject(valueNode);
|
||||
pairs.add(new Object[]{key, value});
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
}
|
||||
|
||||
private class ConstructYamlSet implements Construct {
|
||||
public Object construct(Node node) {
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
return createDefaultSet();
|
||||
} else {
|
||||
return constructSet((MappingNode) node);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void construct2ndStep(Node node, Object object) {
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
constructSet2ndStep((MappingNode) node, (Set<Object>) object);
|
||||
} else {
|
||||
throw new YAMLException("Unexpected recursive set structure. Node: " + node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ConstructYamlStr extends AbstractConstruct {
|
||||
public Object construct(Node node) {
|
||||
return (String) constructScalar((ScalarNode) node);
|
||||
}
|
||||
}
|
||||
|
||||
private class ConstructYamlSeq implements Construct {
|
||||
public Object construct(Node node) {
|
||||
SequenceNode seqNode = (SequenceNode) node;
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
return createDefaultList((seqNode.getValue()).size());
|
||||
} else {
|
||||
return constructSequence(seqNode);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void construct2ndStep(Node node, Object data) {
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
constructSequenceStep2((SequenceNode) node, (List<Object>) data);
|
||||
} else {
|
||||
throw new YAMLException("Unexpected recursive sequence structure. Node: " + node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ConstructYamlMap implements Construct {
|
||||
public Object construct(Node node) {
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
return createDefaultMap();
|
||||
} else {
|
||||
return constructMapping((MappingNode) node);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void construct2ndStep(Node node, Object object) {
|
||||
if (node.isTwoStepsConstruction()) {
|
||||
constructMapping2ndStep((MappingNode) node, (Map<Object, Object>) object);
|
||||
} else {
|
||||
throw new YAMLException("Unexpected recursive mapping structure. Node: " + node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ConstructUndefined extends AbstractConstruct {
|
||||
public Object construct(Node node) {
|
||||
throw new ConstructorException(null, null,
|
||||
"could not determine a constructor for the tag " + node.getTag(), node
|
||||
.getStartMark());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.error;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.scanner.Constant;
|
||||
|
||||
/**
|
||||
* It's just a record and its only use is producing nice error messages. Parser
|
||||
* does not use it for any other purposes.
|
||||
*
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class Mark {
|
||||
private String name;
|
||||
private int line;
|
||||
private int column;
|
||||
private String buffer;
|
||||
private int pointer;
|
||||
|
||||
public Mark(String name, int index, int line, int column, String buffer, int pointer) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
this.buffer = buffer;
|
||||
this.pointer = pointer;
|
||||
}
|
||||
|
||||
private boolean isLineBreak(char ch) {
|
||||
return Constant.NULL_OR_LINEBR.has(ch);
|
||||
}
|
||||
|
||||
public String get_snippet(int indent, int max_length) {
|
||||
if (buffer == null) {
|
||||
return null;
|
||||
}
|
||||
float half = max_length / 2 - 1;
|
||||
int start = pointer;
|
||||
String head = "";
|
||||
while ((start > 0) && (!isLineBreak(buffer.charAt(start - 1)))) {
|
||||
start -= 1;
|
||||
if (pointer - start > half) {
|
||||
head = " ... ";
|
||||
start += 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String tail = "";
|
||||
int end = pointer;
|
||||
while ((end < buffer.length()) && (!isLineBreak(buffer.charAt(end)))) {
|
||||
end += 1;
|
||||
if (end - pointer > half) {
|
||||
tail = " ... ";
|
||||
end -= 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String snippet = buffer.substring(start, end);
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < indent; i++) {
|
||||
result.append(" ");
|
||||
}
|
||||
result.append(head);
|
||||
result.append(snippet);
|
||||
result.append(tail);
|
||||
result.append("\n");
|
||||
for (int i = 0; i < indent + pointer - start + head.length(); i++) {
|
||||
result.append(" ");
|
||||
}
|
||||
result.append("^");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public String get_snippet() {
|
||||
return get_snippet(4, 75);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String snippet = get_snippet();
|
||||
StringBuilder where = new StringBuilder(" in \"");
|
||||
where.append(name);
|
||||
where.append("\", line ");
|
||||
where.append(line + 1);
|
||||
where.append(", column ");
|
||||
where.append(column + 1);
|
||||
if (snippet != null) {
|
||||
where.append(":\n");
|
||||
where.append(snippet);
|
||||
}
|
||||
return where.toString();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* starts with 0
|
||||
*/
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* starts with 0
|
||||
*/
|
||||
public int getColumn() {
|
||||
return column;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.error;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public class MarkedYAMLException extends YAMLException {
|
||||
|
||||
private static final long serialVersionUID = -9119388488683035101L;
|
||||
private String context;
|
||||
private Mark contextMark;
|
||||
private String problem;
|
||||
private Mark problemMark;
|
||||
private String note;
|
||||
|
||||
protected MarkedYAMLException(String context, Mark contextMark, String problem,
|
||||
Mark problemMark, String note) {
|
||||
this(context, contextMark, problem, problemMark, note, null);
|
||||
}
|
||||
|
||||
protected MarkedYAMLException(String context, Mark contextMark, String problem,
|
||||
Mark problemMark, String note, Throwable cause) {
|
||||
super(context + "; " + problem, cause);
|
||||
this.context = context;
|
||||
this.contextMark = contextMark;
|
||||
this.problem = problem;
|
||||
this.problemMark = problemMark;
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
protected MarkedYAMLException(String context, Mark contextMark, String problem, Mark problemMark) {
|
||||
this(context, contextMark, problem, problemMark, null, null);
|
||||
}
|
||||
|
||||
protected MarkedYAMLException(String context, Mark contextMark, String problem,
|
||||
Mark problemMark, Throwable cause) {
|
||||
this(context, contextMark, problem, problemMark, null, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder lines = new StringBuilder();
|
||||
if (context != null) {
|
||||
lines.append(context);
|
||||
lines.append("\n");
|
||||
}
|
||||
if (contextMark != null
|
||||
&& (problem == null || problemMark == null
|
||||
|| (contextMark.getName() != problemMark.getName())
|
||||
|| (contextMark.getLine() != problemMark.getLine()) || (contextMark
|
||||
.getColumn() != problemMark.getColumn()))) {
|
||||
lines.append(contextMark.toString());
|
||||
lines.append("\n");
|
||||
}
|
||||
if (problem != null) {
|
||||
lines.append(problem);
|
||||
lines.append("\n");
|
||||
}
|
||||
if (problemMark != null) {
|
||||
lines.append(problemMark.toString());
|
||||
lines.append("\n");
|
||||
}
|
||||
if (note != null) {
|
||||
lines.append(note);
|
||||
lines.append("\n");
|
||||
}
|
||||
return lines.toString();
|
||||
}
|
||||
|
||||
public String getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public Mark getContextMark() {
|
||||
return contextMark;
|
||||
}
|
||||
|
||||
public String getProblem() {
|
||||
return problem;
|
||||
}
|
||||
|
||||
public Mark getProblemMark() {
|
||||
return problemMark;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.error;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public class YAMLException extends RuntimeException {
|
||||
private static final long serialVersionUID = -4738336175050337570L;
|
||||
|
||||
public YAMLException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public YAMLException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public YAMLException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Marks the inclusion of a previously anchored node.
|
||||
*/
|
||||
public final class AliasEvent extends NodeEvent {
|
||||
public AliasEvent(String anchor, Mark startMark, Mark endMark) {
|
||||
super(anchor, startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(ID id) {
|
||||
return ID.Alias == id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Base class for the end events of the collection nodes.
|
||||
*/
|
||||
public abstract class CollectionEndEvent extends Event {
|
||||
|
||||
public CollectionEndEvent(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Base class for the start events of the collection nodes.
|
||||
*/
|
||||
public abstract class CollectionStartEvent extends NodeEvent {
|
||||
private final String tag;
|
||||
// The implicit flag of a collection start event indicates if the tag may be
|
||||
// omitted when the collection is emitted
|
||||
private final boolean implicit;
|
||||
// flag indicates if a collection is block or flow
|
||||
private final Boolean flowStyle;
|
||||
|
||||
public CollectionStartEvent(String anchor, String tag, boolean implicit, Mark startMark,
|
||||
Mark endMark, Boolean flowStyle) {
|
||||
super(anchor, startMark, endMark);
|
||||
this.tag = tag;
|
||||
this.implicit = implicit;
|
||||
this.flowStyle = flowStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag of this collection.
|
||||
*
|
||||
* @return The tag of this collection, or <code>null</code> if no explicit
|
||||
* tag is available.
|
||||
*/
|
||||
public String getTag() {
|
||||
return this.tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>true</code> if the tag can be omitted while this collection is
|
||||
* emitted.
|
||||
*
|
||||
* @return True if the tag can be omitted while this collection is emitted.
|
||||
*/
|
||||
public boolean getImplicit() {
|
||||
return this.implicit;
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>true</code> if this collection is in flow style, <code>false</code>
|
||||
* for block style.
|
||||
*
|
||||
* @return If this collection is in flow style.
|
||||
*/
|
||||
public Boolean getFlowStyle() {
|
||||
return this.flowStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getArguments() {
|
||||
return super.getArguments() + ", tag=" + tag + ", implicit=" + implicit;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Marks the end of a document.
|
||||
* <p>
|
||||
* This event follows the document's content.
|
||||
* </p>
|
||||
*/
|
||||
public final class DocumentEndEvent extends Event {
|
||||
private final boolean explicit;
|
||||
|
||||
public DocumentEndEvent(Mark startMark, Mark endMark, boolean explicit) {
|
||||
super(startMark, endMark);
|
||||
this.explicit = explicit;
|
||||
}
|
||||
|
||||
public boolean getExplicit() {
|
||||
return explicit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(ID id) {
|
||||
return ID.DocumentEnd == id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Marks the beginning of a document.
|
||||
* <p>
|
||||
* This event followed by the document's content and a {@link DocumentEndEvent}.
|
||||
* </p>
|
||||
*/
|
||||
public final class DocumentStartEvent extends Event {
|
||||
private final boolean explicit;
|
||||
private final Integer[] version;
|
||||
private final Map<String, String> tags;
|
||||
|
||||
public DocumentStartEvent(Mark startMark, Mark endMark, boolean explicit, Integer[] version,
|
||||
Map<String, String> tags) {
|
||||
super(startMark, endMark);
|
||||
this.explicit = explicit;
|
||||
this.version = version;
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public boolean getExplicit() {
|
||||
return explicit;
|
||||
}
|
||||
|
||||
/**
|
||||
* YAML version the document conforms to.
|
||||
*
|
||||
* @return <code>null</code>if the document has no explicit
|
||||
* <code>%YAML</code> directive. Otherwise an array with two
|
||||
* components, the major and minor part of the version (in this
|
||||
* order).
|
||||
*/
|
||||
public Integer[] getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag shorthands as defined by the <code>%TAG</code> directive.
|
||||
*
|
||||
* @return Mapping of 'handles' to 'prefixes' (the handles include the '!'
|
||||
* characters).
|
||||
*/
|
||||
public Map<String, String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(ID id) {
|
||||
return ID.DocumentStart == id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Basic unit of output from a {@link org.elasticsearch.util.yaml.snakeyaml.parser.Parser} or input
|
||||
* of a {@link org.elasticsearch.util.yaml.snakeyaml.emitter.Emitter}.
|
||||
*/
|
||||
public abstract class Event {
|
||||
public enum ID {
|
||||
Alias, DocumentEnd, DocumentStart, MappingEnd, MappingStart, Scalar, SequenceEnd, SequenceStart, StreamEnd, StreamStart
|
||||
}
|
||||
|
||||
private final Mark startMark;
|
||||
private final Mark endMark;
|
||||
|
||||
public Event(Mark startMark, Mark endMark) {
|
||||
this.startMark = startMark;
|
||||
this.endMark = endMark;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "<" + this.getClass().getName() + "(" + getArguments() + ")>";
|
||||
}
|
||||
|
||||
public Mark getStartMark() {
|
||||
return startMark;
|
||||
}
|
||||
|
||||
public Mark getEndMark() {
|
||||
return endMark;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see __repr__ for Event in PyYAML
|
||||
*/
|
||||
protected String getArguments() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public abstract boolean is(ID id);
|
||||
|
||||
/*
|
||||
* for tests only
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Event) {
|
||||
return toString().equals(obj.toString());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
/**
|
||||
* The implicit flag of a scalar event is a pair of boolean values that indicate
|
||||
* if the tag may be omitted when the scalar is emitted in a plain and non-plain
|
||||
* style correspondingly.
|
||||
*
|
||||
* @see http://pyyaml.org/wiki/PyYAMLDocumentation#Events
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public class ImplicitTuple {
|
||||
private final boolean plain;
|
||||
private final boolean nonPlain;
|
||||
|
||||
public ImplicitTuple(boolean plain, boolean nonplain) {
|
||||
this.plain = plain;
|
||||
this.nonPlain = nonplain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true when tag may be omitted when the scalar is emitted in a
|
||||
* plain style.
|
||||
*/
|
||||
public boolean isFirst() {
|
||||
return plain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true when tag may be omitted when the scalar is emitted in a
|
||||
* non-plain style.
|
||||
*/
|
||||
public boolean isSecond() {
|
||||
return nonPlain;
|
||||
}
|
||||
|
||||
public boolean bothFalse() {
|
||||
return !plain && !nonPlain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "implicit=[" + plain + ", " + nonPlain + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Marks the end of a mapping node.
|
||||
*
|
||||
* @see MappingStartEvent
|
||||
*/
|
||||
public final class MappingEndEvent extends CollectionEndEvent {
|
||||
|
||||
public MappingEndEvent(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(ID id) {
|
||||
return ID.MappingEnd == id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Marks the beginning of a mapping node.
|
||||
* <p>
|
||||
* This event is followed by a number of key value pairs. <br>
|
||||
* The pairs are not in any particular order. However, the value always directly
|
||||
* follows the corresponding key. <br>
|
||||
* After the key value pairs follows a {@link MappingEndEvent}.
|
||||
* </p>
|
||||
* <p>
|
||||
* There must be an even number of node events between the start and end event.
|
||||
* </p>
|
||||
*
|
||||
* @see MappingEndEvent
|
||||
*/
|
||||
public final class MappingStartEvent extends CollectionStartEvent {
|
||||
public MappingStartEvent(String anchor, String tag, boolean implicit, Mark startMark,
|
||||
Mark endMark, Boolean flowStyle) {
|
||||
super(anchor, tag, implicit, startMark, endMark, flowStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(ID id) {
|
||||
return ID.MappingStart == id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Base class for all events that mark the beginning of a node.
|
||||
*/
|
||||
public abstract class NodeEvent extends Event {
|
||||
|
||||
private final String anchor;
|
||||
|
||||
public NodeEvent(String anchor, Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
this.anchor = anchor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Node anchor by which this node might later be referenced by a
|
||||
* {@link AliasEvent}.
|
||||
* <p>
|
||||
* Note that {@link AliasEvent}s are by it self <code>NodeEvent</code>s and
|
||||
* use this property to indicate the referenced anchor.
|
||||
*
|
||||
* @return Anchor of this node or <code>null</code> if no anchor is defined.
|
||||
*/
|
||||
public String getAnchor() {
|
||||
return this.anchor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getArguments() {
|
||||
return "anchor=" + anchor;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Marks a scalar value.
|
||||
*/
|
||||
public final class ScalarEvent extends NodeEvent {
|
||||
private final String tag;
|
||||
// style flag of a scalar event indicates the style of the scalar. Possible
|
||||
// values are None, '', '\'', '"', '|', '>'
|
||||
private final Character style;
|
||||
private final String value;
|
||||
// The implicit flag of a scalar event is a pair of boolean values that
|
||||
// indicate if the tag may be omitted when the scalar is emitted in a plain
|
||||
// and non-plain style correspondingly.
|
||||
private final ImplicitTuple implicit;
|
||||
|
||||
public ScalarEvent(String anchor, String tag, ImplicitTuple implicit, String value,
|
||||
Mark startMark, Mark endMark, Character style) {
|
||||
super(anchor, startMark, endMark);
|
||||
this.tag = tag;
|
||||
this.implicit = implicit;
|
||||
this.value = value;
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag of this scalar.
|
||||
*
|
||||
* @return The tag of this scalar, or <code>null</code> if no explicit tag
|
||||
* is available.
|
||||
*/
|
||||
public String getTag() {
|
||||
return this.tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Style of the scalar.
|
||||
* <dl>
|
||||
* <dt>''</dt>
|
||||
* <dd>Flow Style - Plain</dd>
|
||||
* <dt>'\''</dt>
|
||||
* <dd>Flow Style - Single-Quoted</dd>
|
||||
* <dt>'"'</dt>
|
||||
* <dd>Flow Style - Double-Quoted</dd>
|
||||
* <dt>'|'</dt>
|
||||
* <dd>Block Style - Literal</dd>
|
||||
* <dt>'>'</dt>
|
||||
* <dd>Block Style - Folded</dd>
|
||||
* </dl>
|
||||
*
|
||||
* @return Style of the scalar.
|
||||
* @see http://yaml.org/spec/1.1/#id864487
|
||||
*/
|
||||
public Character getStyle() {
|
||||
return this.style;
|
||||
}
|
||||
|
||||
/**
|
||||
* String representation of the value.
|
||||
* <p>
|
||||
* Without quotes and escaping.
|
||||
* </p>
|
||||
*
|
||||
* @return Value as Unicode string.
|
||||
*/
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public ImplicitTuple getImplicit() {
|
||||
return this.implicit;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getArguments() {
|
||||
return super.getArguments() + ", tag=" + tag + ", " + implicit + ", value=" + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(ID id) {
|
||||
return ID.Scalar == id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Marks the end of a sequence.
|
||||
*
|
||||
* @see SequenceStartEvent
|
||||
*/
|
||||
public final class SequenceEndEvent extends CollectionEndEvent {
|
||||
|
||||
public SequenceEndEvent(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(ID id) {
|
||||
return ID.SequenceEnd == id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Marks the beginning of a sequence node.
|
||||
* <p>
|
||||
* This event is followed by the elements contained in the sequence, and a
|
||||
* {@link SequenceEndEvent}.
|
||||
* </p>
|
||||
*
|
||||
* @see SequenceEndEvent
|
||||
*/
|
||||
public final class SequenceStartEvent extends CollectionStartEvent {
|
||||
public SequenceStartEvent(String anchor, String tag, boolean implicit, Mark startMark,
|
||||
Mark endMark, Boolean flowStyle) {
|
||||
super(anchor, tag, implicit, startMark, endMark, flowStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(ID id) {
|
||||
return ID.SequenceStart == id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Marks the end of a stream that might have contained multiple documents.
|
||||
* <p>
|
||||
* This event is the last event that a parser emits. Together with
|
||||
* {@link StreamStartEvent} (which is the first event a parser emits) they mark
|
||||
* the beginning and the end of a stream of documents.
|
||||
* </p>
|
||||
* <p>
|
||||
* See {@link Event} for an exemplary output.
|
||||
* </p>
|
||||
*/
|
||||
public final class StreamEndEvent extends Event {
|
||||
public StreamEndEvent(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(ID id) {
|
||||
return ID.StreamEnd == id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.events;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Marks the start of a stream that might contain multiple documents.
|
||||
* <p>
|
||||
* This event is the first event that a parser emits. Together with
|
||||
* {@link StreamEndEvent} (which is the last event a parser emits) they mark the
|
||||
* beginning and the end of a stream of documents.
|
||||
* </p>
|
||||
* <p>
|
||||
* See {@link Event} for an exemplary output.
|
||||
* </p>
|
||||
*/
|
||||
public final class StreamStartEvent extends Event {
|
||||
|
||||
public StreamStartEvent(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is(ID id) {
|
||||
return ID.StreamStart == id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.introspector;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class FieldProperty extends Property {
|
||||
private final Field field;
|
||||
|
||||
public FieldProperty(Field field) {
|
||||
super(field.getName(), field.getType());
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object object, Object value) throws Exception {
|
||||
field.set(object, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object object) {
|
||||
try {
|
||||
return field.get(object);
|
||||
} catch (Exception e) {
|
||||
throw new YAMLException("Unable to access field " + field.getName() + " on object "
|
||||
+ object + " : " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getActualTypeArguments() {
|
||||
if (field.getGenericType() instanceof ParameterizedType) {
|
||||
ParameterizedType t = (ParameterizedType) field.getGenericType();
|
||||
return t.getActualTypeArguments();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.introspector;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class MethodProperty extends Property {
|
||||
private final PropertyDescriptor property;
|
||||
|
||||
public MethodProperty(PropertyDescriptor property) {
|
||||
super(property.getName(), property.getPropertyType());
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object object, Object value) throws Exception {
|
||||
property.getWriteMethod().invoke(object, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getActualTypeArguments() {
|
||||
if (List.class.isAssignableFrom(property.getPropertyType())
|
||||
|| Set.class.isAssignableFrom(property.getPropertyType())
|
||||
|| Map.class.isAssignableFrom(property.getPropertyType())) {
|
||||
if (property.getReadMethod().getGenericReturnType() instanceof ParameterizedType) {
|
||||
ParameterizedType grt = (ParameterizedType) property.getReadMethod()
|
||||
.getGenericReturnType();
|
||||
return grt.getActualTypeArguments();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object object) {
|
||||
try {
|
||||
return property.getReadMethod().invoke(object);
|
||||
} catch (Exception e) {
|
||||
throw new YAMLException("Unable to find getter for property '" + property.getName()
|
||||
+ "' on object " + object + ":" + e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.introspector;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public abstract class Property implements Comparable<Property> {
|
||||
private final String name;
|
||||
private final Class<? extends Object> type;
|
||||
|
||||
public Property(String name, Class<? extends Object> type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Class<? extends Object> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public abstract Type[] getActualTypeArguments();
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() + " of " + getType();
|
||||
}
|
||||
|
||||
public int compareTo(Property o) {
|
||||
return name.compareTo(o.name);
|
||||
}
|
||||
|
||||
abstract public void set(Object object, Object value) throws Exception;
|
||||
|
||||
abstract public Object get(Object object);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.nodes;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Base class for the two collection types {@link MappingNode mapping} and
|
||||
* {@link SequenceNode collection}.
|
||||
*/
|
||||
public abstract class CollectionNode extends Node {
|
||||
private Boolean flowStyle;
|
||||
|
||||
public CollectionNode(Tag tag, Mark startMark, Mark endMark, Boolean flowStyle) {
|
||||
super(tag, startMark, endMark);
|
||||
this.flowStyle = flowStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialization style of this collection.
|
||||
*
|
||||
* @return <code>true</code> for flow style, <code>false</code> for block
|
||||
* style.
|
||||
*/
|
||||
public Boolean getFlowStyle() {
|
||||
return flowStyle;
|
||||
}
|
||||
|
||||
public void setFlowStyle(Boolean flowStyle) {
|
||||
this.flowStyle = flowStyle;
|
||||
}
|
||||
|
||||
public void setEndMark(Mark endMark) {
|
||||
this.endMark = endMark;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.nodes;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a map.
|
||||
* <p>
|
||||
* A map is a collection of unsorted key-value pairs.
|
||||
* </p>
|
||||
*/
|
||||
public class MappingNode extends CollectionNode {
|
||||
private Class<? extends Object> keyType;
|
||||
private Class<? extends Object> valueType;
|
||||
private List<NodeTuple> value;
|
||||
|
||||
public MappingNode(Tag tag, boolean resolved, List<NodeTuple> value, Mark startMark,
|
||||
Mark endMark, Boolean flowStyle) {
|
||||
super(tag, startMark, endMark, flowStyle);
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value in a Node is required.");
|
||||
}
|
||||
this.value = value;
|
||||
keyType = Object.class;
|
||||
valueType = Object.class;
|
||||
this.resolved = resolved;
|
||||
}
|
||||
|
||||
public MappingNode(Tag tag, List<NodeTuple> value, Boolean flowStyle) {
|
||||
this(tag, true, value, null, null, flowStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeId getNodeId() {
|
||||
return NodeId.mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entries of this map.
|
||||
*
|
||||
* @return List of entries.
|
||||
*/
|
||||
public List<NodeTuple> getValue() {
|
||||
for (NodeTuple nodes : value) {
|
||||
nodes.getKeyNode().setType(keyType);
|
||||
nodes.getValueNode().setType(valueType);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(List<NodeTuple> merge) {
|
||||
value = merge;
|
||||
}
|
||||
|
||||
public void setKeyType(Class<? extends Object> keyType) {
|
||||
this.keyType = keyType;
|
||||
}
|
||||
|
||||
public void setValueType(Class<? extends Object> valueType) {
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String values;
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (NodeTuple node : getValue()) {
|
||||
buf.append("{ key=");
|
||||
buf.append(node.getKeyNode());
|
||||
buf.append("; value=Node<");
|
||||
// to avoid overflow in case of recursive structures
|
||||
buf.append(System.identityHashCode(node.getValueNode()));
|
||||
buf.append("> }");
|
||||
}
|
||||
values = buf.toString();
|
||||
return "<" + this.getClass().getName() + " (tag=" + getTag() + ", values=" + values + ")>";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.nodes;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Base class for all nodes.
|
||||
* <p>
|
||||
* The nodes form the node-graph described in the <a
|
||||
* href="http://yaml.org/spec/1.1/">YAML Specification</a>.
|
||||
* </p>
|
||||
* <p>
|
||||
* While loading, the node graph is usually created by the
|
||||
* {@link org.elasticsearch.util.yaml.snakeyaml.composer.Composer}, and later transformed into
|
||||
* application specific Java classes by the classes from the
|
||||
* {@link org.elasticsearch.util.yaml.snakeyaml.constructor} package.
|
||||
* </p>
|
||||
*/
|
||||
public abstract class Node {
|
||||
private Tag tag;
|
||||
private Mark startMark;
|
||||
protected Mark endMark;
|
||||
private Class<? extends Object> type;
|
||||
private boolean twoStepsConstruction;
|
||||
/**
|
||||
* true when the tag is assigned by the resolver
|
||||
*/
|
||||
protected boolean resolved;
|
||||
protected Boolean useClassConstructor;
|
||||
|
||||
public Node(Tag tag, Mark startMark, Mark endMark) {
|
||||
setTag(tag);
|
||||
this.startMark = startMark;
|
||||
this.endMark = endMark;
|
||||
this.type = Object.class;
|
||||
this.twoStepsConstruction = false;
|
||||
this.resolved = true;
|
||||
this.useClassConstructor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag of this node.
|
||||
* <p>
|
||||
* Every node has a tag assigned. The tag is either local or global.
|
||||
*
|
||||
* @return Tag of this node.
|
||||
*/
|
||||
public Tag getTag() {
|
||||
return this.tag;
|
||||
}
|
||||
|
||||
public Mark getEndMark() {
|
||||
return endMark;
|
||||
}
|
||||
|
||||
/**
|
||||
* For error reporting.
|
||||
*
|
||||
* @return scalar, sequence, mapping
|
||||
* @see class variable 'id' in PyYAML
|
||||
*/
|
||||
public abstract NodeId getNodeId();
|
||||
|
||||
public Mark getStartMark() {
|
||||
return startMark;
|
||||
}
|
||||
|
||||
public void setTag(Tag tag) {
|
||||
if (tag == null) {
|
||||
throw new NullPointerException("tag in a Node is required.");
|
||||
}
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
/*
|
||||
* It is not allowed to overwrite this method. Two Nodes are never equal.
|
||||
*/
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object obj) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
public Class<? extends Object> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Class<? extends Object> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void setTwoStepsConstruction(boolean twoStepsConstruction) {
|
||||
this.twoStepsConstruction = twoStepsConstruction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this node must be constructed in two steps.
|
||||
* <p>
|
||||
* Two-step construction is required whenever a node is a child (direct or
|
||||
* indirect) of it self. That is, if a recursive structure is build using
|
||||
* anchors and aliases.
|
||||
* </p>
|
||||
* <p>
|
||||
* Set by {@link org.elasticsearch.util.yaml.snakeyaml.composer.Composer}, used during the
|
||||
* construction process.
|
||||
* </p>
|
||||
* <p>
|
||||
* Only relevant during loading.
|
||||
* </p>
|
||||
*
|
||||
* @return <code>true</code> if the node is self referenced.
|
||||
*/
|
||||
public boolean isTwoStepsConstruction() {
|
||||
return twoStepsConstruction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
public boolean useClassConstructor() {
|
||||
if (useClassConstructor == null) {
|
||||
if (isResolved() && !Object.class.equals(type) && !tag.equals(Tag.NULL)) {
|
||||
return true;
|
||||
} else if (tag.isCompatible(getType())) {
|
||||
// the tag is compatible with the runtime class
|
||||
// the tag will be ignored
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return useClassConstructor.booleanValue();
|
||||
}
|
||||
|
||||
public void setUseClassConstructor(Boolean useClassConstructor) {
|
||||
this.useClassConstructor = useClassConstructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the tag was added by
|
||||
* {@link org.elasticsearch.util.yaml.snakeyaml.resolver.Resolver}.
|
||||
*
|
||||
* @return <code>true</code> if the tag of this node was resolved</code>
|
||||
*/
|
||||
public boolean isResolved() {
|
||||
return resolved;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.nodes;
|
||||
|
||||
/**
|
||||
* Enum for the three basic YAML types: scalar, sequence and mapping.
|
||||
*/
|
||||
public enum NodeId {
|
||||
scalar, sequence, mapping;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.nodes;
|
||||
|
||||
/**
|
||||
* Stores one key value pair used in a map.
|
||||
*/
|
||||
public class NodeTuple {
|
||||
|
||||
private final Node keyNode;
|
||||
private final Node valueNode;
|
||||
|
||||
public NodeTuple(Node keyNode, Node valueNode) {
|
||||
if (keyNode == null || valueNode == null) {
|
||||
throw new NullPointerException("Nodes must be provided.");
|
||||
}
|
||||
this.keyNode = keyNode;
|
||||
this.valueNode = valueNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key node.
|
||||
*/
|
||||
public Node getKeyNode() {
|
||||
return keyNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value node.
|
||||
*
|
||||
* @return value
|
||||
*/
|
||||
public Node getValueNode() {
|
||||
return valueNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<NodeTuple keyNode=" + keyNode.toString() + "; valueNode=" + valueNode.toString()
|
||||
+ ">";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.nodes;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Represents a scalar node.
|
||||
* <p>
|
||||
* Scalar nodes form the leaves in the node graph.
|
||||
* </p>
|
||||
*/
|
||||
public class ScalarNode extends Node {
|
||||
private Character style;
|
||||
private String value;
|
||||
|
||||
public ScalarNode(Tag tag, String value, Mark startMark, Mark endMark, Character style) {
|
||||
this(tag, true, value, startMark, endMark, style);
|
||||
}
|
||||
|
||||
public ScalarNode(Tag tag, boolean resolved, String value, Mark startMark, Mark endMark,
|
||||
Character style) {
|
||||
super(tag, startMark, endMark);
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value in a Node is required.");
|
||||
}
|
||||
this.value = value;
|
||||
this.style = style;
|
||||
this.resolved = resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get scalar style of this node.
|
||||
*
|
||||
* @return
|
||||
* @see org.elasticsearch.util.yaml.snakeyaml.events.ScalarEvent
|
||||
* @see http://yaml.org/spec/1.1/#id864487
|
||||
*/
|
||||
public Character getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeId getNodeId() {
|
||||
return NodeId.scalar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value of this scalar.
|
||||
*
|
||||
* @return Scalar's value.
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "<" + this.getClass().getName() + " (tag=" + getTag() + ", value=" + getValue()
|
||||
+ ")>";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.nodes;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a sequence.
|
||||
* <p>
|
||||
* A sequence is a ordered collection of nodes.
|
||||
* </p>
|
||||
*/
|
||||
public class SequenceNode extends CollectionNode {
|
||||
private Class<? extends Object> listType;
|
||||
private List<Node> value;
|
||||
|
||||
public SequenceNode(Tag tag, boolean resolved, List<Node> value, Mark startMark, Mark endMark,
|
||||
Boolean flowStyle) {
|
||||
super(tag, startMark, endMark, flowStyle);
|
||||
if (value == null) {
|
||||
throw new NullPointerException("value in a Node is required.");
|
||||
}
|
||||
this.value = value;
|
||||
listType = Object.class;
|
||||
this.resolved = resolved;
|
||||
}
|
||||
|
||||
public SequenceNode(Tag tag, List<Node> value, Boolean flowStyle) {
|
||||
this(tag, true, value, null, null, flowStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeId getNodeId() {
|
||||
return NodeId.sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the elements in this sequence.
|
||||
*
|
||||
* @return Nodes in the specified order.
|
||||
*/
|
||||
public List<Node> getValue() {
|
||||
for (Node node : value) {
|
||||
node.setType(listType);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setListType(Class<? extends Object> listType) {
|
||||
this.listType = listType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "<" + this.getClass().getName() + " (tag=" + getTag() + ", value=" + getValue()
|
||||
+ ")>";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.nodes;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
|
||||
public final class Tag implements Comparable<Tag> {
|
||||
public static final String PREFIX = "tag:yaml.org,2002:";
|
||||
public static final Tag YAML = new Tag(PREFIX + "yaml");
|
||||
public static final Tag VALUE = new Tag(PREFIX + "value");
|
||||
public static final Tag MERGE = new Tag(PREFIX + "merge");
|
||||
public static final Tag SET = new Tag(PREFIX + "set");
|
||||
public static final Tag PAIRS = new Tag(PREFIX + "pairs");
|
||||
public static final Tag OMAP = new Tag(PREFIX + "omap");
|
||||
public static final Tag BINARY = new Tag(PREFIX + "binary");
|
||||
public static final Tag INT = new Tag(PREFIX + "int");
|
||||
public static final Tag FLOAT = new Tag(PREFIX + "float");
|
||||
public static final Tag TIMESTAMP = new Tag(PREFIX + "timestamp");
|
||||
public static final Tag BOOL = new Tag(PREFIX + "bool");
|
||||
public static final Tag NULL = new Tag(PREFIX + "null");
|
||||
public static final Tag STR = new Tag(PREFIX + "str");
|
||||
public static final Tag SEQ = new Tag(PREFIX + "seq");
|
||||
public static final Tag MAP = new Tag(PREFIX + "map");
|
||||
public static final Map<Tag, Set<Class<?>>> COMPATIBILITY_MAP;
|
||||
|
||||
static {
|
||||
COMPATIBILITY_MAP = new HashMap<Tag, Set<Class<?>>>();
|
||||
Set<Class<?>> floatSet = new HashSet<Class<?>>();
|
||||
floatSet.add(Double.class);
|
||||
floatSet.add(Float.class);
|
||||
floatSet.add(BigDecimal.class);
|
||||
COMPATIBILITY_MAP.put(FLOAT, floatSet);
|
||||
//
|
||||
Set<Class<?>> intSet = new HashSet<Class<?>>();
|
||||
intSet.add(Integer.class);
|
||||
intSet.add(Long.class);
|
||||
intSet.add(BigInteger.class);
|
||||
COMPATIBILITY_MAP.put(INT, intSet);
|
||||
//
|
||||
Set<Class<?>> timestampSet = new HashSet<Class<?>>();
|
||||
timestampSet.add(Date.class);
|
||||
timestampSet.add(java.sql.Date.class);
|
||||
timestampSet.add(Timestamp.class);
|
||||
COMPATIBILITY_MAP.put(TIMESTAMP, timestampSet);
|
||||
}
|
||||
|
||||
private final String value;
|
||||
|
||||
public Tag(String tag) {
|
||||
if (tag == null) {
|
||||
throw new NullPointerException("Tag must be provided.");
|
||||
} else if (tag.length() == 0) {
|
||||
throw new IllegalArgumentException("Tag must not be empty.");
|
||||
} else if (tag.trim().length() != tag.length()) {
|
||||
throw new IllegalArgumentException("Tag must not contain leading or trailing spaces.");
|
||||
}
|
||||
this.value = tag;
|
||||
}
|
||||
|
||||
public Tag(Class<? extends Object> clazz) {
|
||||
if (clazz == null) {
|
||||
throw new NullPointerException("Class for tag must be provided.");
|
||||
}
|
||||
this.value = Tag.PREFIX + clazz.getName();
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean startsWith(String prefix) {
|
||||
return value.startsWith(prefix);
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
if (!value.startsWith(Tag.PREFIX)) {
|
||||
throw new YAMLException("Unknown tag: " + value);
|
||||
}
|
||||
return value.substring(Tag.PREFIX.length());
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return value.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof Tag) {
|
||||
return value.equals(((Tag) obj).getValue());
|
||||
} else if (obj instanceof String) {
|
||||
if (value.equals(obj.toString())) {
|
||||
// TODO to be removed later (version 2.0?)
|
||||
System.err.println("Comparing Tag and String is deprecated.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return value.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Java has more then 1 class compatible with a language-independent tag
|
||||
* (!!int, !!float, !!timestamp etc)
|
||||
*
|
||||
* @param clazz - Class to check compatibility
|
||||
* @return true when the Class can be represented by this
|
||||
* language-independent tag
|
||||
*/
|
||||
public boolean isCompatible(Class<?> clazz) {
|
||||
Set<Class<?>> set = COMPATIBILITY_MAP.get(this);
|
||||
if (set != null) {
|
||||
return set.contains(clazz);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this tag matches the global tag for the Class
|
||||
*
|
||||
* @param clazz - Class to check
|
||||
* @return true when the this tag can be used as a global tag for the Class
|
||||
*/
|
||||
public boolean matches(Class<? extends Object> clazz) {
|
||||
return value.equals(Tag.PREFIX + clazz.getName());
|
||||
}
|
||||
|
||||
public int compareTo(Tag o) {
|
||||
return value.compareTo(o.getValue());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.parser;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.events.Event;
|
||||
|
||||
/**
|
||||
* This interface represents an input stream of {@link Event Events}.
|
||||
* <p>
|
||||
* The parser and the scanner form together the 'Parse' step in the loading
|
||||
* process (see chapter 3.1 of the <a href="http://yaml.org/spec/1.1/">YAML
|
||||
* Specification</a>).
|
||||
* </p>
|
||||
*
|
||||
* @see org.elasticsearch.util.yaml.snakeyaml.events.Event
|
||||
*/
|
||||
public interface Parser {
|
||||
|
||||
/**
|
||||
* Check if the next event is one of the given type.
|
||||
*
|
||||
* @param choice Event ID.
|
||||
* @return <code>true</code> if the next event can be assigned to a variable
|
||||
* of the given type. Returns <code>false</code> if no more events
|
||||
* are available.
|
||||
* @throws ParserException Thrown in case of malformed input.
|
||||
*/
|
||||
public boolean checkEvent(Event.ID choice);
|
||||
|
||||
/**
|
||||
* Return the next event, but do not delete it from the stream.
|
||||
*
|
||||
* @return The event that will be returned on the next call to
|
||||
* {@link #getEvent}
|
||||
* @throws ParserException Thrown in case of malformed input.
|
||||
*/
|
||||
public Event peekEvent();
|
||||
|
||||
/**
|
||||
* Returns the next event.
|
||||
* <p>
|
||||
* The event will be removed from the stream.
|
||||
* </p>
|
||||
*
|
||||
* @throws ParserException Thrown in case of malformed input.
|
||||
*/
|
||||
public Event getEvent();
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.parser;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.MarkedYAMLException;
|
||||
|
||||
/**
|
||||
* Exception thrown by the {@link Parser} implementations in case of malformed
|
||||
* input.
|
||||
*/
|
||||
public class ParserException extends MarkedYAMLException {
|
||||
private static final long serialVersionUID = -2349253802798398038L;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param context Part of the input document in which vicinity the problem
|
||||
* occurred.
|
||||
* @param contextMark Position of the <code>context</code> within the document.
|
||||
* @param problem Part of the input document that caused the problem.
|
||||
* @param problemMark Position of the <code>problem</code>. within the document.
|
||||
*/
|
||||
public ParserException(String context, Mark contextMark, String problem, Mark problemMark) {
|
||||
super(context, contextMark, problem, problemMark, null, null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,786 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.parser;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.events.*;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.Tag;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.reader.StreamReader;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.scanner.Scanner;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.scanner.ScannerImpl;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.tokens.*;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.util.ArrayStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* # The following YAML grammar is LL(1) and is parsed by a recursive descent
|
||||
* parser.
|
||||
* stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
|
||||
* implicit_document ::= block_node DOCUMENT-END*
|
||||
* explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
|
||||
* block_node_or_indentless_sequence ::=
|
||||
* ALIAS
|
||||
* | properties (block_content | indentless_block_sequence)?
|
||||
* | block_content
|
||||
* | indentless_block_sequence
|
||||
* block_node ::= ALIAS
|
||||
* | properties block_content?
|
||||
* | block_content
|
||||
* flow_node ::= ALIAS
|
||||
* | properties flow_content?
|
||||
* | flow_content
|
||||
* properties ::= TAG ANCHOR? | ANCHOR TAG?
|
||||
* block_content ::= block_collection | flow_collection | SCALAR
|
||||
* flow_content ::= flow_collection | SCALAR
|
||||
* block_collection ::= block_sequence | block_mapping
|
||||
* flow_collection ::= flow_sequence | flow_mapping
|
||||
* block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
|
||||
* indentless_sequence ::= (BLOCK-ENTRY block_node?)+
|
||||
* block_mapping ::= BLOCK-MAPPING_START
|
||||
* ((KEY block_node_or_indentless_sequence?)?
|
||||
* (VALUE block_node_or_indentless_sequence?)?)*
|
||||
* BLOCK-END
|
||||
* flow_sequence ::= FLOW-SEQUENCE-START
|
||||
* (flow_sequence_entry FLOW-ENTRY)*
|
||||
* flow_sequence_entry?
|
||||
* FLOW-SEQUENCE-END
|
||||
* flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
|
||||
* flow_mapping ::= FLOW-MAPPING-START
|
||||
* (flow_mapping_entry FLOW-ENTRY)*
|
||||
* flow_mapping_entry?
|
||||
* FLOW-MAPPING-END
|
||||
* flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
|
||||
* FIRST sets:
|
||||
* stream: { STREAM-START }
|
||||
* explicit_document: { DIRECTIVE DOCUMENT-START }
|
||||
* implicit_document: FIRST(block_node)
|
||||
* block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START }
|
||||
* flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START }
|
||||
* block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
|
||||
* flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
|
||||
* block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START }
|
||||
* flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
|
||||
* block_sequence: { BLOCK-SEQUENCE-START }
|
||||
* block_mapping: { BLOCK-MAPPING-START }
|
||||
* block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START BLOCK-ENTRY }
|
||||
* indentless_sequence: { ENTRY }
|
||||
* flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
|
||||
* flow_sequence: { FLOW-SEQUENCE-START }
|
||||
* flow_mapping: { FLOW-MAPPING-START }
|
||||
* flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY }
|
||||
* flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY }
|
||||
* </pre>
|
||||
*
|
||||
* Since writing a recursive-descendant parser is a straightforward task, we do
|
||||
* not give many comments here.
|
||||
*
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class ParserImpl implements Parser {
|
||||
private static final Map<String, String> DEFAULT_TAGS = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
DEFAULT_TAGS.put("!", "!");
|
||||
DEFAULT_TAGS.put("!!", Tag.PREFIX);
|
||||
}
|
||||
|
||||
private final Scanner scanner;
|
||||
private Event currentEvent;
|
||||
private List<Integer> yamlVersion;
|
||||
private Map<String, String> tagHandles;
|
||||
private final ArrayStack<Production> states;
|
||||
private final ArrayStack<Mark> marks;
|
||||
private Production state;
|
||||
|
||||
public ParserImpl(StreamReader reader) {
|
||||
this.scanner = new ScannerImpl(reader);
|
||||
currentEvent = null;
|
||||
yamlVersion = null;
|
||||
tagHandles = new HashMap<String, String>();
|
||||
states = new ArrayStack<Production>(100);
|
||||
marks = new ArrayStack<Mark>(10);
|
||||
state = new ParseStreamStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the type of the next event.
|
||||
*/
|
||||
public boolean checkEvent(Event.ID choices) {
|
||||
peekEvent();
|
||||
if (currentEvent != null) {
|
||||
if (currentEvent.is(choices)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next event.
|
||||
*/
|
||||
|
||||
public Event peekEvent() {
|
||||
if (currentEvent == null) {
|
||||
if (state != null) {
|
||||
currentEvent = state.produce();
|
||||
}
|
||||
}
|
||||
return currentEvent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next event and proceed further.
|
||||
*/
|
||||
|
||||
public Event getEvent() {
|
||||
peekEvent();
|
||||
Event value = currentEvent;
|
||||
currentEvent = null;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
|
||||
* implicit_document ::= block_node DOCUMENT-END*
|
||||
* explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
|
||||
* </pre>
|
||||
*/
|
||||
private class ParseStreamStart implements Production {
|
||||
public Event produce() {
|
||||
// Parse the stream start.
|
||||
StreamStartToken token = (StreamStartToken) scanner.getToken();
|
||||
Event event = new StreamStartEvent(token.getStartMark(), token.getEndMark());
|
||||
// Prepare the next state.
|
||||
state = new ParseImplicitDocumentStart();
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseImplicitDocumentStart implements Production {
|
||||
public Event produce() {
|
||||
// Parse an implicit document.
|
||||
if (!scanner.checkToken(Token.ID.Directive, Token.ID.DocumentStart, Token.ID.StreamEnd)) {
|
||||
tagHandles = DEFAULT_TAGS;
|
||||
Token token = scanner.peekToken();
|
||||
Mark startMark = token.getStartMark();
|
||||
Mark endMark = startMark;
|
||||
Event event = new DocumentStartEvent(startMark, endMark, false, null, null);
|
||||
// Prepare the next state.
|
||||
states.push(new ParseDocumentEnd());
|
||||
state = new ParseBlockNode();
|
||||
return event;
|
||||
} else {
|
||||
Production p = new ParseDocumentStart();
|
||||
return p.produce();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseDocumentStart implements Production {
|
||||
@SuppressWarnings("unchecked")
|
||||
public Event produce() {
|
||||
// Parse any extra document end indicators.
|
||||
while (scanner.checkToken(Token.ID.DocumentEnd)) {
|
||||
scanner.getToken();
|
||||
}
|
||||
// Parse an explicit document.
|
||||
Event event;
|
||||
if (!scanner.checkToken(Token.ID.StreamEnd)) {
|
||||
Token token = scanner.peekToken();
|
||||
Mark startMark = token.getStartMark();
|
||||
List<Object> version_tags = processDirectives();
|
||||
List<Object> version = (List<Object>) version_tags.get(0);
|
||||
Map<String, String> tags = (Map<String, String>) version_tags.get(1);
|
||||
if (!scanner.checkToken(Token.ID.DocumentStart)) {
|
||||
throw new ParserException(null, null, "expected '<document start>', but found "
|
||||
+ scanner.peekToken().getTokenId(), scanner.peekToken().getStartMark());
|
||||
}
|
||||
token = scanner.getToken();
|
||||
Mark endMark = token.getEndMark();
|
||||
Integer[] versionInteger;
|
||||
if (version != null) {
|
||||
versionInteger = new Integer[2];
|
||||
versionInteger = version.toArray(versionInteger);
|
||||
} else {
|
||||
versionInteger = null;
|
||||
}
|
||||
event = new DocumentStartEvent(startMark, endMark, true, versionInteger, tags);
|
||||
states.push(new ParseDocumentEnd());
|
||||
state = new ParseDocumentContent();
|
||||
} else {
|
||||
// Parse the end of the stream.
|
||||
StreamEndToken token = (StreamEndToken) scanner.getToken();
|
||||
event = new StreamEndEvent(token.getStartMark(), token.getEndMark());
|
||||
if (!states.isEmpty()) {
|
||||
throw new YAMLException("Unexpected end of stream. States left: " + states);
|
||||
}
|
||||
if (!marks.isEmpty()) {
|
||||
throw new YAMLException("Unexpected end of stream. Marks left: " + marks);
|
||||
}
|
||||
state = null;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseDocumentEnd implements Production {
|
||||
public Event produce() {
|
||||
// Parse the document end.
|
||||
Token token = scanner.peekToken();
|
||||
Mark startMark = token.getStartMark();
|
||||
Mark endMark = startMark;
|
||||
boolean explicit = false;
|
||||
if (scanner.checkToken(Token.ID.DocumentEnd)) {
|
||||
token = scanner.getToken();
|
||||
endMark = token.getEndMark();
|
||||
explicit = true;
|
||||
}
|
||||
Event event = new DocumentEndEvent(startMark, endMark, explicit);
|
||||
// Prepare the next state.
|
||||
state = new ParseDocumentStart();
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseDocumentContent implements Production {
|
||||
public Event produce() {
|
||||
Event event;
|
||||
if (scanner.checkToken(Token.ID.Directive, Token.ID.DocumentStart,
|
||||
Token.ID.DocumentEnd, Token.ID.StreamEnd)) {
|
||||
event = processEmptyScalar(scanner.peekToken().getStartMark());
|
||||
state = states.pop();
|
||||
return event;
|
||||
} else {
|
||||
Production p = new ParseBlockNode();
|
||||
return p.produce();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Object> processDirectives() {
|
||||
yamlVersion = null;
|
||||
tagHandles = new HashMap<String, String>();
|
||||
while (scanner.checkToken(Token.ID.Directive)) {
|
||||
DirectiveToken token = (DirectiveToken) scanner.getToken();
|
||||
if (token.getName().equals("YAML")) {
|
||||
if (yamlVersion != null) {
|
||||
throw new ParserException(null, null, "found duplicate YAML directive", token
|
||||
.getStartMark());
|
||||
}
|
||||
List<Integer> value = (List<Integer>) token.getValue();
|
||||
Integer major = value.get(0);
|
||||
if (major != 1) {
|
||||
throw new ParserException(null, null,
|
||||
"found incompatible YAML document (version 1.* is required)", token
|
||||
.getStartMark());
|
||||
}
|
||||
yamlVersion = (List<Integer>) token.getValue();
|
||||
} else if (token.getName().equals("TAG")) {
|
||||
List<String> value = (List<String>) token.getValue();
|
||||
String handle = value.get(0);
|
||||
String prefix = value.get(1);
|
||||
if (tagHandles.containsKey(handle)) {
|
||||
throw new ParserException(null, null, "duplicate tag handle " + handle, token
|
||||
.getStartMark());
|
||||
}
|
||||
tagHandles.put(handle, prefix);
|
||||
}
|
||||
}
|
||||
List<Object> value = new ArrayList<Object>(2);
|
||||
value.add(yamlVersion);
|
||||
if (!tagHandles.isEmpty()) {
|
||||
value.add(new HashMap<String, String>(tagHandles));
|
||||
} else {
|
||||
value.add(new HashMap<String, String>());
|
||||
}
|
||||
for (String key : DEFAULT_TAGS.keySet()) {
|
||||
if (!tagHandles.containsKey(key)) {
|
||||
tagHandles.put(key, DEFAULT_TAGS.get(key));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* block_node_or_indentless_sequence ::= ALIAS
|
||||
* | properties (block_content | indentless_block_sequence)?
|
||||
* | block_content
|
||||
* | indentless_block_sequence
|
||||
* block_node ::= ALIAS
|
||||
* | properties block_content?
|
||||
* | block_content
|
||||
* flow_node ::= ALIAS
|
||||
* | properties flow_content?
|
||||
* | flow_content
|
||||
* properties ::= TAG ANCHOR? | ANCHOR TAG?
|
||||
* block_content ::= block_collection | flow_collection | SCALAR
|
||||
* flow_content ::= flow_collection | SCALAR
|
||||
* block_collection ::= block_sequence | block_mapping
|
||||
* flow_collection ::= flow_sequence | flow_mapping
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
private class ParseBlockNode implements Production {
|
||||
public Event produce() {
|
||||
return parseNode(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
private Event parseFlowNode() {
|
||||
return parseNode(false, false);
|
||||
}
|
||||
|
||||
private Event parseBlockNodeOrIndentlessSequence() {
|
||||
return parseNode(true, true);
|
||||
}
|
||||
|
||||
private Event parseNode(boolean block, boolean indentlessSequence) {
|
||||
Event event;
|
||||
Mark startMark = null;
|
||||
Mark endMark = null;
|
||||
Mark tagMark = null;
|
||||
if (scanner.checkToken(Token.ID.Alias)) {
|
||||
AliasToken token = (AliasToken) scanner.getToken();
|
||||
event = new AliasEvent(token.getValue(), token.getStartMark(), token.getEndMark());
|
||||
state = states.pop();
|
||||
} else {
|
||||
String anchor = null;
|
||||
TagTuple tagTokenTag = null;
|
||||
if (scanner.checkToken(Token.ID.Anchor)) {
|
||||
AnchorToken token = (AnchorToken) scanner.getToken();
|
||||
startMark = token.getStartMark();
|
||||
endMark = token.getEndMark();
|
||||
anchor = token.getValue();
|
||||
if (scanner.checkToken(Token.ID.Tag)) {
|
||||
TagToken tagToken = (TagToken) scanner.getToken();
|
||||
tagMark = tagToken.getStartMark();
|
||||
endMark = tagToken.getEndMark();
|
||||
tagTokenTag = tagToken.getValue();
|
||||
}
|
||||
} else if (scanner.checkToken(Token.ID.Tag)) {
|
||||
TagToken tagToken = (TagToken) scanner.getToken();
|
||||
startMark = tagToken.getStartMark();
|
||||
tagMark = startMark;
|
||||
endMark = tagToken.getEndMark();
|
||||
tagTokenTag = tagToken.getValue();
|
||||
if (scanner.checkToken(Token.ID.Anchor)) {
|
||||
AnchorToken token = (AnchorToken) scanner.getToken();
|
||||
endMark = token.getEndMark();
|
||||
anchor = token.getValue();
|
||||
}
|
||||
}
|
||||
String tag = null;
|
||||
if (tagTokenTag != null) {
|
||||
String handle = tagTokenTag.getHandle();
|
||||
String suffix = tagTokenTag.getSuffix();
|
||||
if (handle != null) {
|
||||
if (!tagHandles.containsKey(handle)) {
|
||||
throw new ParserException("while parsing a node", startMark,
|
||||
"found undefined tag handle " + handle, tagMark);
|
||||
}
|
||||
tag = tagHandles.get(handle) + suffix;
|
||||
} else {
|
||||
tag = suffix;
|
||||
}
|
||||
}
|
||||
if (startMark == null) {
|
||||
startMark = scanner.peekToken().getStartMark();
|
||||
endMark = startMark;
|
||||
}
|
||||
event = null;
|
||||
boolean implicit = (tag == null || tag.equals("!"));
|
||||
if (indentlessSequence && scanner.checkToken(Token.ID.BlockEntry)) {
|
||||
endMark = scanner.peekToken().getEndMark();
|
||||
event = new SequenceStartEvent(anchor, tag, implicit, startMark, endMark,
|
||||
Boolean.FALSE);
|
||||
state = new ParseIndentlessSequenceEntry();
|
||||
} else {
|
||||
if (scanner.checkToken(Token.ID.Scalar)) {
|
||||
ScalarToken token = (ScalarToken) scanner.getToken();
|
||||
endMark = token.getEndMark();
|
||||
ImplicitTuple implicitValues;
|
||||
if ((token.getPlain() && tag == null) || "!".equals(tag)) {
|
||||
implicitValues = new ImplicitTuple(true, false);
|
||||
} else if (tag == null) {
|
||||
implicitValues = new ImplicitTuple(false, true);
|
||||
} else {
|
||||
implicitValues = new ImplicitTuple(false, false);
|
||||
}
|
||||
event = new ScalarEvent(anchor, tag, implicitValues, token.getValue(),
|
||||
startMark, endMark, token.getStyle());
|
||||
state = states.pop();
|
||||
} else if (scanner.checkToken(Token.ID.FlowSequenceStart)) {
|
||||
endMark = scanner.peekToken().getEndMark();
|
||||
event = new SequenceStartEvent(anchor, tag, implicit, startMark, endMark,
|
||||
Boolean.TRUE);
|
||||
state = new ParseFlowSequenceFirstEntry();
|
||||
} else if (scanner.checkToken(Token.ID.FlowMappingStart)) {
|
||||
endMark = scanner.peekToken().getEndMark();
|
||||
event = new MappingStartEvent(anchor, tag, implicit, startMark, endMark,
|
||||
Boolean.TRUE);
|
||||
state = new ParseFlowMappingFirstKey();
|
||||
} else if (block && scanner.checkToken(Token.ID.BlockSequenceStart)) {
|
||||
endMark = scanner.peekToken().getStartMark();
|
||||
event = new SequenceStartEvent(anchor, tag, implicit, startMark, endMark,
|
||||
Boolean.FALSE);
|
||||
state = new ParseBlockSequenceFirstEntry();
|
||||
} else if (block && scanner.checkToken(Token.ID.BlockMappingStart)) {
|
||||
endMark = scanner.peekToken().getStartMark();
|
||||
event = new MappingStartEvent(anchor, tag, implicit, startMark, endMark,
|
||||
Boolean.FALSE);
|
||||
state = new ParseBlockMappingFirstKey();
|
||||
} else if (anchor != null || tag != null) {
|
||||
// Empty scalars are allowed even if a tag or an anchor is
|
||||
// specified.
|
||||
event = new ScalarEvent(anchor, tag, new ImplicitTuple(implicit, false), "",
|
||||
startMark, endMark, (char) 0);
|
||||
state = states.pop();
|
||||
} else {
|
||||
String node;
|
||||
if (block) {
|
||||
node = "block";
|
||||
} else {
|
||||
node = "flow";
|
||||
}
|
||||
Token token = scanner.peekToken();
|
||||
throw new ParserException("while parsing a " + node + " node", startMark,
|
||||
"expected the node content, but found " + token.getTokenId(), token
|
||||
.getStartMark());
|
||||
}
|
||||
}
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)*
|
||||
// BLOCK-END
|
||||
|
||||
private class ParseBlockSequenceFirstEntry implements Production {
|
||||
public Event produce() {
|
||||
Token token = scanner.getToken();
|
||||
marks.push(token.getStartMark());
|
||||
return new ParseBlockSequenceEntry().produce();
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseBlockSequenceEntry implements Production {
|
||||
public Event produce() {
|
||||
if (scanner.checkToken(Token.ID.BlockEntry)) {
|
||||
BlockEntryToken token = (BlockEntryToken) scanner.getToken();
|
||||
if (!scanner.checkToken(Token.ID.BlockEntry, Token.ID.BlockEnd)) {
|
||||
states.push(new ParseBlockSequenceEntry());
|
||||
return new ParseBlockNode().produce();
|
||||
} else {
|
||||
state = new ParseBlockSequenceEntry();
|
||||
return processEmptyScalar(token.getEndMark());
|
||||
}
|
||||
}
|
||||
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(), token
|
||||
.getStartMark());
|
||||
}
|
||||
Token token = scanner.getToken();
|
||||
Event event = new SequenceEndEvent(token.getStartMark(), token.getEndMark());
|
||||
state = states.pop();
|
||||
marks.pop();
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
|
||||
|
||||
private class ParseIndentlessSequenceEntry implements Production {
|
||||
public Event produce() {
|
||||
if (scanner.checkToken(Token.ID.BlockEntry)) {
|
||||
Token token = scanner.getToken();
|
||||
if (!scanner.checkToken(Token.ID.BlockEntry, Token.ID.Key, Token.ID.Value,
|
||||
Token.ID.BlockEnd)) {
|
||||
states.push(new ParseIndentlessSequenceEntry());
|
||||
return new ParseBlockNode().produce();
|
||||
} else {
|
||||
state = new ParseIndentlessSequenceEntry();
|
||||
return processEmptyScalar(token.getEndMark());
|
||||
}
|
||||
}
|
||||
Token token = scanner.peekToken();
|
||||
Event event = new SequenceEndEvent(token.getStartMark(), token.getEndMark());
|
||||
state = states.pop();
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseBlockMappingFirstKey implements Production {
|
||||
public Event produce() {
|
||||
Token token = scanner.getToken();
|
||||
marks.push(token.getStartMark());
|
||||
return new ParseBlockMappingKey().produce();
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseBlockMappingKey implements Production {
|
||||
public Event produce() {
|
||||
if (scanner.checkToken(Token.ID.Key)) {
|
||||
Token token = scanner.getToken();
|
||||
if (!scanner.checkToken(Token.ID.Key, Token.ID.Value, Token.ID.BlockEnd)) {
|
||||
states.push(new ParseBlockMappingValue());
|
||||
return parseBlockNodeOrIndentlessSequence();
|
||||
} else {
|
||||
state = new ParseBlockMappingValue();
|
||||
return processEmptyScalar(token.getEndMark());
|
||||
}
|
||||
}
|
||||
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(), token
|
||||
.getStartMark());
|
||||
}
|
||||
Token token = scanner.getToken();
|
||||
Event event = new MappingEndEvent(token.getStartMark(), token.getEndMark());
|
||||
state = states.pop();
|
||||
marks.pop();
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseBlockMappingValue implements Production {
|
||||
public Event produce() {
|
||||
if (scanner.checkToken(Token.ID.Value)) {
|
||||
Token token = scanner.getToken();
|
||||
if (!scanner.checkToken(Token.ID.Key, Token.ID.Value, Token.ID.BlockEnd)) {
|
||||
states.push(new ParseBlockMappingKey());
|
||||
return parseBlockNodeOrIndentlessSequence();
|
||||
} else {
|
||||
state = new ParseBlockMappingKey();
|
||||
return processEmptyScalar(token.getEndMark());
|
||||
}
|
||||
}
|
||||
state = new ParseBlockMappingKey();
|
||||
Token token = scanner.peekToken();
|
||||
return processEmptyScalar(token.getStartMark());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* flow_sequence ::= FLOW-SEQUENCE-START
|
||||
* (flow_sequence_entry FLOW-ENTRY)*
|
||||
* flow_sequence_entry?
|
||||
* FLOW-SEQUENCE-END
|
||||
* flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
|
||||
* Note that while production rules for both flow_sequence_entry and
|
||||
* flow_mapping_entry are equal, their interpretations are different.
|
||||
* For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?`
|
||||
* generate an inline mapping (set syntax).
|
||||
* </pre>
|
||||
*/
|
||||
private class ParseFlowSequenceFirstEntry implements Production {
|
||||
public Event produce() {
|
||||
Token token = scanner.getToken();
|
||||
marks.push(token.getStartMark());
|
||||
return new ParseFlowSequenceEntry(true).produce();
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseFlowSequenceEntry implements Production {
|
||||
private boolean first = false;
|
||||
|
||||
public ParseFlowSequenceEntry(boolean first) {
|
||||
this.first = first;
|
||||
}
|
||||
|
||||
public Event produce() {
|
||||
if (!scanner.checkToken(Token.ID.FlowSequenceEnd)) {
|
||||
if (!first) {
|
||||
if (scanner.checkToken(Token.ID.FlowEntry)) {
|
||||
scanner.getToken();
|
||||
} else {
|
||||
Token token = scanner.peekToken();
|
||||
throw new ParserException("while parsing a flow sequence", marks.pop(),
|
||||
"expected ',' or ']', but got " + token.getTokenId(), token
|
||||
.getStartMark());
|
||||
}
|
||||
}
|
||||
if (scanner.checkToken(Token.ID.Key)) {
|
||||
Token token = scanner.peekToken();
|
||||
Event event = new MappingStartEvent(null, null, true, token.getStartMark(),
|
||||
token.getEndMark(), Boolean.TRUE);
|
||||
state = new ParseFlowSequenceEntryMappingKey();
|
||||
return event;
|
||||
} else if (!scanner.checkToken(Token.ID.FlowSequenceEnd)) {
|
||||
states.push(new ParseFlowSequenceEntry(false));
|
||||
return parseFlowNode();
|
||||
}
|
||||
}
|
||||
Token token = scanner.getToken();
|
||||
Event event = new SequenceEndEvent(token.getStartMark(), token.getEndMark());
|
||||
state = states.pop();
|
||||
marks.pop();
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseFlowSequenceEntryMappingKey implements Production {
|
||||
public Event produce() {
|
||||
Token token = scanner.getToken();
|
||||
if (!scanner.checkToken(Token.ID.Value, Token.ID.FlowEntry, Token.ID.FlowSequenceEnd)) {
|
||||
states.push(new ParseFlowSequenceEntryMappingValue());
|
||||
return parseFlowNode();
|
||||
} else {
|
||||
state = new ParseFlowSequenceEntryMappingValue();
|
||||
return processEmptyScalar(token.getEndMark());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseFlowSequenceEntryMappingValue implements Production {
|
||||
public Event produce() {
|
||||
if (scanner.checkToken(Token.ID.Value)) {
|
||||
Token token = scanner.getToken();
|
||||
if (!scanner.checkToken(Token.ID.FlowEntry, Token.ID.FlowSequenceEnd)) {
|
||||
states.push(new ParseFlowSequenceEntryMappingEnd());
|
||||
return parseFlowNode();
|
||||
} else {
|
||||
state = new ParseFlowSequenceEntryMappingEnd();
|
||||
return processEmptyScalar(token.getEndMark());
|
||||
}
|
||||
} else {
|
||||
state = new ParseFlowSequenceEntryMappingEnd();
|
||||
Token token = scanner.peekToken();
|
||||
return processEmptyScalar(token.getStartMark());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseFlowSequenceEntryMappingEnd implements Production {
|
||||
public Event produce() {
|
||||
state = new ParseFlowSequenceEntry(false);
|
||||
Token token = scanner.peekToken();
|
||||
return new MappingEndEvent(token.getStartMark(), token.getEndMark());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* flow_mapping ::= FLOW-MAPPING-START
|
||||
* (flow_mapping_entry FLOW-ENTRY)*
|
||||
* flow_mapping_entry?
|
||||
* FLOW-MAPPING-END
|
||||
* flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
|
||||
* </pre>
|
||||
*/
|
||||
private class ParseFlowMappingFirstKey implements Production {
|
||||
public Event produce() {
|
||||
Token token = scanner.getToken();
|
||||
marks.push(token.getStartMark());
|
||||
return new ParseFlowMappingKey(true).produce();
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseFlowMappingKey implements Production {
|
||||
private boolean first = false;
|
||||
|
||||
public ParseFlowMappingKey(boolean first) {
|
||||
this.first = first;
|
||||
}
|
||||
|
||||
public Event produce() {
|
||||
if (!scanner.checkToken(Token.ID.FlowMappingEnd)) {
|
||||
if (!first) {
|
||||
if (scanner.checkToken(Token.ID.FlowEntry)) {
|
||||
scanner.getToken();
|
||||
} else {
|
||||
Token token = scanner.peekToken();
|
||||
throw new ParserException("while parsing a flow mapping", marks.pop(),
|
||||
"expected ',' or '}', but got " + token.getTokenId(), token
|
||||
.getStartMark());
|
||||
}
|
||||
}
|
||||
if (scanner.checkToken(Token.ID.Key)) {
|
||||
Token token = scanner.getToken();
|
||||
if (!scanner.checkToken(Token.ID.Value, Token.ID.FlowEntry,
|
||||
Token.ID.FlowMappingEnd)) {
|
||||
states.push(new ParseFlowMappingValue());
|
||||
return parseFlowNode();
|
||||
} else {
|
||||
state = new ParseFlowMappingValue();
|
||||
return processEmptyScalar(token.getEndMark());
|
||||
}
|
||||
} else if (!scanner.checkToken(Token.ID.FlowMappingEnd)) {
|
||||
states.push(new ParseFlowMappingEmptyValue());
|
||||
return parseFlowNode();
|
||||
}
|
||||
}
|
||||
Token token = scanner.getToken();
|
||||
Event event = new MappingEndEvent(token.getStartMark(), token.getEndMark());
|
||||
state = states.pop();
|
||||
marks.pop();
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseFlowMappingValue implements Production {
|
||||
public Event produce() {
|
||||
if (scanner.checkToken(Token.ID.Value)) {
|
||||
Token token = scanner.getToken();
|
||||
if (!scanner.checkToken(Token.ID.FlowEntry, Token.ID.FlowMappingEnd)) {
|
||||
states.push(new ParseFlowMappingKey(false));
|
||||
return parseFlowNode();
|
||||
} else {
|
||||
state = new ParseFlowMappingKey(false);
|
||||
return processEmptyScalar(token.getEndMark());
|
||||
}
|
||||
} else {
|
||||
state = new ParseFlowMappingKey(false);
|
||||
Token token = scanner.peekToken();
|
||||
return processEmptyScalar(token.getStartMark());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ParseFlowMappingEmptyValue implements Production {
|
||||
public Event produce() {
|
||||
state = new ParseFlowMappingKey(false);
|
||||
return processEmptyScalar(scanner.peekToken().getStartMark());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* block_mapping ::= BLOCK-MAPPING_START
|
||||
* ((KEY block_node_or_indentless_sequence?)?
|
||||
* (VALUE block_node_or_indentless_sequence?)?)*
|
||||
* BLOCK-END
|
||||
* </pre>
|
||||
*/
|
||||
private Event processEmptyScalar(Mark mark) {
|
||||
return new ScalarEvent(null, null, new ImplicitTuple(true, false), "", mark, mark, (char) 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.parser;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.events.Event;
|
||||
|
||||
/**
|
||||
* Helper for {@link ParserImpl}. A grammar rule to apply given the symbols on
|
||||
* top of its stack and the next input token
|
||||
*
|
||||
* @see http://en.wikipedia.org/wiki/LL_parser
|
||||
*/
|
||||
interface Production {
|
||||
public Event produce();
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.reader;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
public class ReaderException extends YAMLException {
|
||||
private static final long serialVersionUID = 8710781187529689083L;
|
||||
private String name;
|
||||
private char character;
|
||||
private int position;
|
||||
|
||||
public ReaderException(String name, int position, char character, String message) {
|
||||
super(message);
|
||||
this.name = name;
|
||||
this.character = character;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "unacceptable character #" + Integer.toHexString((int) character).toUpperCase()
|
||||
+ " " + getMessage() + "\nin \"" + name + "\", position " + position;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.reader;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.scanner.Constant;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Reader: checks if characters are in allowed range, adds '\0' to the end.
|
||||
*
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public class StreamReader {
|
||||
// NON_PRINTABLE changed from PyYAML: \uFFFD excluded because Java returns
|
||||
// it in case of data corruption
|
||||
final static Pattern NON_PRINTABLE = Pattern
|
||||
.compile("[^\t\n\r\u0020-\u007E\u0085\u00A0-\uD7FF\uE000-\uFFFC]");
|
||||
private String name;
|
||||
private final Reader stream;
|
||||
private int pointer = 0;
|
||||
private boolean eof = true;
|
||||
private final StringBuilder buffer;
|
||||
private int index = 0;
|
||||
private int line = 0;
|
||||
private int column = 0;
|
||||
|
||||
public StreamReader(String stream) {
|
||||
this.name = "<string>";
|
||||
this.buffer = new StringBuilder();
|
||||
checkPrintable(stream);
|
||||
this.buffer.append(stream);
|
||||
this.stream = null;
|
||||
this.eof = true;
|
||||
}
|
||||
|
||||
public StreamReader(Reader reader) {
|
||||
this.name = "<reader>";
|
||||
this.buffer = new StringBuilder();
|
||||
this.stream = reader;
|
||||
this.eof = false;
|
||||
}
|
||||
|
||||
void checkPrintable(CharSequence data) {
|
||||
Matcher em = NON_PRINTABLE.matcher(data);
|
||||
if (em.find()) {
|
||||
int position = this.index + this.buffer.length() - this.pointer + em.start();
|
||||
throw new ReaderException(name, position, em.group().charAt(0),
|
||||
" special characters are not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
public Mark getMark() {
|
||||
return new Mark(name, this.index, this.line, this.column, this.buffer.toString(),
|
||||
this.pointer);
|
||||
}
|
||||
|
||||
public void forward() {
|
||||
forward(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* read the next length characters and move the pointer.
|
||||
*
|
||||
* @param length
|
||||
*/
|
||||
public void forward(int length) {
|
||||
if (this.pointer + length + 1 >= this.buffer.length()) {
|
||||
update(length + 1);
|
||||
}
|
||||
char ch = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
ch = this.buffer.charAt(this.pointer);
|
||||
this.pointer++;
|
||||
this.index++;
|
||||
if (Constant.LINEBR.has(ch) || (ch == '\r' && buffer.charAt(pointer) != '\n')) {
|
||||
this.line++;
|
||||
this.column = 0;
|
||||
} else if (ch != '\uFEFF') {
|
||||
this.column++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public char peek() {
|
||||
return peek(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Peek the next index-th character
|
||||
*
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public char peek(int index) {
|
||||
if (this.pointer + index + 1 > this.buffer.length()) {
|
||||
update(index + 1);
|
||||
}
|
||||
return this.buffer.charAt(this.pointer + index);
|
||||
}
|
||||
|
||||
/**
|
||||
* peek the next length characters
|
||||
*
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
public String prefix(int length) {
|
||||
if (this.pointer + length >= this.buffer.length()) {
|
||||
update(length);
|
||||
}
|
||||
if (this.pointer + length > this.buffer.length()) {
|
||||
return this.buffer.substring(this.pointer, this.buffer.length());
|
||||
} else {
|
||||
return this.buffer.substring(this.pointer, this.pointer + length);
|
||||
}
|
||||
}
|
||||
|
||||
private void update(int length) {
|
||||
this.buffer.delete(0, this.pointer);
|
||||
this.pointer = 0;
|
||||
while (this.buffer.length() < length) {
|
||||
String rawData = null;
|
||||
if (!this.eof) {
|
||||
char[] data = new char[1024];
|
||||
int converted = -2;
|
||||
try {
|
||||
converted = this.stream.read(data);
|
||||
} catch (IOException ioe) {
|
||||
throw new YAMLException(ioe);
|
||||
}
|
||||
if (converted == -1) {
|
||||
this.eof = true;
|
||||
} else {
|
||||
rawData = new String(data, 0, converted);
|
||||
}
|
||||
}
|
||||
if (rawData != null) {
|
||||
checkPrintable(rawData);
|
||||
this.buffer.append(rawData);
|
||||
}
|
||||
if (this.eof) {
|
||||
this.buffer.append('\0');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getColumn() {
|
||||
return column;
|
||||
}
|
||||
|
||||
public Charset getEncoding() {
|
||||
return Charset.forName(((UnicodeReader) this.stream).getEncoding());
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.reader;
|
||||
|
||||
/**
|
||||
version: 1.1 / 2007-01-25
|
||||
- changed BOM recognition ordering (longer boms first)
|
||||
|
||||
Original pseudocode : Thomas Weidenfeller
|
||||
Implementation tweaked: Aki Nieminen
|
||||
Implementation changed: Andrey Somov
|
||||
* UTF-32 removed because it is not supported by YAML
|
||||
* no default encoding
|
||||
|
||||
http://www.unicode.org/unicode/faq/utf_bom.html
|
||||
BOMs:
|
||||
00 00 FE FF = UTF-32, big-endian
|
||||
FF FE 00 00 = UTF-32, little-endian
|
||||
EF BB BF = UTF-8,
|
||||
FE FF = UTF-16, big-endian
|
||||
FF FE = UTF-16, little-endian
|
||||
|
||||
Win2k Notepad:
|
||||
Unicode format = UTF-16LE
|
||||
***/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Generic unicode textreader, which will use BOM mark to identify the encoding
|
||||
* to be used. If BOM is not found then use a given default or system encoding.
|
||||
*/
|
||||
public class UnicodeReader extends Reader {
|
||||
PushbackInputStream internalIn;
|
||||
InputStreamReader internalIn2 = null;
|
||||
|
||||
private static final int BOM_SIZE = 3;
|
||||
|
||||
/**
|
||||
* @param in InputStream to be read
|
||||
*/
|
||||
public UnicodeReader(InputStream in) {
|
||||
internalIn = new PushbackInputStream(in, BOM_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stream encoding or NULL if stream is uninitialized. Call init() or
|
||||
* read() method to initialize it.
|
||||
*/
|
||||
public String getEncoding() {
|
||||
return internalIn2.getEncoding();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read-ahead four bytes and check for BOM marks. Extra bytes are unread
|
||||
* back to the stream, only BOM bytes are skipped.
|
||||
*/
|
||||
protected void init() throws IOException {
|
||||
if (internalIn2 != null)
|
||||
return;
|
||||
|
||||
String encoding;
|
||||
byte bom[] = new byte[BOM_SIZE];
|
||||
int n, unread;
|
||||
n = internalIn.read(bom, 0, bom.length);
|
||||
|
||||
if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
|
||||
encoding = "UTF-8";
|
||||
unread = n - 3;
|
||||
} else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
|
||||
encoding = "UTF-16BE";
|
||||
unread = n - 2;
|
||||
} else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
|
||||
encoding = "UTF-16LE";
|
||||
unread = n - 2;
|
||||
} else {
|
||||
// Unicode BOM mark not found, unread all bytes
|
||||
encoding = "UTF-8";
|
||||
unread = n;
|
||||
}
|
||||
|
||||
if (unread > 0)
|
||||
internalIn.unread(bom, (n - unread), unread);
|
||||
|
||||
// Use given encoding
|
||||
internalIn2 = new InputStreamReader(internalIn, encoding);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
init();
|
||||
internalIn2.close();
|
||||
}
|
||||
|
||||
public int read(char[] cbuf, int off, int len) throws IOException {
|
||||
init();
|
||||
return internalIn2.read(cbuf, off, len);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* See LICENSE file in distribution for copyright and licensing information.
|
||||
*/
|
||||
package org.yaml.snakeyaml.resolver;
|
||||
//Source for Ragel 6.3
|
||||
|
||||
/**
|
||||
* Generated by Ragel 6.3 (http://www.complang.org/ragel/)
|
||||
* @see http://www.complang.org/ragel/
|
||||
*/
|
||||
public class RagelMachine {
|
||||
%%{
|
||||
machine snakeyaml;
|
||||
action bool_tag { tag = "tag:yaml.org,2002:bool"; }
|
||||
action merge_tag { tag = "tag:yaml.org,2002:merge"; }
|
||||
action null_tag { tag = "tag:yaml.org,2002:null"; }
|
||||
action value_tag { tag = "tag:yaml.org,2002:value"; }
|
||||
action int_tag { tag = "tag:yaml.org,2002:int"; }
|
||||
action float_tag { tag = "tag:yaml.org,2002:float"; }
|
||||
action timestamp_tag { tag = "tag:yaml.org,2002:timestamp"; }
|
||||
|
||||
Bool = ("yes" | "Yes" | "YES" | "no" | "No" | "NO" |
|
||||
"true" | "True" | "TRUE" | "false" | "False" | "FALSE" |
|
||||
"on" | "On" | "ON" | "off" | "Off" | "OFF") %/bool_tag;
|
||||
Merge = "<<" %/merge_tag;
|
||||
Value = "=" %/value_tag;
|
||||
Null = ("~" | "null" | "Null" | "NULL" | " ") %/null_tag;
|
||||
|
||||
sign = "-" | "+";
|
||||
digit2 = digit | "_";
|
||||
binaryInt = "0b" [0-1_]+;
|
||||
octalInt = "0" [0-7_]+;
|
||||
decimalInt = "0" | [1-9]digit2* (":" [0-5]? digit)*;
|
||||
hexaInt = "0x" [0-9a-fA-F_]+;
|
||||
Int = sign? (binaryInt | octalInt | decimalInt | hexaInt) %/int_tag;
|
||||
|
||||
exp = [eE] sign digit+;
|
||||
Float = ((sign? ((digit+ digit2* "." digit2* exp?)
|
||||
| ((digit+ digit2*)? "." digit+ digit2* exp?)
|
||||
| (digit+ (":" [0-5]? digit)+ "." digit*)
|
||||
| "." ("inf" | "Inf" | "INF")))
|
||||
| ("." ("nan" | "NaN" | "NAN"))) %/float_tag;
|
||||
|
||||
TimestampShort = digit{4} ("-" digit{2}){2} %/timestamp_tag;
|
||||
fract = "." digit*;
|
||||
zone = [ \t]* ("Z" | (sign digit{1,2} ( ":" digit{2} )?));
|
||||
Timestamp = digit{4} ("-" digit{1,2}){2} ([Tt] | [ \t]+)
|
||||
digit{1,2} ":" digit{2} ":" digit{2} fract? zone? %/timestamp_tag;
|
||||
|
||||
Scalar = Bool | Null | Int | Float | TimestampShort | Merge | Value | Timestamp;
|
||||
main := Scalar;
|
||||
write data nofinal;
|
||||
}%%
|
||||
|
||||
public String scan(String scalar) {
|
||||
if (scalar == null) {
|
||||
throw new NullPointerException("Scalar must be provided.");
|
||||
}
|
||||
String tag = null;
|
||||
int cs = 0;
|
||||
int p = 0;
|
||||
int pe = scalar.length();
|
||||
int eof = pe;
|
||||
char[] data;
|
||||
if (pe == 0) {
|
||||
// NULL value
|
||||
data = new char[] { '~' };
|
||||
pe = 1;
|
||||
eof = 1;
|
||||
} else {
|
||||
data = scalar.toCharArray();
|
||||
}
|
||||
%%{
|
||||
# Initialize and execute.
|
||||
write init;
|
||||
write exec;
|
||||
}%%
|
||||
|
||||
return tag;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.resolver;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.NodeId;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.Tag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Resolver tries to detect a type by scalars's content (when the type is
|
||||
* implicit)
|
||||
*
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public class Resolver {
|
||||
public static final Pattern BOOL = Pattern
|
||||
.compile("^(?:yes|Yes|YES|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF)$");
|
||||
public static final Pattern FLOAT = Pattern
|
||||
.compile("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|[-+]?(?:[0-9][0-9_]*)?\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");
|
||||
public static final Pattern INT = Pattern
|
||||
.compile("^(?:[-+]?0b[0-1_]+|[-+]?0[0-7_]+|[-+]?(?:0|[1-9][0-9_]*)|[-+]?0x[0-9a-fA-F_]+|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$");
|
||||
public static final Pattern MERGE = Pattern.compile("^(?:<<)$");
|
||||
public static final Pattern NULL = Pattern.compile("^(?:~|null|Null|NULL| )$");
|
||||
public static final Pattern EMPTY = Pattern.compile("^$");
|
||||
public static final Pattern TIMESTAMP = Pattern
|
||||
.compile("^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?(?:[Tt]|[ \t]+)[0-9][0-9]?:[0-9][0-9]:[0-9][0-9](?:\\.[0-9]*)?(?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$");
|
||||
public static final Pattern VALUE = Pattern.compile("^(?:=)$");
|
||||
public static final Pattern YAML = Pattern.compile("^(?:!|&|\\*)$");
|
||||
|
||||
protected Map<Character, List<ResolverTuple>> yamlImplicitResolvers = new HashMap<Character, List<ResolverTuple>>();
|
||||
|
||||
/**
|
||||
* Create Resolver
|
||||
*
|
||||
* @param respectDefaultImplicitScalars false to parse/dump scalars as plain Strings
|
||||
* @deprecated override addImplicitResolvers instead
|
||||
*/
|
||||
public Resolver(boolean respectDefaultImplicitScalars) {
|
||||
if (respectDefaultImplicitScalars) {
|
||||
addImplicitResolvers();
|
||||
}
|
||||
}
|
||||
|
||||
protected void addImplicitResolvers() {
|
||||
addImplicitResolver(Tag.BOOL, BOOL, "yYnNtTfFoO");
|
||||
addImplicitResolver(Tag.FLOAT, FLOAT, "-+0123456789.");
|
||||
addImplicitResolver(Tag.INT, INT, "-+0123456789");
|
||||
addImplicitResolver(Tag.MERGE, MERGE, "<");
|
||||
addImplicitResolver(Tag.NULL, NULL, "~nN\0");
|
||||
addImplicitResolver(Tag.NULL, EMPTY, null);
|
||||
addImplicitResolver(Tag.TIMESTAMP, TIMESTAMP, "0123456789");
|
||||
addImplicitResolver(Tag.VALUE, VALUE, "=");
|
||||
// The following implicit resolver is only for documentation
|
||||
// purposes.
|
||||
// It cannot work
|
||||
// because plain scalars cannot start with '!', '&', or '*'.
|
||||
addImplicitResolver(Tag.YAML, YAML, "!&*");
|
||||
}
|
||||
|
||||
public Resolver() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public void addImplicitResolver(Tag tag, Pattern regexp, String first) {
|
||||
if (first == null) {
|
||||
List<ResolverTuple> curr = yamlImplicitResolvers.get(null);
|
||||
if (curr == null) {
|
||||
curr = new ArrayList<ResolverTuple>();
|
||||
yamlImplicitResolvers.put(null, curr);
|
||||
}
|
||||
curr.add(new ResolverTuple(tag, regexp));
|
||||
} else {
|
||||
char[] chrs = first.toCharArray();
|
||||
for (int i = 0, j = chrs.length; i < j; i++) {
|
||||
Character theC = new Character(chrs[i]);
|
||||
if (theC == 0) {
|
||||
// special case: for null
|
||||
theC = null;
|
||||
}
|
||||
List<ResolverTuple> curr = yamlImplicitResolvers.get(theC);
|
||||
if (curr == null) {
|
||||
curr = new ArrayList<ResolverTuple>();
|
||||
yamlImplicitResolvers.put(theC, curr);
|
||||
}
|
||||
curr.add(new ResolverTuple(tag, regexp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Tag resolve(NodeId kind, String value, boolean implicit) {
|
||||
if (kind == NodeId.scalar && implicit) {
|
||||
List<ResolverTuple> resolvers = null;
|
||||
if ("".equals(value)) {
|
||||
resolvers = yamlImplicitResolvers.get('\0');
|
||||
} else {
|
||||
resolvers = yamlImplicitResolvers.get(value.charAt(0));
|
||||
}
|
||||
if (resolvers != null) {
|
||||
for (ResolverTuple v : resolvers) {
|
||||
Tag tag = v.getTag();
|
||||
Pattern regexp = v.getRegexp();
|
||||
if (regexp.matcher(value).matches()) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yamlImplicitResolvers.containsKey(null)) {
|
||||
for (ResolverTuple v : yamlImplicitResolvers.get(null)) {
|
||||
Tag tag = v.getTag();
|
||||
Pattern regexp = v.getRegexp();
|
||||
if (regexp.matcher(value).matches()) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (kind) {
|
||||
case scalar:
|
||||
return Tag.STR;
|
||||
case sequence:
|
||||
return Tag.SEQ;
|
||||
default:
|
||||
return Tag.MAP;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.resolver;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.nodes.Tag;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
final class ResolverTuple {
|
||||
private final Tag tag;
|
||||
private final Pattern regexp;
|
||||
|
||||
public ResolverTuple(Tag tag, Pattern regexp) {
|
||||
this.tag = tag;
|
||||
this.regexp = regexp;
|
||||
}
|
||||
|
||||
public Tag getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public Pattern getRegexp() {
|
||||
return regexp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Tuple tag=" + tag + " regexp=" + regexp;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.scanner;
|
||||
|
||||
public final class Constant {
|
||||
private final static String LINEBR_S = "\n\u0085\u2028\u2029";
|
||||
private final static String FULL_LINEBR_S = "\r" + LINEBR_S;
|
||||
private final static String NULL_OR_LINEBR_S = "\0" + FULL_LINEBR_S;
|
||||
private final static String NULL_BL_LINEBR_S = " " + NULL_OR_LINEBR_S;
|
||||
private final static String NULL_BL_T_LINEBR_S = "\t" + NULL_BL_LINEBR_S;
|
||||
|
||||
public final static Constant LINEBR = new Constant(LINEBR_S);
|
||||
public final static Constant FULL_LINEBR = new Constant(FULL_LINEBR_S);
|
||||
public final static Constant NULL_OR_LINEBR = new Constant(NULL_OR_LINEBR_S);
|
||||
public final static Constant NULL_BL_LINEBR = new Constant(NULL_BL_LINEBR_S);
|
||||
public final static Constant NULL_BL_T_LINEBR = new Constant(NULL_BL_T_LINEBR_S);
|
||||
|
||||
private String content;
|
||||
|
||||
private Constant(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public boolean has(char ch) {
|
||||
return content.indexOf(ch) != -1;
|
||||
}
|
||||
|
||||
public boolean hasNo(char ch) {
|
||||
return !has(ch);
|
||||
}
|
||||
|
||||
public boolean has(char ch, String additional) {
|
||||
return additional.indexOf(ch) != -1 || content.indexOf(ch) != -1;
|
||||
}
|
||||
|
||||
public boolean hasNo(char ch, String additional) {
|
||||
return !has(ch, additional);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.scanner;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.tokens.Token;
|
||||
|
||||
/**
|
||||
* This interface represents an input stream of {@link Token Tokens}.
|
||||
* <p>
|
||||
* The parser and the scanner form together the 'Parse' step in the loading
|
||||
* process (see chapter 3.1 of the <a href="http://yaml.org/spec/1.1/">YAML
|
||||
* Specification</a>).
|
||||
* </p>
|
||||
*
|
||||
* @see org.elasticsearch.util.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
|
||||
* of at least one of the given types. Returns <code>false</code> if
|
||||
* no more tokens are available.
|
||||
* @throws ScannerException Thrown in case of malformed input.
|
||||
*/
|
||||
boolean checkToken(Token.ID... choices);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
Token peekToken();
|
||||
|
||||
/**
|
||||
* Returns the next token.
|
||||
* <p>
|
||||
* The token will be removed from the stream.
|
||||
* </p>
|
||||
*
|
||||
* @throws ScannerException Thrown in case of malformed input.
|
||||
*/
|
||||
Token getToken();
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.scanner;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.MarkedYAMLException;
|
||||
|
||||
/**
|
||||
* Exception thrown by the {@link Scanner} implementations in case of malformed
|
||||
* input.
|
||||
*/
|
||||
public class ScannerException extends MarkedYAMLException {
|
||||
|
||||
private static final long serialVersionUID = 4782293188600445954L;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param context Part of the input document in which vicinity the problem
|
||||
* occurred.
|
||||
* @param contextMark Position of the <code>context</code> within the document.
|
||||
* @param problem Part of the input document that caused the problem.
|
||||
* @param problemMark Position of the <code>problem</code> within the document.
|
||||
* @param note Message for the user with further information about the
|
||||
* problem.
|
||||
*/
|
||||
public ScannerException(String context, Mark contextMark, String problem, Mark problemMark,
|
||||
String note) {
|
||||
super(context, contextMark, problem, problemMark, note);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param context Part of the input document in which vicinity the problem
|
||||
* occurred.
|
||||
* @param contextMark Position of the <code>context</code> within the document.
|
||||
* @param problem Part of the input document that caused the problem.
|
||||
* @param problemMark Position of the <code>problem</code> within the document.
|
||||
*/
|
||||
public ScannerException(String context, Mark contextMark, String problem, Mark problemMark) {
|
||||
this(context, contextMark, problem, problemMark, null);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.scanner;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* Simple keys treatment.
|
||||
* <p>
|
||||
* Helper class for {@link ScannerImpl}.
|
||||
* </p>
|
||||
*
|
||||
* @see ScannerImpl
|
||||
*/
|
||||
final class SimpleKey {
|
||||
private int tokenNumber;
|
||||
private boolean required;
|
||||
private int index;
|
||||
private int line;
|
||||
private int column;
|
||||
private Mark mark;
|
||||
|
||||
public SimpleKey(int tokenNumber, boolean required, int index, int line, int column, Mark mark) {
|
||||
this.tokenNumber = tokenNumber;
|
||||
this.required = required;
|
||||
this.index = index;
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
this.mark = mark;
|
||||
}
|
||||
|
||||
public int getTokenNumber() {
|
||||
return this.tokenNumber;
|
||||
}
|
||||
|
||||
public int getColumn() {
|
||||
return this.column;
|
||||
}
|
||||
|
||||
public Mark getMark() {
|
||||
return mark;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public boolean isRequired() {
|
||||
return required;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SimpleKey - tokenNumber=" + tokenNumber + " required=" + required + " index="
|
||||
+ index + " line=" + line + " column=" + column;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class AliasToken extends Token {
|
||||
private final String value;
|
||||
|
||||
public AliasToken(String value, Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getArguments() {
|
||||
return "value=" + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.Alias;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class AnchorToken extends Token {
|
||||
private final String value;
|
||||
|
||||
public AnchorToken(String value, Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getArguments() {
|
||||
return "value=" + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.Anchor;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class BlockEndToken extends Token {
|
||||
|
||||
public BlockEndToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.BlockEnd;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class BlockEntryToken extends Token {
|
||||
|
||||
public BlockEntryToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.BlockEntry;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class BlockMappingStartToken extends Token {
|
||||
|
||||
public BlockMappingStartToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.BlockMappingStart;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class BlockSequenceStartToken extends Token {
|
||||
|
||||
public BlockSequenceStartToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.BlockSequenceStart;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class DirectiveToken<T> extends Token {
|
||||
private final String name;
|
||||
private final List<T> value;
|
||||
|
||||
public DirectiveToken(String name, List<T> value, Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
this.name = name;
|
||||
if (value != null && value.size() != 2) {
|
||||
throw new YAMLException("Two strings must be provided instead of "
|
||||
+ String.valueOf(value.size()));
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public List<T> getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getArguments() {
|
||||
if (value != null) {
|
||||
return "name=" + name + ", value=[" + value.get(0) + ", " + value.get(1) + "]";
|
||||
} else {
|
||||
return "name=" + name;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.Directive;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class DocumentEndToken extends Token {
|
||||
|
||||
public DocumentEndToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.DocumentEnd;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class DocumentStartToken extends Token {
|
||||
|
||||
public DocumentStartToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.DocumentStart;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class FlowEntryToken extends Token {
|
||||
|
||||
public FlowEntryToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.FlowEntry;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class FlowMappingEndToken extends Token {
|
||||
|
||||
public FlowMappingEndToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.FlowMappingEnd;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class FlowMappingStartToken extends Token {
|
||||
|
||||
public FlowMappingStartToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.FlowMappingStart;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class FlowSequenceEndToken extends Token {
|
||||
|
||||
public FlowSequenceEndToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.FlowSequenceEnd;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class FlowSequenceStartToken extends Token {
|
||||
|
||||
public FlowSequenceStartToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.FlowSequenceStart;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class KeyToken extends Token {
|
||||
|
||||
public KeyToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.Key;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class ScalarToken extends Token {
|
||||
private final String value;
|
||||
private final boolean plain;
|
||||
private final char style;
|
||||
|
||||
public ScalarToken(String value, Mark startMark, Mark endMark, boolean plain) {
|
||||
this(value, plain, startMark, endMark, (char) 0);
|
||||
}
|
||||
|
||||
public ScalarToken(String value, boolean plain, Mark startMark, Mark endMark, char style) {
|
||||
super(startMark, endMark);
|
||||
this.value = value;
|
||||
this.plain = plain;
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public boolean getPlain() {
|
||||
return this.plain;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public char getStyle() {
|
||||
return this.style;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getArguments() {
|
||||
return "value=" + value + ", plain=" + plain + ", style=" + style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.Scalar;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class StreamEndToken extends Token {
|
||||
|
||||
public StreamEndToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.StreamEnd;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class StreamStartToken extends Token {
|
||||
|
||||
public StreamStartToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.StreamStart;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class TagToken extends Token {
|
||||
private final TagTuple value;
|
||||
|
||||
public TagToken(TagTuple value, Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public TagTuple getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getArguments() {
|
||||
return "value=[" + value.getHandle() + ", " + value.getSuffix() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.Tag;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
public final class TagTuple {
|
||||
private final String handle;
|
||||
private final String suffix;
|
||||
|
||||
public TagTuple(String handle, String suffix) {
|
||||
if (suffix == null) {
|
||||
throw new NullPointerException("Suffix must be provided.");
|
||||
}
|
||||
this.handle = handle;
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public String getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public abstract class Token {
|
||||
public enum ID {
|
||||
Alias, Anchor, BlockEnd, BlockEntry, BlockMappingStart, BlockSequenceStart, Directive, DocumentEnd, DocumentStart, FlowEntry, FlowMappingEnd, FlowMappingStart, FlowSequenceEnd, FlowSequenceStart, Key, Scalar, StreamEnd, StreamStart, Tag, Value
|
||||
}
|
||||
|
||||
private final Mark startMark;
|
||||
private final Mark endMark;
|
||||
|
||||
public Token(Mark startMark, Mark endMark) {
|
||||
if (startMark == null || endMark == null) {
|
||||
throw new YAMLException("Token requires marks.");
|
||||
}
|
||||
this.startMark = startMark;
|
||||
this.endMark = endMark;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "<" + this.getClass().getName() + "(" + getArguments() + ")>";
|
||||
}
|
||||
|
||||
public Mark getStartMark() {
|
||||
return startMark;
|
||||
}
|
||||
|
||||
public Mark getEndMark() {
|
||||
return endMark;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see __repr__ for Token in PyYAML
|
||||
*/
|
||||
protected String getArguments() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* For error reporting.
|
||||
*
|
||||
* @see class variable 'id' in PyYAML
|
||||
*/
|
||||
public abstract ID getTokenId();
|
||||
|
||||
/*
|
||||
* for tests only
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Token) {
|
||||
return toString().equals(obj.toString());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.tokens;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.Mark;
|
||||
|
||||
/**
|
||||
* @see <a href="http://pyyaml.org/wiki/PyYAML">PyYAML</a> for more information
|
||||
*/
|
||||
public final class ValueToken extends Token {
|
||||
|
||||
public ValueToken(Mark startMark, Mark endMark) {
|
||||
super(startMark, endMark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID getTokenId() {
|
||||
return ID.Value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ArrayStack<T> {
|
||||
private ArrayList<T> stack;
|
||||
|
||||
public ArrayStack(int initSize) {
|
||||
stack = new ArrayList<T>(initSize);
|
||||
}
|
||||
|
||||
public void push(T obj) {
|
||||
stack.add(obj);
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
return stack.remove(stack.size() - 1);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return stack.isEmpty();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
stack.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you 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.elasticsearch.util.yaml.snakeyaml.util;
|
||||
|
||||
import org.elasticsearch.util.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
public abstract class Base64Coder {
|
||||
// Mapping table from 6-bit nibbles to Base64 characters.
|
||||
private final static char[] map1 = new char[64];
|
||||
|
||||
static {
|
||||
int i = 0;
|
||||
for (char c = 'A'; c <= 'Z'; c++)
|
||||
map1[i++] = c;
|
||||
for (char c = 'a'; c <= 'z'; c++)
|
||||
map1[i++] = c;
|
||||
for (char c = '0'; c <= '9'; c++)
|
||||
map1[i++] = c;
|
||||
map1[i++] = '+';
|
||||
map1[i++] = '/';
|
||||
}
|
||||
|
||||
// Mapping table from Base64 characters to 6-bit nibbles.
|
||||
private final static byte[] map2 = new byte[128];
|
||||
|
||||
static {
|
||||
for (int i = 0; i < map2.length; i++)
|
||||
map2[i] = -1;
|
||||
for (int i = 0; i < 64; i++)
|
||||
map2[map1[i]] = (byte) i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a byte array into Base64 format. No blanks or line breaks are
|
||||
* inserted.
|
||||
*
|
||||
* @param in an array containing the data bytes to be encoded.
|
||||
* @return A character array with the Base64 encoded data.
|
||||
*/
|
||||
public static char[] encode(byte[] in) {
|
||||
int iLen = in.length;
|
||||
int oDataLen = (iLen * 4 + 2) / 3; // output length without padding
|
||||
int oLen = ((iLen + 2) / 3) * 4; // output length including padding
|
||||
char[] out = new char[oLen];
|
||||
int ip = 0;
|
||||
int op = 0;
|
||||
while (ip < iLen) {
|
||||
int i0 = in[ip++] & 0xff;
|
||||
int i1 = ip < iLen ? in[ip++] & 0xff : 0;
|
||||
int i2 = ip < iLen ? in[ip++] & 0xff : 0;
|
||||
int o0 = i0 >>> 2;
|
||||
int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
|
||||
int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
|
||||
int o3 = i2 & 0x3F;
|
||||
out[op++] = map1[o0];
|
||||
out[op++] = map1[o1];
|
||||
out[op] = op < oDataLen ? map1[o2] : '=';
|
||||
op++;
|
||||
out[op] = op < oDataLen ? map1[o3] : '=';
|
||||
op++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes Base64 data. No blanks or line breaks are allowed within the
|
||||
* Base64 encoded data.
|
||||
*
|
||||
* @param in a character array containing the Base64 encoded data.
|
||||
* @return An array containing the decoded data bytes.
|
||||
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
|
||||
*/
|
||||
public static byte[] decode(char[] in) {
|
||||
int iLen = in.length;
|
||||
if (iLen % 4 != 0)
|
||||
throw new YAMLException("Length of Base64 encoded input string is not a multiple of 4.");
|
||||
while (iLen > 0 && in[iLen - 1] == '=')
|
||||
iLen--;
|
||||
int oLen = (iLen * 3) / 4;
|
||||
byte[] out = new byte[oLen];
|
||||
int ip = 0;
|
||||
int op = 0;
|
||||
while (ip < iLen) {
|
||||
int i0 = in[ip++];
|
||||
int i1 = in[ip++];
|
||||
int i2 = ip < iLen ? in[ip++] : 'A';
|
||||
int i3 = ip < iLen ? in[ip++] : 'A';
|
||||
if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
|
||||
throw new YAMLException("Illegal character in Base64 encoded data.");
|
||||
int b0 = map2[i0];
|
||||
int b1 = map2[i1];
|
||||
int b2 = map2[i2];
|
||||
int b3 = map2[i3];
|
||||
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
|
||||
throw new YAMLException("Illegal character in Base64 encoded data.");
|
||||
int o0 = (b0 << 2) | (b1 >>> 4);
|
||||
int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2);
|
||||
int o2 = ((b2 & 3) << 6) | b3;
|
||||
out[op++] = (byte) o0;
|
||||
if (op < oLen)
|
||||
out[op++] = (byte) o1;
|
||||
if (op < oLen)
|
||||
out[op++] = (byte) o2;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue