com.zotoh.maedr.etc.CmdAppOps.java Source code

Java tutorial

Introduction

Here is the source code for com.zotoh.maedr.etc.CmdAppOps.java

Source

/*??
 * COPYRIGHT (C) 2011 CHERIMOIA LLC. ALL RIGHTS RESERVED.
 *
 * THIS IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR
 * MODIFY IT UNDER THE TERMS OF THE APACHE LICENSE, 
 * VERSION 2.0 (THE "LICENSE").
 *
 * THIS LIBRARY IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
 * BUT WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *   
 * SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS 
 * AND LIMITATIONS UNDER THE LICENSE.
 *
 * You should have received a copy of the Apache License
 * along with this distribution; if not, you may obtain a copy of the 
 * License at 
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 ??*/

package com.zotoh.maedr.etc;

import static com.zotoh.core.io.StreamUte.close;
import static com.zotoh.core.io.StreamUte.readStream;
import static com.zotoh.core.io.StreamUte.writeFile;
import static com.zotoh.core.util.CoreUte.isWindows;
import static com.zotoh.core.util.CoreUte.niceFPath;
import static com.zotoh.core.util.CoreUte.rc2Str;
import static com.zotoh.core.util.CoreUte.tstEStrArg;
import static com.zotoh.core.util.StrUte.isEmpty;
import static com.zotoh.core.util.StrUte.nsb;
import static com.zotoh.core.util.StrUte.strstr;

import java.io.File;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import com.zotoh.core.util.JSONUte;
import com.zotoh.maedr.core.CmdHelpError;

/**
 * (Internal use only).
 *
 * @author kenl
 */
class CmdAppOps extends Cmdline {

    /**
     * @param home
     */
    public CmdAppOps(File home, File cwd) {
        super(home, cwd);
    }

    /* (non-Javadoc)
     * @see com.zotoh.maedr.etc.Cmdline#getCmds()
     */
    @SuppressWarnings("serial")
    public Set<String> getCmds() {
        return new HashSet<String>() {
            {
                add("app");
            }
        };
    }

    /* (non-Javadoc)
     * @see com.zotoh.maedr.etc.Cmdline#eval(java.lang.String[])
     */
    protected void eval(String[] args) throws Exception {
        if (args == null || args.length < 2) {
            throw new CmdHelpError();
        }
        String s1 = args[1], s2 = args.length > 2 ? args[2] : "";
        boolean bg = false, web = false;

        if ("compile".equals(s1)) {
            compile();
        } else if ("test".equals(s1)) {
            testCode();
        } else if ("ide/eclipse".equals(s1)) {
            genEclipse();
        } else if ("bundle".equals(s1)) {
            pack(s2);
        } else if ("debug".equals(s1)) {
            dbg(s2);
        } else if (s1.startsWith("run")) {
            bg = "run/bg".equals(s1);
            runScript(bg, s2);
        } else if (s1.startsWith("create")) {
            web = "create/web".equals(s1);
            create(web, s2);
        } else if (s1.startsWith("start")) {
            bg = "start/bg".equals(s1);
            launch(bg);
        } else if (s1.startsWith("invoke")) {
            bg = "invoke/bg".equals(s1);
            invoke(bg, s2);
        } else {
            throw new CmdHelpError();
        }

    }

    private void dbg(String port) throws Exception {
        runTarget(isWindows() ? "run-dbg-app-w32" : "run-dbg-app-nix");
    }

    private void create(boolean web, String app) throws Exception {
        if (isEmpty(app)) {
            throw new CmdHelpError();
        }
        new CmdApps(getMaedrDir(), getCwd()).eval(new String[] { "create", app, (web ? "/webapp" : "") });
    }

    private void pack(String out) throws Exception {
        if (isEmpty(out)) {
            throw new CmdHelpError();
        }
        assertAppDir();

        // make a copy of original ant.xml in the tmp dir
        // coz that's the one which gets packaged.
        String s = rc2Str("com/zotoh/maedr/env/ant.xml", "utf-8");
        File fo = new File(new File(getCwd(), TMP), "/ant.orig.xml");
        writeFile(fo, s, "utf-8");

        boolean web = isWebApp();
        fo = new File(out);
        fo.mkdirs();
        out = niceFPath(fo);
        if (isWindows()) {
            runTargetExtra(web ? bundleWebApp("bundle-webapp-w32", out) : "bundle-w32", ANTOPT_OUTDIR, out);
        } else {
            runTargetExtra(web ? bundleWebApp("bundle-webapp-nix", out) : "bundle-nix", ANTOPT_OUTDIR, out);
        }
    }

