Revision: 8149
Author: r...@google.com
Date: Fri May 14 13:11:53 2010
Log: Add an EntityCounter that computes and persists a count for each
entity kind.
It may be run manually using a different .html entry point as needed.
Also, fix checkstyle errors.
http://code.google.com/p/google-web-toolkit/source/detail?r=8149
Added:
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/server/domain/EntityCounter.java
Modified:
/branches/2.1/bikeshed/src/META-INF/persistence.xml
/branches/2.1/bikeshed/src/com/google/gwt/app/client/NotificationMole.java
/branches/2.1/bikeshed/src/com/google/gwt/mobile/client/MobileScrollPanel.java
/branches/2.1/bikeshed/src/com/google/gwt/mobile/client/Momentum.java
/branches/2.1/bikeshed/src/com/google/gwt/mobile/client/TouchHandler.java
/branches/2.1/bikeshed/src/com/google/gwt/requestfactory/shared/RequestEvent.java
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/DataGenerationService.java
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/DataGenerationServiceAsync.java
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/LoadExpensesDB.java
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/Scaffold.java
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/server/DataGenerationServiceImpl.java
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/server/ReportGenerator.java
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/server/ReportGeneratorMain.java
=======================================
--- /dev/null
+++
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/server/domain/EntityCounter.java
Fri May 14 13:11:53 2010
@@ -0,0 +1,326 @@
+/*
+ * 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.server.domain;
+
+import com.google.apphosting.api.DeadlineExceededException;
+
+import java.util.logging.Logger;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+/**
+ * Stores the current entity counts.
+ */
+...@entity
+public class EntityCounter {
+
+ private static final Logger log =
Logger.getLogger(EntityCounter.class.getName());
+
+ private static final int KIND_EMPLOYEE = 0;
+
+ private static final int KIND_EXPENSE = 1;
+
+ private static final String[] KIND_NAMES =
{"Employee", "Expense", "Report"};
+
+ private static final int KIND_REPORT = 2;
+
+ private static final Long ONE = Long.valueOf(1L);
+
+ private static final Long ZERO = Long.valueOf(0L);
+
+ public static final EntityManager entityManager() {
+ return EMF.get().createEntityManager();
+ }
+
+ public static long getEmployeeCount() {
+ EntityCounter counter = getCounter();
+ Long l = counter.getNumEmployees();
+ return l == null ? 0 : l.longValue();
+ }
+
+ public static long getExpenseCount() {
+ EntityCounter counter = getCounter();
+ Long l = counter.getNumExpenses();
+ return l == null ? 0 : l.longValue();
+ }
+
+ public static long getReportCount() {
+ EntityCounter counter = getCounter();
+ Long l = counter.getNumReports();
+ return l == null ? 0 : l.longValue();
+ }
+
+ public static void reset() {
+ EntityCounter counter = getCounter();
+ counter.clear();
+
+ EntityManager em = entityManager();
+ try {
+ em.merge(counter);
+ } finally {
+ em.close();
+ }
+ }
+
+ public static long updateEmployeeCount() {
+ return update(KIND_EMPLOYEE);
+ }
+
+ public static long updateExpenseCount() {
+ return update(KIND_EXPENSE);
+ }
+
+ public static long updateReportCount() {
+ return update(KIND_REPORT);
+ }
+
+ private static void copy(EntityCounter dest, EntityCounter src) {
+ dest.setId(src.getId());
+ dest.setMaxCheckedEmployeeId(src.getMaxCheckedEmployeeId());
+ dest.setMaxCheckedExpenseId(src.getMaxCheckedExpenseId());
+ dest.setMaxCheckedReportId(src.getMaxCheckedReportId());
+ dest.setNumEmployees(src.getNumEmployees());
+ dest.setNumExpenses(src.getNumExpenses());
+ dest.setNumReports(src.getNumReports());
+ }
+
+ private static EntityCounter getCounter() {
+ EntityManager em = entityManager();
+ try {
+ EntityCounter counter = em.find(EntityCounter.class, 1);
+ if (counter == null) {
+ counter = new EntityCounter();
+ counter.clear();
+ em.persist(counter);
+ }
+ return counter;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ em.close();
+ }
+ }
+
+ private static long update(int kind) {
+ EntityManager em = entityManager();
+
+ String kindName = KIND_NAMES[kind];
+ log.info("Updating count for " + kindName);
+
+ EntityCounter oldCounter = getCounter();
+ EntityCounter counter = new EntityCounter();
+ copy(counter, oldCounter);
+
+ log.info("Starting at getMaxCheckedEmployeeId() = " +
counter.getMaxCheckedEmployeeId());
+ log.info("Starting at getMaxCheckedExpenseId() = " +
counter.getMaxCheckedExpenseId());
+ log.info("Starting at getMaxCheckedReportId() = " +
counter.getMaxCheckedReportId());
+ log.info("Starting at getNumEmployees() = " +
counter.getNumEmployees());
+ log.info("Starting at getNumExpenses() = " + counter.getNumExpenses());
+ log.info("Starting at getNumReports() = " + counter.getNumReports());
+
+ EntityTransaction transaction = em.getTransaction();
+ transaction.begin();
+
+ try {
+ while (true) {
+ Long min;
+ switch (kind) {
+ case KIND_EMPLOYEE:
+ min = counter.getMaxCheckedEmployeeId();
+ break;
+ case KIND_EXPENSE:
+ min = counter.getMaxCheckedExpenseId();
+ break;
+ case KIND_REPORT:
+ min = counter.getMaxCheckedReportId();
+ break;
+ default:
+ throw new RuntimeException("kind = " + kind);
+ }
+ long mmin = min == null ? 0L : min.longValue();
+ long mmax = mmin + 1000;
+ mmin = Math.max(1L, mmin);
+
+ String query = "select count(o) from " + kindName + " o where id
= "
+ + mmin + " and id < " + mmax;
+ Number count = (Number) em.createQuery(query).getSingleResult();
+ long value = count.longValue();
+ if (value == 0) {
+ break;
+ }
+
+ mmin = mmax;
+ min = Long.valueOf(mmin);
+ switch (kind) {
+ case KIND_EMPLOYEE:
+ counter.setMaxCheckedEmployeeId(min);
+ Long emp = counter.getNumEmployees();
+ long totalEmp = (emp == null) ? value : value +
emp.longValue();
+ counter.setNumEmployees(Long.valueOf(totalEmp));
+ break;
+ case KIND_EXPENSE:
+ counter.setMaxCheckedExpenseId(min);
+ Long exp = counter.getNumExpenses();
+ long totalExp = (exp == null) ? value : value +
exp.longValue();
+ counter.setNumExpenses(Long.valueOf(totalExp));
+ break;
+ case KIND_REPORT:
+ counter.setMaxCheckedReportId(min);
+ Long rep = counter.getNumReports();
+ long totalRep = (rep == null) ? value : value +
rep.longValue();
+ counter.setNumReports(Long.valueOf(totalRep));
+ break;
+ default:
+ throw new RuntimeException("kind = " + kind);
+ }
+ }
+
+ em.merge(counter);
+ transaction.commit();
+ transaction = null;
+
+ log.info("Ending at getMaxCheckedEmployeeId() = " +
counter.getMaxCheckedEmployeeId());
+ log.info("Ending at getMaxCheckedExpenseId() = " +
counter.getMaxCheckedExpenseId());
+ log.info("Ending at getMaxCheckedReportId() = " +
counter.getMaxCheckedReportId());
+ log.info("Ending at getNumEmployees() = " +
counter.getNumEmployees());
+ log.info("Ending at getNumExpenses() = " + counter.getNumExpenses());
+ log.info("Ending at getNumReports() = " + counter.getNumReports());
+ } catch (DeadlineExceededException e) {
+ if (transaction != null) {
+ transaction.commit();
+ transaction = null;
+
+ log.info("Ending at getMaxCheckedEmployeeId() = " +
counter.getMaxCheckedEmployeeId());
+ log.info("Ending at getMaxCheckedExpenseId() = " +
counter.getMaxCheckedExpenseId());
+ log.info("Ending at getMaxCheckedReportId() = " +
counter.getMaxCheckedReportId());
+ log.info("Ending at getNumEmployees() = " +
counter.getNumEmployees());
+ log.info("Ending at getNumExpenses() = " +
counter.getNumExpenses());
+ log.info("Ending at getNumReports() = " + counter.getNumReports());
+ }
+ } catch (RuntimeException e) {
+ log.warning("Got exception " + e.getMessage());
+ throw e;
+ } finally {
+ log.warning("Rolling back transaction");
+ if (transaction != null) {
+ transaction.rollback();
+ }
+ transaction = null;
+ em.close();
+ }
+
+ long total;
+ switch (kind) {
+ case KIND_EMPLOYEE:
+ total = counter.getNumEmployees();
+ break;
+ case KIND_EXPENSE:
+ total = counter.getNumExpenses();
+ break;
+ case KIND_REPORT:
+ total = counter.getNumReports();
+ break;
+ default:
+ throw new RuntimeException("kind = " + kind);
+ }
+ log.info("Returning total = " + total);
+ return total;
+ }
+
+ @Id
+ @Column(name = "id")
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private Long maxCheckedEmployeeId;
+ private Long maxCheckedExpenseId;
+ private Long maxCheckedReportId;
+ private Long numEmployees;
+ private Long numExpenses;
+ private Long numReports;
+
+ public Long getId() {
+ return id;
+ }
+
+ public Long getMaxCheckedEmployeeId() {
+ return maxCheckedEmployeeId;
+ }
+
+ public Long getMaxCheckedExpenseId() {
+ return maxCheckedExpenseId;
+ }
+
+ public Long getMaxCheckedReportId() {
+ return maxCheckedReportId;
+ }
+
+ public Long getNumEmployees() {
+ return numEmployees;
+ }
+
+ public Long getNumExpenses() {
+ return numExpenses;
+ }
+
+ public Long getNumReports() {
+ return numReports;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public void setMaxCheckedEmployeeId(Long maxCheckedEmployeeId) {
+ this.maxCheckedEmployeeId = maxCheckedEmployeeId;
+ }
+
+ public void setMaxCheckedExpenseId(Long maxCheckedExpenseId) {
+ this.maxCheckedExpenseId = maxCheckedExpenseId;
+ }
+
+ public void setMaxCheckedReportId(Long maxCheckedReportId) {
+ this.maxCheckedReportId = maxCheckedReportId;
+ }
+
+ public void setNumEmployees(Long numEmployees) {
+ this.numEmployees = numEmployees;
+ }
+
+ public void setNumExpenses(Long numExpenses) {
+ this.numExpenses = numExpenses;
+ }
+
+ public void setNumReports(Long numReports) {
+ this.numReports = numReports;
+ }
+
+ private void clear() {
+ setId(ONE);
+ setNumEmployees(ZERO);
+ setNumExpenses(ZERO);
+ setNumReports(ZERO);
+ setMaxCheckedEmployeeId(ZERO);
+ setMaxCheckedExpenseId(ZERO);
+ setMaxCheckedReportId(ZERO);
+ }
+}
=======================================
--- /branches/2.1/bikeshed/src/META-INF/persistence.xml Wed Apr 28 10:57:16
2010
+++ /branches/2.1/bikeshed/src/META-INF/persistence.xml Fri May 14 13:11:53
2010
@@ -9,6 +9,7 @@
<class>com.google.gwt.sample.expenses.server.domain.Employee</class>
<class>com.google.gwt.sample.expenses.server.domain.Expense</class>
<class>com.google.gwt.sample.expenses.server.domain.Report</class>
+
<class>com.google.gwt.sample.expenses.server.domain.EntityCounter</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="datanucleus.NontransactionalRead"
value="true"/>
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/app/client/NotificationMole.java
Thu May 13 20:18:52 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/app/client/NotificationMole.java
Fri May 14 13:11:53 2010
@@ -45,8 +45,8 @@
}
private class MoleAnimation extends Animation {
- private int startSize;
private int endSize;
+ private int startSize;
@Override
protected void onComplete() {
@@ -77,19 +77,15 @@
private static final Binder BINDER = GWT.create(Binder.class);
- private final MoleAnimation animation = new MoleAnimation();
-
- private int animationDuration;
-
@UiField()
DivElement borderElement;
- @UiField()
- SpanElement notificationText;
-
@UiField
DivElement heightMeasure;
+ @UiField()
+ SpanElement notificationText;
+
int showAttempts = 0;
Timer showTimer = new Timer() {
@@ -101,6 +97,10 @@
}
};
+ private final MoleAnimation animation = new MoleAnimation();
+
+ private int animationDuration;
+
public NotificationMole() {
initWidget(BINDER.createAndBindUi(this));
}
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/mobile/client/MobileScrollPanel.java
Fri May 14 08:28:05 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/mobile/client/MobileScrollPanel.java
Fri May 14 13:11:53 2010
@@ -19,11 +19,11 @@
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.user.client.ui.RequiresResize;
-import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SimplePanel;
/**
- * A panel implementation that behaves like a {...@link ScrollPanel} by
default,
+ * A panel implementation that behaves like a
+ * {...@link com.google.gwt.user.client.ui.ScrollPanel ScrollPanel} by
default,
* but switches to a manual drag-scroll implementation on browsers that
support
* touch events.
*
=======================================
--- /branches/2.1/bikeshed/src/com/google/gwt/mobile/client/Momentum.java
Fri May 14 08:28:05 2010
+++ /branches/2.1/bikeshed/src/com/google/gwt/mobile/client/Momentum.java
Fri May 14 13:11:53 2010
@@ -271,25 +271,25 @@
private double adjustInitialVelocityForDirection(double originalVelocity,
double offset, double min, double max) {
// Convert from pixels/ms to pixels/frame
- double velocity = originalVelocity * MS_PER_FRAME
+ double vel = originalVelocity * MS_PER_FRAME
* INITIAL_VELOCITY_BOOST_FACTOR;
// If the initial velocity is below the minimum threshold, it is
possible
// that we need to bounce back depending on where the element is.
- if (Math.abs(velocity) < MIN_START_VELOCITY) {
+ if (Math.abs(vel) < MIN_START_VELOCITY) {
// If either of these cases are true, then the element is outside of
its
// allowable region and we need to apply a bounce back acceleration
to
// bring it back to rest in its defined area.
if (offset < min) {
- velocity = (min - offset) * POST_BOUNCE_COEFFICIENT;
- velocity = Math.max(velocity, MIN_START_VELOCITY);
+ vel = (min - offset) * POST_BOUNCE_COEFFICIENT;
+ vel = Math.max(vel, MIN_START_VELOCITY);
} else if (offset > max) {
- velocity = (offset - max) * POST_BOUNCE_COEFFICIENT;
- velocity = -Math.max(velocity, MIN_START_VELOCITY);
+ vel = (offset - max) * POST_BOUNCE_COEFFICIENT;
+ vel = -Math.max(vel, MIN_START_VELOCITY);
}
}
- return velocity;
+ return vel;
}
/**
@@ -297,10 +297,10 @@
*/
private void adjustVelocity() {
adjustVelocityComponent(currentOffset.x, minCoord.x, maxCoord.x,
- velocity.x, bouncingX, false /** horizontal */
+ velocity.x, bouncingX, false /* horizontal */
);
adjustVelocityComponent(currentOffset.y, minCoord.y, maxCoord.y,
- velocity.y, bouncingY, true /** vertical */
+ velocity.y, bouncingY, true /* vertical */
);
}
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/mobile/client/TouchHandler.java
Fri May 14 08:42:41 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/mobile/client/TouchHandler.java
Fri May 14 13:11:53 2010
@@ -46,16 +46,31 @@
public class TouchHandler implements EventListener {
/**
- * This would not be safe on all browsers, but none of the WebKit
browsers
- * that actually support touch events have the kinds of memory leak
problems
- * that this would trigger. And they all support event capture.
+ * Delegate to receive drag events.
*/
- private static native void addEventListener(Element elem, String name,
- EventListener listener, boolean capture) /*-{
- elem.addEventListener(name, function(e) {
-
listen...@com.google.gwt.user.client.eventlistener::onBrowserEvent(Lcom/google/gwt/user/client/Event;)(e);
- }, capture);
- }-*/;
+ public interface DragDelegate {
+
+ /**
+ * The object's drag sequence is now complete.
+ *
+ * @param e The touchend event.
+ */
+ void onDragEnd(TouchEvent e);
+
+ /**
+ * The object has been dragged to a new position.
+ *
+ * @param e The touchmove event.
+ */
+ void onDragMove(TouchEvent e);
+
+ /**
+ * The object has started dragging.
+ *
+ * @param e The touchmove event.
+ */
+ void onDragStart(TouchEvent e);
+ }
/**
* Delegate to receive touch events.
@@ -80,31 +95,14 @@
}
/**
- * Delegate to receive drag events.
+ * Whether or not the browser supports touches.
*/
- public interface DragDelegate {
-
- /**
- * The object's drag sequence is now complete.
- *
- * @param e The touchend event.
- */
- void onDragEnd(TouchEvent e);
-
- /**
- * The object has been dragged to a new position.
- *
- * @param e The touchmove event.
- */
- void onDragMove(TouchEvent e);
-
- /**
- * The object has started dragging.
- *
- * @param e The touchmove event.
- */
- void onDragStart(TouchEvent e);
- }
+ private static final boolean SUPPORTS_TOUCHES = supportsTouch();
+
+ /**
+ * Cancel event name.
+ */
+ private static final String CANCEL_EVENT = "touchcancel";
/**
* Threshold in pixels within which to bust clicks.
@@ -112,9 +110,10 @@
private static final int CLICK_BUST_THRESHOLD = 25;
/**
- * Minimum movement of touch required to be considered a drag.
+ * End event name.
*/
- private static final double MIN_TRACKING_FOR_DRAG = 5;
+ private static final String END_EVENT = SUPPORTS_TOUCHES ? "touchend"
+ : "mouseup";
/**
* The number of ms to wait during a drag before updating the reported
start
@@ -123,17 +122,15 @@
private static final double MAX_TRACKING_TIME = 200;
/**
- * The threshold for when to start tracking whether a touch has left the
- * bottom of the browser window. Used to implement a workaround for a
mobile
- * safari bug on the iPhone where a touchend event will never be fired
if the
- * touch goes past the bottom of the window.
+ * Minimum movement of touch required to be considered a drag.
*/
- private static final double TOUCH_END_WORKAROUND_THRESHOLD = 20;
+ private static final double MIN_TRACKING_FOR_DRAG = 5;
/**
- * Whether or not the browser supports touches.
+ * Move event name.
*/
- private static final boolean SUPPORTS_TOUCHES = supportsTouch();
+ private static final String MOVE_EVENT = SUPPORTS_TOUCHES ? "touchmove"
+ : "mousemove";
/**
* Start event name.
@@ -142,21 +139,12 @@
: "mousedown";
/**
- * Move event name.
+ * The threshold for when to start tracking whether a touch has left the
+ * bottom of the browser window. Used to implement a workaround for a
mobile
+ * safari bug on the iPhone where a touchend event will never be fired
if the
+ * touch goes past the bottom of the window.
*/
- private static final String MOVE_EVENT = SUPPORTS_TOUCHES ? "touchmove"
- : "mousemove";
-
- /**
- * End event name.
- */
- private static final String END_EVENT = SUPPORTS_TOUCHES ? "touchend"
- : "mouseup";
-
- /**
- * Cancel event name.
- */
- private static final String CANCEL_EVENT = "touchcancel";
+ private static final double TOUCH_END_WORKAROUND_THRESHOLD = 20;
/**
* Get touch from event. Supports desktop events by returning the event
that
@@ -186,35 +174,34 @@
return android || !!('createTouch' in document);
}-*/;
- private Element element;
- private Timer scrollOffTimer;
-
/**
- * The absolute sum of all touch x/y deltas.
+ * This would not be safe on all browsers, but none of the WebKit
browsers
+ * that actually support touch events have the kinds of memory leak
problems
+ * that this would trigger. And they all support event capture.
*/
- private double totalMoveX, totalMoveY = 0;
-
- private boolean touching, tracking, dragging;
- private TouchEvent lastEvent;
- private Point startTouchPosition;
+ private static native void addEventListener(Element elem, String name,
+ EventListener listener, boolean capture) /*-{
+ elem.addEventListener(name, function(e) {
+
listen...@com.google.gwt.user.client.eventlistener::onBrowserEvent(Lcom/google/gwt/user/client/Event;)(e);
+ }, capture);
+ }-*/;
+
+ private boolean bustNextClick;
+ private DragDelegate dragDelegate;
+
+ private Element element;
/**
- * The coordinate of the most recent relevant touch event. For most drag
- * sequences this will be the same as the startCoordinate. If the touch
- * gesture changes direction significantly or pauses for a while this
- * coordinate will be updated to the coordinate of the last touchmove
event.
+ * Start/end time of the touchstart event.
*/
- private Point recentTouchPosition;
-
+ private double endTime;
/**
* The touch position of the last event before the touchend event.
*/
private Point endTouchPosition;
-
- /**
- * Start/end time of the touchstart event.
- */
- private double endTime;
+ private TouchEvent lastEvent;
+
+ private Point lastTouchPosition;
/**
* The time of the most recent relevant occurence. For most drag
sequences
@@ -224,30 +211,29 @@
*/
private double recentTime;
- private Point lastTouchPosition;
- private DragDelegate dragDelegate;
+ /**
+ * The coordinate of the most recent relevant touch event. For most drag
+ * sequences this will be the same as the startCoordinate. If the touch
+ * gesture changes direction significantly or pauses for a while this
+ * coordinate will be updated to the coordinate of the last touchmove
event.
+ */
+ private Point recentTouchPosition;
+
+ private Timer scrollOffTimer;
+
+ private Point startTouchPosition;
+ /**
+ * The absolute sum of all touch x/y deltas.
+ */
+ private double totalMoveX, totalMoveY = 0;
private TouchDelegate touchDelegate;
- private boolean bustNextClick;
+ private boolean touching, tracking, dragging;
public TouchHandler(Element elem) {
this.element = elem;
this.totalMoveY = 0;
this.totalMoveX = 0;
}
-
- /**
- * Sets the delegate to receive drag events.
- */
- public void setDragDelegate(DragDelegate dragDelegate) {
- this.dragDelegate = dragDelegate;
- }
-
- /**
- * Sets the delegate to receive touch events.
- */
- public void setTouchDelegate(TouchDelegate touchDelegate) {
- this.touchDelegate = touchDelegate;
- }
/**
* Start listenting for events.
@@ -308,6 +294,20 @@
}
}
}
+
+ /**
+ * Sets the delegate to receive drag events.
+ */
+ public void setDragDelegate(DragDelegate dragDelegate) {
+ this.dragDelegate = dragDelegate;
+ }
+
+ /**
+ * Sets the delegate to receive touch events.
+ */
+ public void setTouchDelegate(TouchDelegate touchDelegate) {
+ this.touchDelegate = touchDelegate;
+ }
/**
* Begin tracking the touchable element, it is eligible for dragging.
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/requestfactory/shared/RequestEvent.java
Thu May 13 12:50:46 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/requestfactory/shared/RequestEvent.java
Fri May 14 13:11:53 2010
@@ -29,14 +29,17 @@
void onRequestEvent(RequestEvent requestEvent);
}
+ /**
+ * The request state.
+ */
public enum State {
SENT, RECEIVED
}
- private final State state;
-
public static final Type<Handler> TYPE = new Type<Handler>();
+ private final State state;
+
public RequestEvent(State state) {
this.state = state;
}
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/DataGenerationService.java
Wed May 12 11:38:12 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/DataGenerationService.java
Fri May 14 13:11:53 2010
@@ -26,6 +26,12 @@
@RemoteServiceRelativePath("dataGeneration")
public interface DataGenerationService extends RemoteService {
+ long countEmployees();
+
+ long countExpenses();
+
+ long countReports();
+
/**
* Delete the entire datastore.
*/
@@ -40,4 +46,6 @@
* @return the number of Employees, Reports, and Expenses.
*/
List<Integer> getCounts();
-}
+
+ void resetCounters();
+}
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/DataGenerationServiceAsync.java
Wed May 12 11:38:12 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/DataGenerationServiceAsync.java
Fri May 14 13:11:53 2010
@@ -23,7 +23,11 @@
* Async counterpart of {...@link DataGenerationService}.
*/
public interface DataGenerationServiceAsync {
+ void countEmployees(AsyncCallback<Long> callback);
+ void countExpenses(AsyncCallback<Long> callback);
+ void countReports(AsyncCallback<Long> callback);
void delete(AsyncCallback<Void> callback);
void generate(int millis, AsyncCallback<Void> callback);
void getCounts(AsyncCallback<List<Integer>> callback);
-}
+ void resetCounters(AsyncCallback<Void> callback);
+}
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/LoadExpensesDB.java
Thu May 13 09:13:58 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/LoadExpensesDB.java
Fri May 14 13:11:53 2010
@@ -21,6 +21,7 @@
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
@@ -32,15 +33,25 @@
*/
public class LoadExpensesDB implements EntryPoint {
+ private TextBox amountTextBox;
+
+ private Button countEmployeesButton;
+ private Label countEmployeesLabel;
+ private Button countExpensesButton;
+ private Label countExpensesLabel;
+ private Button countReportsButton;
+ private Label countReportsLabel;
private final DataGenerationServiceAsync dataService =
GWT.create(DataGenerationService.class);
- private Label statusLabel;
+ private Button deleteButton;
+ private Button generateButton;
+
private Label numEmployeesLabel;
- private Label numReportsLabel;
private Label numExpensesLabel;
- private Button generateButton;
- private Button deleteButton;
- private TextBox amountTextBox;
+ private Label numReportsLabel;
+ private Button resetCountsButton;
+ private Label resetCountsLabel;
+ private Label statusLabel;
public void onModuleLoad() {
statusLabel = new Label("");
@@ -52,6 +63,18 @@
deleteButton = new Button("Delete everything");
amountTextBox = new TextBox();
amountTextBox.setText("20000");
+
+ countEmployeesButton = new Button("Count Employees");
+ countEmployeesLabel = new Label("-- Employees");
+
+ countExpensesButton = new Button("Count Expenses");
+ countExpensesLabel = new Label("-- Expenses");
+
+ countReportsButton = new Button("Count Reports");
+ countReportsLabel = new Label("-- Reports");
+
+ resetCountsButton = new Button("Reset Counts");
+ resetCountsLabel = new Label("");
generateButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
@@ -66,8 +89,57 @@
deleteData();
}
});
+
+ resetCountsButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ resetCountsButton.setEnabled(false);
+ resetCounts();
+ }
+ });
+
+ countEmployeesButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ countEmployeesButton.setEnabled(false);
+ countEmployees();
+ }
+ });
+
+ countExpensesButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ countExpensesButton.setEnabled(false);
+ countExpenses();
+ }
+ });
+
+ countReportsButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ countReportsButton.setEnabled(false);
+ countReports();
+ }
+ });
RootPanel root = RootPanel.get();
+
+ root.add(resetCountsButton);
+ root.add(resetCountsLabel);
+
+ root.add(new HTML("<br><br>"));
+
+ root.add(countEmployeesButton);
+ root.add(countEmployeesLabel);
+
+ root.add(new HTML("<br><br>"));
+
+ root.add(countExpensesButton);
+ root.add(countExpensesLabel);
+
+ root.add(new HTML("<br><br>"));
+
+ root.add(countReportsButton);
+ root.add(countReportsLabel);
+
+ root.add(new HTML("<br><br>"));
+
root.add(generateButton);
root.add(amountTextBox);
root.add(statusLabel);
@@ -76,12 +148,57 @@
root.add(numExpensesLabel);
// This button deletes a random chunk from the data store -- be
careful!
-// root.add(new HTML("<br><br><br><br><br><br><br><br><br>"));
-// root.add(deleteButton);
+ // root.add(new HTML("<br><br><br><br><br><br><br><br><br>"));
+ // root.add(deleteButton);
updateCounts();
}
+ private void countEmployees() {
+ countEmployeesLabel.setText("Counting...");
+ dataService.countEmployees(new AsyncCallback<Long>() {
+ public void onFailure(Throwable caught) {
+ countEmployeesButton.setEnabled(true);
+ countEmployeesLabel.setText("Failed");
+ }
+
+ public void onSuccess(Long result) {
+ countEmployeesButton.setEnabled(true);
+ countEmployeesLabel.setText("" + result);
+ }
+ });
+ }
+
+ private void countExpenses() {
+ countExpensesLabel.setText("Counting...");
+ dataService.countExpenses(new AsyncCallback<Long>() {
+ public void onFailure(Throwable caught) {
+ countExpensesButton.setEnabled(true);
+ countExpensesLabel.setText("Failed");
+ }
+
+ public void onSuccess(Long result) {
+ countExpensesButton.setEnabled(true);
+ countExpensesLabel.setText("" + result);
+ }
+ });
+ }
+
+ private void countReports() {
+ countReportsLabel.setText("Counting...");
+ dataService.countReports(new AsyncCallback<Long>() {
+ public void onFailure(Throwable caught) {
+ countReportsButton.setEnabled(true);
+ countReportsLabel.setText("Failed");
+ }
+
+ public void onSuccess(Long result) {
+ countReportsButton.setEnabled(true);
+ countReportsLabel.setText("" + result);
+ }
+ });
+ }
+
private void deleteData() {
dataService.delete(new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
@@ -97,22 +214,6 @@
}
});
}
-
- private void updateCounts() {
- dataService.getCounts(new AsyncCallback<List<Integer>>() {
- public void onFailure(Throwable caught) {
- numEmployeesLabel.setText("? Employees");
- numReportsLabel.setText("? Reports");
- numExpensesLabel.setText("? Expenses");
- }
-
- public void onSuccess(List<Integer> result) {
- numEmployeesLabel.setText("" + result.get(0) + " Employees");
- numReportsLabel.setText("" + result.get(1) + " Reports");
- numExpensesLabel.setText("" + result.get(2) + " Expenses");
- }
- });
- }
private void generateData(int amount) {
dataService.generate(amount, new AsyncCallback<Void>() {
@@ -127,6 +228,37 @@
generateButton.setEnabled(true);
updateCounts();
}
+ });
+ }
+
+ private void resetCounts() {
+ resetCountsLabel.setText("Resetting counts...");
+ dataService.resetCounters(new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ resetCountsButton.setEnabled(true);
+ resetCountsLabel.setText("Resetting counts failed");
+ }
+
+ public void onSuccess(Void result) {
+ resetCountsButton.setEnabled(true);
+ resetCountsLabel.setText("Resetting counts succeeded");
+ }
+ });
+ }
+
+ private void updateCounts() {
+ dataService.getCounts(new AsyncCallback<List<Integer>>() {
+ public void onFailure(Throwable caught) {
+ numEmployeesLabel.setText("? Employees");
+ numReportsLabel.setText("? Reports");
+ numExpensesLabel.setText("? Expenses");
+ }
+
+ public void onSuccess(List<Integer> result) {
+ numEmployeesLabel.setText("" + result.get(0) + " Employees");
+ numReportsLabel.setText("" + result.get(1) + " Reports");
+ numExpensesLabel.setText("" + result.get(2) + " Expenses");
+ }
});
}
}
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/Scaffold.java
Thu May 13 20:18:52 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/client/Scaffold.java
Fri May 14 13:11:53 2010
@@ -33,7 +33,6 @@
import com.google.gwt.sample.expenses.gwt.request.ExpensesRequestFactory;
import com.google.gwt.sample.expenses.gwt.ui.ListActivitiesMapper;
import com.google.gwt.sample.expenses.gwt.ui.ScaffoldListPlaceRenderer;
-import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.valuestore.shared.Record;
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/server/DataGenerationServiceImpl.java
Thu May 13 05:43:01 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/server/DataGenerationServiceImpl.java
Fri May 14 13:11:53 2010
@@ -18,6 +18,7 @@
import com.google.apphosting.api.DeadlineExceededException;
import com.google.gwt.sample.expenses.gwt.client.DataGenerationService;
import com.google.gwt.sample.expenses.server.domain.Employee;
+import com.google.gwt.sample.expenses.server.domain.EntityCounter;
import com.google.gwt.sample.expenses.server.domain.Expense;
import com.google.gwt.sample.expenses.server.domain.Report;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
@@ -35,10 +36,22 @@
private static final Logger log =
Logger.getLogger(DataGenerationServiceImpl.class.getName());
- private long endTime;
+// private long endTime;
private ReportGenerator reportGenerator;
+ public long countEmployees() {
+ return EntityCounter.updateEmployeeCount();
+ }
+
+ public long countExpenses() {
+ return EntityCounter.updateExpenseCount();
+ }
+
+ public long countReports() {
+ return EntityCounter.updateReportCount();
+ }
+
public void delete() {
try {
log.info("Expenses before: " + Expense.countExpenses());
@@ -63,11 +76,12 @@
}
}
- public void generate(int millis) {
+ public void generate(final int amount) {
long startTime = System.currentTimeMillis();
- endTime = startTime + millis;
- int startEmployees = (int) Employee.countEmployees();
- int startReports = (int) Report.countReports();
+// endTime = startTime + amount;
+ final int startEmployees = (int) Employee.countEmployees();
+ final int startReports = (int) Report.countReports();
+ final int startExpenses = (int) Expense.countExpenses();
int numEmployees;
synchronized (DataGenerationServiceImpl.class) {
@@ -75,7 +89,9 @@
reportGenerator = new ReportGenerator() {
@Override
public boolean shouldContinue() {
- return System.currentTimeMillis() < endTime;
+ // return System.currentTimeMillis() < endTime;
+ int numReports = getNumReports();
+ return numReports <= amount;
}
@Override
@@ -126,20 +142,23 @@
}
}
- // Choose department and make a manager
- int department = reportGenerator.getDepartment();
- long supervisorId = 1;
-
- while (System.currentTimeMillis() < endTime) {
- reportGenerator.makeEmployee(department, supervisorId, true, 0,
false);
+ reportGenerator.reset();
+
+ // Use same manager for everyone
+ long supervisorId = 1;
+ while (reportGenerator.shouldContinue()) {
+ int department = reportGenerator.getDepartment();
+ reportGenerator.makeEmployee(department, supervisorId);
}
numEmployees = (int) Employee.countEmployees();
int numReports = (int) Report.countReports();
+ int numExpenses = (int) Expense.countExpenses();
int reportsCreated = numReports - startReports;
int employeesCreated = numEmployees - startEmployees;
- log.info("Generated " + employeesCreated + " employees and " +
- reportsCreated + " reports in " +
+ int expensesCreated = numExpenses - startExpenses;
+ log.info("Generated " + employeesCreated + " employees, " +
+ reportsCreated + " reports, and " + expensesCreated + " expenses
in " +
(System.currentTimeMillis() - startTime) + " milliseconds");
}
@@ -152,4 +171,8 @@
return counts;
}
}
-}
+
+ public void resetCounters() {
+ EntityCounter.reset();
+ }
+}
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/server/ReportGenerator.java
Thu May 13 05:43:01 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/server/ReportGenerator.java
Fri May 14 13:11:53 2010
@@ -333,8 +333,6 @@
// 2% of males hyphenate their last names
private static final double MALE_HYPHENATE_PROBABILITY = 0.02;
- private static final double MANAGER_PROBABILITY = 0.1;
-
private static final long MILLIS_PER_DAY = 24L * 60L * 60L * 1000L;
private static final long MILLIS_PER_HOUR = 60L * 60L * 1000L;
@@ -453,8 +451,7 @@
}
}
- public long makeEmployee(int department, long supervisorKey,
- boolean makeExpenses, int level, boolean allowRecursion) {
+ public long makeEmployee(int department, long supervisorKey) {
if (!shouldContinue()) {
return -1;
}
@@ -473,23 +470,17 @@
employee.password = "";
long id = storeEmployee(employee);
- if (makeExpenses) {
- int numExpenseReports = rand.nextInt(96) + 5;
- for (int i = 0; i < numExpenseReports; i++) {
- makeExpenseReport(id, department, supervisorKey);
- }
- }
-
- if (allowRecursion
- && (level < 2 || rand.nextDouble() < MANAGER_PROBABILITY)) {
- int directs = rand.nextInt(6) + 5;
- for (int i = 0; i < directs; i++) {
- makeEmployee(department, id, true, level + 1, true);
- }
+ int numExpenseReports = rand.nextInt(96) + 5;
+ for (int i = 0; i < numExpenseReports; i++) {
+ makeExpenseReport(id, department, supervisorKey);
}
return id;
}
+
+ public void reset() {
+ this.numReports = 0;
+ }
public abstract boolean shouldContinue();
=======================================
---
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/server/ReportGeneratorMain.java
Thu May 13 05:43:01 2010
+++
/branches/2.1/bikeshed/src/com/google/gwt/sample/expenses/gwt/server/ReportGeneratorMain.java
Fri May 14 13:11:53 2010
@@ -25,76 +25,111 @@
*/
public class ReportGeneratorMain {
- protected static final int MAX_REPORTS = 100000;
+ protected static final int MAX_REPORTS = 18000000;
+ protected static final int REPORTS_PER_DIR = 1000000;
protected static final int VERSION = 1;
- /**
- * @param args
- */
- public static void main(String[] args) throws IOException {
- String dir = "io-expenses-" + MAX_REPORTS + dateToString(new Date());
- new File("/home/rice/www/" + dir).mkdir();
- final PrintWriter empWriter = new PrintWriter("/home/rice/www/" + dir
+ "/employees.csv");
- final PrintWriter repWriter = new PrintWriter("/home/rice/www/" + dir
+ "/reports.csv");
- final PrintWriter expWriter = new PrintWriter("/home/rice/www/" + dir
+ "/expenses.csv");
-
- ReportGenerator reportGenerator = new ReportGenerator() {
- long empids = 1L;
- long expids = 1000000000L;
- long repids = 2000000000L;
-
- @Override
- public boolean shouldContinue() {
- return getNumReports() < MAX_REPORTS;
- }
-
- @Override
- public long storeEmployee(EmployeeDTO employee) {
- long id = empids++;
- //
userName,displayName,supervisorKey,VERSION,key,department,password
- empWriter.println(employee.userName + "," + employee.displayName
+ ","
- + employee.supervisorKey + "," + VERSION + "," + id + ","
- + employee.department + ",");
- return id;
- }
-
- @Override
- public long storeExpense(ExpenseDTO expense) {
- long id = expids++;
- //
category,description,reasonDenied,amount,VERSION,reportId,key,created,approval"
- expWriter.println(expense.category + "," + expense.description
+ ",," + expense.amount + ","
- + VERSION + "," + expense.reportId + "," + id + "," +
dateToString(expense.created)
- + ",");
- return id;
- }
-
- @Override
- public long storeReport(ReportDTO report) {
- long id = repids++;
- //
created,notes,VERSION,approvedSupervisorKey,key,reporterKey,purposeLowerCase,purpose,department
- repWriter.println(dateToString(report.created) + ",\"" +
report.notes + "\"," + VERSION + ","
- + report.approvedSupervisorKey + "," + id + "," +
report.reporterKey + ",\""
- + report.purpose.toLowerCase() + "\",\"" + report.purpose
+ "\"," + report.department);
- return id;
- }
- };
-
-
empWriter.println("userName,displayName,supervisorKey,VERSION,key,department,password");
-
repWriter.println("created,notes,VERSION,approvedSupervisorKey,key,reporterKey,purposeLowerCase,purpose,department");
-
expWriter.println("category,description,reasonDenied,amount,VERSION,reportId,key,created,approval");
-
- reportGenerator.init("/home/rice/www/dist.all.last.txt",
- "/home/rice/www/dist.female.first.txt",
- "/home/rice/www/dist.male.first.txt");
-
- reportGenerator.makeEmployee(0, 0, false, 0, false);
- while (reportGenerator.shouldContinue()) {
- reportGenerator.makeEmployee(reportGenerator.getDepartment(), 1,
true, 1, true);
- }
-
- empWriter.close();
- repWriter.close();
- expWriter.close();
+ static int index = 0;
+ static PrintWriter empWriter;
+ static PrintWriter repWriter;
+ static PrintWriter expWriter;
+ static String startDate = null;
+
+ static void makeOutputDir() {
+ try {
+ if (startDate == null) {
+ startDate = dateToString(new Date());
+ }
+ String dir = "/auto/gwt/io-expenses-" + MAX_REPORTS + "-" +
twoDigit(index++) + "-" + startDate;
+ new File(dir).mkdirs();
+ if (empWriter != null) {
+ empWriter.close();
+ }
+ if (repWriter != null) {
+ repWriter.close();
+ }
+ if (expWriter != null) {
+ expWriter.close();
+ }
+ empWriter = new PrintWriter(dir + "/Employee.csv");
+ repWriter = new PrintWriter(dir + "/Report.csv");
+ expWriter = new PrintWriter(dir + "/Expense.csv");
+
empWriter.println("userName,displayName,supervisorKey,VERSION,key,department,password");
+
repWriter.println("created,notes,VERSION,approvedSupervisorKey,key,reporterKey,purposeLowerCase,purpose,department");
+
expWriter.println("category,description,reasonDenied,amount,VERSION,reportId,key,created,approval");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) throws Exception {
+ try {
+ makeOutputDir();
+
+ ReportGenerator reportGenerator = new ReportGenerator() {
+ long allids = 10684381L;
+
+ @Override
+ public boolean shouldContinue() {
+ return getNumReports() < MAX_REPORTS;
+ }
+
+ @Override
+ public long storeEmployee(EmployeeDTO employee) {
+ // Start a new output directory every 1M reports
+ if (getNumReports() >= REPORTS_PER_DIR * index) {
+ ReportGeneratorMain.makeOutputDir();
+ }
+
+ long id = allids++;
+ //
userName,displayName,supervisorKey,VERSION,key,department,password
+ empWriter.println(employee.userName + "," + employee.displayName
+ ","
+ + employee.supervisorKey + "," + VERSION + "," + id + ","
+ + employee.department + ",");
+ return id;
+ }
+
+ @Override
+ public long storeExpense(ExpenseDTO expense) {
+ long id = allids++;
+ //
category,description,reasonDenied,amount,VERSION,reportId,key,created,approval"
+ expWriter.println(expense.category + "," + expense.description
+ ",," + expense.amount + ","
+ + VERSION + "," + expense.reportId + "," + id + "," +
dateToString(expense.created)
+ + ",");
+ return id;
+ }
+
+ @Override
+ public long storeReport(ReportDTO report) {
+ long id = allids++;
+ //
created,notes,VERSION,approvedSupervisorKey,key,reporterKey,purposeLowerCase,purpose,department
+ repWriter.println(dateToString(report.created) + ",\"" +
report.notes + "\"," + VERSION + ","
+ + report.approvedSupervisorKey + "," + id + "," +
report.reporterKey + ",\""
+ + report.purpose.toLowerCase() + "\",\"" + report.purpose
+ "\"," + report.department);
+ return id;
+ }
+ };
+
+ reportGenerator.init("/home/rice/www/dist.all.last.txt",
+ "/home/rice/www/dist.female.first.txt",
+ "/home/rice/www/dist.male.first.txt");
+
+ // Use same manager for everyone
+ long supervisorId = 1;
+ while (reportGenerator.shouldContinue()) {
+ int department = reportGenerator.getDepartment();
+ reportGenerator.makeEmployee(department, supervisorId);
+ }
+
+ empWriter.close();
+ repWriter.close();
+ expWriter.close();
+ } catch (Exception e) {
+ throw e;
+ }
}
@SuppressWarnings("deprecation")
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors