Package com.googlecode.gwt.test.internal.utils

Source Code of com.googlecode.gwt.test.internal.utils.JsoUtils

package com.googlecode.gwt.test.internal.utils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Text;
import com.google.gwt.user.client.ui.Widget;
import com.googlecode.gwt.test.finder.GwtFinder;
import com.googlecode.gwt.test.utils.GwtReflectionUtils;
import com.googlecode.gwt.test.utils.JavaScriptObjects;
import com.googlecode.gwt.test.utils.WidgetUtils;

/**
*
* Some {@link JavaScriptObject} utility methods. <strong>For internal use only.</strong>
*
* @author Gael Lazzari
*
*/
public class JsoUtils {

   private static final Set<String> DOM_PROPERTIES = new HashSet<String>() {
      /**
     *
     */
      private static final long serialVersionUID = 1L;

      {
         /*
          *
          * Parse HTML standard attributes here : http://www.w3.org/TR/html4/index/attributes.html
          *
          * With this jQuery script :
          *
          * <script language="Javascript"> var array = new Array();
          * $('td[title=Name]').each(function() { var text = $(this).text().trim(); if
          * (jQuery.inArray(text, array) == -1) { array.push(text); } });
          *
          * var java = '<p>'; var length = array.length;
          *
          * for (var i=0; i < length; i++) { java += 'add("' + array[i] + '");<br/>'; }
          *
          * java += '</p>';
          *
          * $('table').parent().html(java); </script>
          */
         add("abbr");
         add("accept-charset");
         add("accept");
         add("accesskey");
         add("action");
         add("align");
         add("alink");
         add("alt");
         add("archive");
         add("axis");
         add("background");
         add("bgcolor");
         add("border");
         add("cellpadding");
         add("cellspacing");
         add("char");
         add("charoff");
         add("charset");
         add("checked");
         add("cite");
         add("class");
         add("classid");
         add("clear");
         add("code");
         add("codebase");
         add("codetype");
         add("color");
         add("cols");
         add("colspan");
         add("compact");
         add("content");
         add("coords");
         add("data");
         add("datetime");
         add("declare");
         add("defer");
         add("dir");
         add("disabled");
         add("enctype");
         add("face");
         add("for");
         add("frame");
         add("frameborder");
         add("headers");
         add("height");
         add("href");
         add("hreflang");
         add("hspace");
         add("http-equiv");
         add("id");
         add("ismap");
         add("label");
         add("lang");
         add("language");
         add("link");
         add("longdesc");
         add("marginheight");
         add("marginwidth");
         add("maxlength");
         add("media");
         add("method");
         add("multiple");
         add("name");
         add("nohref");
         add("noresize");
         add("noshade");
         add("nowrap");
         add("object");
         add("onblur");
         add("onchange");
         add("onclick");
         add("ondblclick");
         add("onfocus");
         add("onkeydown");
         add("onkeypress");
         add("onkeyup");
         add("onload");
         add("onmousedown");
         add("onmousemove");
         add("onmouseout");
         add("onmouseover");
         add("onmouseup");
         add("onreset");
         add("onselect");
         add("onsubmit");
         add("onunload");
         add("profile");
         add("prompt");
         add("readonly");
         add("rel");
         add("rev");
         add("rows");
         add("rowspan");
         add("rules");
         add("scheme");
         add("scope");
         add("scrolling");
         add("selected");
         add("shape");
         add("size");
         add("span");
         add("src");
         add("standby");
         add("start");
         add("style");
         add("summary");
         add("tabindex");
         add("target");
         add("text");
         add("title");
         add("type");
         add("usemap");
         add("valign");
         add("value");
         add("valuetype");
         add("version");
         add("vlink");
         add("vspace");
         add("width");
      }
   };

   private static final String ELEM_PROPERTIES = "ELEM_PROPERTIES";
   private static final String IS_XML_ELEMENT = "IS_XML_ELEMENT";
   private static final String NODE_LIST_FIELD = "childNodes";
   private static final String NODE_LIST_INNER_LIST = "NODE_LIST_INNER_LIST";
   private static final String NODE_NAME = "nodeName";
   private static final String NODE_TYPE_FIELD = "nodeType";
   private static final String PARENT_NODE_FIELD = "parentNode";
   private static final String TAG_NAME = "tagName";

