OfbizRhinoContainer.java 3.92 KB
package com.brainfood.ofbiz.rhino;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.brainfood.rhino.Console;
import com.brainfood.rhino.HelperObjectProvider;
import com.brainfood.rhino.InContext;
import com.brainfood.rhino.Require;
import com.brainfood.rhino.RhinoContainer;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;

import org.ofbiz.base.location.FlexibleLocation;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.cache.UtilCache;

public class OfbizRhinoContainer extends RhinoContainer<OfbizRhinoContainer> {
    public static final String module = OfbizRhinoContainer.class.getName();
    private final File base;

    public OfbizRhinoContainer(File base) {
        super(new OfbizHelperObjectProvider());
        this.base = base;
    }

    public static class OfbizHelperObjectProvider implements HelperObjectProvider<OfbizRhinoContainer> {
        public Console newConsole(OfbizRhinoContainer container) {
            return new OfbizConsole(container);
        }
    }

    public static class OfbizConsole extends Console {
        public OfbizConsole(OfbizRhinoContainer container) {
            super(container);
        }

        @Override
        public String getClassName() {
            return "OfbizConsole";
        }

        private static void addOneLogItem(StringBuilder format, List<Object> logArgs, Object logItem) {
            if (logItem == null) {
                format.append("%s");
                logArgs.add(null);
            } else {
                logArgs.add(Context.toString(logItem));
                logArgs.add(logItem.getClass().getName());
                format.append("%s<%s>");
            }
        }

        public void log(Context cx, Object[] args, Function funObj) {
            StringBuilder format = new StringBuilder();
            List<Object> logArgs = new ArrayList(args.length * 2 + 1);
            format.append(':');
            for (int i = 0; i < args.length; i++) {
                if (i != 0) {
                    format.append(", ");
                }
                addOneLogItem(format, logArgs, args[i]);
            }
            Debug.logInfo(format.toString(), module, logArgs.toArray(new Object[logArgs.size()]));
        }
    }

    public void print(Context cx, Scriptable thisObj, Object[] args, Function funObj) {
        Debug.logInfo("print:%s", module, args);
    }

    public void processSource(Context cx, Scriptable thisObj, String filename) throws FileNotFoundException, IOException {
        while (filename.length() > 0 && filename.charAt(0) == '/') {
            filename = filename.substring(1);
        }
        cx.evaluateReader(thisObj, new FileReader(new File(base, filename)), filename, 1, null);
    }

    private static final UtilCache<String, Require> cache = UtilCache.getOrCreateUtilCache("OfbizRhinoContainer.Require", 0, 5, 10000, false, false);

    public static Require getOrCreateRequire(String appLocation, String configPath, String... deps) throws Exception {
        Require require = cache.get(appLocation);
        if (require == null) {
            File base = new File(FlexibleLocation.resolveLocation(appLocation).getPath());
            OfbizRhinoContainer container = new OfbizRhinoContainer(base);
            File rLocation = new File(FlexibleLocation.resolveLocation("component://ofbiz-rhino/lib/r.js").getPath());
            require = new Require(container, rLocation, configPath);
            for (String dep: deps) {
                require.require(dep);
            }
            require = cache.putIfAbsentAndGet(appLocation, require);
        }
        return require;
    }
}