Package org.jruby.clojure

Source Code of org.jruby.clojure.ClojureLibrary$ClojureDosync

package org.jruby.clojure;

import clojure.lang.IPersistentVector;
import clojure.lang.LockingTransaction;
import clojure.lang.PersistentVector;
import clojure.lang.Ref;
import java.io.IOException;
import java.util.concurrent.Callable;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.Block;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.load.Library;

public class ClojureLibrary implements Library{
    public void load(Ruby runtime, boolean wrap) throws IOException {
        RubyModule cljModule = runtime.defineModule("Clojure");
        runtime.defineClassUnder("Object", runtime.getObject(), new ClojureObjectAllocator(), cljModule);

        runtime.getKernel().defineAnnotatedMethods(ClojureDosync.class);
    }

    public static class ClojureObjectAllocator implements ObjectAllocator {
        public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
            return new ClojureObject(runtime, klazz);
        }
    }

    public static class ClojureObject extends RubyObject {
        public ClojureObject(Ruby runtime, RubyClass klass) {
            super(runtime, klass);
            try {
                variableTable = new Ref(PersistentVector.EMPTY);
            } catch (Exception e) {
                throw runtime.newConcurrencyError(e.getLocalizedMessage());
            }
        }

        @Override
        public Object getVariable(int index) {
            return ((IPersistentVector)variableTable.deref()).nth(index);
        }

        @Override
        public void setVariable(int index, Object value) {
            try {
                variableTable.set(((IPersistentVector)variableTable.deref()).assocN(index, value));
            } catch (IllegalStateException ise) {
                throw getRuntime().newConcurrencyError(ise.getLocalizedMessage());
            }
        }

        private final Ref variableTable;
    }

    public static class ClojureDosync {
        @JRubyMethod
        public static IRubyObject dosync(final ThreadContext context, final IRubyObject self, final Block block) {
            final Ruby ruby = context.getRuntime();
            try {
                return (IRubyObject)LockingTransaction.runInTransaction(new Callable() {
                    public Object call() throws Exception {
                        // re-get transaction in case this gets run in different threads
                        return block.call(ruby.getCurrentContext());
                    }
                });
            } catch (Exception e) {
                throw ruby.newConcurrencyError(e.getLocalizedMessage());
            }
        }
    }
}
TOP

Related Classes of org.jruby.clojure.ClojureLibrary$ClojureDosync

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.