[google-web-toolkit] r9374 committed - (Issue 5564) RF has bad handling of SC_UNAUTHORIZED...

1 view
Skip to first unread message

codesite...@google.com

unread,
Dec 8, 2010, 1:43:18 AM12/8/10
to gwt...@gmail.com
Revision: 9374
Author: rj...@google.com
Date: Tue Dec 7 22:33:06 2010
Log: (Issue 5564) RF has bad handling of SC_UNAUTHORIZED

API breaks:

* The RequestEvent; UserInformation and related proxies, requests and
services;
AuthenticationFailureHandler and LoginWidget were hacky work arounds for the
lack of value objects and a service layer, and have been deleted. For the
same
reason, DefaultRequestTransport no longer takes an EventBus constructor
argument.

* TransportReceiver#onTransportFailure(ServerFailure) replaces
TransportReceiver#onTransportFailure(String), to give custom transports
useful
error reporting.

* ServerFailure now has a boolean isFatal() method (usually true), which
Request#onFailure checks before throwing a RuntimeException?

The Expenses sample has been extended to show how to handle user
authentication
in the wake of these changes. It's easier now, and more flexible.

http://code.google.com/p/google-web-toolkit/issues/detail?id=5564

Review at http://gwt-code-reviews.appspot.com/1194801

http://code.google.com/p/google-web-toolkit/source/detail?r=9374

Added:

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/add.png

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/refresh.png
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/GaeRequest.gwt.xml

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/GaeAuthRequestTransport.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/GaeAuthenticationFailureEvent.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/LoginWidget.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/LoginWidget.ui.xml

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/ReloadOnAuthenticationFailure.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/server

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/server/GaeAuthFilter.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/server/UserServiceLocator.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/server/UserServiceWrapper.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/shared

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/shared/GaeUser.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/shared/GaeUserServiceRequest.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/shared/MakesGaeRequests.java

/trunk/user/test/com/google/gwt/requestfactory/shared/InstanceServiceRequestByName.java
Deleted:

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/server/domain/GaeUserInformation.java
/trunk/user/src/com/google/gwt/requestfactory/server/UserInformation.java

/trunk/user/src/com/google/gwt/requestfactory/server/UserInformationSimpleImpl.java
/trunk/user/src/com/google/gwt/requestfactory/shared/RequestEvent.java

/trunk/user/src/com/google/gwt/requestfactory/shared/UserInformationProxy.java

/trunk/user/src/com/google/gwt/requestfactory/shared/UserInformationRequest.java

/trunk/user/src/com/google/gwt/requestfactory/ui/client/AuthenticationFailureHandler.java
/trunk/user/src/com/google/gwt/requestfactory/ui/client/LoginWidget.java
/trunk/user/src/com/google/gwt/requestfactory/ui/client/LoginWidget.ui.xml
Modified:

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/ExpensesCommon.gwt.xml

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseReportList.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesApp.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobileShell.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobileShell.ui.xml

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesShell.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesShell.ui.xml

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileReportEntry.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ioc/ExpensesFactory.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/EmployeeProxy.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/EmployeeRequest.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpenseProxy.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpenseRequest.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpensesEntityTypesProcessor.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpensesRequestFactory.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ReportProxy.java

/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ReportRequest.java
/trunk/samples/expenses/src/main/webapp/WEB-INF/web.xml
/trunk/tools/api-checker/config/gwt21_22userApi.conf

/trunk/user/src/com/google/gwt/requestfactory/client/DefaultRequestTransport.java

/trunk/user/src/com/google/gwt/requestfactory/client/impl/AbstractClientRequestFactory.java

/trunk/user/src/com/google/gwt/requestfactory/server/DefaultExceptionHandler.java

/trunk/user/src/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidator.java

/trunk/user/src/com/google/gwt/requestfactory/server/RequestFactoryServlet.java

/trunk/user/src/com/google/gwt/requestfactory/server/SimpleRequestProcessor.java

/trunk/user/src/com/google/gwt/requestfactory/server/testing/InProcessRequestTransport.java
/trunk/user/src/com/google/gwt/requestfactory/shared/Receiver.java
/trunk/user/src/com/google/gwt/requestfactory/shared/RequestTransport.java
/trunk/user/src/com/google/gwt/requestfactory/shared/ServerFailure.java

/trunk/user/src/com/google/gwt/requestfactory/shared/impl/AbstractRequestContext.java

/trunk/user/src/com/google/gwt/requestfactory/shared/messages/ServerFailureMessage.java

/trunk/user/test/com/google/gwt/requestfactory/client/RequestFactoryTest.java

/trunk/user/test/com/google/gwt/requestfactory/client/RequestFactoryUnicodeEscapingTest.java

/trunk/user/test/com/google/gwt/requestfactory/server/RequestFactoryExceptionHandlerServlet.java

/trunk/user/test/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidatorTest.java

/trunk/user/test/com/google/gwt/requestfactory/shared/BasicRequestFactory.java

/trunk/user/test/com/google/gwt/requestfactory/shared/SimpleRequestFactory.java

