Coder Social home page Coder Social logo

yamlbeans's Introduction

YamlBeans

Maven Central

Please use the YamlBeans discussion group for support.

Chinese document 中文翻译文档 .

Overview

YamlBeans makes it easy to serialize and deserialize Java object graphs to and from YAML, a human-friendly data format. Replace XML and properties files with YAML for more expressive power (lists, maps, anchors, etc) and easier hand-editing.

Maven Central: https://repo1.maven.org/maven2/com/esotericsoftware/yamlbeans/yamlbeans/

Basic deserialization

The YamlReader class is used to deserialize YAML to Java objects. The following YAML defines a Map with four entries. The "phone numbers" entry is a List of two items, each of which is a Map.

    name: Nathan Sweet
    age: 28
    address: 4011 16th Ave S
    phone numbers:
     - name: Home
       number: 206-555-5138
     - name: Work
       number: 425-555-2306

The "read" method reads the next YAML document and deserializes it into HashMaps, ArrayLists, and Strings. Since we know the root object defined in the YAML of our example is a Map, we can cast the object and make use of it.

    YamlReader reader = new YamlReader(new FileReader("contact.yml"));
    Object object = reader.read();
    System.out.println(object);
    Map map = (Map)object;
    System.out.println(map.get("address"));

Multiple objects

A stream of YAML can contain more than one YAML document. Each call to YamlReader#read() deserializes the next document into an object. YAML documents are delimited by "---" (this is optional for the first document).

    name: Nathan Sweet
    age: 28
    ---
    name: Some One
    age: 25

This prints the String "28" then "25":

    YamlReader reader = new YamlReader(new FileReader("contact.yml"));
    while (true) {
    	Map contact = reader.read();
    	if (contact == null) break;
    	System.out.println(contact.get("age"));
    }

Deserializing other classes

There are two ways to deserialize something other than HashMaps, ArrayLists, and Strings. Imagine this YAML document and Java class:

    name: Nathan Sweet
    age: 28
    public class Contact {
    	public String name;
    	public int age;
    }

The "read" method can be passed a class, so the YamlReader knows what it is deserializing:

    YamlReader reader = new YamlReader(new FileReader("contact.yml"));
    Contact contact = reader.read(Contact.class);
    System.out.println(contact.age);

The YamlReader creates an instance of the Contact class and sets the "name" and "age" fields. The YamlReader determines the "age" value in the YAML needs to be converted into a int. Deserialization would have failed if the age was not a valid int. The YamlReader can set public fields and bean setter methods.

Instead of telling the YamlReader what type to deserialize, the type can alternatively be specified in the YAML using a tag:

    !com.example.Contact
    name: Nathan Sweet
    age: 28

Serializing objects

The YamlWriter class is used to serialize Java objects to YAML. The "write" method automatically handles this by recognizing public fields and bean getter methods.

    Contact contact = new Contact();
    contact.name = "Nathan Sweet";
    contact.age = 28;
    YamlWriter writer = new YamlWriter(new FileWriter("output.yml"));
    writer.write(contact);
    writer.close();

This outputs:

    !com.example.Contact
    name: Nathan Sweet
    age: 28

The tags are automatically output as needed so that the YamlReader class will be able to reconstruct the object graph. For example, serializing this ArrayList does not output any tag for the list because YamlReader uses an ArrayList by default.

    List list = new ArrayList();
    list.add("moo");
    list.add("cow");
    - moo
    - cow

If the list was a LinkedList, then YamlWriter knows that a tag is needed and outputs:

    List list = new LinkedList();
    list.add("moo");
    list.add("cow");
    !java.util.LinkedList
    - moo
    - cow

Note that it is not advisable to subclass Collection or Map. YamlBeans will only serialize the collection or map and its elements, not any additional fields.

Complex graphs

YamlBeans can serialize any object graph.

    public class Contact {
    	public String name;
    	public int age;
    	public List phoneNumbers;
    }
    
    public class Phone {
    	public String name;
    	public String number;
    }
    friends:
      - !com.example.Contact
        name: Bob
        age: 29
        phoneNumbers:
            - !com.example.Phone
              name: Home
              number: 206-555-1234
            - !com.example.Phone
              name: Work
              number: 206-555-5678
      - !com.example.Contact
        name: Mike
        age: 31
        phoneNumbers:
            - !com.example.Phone
              number: 206-555-4321
    enemies:
      - !com.example.Contact
        name: Bill
        phoneNumbers:
            - !com.example.Phone
              name: Cell
              number: 206-555-1234

This is a map of lists of contacts, each with a list of phone numbers. Again, the public fields could also have been bean properties.

Tag shortcuts

Tags can be lengthy sometimes and can clutter up the YAML. Alternate tags can be defined for a class and will be used instead of the full class name.

    YamlWriter writer = new YamlWriter(new FileWriter("output.yml"));
    writer.getConfig().setClassTag("contact", Contact.class);
    writer.write(contact);
    writer.close();

The output no longer contains the full classname for the Contact class.

    !contact
    name: Nathan Sweet
    age: 28

Lists and maps

When reading or writing a List or Map, YamlBeans cannot know what type of objects are supposed to be in the List or Map, so it will write out a tag.

    !com.example.Contact
    name: Bill
        phoneNumbers:
            - !com.example.Phone
              number: 206-555-1234
            - !com.example.Phone
              number: 206-555-5678
            - !com.example.Phone
              number: 206-555-7654

This can make the YAML less readable. To improve this, you may define what element type should be expected for a List or Map field on your object.

    YamlWriter writer = new YamlWriter(new FileWriter("output.yml"));
    writer.getConfig().setPropertyElementType(Contact.class, "phoneNumbers", Phone.class);
    writer.write(contact);
    writer.close();

Now YamlBeans knows what to expect for elements of the "phoneNumbers" field, so extra tags will not be output.

    !com.example.Contact
    name: Bill
        phoneNumbers:
            - number: 206-555-1234
            - number: 206-555-5678
            - number: 206-555-7654

Setting the element type for a Map field tells YamlBeans what to expect for values in the Map. Keys in a Map are always Strings.

Anchors

When an object graph contains multiple references to the same object, an anchor may be used so that the object only needs to be defined once in the YAML.

    oldest friend:
        &1 !contact
        name: Bob
        age: 29
    best friend: *1

In this map, the "oldest friend" and "best friend" keys reference the same object. The YamlReader automatically handles the anchors in the YAML when rebuilding the object graph. By default, the YamlWriter automatically outputs anchors when writing objects.

    Contact contact = new Contact();
    contact.name = "Bob";
    contact.age = 29;
    Map map = new HashMap();
    map.put("oldest friend", contact);
    map.put("best friend", contact);

Duplicate key validation

By default, the behaviour of this YAML parser is to ignore duplicate keys if you have. e.g if you have the following

    name: Nathan Sweet
    age: 28
    address:
      line1: 485 Madison Ave S
      line1: 711 3rd Ave S
      line2: NYC

The above YAML will give you an address object with attribute line1 set to 711 3rd Ave S. This is because the key line1 in the above YAML is duplicated and thus the last value of line1 will be retained. YAML parser will not complain about it. However, if your business logic requires you to validate YAML for such duplicates, then you can still do using allowDuplicates option of the YamlConfig object. Following is how its done:

    try {
        YamlConfig yamlConfig = new YamlConfig();
        yamlConfig.setAllowDuplicates(false); // default value is true
        YamlReader reader = new YamlReader(new FileReader("contact.yml"), yamlConfig);
        Object object = reader.read();
        System.out.println(object);
        Map map = (Map)object;
        System.out.println(map.get("address"));
    } catch (YamlException ex) {
        ex.printStackTrace();
        // or handle duplicate key case here according to your business logic
    }

The above code will not print anything, but throw YamlReaderException at line 5 saying, Duplicate key found 'line1'.

Architecture

The YAML tokenizer, parser, and emitter are based on those from the JvYAML project. They have been heavily refactored, bugs fixed, etc. The rest of the JvYAML project was not used because of its complexity. YamlBeans strives for the simplest possible thing that works, with the goal being to make it easy to use the YAML data format with Java.

YamlBeans supports YAML version 1.0 and 1.1.

More info

See the javadocs for various other features available on the YamlConfig class.

yamlbeans's People

Contributors

alexlopashev avatar ams-tschoening avatar arrayadd avatar cal101 avatar czytx avatar dboitnot avatar dependabot[bot] avatar devcharly avatar ericvergnaud avatar gaibhne avatar guperrot avatar jason-hooker avatar jessepav avatar joebeeton avatar mr14huashao avatar nathansweet avatar nemesismate avatar olga-st avatar ramchaik avatar sanjusoftware avatar seetamraju avatar seii avatar tarzanwill avatar tchemit avatar the-alchemist avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yamlbeans's Issues

Sets don't deserialise to something that equals the original

The following junit test fails at the last assert with the error:

java.lang.AssertionError: expected: java.util.HashSet<[1]> but was: java.util.HashSet<[1]>

@Test
public void test_Set() throws YamlException {
    Set<Integer> set1 = new HashSet<Integer>(); 
    set1.add(1);
    Set<Integer> set2 = new HashSet<Integer>();
    set2.add(1);
    assertEquals(set1, set2);

    // serialise
    Writer sb = new StringWriter();
    YamlWriter writer = new YamlWriter(sb);        
    writer.write(set1);
    writer.close();
    String yaml = sb.toString();

    // deserialise
    YamlReader reader = new YamlReader(new StringReader(yaml));
    Set<Integer> set3 = (Set<Integer>) reader.read();
    assertEquals(set1, set3);
}

The yaml is:

!java.util.HashSet
- 1

Single quotes are not always duplicated when serializing

From [email protected] on April 26, 2012 17:00:47

What steps will reproduce the problem?

Serialize the string "A: 'X'". You get "'A: 'X'''" instead of "'A: ''X'''\n". The first quote in front of the X is not duplicated.

I used trunk.

See attached patch and test cases.

I havent tested for similar problems when the string needs folding.

Attachment: EmitterWriter.java YamlWriterTest.java

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=14

request for automatic detection of parameterized List's

If we have:

public class Machines {
    public List<Machine> machines;
}

public class Machine {
    public String machine_used;
    public List<Measurement> measurements;
}

I have to say:

        yamlConfig.setPropertyElementType(Machines.class, "machines", Machine.class);
        yamlConfig.setPropertyElementType(Machine.class, "measurements", Measurement.class);

Couldn't yamlbeans conceivably use the generic parameter of the List as a safe default?

I can submit a pull request, if it has a decent chance of getting accepted. :)

UTF-8 BOM is not respected

From [email protected] on January 28, 2011 15:26:48

What steps will reproduce the problem?

  1. put the attached file to test folder
  2. run the provided test

    BOM is not removed from the result.


    public void testUtf8Bom() throws IOException {
    File file = new File("test/utf-8.txt");
    assertTrue("Test file not found: " + file.getAbsolutePath(), file.exists());
    YamlReader r = new YamlReader(new FileReader(file));
    String utf = (String) r.read();
    System.out.println(utf);
    String etalon = "test Français €¥$";
    assertEquals("Leading BOM must be removed.", etalon.length(), utf.length());
    assertEquals(etalon, utf);
    }

    How can I exclude BOM from the result ? SnakeYAML provides UnicodeReader() to cope with this general Java problem.

Attachment: utf-8.txt

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=8

[Enhancement] Make setBeanProperties to not depend on it field type.

