| /* | |
| * Copyright 2010 Google Inc. | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not | |
| * use this file except in compliance with the License. You may obtain a copy of | |
| * the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
| * License for the specific language governing permissions and limitations under | |
| * the License. | |
| */ | |
| package com.google.gwt.uibinder.rebind; | |
| import org.w3c.dom.Document; | |
| import org.w3c.dom.Element; | |
| import org.w3c.dom.Node; | |
| import org.w3c.dom.NodeList; | |
| import java.beans.Beans; | |
| import java.util.HashMap; | |
| import java.util.Map; | |
| /** | |
| * Design time implementation of {@link DesignTimeUtils}. | |
| */ | |
| public class DesignTimeUtilsImpl implements DesignTimeUtils { | |
| /** | |
| * Returns <code>true</code> if given "Binder" is under design now. We should | |
| * not use "design time" globally, because while one widget in under design, | |
| * it may use other widgets and we want to execute them as is, without design | |
| * time tweaks. | |
| */ | |
| public static boolean isDesignTime(String fqInterfaceName) { | |
| if (Beans.isDesignTime()) { | |
| String key = "gwt.UiBinder.isDesignTime " + fqInterfaceName; | |
| return System.getProperty(key) != null; | |
| } | |
| return false; | |
| } | |
| private final Map<Element, String> elementPaths = new HashMap<Element, String>(); | |
| private final Map<String, String> attributes = new HashMap<String, String>(); | |
| public void addDeclarations(IndentedWriter w) { | |
| // handler | |
| w.write("public static interface DTObjectHandler {"); | |
| { | |
| w.indent(); | |
| w.write("void handle(String path, Object object);"); | |
| w.write("Object provideFactory(Class rawType, String methodName, Object[] args);"); | |
| w.write("Object provideField(Class rawType, String fieldName);"); | |
| w.outdent(); | |
| } | |
| w.write("}"); | |
| w.write("public DTObjectHandler dtObjectHandler;"); | |
| // attributes | |
| w.write("public final java.util.Map dtAttributes = new java.util.HashMap();"); | |
| w.write("private void dtPutAttribute(String key, Object...values) {"); | |
| { | |
| w.indent(); | |
| w.write("if (values.length == 1) {"); | |
| { | |
| w.indent(); | |
| w.write("dtAttributes.put(key, values[0]);"); | |
| w.outdent(); | |
| } | |
| w.write("} else {"); | |
| { | |
| w.indent(); | |
| w.write("dtAttributes.put(key, java.util.Arrays.asList(values));"); | |
| w.outdent(); | |
| } | |
| w.write("}"); | |
| w.outdent(); | |
| } | |
| w.write("}"); | |
| } | |
| public String getImplName(String implName) { | |
| return implName + "_designTime" + System.currentTimeMillis(); | |
| } | |
| public String getPath(Element element) { | |
| return elementPaths.get(element); | |
| } | |
| public String getProvidedFactory(String typeName, String methodName, | |
| String args) { | |
| return String.format( | |
| "(%1$s) dtObjectHandler.provideFactory(%1$s.class, \"%2$s\", new Object[] {%3$s})", | |
| typeName, methodName, args); | |
| } | |
| public String getProvidedField(String typeName, String fieldName) { | |
| return String.format( | |
| "(%1$s) dtObjectHandler.provideField(%1s.class, \"%2$s\")", typeName, | |
| fieldName); | |
| } | |
| public String getTemplateContent(String path) { | |
| return System.getProperty("gwt.UiBinder.designTime " + path); | |
| } | |
| public void handleUIObject(Statements writer, XMLElement elem, | |
| String fieldName) { | |
| writer.addStatement( | |
| "if (dtObjectHandler != null) dtObjectHandler.handle(\"%s\", %s);", | |
| elem.getDesignTimePath(), fieldName); | |
| } | |
| public boolean isDesignTime() { | |
| return true; | |
| } | |
| public void putAttribute(XMLElement elem, String name, String value) { | |
| String path = elem.getDesignTimePath(); | |
| String key = path + " " + name; | |
| attributes.put(key, value); | |
| } | |
| public void putAttribute(XMLElement elem, String name, String[] values) { | |
| if (values.length == 0) { | |
| return; | |
| } | |
| StringBuilder sb = new StringBuilder(); | |
| for (String value : values) { | |
| if (sb.length() != 0) { | |
| sb.append(", "); | |
| } | |
| sb.append(value); | |
| } | |
| sb.insert(0, "new String[] {"); | |
| sb.append("}"); | |
| putAttribute(elem, name, sb.toString()); | |
| } | |
| public void rememberPathForElements(Document doc) { | |
| rememberPathForElements(doc.getDocumentElement(), "0"); | |
| } | |
| public void writeAttributes(Statements writer) { | |
| for (Map.Entry<String, String> entry : attributes.entrySet()) { | |
| String key = entry.getKey(); | |
| String value = entry.getValue(); | |
| writer.addStatement("dtPutAttribute(\"%s\", %s);", key, value); | |
| } | |
| attributes.clear(); | |
| } | |
| /** | |
| * Returns remembered attributes, used during tests only. | |
| */ | |
| Map<String, String> getAttributes() { | |
| return attributes; | |
| } | |
| /** | |
| * Recursive implementation of {@link #rememberPathForElements(Document)}. | |
| */ | |
| private void rememberPathForElements(Element element, String path) { | |
| elementPaths.put(element, path); | |
| NodeList childNodes = element.getChildNodes(); | |
| int elementIndex = 0; | |
| for (int i = 0; i < childNodes.getLength(); ++i) { | |
| Node childNode = childNodes.item(i); | |
| if (childNode.getNodeType() == Node.ELEMENT_NODE) { | |
| Element childElement = (Element) childNode; | |
| rememberPathForElements(childElement, path + "/" + elementIndex++); | |
| } | |
| } | |
| } | |
| } |