   public static JavaScriptObject cloneJso(JavaScriptObject oldJso, boolean deep) {
      JavaScriptObject newJso = JavaScriptObject.createObject();

      if (Node.is(oldJso)) {
         short nodeType = oldJso.<Node> cast().getNodeType();
         JavaScriptObjects.setProperty(newJso, NODE_TYPE_FIELD, nodeType);
      }

      for (Map.Entry<String, Object> entry : JavaScriptObjects.entrySet(oldJso)) {

         if (PARENT_NODE_FIELD.equals(entry.getKey())) {
            // Nothing to do : new cloned node does not have any parent
         } else if (NODE_TYPE_FIELD.equals(entry.getKey())) {
            // ignore it since it has to be handled at the very beginning of
            // cloning
         } else if (JsoProperties.NODE_OWNER_DOCUMENT.equals(entry.getKey())) {
            JavaScriptObjects.setProperty(newJso, JsoProperties.NODE_OWNER_DOCUMENT,
                     JavaScriptObjects.getObject(oldJso, JsoProperties.NODE_OWNER_DOCUMENT));
         } else if (GwtStyleUtils.STYLE_OBJECT_FIELD.equals(entry.getKey())) {
            Style newStyle = GwtStyleUtils.getStyle(newJso.<Element> cast());
            GwtStyleUtils.cloneStyle(newStyle, (Style) entry.getValue());
         } else if (NODE_LIST_FIELD.equals(entry.getKey())) {
            Node newNode = newJso.cast();
            Node oldNode = oldJso.cast();
            cloneChildNodes(newNode, oldNode, deep);
         } else if (ELEM_PROPERTIES.equals(entry.getKey())) {
            PropertyContainer newPc = getDomProperties(newJso.<Element> cast());
            PropertyContainer oldPc = getDomProperties(oldJso.<Element> cast());

            for (Map.Entry<String, Object> entry2 : oldPc.entrySet()) {
               newPc.put(entry2.getKey(), entry2.getValue());
            }
         } else if (JavaScriptObject.class.isInstance(entry.getValue())) {
            JavaScriptObject oldChildJso = (JavaScriptObject) entry.getValue();
            JavaScriptObject newChildJso = cloneJso(oldChildJso, deep);
            JavaScriptObjects.setProperty(newJso, entry.getKey(), newChildJso);
         } else {
            // copy the property, which should be a String or a primitive type
            // (or
            // corresponding wrapper object)
            JavaScriptObjects.setProperty(newJso, entry.getKey(), entry.getValue());
         }
      }

      return newJso;

   }

   @SuppressWarnings("unchecked")
   public static List<Node> getChildNodeInnerList(Node node) {
      NodeList<Node> nodeList = getChildNodes(node);
      return (List<Node>) JavaScriptObjects.getObject(nodeList, NODE_LIST_INNER_LIST);
   }

   @SuppressWarnings("unchecked")
   public static <T extends Node> List<T> getChildNodeInnerList(NodeList<T> nodeList) {
      assert isNodeList(nodeList) : "not a NodeList";

      return (List<T>) JavaScriptObjects.getObject(nodeList, NODE_LIST_INNER_LIST);
   }

   public static NodeList<Node> getChildNodes(Node node) {
      assert Node.is(node) : "not a Node";
      NodeList<Node> nodeList = JavaScriptObjects.getObject(node, NODE_LIST_FIELD);

      if (nodeList == null) {
         nodeList = newNodeList();
         JavaScriptObjects.setProperty(node, NODE_LIST_FIELD, nodeList);
      }

      return nodeList;
   }

   public static PropertyContainer getDomProperties(Element element) {
      assert Node.is(element) : "not a Node";

      PropertyContainer pc = JavaScriptObjects.getObject(element, ELEM_PROPERTIES);

      if (pc == null) {
         // a propertyContainer with a LinkedHashMap to record the order of DOM
         // properties
         pc = PropertyContainer.newInstance(new LinkedHashMap<String, Object>());
         JavaScriptObjects.setProperty(element, ELEM_PROPERTIES, pc);
      }

      return pc;
   }

   public static short getNodeType(JavaScriptObject jso) {
      return JavaScriptObjects.hasProperty(jso, NODE_TYPE_FIELD) ? JavaScriptObjects.getShort(jso,
               NODE_TYPE_FIELD) : -1;
   }

   public static String getTagName(Element element) {
      assert Element.is(element) : "not an Element";

      return JavaScriptObjects.getString(element, TAG_NAME);
   }

   public static boolean isNodeList(JavaScriptObject jso) {
      return JavaScriptObjects.hasProperty(jso, NODE_LIST_INNER_LIST);
   }

   public static boolean isStandardDOMProperty(String propertyName) {
      return "className".equals(propertyName) || !"class".equals(propertyName)
               && DOM_PROPERTIES.contains(propertyName);
   }