The field dependency for the bean property way is great to allow making the bean transient (it isn't currently working, and I wonder if it is intended to) but with this it is impossible to make some tricks as set a String and then, in the getter/setter make wathever magic to de/serialize de field type. ie:

!thing
template: "t1"

and after in code:

TemplateType template;

String getTemplate() {
   return template.getName();
}

void setTemplate(String template) {
  this.template = getTemplateForName(template);
}

Expected type string but found type integer

I am using yamlbeans-1.09.jar to convert my HashMap of values to yml data. But whenever it encounters a string with a number within it, for example- map.put("version", "1.0"), it renders it out as a number instead of String which makes it invalid. I am facing this issue especially when working with Swagger which requires a YML input which I am generating through yamlbeans.
The Java input is:
HashMap<String, Object> rootElementsForYml = new HashMap<String, Object>();
rootElementsForYml.put(SWAGGER, "2.0");
rootElementsForYml.put(HOST, "api.xxxx.com");
rootElementsForYml.put(BASEPATH, basePath);
rootElementsForYml.put(SCHEMES, new String[]{"https"});

The YML Output which does not work with Swagger is:
basePath: /employment
host: api.xxxx.com
schemes:
- https
swagger: 2.0
info:
title: API Doc
description: Description for the info goes here
version: 1.0.0.

The error thrown is Expected type string but found type integer

Support UUID

Hello

Is there a way to add support for UUID? When I try to read from yaml that has UUID

- !models.Country
    id: f63768b8-b76f-47e8-9882-f15d891ebef9
    name: Afghanistan
    iso2: AF
    iso3: AFG

I get an error

Caused by: com.esotericsoftware.yamlbeans.YamlReader$YamlReaderException: Line 2, column 4: Expected data for a java.util.UUID field but found: scalar

YamlBeans doesn't handle empty tags

I'm trying to parse YAML I get from another application. Many tags are optional, and therefore empty, ie
tag:
tag2: foo
tag3: 123
tag4:

I'm using 1.07, and when I try to parse an empty tag,
com.esotericsoftware.yamlbeans.YamlReader$YamlReaderException: Line 10, column 28: Unable to convert value to required type "long":
at com.esotericsoftware.yamlbeans.YamlReader.readValueInternal(YamlReader.java:228)
at com.esotericsoftware.yamlbeans.YamlReader.readValue(YamlReader.java:152)
at com.esotericsoftware.yamlbeans.YamlReader.readValueInternal(YamlReader.java:295)
at com.esotericsoftware.yamlbeans.YamlReader.readValue(YamlReader.java:152)
at com.esotericsoftware.yamlbeans.YamlReader.read(YamlReader.java:103)
at com.esotericsoftware.yamlbeans.YamlReader.read(YamlReader.java:90)
...
Caused by: java.lang.NumberFormatException: Zero length string
at java.lang.Long.decode(Long.java:630)
at com.esotericsoftware.yamlbeans.YamlReader.readValueInternal(YamlReader.java:208)

cannot build YamlBeans with the provided Maven script

From [email protected] on January 28, 2011 10:58:58

What steps will reproduce the problem?

  1. checkout the latest source (revision 32)
  2. run 'mvn clean test'

    Please also note that the build is platform-dependent. Which platform has been used to build the artifacts which are available for download ?

    What version of the product are you using? On what operating system?
    java version "1.5.0_19"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_19-b02)
    Java HotSpot(TM) Client VM (build 1.5.0_19-b02, mixed mode, sharing)

    Maven 2.2.1


    Please provide any additional information below.

    [INFO] Compiling 2 source files to /home/somov/projects/Yamlbeans-read-only/target/test-classes
    [INFO] ------------------------------------------------------------------------
    [ERROR] BUILD FAILURE
    [INFO] ------------------------------------------------------------------------
    [INFO] Compilation failure

    /home/somov/projects/Yamlbeans-read-only/test/com/esotericsoftware/yamlbeans/YamlWriterTest.java:[19,18] cannot find symbol
    symbol : class ConstructorProperties
    location: package java.beans

Attachment: build.txt

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=6

For the Explicit Block Mapping,why yamlbeans implements the key length < 128 ?

In the YAML Version 1.2 specification (http://yaml.org/spec/1.2/spec.html#id2798057),for the Explicit Block Mapping,having the following specifications:
If the “?” indicator is omitted, parsing needs to see past the implicit key, in the same way as in the single key: value pair flow mapping. Hence, such keys are subject to the same restrictions; they are limited to a single line and must not span more than 1024 Unicode characters.
why yamlbeans implements the key length < 128 ?
return length < 128 && (event.type == ALIAS || event.type == SCALAR && !analysis.empty && !analysis.multiline || checkEmptySequence() || checkEmptyMapping());

Android support

As it is, the library is not currently compatible with Android due to

Caused by: java.lang.ClassNotFoundException: Didn't find class "java.beans.Introspector" on path: DexPathList[[zip file "/data/app/app.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]

Which is a pity because there are not that many YAML libraries out there, and most certainly not as good as yours.

Only able read integer values (Long,Integer,Short,Byte) when in decimal notation

From [email protected] on May 20, 2013 11:57:11

According to http://www.yaml.org/refcard.html is must be possible to used decimal, hex and octal notation for integers.

The solution is to use decode(String) instead of valueOf(String) in the scalar decoding.

I've attached my modified YamlReader.java (from trunk)


/Morten

Attachment: YamlReader.java

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=15

Class tags containing '_' won't deserialize.

From [email protected] on March 12, 2011 17:11:47

To reproduce the problem?

  1. Create a Bean class with an embedded '_' in the name, eg com.example.yaml.Foo_Bar
  2. Serialize an instance of this class to YAML.
  3. Deserialize the YAML back to an instance.

Alternatively you can configure a class tag with the _:

config.setClassTag("Foo_Bar", Station.class);

I expect to get a deserialized Bean (or an error message about using '_'), but see a stack trace from Tokenizer instead:

java.lang.RuntimeException: Couldn't deserialize DTO from YAML String: Error tokenizing YAML.
at com.mot.tod.dto.utils.YAMLBeansSerializer.fromYAML(YAMLBeansSerializer.java:94)
at com.mot.tod.dto.utils.YAMLBeansSerializer.deepCopy(YAMLBeansSerializer.java:130)
at com.mot.tod.dto.DTOTest.testDTO(DTOTest.java:3032)
at com.mot.tod.dto.DTOTest.testLineupMap_Station(DTOTest.java:2662)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: com.esotericsoftware.yamlbeans.YamlException: Error tokenizing YAML.
at com.esotericsoftware.yamlbeans.YamlReader.read(YamlReader.java:110)
at com.esotericsoftware.yamlbeans.YamlReader.read(YamlReader.java:91)
at com.mot.tod.dto.utils.YAMLBeansSerializer.fromYAML(YAMLBeansSerializer.java:90)
... 27 more
Caused by: com.esotericsoftware.yamlbeans.tokenizer.Tokenizer$TokenizerException: Line 0, column 4: While scanning a tag, expected ' ' but found: '_' (95)
at com.esotericsoftware.yamlbeans.tokenizer.Tokenizer.scanTag(Tokenizer.java:705)
at com.esotericsoftware.yamlbeans.tokenizer.Tokenizer.fetchTag(Tokenizer.java:486)
at com.esotericsoftware.yamlbeans.tokenizer.Tokenizer.fetchMoreTokens(Tokenizer.java:306)
at com.esotericsoftware.yamlbeans.tokenizer.Tokenizer.peekNextToken(Tokenizer.java:122)
at com.esotericsoftware.yamlbeans.tokenizer.Tokenizer.peekNextTokenType(Tokenizer.java:127)
at com.esotericsoftware.yamlbeans.parser.Parser$4.produce(Parser.java:133)
at com.esotericsoftware.yamlbeans.parser.Parser.getNextEvent(Parser.java:82)
at com.esotericsoftware.yamlbeans.YamlReader.read(YamlReader.java:101)
... 29 more

What version of the product are you using? On what operating system?

1.0.6 on Windows XP


Please provide any additional information below.

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=12

fix YamlReaderTest.java

From [email protected] on January 28, 2011 08:11:51

Hi YamlReaderTest.java starts from illegal character.
So maven build fails with:

test/com/esotericsoftware/yamlbeans/YamlReaderTest.java:[1,0] illegal character: \65279

BWT.
I do not have java 1.5, but I think build may fail on pure 1.5 with ClassNotFoundException.
Tests may not compile - there are
YamlWriterTest.java: @-ConstructorProperties({"x", "y", "z"})
YamlWriterTest.java: @-ConstructorProperties({"x", "y"})
YamlWriterTest.java: @-ConstructorProperties({"result", "QTime"})

and it's @-since 1.6

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=5

How to generate yml file for a Java class object

This library can generate yml file for a java object given,I wanted to generate yml for the Java class object. This is to get the schema of the java class object. We have libraries to get java class to JSON . For a complex POJO, the JSON is cryptic and I prefer to have a yml representation.

Example
From

public class Phone {
    public String name;
    public String number;
}

To

Phone:
    fields:
      name:
        type: String
      number:
        type: String

New version to keep order

Hi!
Would you like to release a new version of your software in order to make available that fix that keeps read order? I saw fix was commited on June, but last version is from May.

Thanks!

Can't deserialize document with type tags unless all classes on classpath

Actions:

  1. Have a program that serializes a Java object into YAML, using several data container classes as field types.
  2. Write another program that wants to deserialize the YAML into its own data structures. This new program does not have access to the classes defined by the first. It defines its own classes that it wants to deserialize into.

For example, the document might be

!com.example.not.on.classpath.Fish
species: Walleye
weight: 24
  1. Attempt to deserialize into our own OurFish class, providing that as the target type for deserialization:
...
OurFish fish = new YamlReader(input, config).read(OurFish.class);

Expected:
Either our type will override the type tags present within the document, or there will be an option on ReadConfig to do so.

Actual:
Regardless of our provided target type, the parsing fails because the class listed in the type tag in the document is not on our classpath.

I propose this be remedied by means of an ignoreTypeTags option on ReadConfig that would allow callers to specify all their own target types and ignore the type tags present in the document.

Add Support for emit of DocumentEndTag directly after write

I'd like to use Yamlbeans as a library for parsing yaml-network-streams. When using yaml as a stream, it is required to emit a DocumentEndTag after every Document send.

I have implemented it in my fork and would like to hear feedback on my change (naming, etc..).

Outdated maven build

I was noticing the read function printing empty lines in my project, but I see that issue has already been resolved, except the maven build is out of date. Are you guys planning on updating it?

is...() Getter Not Recognized for Booleans

YamlBeans appears not to recognize that is...() is as valid as get...() as a getter method for boolean fields. Case in point, given a boolean field tangible its respective getter and setter methods are isTangible() and setTangible(...). Unfortunately YamlBeans throws an exception unless a getTangible() method is provided.

Problem with arrays of enums implementing an interface.

I'm having troubles with the serialization of enums. Given an array containing elements from an interface, when it is serialized, the enums aren't tagged as such, and so, they can't be deserialized.
For example, having enumArray an array of an interface, YamlBeans serializes:

!test.YamlEnumTest$TestObject
enumArray: 
- V1
- V2

when it should be:

!test.YamlEnumTest$TestObject
enumArray: 
- !test.YamlEnumTest$CustomEnum V1
- !test.YamlEnumTest$CustomEnum V2

This could be fixed if an array could be tagged to use a default enum (just as it can be done with a collection) but it wouldn't work anyway if the array is filled with mixed values from different classes/enums implementing the interface, ie: where the serialization would be like:

!test.YamlEnumTest$TestObject
enumArray: 
- !test.YamlEnumTest$NonEnum
    v1: v1
    v2: v2
- !test.YamlEnumTest$CustomEnum V2
- !test.YamlEnumTest$CustomEnum2 VAL1

Well, all this is tested under the next code:

https://gist.github.com/NemesisMate/7152b60560161ff2154fad9d7827f2d0

only public attributes supported, private instance variables seem to not be supported

From [email protected] on March 15, 2011 16:30:16

What steps will reproduce the problem?

  1. declare a private variable in a java class
  2. use yamlbeans to initialize the class

    I had hoped that this would work, but instead yamlbeans seems to only support public variables or those with public getters/setters. But I'd like to be able to use it for private variables as well.

    Is this not possible?

    Thx
    Ari

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=13

Error when writing strings containing tabs

If a String contains a tabulator (no other special chars like \n), then the value is written as a plain text instead of a double-quoted text. As a result, YAMLReader throws an exception if we load this file.
n. BUT: If the string contains a \t and a \n, it works as expected. See the following junit test cases:

public class TabulatorTest extends TestCase {
    //only tab --> fails
    public void testTab() throws Exception {
        String stringWithTab = new String();
        stringWithTab = "test\ttesttest";

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        YamlWriter yamlWriter = new YamlWriter(new OutputStreamWriter(out));
        yamlWriter.write(stringWithTab);
        yamlWriter.close();

        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
        YamlReader yamlReader = new YamlReader(new InputStreamReader(in));
        String got = yamlReader.read(String.class);

        assertEquals(stringWithTab, got);
    }
    // tab and \n -> ok
    public void testTabAndNL() throws Exception {

        String stringWithTab = new String();
        stringWithTab = "test\ttest\ntest";

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        YamlWriter yamlWriter = new YamlWriter(new OutputStreamWriter(out));
        yamlWriter.write(stringWithTab);
        yamlWriter.close();

        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
        YamlReader yamlReader = new YamlReader(new InputStreamReader(in));
        String got = yamlReader.read(String.class);

        assertEquals(stringWithTab, got);
    }
}

get map, can't get class


name: test1
host: http://127.0.0.1
preConditions:

  • name: request1
    url: localhost:3000/test1
    method: post
    contentType: json
    body: {"aa":"bbbbb","ccc":[{"ddd":"cccc"}]}
    headers: {'content-type':'application/json'}
  • name: request2
    url:
    method:
    contentType:
    body:
    headers: {'content-type':'application/json'}
    testCases:
  • name: test name
    url: localhost:3000/test2
    method: post
    body: {"aa":"${request1.ccc[0].ddd}"}
    headers: {'content-type':'application/json'}
    cookie: {"bbb":"cccc"}
    assert: {"contain":"somestring","jsonPath":"json.path.para:value"}
  • name: test name
    url: /api/path
    method: post
    body: {}
    headers: {}
    assert: {"contain":"somestring","jsonPath":"json.path.para:value"}
    package me.ele.api.it.model;

/**

  • Created by xuxiaozhi on 11/4/15.
    */
    public class PreCondition {
    private String name;
    private String url;
    private String method;
    private String body;
    private String headers;

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public String getUrl() {
    return url;
    }

    public void setUrl(String url) {
    this.url = url;
    }

    public String getMethod() {
    return method;
    }

    public void setMethod(String method) {
    this.method = method;
    }

    public String getBody() {
    return body;
    }

    public void setBody(String body) {
    this.body = body;
    }

    public String getHeaders() {
    return headers;
    }

    public void setHeaders(String headers) {
    this.headers = headers;
    }
    }

package me.ele.api.it.model;

import java.util.List;

/**

  • Created by xuxiaozhi on 11/4/15.
    */
    public class TestSuite {
    private String name;
    private String host;
    private List testCases;
    private List preConditions;

    public String getHost() {
    return host;
    }

    public void setHost(String host) {
    this.host = host;
    }

    public List getTestCases() {
    return testCases;
    }

    public void setTestCases(List testCases) {
    this.testCases = testCases;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public List getPreConditions() {
    return preConditions;
    }

    public void setPreConditions(List preConditions) {
    this.preConditions = preConditions;
    }
    }

puts(CaseUtil.getTestSuites("alpha", "/Users/kingangelTOT/yamltest").get(0).getPreConditions().get(0));

Exception in thread "main" java.lang.ClassCastException: java.util.HashMap cannot be cast to me.ele.api.it.model.PreCondition

Numbers in Maps serialized as Numbers, but deserialized as Strings

YamlWriter makes a difference between Strings and Numbers (as YAML specifies), but YamlReader just treats everything as a String. Is this expected?

Example:

Map<String, Object> m = new HashMap<>();
m.put("foo", 42);
m.put("bar", "42");

System.out.println("input:");
for (Entry<String, Object> entry : m.entrySet())
	System.out.println(entry.getKey() + ": " + entry.getValue() + " " + entry.getValue().getClass());
System.out.println();

StringWriter buffer = new StringWriter();
YamlWriter writer = new YamlWriter(buffer);
writer.write(m);
writer.close();
String yaml = buffer.toString();
System.out.println("YAML:");
System.out.println(yaml);

YamlReader reader = new YamlReader(yaml);
Map<String, Object> m2 = (Map<String, Object>)reader.read();

System.out.println("deserialized:");
for (Entry<String, Object> entry : m2.entrySet())
	System.out.println(entry.getKey() + ": " + entry.getValue() + " " + entry.getValue().getClass());

Output:

input:
bar: 42 class java.lang.String
foo: 42 class java.lang.Integer

YAML:
bar: '42'
foo: 42

deserialized:
bar: 42 class java.lang.String
foo: 42 class java.lang.String

Generics obstructs type parsing

From [email protected] on February 17, 2011 07:02:16

What steps will reproduce the problem?

  1. Generic interface
    public interface Key<ID>
    {
    ID getId();
    void setId(ID id);
    }
  2. Yaml Object
    public class Obj implements Key<Long>
    {
    public Obj() {}

    public Obj(Long id) { this.id = id; }

    Long id;

    public Long getId() {
    return id;
    }

    public void setId(Long id) {
    this.id = id;
    }
    }

  3. Test

    @-Test
    public void testYamlLong() throws Exception
    {
    new File("output.yml").delete();
    YamlWriter writer = new YamlWriter(new FileWriter("output.yml"));
    writer.getConfig().setClassTag("obj", Obj.class);
    writer.write(new Obj(1l));
    writer.close();

    YamlReader reader = new YamlReader(new FileReader("output.yml"));
    reader.getConfig().setClassTag("obj", Obj.class);
    Obj obj = reader.read(Obj.class);
    System.out.println(obj.getId());
    }


    What is the expected output? What do you see instead?
    Expected: 1
    Actual:
    com.esotericsoftware.yamlbeans.YamlReader$YamlReaderException: Line 2, column 0: Error setting property 'id' on class: au.com.rbp.job.domain.Obj
    at com.esotericsoftware.yamlbeans.YamlReader.readValueInternal(YamlReader.java:303)
    at com.esotericsoftware.yamlbeans.YamlReader.readValue(YamlReader.java:156)
    at com.esotericsoftware.yamlbeans.YamlReader.read(YamlReader.java:106)
    at com.esotericsoftware.yamlbeans.YamlReader.read(YamlReader.java:91)
    at au.com.rbp.job.domain.WorkEntryTest.testYamlLong1(WorkEntryTest.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.esotericsoftware.yamlbeans.Beans$MethodProperty.set(Beans.java:181)
    at com.esotericsoftware.yamlbeans.YamlReader.readValueInternal(YamlReader.java:300)
    ... 27 more
    Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
    at au.com.rbp.job.domain.Obj.setId(Obj.java:1)
    ... 33 more


    What version of the product are you using? On what operating system?
    1.0.5

    Please provide any additional information below.

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=10

underscore in package name cause YamlTokenizerError

I spent close to an hour debugging this issue, it would be nice if it were documented (or, alternatively, not happen...).

Here's how to reproduce it:

yaml like this:

mainobject:
  customobjectlist:
    - !com.mydomain.my_package.MyObject
       prop1: hello
       prop2: world

When I took the underscore out of the package name, it worked as expected

How to read and write recursive objects

From [email protected] on January 28, 2011 18:23:32

I have an Employee class with references to other Employees. There are 'manager' and 'deputy' properties (among many others). Unfortunately it is very common that a manager and his deputy refer to each other. It makes a circular relationship.
Currently YamlBeans fails with a StackOverflowException when I try to write such objects. Reading does not work either. (When I write anchors and aliases manually)
How should I read and write recursive structures ?

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=9

Support custom Enum valueOf() method

YamlReader uses Enum.valueOf() to convert Strings to Enumeration values.
Since you cannot override Enum.valueOf() and there is now way to influence its behavior, I suggest adding a SerializableEnum interface (or a better name if you know one).
This interface should define a method (perhaps fromString) that can be used alternatively to valueOf() (can have the same interface, I guess).
That way we can sanitize the input (for example, ignore casing) in a way that makes sense to our specific application.
The same can be done for the other way around (YamlWriter).

By the way, why I need this is because of our coding guidelines versus user experience.
Our coding guidelines indicates that the names within the enumeration should be uppercase, however I do not want to force my users to scream (write everything in caps) in the YAML file.

Also, if I would implement this and it would be approved via a pull request, how long would it take before it would be available on the Maven repository?

Skipping One Side of Bidrectional Links / Collection Handling

From [email protected] on March 30, 2010 09:35:59

I intend to use YamlBeans to automate data provisioning for integration
tests. The objects to be (de-)serialized are normally retrieved from a
database and often have bidirectional links:

Parent:

  • Collection children
  • void addToChildren(child)

Child:

  • Parent parent

Since fixing the serialization of cyclic references this structure can be
serialized however it is heavily anchored without any real need.

Secondly, current deserialization code assumes that collections can be just
created, added to and assigned to the object being deserialized. In my case
collections are normally read-only and can be only worked on using specific
addTo_, removeFrom_ methods (also making it easier to track changes).

The attached patch does two things:

  • Introduce a writeConfig parameter to skip immediate collection
    backreferences
  • Introduce pluggable handlers for collection deserialization
    (CollectionDeserializer)

It also includes new unit tests for the mentioned use cases...

Attachment: backreferences-collections.patch

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=2

Failure in Serializing simple Bean Properties

From [email protected] on June 05, 2013 17:06:08

class Yamltest {
public static class Test {
int a = 1000;
int cc = 20000;
long d = 300000;

    String xy = "POK";
    public Test() {
    }

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public int getCc() {
        return cc;
    }

    public void setCc(int cc) {
        this.cc = cc;
    }

    public long getD() {
        return d;
    }

    public void setD(long d) {
        this.d = d;
    }
}

public static void main(String arg[]) throws YamlException {
    YamlWriter writer = new YamlWriter(new OutputStreamWriter(System.out));
    writer.write(new Test());
    writer.close();
}

}

produces "Test {}". I'd expect it to write the int Bean Properties

Original issue: http://code.google.com/p/yamlbeans/issues/detail?id=16

ClassCastException ParameterizedTypeImpl cannot be cast to Class

Simple test case to reproduce is available here: https://github.com/olegs/yamlbeans/blob/master/test/com/esotericsoftware/yamlbeans/GenericsTest.java

Version 1.11 fails, while 1.08 works well in this case. As far as I can see the problem is located within the following commit: 98bb930#diff-3fc4c5fd5c3ad7273e6668dfdf14b79eR249

Stacktrace:

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class

	at com.esotericsoftware.yamlbeans.Beans$Property.getElementTypeFromGenerics(Beans.java:283)
	at com.esotericsoftware.yamlbeans.Beans$Property.<init>(Beans.java:272)
	at com.esotericsoftware.yamlbeans.Beans$FieldProperty.<init>(Beans.java:245)
	at com.esotericsoftware.yamlbeans.Beans.getProperties(Beans.java:153)
	at com.esotericsoftware.yamlbeans.YamlWriter.countObjectReferences(YamlWriter.java:308)
	at com.esotericsoftware.yamlbeans.YamlWriter.write(YamlWriter.java:77)
	at com.esotericsoftware.yamlbeans.GenericsTest.testComplexMap(GenericsTest.java:36)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.