[gwt-contrib] UiBinder tweaks for GWT Designer
To support UiBinder in GWT Designer we need to have several changes in UiBinder generators, writer and parsers. I will describe below these changes as they are done now. In real patch I will group as much implementation details as possible into single class like DesignTimeUtils or GWTDesignerSupport. It will check for GWT Designer presence and do something only in this case. So, main question is following. Will GWT team accept patch with such changes? This would allow us avoid creating internal patches for 2.0 and each future version of GWT. 1. Declare in binder implementation interface and field with it. Something like this: public static interface WBPObjectHandler {void handle(String path, Object object);} public WBPObjectHandler wbpObjectHandler; In method createAndBindUi() directly after creating each Widget instance (but before applying setX() methods) wbpObjectHandler is used to notify GWT Designer about new widget and its path in XML. GWT Designer bind Widget instance to model (using path) and also asks default values for all properties using getX() methods. Path in XML is / separated string of indexes. For example in ui:UiBinder ui:style/ g:FlowPanel styleName={style.panel} g:Button text=New Button/ /g:FlowPanel /ui:UiBinder 0/1 is FlowPanel 0/1/0 is Button 2. Declare in binder implementation Map with values of attributes. public final java.util.Map wbpAttributes = new java.util.HashMap(); and fill it, here is example if code generated for ui.xml above if (wbpObjectHandler != null) wbpObjectHandler.handle(0/1/0, f_Button2); f_Button2.setText(New Button); wbpAttributes.put(0/1/0 text, New Button); f_FlowPanel1.add(f_Button2); if (wbpObjectHandler != null) wbpObjectHandler.handle(0/1, f_FlowPanel1); f_FlowPanel1.setStyleName( + style.panel() + ); GWT Designer needs to know attribute values to show them to user in properties table. Not all properties have getter, so we can not get these values for existing Widget object. 3. In special parsers for panels, remember also values of attributes for artificial elements. For example Cell in CellPanelParser (and Dock in DockPanel). // Parse horizontal and vertical alignment attributes. if (cellElem.hasAttribute(HALIGN_ATTR)) { String value = cellElem.consumeAttribute(HALIGN_ATTR, hAlignConstantType); writer.addStatement(%1$s.setCellHorizontalAlignment(%2$s, %3$s);, fieldName, childFieldName, value); //XXX Instantiations writer.addStatement(wbpAttributes.put(\%s\, %s);, widgetElem.getPath() + Cell. + HALIGN_ATTR, value); //XXX Instantiations } 4. To allow quick updates of design canvas as user changes properties, without reloading GWT context each time, we should: 4.1. Generate Binder implementation class with new name each time, so be able to define each time new class in same ClassLoader. Right now we just add current time to the name of class. //XXX Instantiations // generate class with new name each time, to allow refresh in same ClassLoader implName += _wbp + System.currentTimeMillis(); //XXX Instantiations 4.2. To parse/render UI.XML file content without saving, i.e. from memory/editor, generate should try to read document from memory. Something like this: private Document getW3cDoc(MortalLogger logger, String templatePath) throws UnableToCompleteException { //XXX Instantiations { String content = System.getProperty(wbp.gwt.UiBinder + templatePath); if (content != null) { Document doc = null; try { doc = new W3cDomHelper(logger.getTreeLogger()).documentFor(content); } catch (SAXParseException e) { logger.die(Error parsing XML (line + e.getLineNumber() + ): + e.getMessage() + + content, e); } catch (Throwable e) { logger.die(Error parsing XML + content, e); } return doc; } } //XXX Instantiations URL url = UiBinderGenerator.class.getClassLoader().getResource(templatePath); // this is default implementation -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] [google-web-toolkit] r8303 committed - Added Hilbrand Bouwkamp for gwt-google-apis contribution
Revision: 8303 Author: zun...@google.com Date: Wed Jun 23 05:53:44 2010 Log: Added Hilbrand Bouwkamp for gwt-google-apis contribution http://code.google.com/p/google-web-toolkit/source/detail?r=8303 Modified: /CLA-SIGNERS === --- /CLA-SIGNERSFri Apr 9 16:47:56 2010 +++ /CLA-SIGNERSWed Jun 23 05:53:44 2010 @@ -6,6 +6,7 @@ btay...@rackspace.com (Bryan Taylor) dannydaemo...@gmail.com (Daniel Valenzuela) fredsa (Fred Sauer) +...@bouwkamp.com (Hilbrand Bouwkamp) ispeters (Ian Shane Petersen) james.strachan (James Strachan) jason.essington (Jason Essington) -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] UiBinder tweaks for GWT Designer
Konstantin, I've not gone over these proposals in great detail, but it does seem like a reasonable idea to build design time hooks into UiBinder-generated code. One very important caveat would be that it must be possible for the compiler to strip them out completely in production mode (this seems likely, but we'd have to be very careful to make sure it happens in practice). I'm going to have to defer to Ray on the architectural details (I haven't touched this generator in a while), and I suspect he'd want to make sure the proposed mechanisms would be generally useful for other kinds of design tools. He's on vacation this week, so I doubt he'll be able to look into it until next week at the earliest. @rjrjr: Please do have a look at this when you have a moment, and if you'd like me to look at anything in particular, I'd be happy to. Cheers, joel. Le 23 juin 2010 06:40, Konstantin.Scheglov konstantin.scheg...@gmail.com a écrit : To support UiBinder in GWT Designer we need to have several changes in UiBinder generators, writer and parsers. I will describe below these changes as they are done now. In real patch I will group as much implementation details as possible into single class like DesignTimeUtils or GWTDesignerSupport. It will check for GWT Designer presence and do something only in this case. So, main question is following. Will GWT team accept patch with such changes? This would allow us avoid creating internal patches for 2.0 and each future version of GWT. 1. Declare in binder implementation interface and field with it. Something like this: public static interface WBPObjectHandler {void handle(String path, Object object);} public WBPObjectHandler wbpObjectHandler; In method createAndBindUi() directly after creating each Widget instance (but before applying setX() methods) wbpObjectHandler is used to notify GWT Designer about new widget and its path in XML. GWT Designer bind Widget instance to model (using path) and also asks default values for all properties using getX() methods. Path in XML is / separated string of indexes. For example in ui:UiBinder ui:style/ g:FlowPanel styleName={style.panel} g:Button text=New Button/ /g:FlowPanel /ui:UiBinder 0/1 is FlowPanel 0/1/0 is Button 2. Declare in binder implementation Map with values of attributes. public final java.util.Map wbpAttributes = new java.util.HashMap(); and fill it, here is example if code generated for ui.xml above if (wbpObjectHandler != null) wbpObjectHandler.handle(0/1/0, f_Button2); f_Button2.setText(New Button); wbpAttributes.put(0/1/0 text, New Button); f_FlowPanel1.add(f_Button2); if (wbpObjectHandler != null) wbpObjectHandler.handle(0/1, f_FlowPanel1); f_FlowPanel1.setStyleName( + style.panel() + ); GWT Designer needs to know attribute values to show them to user in properties table. Not all properties have getter, so we can not get these values for existing Widget object. 3. In special parsers for panels, remember also values of attributes for artificial elements. For example Cell in CellPanelParser (and Dock in DockPanel). // Parse horizontal and vertical alignment attributes. if (cellElem.hasAttribute(HALIGN_ATTR)) { String value = cellElem.consumeAttribute(HALIGN_ATTR, hAlignConstantType); writer.addStatement(%1$s.setCellHorizontalAlignment(%2$s, %3$s);, fieldName, childFieldName, value); //XXX Instantiations writer.addStatement(wbpAttributes.put(\%s\, %s);, widgetElem.getPath() + Cell. + HALIGN_ATTR, value); //XXX Instantiations } 4. To allow quick updates of design canvas as user changes properties, without reloading GWT context each time, we should: 4.1. Generate Binder implementation class with new name each time, so be able to define each time new class in same ClassLoader. Right now we just add current time to the name of class. //XXX Instantiations // generate class with new name each time, to allow refresh in same ClassLoader implName += _wbp + System.currentTimeMillis(); //XXX Instantiations 4.2. To parse/render UI.XML file content without saving, i.e. from memory/editor, generate should try to read document from memory. Something like this: private Document getW3cDoc(MortalLogger logger, String templatePath) throws UnableToCompleteException { //XXX Instantiations { String content = System.getProperty(wbp.gwt.UiBinder + templatePath); if (content != null) { Document doc = null; try { doc = new W3cDomHelper(logger.getTreeLogger()).documentFor(content); } catch (SAXParseException e) { logger.die(Error parsing XML (line + e.getLineNumber() + ): + e.getMessage() + + content, e); } catch (Throwable e) { logger.die(Error parsing XML + content, e); } return doc;
[gwt-contrib] Re: UiBinder. Parser for TextAlignConstant (issue612803)
@rjrjr: What say ye? Have you considered doing something like this before, and perhaps found a way to generalize it such that we don't have to create a separate attribute parser for every enum? Le 22 juin 2010 07:14, konstantin.scheg...@gmail.com a écrit : Reviewers: jgw, Description: It uses friendly names. I will post patch with adding support for names like this for horizontal/vertical alignments (in addition, not replace to keep compatibility with existing code) later. Please review this at http://gwt-code-reviews.appspot.com/612803/show Affected files: user/src/com/google/gwt/uibinder/attributeparsers/AttributeParsers.java user/src/com/google/gwt/uibinder/attributeparsers/TextAlignConstantParser.java user/test/com/google/gwt/uibinder/UiBinderJreSuite.java user/test/com/google/gwt/uibinder/attributeparsers/TextAlignConstantParser_Test.java user/test/com/google/gwt/uibinder/test/UiJavaResources.java -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] Re: UiBinder. Code style for constant parsers.
Le 22 juin 2010 07:03, Konstantin.Scheglov konstantin.scheg...@gmail.com a écrit : Pretty much everything we've done so far has been limited to automatically exposing the Java-level APIs in all their ugliness. The h/v alignment values are implemented somewhat manually, but for things like enums I really like the idea that they can be exposed completely automatically. On the other hand, it would be nice to have prettier names. Perhaps we could find some sort of convention for exposing prettier names for [pseudo-]enums. What about a shortName() method on the enum itself? Hm... Yes, I think that it is possible to create some generic parser for enum-like constants. However because they are not real enums, following things come to mind: 1. During registration in AttributeParsers we will need to pass list of values; 2. To check for shortName() using reflection; 3. To test that each such constant parser instance works correctly, I would write special ui.xml file. Also one more thing worries me. Do you think that it is OK to add into GWT classes on this level information which is used only by some presentation of GWT? I mean that parsing ui.xml files is part of UiBinder, so it should be problem of UiBinder how to parse it. It *does* seem a little odd to have to add a UiBinder-specific short name to every enum (or enum-alike) used as a widget property (especially if they somehow end up in the compiled output). On the other hand, it would also kind of suck to have to put them in a completely separate place, which most widget authors would simply forget to do. On second thought, maybe we can actually get away with just convention. Most enums (e.g., Style.Unit) have names that are upper-case by convention, but we could allow UiBinder to specify them in a case-insensitive manner without ambiguity. That would leave only a handful of special cases (like the TextAlignmentParser patch you just sent). @rjrjr, konstantin: How does that sound to you both? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] [google-web-toolkit] r8304 committed - Adding a null check to ShowcaseGenerator so that we don't try to write...
Revision: 8304 Author: gwt.mirror...@gmail.com Date: Wed Jun 23 08:52:39 2010 Log: Adding a null check to ShowcaseGenerator so that we don't try to write to a public resource that has already been created. This fixes a bug when multiple examples reference the same raw source files. Review at http://gwt-code-reviews.appspot.com/646802 Review by: j...@google.com http://code.google.com/p/google-web-toolkit/source/detail?r=8304 Modified: /trunk/samples/showcase/src/com/google/gwt/sample/showcase/generator/ShowcaseGenerator.java === --- /trunk/samples/showcase/src/com/google/gwt/sample/showcase/generator/ShowcaseGenerator.java Thu Oct 30 09:17:17 2008 +++ /trunk/samples/showcase/src/com/google/gwt/sample/showcase/generator/ShowcaseGenerator.java Wed Jun 23 08:52:39 2010 @@ -33,8 +33,10 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Set; /** * Generate the source code, css styles, and raw source used in the Showcase @@ -66,6 +68,12 @@ */ private TreeLogger logger = null; + /** + * The set of raw files that have already been generated. Raw files can be + * reused by different examples, but we only generate them once. + */ + private SetString rawFiles = new HashSetString(); + @Override public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException { @@ -115,15 +123,22 @@ * @param partialPath the path to the file relative to the public directory * @param contents the file contents */ - private void createPublicResource(String partialPath, String contents) { + private void createPublicResource(String partialPath, String contents) + throws UnableToCompleteException { try { OutputStream outStream = context.tryCreateResource(logger, partialPath); + if (outStream == null) { +String message = Attempting to generate duplicate public resource: ++ partialPath ++ .\nAll generated source files must have unique names.; +logger.log(TreeLogger.ERROR, message); +throw new UnableToCompleteException(); + } outStream.write(contents.getBytes()); context.commitResource(logger, outStream); -} catch (UnableToCompleteException e) { - logger.log(TreeLogger.ERROR, Failed while writing, e); } catch (IOException e) { - logger.log(TreeLogger.ERROR, Failed while writing, e); + logger.log(TreeLogger.ERROR, Error writing file: + partialPath, e); + throw new UnableToCompleteException(); } } @@ -146,6 +161,13 @@ // Generate each raw source file String[] filenames = type.getAnnotation(ShowcaseRaw.class).value(); for (String filename : filenames) { + // Check if the file has already been generated. + String path = pkgName + filename; + if (rawFiles.contains(path)) { +continue; + } + rawFiles.add(path); + // Get the file contents String fileContents = getResourceContents(pkgPath + filename); @@ -230,7 +252,7 @@ * @param outDir the output directory */ private void generateStyleFiles(JClassType type, String styleDefs, - String outDir) { + String outDir) throws UnableToCompleteException { // Look for annotation if (!type.isAnnotationPresent(ShowcaseStyle.class)) { return; -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Adding a null check to ShowcaseGenerator so that we don't try to write to a public resource that... (issue646802)
committed as r8304 http://gwt-code-reviews.appspot.com/646802/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Column should not use a singleton FieldUpdater because the Cell may hang on to the FieldUpdater.... (issue620803)
Reviewers: Dan Rice, Description: Column should not use a singleton FieldUpdater because the Cell may hang on to the FieldUpdater. We now create a new instance each time. Please review this at http://gwt-code-reviews.appspot.com/620803/show Affected files: M user/src/com/google/gwt/user/cellview/client/Column.java -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Finishing implementation of ListViewAdapter. An extensive test class will be submitted in a lat... (issue636802)
Reviewers: jgw, Description: Finishing implementation of ListViewAdapter. An extensive test class will be submitted in a later change because the rest relies on API changes that haven't been submitted yet. Please review this at http://gwt-code-reviews.appspot.com/636802/show Affected files: M user/src/com/google/gwt/view/client/ListViewAdapter.java -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Fix external issue 5052 - JSONParser.parse exceptions with some unicode characters (issue659801)
Reviewers: jat, Description: Fix external issue 5052 - JSONParser.parse exceptions with some unicode characters Please review this at http://gwt-code-reviews.appspot.com/659801/show Affected files: M user/src/com/google/gwt/json/client/JSONParser.java M user/test/com/google/gwt/json/client/JSONTest.java Index: user/src/com/google/gwt/json/client/JSONParser.java === --- user/src/com/google/gwt/json/client/JSONParser.java (revision 8304) +++ user/src/com/google/gwt/json/client/JSONParser.java (working copy) @@ -48,6 +48,11 @@ throw new IllegalArgumentException(empty argument); } try { + // Escape Unicode characters that are legal in a JSON string but + // illegal in JavaScript. When we use JSON.parse() instead of eval(), + // this won't be necessary. + jsonString = jsonString.replace(\u2028, \\u2028); + jsonString = jsonString.replace(\u2029, \\u2029); return evaluate(jsonString); } catch (JavaScriptException ex) { throw new JSONException(ex); Index: user/test/com/google/gwt/json/client/JSONTest.java === --- user/test/com/google/gwt/json/client/JSONTest.java (revision 8304) +++ user/test/com/google/gwt/json/client/JSONTest.java (working copy) @@ -237,7 +237,7 @@ + \c36\:\\\n\, \c37\:\\\r\, \c38\:\\\t\, + \c39\:\/\, \c40\:\\\u2028\, \c41\:\\\u2029\}, o.toString()); } - + public void testLargeArrays() { JSONArray arr = null; for (int j = 1; j 500; j *= 2) { @@ -473,6 +473,52 @@ assertNull(array.get(0)); } + public void testUnicodeSeparators() { +/* + * ECMAScript 5 allows unescaped U+2028 (line separator) and U+2029 + * (paragraph separator) characters to occur inside strings. + */ +String jsonString = { 'name': 'miles\u2028da\u2029vis', 'ins\u2028tru\u2029ment': 'trumpet' }; +try { + JSONValue parsed = JSONParser.parse(jsonString); + JSONObject result = parsed.isObject(); + assertNotNull(result); + + JSONValue nameValue = result.get(name); + assertNotNull(nameValue); + JSONString nameJsonString = nameValue.isString(); + assertNotNull(nameJsonString); + String nameString = nameJsonString.stringValue(); + assertEquals(miles\u2028da\u2029vis, nameString); + String nameStringQuoted = nameJsonString.toString(); + assertEquals(\miles\\u2028da\\u2029vis\, nameStringQuoted); + + JSONValue instrumentValue = result.get(ins\u2028tru\u2029ment); + assertNotNull(instrumentValue); + JSONString instrumentJsonString = instrumentValue.isString(); + assertNotNull(instrumentJsonString); + String instrumentString = instrumentJsonString.stringValue(); + assertEquals(trumpet, instrumentString); +} catch (JSONException e) { + fail(); +} + +// U+2028 and U+2029 should not appear outside a string +jsonString = { 'name': 'miles davis',\u2028'instrument': 'trumpet' }; +try { + JSONParser.parse(jsonString); + fail(); +} catch (JSONException e) { +} + +jsonString = { 'name':\u2029'miles davis', 'instrument': 'trumpet' }; +try { + JSONParser.parse(jsonString); + fail(); +} catch (JSONException e) { +} + } + public void testWidget() { JSONObject v = (JSONObject) JSONParser.parse(widgetTest); JSONObject widget = (JSONObject) v.get(widget); -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Finishing implementation of ListViewAdapter. An extensive test class will be submitted in a lat... (issue636802)
On 2010/06/23 18:29:32, jlabanca wrote: LGTM. http://gwt-code-reviews.appspot.com/636802/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: DefaultSelectionModel#setSelected currently adds an exception even if the default selection stat... (issue658801)
On 2010/06/23 18:28:32, jlabanca wrote: Is there a test suite to which tese should be added? http://gwt-code-reviews.appspot.com/658801/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Fix external issue 5052 - JSONParser.parse exceptions with some unicode characters (issue659801)
http://gwt-code-reviews.appspot.com/659801/diff/1/2 File user/src/com/google/gwt/json/client/JSONParser.java (right): http://gwt-code-reviews.appspot.com/659801/diff/1/2#newcode55 user/src/com/google/gwt/json/client/JSONParser.java:55: jsonString = jsonString.replace(\u2029, \\u2029); Are you sure these are the only ones? When I looked at this before for JSONString, there were many other characters that had to be handled specially. http://gwt-code-reviews.appspot.com/659801/diff/1/3 File user/test/com/google/gwt/json/client/JSONTest.java (right): http://gwt-code-reviews.appspot.com/659801/diff/1/3#newcode240 user/test/com/google/gwt/json/client/JSONTest.java:240: Spaces. http://gwt-code-reviews.appspot.com/659801/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Fix external issue 5052 - JSONParser.parse exceptions with some unicode characters (issue659801)
http://gwt-code-reviews.appspot.com/659801/diff/1/2 File user/src/com/google/gwt/json/client/JSONParser.java (right): http://gwt-code-reviews.appspot.com/659801/diff/1/2#newcode55 user/src/com/google/gwt/json/client/JSONParser.java:55: jsonString = jsonString.replace(\u2029, \\u2029); No, I'm not sure. But note that these characters are called out specifically in the ECMAScript 5 spec, section 15.12.2 (describing JSON.parse): JSON uses a more limited set of white space characters than WhiteSpace and allows Unicode code points U+2028 and U+2029 to directly appear in JSONString literals without using an escape sequence. What other characters do you have in mind? On 2010/06/23 18:54:37, jat wrote: Are you sure these are the only ones? When I looked at this before for JSONString, there were many other characters that had to be handled specially. http://gwt-code-reviews.appspot.com/659801/diff/1/3 File user/test/com/google/gwt/json/client/JSONTest.java (right): http://gwt-code-reviews.appspot.com/659801/diff/1/3#newcode240 user/test/com/google/gwt/json/client/JSONTest.java:240: Fixed. On 2010/06/23 18:54:37, jat wrote: Spaces. http://gwt-code-reviews.appspot.com/659801/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Fix external issue 5052 - JSONParser.parse exceptions with some unicode characters (issue659801)
http://gwt-code-reviews.appspot.com/659801/diff/1/2 File user/src/com/google/gwt/json/client/JSONParser.java (right): http://gwt-code-reviews.appspot.com/659801/diff/1/2#newcode55 user/src/com/google/gwt/json/client/JSONParser.java:55: jsonString = jsonString.replace(\u2029, \\u2029); On 2010/06/23 19:02:01, Dan Rice wrote: No, I'm not sure. But note that these characters are called out specifically in the ECMAScript 5 spec, section 15.12.2 (describing JSON.parse): JSON uses a more limited set of white space characters than WhiteSpace and allows Unicode code points U+2028 and U+2029 to directly appear in JSONString literals without using an escape sequence. What other characters do you have in mind? Mostly other control characters. I would prefer to see the test actually generate strings with all these characters and verify that they come through ok. It doesn't have to be as thorough as the RPC unicode escaping test, but something along those lines would be better. http://gwt-code-reviews.appspot.com/659801/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: DefaultSelectionModel#setSelected currently adds an exception even if the default selection stat... (issue658801)
http://gwt-code-reviews.appspot.com/658801/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: DefaultSelectionModel#setSelected currently adds an exception even if the default selection stat... (issue658801)
http://gwt-code-reviews.appspot.com/658801/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: DefaultSelectionModel#setSelected currently adds an exception even if the default selection stat... (issue658801)
On 2010/06/23 19:08:30, jlabanca wrote: LGTM. http://gwt-code-reviews.appspot.com/658801/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] [google-web-toolkit] r8305 committed - Finishing implementation of ListViewAdapter. An extensive test class ...
Revision: 8305 Author: gwt.mirror...@gmail.com Date: Wed Jun 23 13:30:51 2010 Log: Finishing implementation of ListViewAdapter. An extensive test class will be submitted in a later change because the rest relies on API changes that haven't been submitted yet. Review at http://gwt-code-reviews.appspot.com/636802 Review by: j...@google.com http://code.google.com/p/google-web-toolkit/source/detail?r=8305 Modified: /trunk/user/src/com/google/gwt/view/client/ListViewAdapter.java === --- /trunk/user/src/com/google/gwt/view/client/ListViewAdapter.java Mon Jun 7 12:20:31 2010 +++ /trunk/user/src/com/google/gwt/view/client/ListViewAdapter.java Wed Jun 23 13:30:51 2010 @@ -47,7 +47,23 @@ */ private final class WrappedListIterator implements ListIteratorT { - int i = 0, last = -1; + /** + * The error message when {...@link #add(Object)} or {...@link #remove()} is + * called more than once per call to {...@link #next()} or + * {...@link #previous()}. + */ + private static final String IMPERMEABLE_EXCEPTION = Cannot call add/remove more than once per call to next/previous.; + + /** + * The index of the object that will be returned by {...@link #next()}. + */ + private int i = 0; + + /** + * The index of the last object accessed through {...@link #next()} or + * {...@link #previous()}. + */ + private int last = -1; private WrappedListIterator() { } @@ -62,6 +78,9 @@ } public void add(T o) { +if (last 0) { + throw new IllegalStateException(IMPERMEABLE_EXCEPTION); +} ListWrapper.this.add(i++, o); last = -1; } @@ -98,7 +117,7 @@ public void remove() { if (last 0) { - throw new IllegalStateException(); + throw new IllegalStateException(IMPERMEABLE_EXCEPTION); } ListWrapper.this.remove(last); i = last; @@ -118,6 +137,16 @@ */ private int curSize = 0; +/** + * The delegate wrapper. + */ +private final ListWrapper delegate; + +/** + * Set to true if the pending flush has been cancelled. + */ +private boolean flushCancelled; + /** * We wait until the end of the current event loop before flushing changes * so that we don't spam the views. This also allows users to clear and @@ -126,21 +155,11 @@ private Command flushCommand = new Command() { public void execute() { flushPending = false; - -int newSize = list.size(); -if (curSize != newSize) { - curSize = newSize; - updateDataSize(curSize, true); -} - -if (modified) { - int length = maxModified - minModified; - updateViewData(minModified, length, list.subList(minModified, - maxModified)); - modified = false; -} -minModified = Integer.MAX_VALUE; -maxModified = Integer.MIN_VALUE; +if (flushCancelled) { + flushCancelled = false; + return; +} +flushNow(); } }; @@ -154,15 +173,20 @@ */ private ListT list; +/** + * If this is a sublist, the offset it the index relative to the main list. + */ +private final int offset; + /** * If modified is true, the smallest modified index. */ -private int maxModified; +private int maxModified = Integer.MIN_VALUE; /** * If modified is true, one past the largest modified index. */ -private int minModified; +private int minModified = Integer.MAX_VALUE; /** * True if the list data has been modified. @@ -170,10 +194,21 @@ private boolean modified; public ListWrapper(ListT list) { + this(list, null, 0); +} + +/** + * Construct a new {...@link ListWrapper} that delegates flush calls to the + * specified delegate. + * + * @param list the list to wrap + * @param delegate the delegate + * @param offset the offset of this list + */ +private ListWrapper(ListT list, ListWrapper delegate, int offset) { this.list = list; - minModified = 0; - maxModified = list.size(); - modified = true; + this.delegate = delegate; + this.offset = offset; } public void add(int index, T element) { @@ -193,7 +228,8 @@ minModified = Math.min(minModified, size() - 1); maxModified = size(); modified = true; - return flush(toRet); + flush(); + return toRet; } public boolean addAll(Collection? extends T c) { @@ -201,7 +237,8 @@ boolean toRet = list.addAll(c); maxModified = size(); modified = true; - return flush(toRet); + flush(); + return toRet; } public boolean addAll(int index, Collection? extends T c) { @@ -210,7 +247,8 @@ minModified =
[gwt-contrib] [google-web-toolkit] r8306 committed - Merge trunk r8300 into this branch...
Revision: 8306 Author: j...@google.com Date: Wed Jun 23 14:35:13 2010 Log: Merge trunk r8300 into this branch Adds a workaround for a Safari 5 bug regarding right-shift operators. svn merge -c8300 --ignore-ancestry https://google-web-toolkit.googlecode.com/svn/trunk http://code.google.com/p/google-web-toolkit/source/detail?r=8306 Added: /releases/2.0/dev/core/src/com/google/gwt/dev/js/JsCoerceIntShift.java /releases/2.0/dev/core/test/com/google/gwt/dev/js/JsCoerceIntShiftTest.java Modified: /releases/2.0/branch-info.txt /releases/2.0/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java === --- /dev/null +++ /releases/2.0/dev/core/src/com/google/gwt/dev/js/JsCoerceIntShift.java Wed Jun 23 14:35:13 2010 @@ -0,0 +1,97 @@ +/* + * 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.dev.js; + +import com.google.gwt.core.ext.BadPropertyValueException; +import com.google.gwt.core.ext.PropertyOracle; +import com.google.gwt.core.ext.SelectionProperty; +import com.google.gwt.core.ext.TreeLogger; +import com.google.gwt.dev.jjs.SourceInfo; +import com.google.gwt.dev.js.ast.JsBinaryOperation; +import com.google.gwt.dev.js.ast.JsBinaryOperator; +import com.google.gwt.dev.js.ast.JsContext; +import com.google.gwt.dev.js.ast.JsExpression; +import com.google.gwt.dev.js.ast.JsModVisitor; +import com.google.gwt.dev.js.ast.JsPrefixOperation; +import com.google.gwt.dev.js.ast.JsProgram; +import com.google.gwt.dev.js.ast.JsUnaryOperator; + +/** + * Coerces lhs of right shift operations to int. Necessary for Safari 5 bug + * https://bugs.webkit.org/show_bug.cgi?id=40367 fixed in + * http://trac.webkit.org/changeset/60990 -- this should be removed once that + * fix has been pushed. + */ +public class JsCoerceIntShift { + // TODO(jat): remove this once Safari 5 has the update + + /** + * Rewrite a b as (~~a) b. + */ + private static class MyVisitor extends JsModVisitor { + +@Override +public void endVisit(JsBinaryOperation x, JsContextJsExpression ctx) { + JsBinaryOperator op = x.getOperator(); + if (op != JsBinaryOperator.SHR op != JsBinaryOperator.SHRU) { +return; + } + + SourceInfo sourceInfo = x.getSourceInfo(); + JsExpression lhs = x.getArg1(); + JsExpression rhs = x.getArg2(); + JsExpression newNode = new JsBinaryOperation(sourceInfo, op, + new JsPrefixOperation(sourceInfo, JsUnaryOperator.BIT_NOT, + new JsPrefixOperation(sourceInfo, JsUnaryOperator.BIT_NOT, lhs)), + rhs); + ctx.replaceMe(newNode); +} + } + + /** + * If this permutation may be executed on WebKit, rewrite a b as ~~a b. + * + * @param program + * @param logger + * @param propertyOracles + * @return true if any changes were made + */ + public static boolean exec(JsProgram program, TreeLogger logger, + PropertyOracle[] propertyOracles) { +boolean seenWebKit = false; +for (PropertyOracle oracle : propertyOracles) { + try { +SelectionProperty prop = oracle.getSelectionProperty(logger, +user.agent); +// TODO(jat): more checks if we split up the safari permutation +if (safari.equals(prop.getCurrentValue())) { + seenWebKit = true; + break; +} + } catch (BadPropertyValueException e) { +// if we couldn't get the property, assume this might be used on WebKit. +seenWebKit = true; +break; + } +} +if (!seenWebKit) { + return false; +} +MyVisitor v = new MyVisitor(); +v.accept(program); +return v.didChange(); + } +} === --- /dev/null +++ /releases/2.0/dev/core/test/com/google/gwt/dev/js/JsCoerceIntShiftTest.java Wed Jun 23 14:35:13 2010 @@ -0,0 +1,168 @@ +/* + * 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
[gwt-contrib] [google-web-toolkit] r8307 committed - Merged trunk r8293 into this branch...
Revision: 8307 Author: j...@google.com Date: Wed Jun 23 14:48:11 2010 Log: Merged trunk r8293 into this branch Escaping HTML strings from the client as a good practice to avoid XSS vulnerabilities in apps the build off of the default app. svn merge -c8293 --ignore-ancestry https://google-web-toolkit.googlecode.com/svn/trunk http://code.google.com/p/google-web-toolkit/source/detail?r=8307 Modified: /releases/2.0/branch-info.txt /releases/2.0/user/src/com/google/gwt/user/tools/RpcServerTemplate.javasrc === --- /releases/2.0/branch-info.txt Wed Jun 23 14:35:13 2010 +++ /releases/2.0/branch-info.txt Wed Jun 23 14:48:11 2010 @@ -1514,3 +1514,8 @@ tr...@r8300 was merged into this branch Adds a workaround for a Safari 5 bug regarding right-shift operators. svn merge -c8300 --ignore-ancestry https://google-web-toolkit.googlecode.com/svn/trunk + +tr...@r8293 was merged into this branch + Escaping HTML strings from the client as a good practice to avoid XSS vulnerabilities in apps + the build off of the default app. + svn merge -c8293 --ignore-ancestry https://google-web-toolkit.googlecode.com/svn/trunk === --- /releases/2.0/user/src/com/google/gwt/user/tools/RpcServerTemplate.javasrc Fri Jan 15 13:43:11 2010 +++ /releases/2.0/user/src/com/google/gwt/user/tools/RpcServerTemplate.javasrc Wed Jun 23 14:48:11 2010 @@ -22,7 +22,27 @@ String serverInfo = getServletContext().getServerInfo(); String userAgent = getThreadLocalRequest().getHeader(User-Agent); + +// Escape data from the client to avoid cross-site script vulnerabilities. +input = escapeHtml(input); +userAgent = escapeHtml(userAgent); + return Hello, + input + !brbrI am running + serverInfo + .brbrIt looks like you are using:br + userAgent; } -} + + /** + * Escape an html string. Escaping data received from the client helps to + * prevent cross-site script vulnerabilities. + * + * @param html the html string to escape + * @return the escaped string + */ + private String escapeHtml(String html) { +if (html == null) { + return null; +} +return html.replaceAll(, amp;).replaceAll(, lt;).replaceAll( +, gt;); + } +} -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Bye Bye Boilerplate patch. No static configuration required for servlet (issue661801)
Reviewers: cromwellian, Description: Bye Bye Boilerplate patch. No static configuration required for servlet beyond @Service annotations on request interfaces and @DataTransferObject annotations on Record types. TOKEN no longer required on Record types, as the class itself is used as a token. Introduced OperationRegistry and RequestSecurityProvider interfaces. Removed the no longer used annotations: ServerType, ServerOperation. Deleted ExpensesServerSideOperations. Review by: cromwell...@google.com Please review this at http://gwt-code-reviews.appspot.com/661801/show Affected files: M bikeshed/src/com/google/gwt/app/place/AbstractRecordEditActivity.java M bikeshed/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java A bikeshed/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java A bikeshed/src/com/google/gwt/requestfactory/server/OperationRegistry.java A bikeshed/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java M bikeshed/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java A bikeshed/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java A bikeshed/src/com/google/gwt/requestfactory/shared/DataTransferObject.java M bikeshed/src/com/google/gwt/requestfactory/shared/RequestFactory.java D bikeshed/src/com/google/gwt/requestfactory/shared/ServerOperation.java D bikeshed/src/com/google/gwt/requestfactory/shared/ServerType.java A bikeshed/src/com/google/gwt/requestfactory/shared/Service.java M bikeshed/src/com/google/gwt/sample/expenses/gwt/client/MobileExpenseEntry.java M bikeshed/src/com/google/gwt/sample/expenses/gwt/client/MobileReportEntry.java M bikeshed/src/com/google/gwt/sample/expenses/gwt/request/EmployeeRecord.java M bikeshed/src/com/google/gwt/sample/expenses/gwt/request/EmployeeRequest.java M bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ExpenseRecord.java M bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ExpenseRequest.java D bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ExpensesServerSideOperations.java M bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ReportRecord.java M bikeshed/src/com/google/gwt/sample/expenses/gwt/request/ReportRequest.java M bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/employee/EmployeeEditActivity.java M bikeshed/src/com/google/gwt/sample/expenses/gwt/ui/report/ReportEditActivity.java M bikeshed/src/com/google/gwt/valuestore/client/DeltaValueStoreJsonImpl.java M bikeshed/src/com/google/gwt/valuestore/shared/DeltaValueStore.java M bikeshed/src/com/google/gwt/valuestore/shared/impl/RecordSchema.java M bikeshed/src/com/google/gwt/valuestore/shared/impl/RecordToTypeMap.java A bikeshed/test/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistryTest.java A bikeshed/test/com/google/gwt/requestfactory/server/SimpleFoo.java A bikeshed/test/com/google/gwt/requestfactory/server/SimpleFooRequest.java M bikeshed/test/com/google/gwt/valuestore/client/DeltaValueStoreJsonImplTest.java M bikeshed/test/com/google/gwt/valuestore/shared/SimpleFooRecord.java M bikeshed/test/com/google/gwt/valuestore/shared/impl/SimpleFooRecordImpl.java M bikeshed/war/WEB-INF/web.xml -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Bye Bye Boilerplate patch. No static configuration required for servlet (issue661801)
This time with the correct URL http://gwt-code-reviews.appspot.com/648802/show On 2010/06/23 23:13:19, amitmanjhi wrote: On 2010/06/23 23:07:45, amitmanjhi wrote: Patch is updated version of Ray Cromwell's original patch: http://gwt-code-reviews.appspot.com/661801 http://gwt-code-reviews.appspot.com/661801/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: List.subList not fully compatibile with java.util.List interface. (issue620802)
Slightly different fix committed to trunk at r8308. http://gwt-code-reviews.appspot.com/620802/show -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Added the api warning for newly added classes. (issue619804)
Reviewers: Ray Ryan, Description: Added the api warning for newly added classes. Patch by: amitmanjhi Review by: rjrjr (tbr) Please review this at http://gwt-code-reviews.appspot.com/619804/show Affected files: M bikeshed/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java M bikeshed/src/com/google/gwt/requestfactory/server/OperationRegistry.java M bikeshed/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java M bikeshed/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java M bikeshed/src/com/google/gwt/requestfactory/shared/Service.java Index: bikeshed/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java === --- bikeshed/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java (revision 8309) +++ bikeshed/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java (working copy) @@ -18,6 +18,11 @@ import com.google.gwt.requestfactory.shared.Service; /** + * p + * span style=color:redExperimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * /span + * /p * A security provider that enforces {...@link com.google.gwt.requestfactory.shared.Service} * annotations. */ Index: bikeshed/src/com/google/gwt/requestfactory/server/OperationRegistry.java === --- bikeshed/src/com/google/gwt/requestfactory/server/OperationRegistry.java (revision 8309) +++ bikeshed/src/com/google/gwt/requestfactory/server/OperationRegistry.java (working copy) @@ -18,6 +18,11 @@ import com.google.gwt.requestfactory.shared.RequestFactory; /** + * p + * span style=color:redExperimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * /span + * /p * Maps operation name to {RequestDefinition}. */ public interface OperationRegistry { Index: bikeshed/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java === --- bikeshed/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java (revision 8309) +++ bikeshed/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java (working copy) @@ -27,6 +27,11 @@ import java.util.List; /** + * p + * span style=color:redExperimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * /span + * /p * OperationRegistry which uses the operation name as a convention for * reflection to a method on a class, and returns an appropriate {...@link * com.google.gwt.requestfactory.shared.RequestFactory.RequestDefinition}. Index: bikeshed/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java === --- bikeshed/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java (revision 8309) +++ bikeshed/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java (working copy) @@ -16,6 +16,11 @@ package com.google.gwt.requestfactory.server; /** + * p + * span style=color:redExperimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * /span + * /p * Enforces security policy for operations and classes, as well as permitting * request obfuscation. */ Index: bikeshed/src/com/google/gwt/requestfactory/shared/Service.java === --- bikeshed/src/com/google/gwt/requestfactory/shared/Service.java (revision 8309) +++ bikeshed/src/com/google/gwt/requestfactory/shared/Service.java (working copy) @@ -21,6 +21,11 @@ import java.lang.annotation.Target; /** + * p + * span style=color:redExperimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * /span + * /p * Annotation on Request classes specifying the server side implementations that * back them. */ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] [google-web-toolkit] r8310 committed - Added the api warning for newly added classes....
Revision: 8310 Author: amitman...@google.com Date: Wed Jun 23 15:29:19 2010 Log: Added the api warning for newly added classes. Patch by: amitmanjhi Review by: rjrjr (tbr) Review at http://gwt-code-reviews.appspot.com/619804 http://code.google.com/p/google-web-toolkit/source/detail?r=8310 Modified: /trunk/bikeshed/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java /trunk/bikeshed/src/com/google/gwt/requestfactory/server/OperationRegistry.java /trunk/bikeshed/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java /trunk/bikeshed/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java /trunk/bikeshed/src/com/google/gwt/requestfactory/shared/Service.java === --- /trunk/bikeshed/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java Wed Jun 23 14:38:51 2010 +++ /trunk/bikeshed/src/com/google/gwt/requestfactory/server/DefaultSecurityProvider.java Wed Jun 23 15:29:19 2010 @@ -18,6 +18,11 @@ import com.google.gwt.requestfactory.shared.Service; /** + * p + * span style=color:redExperimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * /span + * /p * A security provider that enforces {...@link com.google.gwt.requestfactory.shared.Service} * annotations. */ === --- /trunk/bikeshed/src/com/google/gwt/requestfactory/server/OperationRegistry.java Wed Jun 23 14:38:51 2010 +++ /trunk/bikeshed/src/com/google/gwt/requestfactory/server/OperationRegistry.java Wed Jun 23 15:29:19 2010 @@ -18,6 +18,11 @@ import com.google.gwt.requestfactory.shared.RequestFactory; /** + * p + * span style=color:redExperimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * /span + * /p * Maps operation name to {RequestDefinition}. */ public interface OperationRegistry { === --- /trunk/bikeshed/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java Wed Jun 23 14:38:51 2010 +++ /trunk/bikeshed/src/com/google/gwt/requestfactory/server/ReflectionBasedOperationRegistry.java Wed Jun 23 15:29:19 2010 @@ -27,6 +27,11 @@ import java.util.List; /** + * p + * span style=color:redExperimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * /span + * /p * OperationRegistry which uses the operation name as a convention for * reflection to a method on a class, and returns an appropriate {...@link * com.google.gwt.requestfactory.shared.RequestFactory.RequestDefinition}. === --- /trunk/bikeshed/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java Wed Jun 23 14:38:51 2010 +++ /trunk/bikeshed/src/com/google/gwt/requestfactory/server/RequestSecurityProvider.java Wed Jun 23 15:29:19 2010 @@ -16,6 +16,11 @@ package com.google.gwt.requestfactory.server; /** + * p + * span style=color:redExperimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * /span + * /p * Enforces security policy for operations and classes, as well as permitting * request obfuscation. */ === --- /trunk/bikeshed/src/com/google/gwt/requestfactory/shared/Service.java Wed Jun 23 14:38:51 2010 +++ /trunk/bikeshed/src/com/google/gwt/requestfactory/shared/Service.java Wed Jun 23 15:29:19 2010 @@ -21,6 +21,11 @@ import java.lang.annotation.Target; /** + * p + * span style=color:redExperimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * /span + * /p * Annotation on Request classes specifying the server side implementations that * back them. */ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors