org.jruby.ext.jvyaml.JRubyConstructor.java Source code

Java tutorial

Introduction

Here is the source code for org.jruby.ext.jvyaml.JRubyConstructor.java

Source

/*
 * See LICENSE file in distribution for copyright and licensing information.
 */
package org.jruby.ext.jvyaml;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import java.util.regex.Pattern;

import org.jvyamlb.Composer;
import org.jvyamlb.Constructor;
import org.jvyamlb.exceptions.ConstructorException;
import org.jvyamlb.ConstructorImpl;
import org.jvyamlb.SafeConstructorImpl;
import org.jvyamlb.Scanner;
import org.jvyamlb.ScannerImpl;
import org.jvyamlb.ComposerImpl;
import org.jvyamlb.ParserImpl;
import org.jvyamlb.ResolverImpl;
import org.jvyamlb.YAML;

import org.jvyamlb.nodes.Node;
import org.jvyamlb.nodes.LinkNode;

import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
import org.jruby.RubyHash;
import org.jruby.RubyString;
import org.jruby.RubyStruct;
import org.jruby.RubyRange;
import org.jruby.javasupport.util.RuntimeHelpers;
import org.jruby.runtime.Block;
import org.jruby.runtime.builtin.IRubyObject;

import org.jruby.util.ByteList;

import org.joda.time.DateTime;
import org.jruby.runtime.ThreadContext;
import org.jvyamlb.nodes.ScalarNode;

/**
 * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
 */
public class JRubyConstructor extends ConstructorImpl {
    private final static Map yamlConstructors = new HashMap();
    private final static Map yamlMultiConstructors = new HashMap();
    private final static Map yamlMultiRegexps = new HashMap();

    public YamlConstructor getYamlConstructor(final Object key) {
        return (YamlConstructor) yamlConstructors.get(key);
    }

    public YamlMultiConstructor getYamlMultiConstructor(final Object key) {
        return (YamlMultiConstructor) yamlMultiConstructors.get(key);
    }

    public Pattern getYamlMultiRegexp(final Object key) {
        return (Pattern) yamlMultiRegexps.get(key);
    }

    public Set getYamlMultiRegexps() {
        return yamlMultiRegexps.keySet();
    }

    public static void addConstructor(final String tag, final YamlConstructor ctor) {
        yamlConstructors.put(tag, ctor);
    }

    public static void addMultiConstructor(final String tagPrefix, final YamlMultiConstructor ctor) {
        yamlMultiConstructors.put(tagPrefix, ctor);
        yamlMultiRegexps.put(tagPrefix, Pattern.compile("^" + tagPrefix));
    }

    private final Ruby runtime;

    public JRubyConstructor(final IRubyObject receiver, final Composer composer) {
        this(receiver.getRuntime(), composer);
    }

    public JRubyConstructor(final Ruby runtime, final Composer composer) {
        super(composer);
        this.runtime = runtime;
    }

    public Object constructRubyScalar(final Node node) {
        if (node instanceof org.jvyamlb.nodes.ScalarNode) {
            ByteList sc = (ByteList) super.constructScalar(node);
            if (sc.length() > 1 && sc.charAt(0) == ':' && ((org.jvyamlb.nodes.ScalarNode) node).getStyle() == 0) {
                int first = sc.get(1);
                int last = sc.get(sc.realSize - 1);
                if ((first == '"' && last == '"') || (first == '\'' && last == '\'')) {

                    Scanner scn = new ScannerImpl(sc.makeShared(1, sc.realSize - 1));
                    Constructor ctor = new JRubyConstructor(runtime, new ComposerImpl(
                            new ParserImpl(scn, YAML.config().version("1.0")), new ResolverImpl()));
                    ctor.checkData();
                    return ((RubyString) ctor.getData()).intern();
                }

                return runtime.newSymbol(new String(sc.bytes, sc.begin + 1, sc.realSize - 1));
            }

            return RubyString.newString(runtime, (ByteList) super.constructScalar(node));
        } else {
            // Assume it's a mapping node

            Map val = (Map) (constructMapping(node));
            RubyString str = (RubyString) val.get(runtime.newString("str"));

            Map props = new HashMap();
            for (Iterator iter = val.entrySet().iterator(); iter.hasNext();) {
                Map.Entry em = (Map.Entry) iter.next();
                if (em.getKey().toString().startsWith("@")) {
                    props.put(em.getKey(), em.getValue());
                    iter.remove();
                }
            }
            for (Iterator iter = props.entrySet().iterator(); iter.hasNext();) {
                Map.Entry em = (Map.Entry) iter.next();
                str.instance_variable_set((IRubyObject) em.getKey(), (IRubyObject) em.getValue());
            }

            return str;
        }
    }