   public static boolean isXmlElement(JavaScriptObject jso) {
      return JavaScriptObjects.hasProperty(jso, IS_XML_ELEMENT);
   }

   public static Document newDocument() {
      Document document = newNode(Node.DOCUMENT_NODE).cast();
      JavaScriptObjects.setProperty(document, JsoProperties.NODE_OWNER_DOCUMENT, document);
      return document;

   }

   public static Element newElement(String tag, Document ownerDocument) {
      Element elem = newNode(Node.ELEMENT_NODE).cast();
      JavaScriptObjects.setProperty(elem, TAG_NAME, tag);
      JavaScriptObjects.setProperty(elem, JsoProperties.NODE_OWNER_DOCUMENT, ownerDocument);

      if (tag.equalsIgnoreCase("html")) {
         JavaScriptObjects.setProperty(elem, NODE_NAME, "HTML");
      }

      return elem;
   }

   public static Node newNode(int nodeType) {
      Node newNode = JavaScriptObject.createObject().cast();
      JavaScriptObjects.setProperty(newNode, NODE_TYPE_FIELD, (short) nodeType);
      return newNode;
   }

   public static <T extends Node> NodeList<T> newNodeList() {
      return newNodeList(new ArrayList<T>());
   }

   @SuppressWarnings("unchecked")
   public static <T extends Node> NodeList<T> newNodeList(List<T> innerList) {
      NodeList<T> nodeList = (NodeList<T>) JavaScriptObject.createObject().cast();
      JavaScriptObjects.setProperty(nodeList, NODE_LIST_INNER_LIST, innerList);
      return nodeList;
   }

   public static Text newText(String data, Document ownerDocument) {
      Text text = newNode(Node.TEXT_NODE).cast();
      JavaScriptObjects.setProperty(text, JsoProperties.NODE_OWNER_DOCUMENT, ownerDocument);
      text.setData(data);

      return text;
   }

   public static Element newXmlElement(Document document, String tagName) {
      Element xmlElement = document.createElement(tagName);
      JavaScriptObjects.setProperty(xmlElement, IS_XML_ELEMENT, true);

      return xmlElement;
   }

   public static void onSetHTML(JavaScriptObject jso, String newHTML, String oldHTML) {
      Widget w = WidgetUtils.getWidget(jso.<Element> cast());

      if (w != null) {
         GwtReflectionUtils.callStaticMethod(GwtFinder.class, "onSetHTML", w, newHTML, oldHTML);
      }

   }

   public static void onSetId(JavaScriptObject jso, String newId, String oldId) {
      Widget w = WidgetUtils.getWidget(jso.<Element> cast());

      if (w != null) {
         GwtReflectionUtils.callStaticMethod(GwtFinder.class, "onSetId", w, newId, oldId);
      }
   }

   public static void onSetText(JavaScriptObject jso, String newText, String oldText) {
      Widget w = WidgetUtils.getWidget(jso.<Element> cast());

      if (w != null) {
         GwtReflectionUtils.callStaticMethod(GwtFinder.class, "onSetText", w, newText, oldText);
      }
   }

   public static String serialize(JavaScriptObject jso) {
      if (Node.is(jso)) {
         return jso.toString();
      }

      StringBuilder sb = new StringBuilder();
      // FIXME : provide support for JavaScriptObject arrays
      sb.append("{ ");

      for (Map.Entry<String, Object> entry : JavaScriptObjects.entrySet(jso)) {
         sb.append("\"").append(entry.getKey()).append("\": ");
         sb.append(entry.getValue()).append(", ");
      }

      sb.replace(sb.length() - 2, sb.length(), "");
      sb.append(" }");

      return sb.toString();

   }

   public static void setParentNode(Node child, Node parent) {
      JavaScriptObjects.setProperty(child, PARENT_NODE_FIELD, parent);
   }

   private static void cloneChildNodes(Node newNode, Node oldNode, boolean deep) {

      List<Node> childs = getChildNodeInnerList(oldNode);
      if (deep) {
         // copy all child nodes
         for (Node child : childs) {
            newNode.appendChild(child.cloneNode(deep));
         }
      } else {
         // only copy the TextNode if exists
         for (Node child : childs) {
            if (Node.TEXT_NODE == child.getNodeType()) {
               newNode.appendChild(Document.get().createTextNode(child.getNodeValue()));
               break;
            }
         }
      }
   }

}
TOP

Related Classes of com.googlecode.gwt.test.internal.utils.JsoUtils

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.