Adds dual key (type + source) handler binding to EventBus. RequestFactory sets the class of a proxy type as the source for EntityProxyChange events, so that subscribers can still listen for events only of specific proxy types. It is no longer necessary for a RequestFactory user to define their own change event types. Renames EntityProxyChange event to better follow convention. Refactors HandlerManager.HandlerRegistry into a new public class, SimpleEventBus. MultiFire, default source stamping, and event recycling are left as features of HandlerManager. HandlerManager no longer implements EventBus interface, in the interest of less confusing API for EventBus users. Note the new static register methods on our event types. It seems better to keep clients from having to know about our TYPE constants. This is also the only way to provide foolproof type safe registration for the parameterized proxy change events. Review at http://gwt-code-reviews.appspot.com/841804 git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8756 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/DynaTableRf.java b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/DynaTableRf.java index ab145eb..37350c0 100644 --- a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/DynaTableRf.java +++ b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/DynaTableRf.java
@@ -19,7 +19,7 @@ import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT.UncaughtExceptionHandler; import com.google.gwt.event.shared.EventBus; -import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.sample.dynatablerf.client.widgets.DayFilterWidget; import com.google.gwt.sample.dynatablerf.client.widgets.FavoritesWidget; import com.google.gwt.sample.dynatablerf.client.widgets.SummaryWidget; @@ -46,7 +46,7 @@ @UiField(provided = true) SummaryWidget calendar; - EventBus eventBus = new HandlerManager(null); + EventBus eventBus = new SimpleEventBus(); @UiField(provided = true) FavoritesWidget favorites;
diff --git a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/FavoritesManager.java b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/FavoritesManager.java index 1e32f74..fdaae1e 100644 --- a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/FavoritesManager.java +++ b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/FavoritesManager.java
@@ -16,8 +16,8 @@ package com.google.gwt.sample.dynatablerf.client; import com.google.gwt.event.shared.EventBus; -import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.sample.dynatablerf.client.events.MarkFavoriteEvent; import com.google.gwt.sample.dynatablerf.shared.PersonProxy; import com.google.gwt.user.client.Cookies; @@ -34,7 +34,7 @@ */ public class FavoritesManager { private static final String COOKIE_NAME = "Favorites"; - private final EventBus eventBus = new HandlerManager(this); + private final EventBus eventBus = new SimpleEventBus(); private final Set<Long> favoriteIds = new HashSet<Long>(); public FavoritesManager() { @@ -89,6 +89,6 @@ favoriteIds.remove(person.getId()); } - eventBus.fireEvent(new MarkFavoriteEvent(person, isFavorite)); + eventBus.fireEventFromSource(new MarkFavoriteEvent(person, isFavorite), this); } }
diff --git a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/widgets/SummaryWidget.java b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/widgets/SummaryWidget.java index 2e1df02..532a0fe 100644 --- a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/widgets/SummaryWidget.java +++ b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/client/widgets/SummaryWidget.java
@@ -18,6 +18,7 @@ import com.google.gwt.cell.client.TextCell; import com.google.gwt.core.client.GWT; import com.google.gwt.event.shared.EventBus; +import com.google.gwt.requestfactory.shared.EntityProxyChange; import com.google.gwt.requestfactory.shared.Receiver; import com.google.gwt.requestfactory.shared.SyncResult; import com.google.gwt.requestfactory.shared.WriteOperation; @@ -25,14 +26,13 @@ import com.google.gwt.sample.dynatablerf.client.events.EditPersonEvent; import com.google.gwt.sample.dynatablerf.shared.DynaTableRequestFactory; import com.google.gwt.sample.dynatablerf.shared.PersonProxy; -import com.google.gwt.sample.dynatablerf.shared.PersonProxyChanged; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.cellview.client.CellTable; +import com.google.gwt.user.cellview.client.CellTable.CleanStyle; import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.cellview.client.SimplePager; -import com.google.gwt.user.cellview.client.CellTable.CleanStyle; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.DockLayoutPanel; import com.google.gwt.user.client.ui.Widget; @@ -134,23 +134,23 @@ table.setRowCount(numRows, false); table.setSelectionModel(selectionModel); - eventBus.addHandler(PersonProxyChanged.TYPE, - new PersonProxyChanged.Handler() { - public void onPersonChanged(PersonProxyChanged event) { + EntityProxyChange.registerForProxyType(eventBus, PersonProxy.class, + new EntityProxyChange.Handler<PersonProxy>() { + public void onProxyChange(EntityProxyChange<PersonProxy> event) { SummaryWidget.this.onPersonChanged(event); } }); selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { public void onSelectionChange(SelectionChangeEvent event) { - SummaryWidget.this.onSelectionChange(event); + SummaryWidget.this.refreshSelection(); } }); fetch(0); } - void onPersonChanged(PersonProxyChanged event) { + void onPersonChanged(EntityProxyChange<PersonProxy> event) { if (WriteOperation.UPDATE.equals(event.getWriteOperation())) { PersonProxy record = event.getProxy(); @@ -182,7 +182,7 @@ fetch(start); } - void onSelectionChange(SelectionChangeEvent event) { + void refreshSelection() { PersonProxy person = selectionModel.getSelectedObject(); if (person == null) { return;
diff --git a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/AddressProxyChanged.java b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/AddressProxyChanged.java deleted file mode 100644 index dd341ee..0000000 --- a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/AddressProxyChanged.java +++ /dev/null
@@ -1,51 +0,0 @@ -/* - * 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.sample.dynatablerf.shared; - -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.GwtEvent; -import com.google.gwt.requestfactory.shared.EntityProxyChangedEvent; -import com.google.gwt.requestfactory.shared.WriteOperation; - -/** - * This class will no longer be necessary pending HandlerManager changes. - */ -public class AddressProxyChanged extends - EntityProxyChangedEvent<AddressProxy, AddressProxyChanged.Handler> { - - /** - * Implemented by handlers of this type of event. - */ - public interface Handler extends EventHandler { - void onAddressChanged(AddressProxyChanged event); - } - - public static final Type<Handler> TYPE = new Type<Handler>(); - - public AddressProxyChanged(AddressProxy record, WriteOperation writeOperation) { - super(record, writeOperation); - } - - @Override - public GwtEvent.Type<Handler> getAssociatedType() { - return TYPE; - } - - @Override - protected void dispatch(Handler handler) { - handler.onAddressChanged(this); - } -}
diff --git a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/PersonProxyChanged.java b/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/PersonProxyChanged.java deleted file mode 100644 index 2265144..0000000 --- a/samples/dynatablerf/src/com/google/gwt/sample/dynatablerf/shared/PersonProxyChanged.java +++ /dev/null
@@ -1,51 +0,0 @@ -/* - * 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.sample.dynatablerf.shared; - -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.GwtEvent; -import com.google.gwt.requestfactory.shared.EntityProxyChangedEvent; -import com.google.gwt.requestfactory.shared.WriteOperation; - -/** - * This class will no longer be necessary pending HandlerManager changes. - */ -public class PersonProxyChanged extends - EntityProxyChangedEvent<PersonProxy, PersonProxyChanged.Handler> { - - /** - * Implemented by handlers of this type of event. - */ - public interface Handler extends EventHandler { - void onPersonChanged(PersonProxyChanged event); - } - - public static final Type<Handler> TYPE = new Type<Handler>(); - - public PersonProxyChanged(PersonProxy record, WriteOperation writeOperation) { - super(record, writeOperation); - } - - @Override - public GwtEvent.Type<Handler> getAssociatedType() { - return TYPE; - } - - @Override - protected void dispatch(Handler handler) { - handler.onPersonChanged(this); - } -}
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseDetails.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseDetails.java index 24a199b..c262683 100644 --- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseDetails.java +++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseDetails.java
@@ -37,23 +37,24 @@ import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; +import com.google.gwt.event.shared.EventBus; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.NumberFormat; -import com.google.gwt.requestfactory.shared.Receiver; import com.google.gwt.requestfactory.shared.EntityProxy; +import com.google.gwt.requestfactory.shared.EntityProxyChange; +import com.google.gwt.requestfactory.shared.Receiver; import com.google.gwt.requestfactory.shared.RequestObject; import com.google.gwt.requestfactory.shared.SyncResult; import com.google.gwt.resources.client.ImageResource; import com.google.gwt.safehtml.client.SafeHtmlTemplates; +import com.google.gwt.safehtml.client.SafeHtmlTemplates.Template; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.safehtml.shared.SafeHtmlUtils; import com.google.gwt.sample.expenses.client.request.EmployeeProxy; import com.google.gwt.sample.expenses.client.request.ExpenseProxy; -import com.google.gwt.sample.expenses.client.request.ExpenseProxyChanged; import com.google.gwt.sample.expenses.client.request.ExpensesRequestFactory; import com.google.gwt.sample.expenses.client.request.ReportProxy; -import com.google.gwt.sample.expenses.client.request.ReportProxyChanged; import com.google.gwt.sample.expenses.client.style.Styles; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiFactory; @@ -89,8 +90,7 @@ * Details about the current expense report on the right side of the app, * including the list of expenses. */ -public class ExpenseDetails extends Composite - implements ExpenseProxyChanged.Handler, ReportProxyChanged.Handler { +public class ExpenseDetails extends Composite { interface Template extends SafeHtmlTemplates { @Template("<select style=\"background-color:white;border:1px solid " @@ -501,12 +501,29 @@ } }); } + + public void init(EventBus eventBus) { + EntityProxyChange.registerForProxyType(eventBus, + ExpenseProxy.class, new EntityProxyChange.Handler<ExpenseProxy>() { + @Override + public void onProxyChange(EntityProxyChange<ExpenseProxy> event) { + onExpenseRecordChanged(event); + } + }); + EntityProxyChange.registerForProxyType(eventBus, + ReportProxy.class, new EntityProxyChange.Handler<ReportProxy>() { + @Override + public void onProxyChange(EntityProxyChange<ReportProxy> event) { + onReportChanged(event); + } + }); + } public Anchor getReportsLink() { return reportsLink; } - public void onExpenseRecordChanged(ExpenseProxyChanged event) { + public void onExpenseRecordChanged(EntityProxyChange<ExpenseProxy> event) { ExpenseProxy newRecord = event.getProxy(); Object newKey = items.getKey(newRecord); @@ -532,7 +549,7 @@ } } - public void onReportChanged(ReportProxyChanged event) { + public void onReportChanged(EntityProxyChange<ReportProxy> event) { ReportProxy changed = event.getProxy(); if (report != null && report.getId().equals(changed.getId())) { // Request the updated report.
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseList.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseList.java index c42d15c..2fb8b48 100644 --- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseList.java +++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseList.java
@@ -1,12 +1,12 @@ /* * 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 @@ -31,8 +31,10 @@ import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; +import com.google.gwt.event.shared.EventBus; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.regexp.shared.RegExp; +import com.google.gwt.requestfactory.shared.EntityProxyChange; import com.google.gwt.requestfactory.shared.Property; import com.google.gwt.requestfactory.shared.Receiver; import com.google.gwt.requestfactory.shared.SyncResult; @@ -41,7 +43,6 @@ import com.google.gwt.sample.expenses.client.request.EmployeeProxy; import com.google.gwt.sample.expenses.client.request.ExpensesRequestFactory; import com.google.gwt.sample.expenses.client.request.ReportProxy; -import com.google.gwt.sample.expenses.client.request.ReportProxyChanged; import com.google.gwt.sample.expenses.client.style.Styles; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiFactory; @@ -70,34 +71,44 @@ /** * The list of expense reports on the right side of the app. */ -public class ExpenseList extends Composite - implements ReportProxyChanged.Handler { +public class ExpenseList extends Composite implements + EntityProxyChange.Handler<ReportProxy> { + + interface ExpenseListUiBinder extends UiBinder<Widget, ExpenseList> { + } /** - * The auto refresh interval in milliseconds. + * Custom listener for this widget. */ - private static final int REFRESH_INTERVAL = 5000; + interface Listener { - private static ExpenseListUiBinder uiBinder = GWT.create( - ExpenseListUiBinder.class); + /** + * Called when the user selects a report. + * + * @param report the selected report + */ + void onReportSelected(ReportProxy report); + } /** - * Utility method to get the first part of the breadcrumb based on the - * department and employee. - * - * @param department the selected department - * @param employee the selected employee - * @return the breadcrumb + * The resources applied to the table. */ - public static String getBreadcrumb( - String department, EmployeeProxy employee) { - if (employee != null) { - return "Reports for " + employee.getDisplayName(); - } else if (department != null) { - return "Reports for " + department; - } else { - return "All Reports"; - } + interface TableResources extends CellTable.CleanResources { + @Source("ExpenseListCellTable.css") + TableStyle cellTableStyle(); + } + + /** + * The styles applied to the table. + */ + interface TableStyle extends CellTable.CleanStyle { + String evenRow(); + + String hoveredRow(); + + String oddRow(); + + String selectedRow(); } /** @@ -147,56 +158,20 @@ } } - interface ExpenseListUiBinder extends UiBinder<Widget, ExpenseList> { - } - /** - * Custom listener for this widget. - */ - interface Listener { - - /** - * Called when the user selects a report. - * - * @param report the selected report - */ - void onReportSelected(ReportProxy report); - } - - /** - * The styles applied to the table. - */ - interface TableStyle extends CellTable.CleanStyle { - String evenRow(); - - String hoveredRow(); - - String oddRow(); - - String selectedRow(); - } - - /** - * The resources applied to the table. - */ - interface TableResources extends CellTable.CleanResources { - @Source("ExpenseListCellTable.css") - TableStyle cellTableStyle(); - } - /** * A cell used to highlight search text. */ private class HighlightCell extends AbstractCell<String> { - private static final String replaceString = - "<span style='color:red;font-weight:bold;'>$1</span>"; + private static final String replaceString = "<span style='color:red;font-weight:bold;'>$1</span>"; @Override public void render(String value, Object viewData, SafeHtmlBuilder sb) { if (value != null) { if (searchRegExp != null) { // The search regex has already been html-escaped - value = searchRegExp.replace(SafeHtmlUtils.htmlEscape(value), replaceString); + value = searchRegExp.replace(SafeHtmlUtils.htmlEscape(value), + replaceString); sb.append(SafeHtmlUtils.fromTrustedString(value)); } else { sb.appendEscaped(value); @@ -204,7 +179,6 @@ } } } - /** * The data provider used to retrieve reports. */ @@ -215,15 +189,40 @@ } } + /** + * The auto refresh interval in milliseconds. + */ + private static final int REFRESH_INTERVAL = 5000; + + private static ExpenseListUiBinder uiBinder = GWT.create(ExpenseListUiBinder.class); + + /** + * Utility method to get the first part of the breadcrumb based on the + * department and employee. + * + * @param department the selected department + * @param employee the selected employee + * @return the breadcrumb + */ + public static String getBreadcrumb(String department, EmployeeProxy employee) { + if (employee != null) { + return "Reports for " + employee.getDisplayName(); + } else if (department != null) { + return "Reports for " + department; + } else { + return "All Reports"; + } + } + @UiField Element breadcrumb; + @UiField SimplePager pager; @UiField(provided = true) DefaultTextBox searchBox; @UiField Image searchButton; - /** * The main table. We provide this in the constructor before calling * {@link UiBinder#createAndBindUi(Object)} because the pager depends on it. @@ -285,7 +284,7 @@ /** * The columns to request with each report. */ - private final String[] reportColumns = new String[]{ + private final String[] reportColumns = new String[] { ReportProxy.created.getName(), ReportProxy.purpose.getName(), ReportProxy.notes.getName()}; @@ -346,7 +345,7 @@ }); } - public void onReportChanged(ReportProxyChanged event) { + public void onProxyChange(EntityProxyChange<ReportProxy> event) { ReportProxy changed = event.getProxy(); Long changedId = changed.getId(); List<ReportProxy> records = table.getDisplayedItems(); @@ -363,7 +362,7 @@ /** * Set the current department and employee to filter on. - * + * * @param department the department, or null if none selected * @param employee the employee, or null if none selected */ @@ -385,7 +384,8 @@ this.listener = listener; } - public void setRequestFactory(ExpensesRequestFactory factory) { + public void init(ExpensesRequestFactory factory, EventBus eventBus) { + EntityProxyChange.registerForProxyType(eventBus, ReportProxy.class, this); this.requestFactory = factory; requestReports(false); } @@ -400,7 +400,7 @@ /** * Add a sortable column to the table. - * + * * @param <C> the data type for the column * @param text the header text * @param cell the cell used to render the column @@ -471,41 +471,39 @@ table.addColumnStyleName(5, common.spacerColumn()); // Add a selection model. - final NoSelectionModel<ReportProxy> selectionModel = new NoSelectionModel< - ReportProxy>(); + final NoSelectionModel<ReportProxy> selectionModel = new NoSelectionModel<ReportProxy>(); table.setSelectionModel(selectionModel); - selectionModel.addSelectionChangeHandler( - new SelectionChangeEvent.Handler() { - public void onSelectionChange(SelectionChangeEvent event) { - Object selected = selectionModel.getLastSelectedObject(); - if (selected != null && listener != null) { - listener.onReportSelected((ReportProxy) selected); - } - } - }); + selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { + public void onSelectionChange(SelectionChangeEvent event) { + Object selected = selectionModel.getLastSelectedObject(); + if (selected != null && listener != null) { + listener.onReportSelected((ReportProxy) selected); + } + } + }); // Spacer column. table.addColumn(new SpacerColumn<ReportProxy>()); // Purpose column. - addColumn( - "Purpose", new HighlightCell(), new GetValue<ReportProxy, String>() { + addColumn("Purpose", new HighlightCell(), + new GetValue<ReportProxy, String>() { public String getValue(ReportProxy object) { return object.getPurpose(); } }, ReportProxy.purpose); // Notes column. - addColumn( - "Notes", new HighlightCell(), new GetValue<ReportProxy, String>() { + addColumn("Notes", new HighlightCell(), + new GetValue<ReportProxy, String>() { public String getValue(ReportProxy object) { return object.getNotes(); } }, ReportProxy.notes); // Department column. - addColumn( - "Department", new TextCell(), new GetValue<ReportProxy, String>() { + addColumn("Department", new TextCell(), + new GetValue<ReportProxy, String>() { public String getValue(ReportProxy object) { return object.getDepartment(); } @@ -525,7 +523,7 @@ /** * Send a request for reports in the current range. - * + * * @param isPolling true if this request is caused by polling */ private void requestReports(boolean isPolling) { @@ -575,14 +573,14 @@ } } }; - requestFactory.reportRequest().countReportsBySearch( - employeeId, dept, startsWith).fire(lastDataSizeReceiver); + requestFactory.reportRequest().countReportsBySearch(employeeId, dept, + startsWith).fire(lastDataSizeReceiver); } // Request reports in the current range. lastDataReceiver = new Receiver<List<ReportProxy>>() { - public void onSuccess( - List<ReportProxy> newValues, Set<SyncResult> syncResults) { + public void onSuccess(List<ReportProxy> newValues, + Set<SyncResult> syncResults) { if (this == lastDataReceiver) { int size = newValues.size(); if (size < table.getPageSize()) { @@ -601,8 +599,8 @@ for (ReportProxy value : newValues) { Object key = reports.getKey(value); if (!isInitialData && !knownReportKeys.contains(key)) { - (new PhaseAnimation.CellTablePhaseAnimation<ReportProxy>( - table, value, reports)).run(); + (new PhaseAnimation.CellTablePhaseAnimation<ReportProxy>(table, + value, reports)).run(); } knownReportKeys.add(key); }
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/Expenses.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/Expenses.java index b062777..c86d0c8 100644 --- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/Expenses.java +++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/Expenses.java
@@ -17,7 +17,8 @@ import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; -import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.requestfactory.client.AuthenticationFailureHandler; import com.google.gwt.requestfactory.client.LoginWidget; import com.google.gwt.requestfactory.shared.Receiver; @@ -29,10 +30,8 @@ import com.google.gwt.safehtml.shared.SafeHtmlUtils; import com.google.gwt.sample.expenses.client.request.EmployeeProxy; import com.google.gwt.sample.expenses.client.request.ExpenseProxy; -import com.google.gwt.sample.expenses.client.request.ExpenseProxyChanged; import com.google.gwt.sample.expenses.client.request.ExpensesRequestFactory; import com.google.gwt.sample.expenses.client.request.ReportProxy; -import com.google.gwt.sample.expenses.client.request.ReportProxyChanged; import com.google.gwt.sample.expenses.client.style.Styles; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.Window.Location; @@ -143,7 +142,7 @@ } }); - final HandlerManager eventBus = new HandlerManager(null); + final EventBus eventBus = new SimpleEventBus(); requestFactory = GWT.create(ExpensesRequestFactory.class); requestFactory.init(eventBus); @@ -157,7 +156,7 @@ root.add(shell); // Check for Authentication failures or mismatches - eventBus.addHandler(RequestEvent.TYPE, new AuthenticationFailureHandler()); + RequestEvent.register(eventBus, new AuthenticationFailureHandler()); // Add a login widget to the page final LoginWidget login = shell.getLoginWidget(); @@ -188,11 +187,7 @@ shell.showExpenseDetails(true); } }); - expenseList.setRequestFactory(requestFactory); - eventBus.addHandler(ReportProxyChanged.TYPE, expenseList); - - // Forward change events to the expense details. - eventBus.addHandler(ExpenseProxyChanged.TYPE, expenseDetails); - eventBus.addHandler(ReportProxyChanged.TYPE, expenseDetails); + expenseList.init(requestFactory, eventBus); + expenseDetails.init(eventBus); } }
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java index d34ea9f..6e455ce 100644 --- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java +++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java
@@ -17,7 +17,8 @@ import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; -import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.requestfactory.client.AuthenticationFailureHandler; import com.google.gwt.requestfactory.client.LoginWidget; import com.google.gwt.requestfactory.shared.Receiver; @@ -46,7 +47,7 @@ /** * TODO(jgw): Put this some place more sensible. - * + * * @param amount the amount in dollars */ public static String formatCurrency(double amount) { @@ -81,10 +82,10 @@ GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() { public void onUncaughtException(Throwable e) { Window.alert("Error: " + e.getMessage()); -// placeController.goTo(Place.NOWHERE); + // placeController.goTo(Place.NOWHERE); } }); - + // Get the employee ID from the URL. long employeeId = 1; try { @@ -97,9 +98,8 @@ return; } - final HandlerManager eventBus = new HandlerManager(null); - final ExpensesRequestFactory requestFactory = GWT.create( - ExpensesRequestFactory.class); + final EventBus eventBus = new SimpleEventBus(); + final ExpensesRequestFactory requestFactory = GWT.create(ExpensesRequestFactory.class); requestFactory.init(eventBus); requestFactory.employeeRequest().findEmployee(Value.of(employeeId)).fire( @@ -111,13 +111,11 @@ RootPanel.get().add(shell); // Check for Authentication failures or mismatches - eventBus.addHandler(RequestEvent.TYPE, - new AuthenticationFailureHandler()); + RequestEvent.register(eventBus, new AuthenticationFailureHandler()); // Add a login widget to the page final LoginWidget login = shell.getLoginWidget(); - Receiver<UserInformationProxy> receiver - = new Receiver<UserInformationProxy>() { + Receiver<UserInformationProxy> receiver = new Receiver<UserInformationProxy>() { public void onSuccess(UserInformationProxy userInformationRecord, Set<SyncResult> syncResults) { login.setUserInformation(userInformationRecord);
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobileShell.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobileShell.java index 917a320..e2416d4 100644 --- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobileShell.java +++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobileShell.java
@@ -18,7 +18,7 @@ import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.EventBus; import com.google.gwt.requestfactory.client.LoginWidget; import com.google.gwt.sample.expenses.client.request.EmployeeProxy; import com.google.gwt.sample.expenses.client.request.ExpenseProxy; @@ -54,11 +54,11 @@ private MobileReportEntry reportEntry; private final EmployeeProxy employee; - private final HandlerManager eventBus; + private final EventBus eventBus; private final ExpensesRequestFactory requestFactory; private ArrayList<MobilePage> pages = new ArrayList<MobilePage>(); - public ExpensesMobileShell(HandlerManager eventBus, + public ExpensesMobileShell(EventBus eventBus, ExpensesRequestFactory requestFactory, EmployeeProxy employee) { this.eventBus = eventBus; this.requestFactory = requestFactory;
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseDetails.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseDetails.java index baabc59..4bdf00e 100644 --- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseDetails.java +++ b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileExpenseDetails.java
@@ -18,13 +18,13 @@ import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Display; -import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.EventBus; import com.google.gwt.i18n.client.DateTimeFormat; +import com.google.gwt.requestfactory.shared.EntityProxyChange; import com.google.gwt.requestfactory.shared.PropertyReference; import com.google.gwt.requestfactory.shared.Receiver; import com.google.gwt.requestfactory.shared.SyncResult; import com.google.gwt.sample.expenses.client.request.ExpenseProxy; -import com.google.gwt.sample.expenses.client.request.ExpenseProxyChanged; import com.google.gwt.sample.expenses.client.request.ExpensesRequestFactory; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; @@ -59,14 +59,14 @@ private final Listener listener; private final ExpensesRequestFactory requestFactory; - public MobileExpenseDetails(Listener listener, HandlerManager eventBus, + public MobileExpenseDetails(Listener listener, EventBus eventBus, ExpensesRequestFactory requestFactory) { this.listener = listener; this.requestFactory = requestFactory; - eventBus.addHandler(ExpenseProxyChanged.TYPE, - new ExpenseProxyChanged.Handler() { - public void onExpenseRecordChanged(ExpenseProxyChanged event) { + EntityProxyChange.registerForProxyType(eventBus, ExpenseProxy.class, + new EntityProxyChange.Handler<ExpenseProxy>() { + public void onProxyChange(EntityProxyChange<ExpenseProxy> event) { if (expense != null) { ExpenseProxy newRecord = event.getProxy(); if (newRecord.getId().equals(expense.getId())) {
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeProxyChanged.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeProxyChanged.java deleted file mode 100644 index ec5ec12..0000000 --- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/EmployeeProxyChanged.java +++ /dev/null
@@ -1,54 +0,0 @@ -/* - * 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.sample.expenses.client.request; - -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.GwtEvent; -import com.google.gwt.requestfactory.shared.EntityProxyChangedEvent; -import com.google.gwt.requestfactory.shared.WriteOperation; - -/** - * "API Generated" event posted when the values of a {@link EmployeeProxy} - * change. - * <p> - * IRL this class will be generated by a JPA-savvy tool run before compilation. - */ -public class EmployeeProxyChanged extends - EntityProxyChangedEvent<EmployeeProxy, EmployeeProxyChanged.Handler> { - - /** - * Implemented by handlers of this type of event. - */ - public interface Handler extends EventHandler { - void onEmployeeChanged(EmployeeProxyChanged event); - } - - public static final Type<Handler> TYPE = new Type<Handler>(); - - public EmployeeProxyChanged(EmployeeProxy record, WriteOperation writeOperation) { - super(record, writeOperation); - } - - @Override - public GwtEvent.Type<Handler> getAssociatedType() { - return TYPE; - } - - @Override - protected void dispatch(Handler handler) { - handler.onEmployeeChanged(this); - } -}
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseProxyChanged.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseProxyChanged.java deleted file mode 100644 index f3c7211..0000000 --- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ExpenseProxyChanged.java +++ /dev/null
@@ -1,54 +0,0 @@ -/* - * 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.sample.expenses.client.request; - -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.GwtEvent; -import com.google.gwt.requestfactory.shared.EntityProxyChangedEvent; -import com.google.gwt.requestfactory.shared.WriteOperation; - -/** - * "API Generated" event posted when the values of an {@link ExpenseProxy} - * change. - * <p> - * IRL this class will be generated by a JPA-savvy tool run before compilation. - */ -public class ExpenseProxyChanged extends - EntityProxyChangedEvent<ExpenseProxy, ExpenseProxyChanged.Handler> { - - /** - * Implemented by handlers of this type of event. - */ - public interface Handler extends EventHandler { - void onExpenseRecordChanged(ExpenseProxyChanged event); - } - - public static final Type<Handler> TYPE = new Type<Handler>(); - - public ExpenseProxyChanged(ExpenseProxy record, WriteOperation writeOperation) { - super(record, writeOperation); - } - - @Override - public GwtEvent.Type<Handler> getAssociatedType() { - return TYPE; - } - - @Override - protected void dispatch(Handler handler) { - handler.onExpenseRecordChanged(this); - } -}
diff --git a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportProxyChanged.java b/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportProxyChanged.java deleted file mode 100644 index ebdc255..0000000 --- a/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/request/ReportProxyChanged.java +++ /dev/null
@@ -1,54 +0,0 @@ -/* - * 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.sample.expenses.client.request; - -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.GwtEvent; -import com.google.gwt.requestfactory.shared.EntityProxyChangedEvent; -import com.google.gwt.requestfactory.shared.WriteOperation; - -/** - * "API Generated" event posted when the values of a {@link EmployeeProxy} - * change. - * <p> - * IRL this class will be generated by a JPA-savvy tool run before compilation. - */ -public class ReportProxyChanged extends - EntityProxyChangedEvent<ReportProxy, ReportProxyChanged.Handler> { - - /** - * Implemented by handlers of this type of event. - */ - public interface Handler extends EventHandler { - void onReportChanged(ReportProxyChanged event); - } - - public static final Type<Handler> TYPE = new Type<Handler>(); - - public ReportProxyChanged(ReportProxy record, WriteOperation writeOperation) { - super(record, writeOperation); - } - - @Override - public GwtEvent.Type<Handler> getAssociatedType() { - return TYPE; - } - - @Override - protected void dispatch(Handler handler) { - handler.onReportChanged(this); - } -}
diff --git a/user/src/com/google/gwt/app/place/AbstractProxyListActivity.java b/user/src/com/google/gwt/app/place/AbstractProxyListActivity.java index 8c8650a..a625689 100644 --- a/user/src/com/google/gwt/app/place/AbstractProxyListActivity.java +++ b/user/src/com/google/gwt/app/place/AbstractProxyListActivity.java
@@ -19,6 +19,7 @@ import com.google.gwt.event.shared.EventBus; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.requestfactory.shared.EntityProxy; +import com.google.gwt.requestfactory.shared.EntityProxyChange; import com.google.gwt.requestfactory.shared.ProxyListRequest; import com.google.gwt.requestfactory.shared.Receiver; import com.google.gwt.requestfactory.shared.RequestFactory; @@ -43,7 +44,8 @@ * development, and is very likely to be deleted. Use it at your own risk. * </span> * </p> - * Abstract activity for requesting and displaying a list of {@link EntityProxy}. + * Abstract activity for requesting and displaying a list of {@link EntityProxy} + * . * <p> * Subclasses must: * @@ -57,8 +59,8 @@ * * @param <P> the type of {@link EntityProxy} listed */ -public abstract class AbstractProxyListActivity<P extends EntityProxy> implements - Activity, ProxyListView.Delegate<P> { +public abstract class AbstractProxyListActivity<P extends EntityProxy> + implements Activity, ProxyListView.Delegate<P> { /** * This mapping allows us to update individual rows as records change. @@ -81,8 +83,7 @@ private Display display; public AbstractProxyListActivity(RequestFactory requests, - PlaceController placeController, ProxyListView<P> view, - Class<P> proxyType) { + PlaceController placeController, ProxyListView<P> view, Class<P> proxyType) { this.view = view; this.requests = requests; this.placeController = placeController; @@ -177,6 +178,12 @@ } public void start(Display display, EventBus eventBus) { + EntityProxyChange.registerForProxyType(eventBus, proxyType, + new EntityProxyChange.Handler<P>() { + public void onProxyChange(EntityProxyChange<P> event) { + update(event.getWriteOperation(), event.getProxy()); + } + }); eventBus.addHandler(PlaceChangeEvent.TYPE, new PlaceChangeEvent.Handler() { public void onPlaceChange(PlaceChangeEvent event) { updateSelection(event.getNewPlace()); @@ -214,7 +221,7 @@ /** * Called when the user chooses a record to view. This default implementation * sends the {@link PlaceController} to an appropriate {@link ProxyPlace}. - * + * * @param record the chosen record */ protected void showDetails(P record) { @@ -223,8 +230,7 @@ private void fireRangeRequest(final Range range, final Receiver<List<P>> callback) { - createRangeRequest(range).with(getView().getPaths()).fire( - callback); + createRangeRequest(range).with(getView().getPaths()).fire(callback); } private void getLastPage() {
diff --git a/user/src/com/google/gwt/app/place/ActivityManager.java b/user/src/com/google/gwt/app/place/ActivityManager.java index d0efe62..90df5d9 100644 --- a/user/src/com/google/gwt/app/place/ActivityManager.java +++ b/user/src/com/google/gwt/app/place/ActivityManager.java
@@ -18,6 +18,7 @@ import com.google.gwt.app.place.Activity.Display; import com.google.gwt.event.shared.EventBus; import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.event.shared.ResettableEventBus; import com.google.gwt.event.shared.UmbrellaException; import java.util.LinkedHashSet; @@ -63,7 +64,7 @@ private final ActivityMapper mapper; private final EventBus eventBus; - private final StopperedEventBus stopperedEventBus; + private final ResettableEventBus stopperedEventBus; private Activity currentActivity = NULL_ACTIVITY; @@ -83,7 +84,7 @@ public ActivityManager(ActivityMapper mapper, EventBus eventBus) { this.mapper = mapper; this.eventBus = eventBus; - this.stopperedEventBus = new StopperedEventBus(eventBus); + this.stopperedEventBus = new ResettableEventBus(eventBus); } /**
diff --git a/user/src/com/google/gwt/event/logical/shared/ValueChangeEvent.java b/user/src/com/google/gwt/event/logical/shared/ValueChangeEvent.java index db3ba26..bf71cf2 100644 --- a/user/src/com/google/gwt/event/logical/shared/ValueChangeEvent.java +++ b/user/src/com/google/gwt/event/logical/shared/ValueChangeEvent.java
@@ -31,7 +31,7 @@ /** * Fires a value change event on all registered handlers in the handler - * manager.If no such handlers exist, this method will do nothing. + * manager. If no such handlers exist, this method will do nothing. * * @param <I> the old value type * @param source the source of the handlers @@ -103,7 +103,7 @@ // The instance knows its BeforeSelectionHandler is of type I, but the TYPE // field itself does not, so we have to do an unsafe cast here. - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) @Override public final Type<ValueChangeHandler<I>> getAssociatedType() { return (Type) TYPE;
diff --git a/user/src/com/google/gwt/event/shared/DefaultHandlerRegistration.java b/user/src/com/google/gwt/event/shared/DefaultHandlerRegistration.java index 91fb67c..e19b557 100644 --- a/user/src/com/google/gwt/event/shared/DefaultHandlerRegistration.java +++ b/user/src/com/google/gwt/event/shared/DefaultHandlerRegistration.java
@@ -19,9 +19,13 @@ /** * Default implementation of {@link HandlerRegistration}. + * + * @deprecated with no replacement; this class is no longer used by any GWT code */ +@Deprecated public class DefaultHandlerRegistration implements HandlerRegistration { + @SuppressWarnings("deprecation") private final HandlerManager manager; private final EventHandler handler; private final Type<?> type; @@ -36,7 +40,8 @@ * @param handler the handler */ protected <H extends EventHandler> DefaultHandlerRegistration( - HandlerManager manager, Type<H> type, H handler) { + @SuppressWarnings("deprecation") HandlerManager manager, Type<H> type, + H handler) { this.manager = manager; this.handler = handler; this.type = type; @@ -45,7 +50,7 @@ /** * Removes the given handler from its manager. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "deprecation"}) // This is safe because when the elements were passed in they conformed to // Type<H>,H. public void removeHandler() {
diff --git a/user/src/com/google/gwt/event/shared/EventBus.java b/user/src/com/google/gwt/event/shared/EventBus.java index a64e9f9..74460c3 100644 --- a/user/src/com/google/gwt/event/shared/EventBus.java +++ b/user/src/com/google/gwt/event/shared/EventBus.java
@@ -15,13 +15,38 @@ */ package com.google.gwt.event.shared; +import com.google.gwt.event.shared.GwtEvent.Type; + /** - * Implemented by objects that dispatch {@link GwtEvent}s. + * Dispatches {@link GwtEvent}s to interested parties. Eases decoupling by + * allowing objects to interact without having direct dependencies upon one + * another, and without requiring event sources to deal with maintaining handler + * lists. There will typically be one EventBus per application, broadcasting + * events that may be of general interest. + * + * @see SimpleEventBus + * @see ResettableEventBus + * @see com.google.gwt.event.shared.testing.CountingEventBus */ -public interface EventBus extends HasHandlers { +public abstract class EventBus implements HasHandlers { /** - * Adds a handler. + * Adds an unfiltered handler to receive events of this type from all sources. + * <p> + * It is rare to call this method directly. More typically a {@link GwtEvent} + * subclass will provide a static <code>register</code> method, or a widget + * will accept handlers directly. + * <p> + * A tip: to make a handler de-register itself, the following works: + * <code><pre>new MyHandler() { + * HandlerRegistration reg = MyEvent.register(eventBus, this); + * + * public void onMyThing(MyEvent event) { + * {@literal /}* do your thing *{@literal /} + * reg.removeHandler(); + * } + * }; + * </pre></code> * * @param <H> The type of handler * @param type the event type associated with this handler @@ -29,6 +54,42 @@ * @return the handler registration, can be stored in order to remove the * handler later */ - <H extends EventHandler> HandlerRegistration addHandler( - GwtEvent.Type<H> type, final H handler); + public abstract <H extends EventHandler> HandlerRegistration addHandler( + Type<H> type, H handler); + + /** + * Adds a handler to receive events of this type from the given source. + * <p> + * It is rare to call this method directly. More typically a {@link GwtEvent} + * subclass will provide a static <code>register</code> method, or a widget + * will accept handlers directly. + * + * @param <H> The type of handler + * @param type the event type associated with this handler + * @param source the source associated with this handler + * @param handler the handler + * @return the handler registration, can be stored in order to remove the + * handler later + */ + public abstract <H extends EventHandler> HandlerRegistration addHandlerToSource( + Type<H> type, Object source, H handler); + + /** + * Fires the event from no source. Only unfiltered handlers will receive it. + * + * @param event the event to fire + */ + public abstract void fireEvent(GwtEvent<?> event); + + /** + * Fires the given event to the handlers listening to the event's type. + * <p> + * Any exceptions thrown by handlers will be bundled into a + * {@link UmbrellaException} and then re-thrown after all handlers have + * completed. An exception thrown by a handler will not prevent other handlers + * from executing. + * + * @param event the event to fire + */ + public abstract void fireEventFromSource(GwtEvent<?> event, Object source); }
diff --git a/user/src/com/google/gwt/event/shared/HandlerManager.java b/user/src/com/google/gwt/event/shared/HandlerManager.java index 1873acd..8b6193b 100644 --- a/user/src/com/google/gwt/event/shared/HandlerManager.java +++ b/user/src/com/google/gwt/event/shared/HandlerManager.java
@@ -17,129 +17,27 @@ import com.google.gwt.event.shared.GwtEvent.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - /** * Manager responsible for adding handlers to event sources and firing those - * handlers on passed in events. + * handlers on passed in events. Primitive ancestor of {@link EventBus}, + * and used at the core of {com.google.gwt.user.client.ui.Widget}. + * + * @deprecated use {@link SimpleEventBus}. */ -public class HandlerManager implements EventBus { +@Deprecated +public class HandlerManager { - /** - * Interface for queued add/remove operations. - */ - private interface AddOrRemoveCommand { - void execute(); - } + private SimpleEventBus eventBus; - /** - * Inner class used to actually contain the handlers. - */ - private static class HandlerRegistry { - private final HashMap<GwtEvent.Type<?>, ArrayList<?>> map = new HashMap<GwtEvent.Type<?>, ArrayList<?>>(); - - private <H extends EventHandler> void addHandler(Type<H> type, H handler) { - ArrayList<H> l = get(type); - if (l == null) { - l = new ArrayList<H>(); - map.put(type, l); - } - l.add(handler); - } - - private <H extends EventHandler> void fireEvent(GwtEvent<H> event, - boolean isReverseOrder) { - Type<H> type = event.getAssociatedType(); - int count = getHandlerCount(type); - Set<Throwable> causes = null; - - if (isReverseOrder) { - for (int i = count - 1; i >= 0; i--) { - H handler = this.<H> getHandler(type, i); - try { - event.dispatch(handler); - } catch (Throwable e) { - if (causes == null) { - // create lazily to avoid excess creation in general case - causes = new HashSet<Throwable>(); - } - causes.add(e); - } - } - } else { - for (int i = 0; i < count; i++) { - H handler = this.<H> getHandler(type, i); - try { - event.dispatch(handler); - } catch (Throwable e) { - if (causes == null) { - // create lazily to avoid excess creation in general case - causes = new HashSet<Throwable>(); - } - causes.add(e); - } - } - } - - if (causes != null) { - throw new UmbrellaException(causes); - } - } - - @SuppressWarnings("unchecked") - private <H> ArrayList<H> get(GwtEvent.Type<H> type) { - // This cast is safe because we control the puts. - return (ArrayList<H>) map.get(type); - } - - private <H extends EventHandler> H getHandler(GwtEvent.Type<H> eventKey, - int index) { - ArrayList<H> l = get(eventKey); - return l.get(index); - } - - private int getHandlerCount(GwtEvent.Type<?> eventKey) { - ArrayList<?> l = map.get(eventKey); - return l == null ? 0 : l.size(); - } - - private boolean isEventHandled(GwtEvent.Type<?> eventKey) { - return map.containsKey(eventKey); - } - - private <H> void removeHandler(GwtEvent.Type<H> eventKey, H handler) { - ArrayList<H> l = get(eventKey); - boolean result = (l == null) ? false : l.remove(handler); - if (result && l.size() == 0) { - map.remove(eventKey); - } - assert result : "Tried to remove unknown handler: " + handler + " from " - + eventKey; - } - } - - private int firingDepth = 0; - private boolean isReverseOrder; - - // map storing the actual handlers - private HandlerRegistry registry; - - // source of the event. + // source of the events private final Object source; - // Add and remove operations received during dispatch. - private List<AddOrRemoveCommand> deferredDeltas; - /** - * Creates a handler manager with the given source. Handlers will be fired in - * the order that they are added. + * Creates a handler manager with a source to be set on all events fired via + * {@link #fireEvent(GwtEvent)}. Handlers will be fired in the order that they + * are added. * - * @param source the event source + * @param source the default event source */ public HandlerManager(Object source) { this(source, false); @@ -153,9 +51,8 @@ * @param fireInReverseOrder true to fire handlers in reverse order */ public HandlerManager(Object source, boolean fireInReverseOrder) { - registry = new HandlerRegistry(); + eventBus = new SimpleEventBus(fireInReverseOrder); this.source = source; - this.isReverseOrder = fireInReverseOrder; } /** @@ -169,28 +66,20 @@ */ public <H extends EventHandler> HandlerRegistration addHandler( GwtEvent.Type<H> type, final H handler) { - assert type != null : "Cannot add a handler with a null type"; - assert handler != null : "Cannot add a null handler"; - if (firingDepth > 0) { - enqueueAdd(type, handler); - } else { - doAdd(type, handler); - } - - return new DefaultHandlerRegistration(this, type, handler); + return eventBus.addHandler(type, handler); } /** * Fires the given event to the handlers listening to the event's type. - * - * Note, any subclass should be very careful about overriding this method, as - * adds/removes of handlers will not be safe except within this - * implementation. - * + * <p> * Any exceptions thrown by handlers will be bundled into a * {@link UmbrellaException} and then re-thrown after all handlers have * completed. An exception thrown by a handler will not prevent other handlers * from executing. + * <p> + * Note, any subclass should be very careful about overriding this method, as + * adds/removes of handlers will not be safe except within this + * implementation. * * @param event the event */ @@ -202,17 +91,11 @@ Object oldSource = event.getSource(); event.setSource(source); try { - firingDepth++; // May throw an UmbrellaException. - registry.fireEvent(event, isReverseOrder); + eventBus.fireEvent(event); } finally { - firingDepth--; - if (firingDepth == 0) { - handleQueuedAddsAndRemoves(); - } - if (oldSource == null) { // This was my event, so I should kill it now that I'm done. event.kill(); @@ -232,10 +115,7 @@ * @return the given handler */ public <H extends EventHandler> H getHandler(GwtEvent.Type<H> type, int index) { - assert index < getHandlerCount(type) : "handlers for " + type.getClass() - + " have size: " + getHandlerCount(type) - + " so do not have a handler at index: " + index; - return registry.getHandler(type, index); + return eventBus.getHandler(type, index); } /** @@ -245,7 +125,7 @@ * @return the number of registered handlers */ public int getHandlerCount(Type<?> type) { - return registry.getHandlerCount(type); + return eventBus.getHandlerCount(type); } /** @@ -255,13 +135,11 @@ * @return whether the given event type is handled */ public boolean isEventHandled(Type<?> e) { - return registry.isEventHandled(e); + return eventBus.isEventHandled(e); } /** - * Removes the given handler from the specified event type. Normally, - * applications should call {@link HandlerRegistration#removeHandler()} - * instead. + * Removes the given handler from the specified event type. * * @param <H> handler type * @@ -270,67 +148,6 @@ */ public <H extends EventHandler> void removeHandler(GwtEvent.Type<H> type, final H handler) { - if (firingDepth > 0) { - enqueueRemove(type, handler); - } else { - doRemove(type, handler); - } - } - - /** - * Not part of the public API, available only to allow visualization tools to - * be developed in gwt-incubator. - * - * @return a map of all handlers in this handler manager - */ - Map<GwtEvent.Type<?>, ArrayList<?>> createHandlerInfo() { - return registry.map; - } - - private void defer(AddOrRemoveCommand command) { - if (deferredDeltas == null) { - deferredDeltas = new ArrayList<AddOrRemoveCommand>(); - } - deferredDeltas.add(command); - } - - private <H extends EventHandler> void doAdd(GwtEvent.Type<H> type, - final H handler) { - registry.addHandler(type, handler); - } - - private <H extends EventHandler> void doRemove(GwtEvent.Type<H> type, - final H handler) { - registry.removeHandler(type, handler); - } - - private <H extends EventHandler> void enqueueAdd(final GwtEvent.Type<H> type, - final H handler) { - defer(new AddOrRemoveCommand() { - public void execute() { - doAdd(type, handler); - } - }); - } - - private <H extends EventHandler> void enqueueRemove( - final GwtEvent.Type<H> type, final H handler) { - defer(new AddOrRemoveCommand() { - public void execute() { - doRemove(type, handler); - } - }); - } - - private void handleQueuedAddsAndRemoves() { - if (deferredDeltas != null) { - try { - for (AddOrRemoveCommand c : deferredDeltas) { - c.execute(); - } - } finally { - deferredDeltas = null; - } - } + eventBus.doRemove(type, null, handler); } }
diff --git a/user/src/com/google/gwt/event/shared/HasHandlers.java b/user/src/com/google/gwt/event/shared/HasHandlers.java index 38776d0..639d3f0 100644 --- a/user/src/com/google/gwt/event/shared/HasHandlers.java +++ b/user/src/com/google/gwt/event/shared/HasHandlers.java
@@ -23,7 +23,7 @@ /** * Fires the given event to the handlers listening to the event's type. - * + * <p> * Any exceptions thrown by handlers will be bundled into a * {@link UmbrellaException} and then re-thrown after all handlers have * completed. An exception thrown by a handler will not prevent other handlers
diff --git a/user/src/com/google/gwt/app/place/StopperedEventBus.java b/user/src/com/google/gwt/event/shared/ResettableEventBus.java similarity index 63% rename from user/src/com/google/gwt/app/place/StopperedEventBus.java rename to user/src/com/google/gwt/event/shared/ResettableEventBus.java index 1cf3219..5769a79 100644 --- a/user/src/com/google/gwt/app/place/StopperedEventBus.java +++ b/user/src/com/google/gwt/event/shared/ResettableEventBus.java
@@ -1,24 +1,20 @@ /* * 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.app.place; +package com.google.gwt.event.shared; -import com.google.gwt.event.shared.EventBus; -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.GwtEvent; -import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.event.shared.GwtEvent.Type; import java.util.HashSet; @@ -28,23 +24,39 @@ * Wraps an EventBus to hold on to any HandlerRegistrations, so that they can * easily all be cleared at once. */ -public class StopperedEventBus implements EventBus { - private final EventBus wrappedBus; +public class ResettableEventBus extends EventBus { + private final EventBus wrapped; private final Set<HandlerRegistration> registrations = new HashSet<HandlerRegistration>(); - - public StopperedEventBus(EventBus wrappedBus) { - this.wrappedBus = wrappedBus; + + public ResettableEventBus(EventBus wrappedBus) { + this.wrapped = wrappedBus; } + @Override public <H extends EventHandler> HandlerRegistration addHandler(Type<H> type, H handler) { - HandlerRegistration rtn = wrappedBus.addHandler(type, handler); + HandlerRegistration rtn = wrapped.addHandler(type, handler); registrations.add(rtn); return rtn; } + @Override + public <H extends EventHandler> HandlerRegistration addHandlerToSource( + GwtEvent.Type<H> type, Object source, H handler) { + HandlerRegistration rtn = wrapped.addHandlerToSource(type, source, + handler); + registrations.add(rtn); + return rtn; + } + + @Override public void fireEvent(GwtEvent<?> event) { - wrappedBus.fireEvent(event); + wrapped.fireEvent(event); + } + + @Override + public void fireEventFromSource(GwtEvent<?> event, Object source) { + wrapped.fireEventFromSource(event, source); } /**
diff --git a/user/src/com/google/gwt/event/shared/SimpleEventBus.java b/user/src/com/google/gwt/event/shared/SimpleEventBus.java new file mode 100644 index 0000000..673d698 --- /dev/null +++ b/user/src/com/google/gwt/event/shared/SimpleEventBus.java
@@ -0,0 +1,323 @@ +/* + * 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.event.shared; + +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.event.shared.GwtEvent.Type; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; + +/** + * Basic implementation of {@link EventBus}. + */ +public class SimpleEventBus extends EventBus { + private final boolean isReverseOrder; + + private int firingDepth = 0; + + /** + * Add and remove operations received during dispatch. + */ + private List<ScheduledCommand> deferredDeltas; + + /** + * Map of event type to map of event source to list of their handlers. + */ + private final Map<GwtEvent.Type<?>, Map<Object, List<?>>> map = new HashMap<GwtEvent.Type<?>, Map<Object, List<?>>>(); + + public SimpleEventBus() { + this(false); + } + + /** + * Allows creation of an instance that fires its handlers in the reverse of + * the order in which they were added, although filtered handlers all fire + * before unfiltered handlers. + * <p> + * + * @deprecated This is a legacy feature, required by HandlerManager. Package + * protected because it is a bad idea to rely upon the order of + * event dispatch, and because fully supporting it (that is, not + * segregating filtered and unfiltered handlers, a distinction not + * used by HandlerManager) is not worth the effort. + */ + @Deprecated + SimpleEventBus(boolean fireInReverseOrder) { + isReverseOrder = fireInReverseOrder; + } + + @Override + public <H extends EventHandler> HandlerRegistration addHandler(Type<H> type, + H handler) { + if (type == null) { + throw new NullPointerException("Cannot add a handler with a null type"); + } + if (handler == null) { + throw new NullPointerException("Cannot add a null handler"); + } + + return doAdd(type, null, handler); + } + + @Override + public <H extends EventHandler> HandlerRegistration addHandlerToSource( + final GwtEvent.Type<H> type, final Object source, final H handler) { + if (type == null) { + throw new NullPointerException("Cannot add a handler with a null type"); + } + if (source == null) { + throw new NullPointerException("Cannot add a handler with a null source"); + } + if (handler == null) { + throw new NullPointerException("Cannot add a null handler"); + } + + return doAdd(type, source, handler); + } + + @Override + public void fireEvent(GwtEvent<?> event) { + if (event == null) { + throw new NullPointerException("Cannot fire null event"); + } + doFire(event, null); + } + + @Override + public void fireEventFromSource(GwtEvent<?> event, Object source) { + if (event == null) { + throw new NullPointerException("Cannot fire null event"); + } + if (source == null) { + throw new NullPointerException("Cannot fire from a null source"); + } + doFire(event, source); + } + + /** + * Package protected to support legacy features in HandlerManager. + */ + <H extends EventHandler> void doRemove( + com.google.gwt.event.shared.GwtEvent.Type<H> type, Object source, + H handler) { + if (firingDepth > 0) { + enqueueRemove(type, source, handler); + } else { + doRemoveNow(type, source, handler); + } + } + + /** + * Package protected to support legacy features in HandlerManager. + */ + @Deprecated + <H extends EventHandler> H getHandler(GwtEvent.Type<H> type, int index) { + assert index < getHandlerCount(type) : "handlers for " + type.getClass() + + " have size: " + getHandlerCount(type) + + " so do not have a handler at index: " + index; + + List<H> l = getHandlerList(type, null); + return l.get(index); + } + + /** + * Package protected to support legacy features in HandlerManager. + */ + @Deprecated + int getHandlerCount(GwtEvent.Type<?> eventKey) { + return getHandlerList(eventKey, null).size(); + } + + /** + * Package protected to support legacy features in HandlerManager. + */ + @Deprecated + boolean isEventHandled(GwtEvent.Type<?> eventKey) { + return map.containsKey(eventKey); + } + + private void defer(ScheduledCommand command) { + if (deferredDeltas == null) { + deferredDeltas = new ArrayList<ScheduledCommand>(); + } + deferredDeltas.add(command); + } + + private <H extends EventHandler> HandlerRegistration doAdd( + final GwtEvent.Type<H> type, final Object source, final H handler) { + if (firingDepth > 0) { + enqueueAdd(type, source, handler); + } else { + doAddNow(type, source, handler); + } + + return new HandlerRegistration() { + public void removeHandler() { + doRemove(type, source, handler); + } + }; + } + + private <H extends EventHandler> void doAddNow(GwtEvent.Type<H> type, + Object source, H handler) { + List<H> l = ensureHandlerList(type, source); + l.add(handler); + } + + private <H extends EventHandler> void doFire(GwtEvent<H> event, Object source) { + try { + firingDepth++; + + if (source != null) { + event.setSource(source); + } + + List<H> handlers = getDispatchList(event.getAssociatedType(), source); + Set<Throwable> causes = null; + + ListIterator<H> it = isReverseOrder + ? handlers.listIterator(handlers.size()) : handlers.listIterator(); + while (isReverseOrder ? it.hasPrevious() : it.hasNext()) { + H handler = isReverseOrder ? it.previous() : it.next(); + + try { + event.dispatch(handler); + } catch (Throwable e) { + if (causes == null) { + causes = new HashSet<Throwable>(); + } + causes.add(e); + } + } + + if (causes != null) { + throw new UmbrellaException(causes); + } + } finally { + firingDepth--; + if (firingDepth == 0) { + handleQueuedAddsAndRemoves(); + } + } + } + + private <H> void doRemoveNow(GwtEvent.Type<H> type, Object source, H handler) { + List<H> l = getHandlerList(type, source); + + boolean removed = l.remove(handler); + assert removed : "redundant remove call"; + if (removed && l.isEmpty()) { + prune(type, source); + } + } + + private <H extends EventHandler> void enqueueAdd(final GwtEvent.Type<H> type, + final Object source, final H handler) { + defer(new ScheduledCommand() { + public void execute() { + doAddNow(type, source, handler); + } + }); + } + + private <H extends EventHandler> void enqueueRemove( + final GwtEvent.Type<H> type, final Object source, final H handler) { + defer(new ScheduledCommand() { + public void execute() { + doRemoveNow(type, source, handler); + } + }); + } + + private <H> List<H> ensureHandlerList(GwtEvent.Type<H> type, Object source) { + Map<Object, List<?>> sourceMap = map.get(type); + if (sourceMap == null) { + sourceMap = new HashMap<Object, List<?>>(); + map.put(type, sourceMap); + } + + // safe, we control the puts. + @SuppressWarnings("unchecked") + List<H> handlers = (List<H>) sourceMap.get(source); + if (handlers == null) { + handlers = new ArrayList<H>(); + sourceMap.put(source, handlers); + } + + return handlers; + } + + private <H> List<H> getDispatchList(GwtEvent.Type<H> type, Object source) { + List<H> directHandlers = getHandlerList(type, source); + if (source == null) { + return directHandlers; + } + + List<H> globalHandlers = getHandlerList(type, null); + + List<H> rtn = new ArrayList<H>(directHandlers); + rtn.addAll(globalHandlers); + return rtn; + } + + private <H> List<H> getHandlerList(GwtEvent.Type<H> type, Object source) { + Map<Object, List<?>> sourceMap = map.get(type); + if (sourceMap == null) { + return Collections.emptyList(); + } + + // safe, we control the puts. + @SuppressWarnings("unchecked") + List<H> handlers = (List<H>) sourceMap.get(source); + if (handlers == null) { + return Collections.emptyList(); + } + + return handlers; + } + + private void handleQueuedAddsAndRemoves() { + if (deferredDeltas != null) { + try { + for (ScheduledCommand c : deferredDeltas) { + c.execute(); + } + } finally { + deferredDeltas = null; + } + } + } + + private void prune(GwtEvent.Type<?> type, Object source) { + Map<Object, List<?>> sourceMap = map.get(type); + + List<?> pruned = sourceMap.remove(source); + + assert pruned != null : "Can't prune what wasn't there"; + assert pruned.isEmpty() : "Pruned unempty list!"; + + if (sourceMap.isEmpty()) { + map.remove(type); + } + } +} \ No newline at end of file
diff --git a/user/src/com/google/gwt/event/shared/testing/CountingEventBus.java b/user/src/com/google/gwt/event/shared/testing/CountingEventBus.java new file mode 100644 index 0000000..3c1a121 --- /dev/null +++ b/user/src/com/google/gwt/event/shared/testing/CountingEventBus.java
@@ -0,0 +1,101 @@ +/* + * 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.event.shared.testing; + +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.event.shared.EventHandler; +import com.google.gwt.event.shared.GwtEvent; +import com.google.gwt.event.shared.GwtEvent.Type; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.event.shared.SimpleEventBus; + +import java.util.HashMap; +import java.util.Map; + +/** + * Wraps an {@link EventBus} to keep a count of registered handlers. Handy for + * tests. + */ +public class CountingEventBus extends EventBus { + private final Map<Type<?>, Integer> counts = new HashMap<GwtEvent.Type<?>, Integer>(); + private final EventBus wrapped; + + public CountingEventBus() { + this(new SimpleEventBus()); + } + + public CountingEventBus(EventBus wrapped) { + this.wrapped = wrapped; + } + + @Override + public <H extends EventHandler> HandlerRegistration addHandler(Type<H> type, + H handler) { + increment(type); + final HandlerRegistration superReg = wrapped.addHandler(type, handler); + return makeReg(type, superReg); + } + + @Override + public <H extends EventHandler> HandlerRegistration addHandlerToSource( + final Type<H> type, Object source, H handler) { + increment(type); + final HandlerRegistration superReg = wrapped.addHandlerToSource(type, + source, handler); + return makeReg(type, superReg); + } + + @Override + public void fireEvent(GwtEvent<?> event) { + wrapped.fireEvent(event); + } + + @Override + public void fireEventFromSource(GwtEvent<?> event, Object source) { + wrapped.fireEventFromSource(event, source); + } + + public int getCount(Type<?> type) { + Integer count = counts.get(type); + return count == null ? 0 : count; + } + + private void decrement(Type<?> type) { + Integer count = counts.get(type); + if (count == null) { + count = 0; + } + counts.put(type, count - 1); + } + + private <H> void increment(final Type<H> type) { + Integer count = counts.get(type); + if (count == null) { + count = 0; + } + counts.put(type, count + 1); + } + + private <H> HandlerRegistration makeReg(final Type<H> type, + final HandlerRegistration superReg) { + return new HandlerRegistration() { + public void removeHandler() { + decrement(type); + superReg.removeHandler(); + } + }; + } +}
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java index 692de66..1024858 100644 --- a/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java +++ b/user/src/com/google/gwt/requestfactory/client/impl/ProxyImpl.java
@@ -15,10 +15,10 @@ */ package com.google.gwt.requestfactory.client.impl; +import com.google.gwt.requestfactory.shared.EntityProxy; import com.google.gwt.requestfactory.shared.EntityProxyId; import com.google.gwt.requestfactory.shared.Property; import com.google.gwt.requestfactory.shared.PropertyReference; -import com.google.gwt.requestfactory.shared.EntityProxy; /** * <p>
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java b/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java index 1784254..dcb5a3f 100644 --- a/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java +++ b/user/src/com/google/gwt/requestfactory/client/impl/ProxySchema.java
@@ -15,9 +15,9 @@ */ package com.google.gwt.requestfactory.client.impl; -import com.google.gwt.requestfactory.shared.Property; import com.google.gwt.requestfactory.shared.EntityProxy; -import com.google.gwt.requestfactory.shared.EntityProxyChangedEvent; +import com.google.gwt.requestfactory.shared.EntityProxyChange; +import com.google.gwt.requestfactory.shared.Property; import com.google.gwt.requestfactory.shared.WriteOperation; import java.util.Collections; @@ -34,7 +34,7 @@ * {@link com.google.gwt.requestfactory.rebind.RequestFactoryGenerator * RequestFactoryGenerator}. Defines the set of properties for a class of * Proxy, and serves as a factory for these proxies and their - * {@link EntityProxyChangedEvent}s. + * {@link EntityProxyChange}s. * * @param <P> the type of the Proxies this schema describes */ @@ -64,12 +64,25 @@ public abstract P create(ProxyJsoImpl jso, boolean isFuture); - public abstract EntityProxyChangedEvent<?, ?> createChangeEvent(EntityProxy record, - WriteOperation writeOperation); - + @SuppressWarnings("unchecked") + public EntityProxyChange<P> createChangeEvent(EntityProxy proxy, + WriteOperation operation) { + assert isCorrectClass(proxy); + return new EntityProxyChange<P>((P) proxy, operation); + } + public abstract Class<? extends EntityProxy> getProxyClass(); public String getToken() { return token; } + + private boolean isCorrectClass(EntityProxy proxy) { + // What we really want to check is isAssignableFrom. Sigh. + Class<? extends EntityProxy> actual = ((ProxyImpl) proxy).asJso().getRequestFactory().getClass( + proxy); + Class<? extends EntityProxy> expected = getProxyClass(); + boolean equals = actual.equals(expected); + return equals; + } }
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java b/user/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java index f8802d8..c78d733 100644 --- a/user/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java +++ b/user/src/com/google/gwt/requestfactory/client/impl/RequestFactoryJsonImpl.java
@@ -257,9 +257,11 @@ * unpopulated copy of the record. */ newJsoRecord = ProxyJsoImpl.emptyCopy(newJsoRecord); - EntityProxy javaRecord = newJsoRecord.getSchema().create(newJsoRecord); - eventBus.fireEvent(newJsoRecord.getSchema().createChangeEvent(javaRecord, - op)); + ProxySchema<?> schema = newJsoRecord.getSchema(); + EntityProxy javaRecord = schema.create(newJsoRecord); + + eventBus.fireEventFromSource(schema.createChangeEvent(javaRecord, op), + schema.getProxyClass()); } private <R extends ProxyImpl> R createFuture(ProxySchema<R> schema) {
diff --git a/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java b/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java index 4477645..ec8611c 100644 --- a/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java +++ b/user/src/com/google/gwt/requestfactory/rebind/RequestFactoryGenerator.java
@@ -51,7 +51,6 @@ import com.google.gwt.requestfactory.client.impl.RequestFactoryJsonImpl; import com.google.gwt.requestfactory.server.ReflectionBasedOperationRegistry; import com.google.gwt.requestfactory.shared.EntityProxy; -import com.google.gwt.requestfactory.shared.EntityProxyChangedEvent; import com.google.gwt.requestfactory.shared.EntityProxyId; import com.google.gwt.requestfactory.shared.Property; import com.google.gwt.requestfactory.shared.PropertyReference; @@ -73,15 +72,18 @@ import java.util.Set; /** - * <p> <span style="color:red">Experimental API: This class is still under rapid + * <p> + * <span style="color:red">Experimental API: This class is still under rapid * development, and is very likely to be deleted. Use it at your own risk. - * </span> </p> Generates implementations of {@link com.google.gwt.requestfactory.shared.RequestFactory - * RequestFactory} and its nested interfaces. + * </span> + * </p> + * Generates implementations of + * {@link com.google.gwt.requestfactory.shared.RequestFactory RequestFactory} + * and its nested interfaces. */ public class RequestFactoryGenerator extends Generator { - private final Set<JClassType> generatedProxyTypes - = new HashSet<JClassType>(); + private final Set<JClassType> generatedProxyTypes = new HashSet<JClassType>(); @Override public String generate(TreeLogger logger, GeneratorContext generatorContext, @@ -94,16 +96,15 @@ // Ensure that the requested type exists if (interfaceType == null) { - logger.log(TreeLogger.ERROR, - "Could not find requested typeName: " + interfaceName); + logger.log(TreeLogger.ERROR, "Could not find requested typeName: " + + interfaceName); throw new UnableToCompleteException(); } if (interfaceType.isInterface() == null) { // The incoming type wasn't a plain interface, we don't support // abstract base classes - logger.log(TreeLogger.ERROR, - interfaceType.getQualifiedSourceName() + " is not an interface.", - null); + logger.log(TreeLogger.ERROR, interfaceType.getQualifiedSourceName() + + " is not an interface.", null); throw new UnableToCompleteException(); } @@ -115,8 +116,9 @@ // If an implementation already exists, we don't need to do any work if (out != null) { - generateOnce(typeOracle.findType(RequestFactory.class.getCanonicalName()), - logger, generatorContext, out, interfaceType, packageName, implName); + generateOnce( + typeOracle.findType(RequestFactory.class.getCanonicalName()), logger, + generatorContext, out, interfaceType, packageName, implName); } return packageName + "." + implName; @@ -151,22 +153,12 @@ Set<JClassType> transitiveDeps = new LinkedHashSet<JClassType>(); if (pw != null) { - logger = logger.branch(TreeLogger.DEBUG, "Generating " - + publicProxyType.getName()); + logger = logger.branch(TreeLogger.DEBUG, + "Generating " + publicProxyType.getName()); ClassSourceFileComposerFactory f = new ClassSourceFileComposerFactory( packageName, proxyImplTypeName); - String eventTypeName = publicProxyType.getName() + "Changed"; - JClassType eventType = typeOracle.findType(packageName, eventTypeName); - if (eventType == null) { - logger.log(TreeLogger.ERROR, - String.format("Cannot find %s implementation %s.%s", - EntityProxyChangedEvent.class.getName(), packageName, - eventTypeName)); - throw new UnableToCompleteException(); - } - f.addImport(AbstractJsonListRequest.class.getName()); f.addImport(AbstractJsonObjectRequest.class.getName()); f.addImport(RequestFactoryJsonImpl.class.getName()); @@ -188,7 +180,7 @@ sw.println(); JClassType propertyType = printSchema(typeOracle, publicProxyType, - proxyImplTypeName, eventType, sw); + proxyImplTypeName, sw); sw.println(); String simpleImplName = publicProxyType.getSimpleSourceName() + "Impl"; @@ -201,8 +193,8 @@ proxyImplTypeName)); sw.println(); - sw.println(String.format("private %s(ProxyJsoImpl jso, boolean isFuture) {", - proxyImplTypeName)); + sw.println(String.format( + "private %s(ProxyJsoImpl jso, boolean isFuture) {", proxyImplTypeName)); sw.indent(); sw.println("super(jso, isFuture);"); sw.outdent(); @@ -214,15 +206,14 @@ if (propertyType.getErasedType() == fieldType.getErasedType()) { JParameterizedType parameterized = fieldType.isParameterized(); if (parameterized == null) { - logger.log(TreeLogger.ERROR, - fieldType + " must have its param type set."); + logger.log(TreeLogger.ERROR, fieldType + + " must have its param type set."); throw new UnableToCompleteException(); } JClassType returnType = parameterized.getTypeArgs()[0]; sw.println(); sw.println(String.format("public %s get%s() {", - returnType.getQualifiedSourceName(), - capitalize(field.getName()))); + returnType.getQualifiedSourceName(), capitalize(field.getName()))); sw.indent(); sw.println(String.format("return get(%s);", field.getName())); sw.outdent(); @@ -254,7 +245,8 @@ capitalize(field.getName()), returnType.getQualifiedSourceName(), varName)); sw.indent(); - sw.println(String.format("set(this.%s, this, %s);", field.getName(), varName)); + sw.println(String.format("set(this.%s, this, %s);", field.getName(), + varName)); sw.outdent(); sw.println("}"); } @@ -278,7 +270,8 @@ JClassType interfaceType, String packageName, String implName) throws UnableToCompleteException { - logger = logger.branch(TreeLogger.DEBUG, + logger = logger.branch( + TreeLogger.DEBUG, String.format("Generating implementation of %s", interfaceType.getName())); @@ -309,8 +302,9 @@ JType returnType = method.getReturnType(); if (null == returnType) { logger.log(TreeLogger.ERROR, String.format( - "Illegal return type for %s. Methods of %s must return interfaces, found void", - method.getName(), interfaceType.getName())); + "Illegal return type for %s. Methods of %s " + + "must return interfaces, found void", method.getName(), + interfaceType.getName())); throw new UnableToCompleteException(); } JClassType asInterface = returnType.isInterface(); @@ -334,12 +328,14 @@ e.printStackTrace(); } - JClassType proxyToTypeInterface = generatorContext.getTypeOracle().findType(ProxyToTypeMap.class.getName()); + JClassType proxyToTypeInterface = generatorContext.getTypeOracle().findType( + ProxyToTypeMap.class.getName()); // TODO: note, this seems like a bug. What if you have 2 RequestFactories? String proxyToTypeMapName = proxyToTypeInterface.getName() + "Impl"; // write create(Class) - sw.println("public " + EntityProxy.class.getName() + " create(Class token) {"); + sw.println("public " + EntityProxy.class.getName() + + " create(Class token) {"); sw.indent(); sw.println("return create(token, new " + proxyToTypeMapName + "());"); sw.outdent(); @@ -347,7 +343,8 @@ sw.println(); // write getClass(String) - sw.println("public Class<? extends " + EntityProxy.class.getName() + "> getClass(String token) {"); + sw.println("public Class<? extends " + EntityProxy.class.getName() + + "> getClass(String token) {"); sw.indent(); sw.println("return getClass(token, new " + proxyToTypeMapName + "());"); sw.outdent(); @@ -355,7 +352,8 @@ sw.println(); // write getProxy(String) - sw.println("public " + EntityProxy.class.getName() + " getProxy(String token) {"); + sw.println("public " + EntityProxy.class.getName() + + " getProxy(String token) {"); sw.indent(); sw.println("return getProxy(token, new " + proxyToTypeMapName + "());"); sw.outdent(); @@ -363,7 +361,8 @@ sw.println(); // write getProxyId(String) - sw.println("public " + EntityProxyId.class.getName() + " getProxyId(String token) {"); + sw.println("public " + EntityProxyId.class.getName() + + " getProxyId(String token) {"); sw.indent(); sw.println("return getProxyId(token, new " + proxyToTypeMapName + "());"); sw.outdent(); @@ -386,8 +385,7 @@ sw.println("}"); sw.println(); - sw.println( - "public ProxySchema<? extends EntityProxy> getSchema(String schemaToken) {"); + sw.println("public ProxySchema<? extends EntityProxy> getSchema(String schemaToken) {"); sw.indent(); sw.println("return new " + proxyToTypeMapName + "().getType(schemaToken);"); sw.outdent(); @@ -396,16 +394,17 @@ // write a method for each request builder and generate it for (JMethod requestSelector : requestSelectors) { String returnTypeName = requestSelector.getReturnType().getQualifiedSourceName(); - String nestedImplName = - capitalize(requestSelector.getName().replace('.', '_')) + "Impl"; + String nestedImplName = capitalize(requestSelector.getName().replace('.', + '_')) + + "Impl"; String nestedImplPackage = generatorContext.getTypeOracle().findType( returnTypeName).getPackage().getName(); sw.println("public " + returnTypeName + " " + requestSelector.getName() + "() {"); sw.indent(); - sw.println( - "return new " + nestedImplPackage + "." + nestedImplName + "(this);"); + sw.println("return new " + nestedImplPackage + "." + nestedImplName + + "(this);"); sw.outdent(); sw.println("}"); sw.println(); @@ -435,7 +434,8 @@ private void generateProxyToTypeMap(TreeLogger logger, GeneratorContext generatorContext, PrintWriter out, JClassType interfaceType, String packageName, String implName) { - logger = logger.branch(TreeLogger.DEBUG, + logger = logger.branch( + TreeLogger.DEBUG, String.format("Generating implementation of %s", interfaceType.getName())); @@ -459,12 +459,12 @@ String qualifiedSourceName = publicProxyType.getQualifiedSourceName(); sw.println("if (proxyClass == " + qualifiedSourceName + ".class) {"); sw.indent(); - sw.println("return (ProxySchema<R>) " + qualifiedSourceName + "Impl.SCHEMA;"); + sw.println("return (ProxySchema<R>) " + qualifiedSourceName + + "Impl.SCHEMA;"); sw.outdent(); sw.println("}"); } - sw.println( - "throw new IllegalArgumentException(\"Unknown proxyClass \" + proxyClass);"); + sw.println("throw new IllegalArgumentException(\"Unknown proxyClass \" + proxyClass);"); sw.indent(); sw.outdent(); sw.outdent(); @@ -495,8 +495,7 @@ sw.outdent(); sw.println("}"); } - sw.println( - "throw new IllegalArgumentException(\"Unknown proxyClass \" + proxyClass);"); + sw.println("throw new IllegalArgumentException(\"Unknown proxyClass \" + proxyClass);"); sw.indent(); sw.outdent(); sw.outdent(); @@ -514,7 +513,8 @@ JMethod selectorMethod, JClassType mainType, String packageName, String implName) throws UnableToCompleteException { JClassType selectorInterface = selectorMethod.getReturnType().isInterface(); - logger = logger.branch(TreeLogger.DEBUG, + logger = logger.branch( + TreeLogger.DEBUG, String.format("Generating implementation of %s", selectorInterface.getName())); @@ -530,8 +530,8 @@ sw.println("private final " + mainType.getName() + "Impl factory;"); sw.println(); // constructor for the class. - sw.println( - "public " + implName + "(" + mainType.getName() + "Impl factory) {"); + sw.println("public " + implName + "(" + mainType.getName() + + "Impl factory) {"); sw.indent(); sw.println("this.factory = factory;"); sw.outdent(); @@ -589,23 +589,22 @@ } else if (isVoidRequest(typeOracle, requestType)) { requestClassName = AbstractVoidRequest.class.getName(); } else { - logger.log(TreeLogger.ERROR, - "Return type " + requestType + " is not yet supported"); + logger.log(TreeLogger.ERROR, "Return type " + requestType + + " is not yet supported"); throw new UnableToCompleteException(); } sw.println(getMethodDeclaration(method) + " {"); sw.indent(); - sw.println( - "return new " + requestClassName + "(factory" + enumArgument + ") {"); + sw.println("return new " + requestClassName + "(factory" + enumArgument + + ") {"); sw.indent(); String requestDataName = RequestData.class.getSimpleName(); sw.println("public " + requestDataName + " getRequestData() {"); sw.indent(); - sw.println( - "return new " + requestDataName + "(\"" + operationName + "\", " - + getParametersAsString(method, typeOracle) + "," - + "getPropertyRefs());"); + sw.println("return new " + requestDataName + "(\"" + operationName + + "\", " + getParametersAsString(method, typeOracle) + "," + + "getPropertyRefs());"); sw.outdent(); sw.println("}"); sw.outdent(); @@ -620,8 +619,9 @@ } /** - * This method is very similar to {@link com.google.gwt.core.ext.typeinfo.JMethod.getReadableDeclaration()}. - * The only change is that each parameter is final. + * This method is very similar to {@link + * com.google.gwt.core.ext.typeinfo.JMethod.getReadableDeclaration()}. The + * only change is that each parameter is final. */ private String getMethodDeclaration(JMethod method) { StringBuilder sb = new StringBuilder("public "); @@ -694,8 +694,7 @@ return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(BigInteger.class.getName())); } - private boolean isBooleanRequest(TypeOracle typeOracle, - JClassType requestType) { + private boolean isBooleanRequest(TypeOracle typeOracle, JClassType requestType) { return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(Boolean.class.getName())); } @@ -712,8 +711,7 @@ return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(Date.class.getName())); } - private boolean isDoubleRequest(TypeOracle typeOracle, - JClassType requestType) { + private boolean isDoubleRequest(TypeOracle typeOracle, JClassType requestType) { return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(Double.class.getName())); } @@ -721,13 +719,11 @@ return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(Enum.class.getName())); } - private boolean isFloatRequest(TypeOracle typeOracle, - JClassType requestType) { + private boolean isFloatRequest(TypeOracle typeOracle, JClassType requestType) { return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(Float.class.getName())); } - private boolean isIntegerRequest(TypeOracle typeOracle, - JClassType requestType) { + private boolean isIntegerRequest(TypeOracle typeOracle, JClassType requestType) { return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(Integer.class.getName())); } @@ -740,8 +736,7 @@ return requestType.isAssignableTo(typeOracle.findType(ProxyListRequest.class.getName())); } - private boolean isProxyRequest(TypeOracle typeOracle, - JClassType requestType) { + private boolean isProxyRequest(TypeOracle typeOracle, JClassType requestType) { return requestType.isAssignableTo(typeOracle.findType(ProxyRequest.class.getName())); } @@ -749,13 +744,11 @@ return requestType.isAssignableTo(typeOracle.findType(EntityProxy.class.getName())); } - private boolean isShortRequest(TypeOracle typeOracle, - JClassType requestType) { + private boolean isShortRequest(TypeOracle typeOracle, JClassType requestType) { return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(Short.class.getName())); } - private boolean isStringRequest(TypeOracle typeOracle, - JClassType requestType) { + private boolean isStringRequest(TypeOracle typeOracle, JClassType requestType) { return requestType.isParameterized().getTypeArgs()[0].isAssignableTo(typeOracle.findType(String.class.getName())); } @@ -802,18 +795,16 @@ * @param typeOracle * @param publicProxyType * @param proxyImplTypeName - * @param eventType * @param sw * @return * @throws UnableToCompleteException */ private JClassType printSchema(TypeOracle typeOracle, - JClassType publicProxyType, String proxyImplTypeName, - JClassType eventType, SourceWriter sw) { - sw.println( - String.format("public static class MySchema extends ProxySchema<%s> {", - proxyImplTypeName)); + JClassType publicProxyType, String proxyImplTypeName, SourceWriter sw) { + sw.println(String.format( + "public static class MySchema extends ProxySchema<%s> {", + proxyImplTypeName)); sw.indent(); sw.println("private final Set<Property<?>> allProperties;"); @@ -856,7 +847,8 @@ sw.println(); sw.println("@Override"); - sw.println(String.format("public %s create(ProxyJsoImpl jso, boolean isFuture) {", + sw.println(String.format( + "public %s create(ProxyJsoImpl jso, boolean isFuture) {", proxyImplTypeName)); sw.indent(); sw.println(String.format("return new %s(jso, isFuture);", proxyImplTypeName)); @@ -864,17 +856,6 @@ sw.println("}"); sw.println(); - sw.println("@Override"); - sw.println(String.format( - "public %s createChangeEvent(EntityProxy proxy, WriteOperation writeOperation) {", - eventType.getName())); - sw.indent(); - sw.println(String.format("return new %s((%s) proxy, writeOperation);", - eventType.getName(), publicProxyType.getName())); - sw.outdent(); - sw.println("}"); - - sw.println(); sw.println("public Class getProxyClass() {"); sw.indent(); sw.println("return " + publicProxyType.getQualifiedSourceName() + ".class;"
diff --git a/user/src/com/google/gwt/requestfactory/shared/EntityProxyChange.java b/user/src/com/google/gwt/requestfactory/shared/EntityProxyChange.java new file mode 100644 index 0000000..8c06444 --- /dev/null +++ b/user/src/com/google/gwt/requestfactory/shared/EntityProxyChange.java
@@ -0,0 +1,99 @@ +/* + * 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.requestfactory.shared; + +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.event.shared.EventHandler; +import com.google.gwt.event.shared.GwtEvent; +import com.google.gwt.event.shared.HandlerRegistration; + +/** + * <p> + * <span style="color:red">Experimental API: This class is still under rapid + * development, and is very likely to be deleted. Use it at your own risk. + * </span> + * </p> + * Abstract base class for an event announcing changes to a {@link EntityProxy}. + * <p> + * Note that this event includes an unpopulated copy of the changed proxy + * — all properties are undefined except it's id. That is, the event + * includes only enough information for receivers to issue requests to get + * themselves fresh copies of the proxy. + * <p> + * TODO: use ProxyId rather than an empty proxy + * + * @param <P> the type of the proxy + */ +public class EntityProxyChange<P extends EntityProxy> extends + GwtEvent<EntityProxyChange.Handler<P>> { + + /** + * Implemented by methods that handle EntityProxyChange events. + * @param <P> the proxy type + */ + public interface Handler<P extends EntityProxy> extends EventHandler { + void onProxyChange(EntityProxyChange<P> event); + } + + private static final Type<EntityProxyChange.Handler<?>> TYPE = new Type<EntityProxyChange.Handler<?>>(); + + /** + * Register a handler for a EntityProxyChange events for a particular proxy + * class. + */ + public static <P extends EntityProxy> HandlerRegistration registerForProxyType( + EventBus eventBus, Class<P> proxyType, + EntityProxyChange.Handler<P> handler) { + return eventBus.addHandlerToSource(TYPE, proxyType, handler); + } + + private P proxy; + + private WriteOperation writeOperation; + + public EntityProxyChange(P proxy, WriteOperation writeOperation) { + this.proxy = proxy; + this.writeOperation = writeOperation; + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Override + public GwtEvent.Type<Handler<P>> getAssociatedType() { + /* + * The instance knows its handler is of type P, but the TYPE field itself + * does not, so we have to do an unsafe cast here. + */ + + return (Type) TYPE; + } + + /** + * @return an unpopulated copy of the changed proxy — all properties are + * undefined except its id + */ + public P getProxy() { + return proxy; + } + + public WriteOperation getWriteOperation() { + return writeOperation; + } + + @Override + protected void dispatch(Handler<P> handler) { + handler.onProxyChange(this); + } +}
diff --git a/user/src/com/google/gwt/requestfactory/shared/EntityProxyChangedEvent.java b/user/src/com/google/gwt/requestfactory/shared/EntityProxyChangedEvent.java deleted file mode 100644 index d0e0d1b..0000000 --- a/user/src/com/google/gwt/requestfactory/shared/EntityProxyChangedEvent.java +++ /dev/null
@@ -1,62 +0,0 @@ -/* - * 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.requestfactory.shared; - -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.GwtEvent; - -/** - * <p> - * <span style="color:red">Experimental API: This class is still under rapid - * development, and is very likely to be deleted. Use it at your own risk. - * </span> - * </p> - * Abstract base class for an event announcing changes to a {@link EntityProxy}. - * <p> - * Note that this event includes an unpopulated copy of the changed proxy - * — all properties are undefined except it's id. That is, the event - * includes only enough information for receivers to issue requests to get - * themselves fresh copies of the proxy. - * <p> - * TODO: rather than an empty proxy, consider using a string token - * - * @param <P> the type of the proxy - * @param <H> the type of event handler - */ -// TODO Should this provide a collection of changed values rather than fire for -// each one? -public abstract class EntityProxyChangedEvent<P extends EntityProxy, H extends EventHandler> - extends GwtEvent<H> { - P proxy; - WriteOperation writeOperation; - - public EntityProxyChangedEvent(P proxy, WriteOperation writeOperation) { - this.proxy = proxy; - this.writeOperation = writeOperation; - } - - /** - * @return an unpopulated copy of the changed proxy — all properties - * are undefined except its id - */ - public P getProxy() { - return proxy; - } - - public WriteOperation getWriteOperation() { - return writeOperation; - } -}
diff --git a/user/src/com/google/gwt/requestfactory/shared/RequestEvent.java b/user/src/com/google/gwt/requestfactory/shared/RequestEvent.java index dc2f420..838b031 100644 --- a/user/src/com/google/gwt/requestfactory/shared/RequestEvent.java +++ b/user/src/com/google/gwt/requestfactory/shared/RequestEvent.java
@@ -15,8 +15,10 @@ */ package com.google.gwt.requestfactory.shared; +import com.google.gwt.event.shared.EventBus; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.GwtEvent; +import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.http.client.Response; /** @@ -28,33 +30,41 @@ * An event posted whenever an RPC request is sent or its response is received. */ public class RequestEvent extends GwtEvent<RequestEvent.Handler> { + /** * Implemented by handlers of this type of event. */ public interface Handler extends EventHandler { void onRequestEvent(RequestEvent requestEvent); } - + /** * The request state. */ public enum State { SENT, RECEIVED } - - public static final Type<Handler> TYPE = new Type<Handler>(); + + private static final Type<Handler> TYPE = new Type<Handler>(); + + public static HandlerRegistration register(EventBus eventBus, + RequestEvent.Handler handler) { + return eventBus.addHandler(TYPE, handler); + } private final State state; - - // Will only be non-null if this is an event of type RECIEVED, and the - // RPC was successful + + /** + * Will only be non-null if this is an event of type {@link State#RECEIVED}, + * and the RPC was successful + */ private final Response response; public RequestEvent(State state, Response response) { this.state = state; this.response = response; } - + @Override public GwtEvent.Type<Handler> getAssociatedType() { return TYPE; @@ -63,7 +73,7 @@ public Response getResponse() { return response; } - + public State getState() { return state; }
diff --git a/user/src/com/google/gwt/requestfactory/shared/UserInformationProxyChanged.java b/user/src/com/google/gwt/requestfactory/shared/UserInformationProxyChanged.java deleted file mode 100644 index 457b5ef..0000000 --- a/user/src/com/google/gwt/requestfactory/shared/UserInformationProxyChanged.java +++ /dev/null
@@ -1,51 +0,0 @@ -/* - * 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.requestfactory.shared; - -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.GwtEvent; - -/** - * "API Generated" event posted when the values of a {@link UserInformationProxy} - * change. - */ -public class UserInformationProxyChanged extends - EntityProxyChangedEvent<UserInformationProxy, UserInformationProxyChanged.Handler> { - - /** - * Implemented by handlers of this type of event. - */ - public interface Handler extends EventHandler { - void onUserInformationChanged(UserInformationProxyChanged event); - } - - public static final Type<Handler> TYPE = new Type<Handler>(); - - public UserInformationProxyChanged(UserInformationProxy record, WriteOperation writeOperation) { - super(record, writeOperation); - } - - @Override - public GwtEvent.Type<Handler> getAssociatedType() { - return TYPE; - } - - @Override - protected void dispatch(Handler handler) { - handler.onUserInformationChanged(this); - } -}
diff --git a/user/src/com/google/gwt/user/client/ui/Widget.java b/user/src/com/google/gwt/user/client/ui/Widget.java index 3a48ace..a148ba5 100644 --- a/user/src/com/google/gwt/user/client/ui/Widget.java +++ b/user/src/com/google/gwt/user/client/ui/Widget.java
@@ -19,7 +19,6 @@ import com.google.gwt.event.dom.client.DomEvent; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.GwtEvent; -import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.event.shared.HasHandlers; import com.google.gwt.event.shared.GwtEvent.Type; @@ -43,7 +42,8 @@ */ int eventsToSink; private boolean attached; - private HandlerManager handlerManager; + @SuppressWarnings("deprecation") + private com.google.gwt.event.shared.HandlerManager handlerManager; private Object layoutData; private Widget parent; @@ -57,6 +57,7 @@ * @param handler the handler * @return {@link HandlerRegistration} used to remove the handler */ + @SuppressWarnings("deprecation") public final <H extends EventHandler> HandlerRegistration addDomHandler( final H handler, DomEvent.Type<H> type) { assert handler != null : "handler must not be null"; @@ -73,11 +74,13 @@ * @param handler the handler * @return {@link HandlerRegistration} used to remove the handler */ + @SuppressWarnings("deprecation") public final <H extends EventHandler> HandlerRegistration addHandler( final H handler, GwtEvent.Type<H> type) { return ensureHandlers().addHandler(type, handler); } + @SuppressWarnings("deprecation") public void fireEvent(GwtEvent<?> event) { if (handlerManager != null) { handlerManager.fireEvent(event); @@ -199,13 +202,14 @@ } /** - * Creates the {@link HandlerManager} used by this Widget. You can overwrite + * Creates the {@link HandlerManager} used by this Widget. You can override * this method to create a custom {@link HandlerManager}. * * @return the {@link HandlerManager} you want to use */ - protected HandlerManager createHandlerManager() { - return new HandlerManager(this); + @SuppressWarnings("deprecation") + protected com.google.gwt.event.shared.HandlerManager createHandlerManager() { + return new com.google.gwt.event.shared.HandlerManager(this); } /** @@ -247,6 +251,7 @@ * @param type the event type * @return the number of registered handlers */ + @SuppressWarnings("deprecation") protected int getHandlerCount(Type<?> type) { return handlerManager == null ? 0 : handlerManager.getHandlerCount(type); } @@ -368,12 +373,14 @@ * * @return the handler manager * */ - HandlerManager ensureHandlers() { + @SuppressWarnings("deprecation") + com.google.gwt.event.shared.HandlerManager ensureHandlers() { return handlerManager == null ? handlerManager = createHandlerManager() : handlerManager; } - HandlerManager getHandlerManager() { + @SuppressWarnings("deprecation") + com.google.gwt.event.shared.HandlerManager getHandlerManager() { return handlerManager; }
diff --git a/user/test/com/google/gwt/app/place/AbstractPlaceHistoryHandlerTest.java b/user/test/com/google/gwt/app/place/AbstractPlaceHistoryHandlerTest.java index 1fb7612..93c6ef4 100644 --- a/user/test/com/google/gwt/app/place/AbstractPlaceHistoryHandlerTest.java +++ b/user/test/com/google/gwt/app/place/AbstractPlaceHistoryHandlerTest.java
@@ -22,8 +22,8 @@ import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.EventBus; -import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.event.shared.SimpleEventBus; import junit.framework.TestCase; @@ -116,7 +116,7 @@ Logger deadLogger = new Logger("shut up", null) { }; - EventBus eventBus = new HandlerManager(null); + EventBus eventBus = new SimpleEventBus(); PlaceController placeController = new PlaceController(eventBus, new MockPlaceControllerDelegate()) {
diff --git a/user/test/com/google/gwt/app/place/ActivityManagerTest.java b/user/test/com/google/gwt/app/place/ActivityManagerTest.java index d5a531a..a35f72f 100644 --- a/user/test/com/google/gwt/app/place/ActivityManagerTest.java +++ b/user/test/com/google/gwt/app/place/ActivityManagerTest.java
@@ -18,12 +18,13 @@ import com.google.gwt.event.shared.EventBus; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.GwtEvent; -import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.UmbrellaException; +import com.google.gwt.event.shared.testing.CountingEventBus; import com.google.gwt.user.client.ui.Widget; import junit.framework.TestCase; + /** * Eponymous unit test. */ @@ -128,7 +129,7 @@ } }; - private HandlerManager eventBus = new HandlerManager(null); + private CountingEventBus eventBus = new CountingEventBus(); private ActivityManager manager = new ActivityManager( myMap, eventBus); @@ -259,7 +260,7 @@ public void testDropHandlersOnStop() { manager.setDisplay(realDisplay); - assertEquals(0, eventBus.getHandlerCount(Event.TYPE)); + assertEquals(0, eventBus.getCount(Event.TYPE)); activity1 = new SyncActivity(null) { @Override @@ -277,30 +278,30 @@ PlaceChangeEvent event = new PlaceChangeEvent(place1); eventBus.fireEvent(event); - assertEquals(1, eventBus.getHandlerCount(Event.TYPE)); + assertEquals(1, eventBus.getCount(Event.TYPE)); event = new PlaceChangeEvent(place2); eventBus.fireEvent(event); - assertEquals(0, eventBus.getHandlerCount(Event.TYPE)); + assertEquals(0, eventBus.getCount(Event.TYPE)); // Make sure we didn't nuke the ActivityManager's own handlers - assertEquals(1, eventBus.getHandlerCount(PlaceChangeEvent.TYPE)); - assertEquals(1, eventBus.getHandlerCount(PlaceChangeRequesteEvent.TYPE)); + assertEquals(1, eventBus.getCount(PlaceChangeEvent.TYPE)); + assertEquals(1, eventBus.getCount(PlaceChangeRequesteEvent.TYPE)); } public void testEventSetupAndTeardown() { - assertEquals(0, eventBus.getHandlerCount(PlaceChangeEvent.TYPE)); - assertEquals(0, eventBus.getHandlerCount(PlaceChangeRequesteEvent.TYPE)); + assertEquals(0, eventBus.getCount(PlaceChangeEvent.TYPE)); + assertEquals(0, eventBus.getCount(PlaceChangeRequesteEvent.TYPE)); manager.setDisplay(realDisplay); - assertEquals(1, eventBus.getHandlerCount(PlaceChangeEvent.TYPE)); - assertEquals(1, eventBus.getHandlerCount(PlaceChangeRequesteEvent.TYPE)); + assertEquals(1, eventBus.getCount(PlaceChangeEvent.TYPE)); + assertEquals(1, eventBus.getCount(PlaceChangeRequesteEvent.TYPE)); manager.setDisplay(null); - assertEquals(0, eventBus.getHandlerCount(PlaceChangeEvent.TYPE)); - assertEquals(0, eventBus.getHandlerCount(PlaceChangeRequesteEvent.TYPE)); + assertEquals(0, eventBus.getCount(PlaceChangeEvent.TYPE)); + assertEquals(0, eventBus.getCount(PlaceChangeRequesteEvent.TYPE)); } public void testExceptionsOnStopAndStart() { @@ -331,7 +332,7 @@ try { PlaceChangeEvent event = new PlaceChangeEvent(place1); eventBus.fireEvent(event); - assertEquals(1, eventBus.getHandlerCount(Event.TYPE)); + assertEquals(1, eventBus.getCount(Event.TYPE)); event = new PlaceChangeEvent(place2); eventBus.fireEvent(event); @@ -347,7 +348,7 @@ assertTrue(activity1.stopped); assertNotNull(activity2.display); - assertEquals(0, eventBus.getHandlerCount(Event.TYPE)); + assertEquals(0, eventBus.getCount(Event.TYPE)); } public void testRejected() {
diff --git a/user/test/com/google/gwt/app/place/PlaceControllerTest.java b/user/test/com/google/gwt/app/place/PlaceControllerTest.java index 1eb3363..3f93a32 100644 --- a/user/test/com/google/gwt/app/place/PlaceControllerTest.java +++ b/user/test/com/google/gwt/app/place/PlaceControllerTest.java
@@ -15,7 +15,8 @@ */ package com.google.gwt.app.place; -import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.EventBus; +import com.google.gwt.event.shared.SimpleEventBus; import junit.framework.TestCase; @@ -51,7 +52,7 @@ private Logger deadLogger = new Logger("shut up", null) { }; - private HandlerManager eventBus = new HandlerManager(null); + private EventBus eventBus = new SimpleEventBus(); private MockPlaceControllerDelegate delegate = new MockPlaceControllerDelegate(); private PlaceController placeController = new PlaceController( eventBus, delegate) {
diff --git a/user/test/com/google/gwt/event/EventSuite.java b/user/test/com/google/gwt/event/EventSuite.java index 905c866..008e88c 100644 --- a/user/test/com/google/gwt/event/EventSuite.java +++ b/user/test/com/google/gwt/event/EventSuite.java
@@ -18,6 +18,8 @@ import com.google.gwt.event.dom.client.DomEventTest; import com.google.gwt.event.logical.shared.LogicalEventsTest; import com.google.gwt.event.shared.HandlerManagerTest; +import com.google.gwt.event.shared.SimpleEventBusTest; +import com.google.gwt.event.shared.ResettableEventBusTest; import com.google.gwt.junit.tools.GWTTestSuite; import junit.framework.Test; @@ -30,14 +32,11 @@ GWTTestSuite suite = new GWTTestSuite( "Test for suite for the com.google.gwt.event module."); - // ...logical.shared suite.addTestSuite(LogicalEventsTest.class); - - // ...dom.client suite.addTestSuite(DomEventTest.class); - - // ...dom.shared suite.addTestSuite(HandlerManagerTest.class); + suite.addTestSuite(SimpleEventBusTest.class); + suite.addTestSuite(ResettableEventBusTest.class); return suite; }
diff --git a/user/test/com/google/gwt/event/dom/client/DomEventTest.java b/user/test/com/google/gwt/event/dom/client/DomEventTest.java index e7c211c..65f35e4 100644 --- a/user/test/com/google/gwt/event/dom/client/DomEventTest.java +++ b/user/test/com/google/gwt/event/dom/client/DomEventTest.java
@@ -26,7 +26,6 @@ /** * Events test. */ -// TODO(ECC) check that max handlers work properly. public class DomEventTest extends HandlerTestBase { private HandlerManager manager; static class Flag {
diff --git a/user/test/com/google/gwt/event/logical/shared/LogicalEventsTest.java b/user/test/com/google/gwt/event/logical/shared/LogicalEventsTest.java index dc03d2a..ec9ff31 100644 --- a/user/test/com/google/gwt/event/logical/shared/LogicalEventsTest.java +++ b/user/test/com/google/gwt/event/logical/shared/LogicalEventsTest.java
@@ -75,7 +75,7 @@ @SuppressWarnings("unchecked") private <H extends EventHandler> void simpleFire(GwtEvent.Type<H> type, - GwtEvent instance) { + @SuppressWarnings("rawtypes") GwtEvent instance) { Fire f = new Fire(); manager.addHandler(type, (H) f); manager.fireEvent(instance);
diff --git a/user/test/com/google/gwt/event/shared/HandlerManagerTest.java b/user/test/com/google/gwt/event/shared/HandlerManagerTest.java index 6fed302..6b6ce9d 100644 --- a/user/test/com/google/gwt/event/shared/HandlerManagerTest.java +++ b/user/test/com/google/gwt/event/shared/HandlerManagerTest.java
@@ -24,17 +24,14 @@ import java.util.Set; /** - * Handler manager test. + * Handler manager test. Very redundant with {@link SimpleEventBusTest}, but + * preserved to guard against regressions. */ +@SuppressWarnings("deprecation") public class HandlerManagerTest extends HandlerTestBase { - public void testAddHandlers() { - + public void testAddAndRemoveHandlers() { HandlerManager manager = new HandlerManager("bogus source"); - addHandlers(manager); - } - - private void addHandlers(HandlerManager manager) { manager.addHandler(MouseDownEvent.getType(), mouse1); manager.addHandler(MouseDownEvent.getType(), mouse2); manager.addHandler(MouseDownEvent.getType(), adaptor1); @@ -64,11 +61,6 @@ }); assertFired(mouse1, mouse2, mouse3, adaptor1); assertNotFired(click1, click2); - } - - public void testRemoveHandlers() { - HandlerManager manager = new HandlerManager("bogus source"); - addHandlers(manager); // Gets rid of first instance. manager.removeHandler(MouseDownEvent.getType(), adaptor1); manager.fireEvent(new MouseDownEvent() { @@ -190,8 +182,7 @@ assertNotFired(two); } - // This test is disabled because it fails '-ea' - public void notestConcurrentAddAfterRemoveIsNotClobbered() { + public void testConcurrentAddAfterRemoveIsNotClobbered() { final HandlerManager manager = new HandlerManager("bogus source"); MouseDownHandler one = new MouseDownHandler() { @@ -203,7 +194,9 @@ }; manager.addHandler(MouseDownEvent.getType(), one); - if (!GWT.isScript()) { + boolean assertsOn = getClass().desiredAssertionStatus(); + + if (assertsOn) { try { manager.fireEvent(new MouseDownEvent() { }); @@ -225,6 +218,9 @@ public void testMultiFiring() { + final MouseDownEvent masterEvent = new MouseDownEvent() { + }; + HandlerManager manager = new HandlerManager("source1"); final HandlerManager manager2 = new HandlerManager("source2"); @@ -244,6 +240,7 @@ public void onMouseDown(MouseDownEvent event) { assertEquals("source2", event.getSource()); + assertSame(masterEvent, event); } }); @@ -251,14 +248,15 @@ public void onMouseDown(MouseDownEvent event) { assertEquals("source1", event.getSource()); + assertSame(masterEvent, event); } }); reset(); - manager.fireEvent(new MouseDownEvent() { - }); + manager.fireEvent(masterEvent); assertFired(mouse1, adaptor1, mouse3); + assertFalse("Event should be dead", masterEvent.isLive()); } // This test is disabled because it fails '-ea' @@ -352,6 +350,20 @@ // Exception should not have prevented all three mouse handlers from getting // the event. assertFired(mouse1, mouse2, mouse3); - assertFalse("Event should be dead", event.isLive()); + } + + public void testNullSourceOkay() { + SimpleEventBus reg = new SimpleEventBus(); + + MouseDownHandler handler = new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { + add(this); + assertNull(event.getSource()); + } + }; + reg.addHandler(MouseDownEvent.getType(), handler); + reg.fireEvent(new MouseDownEvent() { + }); + assertFired(handler); } }
diff --git a/user/test/com/google/gwt/event/shared/ResettableEventBusTest.java b/user/test/com/google/gwt/event/shared/ResettableEventBusTest.java new file mode 100644 index 0000000..e4fc834 --- /dev/null +++ b/user/test/com/google/gwt/event/shared/ResettableEventBusTest.java
@@ -0,0 +1,61 @@ +/* + * 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.event.shared; + +import com.google.gwt.event.dom.client.DomEvent.Type; +import com.google.gwt.event.dom.client.MouseDownEvent; +import com.google.gwt.event.dom.client.MouseDownHandler; +import com.google.gwt.event.shared.testing.CountingEventBus; + +/** + * Eponymous unit test. + */ +public class ResettableEventBusTest extends HandlerTestBase { + public void testSimple() { + CountingEventBus wrapped = new CountingEventBus(); + ResettableEventBus subject = new ResettableEventBus(wrapped); + + Type<MouseDownHandler> type = MouseDownEvent.getType(); + + assertEquals(0, wrapped.getCount(type)); + + subject.addHandler(type, mouse1); + subject.addHandlerToSource(type, "baker", mouse2); + subject.addHandler(type, mouse3); + + assertEquals(3, wrapped.getCount(type)); + + subject.fireEvent(new MouseDownEvent() { + }); + assertFired(mouse1, mouse3); + assertNotFired(mouse2); + + reset(); + + subject.fireEventFromSource(new MouseDownEvent() { + }, "baker"); + assertFired(mouse1, mouse2, mouse3); + + reset(); + + subject.removeHandlers(); + assertEquals(0, wrapped.getCount(type)); + + subject.fireEvent(new MouseDownEvent() { + }); + assertNotFired(mouse1, mouse2, mouse3); + } +}
diff --git a/user/test/com/google/gwt/event/shared/SimpleEventBusTest.java b/user/test/com/google/gwt/event/shared/SimpleEventBusTest.java new file mode 100644 index 0000000..3221e83 --- /dev/null +++ b/user/test/com/google/gwt/event/shared/SimpleEventBusTest.java
@@ -0,0 +1,481 @@ +/* + * 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.event.shared; + +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.DomEvent.Type; +import com.google.gwt.event.dom.client.MouseDownEvent; +import com.google.gwt.event.dom.client.MouseDownHandler; +import com.google.gwt.event.shared.testing.CountingEventBus; + +import junit.framework.AssertionFailedError; + +import java.util.Set; + +/** + * Eponymous unit test. + */ +public class SimpleEventBusTest extends HandlerTestBase { + + public void testAddAndRemoveHandlers() { + CountingEventBus eventBus = new CountingEventBus(new SimpleEventBus()); + eventBus.addHandler(MouseDownEvent.getType(), mouse1); + eventBus.addHandler(MouseDownEvent.getType(), mouse2); + HandlerRegistration reg1 = eventBus.addHandler(MouseDownEvent.getType(), + adaptor1); + eventBus.fireEvent(new MouseDownEvent() { + }); + assertEquals(3, eventBus.getCount(MouseDownEvent.getType())); + assertFired(mouse1, mouse2, adaptor1); + eventBus.addHandler(MouseDownEvent.getType(), mouse3); + assertEquals(4, eventBus.getCount(MouseDownEvent.getType())); + + eventBus.addHandler(MouseDownEvent.getType(), mouse1); + eventBus.addHandler(MouseDownEvent.getType(), mouse2); + HandlerRegistration reg2 = eventBus.addHandler(MouseDownEvent.getType(), + adaptor1); + + /* + * You can indeed add handlers twice, they will only be removed one at a + * time though. + */ + assertEquals(7, eventBus.getCount(MouseDownEvent.getType())); + eventBus.addHandler(ClickEvent.getType(), adaptor1); + eventBus.addHandler(ClickEvent.getType(), click1); + eventBus.addHandler(ClickEvent.getType(), click2); + + assertEquals(7, eventBus.getCount(MouseDownEvent.getType())); + assertEquals(3, eventBus.getCount(ClickEvent.getType())); + + reset(); + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(mouse1, mouse2, mouse3, adaptor1); + assertNotFired(click1, click2); + + // Gets rid of first instance. + reg1.removeHandler(); + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(mouse1, mouse2, mouse3, adaptor1); + assertNotFired(click1, click2); + + // Gets rid of second instance. + reg2.removeHandler(); + reset(); + eventBus.fireEvent(new MouseDownEvent() { + }); + + assertFired(mouse1, mouse2, mouse3); + assertNotFired(adaptor1, click1, click2); + + // Checks to see if click events are still working. + reset(); + eventBus.fireEvent(new ClickEvent() { + }); + + assertNotFired(mouse1, mouse2, mouse3); + assertFired(click1, click2, adaptor1); + } + + public void testConcurrentAdd() { + final SimpleEventBus eventBus = new SimpleEventBus(); + final MouseDownHandler two = new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { + add(this); + } + }; + MouseDownHandler one = new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { + eventBus.addHandler(MouseDownEvent.getType(), two); + add(this); + } + }; + eventBus.addHandler(MouseDownEvent.getType(), one); + eventBus.addHandler(MouseDownEvent.getType(), mouse1); + eventBus.addHandler(MouseDownEvent.getType(), mouse2); + eventBus.addHandler(MouseDownEvent.getType(), mouse3); + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(one, mouse1, mouse2, mouse3); + assertNotFired(two); + + reset(); + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(one, two, mouse1, mouse2, mouse3); + } + + class ShyHandler implements MouseDownHandler { + HandlerRegistration r; + + public void onMouseDown(MouseDownEvent event) { + add(this); + r.removeHandler(); + } + } + + public void testConcurrentRemove() { + final SimpleEventBus eventBus = new SimpleEventBus(); + + ShyHandler h = new ShyHandler(); + + eventBus.addHandler(MouseDownEvent.getType(), mouse1); + h.r = eventBus.addHandler(MouseDownEvent.getType(), h); + eventBus.addHandler(MouseDownEvent.getType(), mouse2); + eventBus.addHandler(MouseDownEvent.getType(), mouse3); + + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(h, mouse1, mouse2, mouse3); + reset(); + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(mouse1, mouse2, mouse3); + assertNotFired(h); + } + + class SourcedHandler implements MouseDownHandler { + final String expectedSource; + + SourcedHandler(String source) { + this.expectedSource = source; + } + + public void onMouseDown(MouseDownEvent event) { + add(this); + assertEquals(expectedSource, event.getSource()); + } + } + + public void testAssertThrowsNpe() { + final SimpleEventBus eventBus = new SimpleEventBus(); + + try { + assertThrowsNpe(new ScheduledCommand() { + public void execute() { + eventBus.addHandler(MouseDownEvent.getType(), mouse1); + } + }); + fail("expected AssertionFailedError"); + } catch (AssertionFailedError e) { + /* pass */ + } + } + + public void testNullChecks() { + final SimpleEventBus eventBus = new SimpleEventBus(); + final Type<MouseDownHandler> type = MouseDownEvent.getType(); + + assertThrowsNpe(new ScheduledCommand() { + public void execute() { + eventBus.addHandler(null, mouse1); + } + }); + + assertThrowsNpe(new ScheduledCommand() { + public void execute() { + eventBus.addHandlerToSource(type, "foo", null); + } + }); + assertThrowsNpe(new ScheduledCommand() { + public void execute() { + eventBus.addHandlerToSource(type, null, mouse1); + } + }); + assertThrowsNpe(new ScheduledCommand() { + public void execute() { + eventBus.addHandlerToSource(null, "foo", mouse1); + } + }); + + assertThrowsNpe(new ScheduledCommand() { + public void execute() { + eventBus.fireEvent(null); + } + }); + + assertThrowsNpe(new ScheduledCommand() { + public void execute() { + eventBus.fireEventFromSource(null, ""); + } + }); + + assertThrowsNpe(new ScheduledCommand() { + public void execute() { + eventBus.fireEventFromSource(new MouseDownEvent() { + }, null); + } + }); + assertThrowsNpe(new ScheduledCommand() { + public void execute() { + eventBus.fireEventFromSource(null, "baker"); + } + }); + } + + private void assertThrowsNpe(ScheduledCommand command) { + try { + command.execute(); + fail("expected NullPointerException"); + } catch (NullPointerException e) { + /* pass */ + } + } + + public void testFromSource() { + final SimpleEventBus eventBus = new SimpleEventBus(); + + SourcedHandler global = new SourcedHandler("able"); + SourcedHandler able = new SourcedHandler("able"); + SourcedHandler baker = new SourcedHandler("baker"); + + eventBus.addHandler(MouseDownEvent.getType(), global); + eventBus.addHandlerToSource(MouseDownEvent.getType(), "able", able); + eventBus.addHandlerToSource(MouseDownEvent.getType(), "baker", baker); + + eventBus.fireEventFromSource(new MouseDownEvent() { + }, "able"); + assertFired(global, able); + assertNotFired(baker); + } + + public void testNoSource() { + final SimpleEventBus eventBus = new SimpleEventBus(); + + SourcedHandler global = new SourcedHandler(null); + SourcedHandler able = new SourcedHandler("able"); + SourcedHandler baker = new SourcedHandler("baker"); + + eventBus.addHandler(MouseDownEvent.getType(), global); + eventBus.addHandlerToSource(MouseDownEvent.getType(), "able", able); + eventBus.addHandlerToSource(MouseDownEvent.getType(), "baker", baker); + + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(global); + assertNotFired(able, baker); + } + + public void testConcurrentAddAndRemoveByNastyUsersTryingToHurtUs() { + final SimpleEventBus eventBus = new SimpleEventBus(); + final MouseDownHandler two = new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { + add(this); + } + + @Override + public String toString() { + return "two"; + } + }; + MouseDownHandler one = new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { + eventBus.addHandler(MouseDownEvent.getType(), two).removeHandler(); + add(this); + } + + @Override + public String toString() { + return "one"; + } + }; + eventBus.addHandler(MouseDownEvent.getType(), one); + eventBus.addHandler(MouseDownEvent.getType(), mouse1); + eventBus.addHandler(MouseDownEvent.getType(), mouse2); + eventBus.addHandler(MouseDownEvent.getType(), mouse3); + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(one, mouse1, mouse2, mouse3); + assertNotFired(two); + + reset(); + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(one, mouse1, mouse2, mouse3); + assertNotFired(two); + } + + public void testRemoveSelf() { + final SimpleEventBus eventBus = new SimpleEventBus(); + + MouseDownHandler h = new MouseDownHandler() { + HandlerRegistration reg = eventBus.addHandler(MouseDownEvent.getType(), + this); + + public void onMouseDown(MouseDownEvent event) { + add(this); + reg.removeHandler(); + } + }; + + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(h); + + reset(); + + eventBus.fireEvent(new MouseDownEvent() { + }); + assertNotFired(h); + } + + public void testNoDoubleRemove() { + final SimpleEventBus eventBus = new SimpleEventBus(); + HandlerRegistration reg = eventBus.addHandler(MouseDownEvent.getType(), + mouse1); + reg.removeHandler(); + + boolean assertsOn = getClass().desiredAssertionStatus(); + + if (assertsOn) { + try { + reg.removeHandler(); + fail("Should have thrown on remove"); + } catch (AssertionError e) { /* pass */ + } + } else { + reg.removeHandler(); + // Succeed on no assert failure + } + } + + public void testConcurrentAddAfterRemoveIsNotClobbered() { + final SimpleEventBus eventBus = new SimpleEventBus(); + + MouseDownHandler one = new MouseDownHandler() { + HandlerRegistration reg = addIt(); + + public void onMouseDown(MouseDownEvent event) { + reg.removeHandler(); + addIt(); + add(this); + } + + private HandlerRegistration addIt() { + return eventBus.addHandler(MouseDownEvent.getType(), mouse1); + } + }; + + eventBus.addHandler(MouseDownEvent.getType(), one); + + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(one); + + reset(); + + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(one, mouse1); + } + + public void testReverseOrder() { + @SuppressWarnings("deprecation") + final SimpleEventBus eventBus = new SimpleEventBus(true); + final MouseDownHandler handler0 = new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { + add(this); + } + }; + final MouseDownHandler handler1 = new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { + assertNotFired(handler0); + add(this); + } + }; + final MouseDownHandler handler2 = new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { + assertNotFired(handler0, handler1); + add(this); + } + }; + eventBus.addHandler(MouseDownEvent.getType(), handler0); + eventBus.addHandler(MouseDownEvent.getType(), handler1); + eventBus.addHandler(MouseDownEvent.getType(), handler2); + + reset(); + eventBus.fireEvent(new MouseDownEvent() { + }); + assertFired(handler0, handler1, handler2); + } + + static class ThrowingHandler implements MouseDownHandler { + private final RuntimeException e; + + public ThrowingHandler(RuntimeException e) { + this.e = e; + } + + public void onMouseDown(MouseDownEvent event) { + throw e; + } + } + + public void testHandlersThrow() { + RuntimeException exception1 = new RuntimeException("first exception"); + RuntimeException exception2 = new RuntimeException("second exception"); + + final SimpleEventBus eventBus = new SimpleEventBus(); + + eventBus.addHandler(MouseDownEvent.getType(), mouse1); + eventBus.addHandler(MouseDownEvent.getType(), new ThrowingHandler( + exception1)); + eventBus.addHandler(MouseDownEvent.getType(), mouse2); + eventBus.addHandler(MouseDownEvent.getType(), new ThrowingHandler( + exception2)); + eventBus.addHandler(MouseDownEvent.getType(), mouse3); + + MouseDownEvent event = new MouseDownEvent() { + }; + + try { + eventBus.fireEvent(event); + fail("eventBus should have thrown"); + } catch (UmbrellaException e) { + Set<Throwable> causes = e.getCauses(); + assertEquals("Exception should wrap the two thrown exceptions", 2, + causes.size()); + assertTrue("First exception should be under the umbrella", + causes.contains(exception1)); + assertTrue("Second exception should be under the umbrella", + causes.contains(exception2)); + } + + /* + * Exception should not have prevented all three mouse handlers from getting + * the event. + */ + assertFired(mouse1, mouse2, mouse3); + } + + public void testNullSourceOkay() { + SimpleEventBus reg = new SimpleEventBus(); + + MouseDownHandler handler = new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { + add(this); + assertNull(event.getSource()); + } + }; + reg.addHandler(MouseDownEvent.getType(), handler); + reg.fireEvent(new MouseDownEvent() { + }); + assertFired(handler); + } +}
diff --git a/user/test/com/google/gwt/requestfactory/client/EditorTest.java b/user/test/com/google/gwt/requestfactory/client/EditorTest.java index c96341b..5dade68 100644 --- a/user/test/com/google/gwt/requestfactory/client/EditorTest.java +++ b/user/test/com/google/gwt/requestfactory/client/EditorTest.java
@@ -19,7 +19,7 @@ import com.google.gwt.editor.client.Editor; import com.google.gwt.editor.client.adapters.SimpleEditor; import com.google.gwt.event.shared.EventBus; -import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.junit.client.GWTTestCase; import com.google.gwt.requestfactory.shared.Receiver; import com.google.gwt.requestfactory.shared.SimpleBarProxy; @@ -71,7 +71,7 @@ @Override public void gwtSetUp() { factory = GWT.create(SimpleRequestFactory.class); - eventBus = new HandlerManager(null); + eventBus = new SimpleEventBus(); factory.init(eventBus); }
diff --git a/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java b/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java index 71d0d50..ec50976 100644 --- a/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java +++ b/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java
@@ -16,7 +16,7 @@ package com.google.gwt.requestfactory.client; import com.google.gwt.core.client.GWT; -import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.junit.client.GWTTestCase; import com.google.gwt.requestfactory.client.impl.ProxyImpl; import com.google.gwt.requestfactory.shared.EntityProxy; @@ -36,13 +36,11 @@ public class RequestFactoryTest extends GWTTestCase { private SimpleRequestFactory req; - private HandlerManager eventBus; @Override public void gwtSetUp() { req = GWT.create(SimpleRequestFactory.class); - eventBus = new HandlerManager(null); - req.init(eventBus); + req.init(new SimpleEventBus()); } @Override @@ -60,7 +58,7 @@ public void testDummyCreate() { delayTestFinish(5000); - final SimpleFooProxy foo = (SimpleFooProxy) req.create(SimpleFooProxy.class); + final SimpleFooProxy foo = req.create(SimpleFooProxy.class); Object futureId = foo.getId(); assertEquals(futureId, foo.getId()); assertTrue(((ProxyImpl) foo).isFuture()); @@ -83,19 +81,19 @@ public void testStableId() { delayTestFinish(5000); - final SimpleFooProxy foo = (SimpleFooProxy) req.create(SimpleFooProxy.class); + final SimpleFooProxy foo = req.create(SimpleFooProxy.class); final Object futureId = foo.getId(); assertTrue(((ProxyImpl) foo).isFuture()); RequestObject<SimpleFooProxy> fooReq = req.simpleFooRequest().persistAndReturnSelf( foo); - + final SimpleFooProxy newFoo = fooReq.edit(foo); assertEquals(futureId, foo.getId()); assertTrue(((ProxyImpl) foo).isFuture()); assertEquals(futureId, newFoo.getId()); assertTrue(((ProxyImpl) newFoo).isFuture()); - - newFoo.setUserName("GWT basic user"); + + newFoo.setUserName("GWT basic user"); fooReq.fire(new Receiver<SimpleFooProxy>() { public void onSuccess(final SimpleFooProxy returned, @@ -109,7 +107,7 @@ checkStableIdEquals(foo, returned); checkStableIdEquals(newFoo, returned); - + RequestObject<SimpleFooProxy> editRequest = req.simpleFooRequest().persistAndReturnSelf( returned); final SimpleFooProxy editableFoo = editRequest.edit(returned); @@ -126,12 +124,12 @@ } }); } - + private void checkStableIdEquals(SimpleFooProxy expected, SimpleFooProxy actual) { assertNotSame(expected.stableId(), actual.stableId()); assertEquals(expected.stableId(), actual.stableId()); assertEquals(expected.stableId().hashCode(), actual.stableId().hashCode()); - + // No assumptions about the proxy objects (being proxies and all) assertNotSame(expected, actual); assertFalse(expected.equals(actual)); @@ -152,7 +150,7 @@ SyncResult syncResult = syncResults.iterator().next(); /* * Make sure your class path includes: - * + * * tools/apache/log4j/log4j-1.2.16.jar * tools/hibernate/validator/hibernate-validator-4.1.0.Final.jar * tools/slf4j/slf4j-api/slf4j-api-1.6.1.jar @@ -183,18 +181,18 @@ assertEquals(1, syncResults.size()); SyncResult syncResult = syncResults.iterator().next(); assertFalse(syncResult.hasViolations()); - + RequestObject<Void> editRequest = req.simpleFooRequest().persist(returned); SimpleFooProxy editableFoo = editRequest.edit(returned); editableFoo.setUserName("A"); - + editRequest.fire(new Receiver<Void>() { public void onSuccess(Void returned, Set<SyncResult> syncResults) { assertEquals(1, syncResults.size()); SyncResult syncResult = syncResults.iterator().next(); /* * Make sure your class path includes: - * + * * tools/apache/log4j/log4j-1.2.16.jar * tools/hibernate/validator/hibernate-validator-4.1.0.Final.jar * tools/slf4j/slf4j-api/slf4j-api-1.6.1.jar @@ -208,7 +206,6 @@ violations.get("userName")); finishTest(); } - }); } }); @@ -232,18 +229,18 @@ assertEquals(1, syncResults.size()); SyncResult syncResult = syncResults.iterator().next(); assertFalse(syncResult.hasViolations()); - + RequestObject<SimpleFooProxy> editRequest = req.simpleFooRequest().persistAndReturnSelf(returned); SimpleFooProxy editableFoo = editRequest.edit(returned); editableFoo.setUserName("A"); - + editRequest.fire(new Receiver<SimpleFooProxy>() { public void onSuccess(SimpleFooProxy returned, Set<SyncResult> syncResults) { assertEquals(1, syncResults.size()); SyncResult syncResult = syncResults.iterator().next(); /* * Make sure your class path includes: - * + * * tools/apache/log4j/log4j-1.2.16.jar * tools/hibernate/validator/hibernate-validator-4.1.0.Final.jar * tools/slf4j/slf4j-api/slf4j-api-1.6.1.jar @@ -257,7 +254,6 @@ violations.get("userName")); finishTest(); } - }); } });
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java b/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java index 7e69057..79815a9 100644 --- a/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java +++ b/user/test/com/google/gwt/requestfactory/client/impl/DeltaValueStoreJsonImplTest.java
@@ -15,7 +15,7 @@ */ package com.google.gwt.requestfactory.client.impl; -import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONParser; @@ -59,8 +59,7 @@ public void gwtSetUp() { valueStore = new ValueStoreJsonImpl(); requestFactory = (RequestFactoryJsonImpl) SimpleRequestFactoryInstance.factory(); - HandlerManager eventBus = new HandlerManager(null); - requestFactory.init(eventBus); + requestFactory.init(new SimpleEventBus()); // add a proxy jso = ProxyJsoImpl.create(42L, 1, SimpleRequestFactoryInstance.schema(),
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/EntityProxyIdImplTest.java b/user/test/com/google/gwt/requestfactory/client/impl/EntityProxyIdImplTest.java index 246a782..01aef54 100644 --- a/user/test/com/google/gwt/requestfactory/client/impl/EntityProxyIdImplTest.java +++ b/user/test/com/google/gwt/requestfactory/client/impl/EntityProxyIdImplTest.java
@@ -16,8 +16,6 @@ package com.google.gwt.requestfactory.client.impl; import com.google.gwt.requestfactory.shared.EntityProxy; -import com.google.gwt.requestfactory.shared.EntityProxyChangedEvent; -import com.google.gwt.requestfactory.shared.WriteOperation; import junit.framework.TestCase; @@ -37,12 +35,6 @@ } @Override - public EntityProxyChangedEvent<?, ?> createChangeEvent(EntityProxy proxy, - WriteOperation writeOperation) { - throw new UnsupportedOperationException("Auto-generated method stub"); - } - - @Override public Class<? extends EntityProxy> getProxyClass() { throw new UnsupportedOperationException("Auto-generated method stub"); }
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/SimpleBazProxyImpl.java b/user/test/com/google/gwt/requestfactory/client/impl/SimpleBazProxyImpl.java index 36c1712..8c5406f 100644 --- a/user/test/com/google/gwt/requestfactory/client/impl/SimpleBazProxyImpl.java +++ b/user/test/com/google/gwt/requestfactory/client/impl/SimpleBazProxyImpl.java
@@ -15,10 +15,8 @@ */ package com.google.gwt.requestfactory.client.impl; -import com.google.gwt.requestfactory.shared.Property; import com.google.gwt.requestfactory.shared.EntityProxy; -import com.google.gwt.requestfactory.shared.EntityProxyChangedEvent; -import com.google.gwt.requestfactory.shared.WriteOperation; +import com.google.gwt.requestfactory.shared.Property; import java.util.Collections; import java.util.HashSet; @@ -56,13 +54,6 @@ } @Override - public EntityProxyChangedEvent<?, ?> createChangeEvent(EntityProxy proxy, - WriteOperation writeOperation) { - // ignore - return null; - } - - @Override public Class<? extends EntityProxy> getProxyClass() { // ignore return null;
diff --git a/user/test/com/google/gwt/requestfactory/client/impl/ValueStoreJsonImplTest.java b/user/test/com/google/gwt/requestfactory/client/impl/ValueStoreJsonImplTest.java index ef00b46..43ff11d 100644 --- a/user/test/com/google/gwt/requestfactory/client/impl/ValueStoreJsonImplTest.java +++ b/user/test/com/google/gwt/requestfactory/client/impl/ValueStoreJsonImplTest.java
@@ -15,7 +15,7 @@ */ package com.google.gwt.requestfactory.client.impl; -import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.junit.client.GWTTestCase; /** @@ -33,8 +33,7 @@ ProxyJsoImpl minimalJso = ProxyJsoImplTest.getMinimalJso(); ProxyJsoImpl populatedJso = ProxyJsoImplTest.getPopulatedJso(); ProxyJsoImpl copyPopulatedJso = ProxyJsoImplTest.getPopulatedJso(); - HandlerManager eventBus = new HandlerManager(null); - minimalJso.getRequestFactory().init(eventBus); + minimalJso.getRequestFactory().init(new SimpleEventBus()); assertNull(valueStore.putInValueStore(minimalJso)); assertNull(valueStore.putInValueStore(populatedJso));
diff --git a/user/test/com/google/gwt/requestfactory/shared/SimpleBarProxyChanged.java b/user/test/com/google/gwt/requestfactory/shared/SimpleBarProxyChanged.java deleted file mode 100644 index 62fe93e..0000000 --- a/user/test/com/google/gwt/requestfactory/shared/SimpleBarProxyChanged.java +++ /dev/null
@@ -1,50 +0,0 @@ -/* - * 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.requestfactory.shared; - -import com.google.gwt.event.shared.EventHandler; - -/** - * Test implementation of {@link com.google.gwt.requestfactory.shared.EntityProxyChangedEvent} for - * {@link com.google.gwt.requestfactory.shared.SimpleFooProxy}. - */ -public class SimpleBarProxyChanged extends - EntityProxyChangedEvent<SimpleBarProxy, SimpleBarProxyChanged.Handler> { - -/** - * Test Handler for SimpleFooChanged event. - */ - public interface Handler extends EventHandler { - void onSimpleBarProxyChanged(SimpleBarProxyChanged proxy); - } - - public static final Type<Handler> TYPE = new Type<Handler>(); - - public SimpleBarProxyChanged(SimpleBarProxy proxy, - WriteOperation writeOperation) { - super(proxy, writeOperation); - } - - @Override - public Type<Handler> getAssociatedType() { - return TYPE; - } - - @Override - protected void dispatch(Handler handler) { - handler.onSimpleBarProxyChanged(this); - } -}
diff --git a/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxyChanged.java b/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxyChanged.java deleted file mode 100644 index 4ab65ff..0000000 --- a/user/test/com/google/gwt/requestfactory/shared/SimpleFooProxyChanged.java +++ /dev/null
@@ -1,50 +0,0 @@ -/* - * 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.requestfactory.shared; - -import com.google.gwt.event.shared.EventHandler; - -/** - * Test implementation of {@link EntityProxyChangedEvent} for - * {@link SimpleFooProxy}. - */ -public class SimpleFooProxyChanged extends - EntityProxyChangedEvent<SimpleFooProxy, SimpleFooProxyChanged.Handler> { - -/** - * Test Handler for SimpleFooChanged event. - */ - public interface Handler extends EventHandler { - void onSimpleFooProxyChanged(SimpleFooProxyChanged proxy); - } - - public static final Type<Handler> TYPE = new Type<Handler>(); - - public SimpleFooProxyChanged(SimpleFooProxy proxy, - WriteOperation writeOperation) { - super(proxy, writeOperation); - } - - @Override - public Type<Handler> getAssociatedType() { - return TYPE; - } - - @Override - protected void dispatch(Handler handler) { - handler.onSimpleFooProxyChanged(this); - } -}