    private String bundleWebApp(String target, String outdir) throws Exception {
        File cfg = new File(getCwd(), CFG);
        JSONObject dev, devs, root;
        InputStream inp = null;

        try {
            root = JSONUte.read(inp = readStream(new File(cfg, APPCONF)));
            devs = root.optJSONObject(CFGKEY_DEVICES);
        } finally {
            close(inp);
        }

        String json, xml, proc = "", key, type, jetty = "";
        int cnt = 0;
        for (Iterator<?> it = devs.keys(); it.hasNext();) {
            key = nsb(it.next());
            dev = devs.optJSONObject(key);
            type = dev.optString(CFGKEY_TYPE);
            if (dev.has(DEV_STATUS) && dev.optBoolean(DEV_STATUS) == false) {
                continue;
            }
            if (!"jetty".equals(type)) {
                continue;
            }
            proc = dev.optString("processor");
            jetty = key;
            ++cnt;
        }
        if (cnt > 1) {
            throw new Exception("Too many Jetty device(s)");
        }
        if (cnt == 0) {
            throw new Exception("No Jetty device defined");
        }
        dev = (JSONObject) devs.remove(jetty);
        xml = toWebXML(dev);
        dev = new JSONObject();
        dev.put(CFGKEY_TYPE, DT_WEB_SERVLET);
        dev.put("port", "0");
        dev.put("host", "");
        if (!isEmpty(proc)) {
            dev.put("processor", proc);
        }
        devs.put(WEBSERVLET_DEVID, dev);
        json = JSONUte.asString(root);

        File fo = new File(outdir, "webapps");
        fo.mkdirs();
        File t = new File(fo, TMP);
        t.mkdirs();
        new File(fo, REALM).mkdirs();
        new File(fo, DB).mkdirs();
        File c = new File(fo, CFG);
        c.mkdirs();
        new File(fo, LOGS).mkdirs();

        FileUtils.copyFileToDirectory(new File(cfg, APPPROPS), c);
        writeFile(new File(c, APPCONF), json, "utf-8");
        writeFile(new File(t, "web.xml"), xml, "utf-8");

        return target;
    }

    private void testCode() throws Exception {
        assertAppDir();
        runTarget("test-code");
    }

    private void compile() throws Exception {
        assertAppDir();
        runTarget("compile-code");
    }

    private void launch(boolean bg) throws Exception {
        assertAppDir();
        if (bg) {
            runTarget(isWindows() ? "run-app-bg-w32" : "run-app-bg-nix");
        } else {
            runTarget("run-app");
        }
    }

    private void runScript(boolean bg, String script) throws Exception {
        tstEStrArg("script-file", script);
        assertAppDir();
        if (bg) {
            runTargetExtra(isWindows() ? "run-script-bg-w32" : "run-script-bg-nix", ANTOPT_SCRIPTFILE, script);
        } else {
            runTargetExtra("run-script", ANTOPT_SCRIPTFILE, script);
        }
    }

    private void invoke(boolean bg, String svc) throws Exception {
        tstEStrArg("java.runnable-class", svc);
        assertAppDir();
        if (bg) {
            runTargetExtra(isWindows() ? "run-svc-bg-w32" : "run-svc-bg-nix", ANTOPT_SVCPOINT, svc);
        } else {
            runTargetExtra("run-svc", ANTOPT_SVCPOINT, svc);
        }
    }

    private String toWebXML(JSONObject jetty) throws Exception {
        String xml = rc2Str("com/zotoh/maedr/env/web.xml", "utf-8");
        String r = toServletFrag(jetty) + toFilterDefs(jetty);
        xml = strstr(xml, "<!-- INSERT CONTENT HERE -->", r);
        return xml;
    }

    private String toServletFrag(JSONObject jetty) throws Exception {
        String sn = "MAEDR Servlet";
        String s = "<servlet>\n\t<servlet-name>" + sn + "</servlet-name>\n\t"
                + "<servlet-class>com.zotoh.maedr.device.WEBServlet</servlet-class>\n"
                + "\t<load-on-startup>1</load-on-startup>\n" + "</servlet>";
        return s + "\n" + toServletMappings(jetty, sn);
    }

    private String toServletMappings(JSONObject jetty, String sn) throws Exception {
        StringBuilder b = new StringBuilder(512);
        String s;
        JSONArray urls = jetty.optJSONArray("urlpatterns");
        if (urls != null)
            for (int i = 0; i < urls.length(); ++i) {
                s = "<servlet-mapping>\n\t<servlet-name>" + sn + "</servlet-name>\n\t" + "<url-pattern>"
                        + urls.optString(i) + "</url-pattern>\n</servlet-mapping>\n";
                b.append(s);
            }
        return b.toString();
    }

    private String toFilterDefs(JSONObject jetty) throws Exception {
        StringBuilder b = new StringBuilder(512);
        String s, fn;
        JSONArray fils = jetty.optJSONArray("filters");
        JSONObject f;
        if (fils != null)
            for (int i = 0; i < fils.length(); ++i) {
                fn = "filter" + Integer.toString(i + 1);
                f = fils.optJSONObject(i);
                s = "<filter>\n\t<filter-name>" + fn + "</filter-name>\n\t<filter-class>" + f.optString("class")
                        + "</filter-class>" + toFilterParams(f.optJSONObject("params")) + "</filter>\n"
                        + "<filter-mapping>\n\t<filter-name>" + fn + "</filter-name>\n\t" + "<url-pattern>"
                        + f.optString("urlpattern") + "</url-pattern>\n" + "</filter-mapping>\n";
                b.append(s);
            }

        return b.toString();
    }

    private String toFilterParams(JSONObject obj) throws Exception {
        StringBuilder b = new StringBuilder(512);
        String key;
        if (obj != null)
            for (Iterator<?> it = obj.keys(); it.hasNext();) {
                key = nsb(it.next());
                b.append(toInitParam(key, obj.optString(key)));
            }
        return b.toString();
    }

    private String toInitParam(String pn, String pv) {
        return "<init-param>\n\t<param-name>" + pn + "</param-name>\n\t<param-value>" + pv
                + "</param-value>\n</init-param>\n";
    }

    protected void genEclipse() throws Exception {
        assertAppDir();

        String lang = getAppLang();
        if ("groovy".equals(lang)) {
        } else if ("scala".equals(lang)) {
        } else if ("java".equals(lang)) {
        } else {
            throw new Exception("Failed to generate eclipse project, language = " + lang);
        }
        genEclipseProj(lang);
    }

    protected void genEclipseProj(String lang) throws Exception {
        File out, ec, cwd = getCwd(), home = getMaedrDir();
        ec = new File(cwd, ECPPROJ);
        ec.mkdirs();
        FileUtils.cleanDirectory(ec);
        String app = cwd.getName();
        StringBuilder sb;
        String str = rc2Str("com/zotoh/maedr/eclipse/" + lang + "/project.txt", "utf-8");
        str = strstr(str, "${APP.NAME}", app);
        str = strstr(str, "${" + lang.toUpperCase() + ".SRC}", niceFPath(new File(cwd, "src/main/" + lang)));
        str = strstr(str, "${TEST.SRC}", niceFPath(new File(cwd, "src/main/test")));
        out = new File(ec, ".project");
        writeFile(out, str, "utf-8");
        str = rc2Str("com/zotoh/maedr/eclipse/" + lang + "/classpath.txt", "utf-8");
        sb = new StringBuilder(512);
        scanJars(new File(home, "lib"), sb);
        scanJars(new File(home, "thirdparty"), sb);
        scanJars(new File(home, "dist"), sb);
        scanJars(new File(cwd, "lib"), sb);
        scanJars(new File(cwd, "thirdparty"), sb);
        scanJars(new File(cwd, "dist"), sb);
        str = strstr(str, "${CLASS.PATH.ENTRIES}", sb.toString());
        out = new File(ec, ".classpath");
        writeFile(out, str, "utf-8");
    }

    private void scanJars(File dir, StringBuilder out) throws Exception {
        File[] fs = dir.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith(".jar");
            }
        });
        String p;
        if (fs != null)
            for (int i = 0; i < fs.length; ++i) {
                p = niceFPath(fs[i]);
                p = "<classpathentry kind=\"lib\" path=\"" + p + "\"/>\n";
                out.append(p);
            }
    }

}