Cherry picks from trunk to releases/2.1:
r8958 Updating the doc build file to include the new examples for Cells
rTBD Resolves ROO-1508 by requiring CompositeEditors to return a canonical component Editor instance for path traversal
git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/2.1@8962 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/doc/build.xml b/doc/build.xml
index 6b40bb8..0f10a55 100644
--- a/doc/build.xml
+++ b/doc/build.xml
@@ -9,9 +9,6 @@
<!-- Platform shouldn't matter here, just picking one -->
<property.ensure name="gwt.dev.jar" location="${gwt.build.lib}/gwt-dev.jar" />
- <!-- This file controls the contents of the javadoc -->
- <property file="packages.properties" />
-
<!--
*** Note that if the USER_SOURCE_PATH paths are updated,
the fileset dependencies in the outofdate tags in the
@@ -42,6 +39,7 @@
<path refid="USER_SOURCE_PATH" />
</path>
+ <!-- Rebuild the javadoc if a source file is newer than the index-->
<target name="javadoc">
<outofdate>
<sourcefiles>
@@ -71,35 +69,51 @@
</targetfiles>
<sequential>
<echo>Building javadoc</echo>
- <java classpathref="DOC_PATH" classname="com.google.doctool.custom.GWTJavaDoclet" fork="yes" failonerror="true">
- <jvmarg value="-Xmx512M" />
- <arg value="-quiet" />
- <arg value="-notimestamp" />
- <arg value="-source" />
- <arg value="1.5" />
- <arg value="-windowtitle" />
- <arg value="Google Web Toolkit Javadoc" />
- <arg value="-doctitle" />
- <arg value="Google Web Toolkit API Reference" />
- <arg value="-header" />
- <arg value="GWT ${gwt.version}" />
- <arg value="-encoding"/>
- <arg value="UTF-8"/>
- <arg value="-d" />
- <arg value="${project.build}/javadoc" />
- <arg value="-classpath" />
- <arg pathref="USER_CLASS_PATH" />
- <arg value="-sourcepath" />
- <arg pathref="USER_SOURCE_PATH" />
- <arg value="-examplepackages" />
- <arg value="com.google.gwt.examples;com.google.gwt.examples.i18n;com.google.gwt.examples.http.client;com.google.gwt.examples.rpc.server;com.google.gwt.examples.benchmarks" />
- <arg value="-packages" />
- <arg value="${USER_PKGS};${USER_CLASSES}" />
- </java>
+ <antcall target="makeJavadoc" />
</sequential>
</outofdate>
</target>
+ <!-- Really rebuild the javadoc -->
+ <target name="makeJavadoc">
+ <exec executable="chmod">
+ <arg value="+x" />
+ <arg value="${gwt.root}/doc/find-packages.sh" />
+ </exec>
+ <exec executable="${gwt.root}/doc/find-packages.sh" />
+ <property file="packages.properties" />
+ <java classpathref="DOC_PATH" classname="com.google.doctool.custom.GWTJavaDoclet" fork="yes" failonerror="true">
+ <jvmarg value="-Xmx1024m" />
+ <arg value="-quiet" />
+ <arg value="-notimestamp" />
+ <arg value="-source" />
+ <arg value="1.5" />
+ <arg value="-windowtitle" />
+ <arg value="Google Web Toolkit Javadoc" />
+ <arg value="-doctitle" />
+ <arg value="Google Web Toolkit API Reference" />
+ <arg value="-header" />
+ <arg value="GWT ${gwt.version}" />
+ <arg value="-encoding"/>
+ <arg value="UTF-8"/>
+ <arg value="-d" />
+ <arg value="${project.build}/javadoc" />
+ <arg value="-linkoffline" />
+ <arg value="http://download.oracle.com/javaee/6/api/" />
+ <arg value="validation-package-list" />
+ <arg value="-link" />
+ <arg value="http://www.json.org/javadoc" />
+ <arg value="-classpath" />
+ <arg pathref="USER_CLASS_PATH" />
+ <arg value="-sourcepath" />
+ <arg pathref="USER_SOURCE_PATH" />
+ <arg value="-examplepackages" />
+ <arg value="com.google.gwt.examples;com.google.gwt.examples.i18n;com.google.gwt.examples.http.client;com.google.gwt.examples.rpc.server;com.google.gwt.examples.benchmarks;com.google.gwt.examples.cell;com.google.gwt.examples.cellview;com.google.gwt.examples.view" />
+ <arg value="-packages" />
+ <arg value="${USER_PKGS};${USER_CLASSES}" />
+ </java>
+ </target>
+
<target name="emul-ezt">
<outofdate>
<sourcefiles>
@@ -112,6 +126,12 @@
</targetfiles>
<sequential>
<echo>Building JRE emulation EZT</echo>
+ <exec executable="chmod">
+ <arg value="+x" />
+ <arg value="${gwt.root}/doc/find-packages.sh" />
+ </exec>
+ <exec executable="${gwt.root}/doc/find-packages.sh" />
+ <property file="packages.properties" />
<java classpathref="DOC_PATH" classname="com.google.doctool.JreDocTool" fork="yes" failonerror="true">
<arg value="-out" />
<arg value="${project.build}/emul-ezt/fragment.html" />
diff --git a/doc/find-packages.sh b/doc/find-packages.sh
new file mode 100644
index 0000000..9383271
--- /dev/null
+++ b/doc/find-packages.sh
@@ -0,0 +1,93 @@
+#!/bin/bash
+set noglob
+
+OUTFILE=packages.properties
+TMPFILE=/tmp/gwt-javadoc-packages$$
+
+# Regex patterns to exclude from the list of packages
+EXCLUSIONS="\
+^com\.example\.|\
+^com\.google\.gwt\.dev(\.|$)|\
+^com\.google\.gwt\.emul\.|\
+^com\.google\.gwt\.examples(\.|$)|\
+^com\.google\.gwt\.i18n\.server(\.|$)|\
+^com\.google\.gwt\.i18n\.tools|\
+^com\.google\.gwt\.lang|\
+^com\.google\.gwt\.junit(\.|$)|\
+^com\.google\.gwt\.resources\.css(\.|$)|\
+^com\.google\.gwt\.resources\.rg(\.|$)|\
+^com\.google\.gwt\.rpc\.client\.ast(\.|$)|\
+^com\.google\.gwt\.soyc(\.|$)|\
+^com\.google\.gwt\.validation(.|$)|\
+^com\.google\.gwt\.user\.client\.rpc\.core\.|\
+^javax\.|\
+^junit\.|\
+^org\.|\
+\.impl(\.|$)|\
+\.rebind(\.|$)"
+
+# Generate the packages.properties file
+# Changes to LANG_PKGS and USER_CLASSES go here
+# Note that line continuation backslashes must be escaped
+cat > ${OUTFILE} <<EOF
+# THIS FILE IS AUTOMATICALLY GENERATED
+#
+# This file contains all of the user javadoc packages
+#
+# JRE emulation packages
+LANG_PKGS=\\
+java.lang;\\
+java.lang.annotation;\\
+java.io;\\
+java.sql;\\
+java.util
+# The last package should not have a trailing semicolon
+
+# Individual classes to include when we don't want to include an entire package
+USER_CLASSES=\\
+\${gwt.root}/user/src/com/google/gwt/junit/tools/GWTTestSuite.java:\\
+\${gwt.root}/user/src/com/google/gwt/i18n/rebind/LocaleUtils.java:\\
+\${gwt.root}/user/src/com/google/gwt/i18n/server/GwtLocaleFactoryImpl.java:\\
+\${gwt.root}/user/src/com/google/gwt/i18n/server/GwtLocaleImpl.java
+
+# Packages to include
+USER_PKGS=\\
+EOF
+
+rm -f ${TMPFILE}
+
+# Create a list of all packages with at least one Java source file
+# List all source files
+for dir in ../user/src ../user/javadoc ../user/super ../dev/core/src ../dev/core/super
+do
+(cd ${dir}; find . -name '*.java') >> ${TMPFILE}
+done
+
+cat ${TMPFILE} | \
+# Remove source file names
+sed 's@/[-A-Za-z0-9_]*\.java$@@'| \
+# Removce initial './'
+sed s@^\./@@ | \
+# Remove .../super/ and .../translatable prefixes
+sed s@^.*/super/@@ | \
+sed s@^.*/translatable/@@ | \
+# Change slashes to dots
+sed s@/@.@g | \
+# Remove excluded patters
+egrep -v ${EXCLUSIONS} > ${TMPFILE}-2
+mv ${TMPFILE}-2 ${TMPFILE}
+
+# Re-add whitelisted packages that would otherwise be excluded
+echo com.google.gwt.i18n.rebind.format >> ${TMPFILE}
+echo com.google.gwt.i18n.rebind.keygen >> ${TMPFILE}
+echo com.google.gwt.junit.client >> ${TMPFILE}
+
+# Sort, uniqify, and add ';\' to each line except the last
+cat ${TMPFILE} | \
+sort | \
+uniq | \
+sed '$q;s@$@;\\@' >> ${OUTFILE}
+echo '# The last package should not have a trailing semicolon' >> ${OUTFILE}
+
+# Clean up
+rm -f ${TMPFILE}
diff --git a/doc/json-package-list/package-list b/doc/json-package-list/package-list
new file mode 100644
index 0000000..6374a8e
--- /dev/null
+++ b/doc/json-package-list/package-list
@@ -0,0 +1 @@
+org.json
diff --git a/doc/packages.properties b/doc/packages.properties
deleted file mode 100644
index 413eae4..0000000
--- a/doc/packages.properties
+++ /dev/null
@@ -1,65 +0,0 @@
-# This file contains all of the user javadoc packages.
-LANG_PKGS=\
-java.lang;\
-java.lang.annotation;\
-java.io;\
-java.sql;\
-java.util
-# The last package should not have a trailing semicolon
-
-# Individual classes to include when we don't want to include an entire package.
-USER_CLASSES=\
-${gwt.root}/user/src/com/google/gwt/junit/tools/GWTTestSuite.java:\
-${gwt.root}/user/src/com/google/gwt/i18n/rebind/LocaleUtils.java:\
-${gwt.root}/user/src/com/google/gwt/i18n/server/GwtLocaleFactoryImpl.java:\
-${gwt.root}/user/src/com/google/gwt/i18n/server/GwtLocaleImpl.java
-
-USER_PKGS=\
-com.google.gwt.animation.client;\
-com.google.gwt.benchmarks.client;\
-com.google.gwt.cell.client;\
-com.google.gwt.core.client;\
-com.google.gwt.core.ext;\
-com.google.gwt.core.ext.soyc;\
-com.google.gwt.core.ext.linker;\
-com.google.gwt.core.ext.typeinfo;\
-com.google.gwt.core.linker;\
-com.google.gwt.debug.client;\
-com.google.gwt.dom.client;\
-com.google.gwt.editor.client;\
-com.google.gwt.editor.client.adapters;\
-com.google.gwt.editor.client.testing;\
-com.google.gwt.event.dom.client;\
-com.google.gwt.event.logical.shared;\
-com.google.gwt.event.shared;\
-com.google.gwt.http.client;\
-com.google.gwt.i18n.client;\
-com.google.gwt.i18n.shared;\
-com.google.gwt.i18n.client.constants;\
-com.google.gwt.i18n.rebind.format;\
-com.google.gwt.i18n.rebind.keygen;\
-com.google.gwt.json.client;\
-com.google.gwt.junit.client;\
-com.google.gwt.logging.client;\
-com.google.gwt.benchmarks.client;\
-com.google.gwt.regexp.shared;\
-com.google.gwt.resources.client;\
-com.google.gwt.resources.ext;\
-com.google.gwt.user.cellview.client;\
-com.google.gwt.user.client;\
-com.google.gwt.user.client.rpc;\
-com.google.gwt.user.client.ui;\
-com.google.gwt.user.datepicker.client;\
-com.google.gwt.user.server.rpc;\
-com.google.gwt.xml.client;\
-com.google.gwt.uibinder.client;\
-com.google.gwt.rpc.client;\
-com.google.gwt.rpc.server;\
-com.google.gwt.jsonp.client;\
-com.google.gwt.view.client;\
-com.google.gwt.app.client;\
-com.google.gwt.app.place;\
-com.google.gwt.requestfactory.client;\
-com.google.gwt.requestfactory.server;\
-com.google.gwt.requestfactory.shared
-# The last package should not have a trailing semicolon
diff --git a/doc/validation-package-list/package-list b/doc/validation-package-list/package-list
new file mode 100644
index 0000000..8b0d75a
--- /dev/null
+++ b/doc/validation-package-list/package-list
@@ -0,0 +1,2 @@
+javax.validation
+javax.validation.constraints
diff --git a/user/src/com/google/gwt/editor/client/CompositeEditor.java b/user/src/com/google/gwt/editor/client/CompositeEditor.java
index 11569de..95d48a6 100644
--- a/user/src/com/google/gwt/editor/client/CompositeEditor.java
+++ b/user/src/com/google/gwt/editor/client/CompositeEditor.java
@@ -82,6 +82,12 @@
}
/**
+ * Returns an canonical sub-editor instance that will be used by the driver
+ * for computing all edited paths.
+ */
+ E createEditorForTraversal();
+
+ /**
* Used to implement {@link EditorDelegate#getPath()}.
*/
String getPathElement(E subEditor);
diff --git a/user/src/com/google/gwt/editor/client/adapters/ListEditor.java b/user/src/com/google/gwt/editor/client/adapters/ListEditor.java
index 314be63..988aaa2 100644
--- a/user/src/com/google/gwt/editor/client/adapters/ListEditor.java
+++ b/user/src/com/google/gwt/editor/client/adapters/ListEditor.java
@@ -52,6 +52,12 @@
this.editorSource = source;
}
+ public E createEditorForTraversal() {
+ E toReturn = editorSource.create(0);
+ editorSource.dispose(toReturn);
+ return toReturn;
+ }
+
public void flush() {
list.flush();
}
diff --git a/user/src/com/google/gwt/editor/client/adapters/OptionalFieldEditor.java b/user/src/com/google/gwt/editor/client/adapters/OptionalFieldEditor.java
index cac0a07..0373e16 100644
--- a/user/src/com/google/gwt/editor/client/adapters/OptionalFieldEditor.java
+++ b/user/src/com/google/gwt/editor/client/adapters/OptionalFieldEditor.java
@@ -63,6 +63,10 @@
this.subEditor = subEditor;
}
+ public E createEditorForTraversal() {
+ return subEditor;
+ }
+
public void flush() {
currentValue = chain.getValue(subEditor);
}
diff --git a/user/src/com/google/gwt/editor/rebind/AbstractEditorDriverGenerator.java b/user/src/com/google/gwt/editor/rebind/AbstractEditorDriverGenerator.java
index 18f9f62..a33e03b 100644
--- a/user/src/com/google/gwt/editor/rebind/AbstractEditorDriverGenerator.java
+++ b/user/src/com/google/gwt/editor/rebind/AbstractEditorDriverGenerator.java
@@ -194,8 +194,8 @@
for (EditorData d : data) {
String mutableObjectExpression;
if (d.getBeanOwnerExpression().length() > 0) {
- mutableObjectExpression = mutableObjectExpression(d, String.format(
- "(getObject()%s)", d.getBeanOwnerExpression()));
+ mutableObjectExpression = mutableObjectExpression(d,
+ String.format("(getObject()%s)", d.getBeanOwnerExpression()));
} else {
mutableObjectExpression = "getObject()";
}
@@ -294,7 +294,8 @@
editor.getQualifiedSourceName(), List.class.getName());
sw.indent();
for (EditorData d : data) {
- if (d.isDelegateRequired() || d.isDeclaredPathNested()) {
+ if (d.isDelegateRequired() || d.isDeclaredPathNested()
+ || d.isCompositeEditor()) {
// if (editor.subEditor != null) {
sw.println("if (editor.%s != null) {", d.getSimpleExpression());
sw.indent();
@@ -308,6 +309,15 @@
sw.println("%s.traverseEditor(editor.%s, localPath, paths);",
getEditorDelegate(d), d.getSimpleExpression());
}
+ if (d.isCompositeEditor()) {
+ /*
+ * composedDelegate.traverseEditor(editor.subEditor.
+ * createEditorForTraversal(), localPath, paths);
+ */
+ sw.println(
+ "%s.traverseEditor(editor.%s.createEditorForTraversal(), localPath, paths);",
+ getEditorDelegate(d.getComposedData()), d.getSimpleExpression());
+ }
sw.outdent();
sw.println("}");
}
@@ -330,7 +340,7 @@
* @param context
* @param model
* @param sw
- *
+ *
* @throws UnableToCompleteException
*/
protected void writeAdditionalContent(TreeLogger logger,
diff --git a/user/src/com/google/gwt/editor/rebind/model/EditorModel.java b/user/src/com/google/gwt/editor/rebind/model/EditorModel.java
index 3dab1b4..8577228 100644
--- a/user/src/com/google/gwt/editor/rebind/model/EditorModel.java
+++ b/user/src/com/google/gwt/editor/rebind/model/EditorModel.java
@@ -60,7 +60,7 @@
if (compositeEditorIntf.equals(parameterized.getBaseType())) {
JClassType[] typeArgs = parameterized.getTypeArgs();
assert typeArgs.length == 3;
- return new JClassType[] {typeArgs[1], typeArgs[2]};
+ return new JClassType[]{typeArgs[1], typeArgs[2]};
}
}
}
@@ -83,8 +83,8 @@
if (parameterization != null) {
return parameterization[0];
}
- logger.log(TreeLogger.ERROR, noEditorParameterizationMessage(editorIntf,
- editorType));
+ logger.log(TreeLogger.ERROR,
+ noEditorParameterizationMessage(editorIntf, editorType));
throw new UnableToCompleteException();
}
@@ -102,8 +102,8 @@
if (parameterization != null) {
return parameterization[0];
}
- logger.log(TreeLogger.ERROR, noEditorParameterizationMessage(editorIntf,
- editorType));
+ logger.log(TreeLogger.ERROR,
+ noEditorParameterizationMessage(editorIntf, editorType));
throw new UnableToCompleteException();
}
@@ -326,6 +326,10 @@
&& isEditorIntf.isAssignableFrom(editorType)) {
// Ignore IsEditor.asEditor()
continue;
+ } else if (access.getPath().equals("createEditorForTraversal")
+ && compositeEditorIntf.isAssignableFrom(editorType)) {
+ // Ignore CompositeEditor.createEditorForTraversal();
+ continue;
}
List<EditorData> data = createEditorData(access);
accumulateEditorData(data, flatData, toReturn);
@@ -376,8 +380,8 @@
// Are we looking at a view that implements IsEditor?
if (access.isEditor()) {
- EditorAccess subAccess = EditorAccess.via(access, calculateIsEditedType(
- subLogger, access.getEditorType()));
+ EditorAccess subAccess = EditorAccess.via(access,
+ calculateIsEditedType(subLogger, access.getEditorType()));
toReturn = createEditorData(subAccess);
// If an object only implements IsEditor, return now
diff --git a/user/test/com/google/gwt/requestfactory/client/ui/EditorTest.java b/user/test/com/google/gwt/requestfactory/client/ui/EditorTest.java
index 6b1cc48..d9b71ae 100644
--- a/user/test/com/google/gwt/requestfactory/client/ui/EditorTest.java
+++ b/user/test/com/google/gwt/requestfactory/client/ui/EditorTest.java
@@ -23,6 +23,8 @@
import com.google.gwt.editor.client.EditorError;
import com.google.gwt.editor.client.HasEditorDelegate;
import com.google.gwt.editor.client.HasEditorErrors;
+import com.google.gwt.editor.client.adapters.EditorSource;
+import com.google.gwt.editor.client.adapters.ListEditor;
import com.google.gwt.editor.client.adapters.SimpleEditor;
import com.google.gwt.requestfactory.client.RequestFactoryEditorDriver;
import com.google.gwt.requestfactory.client.RequestFactoryTestBase;
@@ -55,6 +57,10 @@
RequestFactoryEditorDriver<SimpleFooProxy, SimpleFooEditor> {
}
+ static class SimpleFooBarOnlyEditor implements Editor<SimpleFooProxy> {
+ SimpleBarEditor barField = new SimpleBarEditor();
+ }
+
static class SimpleFooEditor implements HasEditorErrors<SimpleFooProxy> {
/**
* Test field-based access.
@@ -67,6 +73,13 @@
@Path("barField.userName")
final SimpleEditor<String> barName = SimpleEditor.of();
+ final ListEditor<SimpleFooProxy, SimpleFooBarOnlyEditor> selfOneToManyField = ListEditor.of(new EditorSource<SimpleFooBarOnlyEditor>() {
+ @Override
+ public SimpleFooBarOnlyEditor create(int index) {
+ return new SimpleFooBarOnlyEditor();
+ }
+ });
+
private final SimpleBarEditor barEditor = new SimpleBarEditor();
List<EditorError> errors;
@@ -108,32 +121,32 @@
driver.initialize(req, editor);
req.simpleFooRequest().findSimpleFooById(1L).with(driver.getPaths()).fire(
- new Receiver<SimpleFooProxy>() {
- @Override
- public void onSuccess(SimpleFooProxy response) {
-
- SimpleFooRequest context = req.simpleFooRequest();
- driver.edit(response, context);
- context.persistAndReturnSelf().using(response).with(
- driver.getPaths()).to(new Receiver<SimpleFooProxy>() {
+ new Receiver<SimpleFooProxy>() {
@Override
public void onSuccess(SimpleFooProxy response) {
- assertEquals("EditorFooTest", response.getUserName());
- assertEquals("EditorBarTest",
- response.getBarField().getUserName());
- finishTestAndReset();
+
+ SimpleFooRequest context = req.simpleFooRequest();
+ driver.edit(response, context);
+ context.persistAndReturnSelf().using(response).with(
+ driver.getPaths()).to(new Receiver<SimpleFooProxy>() {
+ @Override
+ public void onSuccess(SimpleFooProxy response) {
+ assertEquals("EditorFooTest", response.getUserName());
+ assertEquals("EditorBarTest",
+ response.getBarField().getUserName());
+ finishTestAndReset();
+ }
+ });
+ assertEquals("GWT", editor.userName.getValue());
+ assertEquals("FOO", editor.barEditor().userName.getValue());
+ assertEquals("FOO", editor.barName.getValue());
+ editor.userName.setValue("EditorFooTest");
+ // When there are duplicate paths, last declared editor wins
+ editor.barEditor().userName.setValue("EditorBarTest");
+ editor.barName.setValue("ignored");
+ driver.flush().fire();
}
});
- assertEquals("GWT", editor.userName.getValue());
- assertEquals("FOO", editor.barEditor().userName.getValue());
- assertEquals("FOO", editor.barName.getValue());
- editor.userName.setValue("EditorFooTest");
- // When there are duplicate paths, last declared editor wins
- editor.barEditor().userName.setValue("EditorBarTest");
- editor.barName.setValue("ignored");
- driver.flush().fire();
- }
- });
}
public void testNoSubscription() {
@@ -141,10 +154,10 @@
final SimpleFooDriver driver = GWT.create(SimpleFooDriver.class);
driver.initialize(req, editor);
-
+
/*
* Confirm that it's always safe to call subscribe. The editor's delegate
- * isn't set until edit is called, so edit nothing.
+ * isn't set until edit is called, so edit nothing.
*/
driver.edit(null, null);
assertNull(editor.delegate.subscribe());
@@ -157,10 +170,11 @@
final SimpleFooDriver driver = GWT.create(SimpleFooDriver.class);
driver.initialize(req, editor);
- assertEquals(Arrays.asList("barField.userName", "barField"),
- Arrays.asList(driver.getPaths()));
+ String[] paths = driver.getPaths();
+ assertEquals(Arrays.asList("barField.userName", "selfOneToManyField",
+ "selfOneToManyField.barField", "barField"), Arrays.asList(paths));
- req.simpleFooRequest().findSimpleFooById(1L).with(driver.getPaths()).fire(
+ req.simpleFooRequest().findSimpleFooById(1L).with(paths).fire(
new Receiver<SimpleFooProxy>() {
@Override
public void onSuccess(SimpleFooProxy response) {
@@ -202,7 +216,7 @@
}
});
}
-
+
public void testViolations() {
delayTestFinish(TEST_TIMEOUT);
final SimpleFooEditor editor = new SimpleFooEditor();