    public Object constructPrivateType(final Node node) {
        Object val = null;
        if (node.getValue() instanceof Map) {
            val = constructRubyMapping(node);
        } else if (node.getValue() instanceof List) {
            val = constructRubySequence(node);
        } else {
            val = constructRubyScalar(node);
        }
        return RuntimeHelpers.invoke(runtime.getCurrentContext(),
                runtime.fastGetModule("JvYAML").fastGetConstant("PrivateType"), "new",
                runtime.newString(node.getTag()), (IRubyObject) val);
    }

    public Object constructRubySequence(final Node node) {
        final RubyArray arr = runtime.newArray();
        List l = (List) super.constructSequence(node);
        doRecursionFix(node, arr);
        int i = 0;
        for (Iterator iter = l.iterator(); iter.hasNext(); i++) {
            Object oo = iter.next();
            if (oo instanceof LinkNode) {
                arr.append(runtime.getNil());
                final IRubyObject ix = runtime.newFixnum(i);
                addFixer((Node) (((LinkNode) oo).getValue()), new RecursiveFixer() {
                    public void replace(Node node, Object real) {
                        arr.aset(ix, (IRubyObject) real);
                    }
                });
            } else {
                arr.append((IRubyObject) oo);
            }
        }
        return arr;
    }

    public Object constructRubyMapping(final Node node) {
        RubyHash h1 = RubyHash.newHash(runtime, (Map) super.constructMapping(node), runtime.getNil());
        return h1;
    }

    public Object constructRubyPairs(final Node node) {
        return runtime.newArray((List) super.constructPairs(node));
    }

    public static Object constructYamlNull(final Constructor ctor, final Node node) {
        return ((JRubyConstructor) ctor).runtime.getNil();
    }

    public static Object constructYamlBool(final Constructor ctor, final Node node) {
        return SafeConstructorImpl.constructYamlBool(ctor, node) == Boolean.TRUE
                ? ((JRubyConstructor) ctor).runtime.getTrue()
                : ((JRubyConstructor) ctor).runtime.getFalse();
    }

    public static Object constructYamlOmap(final Constructor ctor, final Node node) {
        Ruby runtime = ((JRubyConstructor) ctor).runtime;
        RubyArray arr = (RubyArray) (runtime.fastGetModule("JvYAML").fastGetConstant("Omap")
                .callMethod(runtime.getCurrentContext(), "new"));
        List l = (List) ctor.constructSequence(node);
        ctor.doRecursionFix(node, arr);
        for (Iterator iter = l.iterator(); iter.hasNext();) {
            IRubyObject v = (IRubyObject) iter.next();
            if (v instanceof RubyHash) {
                arr.concat(((RubyHash) v).to_a());
            } else {
                throw new ConstructorException(null, "Invalid !omap entry: " + l, null);
            }
        }
        return arr;
    }

    public static Object constructYamlPairs(final Constructor ctor, final Node node) {
        return ((JRubyConstructor) ctor).constructRubyPairs(node);
    }

    public static Object constructYamlSet(final Constructor ctor, final Node node) {
        return SafeConstructorImpl.constructYamlSet(ctor, node);
    }

    public static Object constructYamlStr(final Constructor ctor, final Node node) {
        final Object _str = ((JRubyConstructor) ctor).constructRubyScalar(node);
        if (_str instanceof RubyString) {
            final RubyString str = (RubyString) _str;
            if (node instanceof ScalarNode) {
                return (str.getByteList().realSize == 0 && ((ScalarNode) node).getStyle() == 0)
                        ? str.getRuntime().getNil()
                        : str;
            }
        }
        return _str;
    }

    public static Object constructYamlSeq(final Constructor ctor, final Node node) {
        return ((JRubyConstructor) ctor).constructRubySequence(node);
    }

    public static Object constructYamlMap(final Constructor ctor, final Node node) {
        return ((JRubyConstructor) ctor).constructRubyMapping(node);
    }

    public static Object constructUndefined(final Constructor ctor, final Node node) {
        throw new ConstructorException(null, "could not determine a constructor for the tag " + node.getTag(),
                null);
    }

