/**
 * Copyright (c) 2008-2011, http://www.snakeyaml.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package examples;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;

import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.NodeId;

/**
 * Example for http://code.google.com/p/snakeyaml/wiki/howto
 */
public class SelectiveConstructorTest extends TestCase {
    class SelectiveConstructor extends Constructor {
        public SelectiveConstructor() {
            // define a custom way to create a mapping node
            yamlClassConstructors.put(NodeId.mapping, new MyPersistentObjectConstruct());
        }

        class MyPersistentObjectConstruct extends Constructor.ConstructMapping {
            @Override
            protected Object constructJavaBean2ndStep(MappingNode node, Object object) {
                Class type = node.getType();
                if (type.equals(MyPersistentObject.class)) {
                    // create a map
                    Map map = constructMapping(node);
                    String id = (String) map.get("id");
                    return new MyPersistentObject(id, 17);
                } else {
                    // create JavaBean
                    return super.constructJavaBean2ndStep(node, object);
                }
            }
        }
    }

    public void testConstructor() throws IOException {
        Yaml yaml = new Yaml(new SelectiveConstructor());
        List<?> data = (List<?>) yaml
                .load("- 1\n- 2\n- !!examples.MyPersistentObject {amount: 222, id: persistent}");
        // System.out.println(data);
        assertEquals(3, data.size());
        MyPersistentObject myObject = (MyPersistentObject) data.get(2);
        assertEquals(17, myObject.getAmount());
        assertEquals("persistent", myObject.getId());
    }
}

class MyPersistentObject {
    private String id;
    private int amount;

    public MyPersistentObject() {
        this.id = "noid";
        this.amount = 222;
    }

    public MyPersistentObject(String id, int amount) {
        this.id = id;
        this.amount = amount;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    @Override
    public String toString() {
        return "MyPersistentObject [id=" + id + ", amount=" + amount + "]";
    }
}
