Java tutorial
/* * 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; } }