    public static Object constructYamlTimestamp(final Constructor ctor, final Node node) {
        Object[] value = (Object[]) SafeConstructorImpl.constructYamlTimestamp(ctor, node);
        DateTime dt = (DateTime) (value[0]);
        org.jruby.RubyTime rt = org.jruby.RubyTime.newTime(((JRubyConstructor) ctor).runtime, dt);
        rt.setUSec(((Integer) value[1]));
        return rt;
    }

    public static Object constructYamlTimestampYMD(final Constructor ctor, final Node node) {
        DateTime dt = (DateTime) (((Object[]) SafeConstructorImpl.constructYamlTimestamp(ctor, node))[0]);
        Ruby runtime = ((JRubyConstructor) ctor).runtime;
        return RuntimeHelpers.invoke(runtime.getCurrentContext(), runtime.fastGetClass("Date"), "new",
                runtime.newFixnum(dt.getYear()), runtime.newFixnum(dt.getMonthOfYear()),
                runtime.newFixnum(dt.getDayOfMonth()));
    }

    public static Object constructYamlInt(final Constructor ctor, final Node node) {
        return org.jruby.javasupport.JavaUtil.convertJavaToRuby(((JRubyConstructor) ctor).runtime,
                SafeConstructorImpl.constructYamlInt(ctor, node));
    }

    public static Object constructYamlFloat(final Constructor ctor, final Node node) {
        return ((JRubyConstructor) ctor).runtime
                .newFloat(((Double) SafeConstructorImpl.constructYamlFloat(ctor, node)).doubleValue());
    }

    public static Object constructYamlBinary(final Constructor ctor, final Node node) {
        Object b = SafeConstructorImpl.constructYamlBinary(ctor, node);
        if (b instanceof byte[]) {
            return RubyString.newString(((JRubyConstructor) ctor).runtime, new ByteList((byte[]) b, false));
        } else {
            return ((JRubyConstructor) ctor).runtime.newString((String) b);
        }
    }

    public static Object constructJava(final Constructor ctor, final String pref, final Node node) {
        return SafeConstructorImpl.constructJava(ctor, pref, node);
    }

    public static Object constructRubyException(final Constructor ctor, final String tag, final Node node) {
        final Ruby runtime = ((JRubyConstructor) ctor).runtime;
        RubyModule objClass = runtime.getObject();
        if (tag != null) {
            final String[] nms = tag.split("::");
            try {
                for (int i = 0, j = nms.length; i < j; i++) {
                    objClass = (RubyModule) objClass.getConstant(nms[i]);
                }
            } catch (Exception e) {
                // No constant available, so we'll fall back on YAML::Object
                objClass = (RubyClass) runtime.fastGetModule("JvYAML").fastGetConstant("Object");
                final RubyHash vars = (RubyHash) (((JRubyConstructor) ctor).constructRubyMapping(node));
                return RuntimeHelpers.invoke(runtime.getCurrentContext(), objClass, "new", runtime.newString(tag),
                        vars);
            }
        }
        final RubyClass theCls = (RubyClass) objClass;
        final RubyObject oo = (RubyObject) theCls.getAllocator().allocate(runtime, theCls);
        final Map vars = (Map) (ctor.constructMapping(node));
        ctor.doRecursionFix(node, oo);
        for (final Iterator<Map.Entry> iter = vars.entrySet().iterator(); iter.hasNext();) {
            Map.Entry entry = iter.next();
            final IRubyObject key = (IRubyObject) entry.getKey();
            final Object val = vars.get(key);
            if (val instanceof LinkNode) {
                final String KEY = "@" + key.toString();
                ctor.addFixer((Node) (((LinkNode) val).getValue()), new RecursiveFixer() {
                    public void replace(Node node, Object real) {
                        oo.setInstanceVariable(KEY, (IRubyObject) real);
                    }
                });
            } else {
                oo.setInstanceVariable("@" + key.toString(), (IRubyObject) val);
            }
        }
        return oo;
    }