=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/add.png
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,10 @@
+‰PNG
+
+
+IHDR
+
+ rëä| tEXtSoftware Adobe
ImageReadyqÉe< @IDATxÚbdÀ ô<ÛÿÃØ—¶W2¢Ë31 ¹&FdO Bçý tA}¯ 8ûâ¶
+L› ± S±€A
+O ®ª
+9*ÀÀ
+ IEND®B`‚
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/refresh.png
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,11 @@
+‰PNG
+
+
+IHDR H-Ñ tEXtSoftware Adobe
ImageReadyqÉe< ˆIDATxÚbd@ zží @* ˆ PÁ
^xi{å ¨ºùŒHšú T ~ Òø ˆ Ñ5ñrs0ø»ê2 ëÊ2ð ÙûOÜfظû2Ãç¯?PL`„:o?ˆ£®$ÎÐW øIFB`
+ { jºÿ§/? ½ gð#kf æi~ýö ئîJÿk@MÞŒŒŒ ?`êß-öóן(d ™€šl@ 'íŸòÒBèšÀ ®
l#Œ!%ο ] t”ùIˆ
+ñ0àÔøèÙû«Ø‚ÑÓA« HuâÔxåÖsml ®8€MœÉÉR
+̸÷è Ð?
+¸" (' ÄðxfÜuøúá’¶
+à bce¾öë÷_o`
+A ¦Í þü ©» Ä Œÿÿÿwèžµwÿ’
+§!N`düôïÿ ”xdddHüÿŸ $¯«.õeI œ. È @Í @) ¤ ¨‰ šŠàÎ j ·êò<.€BŸ !ù¿ÿÌ¥G K7žaØwü Šÿ@ |
]t@4(­& 5~ 0 èí–9–¾ 1 IEND®B`‚
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/GaeRequest.gwt.xml
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit
0.0.999//EN" "http://google-web-toolkit.googlecode.com/svn/tags/0.0.999/distro-source/core/src/gwt-module.dtd">
+<module>
+ <inherits name='com.google.gwt.requestfactory.RequestFactory'/>
+
+ <source path='client'/>
+ <source path='shared'/>
+</module>
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/GaeAuthRequestTransport.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,72 @@
+/*
+ * 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.gaerequest.client;
+
+import com.google.gwt.event.shared.EventBus;
+import com.google.gwt.http.client.Request;
+import com.google.gwt.http.client.RequestCallback;
+import com.google.gwt.http.client.Response;
+import com.google.gwt.requestfactory.client.DefaultRequestTransport;
+import com.google.gwt.requestfactory.shared.ServerFailure;
+
+/**
+ * Extends DefaultRequestTransport to handle the authentication failures
+ * reported by {@link
com.google.gwt.sample.gaerequest.server.GaeAuthFilter}
+ */
+public class GaeAuthRequestTransport extends DefaultRequestTransport {
+ private final EventBus eventBus;
+
+ public GaeAuthRequestTransport(EventBus eventBus) {
+ this.eventBus = eventBus;
+ }
+
+ @Override
+ protected RequestCallback createRequestCallback(
+ final TransportReceiver receiver) {
+ final RequestCallback superCallback =
super.createRequestCallback(receiver);
+
+ return new RequestCallback() {
+ public void onResponseReceived(Request request, Response response) {
+ /*
+ * The GaeAuthFailure filter responds with
Response.SC_UNAUTHORIZED and
+ * adds a "login" url header if the user is not logged in. When we
+ * receive that combo, post an event so that the app can handle
things
+ * as it sees fit.
+ */
+
+ if (Response.SC_UNAUTHORIZED == response.getStatusCode()) {
+ String loginUrl = response.getHeader("login");
+ if (loginUrl != null) {
+ /*
+ * Hand the receiver a non-fatal callback, so that
+ * com.google.gwt.requestfactory.shared.Receiver will not post
a
+ * runtime exception.
+ */
+ receiver.onTransportFailure(new ServerFailure(
+ "Unauthenticated user", null, null, false /* not fatal
*/));
+ eventBus.fireEvent(new
GaeAuthenticationFailureEvent(loginUrl));
+ return;
+ }
+ }
+ superCallback.onResponseReceived(request, response);
+ }
+
+ public void onError(Request request, Throwable exception) {
+ superCallback.onError(request, exception);
+ }
+ };
+ }
+}
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/GaeAuthenticationFailureEvent.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,89 @@
+/*
+ * 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.gaerequest.client;
+
+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;
+
+/**
+ * An event posted when an authentication failure is detected.
+ */
+public class GaeAuthenticationFailureEvent extends
GwtEvent<GaeAuthenticationFailureEvent.Handler> {
+
+ /**
+ * Implemented by handlers of this type of event.
+ */
+ public interface Handler extends EventHandler {
+ /**
+ * Called when a {@link GaeAuthenticationFailureEvent} is fired.
+ *
+ * @param requestEvent a {@link GaeAuthenticationFailureEvent} instance
+ */
+ void onAuthFailure(GaeAuthenticationFailureEvent requestEvent);
+ }
+
+ private static final Type<Handler> TYPE = new Type<Handler>();
+
+ /**
+ * Register a {@link GaeAuthenticationFailureEvent.Handler} on an {@link
EventBus}.
+ *
+ * @param eventBus the {@link EventBus}
+ * @param handler a {@link GaeAuthenticationFailureEvent.Handler}
+ * @return a {@link HandlerRegistration} instance
+ */
+ public static HandlerRegistration register(EventBus eventBus,
+ GaeAuthenticationFailureEvent.Handler handler) {
+ return eventBus.addHandler(TYPE, handler);
+ }
+
+ /**
+ * Will only be non-null if this is an event of type {@link
State#RECEIVED},
+ * and the RPC was successful.
+ */
+ private final String loginUrl;
+
+ /**
+ * Constructs a new @{link RequestEvent}.
+ *
+ * @param state a {@link State} instance
+ * @param response a {@link Response} instance
+ */
+ public GaeAuthenticationFailureEvent(String loginUrl) {
+ this.loginUrl = loginUrl;
+ }
+
+ @Override
+ public GwtEvent.Type<Handler> getAssociatedType() {
+ return TYPE;
+ }
+
+ /**
+ * Returns the URL the user can visit to reauthenticate.
+ *
+ * @return a {@link Response} instance
+ */
+ public String getLoginUrl() {
+ return loginUrl;
+ }
+
+ @Override
+ protected void dispatch(Handler handler) {
+ handler.onAuthFailure(this);
+ }
+}
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/LoginWidget.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,95 @@
+/*
+ * 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.gaerequest.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.SpanElement;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.requestfactory.shared.Receiver;
+import com.google.gwt.sample.gaerequest.shared.GaeUser;
+import com.google.gwt.sample.gaerequest.shared.GaeUserServiceRequest;
+import com.google.gwt.sample.gaerequest.shared.MakesGaeRequests;
+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.client.Window.Location;
+import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * A simple widget which displays info about the user and a logout link.
In real
+ * life you'd probably blow this up into MVP parts.
+ * <p>
+ * On the other hand, it's pleasant that this widget is completely self
+ * contained, taking care of its own RPC needs when awoken by being
attached to
+ * the dom. Hopefully that's not too magical.
+ */
+public class LoginWidget extends Composite {
+ interface Binder extends UiBinder<Widget, LoginWidget> {
+ }
+
+ private static final Binder BINDER = GWT.create(Binder.class);
+
+ private final MakesGaeRequests requests;
+
+ @UiField
+ SpanElement name;
+ @UiField
+ Anchor logoutLink;
+
+ public LoginWidget(MakesGaeRequests requests) {
+ this.requests = requests;
+ initWidget(BINDER.createAndBindUi(this));
+ }
+
+ @Override
+ protected void onLoad() {
+ GaeUserServiceRequest request = requests.userServiceRequest();
+
+ request.createLogoutURL(Location.getHref()).to(new Receiver<String>() {
+ public void onSuccess(String response) {
+ setLogoutUrl(response);
+ }
+ });
+ request.getCurrentUser().to(new Receiver<GaeUser>() {
+ @Override
+ public void onSuccess(GaeUser response) {
+ setUserName(response.getNickname());
+ }
+ });
+ request.fire();
+ }
+
+ public void setUserName(String userName) {
+ name.setInnerText(userName);
+ }
+
+ public void setLogoutUrl(String url) {
+ logoutLink.setHref(url);
+ }
+
+ /**
+ * Squelch clicks of the logout link if no href has been set.
+ */
+ @UiHandler("logoutLink")
+ void handleClick(ClickEvent e) {
+ if ("".equals(logoutLink.getHref())) {
+ e.stopPropagation();
+ }
+ }
+}
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/LoginWidget.ui.xml
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,17 @@
+<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
+ xmlns:g='urn:import:com.google.gwt.user.client.ui'>
+ <ui:style>
+ .link {
+ /* make it look like text */
+ color: inherit;
+ text-decoration: inherit;
+ }
+ </ui:style>
+
+ <g:HTMLPanel>
+ <div>
+ <span ui:field="name">Not logged in</span> |
+ <g:Anchor ui:field="logoutLink" addStyleNames="{style.link}">Sign
out</g:Anchor>
+ </div>
+ </g:HTMLPanel>
+</ui:UiBinder>
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/client/ReloadOnAuthenticationFailure.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,36 @@
+/*
+ * 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.gaerequest.client;
+
+import com.google.gwt.event.shared.EventBus;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Window.Location;
+
+/**
+ * A minimal auth failure handler which takes the user a login page.
+ */
+public class ReloadOnAuthenticationFailure implements
+ GaeAuthenticationFailureEvent.Handler {
+
+ public HandlerRegistration register(EventBus eventBus) {
+ return GaeAuthenticationFailureEvent.register(eventBus, this);
+ }
+
+ public void onAuthFailure(GaeAuthenticationFailureEvent requestEvent) {
+ Location.replace(requestEvent.getLoginUrl());
+ }
+}
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/server/GaeAuthFilter.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,57 @@
+/*
+ * 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.gaerequest.server;
+
+import com.google.appengine.api.users.UserService;
+import com.google.appengine.api.users.UserServiceFactory;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * A servlet filter that handles basic GAE user authentication.
+ */
+public class GaeAuthFilter implements Filter {
+
+ public void destroy() {
+ }
+
+ public void doFilter(ServletRequest servletRequest, ServletResponse
servletResponse,
+ FilterChain filterChain) throws IOException, ServletException {
+ UserService userService = UserServiceFactory.getUserService();
+ HttpServletRequest request = (HttpServletRequest) servletRequest;
+ HttpServletResponse response = (HttpServletResponse) servletResponse;
+
+ if (!userService.isUserLoggedIn()) {
+ response.setHeader("login",
userService.createLoginURL(request.getRequestURI()));
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ return;
+ }
+
+ filterChain.doFilter(request, response);
+ }
+
+ public void init(FilterConfig config) {
+ }
+}
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/server/UserServiceLocator.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,44 @@
+/*
+ * 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.gaerequest.server;
+
+import com.google.appengine.api.users.User;
+import com.google.appengine.api.users.UserService;
+import com.google.appengine.api.users.UserServiceFactory;
+import com.google.gwt.requestfactory.shared.ServiceLocator;
+
+/**
+ * Gives a RequestFactory system access to the Google AppEngine
UserService.
+ */
+public class UserServiceLocator implements ServiceLocator {
+ public UserServiceWrapper getInstance(Class<?> clazz) {
+ final UserService service = UserServiceFactory.getUserService();
+ return new UserServiceWrapper() {
+
+ public String createLoginURL(String destinationURL) {
+ return service.createLoginURL(destinationURL);
+ }
+
+ public String createLogoutURL(String destinationURL) {
+ return service.createLogoutURL(destinationURL);
+ }
+
+ public User getCurrentUser() {
+ return service.getCurrentUser();
+ }
+ };
+ }
+}
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/server/UserServiceWrapper.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,32 @@
+/*
+ * 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.gaerequest.server;
+
+import com.google.appengine.api.users.User;
+
+/**
+ * Service object that reduces the visible api of
+ * {@link com.google.appengine.api.users.UserService}. Needed to work
around a
+ * limitation of RequestFactory, which cannot yet handle overloaded service
+ * methods.
+ */
+public interface UserServiceWrapper {
+ public String createLoginURL(String destinationURL);
+
+ public String createLogoutURL(String destinationURL);
+
+ public User getCurrentUser();
+}
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/shared/GaeUser.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,28 @@
+/*
+ * 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.gaerequest.shared;
+
+import com.google.gwt.requestfactory.shared.ProxyForName;
+import com.google.gwt.requestfactory.shared.ValueProxy;
+
+/**
+ * Client visible proxy of Google AppEngine User class.
+ */
+@ProxyForName("com.google.appengine.api.users.User")
+public interface GaeUser extends ValueProxy {
+ String getNickname();
+ String getEmail();
+}
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/shared/GaeUserServiceRequest.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,33 @@
+/*
+ * 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.gaerequest.shared;
+
+import com.google.gwt.requestfactory.shared.Request;
+import com.google.gwt.requestfactory.shared.RequestContext;
+import com.google.gwt.requestfactory.shared.ServiceName;
+
+/**
+ * Makes requests of the Google AppEngine UserService.
+ */
+@ServiceName(value
= "com.google.gwt.sample.gaerequest.server.UserServiceWrapper",
+ locator = "com.google.gwt.sample.gaerequest.server.UserServiceLocator")
+public interface GaeUserServiceRequest extends RequestContext {
+ public Request<String> createLoginURL(String destinationURL);
+
+ public Request<String> createLogoutURL(String destinationURL);
+
+ public Request<GaeUser> getCurrentUser();
+}
=======================================
--- /dev/null
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/gaerequest/shared/MakesGaeRequests.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,28 @@
+/*
+ * 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.gaerequest.shared;
+
+/**
+ * Implemented by {@link
com.google.gwt.requestfactory.shared.RequestFactory}s
+ * that vend AppEngine requests.
+ */
+public interface MakesGaeRequests {
+
+ /**
+ * Return a request selector.
+ */
+ GaeUserServiceRequest userServiceRequest();
+}
=======================================
--- /dev/null
+++
/trunk/user/test/com/google/gwt/requestfactory/shared/InstanceServiceRequestByName.java
Tue Dec 7 22:33:06 2010
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+/**
+ * Used to test the ServiceLocator extension hook.
+ */
+@ServiceName(value
= "com.google.gwt.requestfactory.server.InstanceService",
+ locator
= "com.google.gwt.requestfactory.server.InstanceServiceLocator")
+public interface InstanceServiceRequestByName extends RequestContext {
+ Request<Integer> add(int value);
+}
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/server/domain/GaeUserInformation.java
Wed Aug 18 18:29:03 2010
+++ /dev/null
@@ -1,90 +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.server.domain;
-
-import com.google.appengine.api.users.User;
-import com.google.appengine.api.users.UserService;
-import com.google.appengine.api.users.UserServiceFactory;
-import com.google.gwt.requestfactory.server.UserInformation;
-
-/**
- * A user information class that uses the Google App Engine authentication
- * framework.
- */
-public class GaeUserInformation extends UserInformation {
- private static UserService userService =
UserServiceFactory.getUserService();
-
- public static GaeUserInformation getCurrentUserInformation(String
redirectUrl) {
- return new GaeUserInformation(redirectUrl);
- }
-
- public GaeUserInformation(String redirectUrl) {
- super(redirectUrl);
- }
-
- @Override
- public String getEmail() {
- User user = userService.getCurrentUser();
- if (user == null) {
- return "";
- }
- return user.getEmail();
- }
-
- @Override
- public Long getId() {
- User user = userService.getCurrentUser();
- if (user == null) {
- return 0L;
- }
- return new Long(user.hashCode());
- }
-
- @Override
- public String getLoginUrl() {
- return userService.createLoginURL(redirectUrl);
- }
-
- @Override
- public String getLogoutUrl() {
- return userService.createLogoutURL(redirectUrl);
- }
-
- @Override
- public String getName() {
- User user = userService.getCurrentUser();
- if (user == null) {
- return "";
- }
- return user.getNickname();
- }
-
- @Override
- public boolean isUserLoggedIn() {
- return userService.isUserLoggedIn();
- }
-
- /**
- * Does nothing since in GAE authentication, the unique ID is provided by
- * the user service and is based on a hash in the User object.
- */
- @Override
- public void setId(Long id) {
- // Do nothing
- }
-
-}
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/server/UserInformation.java
Thu Nov 18 20:07:43 2010
+++ /dev/null
@@ -1,177 +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.server;
-
-/**
- * A base class for providing authentication related information about the
user.
- * Services that want real authentication should subclass this class with a
- * matching constructor, and set their class name via
- * {@link #setUserInformationImplClass(String)}.
- */
-public abstract class UserInformation {
-
- /**
- * Reset by {@link #getCurrentUserInformation}, which is called by
- * {@link RequestFactoryServlet#doPost} at the start of each request, so
- * shouldn't leak between re-used threads.
- */
- private static final ThreadLocal<UserInformation> currentUser = new
ThreadLocal<UserInformation>();
-
- private static String userInformationImplClass = "";
-
- /**
- * Instance finder method required by RequestFactory. Returns the last
- * UserInformation established for this thread by a call to
- * getCurrentUserInformation, or null if non has been set.
- *
- * @param id ignored, required by RequestFactoryServlet
- */
- public static UserInformation findUserInformation(Long id) {
- return currentUser.get();
- }
-
- /**
- * Called by {@link RequestFactoryServlet#doPost} at the start of each
request
- * received. Establishes the current user information for this request,
and
- * notes a redirect url to be provided back to the client if the user's
bona
- * fides cannot be established. All succeeding calls to
- * {@link #findUserInformation(Long)} made from the same thread will
return
- * the same UserInfo instance.
- * <p>
- * If {@link #setUserInformationImplClass(String)} has been called with a
- * class name, that class is used to gather the information by calling a
- * (String) constructor. If the impl class name is "", or if the class
cannont
- * be instantiated, dummy user info is returned.
- *
- * @param redirectUrl the redirect URL as a String
- * @return a {@link UserInformation} instance
- */
- public static UserInformation getCurrentUserInformation(String
redirectUrl) {
- currentUser.remove();
- if (!"".equals(userInformationImplClass)) {
- try {
- currentUser.set((UserInformation) Class.forName(
-
userInformationImplClass).getConstructor(String.class).newInstance(
- redirectUrl));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- if (currentUser.get() == null) {
- currentUser.set(new UserInformationSimpleImpl(redirectUrl));
- }
- return currentUser.get();
- }
-
- /**
- * Sets the implementation class to be used to gather user information in
- * {@link #getCurrentUserInformation(String)}.
- *
- * @param clazz a class name
- */
- public static void setUserInformationImplClass(String clazz) {
- userInformationImplClass = clazz;
- }
-
- /**
- * The redirect URL as a String.
- */
- protected String redirectUrl = "";
- private Integer version = 0;
-
- /**
- * Constructs a new {@link UserInformation} instance.
- *
- * @param redirectUrl the redirect URL as a String
- */
- public UserInformation(String redirectUrl) {
- if (redirectUrl != null) {
- this.redirectUrl = redirectUrl;
- }
- }
-
- /**
- * Returns the user's email address.
- *
- * @return the user's email address as a String
- */
- public abstract String getEmail();
-
- /**
- * Returns the user's id.
- *
- * @return the user's id as a Long
- * @see #setId(Long)
- */
- public abstract Long getId();
-
- /**
- * Returns the user's login URL.
- *
- * @return the user's login URL as a String
- */
- public abstract String getLoginUrl();
-
- /**
- * Returns the user's logout URL.
- *
- * @return the user's logout URL as a String
- */
- public abstract String getLogoutUrl();
-
- /**
- * Returns the user's name.
- *
- * @return the user's name as a String
- */
- public abstract String getName();
-
- /**
- * Returns the version of this instance.
- *
- * @return an Integer version number
- * @see #setVersion(Integer)
- */
- public Integer getVersion() {
- return this.version;
- }
-
- /**
- * Returns whether the user is logged in.
- *
- * @return {@code true} if the user is logged in
- */
- public abstract boolean isUserLoggedIn();
-
- /**
- * Sets the id for this user.
- *
- * @param id a String id
- * @see #getId()
- */
- public abstract void setId(Long id);
-
- /**
- * Sets the version of this instance.
- *
- * @param version an Integer version number
- * @see #getVersion()
- */
- public void setVersion(Integer version) {
- this.version = version;
- }
-}
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/server/UserInformationSimpleImpl.java
Fri Nov 5 04:25:19 2010
+++ /dev/null
@@ -1,69 +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.server;
-
-/**
- * This implementation treats the user as constantly signed in, and
without any
- * information.
- */
-public class UserInformationSimpleImpl extends UserInformation {
-
- private Long id = 0L;
-
- /**
- * Constructs an UserInformationSimpleImpl object.
- *
- * @param redirectUrl the redirect URL as a String
- */
- public UserInformationSimpleImpl(String redirectUrl) {
- super(redirectUrl);
- }
-
- @Override
- public String getEmail() {
- return "Dummy Email";
- }
-
- @Override
- public Long getId() {
- return this.id;
- }
-
- @Override
- public String getLoginUrl() {
- return "";
- }
-
- @Override
- public String getLogoutUrl() {
- return "";
- }
-
- @Override
- public String getName() {
- return "Dummy User";
- }
-
- @Override
- public boolean isUserLoggedIn() {
- return true;
- }
-
- @Override
- public void setId(Long id) {
- this.id = id;
- }
-}
=======================================
--- /trunk/user/src/com/google/gwt/requestfactory/shared/RequestEvent.java
Thu Oct 14 18:28:29 2010
+++ /dev/null
@@ -1,108 +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.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;
-
-/**
- * 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 {
- /**
- * Called when a {@link RequestEvent} is fired.
- *
- * @param requestEvent a {@link RequestEvent} instance
- */
- void onRequestEvent(RequestEvent requestEvent);
- }
-
- /**
- * The request state.
- */
- public enum State {
- SENT, RECEIVED
- }
-
- private static final Type<Handler> TYPE = new Type<Handler>();
-
- /**
- * Register a {@link RequestEvent.Handler} on an {@link EventBus}.
- *
- * @param eventBus the {@link EventBus}
- * @param handler a {@link RequestEvent.Handler}
- * @return a {@link HandlerRegistration} instance
- */
- 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 {@link
State#RECEIVED},
- * and the RPC was successful.
- */
- private final Response response;
-
- /**
- * Constructs a new @{link RequestEvent}.
- *
- * @param state a {@link State} instance
- * @param response a {@link Response} instance
- */
- public RequestEvent(State state, Response response) {
- this.state = state;
- this.response = response;
- }
-
- @Override
- public GwtEvent.Type<Handler> getAssociatedType() {
- return TYPE;
- }
-
- /**
- * Returns the {@link Response} associated with this event.
- *
- * @return a {@link Response} instance
- */
- public Response getResponse() {
- return response;
- }
-
- /**
- * Returns the {@link State} associated with this event.
- *
- * @return a {@link State} instance
- */
- public State getState() {
- return state;
- }
-
- @Override
- protected void dispatch(Handler handler) {
- handler.onRequestEvent(this);
- }
-}
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/shared/UserInformationProxy.java
Thu Oct 14 18:28:29 2010
+++ /dev/null
@@ -1,53 +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.requestfactory.server.UserInformation;
-
-/**
- * "API Generated" DTO interface based on {@link UserInformation}.
- */
-@ProxyFor(UserInformation.class)
-public interface UserInformationProxy extends EntityProxy {
- /**
- * Returns the user's email address.
- *
- * @return the user's email address as a String
- */
- String getEmail();
-
- /**
- * Returns the user's login url.
- *
- * @return the user's login url as a String
- */
- String getLoginUrl();
-
- /**
- * Returns the user's logout url.
- *
- * @return the user's logout url as a String
- */
- String getLogoutUrl();
-
- /**
- * Returns the user's name.
- *
- * @return the user's name as a String
- */
- String getName();
-}
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/shared/UserInformationRequest.java
Thu Oct 14 18:28:29 2010
+++ /dev/null
@@ -1,35 +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.requestfactory.server.UserInformation;
-
-/**
- * "API Generated" request selector interface implemented by objects that
give
- * client access to the methods of {@link UserInformation}.
- */
-@Service(UserInformation.class)
-public interface UserInformationRequest extends RequestContext {
-
- /**
- * Returns the current user information given a redirect URL.
- *
- * @param redirectUrl the redirect UR as a String
- * @return an instance of {@link Request}&lt;{@link
UserInformationProxy}&gt;
- */
- Request<UserInformationProxy> getCurrentUserInformation(String
redirectUrl);
-}
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/ui/client/AuthenticationFailureHandler.java
Tue Oct 5 17:59:14 2010
+++ /dev/null
@@ -1,58 +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.ui.client;
-
-import com.google.gwt.http.client.Response;
-import com.google.gwt.requestfactory.shared.RequestEvent;
-import com.google.gwt.requestfactory.shared.RequestEvent.State;
-import com.google.gwt.user.client.Window.Location;
-
-/**
- * A request event handler which listens to every request and reacts if
there
- * is an authentication problem. Note that the server side code is
responsible
- * for making sure that no sensitive information is returned in case of
- * authentication issues. This handler is just responsible for making such
- * failures user friendly.
- */
-public class AuthenticationFailureHandler implements RequestEvent.Handler {
- private String lastSeenUser = null;
-
- public void onRequestEvent(RequestEvent requestEvent) {
- if (requestEvent.getState() == State.RECEIVED) {
- Response response = requestEvent.getResponse();
- if (response == null) {
- // We should only get to this state if the RPC failed, in which
- // case we went through the RequestCallback.onError() code path
- // already and we don't need to do any additional error handling
- // here, but we don't want to throw further exceptions.
- return;
- }
- if (Response.SC_UNAUTHORIZED == response.getStatusCode()) {
- String loginUrl = response.getHeader("login");
- Location.replace(loginUrl);
- }
- String newUser = response.getHeader("userId");
- if (lastSeenUser == null) {
- lastSeenUser = newUser;
- } else if (!lastSeenUser.equals(newUser)) {
- // A new user has logged in, just reload the app and start over
- Location.reload();
- }
- }
- }
-
-}
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/ui/client/LoginWidget.java
Thu Oct 14 18:28:29 2010
+++ /dev/null
@@ -1,60 +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.ui.client;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.SpanElement;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.requestfactory.shared.UserInformationProxy;
-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.client.Window.Location;
-import com.google.gwt.user.client.ui.Composite;
-import com.google.gwt.user.client.ui.Widget;
-
-/**
- * A simple widget which displays info about the user and a logout link.
- */
-public class LoginWidget extends Composite {
- interface Binder extends UiBinder<Widget, LoginWidget> { }
- private static final Binder BINDER = GWT.create(Binder.class);
-
- @UiField SpanElement name;
- String logoutUrl = "";
-
- public LoginWidget() {
- initWidget(BINDER.createAndBindUi(this));
- }
-
- /**
- * Sets the user information using a {@link UserInformationProxy}.
- *
- * @param info a {@link UserInformationProxy} instance
- */
- public void setUserInformation(UserInformationProxy info) {
- name.setInnerText(info.getName());
- logoutUrl = info.getLogoutUrl();
- }
-
- @UiHandler("logoutLink")
- void handleClick(@SuppressWarnings("unused") ClickEvent e) {
- if (logoutUrl != "") {
- Location.replace(logoutUrl);
- }
- }
-}
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/ui/client/LoginWidget.ui.xml
Tue Oct 5 17:59:14 2010
+++ /dev/null
@@ -1,15 +0,0 @@
-<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
- xmlns:g='urn:import:com.google.gwt.user.client.ui'>
- <ui:style>
- .link {
- cursor: pointer;
- }
- </ui:style>
-
- <g:HTMLPanel>
- <div>
- <span ui:field="name">Not logged in</span> |
- <g:InlineLabel ui:field="logoutLink"
addStyleNames="{style.link}">Sign out</g:InlineLabel>
- </div>
- </g:HTMLPanel>
-</ui:UiBinder>
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/ExpensesCommon.gwt.xml
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/ExpensesCommon.gwt.xml
Tue Dec 7 22:33:06 2010
@@ -2,10 +2,10 @@
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit
0.0.999//EN" "http://google-web-toolkit.googlecode.com/svn/tags/0.0.999/distro-source/core/src/gwt-module.dtd">
<module>
<inherits name='com.google.gwt.activity.Activity' />
+ <inherits name='com.google.gwt.mobile.Mobile'/>
<inherits name='com.google.gwt.place.Place' />
<inherits name='com.google.gwt.requestfactory.RequestFactory'/>
- <!-- <inherits
name='com.google.gwt.sample.expenses.client.style.Style'/> -->
- <inherits name='com.google.gwt.mobile.Mobile'/>
+ <inherits name='com.google.gwt.sample.gaerequest.GaeRequest'/>
<inherits name='com.google.gwt.user.cellview.CellView'/>

<source path='client'/>
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseReportList.java
Wed Dec 1 05:40:20 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpenseReportList.java
Tue Dec 7 22:33:06 2010
@@ -347,7 +347,7 @@

public void onProxyChange(EntityProxyChange<ReportProxy> event) {
EntityProxyId<ReportProxy> changedId = event.getProxyId();
- List<ReportProxy> records = table.getDisplayedItems();
+ List<ReportProxy> records = table.getVisibleItems();
int i = 0;
for (ReportProxy record : records) {
if (record != null && changedId.equals(record.stableId())) {
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesApp.java
Sat Oct 16 18:02:46 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesApp.java
Tue Dec 7 22:33:06 2010
@@ -23,17 +23,11 @@
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.requestfactory.shared.EntityProxyId;
-import com.google.gwt.requestfactory.shared.Receiver;
-import com.google.gwt.requestfactory.shared.RequestEvent;
-import com.google.gwt.requestfactory.shared.UserInformationProxy;
-import
com.google.gwt.requestfactory.ui.client.AuthenticationFailureHandler;
-import com.google.gwt.requestfactory.ui.client.LoginWidget;
import com.google.gwt.sample.expenses.client.place.ReportListPlace;
import com.google.gwt.sample.expenses.client.place.ReportPlace;
import com.google.gwt.sample.expenses.shared.EmployeeProxy;
-import com.google.gwt.sample.expenses.shared.ExpensesRequestFactory;
import com.google.gwt.sample.expenses.shared.ReportProxy;
-import com.google.gwt.user.client.Window.Location;
+import
com.google.gwt.sample.gaerequest.client.ReloadOnAuthenticationFailure;
import com.google.gwt.user.client.ui.HasWidgets;

import java.util.logging.Level;
@@ -55,7 +49,6 @@
private final EventBus eventBus;
private final PlaceController placeController;
private final PlaceHistoryHandler placeHistoryHandler;
- private final ExpensesRequestFactory requestFactory;
private final ExpensesShell shell;

private EntityProxyId<EmployeeProxy> lastEmployee;
@@ -63,12 +56,11 @@

public ExpensesApp(ActivityManager activityManager, EventBus eventBus,
PlaceController placeController, PlaceHistoryHandler
placeHistoryHandler,
- ExpensesRequestFactory requestFactory, ExpensesShell shell) {
+ ExpensesShell shell) {
this.activityManager = activityManager;
this.eventBus = eventBus;
this.placeController = placeController;
this.placeHistoryHandler = placeHistoryHandler;
- this.requestFactory = requestFactory;
this.shell = shell;
}

@@ -94,18 +86,7 @@
});

// Check for Authentication failures or mismatches
- RequestEvent.register(eventBus, new AuthenticationFailureHandler());
-
- // Kick off the login widget
- final LoginWidget login = shell.getLoginWidget();
- Receiver<UserInformationProxy> receiver = new
Receiver<UserInformationProxy>() {
- @Override
- public void onSuccess(UserInformationProxy userInformationRecord) {
- login.setUserInformation(userInformationRecord);
- }
- };
- requestFactory.userInformationRequest().getCurrentUserInformation(
- Location.getHref()).fire(receiver);
+ new ReloadOnAuthenticationFailure().register(eventBus);

// Listen for requests from ExpenseTree.
expenseTree.setListener(new ExpenseTree.Listener() {
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobile.java
Tue Dec 7 22:33:06 2010
@@ -20,21 +20,25 @@
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.requestfactory.shared.Receiver;
-import com.google.gwt.requestfactory.shared.RequestEvent;
-import com.google.gwt.requestfactory.shared.UserInformationProxy;
-import
com.google.gwt.requestfactory.ui.client.AuthenticationFailureHandler;
-import com.google.gwt.requestfactory.ui.client.LoginWidget;
import com.google.gwt.sample.expenses.shared.EmployeeProxy;
import com.google.gwt.sample.expenses.shared.ExpensesRequestFactory;
+import com.google.gwt.sample.gaerequest.client.GaeAuthRequestTransport;
+import com.google.gwt.sample.gaerequest.client.LoginWidget;
+import
com.google.gwt.sample.gaerequest.client.ReloadOnAuthenticationFailure;
import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

+import java.util.logging.Level;
+import java.util.logging.Logger;
+
/**
* Entry point for the mobile version of the Expenses app.
+ * <p>
+ * TODO Should be using ExpenseFactory
*/
public class ExpensesMobile implements EntryPoint {
+ private static final Logger log =
Logger.getLogger(ExpensesMobile.class.getName());

/**
* The url parameter that specifies the employee id.
@@ -77,8 +81,7 @@
public void onModuleLoad() {
GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
public void onUncaughtException(Throwable e) {
- Window.alert("Error: " + e.getMessage());
- // placeController.goTo(Place.NOWHERE);
+ log.log(Level.SEVERE, e.getMessage(), e);
}
});

@@ -96,29 +99,18 @@

final EventBus eventBus = new SimpleEventBus();
final ExpensesRequestFactory requestFactory =
GWT.create(ExpensesRequestFactory.class);
- requestFactory.initialize(eventBus);
+ requestFactory.initialize(eventBus, new
GaeAuthRequestTransport(eventBus));

requestFactory.employeeRequest().findEmployee(employeeId).fire(
new Receiver<EmployeeProxy>() {
@Override
public void onSuccess(EmployeeProxy employee) {
final ExpensesMobileShell shell = new
ExpensesMobileShell(eventBus,
- requestFactory, employee);
+ requestFactory, employee, new LoginWidget(requestFactory));
RootPanel.get().add(shell);

// Check for Authentication failures or mismatches
- RequestEvent.register(eventBus, new
AuthenticationFailureHandler());
-
- // Add a login widget to the page
- final LoginWidget login = shell.getLoginWidget();
- Receiver<UserInformationProxy> receiver = new
Receiver<UserInformationProxy>() {
- @Override
- public void onSuccess(UserInformationProxy
userInformationRecord) {
- login.setUserInformation(userInformationRecord);
- }
- };
-
requestFactory.userInformationRequest().getCurrentUserInformation(
- Location.getHref()).fire(receiver);
+ new ReloadOnAuthenticationFailure().register(eventBus);
}
});
}
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobileShell.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobileShell.java
Tue Dec 7 22:33:06 2010
@@ -19,11 +19,11 @@
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.EventBus;
-import com.google.gwt.requestfactory.ui.client.LoginWidget;
import com.google.gwt.sample.expenses.shared.EmployeeProxy;
import com.google.gwt.sample.expenses.shared.ExpenseProxy;
import com.google.gwt.sample.expenses.shared.ExpensesRequestFactory;
import com.google.gwt.sample.expenses.shared.ReportProxy;
+import com.google.gwt.sample.gaerequest.client.LoginWidget;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
@@ -39,13 +39,19 @@
*/
public class ExpensesMobileShell extends Composite {

- interface ShellUiBinder extends UiBinder<Widget, ExpensesMobileShell> { }
+ interface ShellUiBinder extends UiBinder<Widget, ExpensesMobileShell> {
+ }
+
private static ShellUiBinder BINDER = GWT.create(ShellUiBinder.class);

- @UiField SimplePanel container;
- @UiField HTML backButton, addButton, refreshButton, customButton;
- @UiField LoginWidget loginWidget;
- @UiField Element titleSpan;
+ @UiField
+ SimplePanel container;
+ @UiField
+ HTML backButton, addButton, refreshButton, customButton;
+ @UiField(provided = true)
+ final LoginWidget loginWidget;
+ @UiField
+ Element titleSpan;

private MobileReportList reportList;
private MobileExpenseList expenseList;
@@ -59,10 +65,12 @@
private ArrayList<MobilePage> pages = new ArrayList<MobilePage>();

public ExpensesMobileShell(EventBus eventBus,
- ExpensesRequestFactory requestFactory, EmployeeProxy employee) {
+ ExpensesRequestFactory requestFactory, EmployeeProxy employee,
+ LoginWidget loginWidget) {
this.eventBus = eventBus;
this.requestFactory = requestFactory;
this.employee = employee;
+ this.loginWidget = loginWidget;

initWidget(BINDER.createAndBindUi(this));
showReportList();
@@ -74,7 +82,7 @@
public LoginWidget getLoginWidget() {
return loginWidget;
}
-
+
@UiHandler("addButton")
void onAdd(@SuppressWarnings("unused") ClickEvent evt) {
topPage().onAdd();
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobileShell.ui.xml
Tue Oct 5 17:59:14 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesMobileShell.ui.xml
Tue Dec 7 22:33:06 2010
@@ -3,17 +3,37 @@
xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:m='urn:import:com.google.gwt.mobile.client'
xmlns:r='urn:import:com.google.gwt.requestfactory.ui.client'
- xmlns:g='urn:import:com.google.gwt.user.client.ui'>
-
- <ui:style field='mobile' src='mobile.css'/>
-
+ xmlns:g='urn:import:com.google.gwt.user.client.ui'
+ xmlns:a='urn:import:com.google.gwt.sample.gaerequest.client'>
+
+ <ui:image field='add'/>
+ <ui:image field='refresh'/>
+
+ <ui:style field='mobile' src='mobile.css'>
+ @sprite .refresh {
+ gwt-image: "refresh";
+ }
+ @sprite .add {
+ gwt-image: "add";
+ }
+ .button {
+ cursor: pointer;
+ }
+ .backButton {
+ cursor: pointer;
+ }
+ .customButton {
+ cursor: pointer;
+ }
+ </ui:style>
+
<g:HTMLPanel>
- <r:LoginWidget styleName='{mobile.login}' ui:field="loginWidget"/>
+ <a:LoginWidget styleName='{mobile.login}' ui:field="loginWidget"/>
<div class='{mobile.bar}'>
<g:HTML ui:field='backButton'
styleName='{mobile.backButton}'><div>Back</div></g:HTML>
- <g:HTML ui:field='addButton' styleName='{mobile.button}'><img
src='images/add.png'/></g:HTML>
+ <g:HTML ui:field='addButton' addStyleNames='{mobile.button}'><div
class='{mobile.add}'/></g:HTML>
<g:HTML ui:field='customButton' styleName='{mobile.customButton}'/>
- <g:HTML ui:field='refreshButton' styleName='{mobile.button}'><img
src='images/refresh.png'/></g:HTML>
+ <g:HTML ui:field='refreshButton' styleName='{mobile.button}'><div
class='{mobile.refresh}'/></g:HTML>
<div class='{mobile.title}' ui:field='titleSpan'>Expenses</div>
</div>
<g:SimplePanel ui:field='container'/>
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesShell.java
Sat Oct 16 18:02:46 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesShell.java
Tue Dec 7 22:33:06 2010
@@ -16,7 +16,7 @@
package com.google.gwt.sample.expenses.client;

import com.google.gwt.core.client.GWT;
-import com.google.gwt.requestfactory.ui.client.LoginWidget;
+import com.google.gwt.sample.gaerequest.client.LoginWidget;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
@@ -35,21 +35,25 @@

@UiField(provided = true)
final ExpenseReportList expenseList;
-
+
@UiField(provided = true)
final ExpenseReportDetails expenseDetails;

@UiField(provided = true)
final ExpenseTree expenseTree;
-
+
+ @UiField(provided = true)
+ final LoginWidget loginWidget;
+
@UiField SlidingPanel slidingPanel;
- @UiField LoginWidget loginWidget;
@UiField DockLayoutPanel dockLayout;

- public ExpensesShell(ExpenseTree expenseTree, ExpenseReportList
expenseList, ExpenseReportDetails expenseDetails) {
+ public ExpensesShell(ExpenseTree expenseTree, ExpenseReportList
expenseList,
+ ExpenseReportDetails expenseDetails, LoginWidget loginWidget) {
this.expenseTree = expenseTree;
this.expenseList = expenseList;
this.expenseDetails = expenseDetails;
+ this.loginWidget = loginWidget;
initWidget(uiBinder.createAndBindUi(this));
}

@@ -68,7 +72,7 @@
public LoginWidget getLoginWidget() {
return loginWidget;
}
-
+
public HasOneWidget getPanel() {
return slidingPanel;
}
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesShell.ui.xml
Sat Oct 16 18:02:46 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ExpensesShell.ui.xml
Tue Dec 7 22:33:06 2010
@@ -4,7 +4,9 @@
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:m='urn:import:com.google.gwt.mobile.client'
xmlns:r='urn:import:com.google.gwt.requestfactory.ui.client'
- xmlns:e='urn:import:com.google.gwt.sample.expenses.client'>
+ xmlns:e='urn:import:com.google.gwt.sample.expenses.client'
+ xmlns:a='urn:import:com.google.gwt.sample.gaerequest.client'>
+

<ui:with field='styles'
type='com.google.gwt.sample.expenses.client.style.Styles' />

@@ -44,7 +46,7 @@
<g:DockLayoutPanel unit='PX'>
<g:north size='96'>
<g:HTMLPanel styleName='{style.title}'>
- <r:LoginWidget styleName='{style.login}' ui:field="loginWidget"/>
+ <a:LoginWidget styleName='{style.login}' ui:field="loginWidget"/>
<table height='100%' cellpadding='8' cellspacing='0'>
<tr>
<td>
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileReportEntry.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/MobileReportEntry.java
Tue Dec 7 22:33:06 2010
@@ -166,9 +166,15 @@

@SuppressWarnings("deprecation")
private void showCreationDate(Date d) {
- // TODO(jgw): Use non-deprecated date methods for this.
- dateYear.setSelectedIndex(d.getYear() - 100);
- dateMonth.setSelectedIndex(d.getMonth());
- dateDay.setSelectedIndex(d.getDate() - 1);
+ if (d != null) {
+ // TODO(jgw): Use non-deprecated date methods for this.
+ dateYear.setSelectedIndex(d.getYear() - 100);
+ dateMonth.setSelectedIndex(d.getMonth());
+ dateDay.setSelectedIndex(d.getDate() - 1);
+ } else {
+ dateYear.setSelectedIndex(0);
+ dateMonth.setSelectedIndex(0);
+ dateDay.setSelectedIndex(0);
+ }
}
}
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ioc/ExpensesFactory.java
Sat Oct 16 18:02:46 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/client/ioc/ExpensesFactory.java
Tue Dec 7 22:33:06 2010
@@ -32,6 +32,8 @@
import com.google.gwt.sample.expenses.client.place.ReportListPlace;
import com.google.gwt.sample.expenses.client.place.ReportPlace;
import com.google.gwt.sample.expenses.shared.ExpensesRequestFactory;
+import com.google.gwt.sample.gaerequest.client.GaeAuthRequestTransport;
+import com.google.gwt.sample.gaerequest.client.LoginWidget;

/**
* In charge of instantiation.
@@ -41,6 +43,7 @@
public class ExpensesFactory {

private final EventBus eventBus = new SimpleEventBus();
+ private final GaeAuthRequestTransport requestTransport = new
GaeAuthRequestTransport(eventBus);
private final ExpensesRequestFactory requestFactory =
GWT.create(ExpensesRequestFactory.class);
private final ExpensesPlaceHistoryMapper historyMapper =
GWT.create(ExpensesPlaceHistoryMapper.class);
private final PlaceHistoryHandler placeHistoryHandler;
@@ -49,21 +52,23 @@
private final ExpenseReportList expenseList = new
ExpenseReportList(requestFactory);
private final ExpenseReportDetails expenseDetails = new
ExpenseReportDetails(
requestFactory);
+ private final LoginWidget loginWidget = new LoginWidget(requestFactory);
+
private final ActivityMapper activityMapper = new ExpensesActivityMapper(
expenseDetails, expenseList);
private final ActivityManager activityManager = new ActivityManager(
activityMapper, eventBus);

public ExpensesFactory() {
- requestFactory.initialize(eventBus);
+ requestFactory.initialize(eventBus, requestTransport);
historyMapper.setFactory(this);
placeHistoryHandler = new PlaceHistoryHandler(historyMapper);
}

public ExpensesApp getExpensesApp() {
return new ExpensesApp(activityManager, eventBus, placeController,
- placeHistoryHandler, requestFactory, new ExpensesShell(expenseTree,
- expenseList, expenseDetails));
+ placeHistoryHandler, new ExpensesShell(expenseTree,
+ expenseList, expenseDetails, loginWidget));
}

/**
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/EmployeeProxy.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/EmployeeProxy.java
Tue Dec 7 22:33:06 2010
@@ -20,10 +20,7 @@
import com.google.gwt.requestfactory.shared.ProxyFor;

/**
- * "API Generated" DTO interface based on
- * {@link com.google.gwt.sample.expenses.server.domain.Employee}.
- * <p>
- * IRL this class will be generated by a JPA-savvy tool run before
compilation.
+ * Employee DTO.
*/
@ProxyFor(com.google.gwt.sample.expenses.server.domain.Employee.class)
public interface EmployeeProxy extends EntityProxy {
@@ -31,6 +28,10 @@

String getDisplayName();

+ /*
+ * TODO You shouldn't need to expose Ids like this.
+ * Instead use EntityProxy.stableId() and RequestFactory.find()
+ */
Long getId();

String getPassword();
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/EmployeeRequest.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/EmployeeRequest.java
Tue Dec 7 22:33:06 2010
@@ -24,11 +24,7 @@
import java.util.List;

/**
- * "API Generated" request selector interface implemented by objects that
give
- * client access to the methods of
- * {@link com.google.gwt.sample.expenses.server.domain.Employee}.
- * <p>
- * IRL this class will be generated by a JPA-savvy tool run before
compilation.
+ * Builds requests for the Employee service.
*/
@Service(Employee.class)
public interface EmployeeRequest extends RequestContext {
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpenseProxy.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpenseProxy.java
Tue Dec 7 22:33:06 2010
@@ -22,10 +22,7 @@
import java.util.Date;

/**
- * "API Generated" DTO interface based on
- * {@link com.google.gwt.sample.expenses.server.domain.Expense}.
- * <p>
- * IRL this class will be generated by a JPA-savvy tool run before
compilation.
+ * Expense DTO.
*/
@ProxyFor(com.google.gwt.sample.expenses.server.domain.Expense.class)
public interface ExpenseProxy extends EntityProxy {
@@ -39,6 +36,10 @@

String getDescription();

+ /*
+ * TODO You shouldn't need to expose Ids like this.
+ * Instead use EntityProxy.stableId() and RequestFactory.find()
+ */
Long getId();

String getReasonDenied();
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpenseRequest.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpenseRequest.java
Tue Dec 7 22:33:06 2010
@@ -24,11 +24,7 @@
import java.util.List;

/**
- * "API Generated" request selector interface implemented by objects that
give
- * client access to the methods of
- * {@link com.google.gwt.sample.expenses.server.domain.Expense}.
- * <p>
- * IRL this class will be generated by a JPA-savvy tool run before
compilation.
+ * Builds requests for the ExpenseRequest service.
*/
@Service(Expense.class)
public interface ExpenseRequest extends RequestContext {
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpensesEntityTypesProcessor.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpensesEntityTypesProcessor.java
Tue Dec 7 22:33:06 2010
@@ -22,11 +22,6 @@
import java.util.Set;

/**
- * "API Generated" tool for resolving an arbitray Class to a specific proxy
- * type.
- * <p>
- * IRL this class will be generated by a JPA-savvy tool run before
compilation.
- * <p>
* A helper class for dealing with proxy types. Subclass it and override
the
* various handle methods for type specific handling of proxy objects or
* classes, then call {@link #process(Class)} or {@link #process(Object)}.
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpensesRequestFactory.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ExpensesRequestFactory.java
Tue Dec 7 22:33:06 2010
@@ -16,17 +16,13 @@
package com.google.gwt.sample.expenses.shared;

import com.google.gwt.requestfactory.shared.RequestFactory;
-import com.google.gwt.requestfactory.shared.UserInformationRequest;
+import com.google.gwt.sample.gaerequest.shared.MakesGaeRequests;

/**
- * "API generated" factory interface to build request objects for the
methods of
- * {@link com.google.gwt.sample.expenses.server.domain}. Client code can
- * GWT.create() an instance of this interface to build and fire request
objects.
- * <p>
- * IRL this interface will be generated by a JPA-savvy tool run before
- * compilation.
+ * RequestFactory interface. Instances created via {@link
com.google.gwt.core.client.GWT#create}
+ * can insantiate RPC request objects.
*/
-public interface ExpensesRequestFactory extends RequestFactory {
+public interface ExpensesRequestFactory extends RequestFactory,
MakesGaeRequests {

/**
* @return a request selector
@@ -42,10 +38,4 @@
* @return a request selector
*/
ReportRequest reportRequest();
-
- /**
- * @return a request selector
- */
- UserInformationRequest userInformationRequest();
-
-}
+}
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ReportProxy.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ReportProxy.java
Tue Dec 7 22:33:06 2010
@@ -22,10 +22,7 @@
import java.util.Date;

/**
- * "API Generated" DTO interface based on
- * {@link com.google.gwt.sample.expenses.server.domain.Report}.
- * <p>
- * IRL this class will be generated by a JPA-savvy tool run before
compilation.
+ * Report DTO.
*/
@ProxyFor(com.google.gwt.sample.expenses.server.domain.Report.class)
public interface ReportProxy extends EntityProxy {
@@ -35,6 +32,10 @@

String getDepartment();

+ /*
+ * TODO You shouldn't need to expose Ids like this.
+ * Instead use EntityProxy.stableId() and RequestFactory.find()
+ */
Long getId();

String getNotes();
=======================================
---
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ReportRequest.java
Fri Oct 15 14:10:22 2010
+++
/trunk/samples/expenses/src/main/java/com/google/gwt/sample/expenses/shared/ReportRequest.java
Tue Dec 7 22:33:06 2010
@@ -24,11 +24,7 @@
import java.util.List;

/**
- * "API Generated" request selector interface implemented by objects that
give
- * client access to the methods of
- * {@link com.google.gwt.sample.expenses.server.domain.Report}.
- * <p>
- * IRL this class will be generated by a JPA-savvy tool run before
compilation.
+ * Builds requests for the Report service.
*/
@Service(Report.class)
public interface ReportRequest extends RequestContext {
=======================================
--- /trunk/samples/expenses/src/main/webapp/WEB-INF/web.xml Wed Aug 18
18:29:03 2010
+++ /trunk/samples/expenses/src/main/webapp/WEB-INF/web.xml Tue Dec 7
22:33:06 2010
@@ -4,57 +4,153 @@
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
-
- <!-- Servlets -->
- <servlet>
- <servlet-name>requestFactoryServlet</servlet-name>
-
<servlet-class>com.google.gwt.requestfactory.server.RequestFactoryServlet</servlet-class>
- </servlet>
-
- <servlet>
- <servlet-name>dataGeneration</servlet-name>
-
<servlet-class>com.google.gwt.sample.expenses.server.DataGenerationServiceImpl</servlet-class>
- </servlet>
-
- <!-- Enable remote API on Java (for datastore bulkloader). You also need
- to add appengine-tools-api.jar from the appengine plugin directory to
war/WEB-INF/lib -->
- <servlet>
- <servlet-name>remoteapi</servlet-name>
-
<servlet-class>com.google.apphosting.utils.remoteapi.RemoteApiServlet</servlet-class>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>remoteapi</servlet-name>
- <url-pattern>/remote_api</url-pattern>
- </servlet-mapping>
-
- <servlet-mapping>
- <servlet-name>requestFactoryServlet</servlet-name>
- <url-pattern>/gwtRequest</url-pattern>
- </servlet-mapping>
-
- <servlet-mapping>
- <servlet-name>dataGeneration</servlet-name>
- <url-pattern>/loadexpensesdb/dataGeneration</url-pattern>
- </servlet-mapping>
-
- <!-- AppStats -->
- <!-- <servlet> <servlet-name>appstats</servlet-name>
<servlet-class>com.google.appengine.tools.appstats.AppstatsServlet</servlet-class>
- <init-param> <param-name>requireAdminAuthentication</param-name>
<param-value>false</param-value>
- </init-param> </servlet> <servlet-mapping>
<servlet-name>appstats</servlet-name>
- <url-pattern>/appstats/*</url-pattern> </servlet-mapping> <filter>
<filter-name>appstats</filter-name>
-
<filter-class>com.google.appengine.tools.appstats.AppstatsFilter</filter-class>
- <init-param> <param-name>logMessage</param-name> <param-value>Appstats
available:
- /appstats/details?time={ID}</param-value> </init-param> <init-param>
<param-name>basePath</param-name>
- <param-value>/appstats/</param-value> </init-param> </filter>
<filter-mapping>
- <filter-name>appstats</filter-name> <url-pattern>/*</url-pattern>
</filter-mapping> -->
-
- <!-- <security-constraint> <web-resource-collection>
<web-resource-name>remoteapi</web-resource-name>
- <url-pattern>/remote_api</url-pattern> </web-resource-collection>
<auth-constraint>
- <role-name>admin</role-name> </auth-constraint> </security-constraint>
-->
-
- <!-- Require login. -->
- <!-- <security-constraint> <web-resource-collection>
<web-resource-name>Access</web-resource-name>
- <url-pattern>/*</url-pattern> </web-resource-collection>
<auth-constraint>
- <role-name>admin</role-name> </auth-constraint> </security-constraint>
-->
+ <security-constraint>
+ <display-name>
+ Redirect to the login page if needed before showing
+ any html pages
+ </display-name>
+ <web-resource-collection>
+ <url-pattern>*.html</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>*</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <!--
+
+ Expenses.html and ExpensesMobile.html rely upon RequestFactoryServlet
+
+ -->
+
+ <servlet>
+ <servlet-name>requestFactoryServlet</servlet-name>
+
<servlet-class>com.google.gwt.requestfactory.server.RequestFactoryServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>requestFactoryServlet</servlet-name>
+ <url-pattern>/gwtRequest</url-pattern>
+ </servlet-mapping>
+
+ <filter>
+ <filter-name>GaeAuthFilter</filter-name>
+
<filter-class>com.google.gwt.sample.gaerequest.server.GaeAuthFilter</filter-class>
+ <description>
+ This filter demonstrates making GAE authentication
+ services visible to a RequestFactory client.
+ </description>
+ </filter>
+ <filter-mapping>
+ <filter-name>GaeAuthFilter</filter-name>
+ <url-pattern>/gwtRequest/*</url-pattern>
+ </filter-mapping>
+
+
+ <!--
+
+ LoadExpensesDB.html uses GWT RPC to implement its DataGenerationService
+
+ -->
+
+ <servlet>
+ <servlet-name>dataGeneration</servlet-name>
+
<servlet-class>com.google.gwt.sample.expenses.server.DataGenerationServiceImpl</servlet-class>
+ <description>
+ GWT RPC service used by LoadExpensesDB.html
+ </description>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>dataGeneration</servlet-name>
+ <url-pattern>/loadexpensesdb/dataGeneration</url-pattern>
+ </servlet-mapping>
+
+ <!--<security-constraint>
+ <display-name>
+ Require admin access for LoadExpensesDB.html and its servlet
+ </display-name>
+ <web-resource-collection>
+ <url-pattern>/loadexpensesdb/*</url-pattern>
+ <url-pattern>/LoadExpensesDB.html</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>admin</role-name>
+ </auth-constraint>
+ </security-constraint>-->
+
+
+ <!--
+
+ AppStats
+
+ Uncomment to use GAE's App Stats
+ http://code.google.com/appengine/docs/java/tools/appstats.html
+
+ Visualize the stats with Speed Tracer
+ http://code.google.com/webtoolkit/speedtracer/server-side-tracing.html
+
+ -->
+
+ <!--<servlet>
+ <servlet-name>appstats</servlet-name>
+
<servlet-class>com.google.appengine.tools.appstats.AppstatsServlet</servlet-class>
+ <init-param>
+ <param-name>requireAdminAuthentication</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>appstats</servlet-name>
+ <url-pattern>/appstats/*</url-pattern>
+ </servlet-mapping>
+ <filter>
+ <filter-name>appstats</filter-name>
+
<filter-class>com.google.appengine.tools.appstats.AppstatsFilter</filter-class>
+ <init-param>
+ <param-name>logMessage</param-name>
+ <param-value>Appstats available:
+ /appstats/details?time={ID}</param-value>
+ </init-param>
+ <init-param>
+ <param-name>basePath</param-name>
+ <param-value>/appstats/</param-value>
+ </init-param>
+ </filter>
+ <filter-mapping>
+ <filter-name>appstats</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>-->
+
+
+ <!--
+
+ GAE Remote API provides a bulk uploader and other goodies
+
+ -->
+
+ <!-- <servlet>
+ <servlet-name>remoteapi</servlet-name>
+
<servlet-class>com.google.apphosting.utils.remoteapi.RemoteApiServlet</servlet-class>
+ <description>
+ Provides access to the GAE datastore bulkloader, requires
appengine-tools-api.jar
+ (which is commented out in pom.xml, qv)
+ </description>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>remoteapi</servlet-name>
+ <url-pattern>/remote_api</url-pattern>
+ </servlet-mapping>
+
+ <security-constraint>
+ <display-name>
+ Require admin access for remoteapi
+ </display-name>
+ <web-resource-collection>
+ <url-pattern>/remote_api</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>admin</role-name>
+ </auth-constraint>
+ </security-constraint>-->
+
</web-app>
=======================================
--- /trunk/tools/api-checker/config/gwt21_22userApi.conf Thu Dec 2
08:13:42 2010
+++ /trunk/tools/api-checker/config/gwt21_22userApi.conf Tue Dec 7
22:33:06 2010
@@ -41,6 +41,9 @@
:com/google/gwt/resources/rg/**\
:com/google/gwt/requestfactory/client/impl/FindRequest.java\
:com/google/gwt/requestfactory/shared/impl/MessageFactoryHolder.java\
+:com/google/gwt/requestfactory/shared/UserInformationProxy.java\
+:com/google/gwt/requestfactory/shared/UserInformationRequest.java\
+:com/google/gwt/requestfactory/ui/client/LoginWidget.java\
:com/google/gwt/rpc/client/impl/ClientWriterFactory.java\
:com/google/gwt/rpc/client/impl/EscapeUtil.java\
:com/google/gwt/soyc/**\
@@ -110,6 +113,14 @@
# when adding to the white-list, include comments as to why the addition is
# being made.

+# RequestFactory tweaks in 2.1.1
+com.google.gwt.requestfactory.client.DefaultRequestTransport::DefaultRequestTransport(Lcom/google/gwt/event/shared/EventBus;)
MISSING
+com.google.gwt.requestfactory.shared.RequestEvent MISSING
+com.google.gwt.requestfactory.shared.RequestEvent.Handler MISSING
+com.google.gwt.requestfactory.shared.RequestEvent.State MISSING
+com.google.gwt.requestfactory.shared.ServerFailure::ServerFailure(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)
MISSING
+com.google.gwt.requestfactory.ui.client.AuthenticationFailureHandler
MISSING
+
# AutoBean packages have been moved since 2.1
com.google.gwt.editor.client.AutoBean MISSING
com.google.gwt.editor.client.AutoBeanFactory MISSING
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/client/DefaultRequestTransport.java
Thu Oct 14 18:28:29 2010
+++
/trunk/user/src/com/google/gwt/requestfactory/client/DefaultRequestTransport.java
Tue Dec 7 22:33:06 2010
@@ -18,16 +18,14 @@
import static
com.google.gwt.user.client.rpc.RpcRequestBuilder.STRONG_NAME_HEADER;

import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.shared.EventBus;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
-import com.google.gwt.requestfactory.shared.RequestEvent;
import com.google.gwt.requestfactory.shared.RequestFactory;
import com.google.gwt.requestfactory.shared.RequestTransport;
-import com.google.gwt.requestfactory.shared.RequestEvent.State;
+import com.google.gwt.requestfactory.shared.ServerFailure;
import com.google.gwt.user.client.Window.Location;

import java.util.logging.Level;
@@ -38,6 +36,7 @@
* {@link RequestBuilder}.
*/
public class DefaultRequestTransport implements RequestTransport {
+ private static final String SERVER_ERROR = "Server Error";

/**
* The default URL for a DefaultRequestTransport is
@@ -52,29 +51,13 @@
* happen every time a request is made from the server should be logged
to
* this logger.
*/
- private static Logger wireLogger =
Logger.getLogger("WireActivityLogger");
- private static final String SERVER_ERROR = "Server Error";
-
- private final EventBus eventBus;
+ private static final Logger wireLogger =
Logger.getLogger("WireActivityLogger");
+
private String requestUrl = GWT.getHostPageBaseURL() + URL;
-
- /**
- * Construct a DefaultRequestTransport.
- *
- * @param eventBus the same EventBus passed into
- * {@link RequestFactory#initialize(EventBus)
- * RequestFactory.initialize}.
- */
- public DefaultRequestTransport(EventBus eventBus) {
- if (eventBus == null) {
- throw new IllegalArgumentException("eventBus must not be null");
- }
- this.eventBus = eventBus;
- }

/**
* Returns the current URL used by this transport.
- *
+ *
* @return the URL as a String
* @see #setRequestUrl(String)
*/
@@ -92,7 +75,6 @@
try {
wireLogger.finest("Sending fire request");
builder.send();
- postRequestEvent(State.SENT, null);
} catch (RequestException e) {
wireLogger.log(Level.SEVERE, SERVER_ERROR + " (" + e.getMessage()
+ ")",
e);
@@ -111,7 +93,7 @@

/**
* Override to change the headers sent in the HTTP request.
- *
+ *
* @param builder a {@link RequestBuilder} instance
*/
protected void configureRequestBuilder(RequestBuilder builder) {
@@ -134,7 +116,7 @@
* Creates a RequestCallback that maps the HTTP response onto the
* {@link
com.google.gwt.requestfactory.shared.RequestTransport.TransportReceiver
* TransportReceiver} interface.
- *
+ *
* @param receiver a {@link TransportReceiver}
* @return a {@link RequestCallback} instance
*/
@@ -143,40 +125,22 @@
return new RequestCallback() {

public void onError(Request request, Throwable exception) {
- postRequestEvent(State.RECEIVED, null);
wireLogger.log(Level.SEVERE, SERVER_ERROR, exception);
- receiver.onTransportFailure(exception.getMessage());
+ receiver.onTransportFailure(new
ServerFailure(exception.getMessage()));
}

public void onResponseReceived(Request request, Response response) {
wireLogger.finest("Response received");
- try {
- if (200 == response.getStatusCode()) {
- String text = response.getText();
- receiver.onTransportSuccess(text);
- } else if (Response.SC_UNAUTHORIZED == response.getStatusCode())
{
- String message = "Need to log in";
- wireLogger.finest(message);
- receiver.onTransportFailure(message);
- } else if (response.getStatusCode() > 0) {
- /*
- * During the redirection for logging in, we get a response
with no
- * status code, but it's not an error, so we only log errors
with
- * bad status codes here.
- */
- String message = SERVER_ERROR + " " + response.getStatusCode()
- + " " + response.getText();
- wireLogger.severe(message);
- receiver.onTransportFailure(message);
- }
- } finally {
- postRequestEvent(State.RECEIVED, response);
+ if (Response.SC_OK == response.getStatusCode()) {
+ String text = response.getText();
+ receiver.onTransportSuccess(text);
+ } else {
+ String message = SERVER_ERROR + " " + response.getStatusCode()
+ " "
+ + response.getText();
+ wireLogger.severe(message);
+ receiver.onTransportFailure(new ServerFailure(message));
}
}
};
}
-
- private void postRequestEvent(State received, Response response) {
- eventBus.fireEvent(new RequestEvent(received, response));
- }
-}
+}
=======================================
---
/trunk/user/src/com/google/gwt/requestfactory/client/impl/AbstractClientRequestFactory.java
Fri Nov 5 04:25:19 2010
+++
/trunk/user/src/com/google/gwt/requestfactory/client/impl/AbstractClientRequestFactory.java
Tue Dec 7 22:33:06 2010
@@ -26,6 +26,6 @@
AbstractRequestFactory {
@Override
public void initialize(EventBus eventBus) {
- initialize(eventBus, new DefaultRequestTransport(eventBus));
+ initialize(eventBus, new DefaultRequestTransport());
}
}
=======================================
***Additional files exist in this changeset.***
Reply all
Reply to author
Forward
0 new messages