<module>\r
<inherits name='com.google.gwt.user.User'/>\r
\r
+ <!-- Json and Xml builders -->\r
<generate-with class="com.google.gwt.query.rebind.JsonBuilderGenerator">\r
<when-type-assignable class="com.google.gwt.query.client.builders.JsonBuilder"/>\r
</generate-with>\r
+ <generate-with class="com.google.gwt.query.rebind.XmlBuilderGenerator">\r
+ <when-type-assignable class="com.google.gwt.query.client.builders.XmlBuilder"/>\r
+ </generate-with> \r
\r
<!-- Lazy Generator -->\r
<generate-with class="com.google.gwt.query.rebind.LazyGenerator">\r
}\r
\r
/**\r
- * Return the text contained in the first matched element.\r
+ * Return the concatened text contained in the matched elements.\r
*/\r
public String text() {\r
String result = "";\r
for (Element e : elements) {\r
- result += e.getInnerText();\r
+ result += JsUtils.text(e);\r
}\r
return result;\r
}\r
+++ /dev/null
-/*\r
- * Copyright 2011, The gwtquery team.\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not\r
- * use this file except in compliance with the License. You may obtain a copy of\r
- * the License at\r
- * \r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- * \r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
- * License for the specific language governing permissions and limitations under\r
- * the License.\r
- */\r
-package com.google.gwt.query.client.builders;\r
-\r
-import static java.lang.annotation.ElementType.METHOD;\r
-import java.lang.annotation.Retention;\r
-import java.lang.annotation.RetentionPolicy;\r
-import java.lang.annotation.Target;\r
-\r
-/**\r
- */\r
-@Target({METHOD})\r
-@Retention(RetentionPolicy.RUNTIME)\r
-public @interface JsonName {\r
- String value();\r
-}\r
--- /dev/null
+/*\r
+ * Copyright 2011, The gwtquery team.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not\r
+ * use this file except in compliance with the License. You may obtain a copy of\r
+ * the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
+ * License for the specific language governing permissions and limitations under\r
+ * the License.\r
+ */\r
+package com.google.gwt.query.client.builders;\r
+\r
+import static java.lang.annotation.ElementType.METHOD;\r
+import java.lang.annotation.Retention;\r
+import java.lang.annotation.RetentionPolicy;\r
+import java.lang.annotation.Target;\r
+\r
+/**\r
+ * Annotation used to specify the attribute, tag or property name\r
+ * in Json or Xml builders.\r
+ */\r
+@Target({METHOD})\r
+@Retention(RetentionPolicy.RUNTIME)\r
+public @interface Name {\r
+ String value();\r
+}\r
--- /dev/null
+/*\r
+ * Copyright 2011, The gwtquery team.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not\r
+ * use this file except in compliance with the License. You may obtain a copy of\r
+ * the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
+ * License for the specific language governing permissions and limitations under\r
+ * the License.\r
+ */\r
+package com.google.gwt.query.client.builders;\r
+\r
+import com.google.gwt.dom.client.Element;\r
+\r
+/**\r
+ * Tagging interface used to generate XmlBuilder classes. \r
+ */\r
+public interface XmlBuilder {\r
+ /**\r
+ * load a string or a documentElement.\r
+ */\r
+ <J> J load(Object o);\r
+ \r
+ /**\r
+ * parses a xml string and loads the resulting documentElement.\r
+ */\r
+ <J> J parse(String xml);\r
+ \r
+ /**\r
+ * Returns the documentElement.\r
+ */\r
+ Element getDocumentElement();\r
+}\r
--- /dev/null
+/*
+ * Copyright 2011, The gwtquery team.
+ *
+ * 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.query.client.builders;
+
+import static com.google.gwt.query.client.GQuery.$;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.query.client.GQuery;
+import com.google.gwt.query.client.Properties;
+import com.google.gwt.query.client.js.JsUtils;
+
+public abstract class XmlBuilderBase<J extends XmlBuilderBase<?>> implements XmlBuilder {
+
+ //TODO empty document
+ protected GQuery g = $(JsUtils.parseXML("<root/>"));
+
+ @SuppressWarnings("unchecked")
+ public J parse(String xml) {
+ return load(JsUtils.parseXML(xml));
+ }
+
+ @SuppressWarnings("unchecked")
+ public J load(Object o) {
+ assert o == null || o instanceof JavaScriptObject && JsUtils.isElement((JavaScriptObject)o) || o instanceof String;
+ if (o != null && o instanceof String) {
+ return parse((String)o);
+ }
+ if (o != null) {
+ g=$((Element)o);
+ }
+ return (J)this;
+ }
+
+ public String getText() {
+ return g.text();
+ }
+
+ public void setText(String s) {
+ g.text(s);
+ }
+
+ public String toString() {
+ return g.toString();
+ }
+
+ protected Element getElementBase(String n) {
+ return g.children(n).get(0);
+ }
+
+ protected Element[] getElementsBase(String n) {
+ return g.children(n).elements();
+ }
+
+ public Element getDocumentElement() {
+ return g.get(0);
+ }
+
+ protected float getFloatBase(String s) {
+ String n = getStrBase(s).replaceAll("[^\\d\\-\\.]", "");
+ return n.isEmpty() ? 0 : Float.parseFloat(n);
+ }
+
+ protected Boolean getBooleanBase(String n) {
+ return "true".equalsIgnoreCase(getStrBase(n));
+ }
+
+ protected String getStrBase(String n) {
+ return g.attr(n);
+ }
+
+ protected Properties getPropertiesBase(String n) {
+ // TODO:
+ return null;
+ }
+}
return (new XMLSerializer()).serializeToString(o);
}-*/;
+ public String text(Element e) {
+ return e.getInnerText();
+ }
+
public JsArray<Element> unique(JsArray<Element> a) {
JsArray<Element> ret = JavaScriptObject.createArray().cast();
JsCache cache = JsCache.create();
}
return super.unique(a);
}
+
+ @Override
+ public String text(Element e) {
+ return isXML(e) ? xmlText(e) : super.text(e);
+ }
+
+ private native String xmlText(Element e) /*-{
+ return e.text;
+ }-*/;
}
/**
return utilsImpl.XML2String(o);
}
+ public static String text(Element e) {
+ return utilsImpl.text(e);
+ }
+
/**
* Parses a xml string and return the xml document element which
* can then be passed to GQuery to create a typical GQuery object
import com.google.gwt.core.ext.typeinfo.TypeOracle;\r
import com.google.gwt.query.client.Properties;\r
import com.google.gwt.query.client.builders.JsonBuilder;\r
-import com.google.gwt.query.client.builders.JsonName;\r
+import com.google.gwt.query.client.builders.Name;\r
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;\r
import com.google.gwt.user.rebind.SourceWriter;\r
\r
\r
public void generateMethod(SourceWriter sw, JMethod method, TreeLogger logger)\r
throws UnableToCompleteException {\r
- JsonName nameAnnotation = method.getAnnotation(JsonName.class);\r
+ Name nameAnnotation = method.getAnnotation(Name.class);\r
String name = nameAnnotation != null ? nameAnnotation.value()\r
: method.getName().replaceFirst("^(get|set)", "").toLowerCase();\r
\r
--- /dev/null
+/*\r
+ * Copyright 2011, The gwtquery team.\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not\r
+ * use this file except in compliance with the License. You may obtain a copy of\r
+ * the License at\r
+ * \r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
+ * License for the specific language governing permissions and limitations under\r
+ * the License.\r
+ */\r
+package com.google.gwt.query.rebind;\r
+\r
+import java.io.PrintWriter;\r
+\r
+import com.google.gwt.core.ext.Generator;\r
+import com.google.gwt.core.ext.GeneratorContext;\r
+import com.google.gwt.core.ext.TreeLogger;\r
+import com.google.gwt.core.ext.UnableToCompleteException;\r
+import com.google.gwt.core.ext.typeinfo.JArrayType;\r
+import com.google.gwt.core.ext.typeinfo.JClassType;\r
+import com.google.gwt.core.ext.typeinfo.JMethod;\r
+import com.google.gwt.core.ext.typeinfo.JParameter;\r
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;\r
+import com.google.gwt.core.ext.typeinfo.JType;\r
+import com.google.gwt.core.ext.typeinfo.TypeOracle;\r
+import com.google.gwt.query.client.Properties;\r
+import com.google.gwt.query.client.builders.XmlBuilder;\r
+import com.google.gwt.query.client.builders.Name;\r
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;\r
+import com.google.gwt.user.rebind.SourceWriter;\r
+\r
+/**\r
+ */\r
+public class XmlBuilderGenerator extends Generator {\r
+ TypeOracle oracle;\r
+ static JClassType xmlBuilderType;\r
+ static JClassType stringType;\r
+\r
+ public String generate(TreeLogger treeLogger,\r
+ GeneratorContext generatorContext, String requestedClass)\r
+ throws UnableToCompleteException {\r
+ oracle = generatorContext.getTypeOracle();\r
+ JClassType clazz = oracle.findType(requestedClass);\r
+ xmlBuilderType = oracle.findType(XmlBuilder.class.getName());\r
+ stringType = oracle.findType(String.class.getName());\r
+\r
+ String t[] = generateClassName(clazz);\r
+\r
+ SourceWriter sw = getSourceWriter(treeLogger, generatorContext, t[0],\r
+ t[1], requestedClass);\r
+ if (sw != null) {\r
+ for (JMethod method : clazz.getMethods()) {\r
+ generateMethod(sw, method, treeLogger);\r
+ }\r
+ sw.commit(treeLogger);\r
+ }\r
+ return t[2];\r
+ }\r
+\r
+ public String[] generateClassName(JType t) {\r
+ String[] ret = new String[3];\r
+ JClassType c = t.isClassOrInterface();\r
+ ret[0] = c.getPackage().getName();\r
+ ret[1] = c.getName().replace('.', '_') + "_XmlBuilder";\r
+ ret[2] = ret[0] + "." + ret[1];\r
+ return ret;\r
+ }\r
+\r
+ public boolean isTypeAssignableTo(JType t, JClassType o) {\r
+ JClassType c = t.isClassOrInterface();\r
+ return (c != null && c.isAssignableTo(o));\r
+ }\r
+\r
+ public void generateMethod(SourceWriter sw, JMethod method, TreeLogger logger)\r
+ throws UnableToCompleteException {\r
+ Name nameAnnotation = method.getAnnotation(Name.class);\r
+ String name = nameAnnotation != null ? nameAnnotation.value()\r
+ : method.getName().replaceFirst("^(get|set)", "").toLowerCase();\r
+\r
+ String retType = method.getReturnType().getParameterizedQualifiedSourceName();\r
+\r
+ sw.print("public final " + retType + " " + method.getName());\r
+ JParameter[] params = method.getParameters();\r
+ if (params.length == 0) {\r
+ JArrayType arr = method.getReturnType().isArray();\r
+ sw.println("() {");\r
+ sw.indent();\r
+ if (retType.matches("(java.lang.Boolean|boolean)")) {\r
+ sw.println("return getBooleanBase(\"" + name + "\");");\r
+ } else if (method.getReturnType().isPrimitive() != null) {\r
+ sw.println("return (" + retType + ")getFloatBase(\"" + name + "\");");\r
+ } else if (isTypeAssignableTo(method.getReturnType(), stringType)) {\r
+ sw.println("return getStrBase(\"" + name + "\");");\r
+ } else if (isTypeAssignableTo(method.getReturnType(), xmlBuilderType)) {\r
+ String q = method.getReturnType().getQualifiedSourceName();\r
+ sw.println("Element e = getElementBase(\"" + name + "\");");\r
+ sw.println("return e == null ? null : (" + q + ")((" + q + ")GWT.create(" + q + ".class)).load(e);");\r
+ } else if (retType.equals(Properties.class.getName())){\r
+ sw.println("return getPropertiesBase(\"" + name + "\");");\r
+ } else if (arr != null) {\r
+ String q = arr.getComponentType().getQualifiedSourceName();\r
+ sw.println("ArrayList<" + q + "> l = new ArrayList<" + q+ ">();");\r
+ sw.println("for (Element e: getElementsBase(\"" + name + "\")) {");\r
+ sw.println(" " + q + " c = GWT.create(" + q + ".class);");\r
+ sw.println(" c.load(e);");\r
+ sw.println(" l.add(c);");\r
+ sw.println("}");\r
+ sw.println("return l.toArray(new " + q + "[0]);");\r
+// } else {\r
+// sw.println("return p.get(\"" + name + "\");");\r
+ }\r
+ sw.outdent();\r
+ sw.println("}");\r
+ } else if (params.length == 1) {\r
+ JType type = params[0].getType();\r
+ JArrayType arr = type.isArray();\r
+ JPrimitiveType pri = type.isPrimitive();\r
+ sw.print("(" + type.getParameterizedQualifiedSourceName() + " a)");\r
+ sw.println("{");\r
+ sw.indent();\r
+ if (arr != null) {\r
+ sw.println("setArrayBase(\"" + name + "\", a);");\r
+ } else if (pri != null) {\r
+ } else {\r
+ sw.println("p.set(\"" + name + "\", a);");\r
+ }\r
+ if (!"void".equals(retType)){\r
+ if (isTypeAssignableTo(method.getReturnType(), method.getEnclosingType())) {\r
+ sw.println("return this;");\r
+ } else {\r
+ sw.println("return null;");\r
+ }\r
+ }\r
+ sw.outdent();\r
+ sw.println("}");\r
+ }\r
+ }\r
+\r
+ protected SourceWriter getSourceWriter(TreeLogger logger,\r
+ GeneratorContext context, String packageName, String className,\r
+ String... interfaceNames) {\r
+ PrintWriter printWriter = context.tryCreate(logger, packageName, className);\r
+ if (printWriter == null) {\r
+ return null;\r
+ }\r
+ ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(\r
+ packageName, className);\r
+ composerFactory.setSuperclass("com.google.gwt.query.client.builders.XmlBuilderBase<"\r
+ + packageName + "." + className + ">");\r
+ composerFactory.addImport("com.google.gwt.query.client.js.*");\r
+ composerFactory.addImport("com.google.gwt.query.client.*");\r
+ composerFactory.addImport("com.google.gwt.core.client.*");\r
+ composerFactory.addImport("com.google.gwt.dom.client.*");\r
+ composerFactory.addImport("java.util.*");\r
+ for (String interfaceName : interfaceNames) {\r
+ composerFactory.addImplementedInterface(interfaceName);\r
+ }\r
+ return composerFactory.createSourceWriter(context, printWriter);\r
+ }\r
+}\r
import com.google.gwt.dom.client.Element;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.query.client.builders.JsonBuilder;
-import com.google.gwt.query.client.builders.JsonName;
+import com.google.gwt.query.client.builders.Name;
+import com.google.gwt.query.client.builders.XmlBuilder;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
}
}
- interface MyClass extends JsonBuilder {
+ interface JsonExample extends JsonBuilder {
int getA();
- MyClass getB();
- @JsonName("u")
+ JsonExample getB();
+ @Name("u")
String getUrl();
long getD();
Boolean getZ();
String[] getT();
- MyClass setT(String[] strings);
- MyClass setZ(Boolean b);
+ JsonExample setT(String[] strings);
+ JsonExample setZ(Boolean b);
}
public void testJsonBuilder() {
String json = "[{a:1, b:{a:2,b:{a:3}},u:url, d:'2','t':['hola','adios'], 'z': true}]";
- MyClass c = GWT.create(MyClass.class);
+ JsonExample c = GWT.create(JsonExample.class);
assertEquals(0, c.getA());
c.parse(json, true);
assertEquals(1, c.getA());
assertEquals("foo", c.getT()[0]);
assertEquals("bar", c.getT()[1]);
}
+
+ interface XmlExample extends XmlBuilder {
+ String getA();
+ Boolean getB();
+ @Name("c")
+ int getNumber();
+
+ XmlExample[] getX();
+ @Name("x")
+ XmlExample getFirstX();
+ }
+
+ public void testXmlBuilder() {
+ String xml = "<a a='ra' b='true' c='-1.48'><x a='xa1'/> <x a='xa2'/> text</a>";
+ XmlExample x = GWT.create(XmlExample.class);
+ x.parse(xml);
+ assertTrue(x.getB());
+ assertEquals("ra", x.getA());
+ assertEquals(-1, x.getNumber());
+ assertEquals("xa2", x.getX()[1].getA());
+ assertEquals("xa1", x.getFirstX().getA());
+ }
}