ilmoeuro / snakeyaml

Automatically exported from code.google.com/p/snakeyaml
0 stars 0 forks source link

Documentation for Custom document doesn't compile #44

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
In the manual:

            String val = (String) constructScalar(node);

doesn't compile, since the method doesn't work with a node.

Also, the test case for Dice doesn't seem to be working (since nodes does
not contain a Tag).

I can't get a Custom Document writer to work. Is there other working
examples other than the Dice?

Original issue reported on code.google.com by ptar...@gmail.com on 15 Jan 2010 at 7:10

GoogleCodeExporter commented 9 years ago
Can you please provide more information ? 
What does not compile ? Try to compile SnakeYAML with 'mvn clean compile'.
If you cannot compile your custom code can you please attach the complete 
source file ?

The documentation contains information about the last official release - 1.5.
But in the Mercurial repository the Tag class is used instead of String.
(see 
http://groups.google.com/group/snakeyaml-core/browse_thread/thread/ebb40fc28ea19
299)

Search for the Dice example in the source if you use the latest source.

Original comment by aso...@gmail.com on 15 Jan 2010 at 3:18

GoogleCodeExporter commented 9 years ago
Thank you for the source link. This code works:

import java.io.BufferedWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.UUID;

import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.representer.Represent;
import org.yaml.snakeyaml.representer.Representer;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.Loader;
import org.yaml.snakeyaml.Dumper;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.constructor.AbstractConstruct;

public class Convert {
    public static void main(String args[]) {
        UUID uuid = UUID.randomUUID();

        StringWriter sw = new StringWriter();
        Writer writer = new BufferedWriter(sw);

        Yaml yaml = new Yaml();
        yaml.dump(uuid, writer);
        System.out.println("No Custom Class");
        System.out.println(sw.toString());

        sw = new StringWriter();
        writer = new BufferedWriter(sw);

        yaml = new Yaml(new Loader(new UUIDConstructor()), new Dumper(new
UUIDRepresenter(), new DumperOptions()));
        yaml.dump(uuid, writer);
        System.out.println("Custom Class");
        System.out.println(sw.toString());
    }

    public static class UUIDConstructor extends Constructor {
        public UUIDConstructor() {
            this.yamlConstructors.put("!uuid", new ConstructUUID());
        }

        private class ConstructUUID extends AbstractConstruct {
            public Object construct(Node node) {
                String val = (String) constructScalar((ScalarNode) node);
                return UUID.fromString(val);
            }
        }
    }

    public static class UUIDRepresenter extends Representer {
        public UUIDRepresenter() {
            this.representers.put(UUID.class, new RepresentUUID());
        }

        private class RepresentUUID implements Represent {
            public Node representData(Object data) {
                UUID uuid = (UUID) data;
                String value = uuid.toString();
                return representScalar("!uuid", value);
            }
        }
    }
}

 javac -classpath snakeyaml-1.5.jar Convert.java && java -classpath
snakeyaml-1.5.jar:. Convert
No Custom Class
!!java.util.UUID {leastSignificantBits: -8464675218539248493, 
mostSignificantBits:
-1320767580297608855}

Custom Class
!uuid 'edabb0e2-2982-4169-8a87-6ebc8bea8493'

My problem was having to case (ScalarNode). Why do you have to cast? Why 
doesn't the
method signature just take that type of Node?

Original comment by ptar...@gmail.com on 20 Jan 2010 at 9:35

GoogleCodeExporter commented 9 years ago
Do you mean why constructScalar() method requires a ScalarNode argument ?
To avoid a runtime error when a scalar is expected to be created form a mapping 
node.

For instance, in your YAML document you may put "!uuid" tag for a sequence (or 
mapping) node. Then you will get an exception in your code when you cast and 
not in 
the SnakeYAML core. It helps to establish a contract and divide 
responsibilities. In 
your code you may always check the class before you cast to be sure there is no 
surprise.

May we close the issue ?

Original comment by py4fun@gmail.com on 20 Jan 2010 at 10:34

GoogleCodeExporter commented 9 years ago
Understood. I was expecting me to define a method that works on scalars and 
have 
methods in the parent class that threw exceptions when they were called (and 
not 
overridden).

Please close. Open a new bug if you like my design recommendation.

Original comment by ptar...@gmail.com on 20 Jan 2010 at 10:44

GoogleCodeExporter commented 9 years ago

Original comment by aso...@gmail.com on 20 Jan 2010 at 1:40