org.gk.engine.client.Engine.java Source code

Java tutorial

Introduction

Here is the source code for org.gk.engine.client.Engine.java

Source

/*
 * Copyright (C) 2000-2012  InfoChamp System Corporation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program 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
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.gk.engine.client;

import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import jfreecode.gwt.event.client.bus.EventBus;
import jfreecode.gwt.event.client.bus.EventObject;
import jfreecode.gwt.event.client.bus.EventProcessImpl;
import jfreecode.gwt.event.client.bus.JsonConvert;

import org.gk.engine.client.build.Builder;
import org.gk.engine.client.build.EngineDataStore;
import org.gk.engine.client.build.INodeProvider;
import org.gk.engine.client.build.js.XJavaScript;
import org.gk.engine.client.build.layout.XLayoutData;
import org.gk.engine.client.event.EventCenter;
import org.gk.engine.client.event.EventHandler;
import org.gk.engine.client.exception.GKEngineException;
import org.gk.engine.client.exception.LibraryNotFoundException;
import org.gk.engine.client.gen.UIGen;
import org.gk.engine.client.i18n.EngineMessages;
import org.gk.engine.client.logging.EngineLogger;
import org.gk.engine.client.utils.ComLibrary;
import org.gk.engine.client.utils.NodeUtils;
import org.gk.ui.client.com.form.gkList;
import org.gk.ui.client.com.form.gkMap;

import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.core.DomQuery;
import com.extjs.gxt.ui.client.core.XDOM;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.Container;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.form.AdapterField;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.Node;
import com.google.gwt.xml.client.NodeList;

/**
 * <title>?GWTGK</title>
 * 
 * <pre>
 * GK?gul?gul????
 * ??APIAP???Widget
 * ?
 * 1.GWTgk
 * 2.?GWTPage??Engine
 * </pre>
 * 
 * @author I21890
 * @since 2010/07/07
 */
public class Engine implements IEngine, INodeProvider {

    static {
        // truepageToolbar image? (??)
        // booleanGXT.java??div
        // ?true,false
        /**
         * <pre>
         * GXT ?Initializes GXT
         *  if ("none".equals(XDOM.getComputedStyle(div,"backgroundImage"))) { 
         *  isHighContrastMode = true;
         * XDOM.getBodyEl().addStyleName("x-contrast"); }
         * </pre>
         */
        GXT.isHighContrastMode = false;
        GXT.setAutoIdPrefix("gk");
    }
    private static Engine engine;
    protected String id = XDOM.getUniqueId();
    protected String gul = "<page>\r\n</page>";
    // ??XML Node
    protected Node preprocessNode;
    // ??GKGKUIGen?Component?
    protected List<UIGen> uiGenNodeList = new gkList<UIGen>();
    // render?LayoutContainer?
    protected static Map<String, Set> renderPanelCom = new gkMap();
    protected static Map<String, Set> renderPanelComBak = new gkMap();

    public static Engine get() {
        if (engine == null) {
            engine = new Engine();
            engine.build();
        }
        return engine;
    }

    public static String getVersion() {
        return Version.BUILD;
    }

    /**
     * <pre>
     * ? <com></com> ,
     * NodeProvider ??Node?
     * </pre>
     */
    private Engine() {
        // ??GKEngine????alert
        GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
            @Override
            public void onUncaughtException(Throwable e) {
                EngineLogger.log(e);
            }
        });
    }

    private void build() {
        Builder.attach(Engine.this);
        loadingLibrary();
        JSMethods.hookJSMethods();
    }

    /**
     * ?lib
     */
    public native void loadingLibrary()/*-{
                                       (function() {
                                       var gkEngine = $wnd.document.getElementById('_gk_');
                                       if (gkEngine != null && gkEngine.getAttribute('lib') != null) {
                                       var gkEngineLib = gkEngine.getAttribute('lib');
                                       @org.gk.engine.client.utils.ComLibrary::loadingLibrary(Ljava/lang/String;)(gkEngineLib);
                                       } else {
                                       @org.gk.engine.client.utils.ComLibrary::loadingLibrary(Ljava/lang/String;)("/gul/lib/component.lib");
                                       }
                                       })();
                                       }-*/;

    private static String getCookie(String name) {
        return Cookies.getCookie(name);
    }

    private static void setCookie(String name, String value) {
        long timestamp = new Date().getTime() + (1000 * 86400) * 14; // 2 week
        Cookies.setCookie(name, value, new Date(timestamp));
    }

    /**
     * javascript
     * 
     * @param js
     *            javascript
     */
    private static native void executeJS(String js)/*-{
                                                   $wnd.eval(js);
                                                   }-*/;

    private static native void registryWindowFocusBlur(String userId, String midTime)/*-{
                                                                                     $wnd.onfocus = function() {
                                                                                     @org.gk.engine.client.Engine::listener(Ljava/lang/String;Ljava/lang/String;)(userId, '' + midTime);
                                                                                     }
                                                                                     $wnd.onblur = function() {
                                                                                     @org.gk.engine.client.Engine::listener(Ljava/lang/String;Ljava/lang/String;)(userId, '0');
                                                                                     }
                                                                                     }-*/;

    /**
     * ?gk.loadGUL
     * 
     * <pre>
     * PagePagePathWeb?? 
     * ?
     * : http://www.ezoui.com/portal/index.gul
     * </pre>
     * 
     * @return String
     */
    public static native String getGKPath()/*-{
                                           return $wnd.gk.path;
                                           }-*/;

    /**
     * polling
     * 
     * @param userId
     * @param midTime
     */
    private static void listener(String userId, String midTime) {
        if (midTime == null || midTime.equals("0") || (userId != null && userId.toLowerCase().equals("guest"))) {
            EventBus.get(userId).disconnect();
            return;
        }
        String gkPath = getGKPath();
        if (gkPath != null && gkPath.startsWith("http://")) {
            String[] urlSplit = gkPath.split("/");
            if (urlSplit.length == 3) {
                throw new GKEngineException("gk.listener failure! " + gkPath);
            }
            String host = urlSplit[0] + "//" + urlSplit[2] + "/" + urlSplit[3] + "/";
            EventBus.get(userId).connectServer(host, Integer.parseInt(midTime));
        } else {
            EventBus.get(userId).connectServer(Integer.parseInt(midTime));
        }
        EventBus.get(userId).subscribe("javascript", new EventProcessImpl("javascript") {
            @Override
            public void execute(String eventId, EventObject eo) {
                try {
                    executeJS(eo.getInfoString());
                } catch (Exception e) {
                    EngineLogger.console("executeJS:" + e);
                }
            }
        });
        EventBus.get(userId).subscribe("callback", new EventProcessImpl("callback") {
            @Override
            public void execute(String eventId, EventObject eo) {
                Map gkInfo = eo.getInfoMap();
                Iterator it = gkInfo.entrySet().iterator();
                while (it.hasNext()) {
                    Entry<String, Object> entry = (Entry) it.next();
                    EventHandler.setAttributeValue(entry.getKey(), entry.getValue());
                }
            }
        });
    }

    protected static void invokeEvent(String gulAttribute, JavaScriptObject jso) {
        invokeEvent("", gulAttribute, jso);
    }

    protected static void invokeEvent(String srcId, String gulAttribute, JavaScriptObject jso) {
        XJavaScript js = new XJavaScript(srcId, "");
        EventCenter.exec(js.getId(), gulAttribute, js, new BaseEvent(jso));
    }

    @Override
    public Component getComponent(String id) {
        return getComponent().get(id);
    }

    @Override
    public Map<String, Component> getComponent() {
        return EngineDataStore.getComponentMap();
    }

    @Override
    public void render(String gul, LayoutContainer lc) {
        render(gul, lc, true);
    }

    @Override
    public void render(String gul, LayoutContainer lc, boolean clearAll) {
        if (clearAll) {
            this.gul = gul;
            renderPanelCom.clear();
            EngineDataStore.clearAll();
            bus.removeAll();
            EventCenter.clear();
        }
        renderPanel(gul, lc);
    }

    public String gul() {
        return gul;
    }

    public void renderPanel(String gul, LayoutContainer lc) {
        renderPanel(gul, lc, false);
    }

    /**
     * <pre>
     *  ??GULLayoutContainer
     *  ?GUL?Component id?
     *  ??ID
     * </pre>
     * 
     * @param gul
     * @param container
     * @param hasRoot
     */
    public void renderPanel(String gul, LayoutContainer container, boolean hasRoot) {
        // ??Engine???
        gul = beforeParser(gul);
        gul = i18n(gul);
        // ???rootxml??root Tag
        if (hasRoot) {
            gul = new StringBuffer("<root>").append(gul).append("</root>").toString();
        }
        uiGenNodeList.clear();

        // ??? component 
        removeAllComponent(container);

        // ?Bus??Bus
        String outsideBusName = EventBus.get().getName();
        EventBus.setDefaultName(bus.getName());
        // 
        backup();
        try {
            // GUL?XML?Exception
            Document doc = parseGUL(gul);

            NodeList nodeList = hasRoot ? doc.getChildNodes().item(0).getChildNodes() : doc.getChildNodes();

            // GUL???
            long time = System.currentTimeMillis();
            parserNode(uiGenNodeList, nodeList);
            putRenderPanelComSet(container);
            long processNodeSpendTime = System.currentTimeMillis() - time;

            // ???
            time = System.currentTimeMillis();
            renderUI(container);
            container.layout();
            initialAllUIGen(container);
            long renderUISpendTime = System.currentTimeMillis() - time;

            // ??
            printLastRenderSpendTime(processNodeSpendTime, renderUISpendTime);
            // ??
            bus.publish(new EventObject(getId() + ".afterRender"));
        } catch (Throwable e) {
            EngineLogger.log(e);
            rollback();
        } finally {
            // 
            clearBackup();
            // Bus??
            EventBus.setDefaultName(outsideBusName);
            // ?render???log???
            check();
        }
    }

    private Document parseGUL(String gul) {
        gul = ComLibrary.replaceAnonymousId(gul);
        return NodeUtils.parseGUL(gul);
    }

    private void check() {
        // ?render???log???
        EngineLogger.console(EventBus.getEventBusList());
        EngineLogger.console("Nodes:" + EngineDataStore.getUIGenNodeMapSize());
        EngineLogger.console("Components:" + EngineDataStore.getComponentMapSize());
        EngineLogger.console("renderPanelCom:" + renderPanelCom.size());

        // ?
        int uiGenNodeSize = EngineDataStore.getUIGenNodeMapSize();
        int rpComSize = 0;
        Set key = renderPanelCom.keySet();
        Iterator it = key.iterator();
        while (it.hasNext()) {
            String ke = it.next().toString() + "";
            Set map = renderPanelCom.get(ke);
            rpComSize += map.size();
        }
        if (uiGenNodeSize != rpComSize) {
            String temp = "";
            Map nodeMap = EngineDataStore.getUIGenNodeMap();
            it = key.iterator();
            while (it.hasNext()) {
                String ke = it.next().toString() + "";
                Set map = renderPanelCom.get(ke);
                Iterator mapIt = map.iterator();
                while (mapIt.hasNext()) {
                    Object obj = mapIt.next();
                    if (!nodeMap.containsKey(obj)) {
                        temp += obj + ",";
                    }
                }
            }
            if (!temp.equals("")) {
                EngineLogger.console("different info===\n");
                EngineLogger.console(temp + "\n");
                EngineLogger.console("============");
            }
        }
    }

    /**
     * 
     */
    private void backup() {
        EngineDataStore.backup();
        renderPanelComBak.putAll(renderPanelCom);
    }

    /**
     * 
     */
    private void rollback() {
        EngineDataStore.rollback();
        renderPanelCom.clear();
        renderPanelCom.putAll(renderPanelComBak);
    }

    /**
     * 
     */
    private void clearBackup() {
        EngineDataStore.clearBackup();
        renderPanelComBak.clear();
    }

    public void removeComponent(String id) {
        EngineDataStore.removeComponent(id);//  GXT 
        EngineDataStore.removeUIGenNode(id);//  XComponent 
        EventCenter.remove(id); // ?
    }

    /**
     * @param containerId
     */
    public void removeRenderPanelComponent(String containerId) {
        renderPanelCom.remove(containerId);
    }

    private void removeAllComponent(Container layoutContainer) {
        // ?gxt?
        Iterator<Component> componentIt = layoutContainer.getItems().iterator();
        while (componentIt.hasNext()) {
            Component com = componentIt.next();
            if (com instanceof Container) {
                removeAllComponent((Container) com);
            } else if (com instanceof Grid) {
                removeColumnModel((Grid) com);
            } else if (com instanceof AdapterField) {
                removeAdaptWidget((AdapterField) com);
            }
            removeComponent(com.getId());
            removeRenderPanelComById(com.getId());
        }
        // ?renderPanelCom?
        removeRenderPanelCom(layoutContainer.getId());
        // ??
        layoutContainer.removeAll();
    }

    private void removeRenderPanelCom(String containerId) {
        if (renderPanelCom.get(containerId) == null) {
            return;
        }
        Iterator<String> comIt = renderPanelCom.get(containerId).iterator();
        while (comIt.hasNext()) {
            removeComponent(comIt.next());
        }
        renderPanelCom.remove(containerId);
    }

    private void removeRenderPanelComById(String id) {
        Set key = renderPanelCom.keySet();
        Iterator it = key.iterator();
        while (it.hasNext()) {
            String ke = it.next().toString() + "";
            Set set = renderPanelCom.get(ke);
            if (set.contains(id)) {
                set.remove(id);
                return;
            }
        }
    }

    /**
     * Grid??Grid?ColumnConfigEngineDataStore
     * 
     * @param grid
     */
    private void removeColumnModel(Grid grid) {
        ColumnModel cm = grid.getColumnModel();
        Iterator<ColumnConfig> columnIt = cm.getColumns().iterator();
        while (columnIt.hasNext()) {
            String id = columnIt.next().getId();
            removeComponent(id);
            removeRenderPanelComById(id);
        }
        // ??DomQuerygridid_rowIndex
        com.google.gwt.dom.client.NodeList<Element> nodes = DomQuery.select("*[id*=_]", grid.getElement());
        for (int i = 0; i < nodes.getLength(); i++) {
            Element ele = nodes.getItem(i);
            removeComponent(ele.getId());
            removeRenderPanelComById(ele.getId());
        }
    }

    /**
     * adaptField??adaptField?widgetEngineDataStore
     * 
     * @param field
     */
    private void removeAdaptWidget(AdapterField field) {
        com.google.gwt.user.client.ui.Widget widget = field.getWidget();
        if (widget instanceof Container) {
            removeAllComponent((Container) widget);
        }
    }

    /**
     * RenderPanelid , ???
     * 
     * @param lc
     */
    private void putRenderPanelComSet(LayoutContainer lc) {
        renderPanelCom.put(lc.getId(), new LinkedHashSet(EngineDataStore.genSequenceSet()));
        EngineDataStore.genSequenceSet().clear();
    }

    private static void printLastRenderSpendTime(long processNodeTime, long renderTime) {
        String p = "processNode:" + (processNodeTime / 1000.0);
        String r = "render:" + (renderTime / 1000.0);
        System.err.println("GK: " + p + " / " + r);
    }

    public String getId() {
        return id;
    }

    @Override
    public void parserNode(List<UIGen> list, NodeList nodes) {
        for (int i = 0; i < nodes.getLength(); i++) {
            preprocessNode(nodes.item(i), list);
        }
    }

    @Override
    public void parserNode(List<UIGen> list, Node node) {
        preprocessNode(node, list);
    }

    /**
     * ??Node
     * 
     * @param node
     *            ??Node
     * @param list
     *            ?NodeuiGenlist
     */
    public void preprocessNode(Node node, List<UIGen> list) {
        // Override
        this.preprocessNode = ComLibrary.overrideNode(node);

        int processTagAmt = 0;
        String nName = node.getNodeName();
        // ? <#text></#text>?<#comment></#comment>?<import></import>
        if (nName.endsWith("#text") || nName.endsWith("#comment") || nName.endsWith("import")) {
            return;
        }
        // ?com???buildList?
        processTagAmt = builder.publish(new EventObject(nName.toLowerCase(), list));
        // processTagAmt=0Tag?tag??GUL??
        if (processTagAmt == 0) {
            processExternalTag(nName, node, list);
        }
    }

    /**
     * ??
     * 
     * @return boolean
     */
    public boolean isReady() {
        return ComLibrary.isReady();
    }

    /**
     * ?
     * 
     * @param nodeName
     * @param node
     * @param list
     */
    private void processExternalTag(String nodeName, Node node, List<UIGen> list) {
        // ?attach
        if (ComLibrary.contains(nodeName)) {
            if (!ComLibrary.isServerPage(nodeName)) {
                NodeList nList = ComLibrary.replaceNode(nodeName, node);
                parserNode(list, nList);
            } else {
                Map nodeInfo = NodeUtils.getAttributes(node);
                String url = ComLibrary.getContent(nodeName);
                String gul = ajaxComponent(url, nodeInfo);
                NodeList nList = ComLibrary.replaceNode(node, gul);
                parserNode(list, nList);
            }
        } else {
            throw new LibraryNotFoundException(EngineMessages.msg.error_libraryNotFound(nodeName));
        }
    }

    /**
     * <pre>
     * ???ajaxjsp?GUL??redner?
     * ??jsp??
     * http://api.jquery.com/jQuery.post/   ?? data j={...} 
     * </pre>
     * 
     * @param url
     * @param nodeInfo
     * @return String
     */
    private String ajaxComponent(String url, Map nodeInfo) {
        String id = DOM.createUniqueId();
        nodeInfo.put("_gk_file", url);
        StringBuffer gul = new StringBuffer("<page><panel id='").append(id);
        gul.append("' layout='fit'>").append("<js init='js:this'>");
        gul.append("$.ajax({type : 'POST',url  : 'event/put/ajaxComponent/jspBean.forward.go");
        gul.append("',data:");
        gul.append("'j={\"t\":\"map\",\"i\":").append(JsonConvert.toJSONObject(nodeInfo) + "").append("}");
        gul.append("',dataType : 'text',success : function(gul) {gk.set('");
        gul.append(id).append("',gul);}});</js></panel></page>");
        return gul.toString();
    }

    /**
     * nodeList?Component?Panel
     * 
     * @param panel
     */
    private void renderUI(LayoutContainer panel) {
        Iterator<UIGen> it = uiGenNodeList.iterator();
        // uiGenNodeList?renderpage()?uiGenNodeList
        while (it.hasNext() && !uiGenNodeList.isEmpty()) {
            UIGen uiGen = it.next();
            Component com = uiGen.build();
            if (com != null) {
                // Window?
                if (!(com instanceof Window)) {
                    // layoutlayoutData
                    if (uiGen instanceof XLayoutData) {
                        XLayoutData xLayout = (XLayoutData) uiGen;
                        panel.add(com, xLayout.getLayoutData());
                    } else {
                        panel.add(com);
                    }
                }
                // uiGenNodeList????remove
                if (uiGenNodeList.contains(uiGen)) {
                    it.remove();
                }
            }
        }
    }

    /**
     * ?
     * 
     * @param lc
     */
    private void initialAllUIGen(LayoutContainer lc) {
        Iterator<String> it = renderPanelCom.get(lc.getId()).iterator();
        while (it.hasNext()) {
            UIGen ui = EngineDataStore.getUIGenNode(it.next());
            ui.init();
        }
    }

    public native static String beforeParser(String gul)/*-{
                                                        return $wnd.gk.beforeParser(gul);
                                                        }-*/;

    public native static String i18n(String gul)/*-{
                                                return $wnd.gk.i18n(gul);
                                                }-*/;

    @Override
    public Node getPreprocessNode() {
        return preprocessNode;
    }
}