    public static Object constructRubyStruct(final Constructor ctor, final String tag, final Node node) {
        final Ruby runtime = ((JRubyConstructor) ctor).runtime;
        RubyModule sClass = runtime.fastGetModule("Struct");
        RubyClass struct_type;
        String[] nms = tag.split("::");
        for (int i = 0, j = nms.length; i < j && sClass != null; i++) {
            sClass = (RubyModule) sClass.getConstant(nms[i]);
        }

        Map props = new HashMap();
        Map val = (Map) (ctor.constructMapping(node));
        for (Iterator iter = val.entrySet().iterator(); iter.hasNext();) {
            Map.Entry em = (Map.Entry) iter.next();
            if (em.getKey().toString().startsWith("@")) {
                props.put(em.getKey(), em.getValue());
                iter.remove();
            }
        }

        // If no such struct exists...
        if (sClass == null) {
            IRubyObject[] params = new IRubyObject[val.size() + 1];
            params[0] = runtime.newString(tag);
            int i = 1;
            for (Iterator iter = val.entrySet().iterator(); iter.hasNext(); i++) {
                Map.Entry em = (Map.Entry) iter.next();
                params[i] = ((RubyString) em.getKey()).intern();
            }
            struct_type = RubyStruct.newInstance(runtime.fastGetModule("Struct"), params, Block.NULL_BLOCK);
        } else {
            struct_type = (RubyClass) sClass;
        }
        IRubyObject st = struct_type.callMethod(runtime.getCurrentContext(), "new");
        RubyArray members = RubyStruct.members(struct_type, Block.NULL_BLOCK);
        for (int i = 0, j = members.size(); i < j; i++) {
            IRubyObject m = members.eltInternal(i);
            st.callMethod(runtime.getCurrentContext(), m.toString() + "=", (IRubyObject) val.get(m));
        }
        for (Iterator iter = props.entrySet().iterator(); iter.hasNext();) {
            Map.Entry em = (Map.Entry) iter.next();
            ((RubyObject) st).instance_variable_set((IRubyObject) em.getKey(), (IRubyObject) em.getValue());
        }
        return st;
    }

    public static Object constructRuby(final Constructor ctor, final RubyClass theCls, final Node node) {
        final Ruby runtime = ((JRubyConstructor) ctor).runtime;
        if (theCls.respondsTo("jvyaml_new")) {
            final RubyHash vars = (RubyHash) (((JRubyConstructor) ctor).constructRubyMapping(node));
            return RuntimeHelpers.invoke(runtime.getCurrentContext(), theCls, "jvyaml_new", theCls,
                    runtime.newString(node.getTag()), vars);
        } else {
            final RubyObject oo = (RubyObject) theCls.getAllocator().allocate(runtime, theCls);
            if (oo.respondsTo("jvyaml_initialize")) {
                RubyHash vars = (RubyHash) (((JRubyConstructor) ctor).constructRubyMapping(node));
                RuntimeHelpers.invoke(runtime.getCurrentContext(), oo, "jvyaml_initialize",
                        runtime.newString(node.getTag()), vars);
            } else {
                final Map vars = (Map) (ctor.constructMapping(node));
                ctor.doRecursionFix(node, oo);
                for (final Iterator iter = vars.keySet().iterator(); iter.hasNext();) {
                    final IRubyObject key = (IRubyObject) iter.next();
                    final Object val = vars.get(key);
                    if (val instanceof LinkNode) {
                        final String KEY = "@" + key.toString();
                        ctor.addFixer((Node) (((LinkNode) val).getValue()), new RecursiveFixer() {
                            public void replace(Node node, Object real) {
                                oo.setInstanceVariable(KEY, (IRubyObject) real);
                            }
                        });
                    } else {
                        oo.setInstanceVariable("@" + key.toString(), (IRubyObject) val);
                    }
                }
            }
            return oo;
        }
    }

    public static Object constructRuby(final Constructor ctor, final String tag, final Node node) {
        final Ruby runtime = ((JRubyConstructor) ctor).runtime;
        RubyModule objClass = runtime.getObject();
        if (tag != null) {
            final String[] nms = tag.split("::");
            try {
                for (int i = 0, j = nms.length; i < j; i++) {
                    objClass = (RubyModule) objClass.getConstant(nms[i]);
                }
            } catch (Exception e) {
                // No constant available, so we'll fall back on YAML::Object
                objClass = (RubyClass) runtime.fastGetModule("JvYAML").fastGetConstant("Object");
                final RubyHash vars = (RubyHash) (((JRubyConstructor) ctor).constructRubyMapping(node));
                return RuntimeHelpers.invoke(runtime.getCurrentContext(), objClass, "new", runtime.newString(tag),
                        vars);
            }
        }
        final RubyClass theCls = (RubyClass) objClass;
        return constructRuby(ctor, theCls, node);
    }

    public static Object constructRubyRegexp(final Constructor ctor, final Node node) {
        final Ruby runtime = ((JRubyConstructor) ctor).runtime;
        String s1 = ctor.constructScalar(node).toString();
        // This should be fixed in some way
        return runtime.evalScriptlet(s1);
    }

    public static Object constructRubyRange(final Constructor ctor, final Node node) {
        final Ruby runtime = ((JRubyConstructor) ctor).runtime;
        ThreadContext context = runtime.getCurrentContext();
        if (node instanceof org.jvyamlb.nodes.ScalarNode) {
            String s1 = ctor.constructScalar(node).toString();
            String first;
            String second;
            boolean exc = false;
            int ix = -1;
            if ((ix = s1.indexOf("...")) != -1) {
                first = s1.substring(0, ix);
                second = s1.substring(ix + 3);
                exc = true;
            } else {
                ix = s1.indexOf("..");
                first = s1.substring(0, ix);
                second = s1.substring(ix + 2);
            }
            IRubyObject fist = runtime.fastGetModule("JvYAML").callMethod(context, "load",
                    runtime.newString(first));
            IRubyObject sic = runtime.fastGetModule("JvYAML").callMethod(context, "load",
                    runtime.newString(second));
            return RubyRange.newRange(runtime, context, fist, sic, exc);
        } else {
            final Map vars = (Map) (ctor.constructMapping(node));
            IRubyObject beg = (IRubyObject) vars.get(runtime.newString("begin"));
            IRubyObject end = (IRubyObject) vars.get(runtime.newString("end"));
            boolean excl = ((IRubyObject) vars.get(runtime.newString("excl"))).isTrue();
            return RubyRange.newRange(runtime, context, beg, end, excl);
        }
    }

    public static Object findAndCreateFromCustomTagging(final Constructor ctor, final Node node) {
        String tag = node.getTag();
        Ruby runtime = ((JRubyConstructor) ctor).runtime;
        IRubyObject _cl = runtime.fastGetModule("JvYAML").callMethod(runtime.getCurrentContext(), "tagged_classes")
                .callMethod(runtime.getCurrentContext(), "[]", runtime.newString(tag));
        if (!(_cl instanceof RubyClass)) {
            return null;
        }
        RubyClass clazz = (RubyClass) _cl;
        if (clazz != null && !clazz.isNil()) {
            return constructRuby(ctor, clazz, node);
        }
        return null;
    }

    public static Object constructRubyInt(final Constructor ctor, final String tag, final Node node) {
        final Ruby runtime = ((JRubyConstructor) ctor).runtime;
        RubyModule objClass = runtime.getObject();
        if (tag != null) {
            final String[] nms = tag.split("::");
            for (int i = 0, j = nms.length; i < j; i++) {
                objClass = (RubyModule) objClass.getConstant(nms[i]);
            }
        }
        final RubyClass theCls = (RubyClass) objClass;
        final RubyObject oo = (RubyObject) theCls.getAllocator().allocate(runtime, theCls);
        final IRubyObject val = (IRubyObject) constructYamlInt(ctor, node);
        oo.callInit(new IRubyObject[] { val }, org.jruby.runtime.Block.NULL_BLOCK);
        return oo;
    }

    public static Object constructRubyString(final Constructor ctor, final String tag, final Node node) {
        final Ruby runtime = ((JRubyConstructor) ctor).runtime;
        RubyModule objClass = runtime.getObject();
        if (tag != null) {
            final String[] nms = tag.split("::");
            for (int i = 0, j = nms.length; i < j; i++) {
                objClass = (RubyModule) objClass.getConstant(nms[i]);
            }
        }
        final RubyClass theCls = (RubyClass) objClass;
        final RubyObject oo = (RubyObject) theCls.getAllocator().allocate(runtime, theCls);
        final IRubyObject val = (IRubyObject) constructYamlStr(ctor, node);
        oo.callInit(new IRubyObject[] { val }, org.jruby.runtime.Block.NULL_BLOCK);
        return oo;
    }

    public static Object constructRubyMap(final Constructor ctor, final String tag, final Node node) {
        final Ruby runtime = ((JRubyConstructor) ctor).runtime;
        RubyModule objClass = runtime.getObject();
        if (tag != null) {
            final String[] nms = tag.split("::");
            for (int i = 0, j = nms.length; i < j; i++) {
                objClass = (RubyModule) objClass.getConstant(nms[i]);
            }
        }
        final RubyClass theCls = (RubyClass) objClass;
        final RubyObject oo = (RubyObject) theCls.getAllocator().allocate(runtime, theCls);
        final Map vars = (Map) (ctor.constructMapping(node));
        for (final Iterator iter = vars.keySet().iterator(); iter.hasNext();) {
            final IRubyObject key = (IRubyObject) iter.next();
            RuntimeHelpers.invoke(oo.getRuntime().getCurrentContext(), oo, "[]=", key, (IRubyObject) vars.get(key));
        }
        return oo;
    }

    public static Object constructRubySequence(final Constructor ctor, final String tag, final Node node) {
        final Ruby runtime = ((JRubyConstructor) ctor).runtime;
        RubyModule objClass = runtime.getObject();
        if (tag != null) {
            final String[] nms = tag.split("::");
            for (int i = 0, j = nms.length; i < j; i++) {
                objClass = (RubyModule) objClass.getConstant(nms[i]);
            }
        }
        final RubyClass theCls = (RubyClass) objClass;
        final RubyObject oo = (RubyObject) theCls.getAllocator().allocate(runtime, theCls);
        final List vars = (List) (ctor.constructSequence(node));
        for (final Iterator iter = vars.iterator(); iter.hasNext();) {
            RuntimeHelpers.invoke(oo.getRuntime().getCurrentContext(), oo, "<<", (IRubyObject) iter.next());
        }
        return oo;
    }

    static {
        addConstructor("tag:yaml.org,2002:null", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlNull(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:bool", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlBool(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:omap", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlOmap(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:pairs", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlPairs(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:set", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlSet(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:int", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlInt(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:float", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlFloat(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:timestamp", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                java.util.regex.Matcher match = SafeConstructorImpl.YMD_REGEXP.matcher(node.getValue().toString());
                if (match.matches()) {
                    return constructYamlTimestampYMD(self, node);
                } else {
                    return constructYamlTimestamp(self, node);
                }
            }
        });
        addConstructor("tag:yaml.org,2002:timestamp#ymd", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlTimestampYMD(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:str", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlStr(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:binary", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlBinary(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:seq", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlSeq(self, node);
            }
        });
        addConstructor("tag:yaml.org,2002:map", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructYamlMap(self, node);
            }
        });
        addConstructor("tag:ruby.yaml.org,2002:range", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructRubyRange(self, node);
            }
        });
        addConstructor("tag:ruby.yaml.org,2002:regexp", new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                return constructRubyRegexp(self, node);
            }
        });
        addConstructor(null, new YamlConstructor() {
            public Object call(final Constructor self, final Node node) {
                Object v1 = findAndCreateFromCustomTagging(self, node);
                if (null != v1) {
                    return v1;
                }
                return self.constructPrivateType(node);
            }
        });
        addMultiConstructor("tag:yaml.org,2002:map:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRubyMap(self, pref, node);
            }
        });
        addMultiConstructor("tag:ruby.yaml.org,2002:hash:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRubyMap(self, pref, node);
            }
        });
        addMultiConstructor("tag:yaml.org,2002:int:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRubyInt(self, pref, node);
            }
        });
        addMultiConstructor("tag:yaml.org,2002:seq:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRubySequence(self, pref, node);
            }
        });
        addMultiConstructor("tag:ruby.yaml.org,2002:array:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRubySequence(self, pref, node);
            }
        });
        addMultiConstructor("tag:yaml.org,2002:str:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRubyString(self, pref, node);
            }
        });
        addMultiConstructor("tag:ruby.yaml.org,2002:string:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRubyString(self, pref, node);
            }
        });
        addMultiConstructor("tag:yaml.org,2002:ruby/object:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRuby(self, pref, node);
            }
        });
        addMultiConstructor("tag:ruby.yaml.org,2002:object:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRuby(self, pref, node);
            }
        });
        addMultiConstructor("tag:yaml.org,2002:java/object:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructJava(self, pref, node);
            }
        });
        addMultiConstructor("tag:java.yaml.org,2002:object:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructJava(self, pref, node);
            }
        });
        addMultiConstructor("tag:ruby.yaml.org,2002:struct:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRubyStruct(self, pref, node);
            }
        });
        addMultiConstructor("tag:ruby.yaml.org,2002:exception:", new YamlMultiConstructor() {
            public Object call(final Constructor self, final String pref, final Node node) {
                return constructRuby(self, pref, node);
            }
        });
    }
}// JRubyConstructor