From dc8bc6119c1bd019600559db552ec26b4db2ec54 Mon Sep 17 00:00:00 2001 From: John Ahlroos Date: Fri, 31 Aug 2012 14:22:26 +0300 Subject: More state getter removal --- .../loginform/LoginFormUIInLoginHandler.java | 104 ++++++++++----------- 1 file changed, 52 insertions(+), 52 deletions(-) (limited to 'uitest/src') diff --git a/uitest/src/com/vaadin/tests/components/loginform/LoginFormUIInLoginHandler.java b/uitest/src/com/vaadin/tests/components/loginform/LoginFormUIInLoginHandler.java index b3ebb02751..58656cb7bf 100755 --- a/uitest/src/com/vaadin/tests/components/loginform/LoginFormUIInLoginHandler.java +++ b/uitest/src/com/vaadin/tests/components/loginform/LoginFormUIInLoginHandler.java @@ -1,52 +1,52 @@ -package com.vaadin.tests.components.loginform; - -import com.vaadin.tests.components.TestBase; -import com.vaadin.ui.Label; -import com.vaadin.ui.LoginForm; -import com.vaadin.ui.LoginForm.LoginEvent; -import com.vaadin.ui.LoginForm.LoginListener; -import com.vaadin.ui.UI; - -public class LoginFormUIInLoginHandler extends TestBase { - - @Override - protected void setup() { - LoginForm lf = new LoginForm(); - lf.addListener(new LoginListener() { - - @Override - public void onLogin(LoginEvent event) { - UI r1 = UI.getCurrent(); - if (r1 != null) { - addComponent(new Label("UI.getCurrent().data: " - + r1.getData())); - } else { - addComponent(new Label("UI.getCurrent() is null")); - } - UI r2 = ((LoginForm) event.getSource()).getUI(); - if (r2 != null) { - addComponent(new Label("event.getSource().data: " - + r2.getData())); - } else { - addComponent(new Label( - "event.getSource().getRoot() is null")); - } - } - }); - addComponent(lf); - getLayout().getUI().setData("This UI"); - } - - @Override - protected String getDescription() { - // TODO Auto-generated method stub - return null; - } - - @Override - protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; - } - -} +package com.vaadin.tests.components.loginform; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Label; +import com.vaadin.ui.LoginForm; +import com.vaadin.ui.LoginForm.LoginEvent; +import com.vaadin.ui.LoginForm.LoginListener; +import com.vaadin.ui.UI; + +public class LoginFormUIInLoginHandler extends TestBase { + + @Override + protected void setup() { + LoginForm lf = new LoginForm(); + lf.addListener(new LoginListener() { + + @Override + public void onLogin(LoginEvent event) { + UI r1 = UI.getCurrent(); + if (r1 != null) { + addComponent(new Label("UI.getCurrent().data: " + + r1.getData())); + } else { + addComponent(new Label("UI.getCurrent() is null")); + } + UI r2 = ((LoginForm) event.getSource()).getUI(); + if (r2 != null) { + addComponent(new Label("event.getSource().data: " + + r2.getData())); + } else { + addComponent(new Label( + "event.getSource().getRoot() is null")); + } + } + }); + addComponent(lf); + getLayout().getUI().setData("This UI"); + } + + @Override + protected String getDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} -- cgit v1.2.3 From 594a21116845ae2aacc8c40fd76ee50b84d1e968 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Fri, 31 Aug 2012 14:27:45 +0300 Subject: Run tests with assertions enabled (#9450) --- .../vaadin/tests/server/TestAssertionsEnabled.java | 33 ++++++++++++++++ .../vaadin/launcher/DevelopmentServerLauncher.java | 14 +++++++ .../com/vaadin/tests/VerifyAssertionsEnabled.html | 26 +++++++++++++ .../com/vaadin/tests/VerifyAssertionsEnabled.java | 45 ++++++++++++++++++++++ uitest/vaadin-server.xml | 1 + 5 files changed, 119 insertions(+) create mode 100644 server/tests/src/com/vaadin/tests/server/TestAssertionsEnabled.java create mode 100644 uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.html create mode 100644 uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.java (limited to 'uitest/src') diff --git a/server/tests/src/com/vaadin/tests/server/TestAssertionsEnabled.java b/server/tests/src/com/vaadin/tests/server/TestAssertionsEnabled.java new file mode 100644 index 0000000000..ee481c61f8 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/TestAssertionsEnabled.java @@ -0,0 +1,33 @@ +/* + * Copyright 2011 Vaadin Ltd. + * + * 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.vaadin.tests.server; + +import junit.framework.TestCase; + +public class TestAssertionsEnabled extends TestCase { + public void testAssertionsEnabled() { + boolean assertFailed = false; + try { + assert false; + } catch (AssertionError e) { + assertFailed = true; + } finally { + assertTrue("Unit tests should be run with assertions enabled", + assertFailed); + } + } +} diff --git a/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java b/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java index 6162820dac..f45aac8173 100644 --- a/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java +++ b/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java @@ -54,6 +54,8 @@ public class DevelopmentServerLauncher { public static void main(String[] args) { System.setProperty("java.awt.headless", "true"); + assertAssertionsEnabled(); + // Pass-through of arguments for Jetty final Map serverArgs = parseArguments(args); @@ -88,6 +90,18 @@ public class DevelopmentServerLauncher { } } + private static void assertAssertionsEnabled() { + try { + assert false; + + throw new RuntimeException("You should run " + + DevelopmentServerLauncher.class.getSimpleName() + + " with assertions enabled. Add -ea as a VM argument."); + } catch (AssertionError e) { + // All is fine + } + } + /** * Run the server with specified arguments. * diff --git a/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.html b/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.html new file mode 100644 index 0000000000..40ac075d53 --- /dev/null +++ b/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.html @@ -0,0 +1,26 @@ + + + + + + +New Test + + + + + + + + + + + + + + + + +
New Test
open/run/com.vaadin.tests.VerifyAssertionsEnabled?restartApplication
assertTextvaadin=runcomvaadintestsVerifyAssertionsEnabled::/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[0]Assertions are enabled
+ + diff --git a/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.java b/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.java new file mode 100644 index 0000000000..d812ea644a --- /dev/null +++ b/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.java @@ -0,0 +1,45 @@ +/* + * Copyright 2011 Vaadin Ltd. + * + * 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.vaadin.tests; + +import com.vaadin.server.WrappedRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; + +public class VerifyAssertionsEnabled extends AbstractTestUI { + + @Override + protected void setup(WrappedRequest request) { + try { + assert false; + addComponent(new Label("Assertions are not enabled")); + } catch (AssertionError e) { + addComponent(new Label("Assertions are enabled")); + } + } + + @Override + protected String getTestDescription() { + return "Tests whether the testing server is run with assertions enabled."; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(9450); + } + +} diff --git a/uitest/vaadin-server.xml b/uitest/vaadin-server.xml index d4d23581ec..5f2aa06303 100644 --- a/uitest/vaadin-server.xml +++ b/uitest/vaadin-server.xml @@ -41,6 +41,7 @@ + -- cgit v1.2.3 From cf9ab5aea84d2be1686c5f46edd9522cd0750baf Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 30 Aug 2012 16:24:12 +0300 Subject: Remove user handling in Application (#9402) --- server/src/com/vaadin/Application.java | 200 --------------------- uitest/src/com/vaadin/tests/UpgradingSample.java | 197 -------------------- .../tests/application/ErrorInUnloadEvent.java | 9 +- 3 files changed, 5 insertions(+), 401 deletions(-) delete mode 100644 uitest/src/com/vaadin/tests/UpgradingSample.java (limited to 'uitest/src') diff --git a/server/src/com/vaadin/Application.java b/server/src/com/vaadin/Application.java index 5f7260e350..fb2691c6d3 100644 --- a/server/src/com/vaadin/Application.java +++ b/server/src/com/vaadin/Application.java @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; -import java.util.EventListener; import java.util.EventObject; import java.util.HashMap; import java.util.HashSet; @@ -429,11 +428,6 @@ public class Application implements Terminal.ErrorListener, Serializable { */ private DeploymentConfiguration configuration; - /** - * The current user or null if no user has logged in. - */ - private Object user; - /** * The application's URL. */ @@ -449,11 +443,6 @@ public class Application implements Terminal.ErrorListener, Serializable { */ private Locale locale; - /** - * List of listeners listening user changes. - */ - private LinkedList userChangeListeners = null; - /** * URL where the user is redirected to on application close, or null if * application is just closed without redirection. @@ -500,59 +489,6 @@ public class Application implements Terminal.ErrorListener, Serializable { private GlobalResourceHandler globalResourceHandler; - /** - * Gets the user of the application. - * - *

- * Vaadin doesn't define of use user object in any way - it only provides - * this getter and setter methods for convenience. The user is any object - * that has been stored to the application with {@link #setUser(Object)}. - *

- * - * @return the User of the application. - */ - public Object getUser() { - return user; - } - - /** - *

- * Sets the user of the application instance. An application instance may - * have a user associated to it. This can be set in login procedure or - * application initialization. - *

- *

- * A component performing the user login procedure can assign the user - * property of the application and make the user object available to other - * components of the application. - *

- *

- * Vaadin doesn't define of use user object in any way - it only provides - * getter and setter methods for convenience. The user reference stored to - * the application can be read with {@link #getUser()}. - *

- * - * @param user - * the new user. - */ - public void setUser(Object user) { - final Object prevUser = this.user; - if (user == prevUser || (user != null && user.equals(prevUser))) { - return; - } - - this.user = user; - if (userChangeListeners != null) { - final Object[] listeners = userChangeListeners.toArray(); - final UserChangeEvent event = new UserChangeEvent(this, user, - prevUser); - for (int i = 0; i < listeners.length; i++) { - ((UserChangeListener) listeners[i]) - .applicationUserChanged(event); - } - } - } - /** * Gets the URL of the application. * @@ -714,142 +650,6 @@ public class Application implements Terminal.ErrorListener, Serializable { this.locale = locale; } - /** - *

- * An event that characterizes a change in the current selection. - *

- * Application user change event sent when the setUser is called to change - * the current user of the application. - * - * @since 3.0 - */ - public class UserChangeEvent extends java.util.EventObject { - - /** - * New user of the application. - */ - private final Object newUser; - - /** - * Previous user of the application. - */ - private final Object prevUser; - - /** - * Constructor for user change event. - * - * @param source - * the application source. - * @param newUser - * the new User. - * @param prevUser - * the previous User. - */ - public UserChangeEvent(Application source, Object newUser, - Object prevUser) { - super(source); - this.newUser = newUser; - this.prevUser = prevUser; - } - - /** - * Gets the new user of the application. - * - * @return the new User. - */ - public Object getNewUser() { - return newUser; - } - - /** - * Gets the previous user of the application. - * - * @return the previous Vaadin user, if user has not changed ever on - * application it returns null - */ - public Object getPreviousUser() { - return prevUser; - } - - /** - * Gets the application where the user change occurred. - * - * @return the Application. - */ - public Application getApplication() { - return (Application) getSource(); - } - } - - /** - * The UserChangeListener interface for listening application - * user changes. - * - * @since 3.0 - */ - public interface UserChangeListener extends EventListener, Serializable { - - /** - * The applicationUserChanged method Invoked when the - * application user has changed. - * - * @param event - * the change event. - */ - public void applicationUserChanged(Application.UserChangeEvent event); - } - - /** - * Adds the user change listener. - * - * This allows one to get notification each time {@link #setUser(Object)} is - * called. - * - * @param listener - * the user change listener to add. - */ - public void addUserChangeListener(UserChangeListener listener) { - if (userChangeListeners == null) { - userChangeListeners = new LinkedList(); - } - userChangeListeners.add(listener); - } - - /** - * @deprecated Since 7.0, replaced by - * {@link #addUserChangeListener(UserChangeListener)} - **/ - @Deprecated - public void addListener(UserChangeListener listener) { - addUserChangeListener(listener); - } - - /** - * Removes the user change listener. - * - * @param listener - * the user change listener to remove. - */ - - public void removeUserChangeListener(UserChangeListener listener) { - if (userChangeListeners == null) { - return; - } - userChangeListeners.remove(listener); - if (userChangeListeners.isEmpty()) { - userChangeListeners = null; - } - } - - /** - * @deprecated Since 7.0, replaced by - * {@link #removeUserChangeListener(UserChangeListener)} - **/ - @Deprecated - public void removeListener(UserChangeListener listener) { - removeUserChangeListener(listener); - } - /** * Window detach event. * diff --git a/uitest/src/com/vaadin/tests/UpgradingSample.java b/uitest/src/com/vaadin/tests/UpgradingSample.java deleted file mode 100644 index 48e2222d7e..0000000000 --- a/uitest/src/com/vaadin/tests/UpgradingSample.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2011 Vaadin Ltd. - * - * 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.vaadin.tests; - -// -// Millstone imports were replaced -// -// import org.millstone.base.Application; -// import org.millstone.base.ui.*; -// import org.millstone.base.data.*; -// -import com.vaadin.Application; -import com.vaadin.data.Property; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.CustomComponent; -import com.vaadin.ui.GridLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.Panel; -import com.vaadin.ui.UI.LegacyWindow; -import com.vaadin.ui.TextField; -import com.vaadin.ui.Tree; -import com.vaadin.ui.VerticalLayout; - -/** - *

- * Example application demonstrating simple user login. This example is from - * MillStone 3.1.1 examples section. Upgrading from 3.1.1 to 4.0.0 was done by - * updating imports, also setTheme("corporate") call was added to application - * init method. - *

- * - * @since 3.1.1 - * @author Vaadin Ltd. - */ -public class UpgradingSample extends Application.LegacyApplication implements - Property.ValueChangeListener { - - /* Menu for navigating inside the application. */ - private final Tree menu = new Tree(); - - /* Contents of the website */ - private final String[][] pages = { - { "Welcome", "Welcome to our website..." }, - { "Products", "Public product information." }, - { "Contact", "Public contact information." }, - { "CRM", "CRM Database requiring login." }, - { "Intranet", "Internal information database." } }; - - /* Application layout */ - private final GridLayout layout = new GridLayout(2, 1); - - /* Initialize the application */ - @Override - public void init() { - - // Create the main window of the application - final LegacyWindow main = new LegacyWindow("Login example", layout); - setMainWindow(main); - - // Add menu and loginbox to the application - final VerticalLayout l = new VerticalLayout(); - layout.addComponent(l, 0, 0); - l.addComponent(menu); - l.addComponent(new LoginBox()); - - // Setup menu - menu.setStyleName("menu"); - menu.addListener(this); - menu.setImmediate(true); - addToMenu(new String[] { "Welcome", "Products", "Contact" }); - } - - // Overriding usetUser method is a simple way of updating application - // privileges when the user is changed - @Override - public void setUser(Object user) { - super.setUser(user); - if (user != null) { - addToMenu(new String[] { "CRM", "Intranet" }); - } - } - - public void addToMenu(String[] items) { - for (int i = 0; i < items.length; i++) { - menu.addItem(items[i]); - menu.setChildrenAllowed(items[i], false); - } - if (menu.getValue() == null) { - menu.setValue(items[0]); - } - } - - // Handle menu selection and update visible page - @Override - public void valueChange(Property.ValueChangeEvent event) { - layout.removeComponent(1, 0); - final String title = (String) menu.getValue(); - for (int i = 0; i < pages.length; i++) { - if (pages[i][0].equals(title)) { - final Panel p = new Panel(pages[i][0]); - p.addComponent(new Label(pages[i][1])); - p.setStyleName("strong"); - layout.addComponent(p, 1, 0); - } - } - } - - // Simple loginbox component for the application - public class LoginBox extends CustomComponent implements - Application.UserChangeListener { - - // The components this loginbox is composed of - private final TextField loginName = new TextField("Name"); - - private final Button loginButton = new Button("Enter", - new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - login(); - } - }); - - private final Panel loginPanel = new Panel("Login"); - - private final Panel statusPanel = new Panel(); - - private final Button logoutButton = new Button("Logout", - new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - close(); - } - }); - - private final Label statusLabel = new Label(); - - // Initialize login component - public LoginBox() { - - // Initialize the component - loginPanel.addComponent(loginName); - loginPanel.addComponent(loginButton); - loginPanel.setStyleName("strong"); - loginName.setColumns(8); - statusPanel.addComponent(statusLabel); - statusPanel.addComponent(logoutButton); - - // Set the status of the loginbox and show correct - // components - updateStatus(); - - // Listen application user change events - UpgradingSample.this.addListener(this); - } - - // Login into application - public void login() { - final String name = loginName.getValue(); - if (name != null && name.length() > 0) { - setUser(name); - } - loginName.setValue(""); - } - - // Update login status on application user change events - @Override - public void applicationUserChanged(Application.UserChangeEvent event) { - updateStatus(); - } - - // Update login status of the component by exposing correct - // components - private void updateStatus() { - statusLabel.setValue("User: " + getUser()); - if (getUser() != null) { - setCompositionRoot(statusPanel); - } else { - setCompositionRoot(loginPanel); - } - } - } -} diff --git a/uitest/src/com/vaadin/tests/application/ErrorInUnloadEvent.java b/uitest/src/com/vaadin/tests/application/ErrorInUnloadEvent.java index d7e9155ded..1278032f3c 100644 --- a/uitest/src/com/vaadin/tests/application/ErrorInUnloadEvent.java +++ b/uitest/src/com/vaadin/tests/application/ErrorInUnloadEvent.java @@ -10,17 +10,18 @@ import com.vaadin.ui.FormLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.PasswordField; -import com.vaadin.ui.UI.LegacyWindow; import com.vaadin.ui.TextField; +import com.vaadin.ui.UI.LegacyWindow; import com.vaadin.ui.VerticalLayout; public class ErrorInUnloadEvent extends AbstractTestCase { private LegacyWindow mainWindow; + private Object user = null; @Override public void init() { - if (getUser() == null) { + if (user == null) { showLoginWindow(); } else { showMainWindow(); @@ -55,7 +56,7 @@ public class ErrorInUnloadEvent extends AbstractTestCase { String username = userField.getValue(); String password = passwordField.getValue(); - setUser(username); + user = username; showMainWindow(); } }); @@ -84,7 +85,7 @@ public class ErrorInUnloadEvent extends AbstractTestCase { logout.addListener(new ClickListener() { @Override public void buttonClick(final ClickEvent event) { - setUser(null); + user = null; showLoginWindow(); } -- cgit v1.2.3 From 8679f49c5e036d39d34a9fca8a907c4d19df21c9 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Fri, 31 Aug 2012 12:02:51 +0300 Subject: Refactor UI bootstrap (#9443) --- WebContent/VAADIN/vaadinBootstrap.js | 8 +- server/src/com/vaadin/Application.java | 341 +++++++++++---------- .../vaadin/UIRequiresMoreInformationException.java | 37 --- .../com/vaadin/annotations/PreserveOnRefresh.java | 28 ++ server/src/com/vaadin/annotations/Title.java | 38 +++ .../vaadin/server/AbstractApplicationPortlet.java | 9 +- .../server/AbstractCommunicationManager.java | 36 +-- .../vaadin/server/BootstrapFragmentResponse.java | 13 +- server/src/com/vaadin/server/BootstrapHandler.java | 107 ++----- .../com/vaadin/server/BootstrapPageResponse.java | 14 +- .../src/com/vaadin/server/BootstrapResponse.java | 40 +-- .../com/vaadin/server/CommunicationManager.java | 7 - .../src/com/vaadin/server/DefaultUIProvider.java | 3 +- .../vaadin/server/PortletCommunicationManager.java | 7 - server/src/com/vaadin/server/UIProvider.java | 3 +- server/src/com/vaadin/server/WrappedRequest.java | 9 +- server/src/com/vaadin/ui/UI.java | 50 ++- .../server/component/root/CustomUIClassLoader.java | 28 +- .../vaadin/launcher/ApplicationRunnerServlet.java | 4 +- .../tests/application/RefreshStatePreserve.java | 7 +- .../tests/application/ThreadLocalInstances.java | 19 +- .../loginform/LoginFormWithMultipleWindows.java | 13 +- .../vaadin/tests/components/ui/LazyInitUIs.java | 44 ++- .../tests/components/ui/UIsInMultipleTabs.java | 4 +- .../minitutorials/v7a1/CreatingPreserveState.java | 5 +- .../v7a1/DifferentFeaturesForDifferentClients.java | 42 ++- .../vaadincontext/TestAddonContextListener.java | 5 +- 27 files changed, 440 insertions(+), 481 deletions(-) delete mode 100644 server/src/com/vaadin/UIRequiresMoreInformationException.java create mode 100644 server/src/com/vaadin/annotations/PreserveOnRefresh.java create mode 100644 server/src/com/vaadin/annotations/Title.java (limited to 'uitest/src') diff --git a/WebContent/VAADIN/vaadinBootstrap.js b/WebContent/VAADIN/vaadinBootstrap.js index 1f5f3fa973..36cf2ec8eb 100644 --- a/WebContent/VAADIN/vaadinBootstrap.js +++ b/WebContent/VAADIN/vaadinBootstrap.js @@ -153,15 +153,11 @@ var bootstrapApp = function(mayDefer) { var themeUri = getConfig('themeUri'); - if (themeUri) { - loadTheme(themeUri); - } + loadTheme(themeUri); var widgetsetBase = getConfig('widgetsetBase'); var widgetset = getConfig('widgetset'); - if (widgetset && widgetsetBase) { - loadWidgetset(widgetsetBase, widgetset); - } + loadWidgetset(widgetsetBase, widgetset); if (getConfig('uidl') === undefined) { if (mayDefer) { diff --git a/server/src/com/vaadin/Application.java b/server/src/com/vaadin/Application.java index fb2691c6d3..b1a9ae1d26 100644 --- a/server/src/com/vaadin/Application.java +++ b/server/src/com/vaadin/Application.java @@ -28,7 +28,6 @@ import java.util.Collections; import java.util.Enumeration; import java.util.EventObject; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -36,14 +35,15 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; -import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.vaadin.annotations.EagerInit; +import com.vaadin.annotations.PreserveOnRefresh; import com.vaadin.annotations.Theme; +import com.vaadin.annotations.Title; import com.vaadin.annotations.Widgetset; import com.vaadin.data.util.converter.Converter; import com.vaadin.data.util.converter.ConverterFactory; @@ -210,15 +210,16 @@ public class Application implements Terminal.ErrorListener, Serializable { * This implementation simulates the way of finding a window for a * request by extracting a window name from the requested path and * passes that name to {@link #getWindow(String)}. - * + *

* {@inheritDoc} - * - * @see #getWindow(String) - * @see Application#getUI(WrappedRequest) */ - @Override - public UI.LegacyWindow getUI(WrappedRequest request) { + protected T createUIInstance(WrappedRequest request, + Class uiClass) { + return uiClass.cast(getUIInstance(request)); + } + + private UI getUIInstance(WrappedRequest request) { String pathInfo = request.getRequestPathInfo(); String name = null; if (pathInfo != null && pathInfo.length() > 0) { @@ -235,6 +236,19 @@ public class Application implements Terminal.ErrorListener, Serializable { return mainWindow; } + /** + * This implementation simulates the way of finding a window for a + * request by extracting a window name from the requested path and + * passes that name to {@link #getWindow(String)}. + * + *

+ * {@inheritDoc} + */ + @Override + public Class getUIClass(WrappedRequest request) { + return getUIInstance(request).getClass(); + } + /** * Sets the application's theme. *

@@ -269,9 +283,9 @@ public class Application implements Terminal.ErrorListener, Serializable { *

* {@inheritDoc} */ - @Override - public String getThemeForUI(UI uI) { + public String getThemeForUI(WrappedRequest request, + Class uiClass) { return theme; } @@ -476,15 +490,6 @@ public class Application implements Terminal.ErrorListener, Serializable { private final EventRouter eventRouter = new EventRouter(); - /** - * Keeps track of which uIs have been inited. - *

- * TODO Investigate whether this might be derived from the different states - * in getUIForRrequest. - *

- */ - private Set initedUIs = new HashSet(); - private List uiProviders = new LinkedList(); private GlobalResourceHandler globalResourceHandler; @@ -1577,67 +1582,98 @@ public class Application implements Terminal.ErrorListener, Serializable { } /** - * Gets a UI for a request for which no UI is already known. This method is - * called when the framework processes a request that does not originate - * from an existing UI instance. This typically happens when a host page is - * requested. - * + * Gets the UI class for a request for which no UI is already known. This + * method is called when the framework processes a request that does not + * originate from an existing UI instance. This typically happens when a + * host page is requested. *

* Subclasses of Application may override this method to provide custom - * logic for choosing how to create a suitable UI or for picking an already - * created UI. If an existing UI is picked, care should be taken to avoid - * keeping the same UI open in multiple browser windows, as that will cause - * the states to go out of sync. - *

- * + * logic for choosing what kind of UI to use. *

- * If {@link BrowserDetails} are required to create a UI, the implementation - * can throw a {@link UIRequiresMoreInformationException} exception. In this - * case, the framework will instruct the browser to send the additional - * details, whereupon this method is invoked again with the browser details - * present in the wrapped request. Throwing the exception if the browser - * details are already available is not supported. - *

+ * The default implementation in {@link Application} uses the + * {@value #UI_PARAMETER} parameter from web.xml for finding the name of the + * UI class. If {@link DeploymentConfiguration#getClassLoader()} does not + * return null, the returned {@link ClassLoader} is used for + * loading the UI class. Otherwise the {@link ClassLoader} used to load this + * class is used. * - *

- * The default implementation in {@link Application} creates a new instance - * of the UI class returned by {@link #getUIClassName(WrappedRequest)}, - * which in turn uses the {@value #UI_PARAMETER} parameter from web.xml. If - * {@link DeploymentConfiguration#getClassLoader()} for the request returns - * a {@link ClassLoader}, it is used for loading the UI class. Otherwise the - * {@link ClassLoader} used to load this class is used. *

* * @param request * the wrapped request for which a UI is needed * @return a UI instance to use for the request - * @throws UIRequiresMoreInformationException - * may be thrown by an implementation to indicate that - * {@link BrowserDetails} are required to create a UI * - * @see #getUIClassName(WrappedRequest) * @see UI - * @see UIRequiresMoreInformationException * @see WrappedRequest#getBrowserDetails() * * @since 7.0 */ - protected UI getUI(WrappedRequest request) - throws UIRequiresMoreInformationException { - - // Iterate in reverse order - test check newest provider first - for (int i = uiProviders.size() - 1; i >= 0; i--) { + public Class getUIClass(WrappedRequest request) { + // Iterate in reverse order - check newest provider first + int providersSize = uiProviders.size(); + if (providersSize == 0) { + throw new IllegalStateException("There are no UI providers"); + } + for (int i = providersSize - 1; i >= 0; i--) { UIProvider provider = uiProviders.get(i); Class uiClass = provider.getUIClass(this, request); if (uiClass != null) { - return provider.instantiateUI(this, uiClass, request); + return uiClass; + } + } + + throw new RuntimeException( + "No UI provider returned an UI class for request"); + } + + /** + * Creates an UI instance for a request for which no UI is already known. + * This method is called when the framework processes a request that does + * not originate from an existing UI instance. This typically happens when a + * host page is requested. + *

+ * Subclasses of Application may override this method to provide custom + * logic for choosing how to create a suitable UI or for picking an already + * created UI. If an existing UI is picked, care should be taken to avoid + * keeping the same UI open in multiple browser windows, as that will cause + * the states to go out of sync. + *

+ * + * @param request + * @param uiClass + * @return + */ + protected T createUIInstance(WrappedRequest request, + Class uiClass) { + int providersSize = uiProviders.size(); + if (providersSize == 0) { + throw new IllegalStateException("There are no UI providers"); + } + + for (int i = providersSize - 1; i >= 0; i--) { + UIProvider provider = uiProviders.get(i); + + Class providerClass = provider.getUIClass(this, + request); + if (providerClass != null) { + if (providerClass != uiClass) { + getLogger().warning( + "Mismatching UI classes. Expected " + uiClass + + " but got " + providerClass + " from " + + provider); + // Try with next provider if we didn't get the expected + // class + continue; + } + return uiClass.cast(provider.instantiateUI(this, uiClass, + request)); } } throw new RuntimeException( - "No UI providers available or providers are not able to find UI instance"); + "No UI provider created an UI instance for request"); } /** @@ -1653,8 +1689,9 @@ public class Application implements Terminal.ErrorListener, Serializable { * * @since 7.0 */ - public String getThemeForUI(UI uI) { - Theme uiTheme = getAnnotationFor(uI.getClass(), Theme.class); + public String getThemeForUI(WrappedRequest request, + Class uiClass) { + Theme uiTheme = getAnnotationFor(uiClass, Theme.class); if (uiTheme != null) { return uiTheme.value(); } else { @@ -1665,18 +1702,22 @@ public class Application implements Terminal.ErrorListener, Serializable { /** * Finds the widgetset to use for a specific UI. If no specific widgetset is * required, null is returned. + *

+ * The default implementation uses the @{@link Widgetset} annotation if it's + * defined for the UI class. * - * TODO Tell what the default implementation does once it does something. - * - * @param uI - * the UI to get a widgetset for + * @param request + * the wrapped request for which to get a widgetset + * @param uiClass + * the UI class to get a widgetset for * @return the name of the widgetset, or null if the default * widgetset should be used * * @since 7.0 */ - public String getWidgetsetForUI(UI uI) { - Widgetset uiWidgetset = getAnnotationFor(uI.getClass(), Widgetset.class); + public String getWidgetsetForUI(WrappedRequest request, + Class uiClass) { + Widgetset uiWidgetset = getAnnotationFor(uiClass, Widgetset.class); if (uiWidgetset != null) { return uiWidgetset.value(); } else { @@ -1818,8 +1859,6 @@ public class Application implements Terminal.ErrorListener, Serializable { */ private static final ThreadLocal currentApplication = new ThreadLocal(); - private boolean uiPreserved = false; - /** * Gets the currently used application. The current application is * automatically defined when processing requests to the server. In other @@ -1894,17 +1933,12 @@ public class Application implements Terminal.ErrorListener, Serializable { * @param request * the request for which a UI is desired * @return a UI belonging to the request - * @throws UIRequiresMoreInformationException - * if no existing UI could be found and creating a new UI - * requires additional information from the browser * - * @see #getUI(WrappedRequest) - * @see UIRequiresMoreInformationException + * @see #createUI(WrappedRequest) * * @since 7.0 */ - public UI getUIForRequest(WrappedRequest request) - throws UIRequiresMoreInformationException { + public UI getUIForRequest(WrappedRequest request) { UI uI = UI.getCurrent(); if (uI != null) { return uI; @@ -1917,69 +1951,75 @@ public class Application implements Terminal.ErrorListener, Serializable { && browserDetails.getUriFragment() != null; uI = uIs.get(uiId); + Class uiClass = null; + + if (uI == null && hasBrowserDetails + && !retainOnRefreshUIs.isEmpty()) { + uiClass = getUIClass(request); - if (uI == null && isUiPreserved()) { // Check for a known UI - if (!retainOnRefreshUIs.isEmpty()) { - Integer retainedUIId; - if (!hasBrowserDetails) { - throw new UIRequiresMoreInformationException(); - } else { - String windowName = browserDetails.getWindowName(); - retainedUIId = retainOnRefreshUIs.get(windowName); - } + @SuppressWarnings("null") + String windowName = browserDetails.getWindowName(); + Integer retainedUIId = retainOnRefreshUIs.get(windowName); - if (retainedUIId != null) { + if (retainedUIId != null) { + UI retainedUI = uIs.get(retainedUIId); + // We've had the same UI instance in a window with this + // name, but should we still use it? + if (retainedUI.getClass() == uiClass) { uiId = retainedUIId; - uI = uIs.get(uiId); + uI = retainedUI; + } else { + getLogger().info( + "Not using retained UI in " + windowName + + " because retained UI was of type " + + retainedUIId.getClass() + " but " + + uiClass + + " is expected for the request."); } } } - if (uI == null) { - // Throws exception if UI can not yet be created - uI = getUI(request); + } // end synchronized block - // Initialize some fields for a newly created UI - if (uI.getApplication() == null) { - uI.setApplication(this); - } - if (uI.getUIId() < 0) { + UI.setCurrent(uI); - if (uiId == null) { - // Get the next id if none defined - uiId = Integer.valueOf(nextUIId++); - } - uI.setUIId(uiId.intValue()); - uIs.put(uiId, uI); - } - } + return uI; + } - // Set thread local here so it is available in init - UI.setCurrent(uI); + public UI createUI(WrappedRequest request) { + Class uiClass = getUIClass(request); - if (!initedUIs.contains(uiId)) { - boolean initRequiresBrowserDetails = isUiPreserved() - || !uI.getClass().isAnnotationPresent(EagerInit.class); - if (!initRequiresBrowserDetails || hasBrowserDetails) { - uI.doInit(request); + UI ui = createUIInstance(request, uiClass); - // Remember that this UI has been initialized - initedUIs.add(uiId); + // Initialize some fields for a newly created UI + if (ui.getApplication() == null) { + ui.setApplication(this); + } + // Get the next id + Integer uiId = Integer.valueOf(nextUIId++); - // init() might turn on preserve so do this afterwards - if (isUiPreserved()) { - // Remember this UI - String windowName = request.getBrowserDetails() - .getWindowName(); - retainOnRefreshUIs.put(windowName, uiId); - } - } + uIs.put(uiId, ui); + + // Set thread local here so it is available in init + UI.setCurrent(ui); + + ui.doInit(request, uiId.intValue()); + + if (isUiPreserved(request, uiClass)) { + // Remember this UI + String windowName = request.getBrowserDetails().getWindowName(); + if (windowName == null) { + getLogger().warning( + "There is no window.name available for UI " + uiClass + + " that should be preserved."); + } else { + retainOnRefreshUIs.put(windowName, uiId); } - } // end synchronized block + } - return uI; + return ui; } /** @@ -2002,54 +2042,23 @@ public class Application implements Terminal.ErrorListener, Serializable { return uiId; } - /** - * Sets whether the same UI state should be reused if the framework can - * detect that the application is opened in a browser window where it has - * previously been open. The framework attempts to discover this by checking - * the value of window.name in the browser. - *

- * NOTE that you should avoid turning this feature on/off on-the-fly when - * the UI is already shown, as it might not be retained as intended. - *

- * - * @param uiPreserved - * trueif the same UI instance should be reused e.g. - * when the browser window is refreshed. - */ - public void setUiPreserved(boolean uiPreserved) { - this.uiPreserved = uiPreserved; - if (!uiPreserved) { - retainOnRefreshUIs.clear(); - } - } - /** * Checks whether the same UI state should be reused if the framework can * detect that the application is opened in a browser window where it has * previously been open. The framework attempts to discover this by checking * the value of window.name in the browser. * + * @param request + * @param uiClass + * * @return trueif the same UI instance should be reused e.g. * when the browser window is refreshed. */ - public boolean isUiPreserved() { - return uiPreserved; - } - - /** - * Checks whether there's a pending initialization for the UI with the given - * id. - * - * @param uiId - * UI id to check for - * @return true of the initialization is pending, - * false if the UI id is not registered or if the UI - * has already been initialized - * - * @see #getUIForRequest(WrappedRequest) - */ - public boolean isUIInitPending(int uiId) { - return !initedUIs.contains(Integer.valueOf(uiId)); + public boolean isUiPreserved(WrappedRequest request, + Class uiClass) { + PreserveOnRefresh preserveOnRefresh = getAnnotationFor(uiClass, + PreserveOnRefresh.class); + return preserveOnRefresh != null; } /** @@ -2268,4 +2277,20 @@ public class Application implements Terminal.ErrorListener, Serializable { return globalResourceHandler; } + + public String getPageTitleForUI(WrappedRequest request, + Class uiClass) { + Title titleAnnotation = getAnnotationFor(uiClass, Title.class); + if (titleAnnotation == null) { + return null; + } else { + return titleAnnotation.value(); + } + } + + public boolean isEagerInit(WrappedRequest request, + Class uiClass) { + EagerInit eagerInit = getAnnotationFor(uiClass, EagerInit.class); + return eagerInit != null; + } } diff --git a/server/src/com/vaadin/UIRequiresMoreInformationException.java b/server/src/com/vaadin/UIRequiresMoreInformationException.java deleted file mode 100644 index 76a31d88ef..0000000000 --- a/server/src/com/vaadin/UIRequiresMoreInformationException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011 Vaadin Ltd. - * - * 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.vaadin; - -import com.vaadin.server.WrappedRequest; -import com.vaadin.server.WrappedRequest.BrowserDetails; - -/** - * Exception that is thrown to indicate that creating or initializing the UI - * requires information detailed from the web browser ({@link BrowserDetails}) - * to be present. - * - * This exception may not be thrown if that information is already present in - * the current WrappedRequest. - * - * @see Application#getUI(WrappedRequest) - * @see WrappedRequest#getBrowserDetails() - * - * @since 7.0 - */ -public class UIRequiresMoreInformationException extends Exception { - // Nothing of interest here -} diff --git a/server/src/com/vaadin/annotations/PreserveOnRefresh.java b/server/src/com/vaadin/annotations/PreserveOnRefresh.java new file mode 100644 index 0000000000..59c4abb723 --- /dev/null +++ b/server/src/com/vaadin/annotations/PreserveOnRefresh.java @@ -0,0 +1,28 @@ +/* + * Copyright 2011 Vaadin Ltd. + * + * 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.vaadin.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface PreserveOnRefresh { + +} diff --git a/server/src/com/vaadin/annotations/Title.java b/server/src/com/vaadin/annotations/Title.java new file mode 100644 index 0000000000..fcd5d986a8 --- /dev/null +++ b/server/src/com/vaadin/annotations/Title.java @@ -0,0 +1,38 @@ +/* + * Copyright 2011 Vaadin Ltd. + * + * 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.vaadin.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.vaadin.ui.UI; + +/** + * Defines the HTML page title for a {@link UI}. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Title { + /** + * Gets the HTML title that should be used if the UI is used on it's own. + * + * @return a page title string + */ + public String value(); +} diff --git a/server/src/com/vaadin/server/AbstractApplicationPortlet.java b/server/src/com/vaadin/server/AbstractApplicationPortlet.java index e47e00577b..e8151462aa 100644 --- a/server/src/com/vaadin/server/AbstractApplicationPortlet.java +++ b/server/src/com/vaadin/server/AbstractApplicationPortlet.java @@ -56,7 +56,6 @@ import com.liferay.portal.kernel.util.PropsUtil; import com.vaadin.Application; import com.vaadin.Application.ApplicationStartEvent; import com.vaadin.Application.SystemMessages; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.server.AbstractCommunicationManager.Callback; import com.vaadin.ui.UI; @@ -501,12 +500,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet // Both action requests and render requests are ok // without a UI as they render the initial HTML // and then do a second request - try { - uI = application - .getUIForRequest(wrappedRequest); - } catch (UIRequiresMoreInformationException e) { - // Ignore problem and continue without UI - } + uI = application.getUIForRequest(wrappedRequest); break; case BROWSER_DETAILS: // Should not try to find a UI here as the @@ -902,7 +896,6 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet throws PortletException { try { final Application application = getApplicationClass().newInstance(); - application.setUiPreserved(true); return application; } catch (final IllegalAccessException e) { throw new PortletException("getNewApplication failed", e); diff --git a/server/src/com/vaadin/server/AbstractCommunicationManager.java b/server/src/com/vaadin/server/AbstractCommunicationManager.java index 08ad48ff3d..72406e629d 100644 --- a/server/src/com/vaadin/server/AbstractCommunicationManager.java +++ b/server/src/com/vaadin/server/AbstractCommunicationManager.java @@ -60,13 +60,11 @@ import javax.servlet.http.HttpServletResponse; import com.vaadin.Application; import com.vaadin.Application.SystemMessages; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.annotations.JavaScript; import com.vaadin.annotations.StyleSheet; import com.vaadin.external.json.JSONArray; import com.vaadin.external.json.JSONException; import com.vaadin.external.json.JSONObject; -import com.vaadin.server.BootstrapHandler.BootstrapContext; import com.vaadin.server.ComponentSizeValidator.InvalidLayout; import com.vaadin.server.RpcManager.RpcInvocationException; import com.vaadin.server.StreamVariable.StreamingEndEvent; @@ -1512,7 +1510,7 @@ public abstract class AbstractCommunicationManager implements Serializable { } private String getTheme(UI uI) { - String themeName = uI.getApplication().getThemeForUI(uI); + String themeName = uI.getTheme(); String requestThemeName = getRequestTheme(); if (requestThemeName != null) { @@ -2410,36 +2408,22 @@ public abstract class AbstractCommunicationManager implements Serializable { WrappedResponse response, Application application) throws IOException { - // if we do not yet have a currentUI, it should be initialized - // shortly, and we should send the initial UIDL - boolean sendUIDL = UI.getCurrent() == null; + assert UI.getCurrent() == null; try { CombinedRequest combinedRequest = new CombinedRequest(request); - UI uI = application.getUIForRequest(combinedRequest); response.setContentType("application/json; charset=UTF-8"); - // Use the same logic as for determined UIs - BootstrapHandler bootstrapHandler = getBootstrapHandler(); - BootstrapContext context = bootstrapHandler.createContext( - combinedRequest, response, application, uI.getUIId()); - - String widgetset = context.getWidgetsetName(); - String theme = context.getThemeName(); - String themeUri = bootstrapHandler.getThemeUri(context, theme); + UI uI = application.getUIForRequest(combinedRequest); + if (uI == null) { + uI = application.createUI(combinedRequest); + } - // TODO These are not required if it was only the init of the UI - // that was delayed JSONObject params = new JSONObject(); - params.put("widgetset", widgetset); - params.put("themeUri", themeUri); - // UI id might have changed based on e.g. window.name params.put(UIConstants.UI_ID_PARAMETER, uI.getUIId()); - if (sendUIDL) { - String initialUIDL = getInitialUIDL(combinedRequest, uI); - params.put("uidl", initialUIDL); - } + String initialUIDL = getInitialUIDL(combinedRequest, uI); + params.put("uidl", initialUIDL); // NOTE! GateIn requires, for some weird reason, getOutputStream // to be used instead of getWriter() (it seems to interpret @@ -2452,10 +2436,6 @@ public abstract class AbstractCommunicationManager implements Serializable { // NOTE GateIn requires the buffers to be flushed to work outWriter.flush(); out.flush(); - } catch (UIRequiresMoreInformationException e) { - // Requiring more information at this point is not allowed - // TODO handle in a better way - throw new RuntimeException(e); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); diff --git a/server/src/com/vaadin/server/BootstrapFragmentResponse.java b/server/src/com/vaadin/server/BootstrapFragmentResponse.java index 16f7bc653b..149f59e7a5 100644 --- a/server/src/com/vaadin/server/BootstrapFragmentResponse.java +++ b/server/src/com/vaadin/server/BootstrapFragmentResponse.java @@ -21,6 +21,7 @@ import java.util.List; import org.jsoup.nodes.Node; import com.vaadin.Application; +import com.vaadin.ui.UI; /** * A representation of a bootstrap fragment being generated. The bootstrap @@ -37,7 +38,7 @@ public class BootstrapFragmentResponse extends BootstrapResponse { * Crate a new bootstrap fragment response. * * @see BootstrapResponse#BootstrapResponse(BootstrapHandler, - * WrappedRequest, Application, Integer) + * WrappedRequest, Application, Class) * * @param handler * the bootstrap handler that is firing the event @@ -47,16 +48,16 @@ public class BootstrapFragmentResponse extends BootstrapResponse { * @param application * the application for which the bootstrap page should be * generated - * @param uiId - * the generated id of the UI that will be displayed on the page + * @param uiClass + * the class of the UI that will be displayed on the page * @param fragmentNodes * a mutable list containing the DOM nodes that will make up the * application HTML */ public BootstrapFragmentResponse(BootstrapHandler handler, - WrappedRequest request, Application application, Integer uiId, - List fragmentNodes) { - super(handler, request, application, uiId); + WrappedRequest request, Application application, + Class uiClass, List fragmentNodes) { + super(handler, request, application, uiClass); this.fragmentNodes = fragmentNodes; } diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java index 280372a5e5..2b31d5d3bc 100644 --- a/server/src/com/vaadin/server/BootstrapHandler.java +++ b/server/src/com/vaadin/server/BootstrapHandler.java @@ -37,12 +37,10 @@ import org.jsoup.nodes.Node; import org.jsoup.parser.Tag; import com.vaadin.Application; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.external.json.JSONException; import com.vaadin.external.json.JSONObject; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.Version; -import com.vaadin.shared.ui.ui.UIConstants; import com.vaadin.ui.UI; public abstract class BootstrapHandler implements RequestHandler { @@ -74,30 +72,20 @@ public abstract class BootstrapHandler implements RequestHandler { return bootstrapResponse.getApplication(); } - public Integer getUIId() { - return bootstrapResponse.getUIId(); - } - - public UI getUI() { - return bootstrapResponse.getUI(); + public Class getUIClass() { + return bootstrapResponse.getUiClass(); } public String getWidgetsetName() { if (widgetsetName == null) { - UI uI = getUI(); - if (uI != null) { - widgetsetName = getWidgetsetForUI(this); - } + widgetsetName = getWidgetsetForUI(this); } return widgetsetName; } public String getThemeName() { if (themeName == null) { - UI uI = getUI(); - if (uI != null) { - themeName = findAndEscapeThemeName(this); - } + themeName = findAndEscapeThemeName(this); } return themeName; } @@ -120,23 +108,11 @@ public abstract class BootstrapHandler implements RequestHandler { WrappedRequest request, WrappedResponse response) throws IOException { - // TODO Should all urls be handled here? - Integer uiId = null; try { - UI uI = application.getUIForRequest(request); - if (uI == null) { - writeError(response, new Throwable("No UI found")); - return true; - } + Class uiClass = application.getUIClass(request); - uiId = Integer.valueOf(uI.getUIId()); - } catch (UIRequiresMoreInformationException e) { - // Just keep going without uiId - } - - try { BootstrapContext context = createContext(request, response, - application, uiId); + application, uiClass); setupMainDiv(context); BootstrapFragmentResponse fragmentResponse = context @@ -166,8 +142,8 @@ public abstract class BootstrapHandler implements RequestHandler { Map headers = new LinkedHashMap(); Document document = Document.createShell(""); BootstrapPageResponse pageResponse = new BootstrapPageResponse( - this, request, context.getApplication(), context.getUIId(), - document, headers); + this, request, context.getApplication(), + context.getUIClass(), document, headers); List fragmentNodes = fragmentResponse.getFragmentNodes(); Element body = document.body(); for (Node node : fragmentNodes) { @@ -242,10 +218,11 @@ public abstract class BootstrapHandler implements RequestHandler { head.appendElement("meta").attr("http-equiv", "X-UA-Compatible") .attr("content", "chrome=1"); - UI uI = context.getUI(); - String title = ((uI == null || uI.getCaption() == null) ? "" : uI - .getCaption()); - head.appendElement("title").appendText(title); + String title = context.getApplication().getPageTitleForUI( + context.getRequest(), context.getUIClass()); + if (title != null) { + head.appendElement("title").appendText(title); + } head.appendElement("style").attr("type", "text/css") .appendText("html, body {height:100%;margin:0;}"); @@ -267,11 +244,12 @@ public abstract class BootstrapHandler implements RequestHandler { body.addClass(ApplicationConstants.GENERATED_BODY_CLASSNAME); } - public BootstrapContext createContext(WrappedRequest request, - WrappedResponse response, Application application, Integer uiId) { + private BootstrapContext createContext(WrappedRequest request, + WrappedResponse response, Application application, + Class uiClass) { BootstrapContext context = new BootstrapContext(response, - new BootstrapFragmentResponse(this, request, application, uiId, - new ArrayList())); + new BootstrapFragmentResponse(this, request, application, + uiClass, new ArrayList())); return context; } @@ -290,10 +268,10 @@ public abstract class BootstrapHandler implements RequestHandler { protected abstract String getApplicationId(BootstrapContext context); public String getWidgetsetForUI(BootstrapContext context) { - UI uI = context.getUI(); WrappedRequest request = context.getRequest(); - String widgetset = uI.getApplication().getWidgetsetForUI(uI); + String widgetset = context.getApplication().getWidgetsetForUI( + context.getRequest(), context.getUIClass()); if (widgetset == null) { widgetset = request.getDeploymentConfiguration() .getConfiguredWidgetset(request); @@ -413,14 +391,9 @@ public abstract class BootstrapHandler implements RequestHandler { protected JSONObject getApplicationParameters(BootstrapContext context) throws JSONException, PaintException { Application application = context.getApplication(); - Integer uiId = context.getUIId(); JSONObject appConfig = new JSONObject(); - if (uiId != null) { - appConfig.put(UIConstants.UI_ID_PARAMETER, uiId); - } - if (context.getThemeName() != null) { appConfig.put("themeUri", getThemeUri(context, context.getThemeName())); @@ -433,18 +406,18 @@ public abstract class BootstrapHandler implements RequestHandler { appConfig.put("widgetset", context.getWidgetsetName()); - if (uiId == null || application.isUIInitPending(uiId.intValue())) { - appConfig.put("initialPath", context.getRequest() - .getRequestPathInfo()); - - Map parameterMap = context.getRequest() - .getParameterMap(); - appConfig.put("initialParams", parameterMap); - } else { + if (application.isEagerInit(context.getRequest(), context.getUIClass())) { + throw new RuntimeException( + "Eager UI init is currently not supported"); // write the initial UIDL into the config - appConfig.put("uidl", - getInitialUIDL(context.getRequest(), context.getUI())); + // appConfig.put("uidl", + // getInitialUIDL(context.getRequest(), context.getUI())); } + appConfig.put("initialPath", context.getRequest().getRequestPathInfo()); + + Map parameterMap = context.getRequest() + .getParameterMap(); + appConfig.put("initialParams", parameterMap); return appConfig; } @@ -532,7 +505,8 @@ public abstract class BootstrapHandler implements RequestHandler { * @return */ public String getThemeName(BootstrapContext context) { - return context.getApplication().getThemeForUI(context.getUI()); + return context.getApplication().getThemeForUI(context.getRequest(), + context.getUIClass()); } /** @@ -561,21 +535,4 @@ public abstract class BootstrapHandler implements RequestHandler { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getLocalizedMessage()); } - - /** - * Gets the initial UIDL message to send to the client. - * - * @param request - * the originating request - * @param ui - * the UI for which the UIDL should be generated - * @return a string with the initial UIDL message - * @throws PaintException - * if an exception occurs while painting the components - * @throws JSONException - * if an exception occurs while formatting the output - */ - protected abstract String getInitialUIDL(WrappedRequest request, UI ui) - throws PaintException, JSONException; - } diff --git a/server/src/com/vaadin/server/BootstrapPageResponse.java b/server/src/com/vaadin/server/BootstrapPageResponse.java index d6df145728..a5fdfe4707 100644 --- a/server/src/com/vaadin/server/BootstrapPageResponse.java +++ b/server/src/com/vaadin/server/BootstrapPageResponse.java @@ -21,6 +21,7 @@ import java.util.Map; import org.jsoup.nodes.Document; import com.vaadin.Application; +import com.vaadin.ui.UI; /** * A representation of a bootstrap page being generated. The bootstrap page @@ -39,7 +40,7 @@ public class BootstrapPageResponse extends BootstrapResponse { * Crate a new bootstrap page response. * * @see BootstrapResponse#BootstrapResponse(BootstrapHandler, - * WrappedRequest, Application, Integer) + * WrappedRequest, Application, Class) * * @param handler * the bootstrap handler that is firing the event @@ -49,17 +50,18 @@ public class BootstrapPageResponse extends BootstrapResponse { * @param application * the application for which the bootstrap page should be * generated - * @param uiId - * the generated id of the UI that will be displayed on the page + * @param uiClass + * the class of the UI that will be displayed on the page * @param document * the DOM document making up the HTML page * @param headers * a map into which header data can be added */ public BootstrapPageResponse(BootstrapHandler handler, - WrappedRequest request, Application application, Integer uiId, - Document document, Map headers) { - super(handler, request, application, uiId); + WrappedRequest request, Application application, + Class uiClass, Document document, + Map headers) { + super(handler, request, application, uiClass); this.headers = headers; this.document = document; } diff --git a/server/src/com/vaadin/server/BootstrapResponse.java b/server/src/com/vaadin/server/BootstrapResponse.java index 962b48dc31..3173569059 100644 --- a/server/src/com/vaadin/server/BootstrapResponse.java +++ b/server/src/com/vaadin/server/BootstrapResponse.java @@ -19,7 +19,6 @@ package com.vaadin.server; import java.util.EventObject; import com.vaadin.Application; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.ui.UI; /** @@ -32,7 +31,7 @@ import com.vaadin.ui.UI; public abstract class BootstrapResponse extends EventObject { private final WrappedRequest request; private final Application application; - private final Integer uiId; + private final Class uiClass; /** * Creates a new bootstrap event. @@ -45,15 +44,15 @@ public abstract class BootstrapResponse extends EventObject { * @param application * the application for which the bootstrap page should be * generated - * @param uiId - * the generated id of the UI that will be displayed on the page + * @param uiClass + * the class of the UI that will be displayed on the page */ public BootstrapResponse(BootstrapHandler handler, WrappedRequest request, - Application application, Integer uiId) { + Application application, Class uiClass) { super(handler); this.request = request; this.application = application; - this.uiId = uiId; + this.uiClass = uiClass; } /** @@ -89,32 +88,13 @@ public abstract class BootstrapResponse extends EventObject { } /** - * Gets the UI id that has been generated for this response. Please note - * that if {@link Application#isUiPreserved()} is enabled, a previously - * created UI with a different id might eventually end up being used. + * Gets the class of the UI that will be displayed on the generated + * bootstrap page. * - * @return the UI id + * @return the class of the UI */ - public Integer getUIId() { - return uiId; + public Class getUiClass() { + return uiClass; } - /** - * Gets the UI for which this page is being rendered, if available. Some - * features of the framework will postpone the UI selection until after the - * bootstrap page has been rendered and required information from the - * browser has been sent back. This method will return null if - * no UI instance is yet available. - * - * @see Application#isUiPreserved() - * @see Application#getUI(WrappedRequest) - * @see UIRequiresMoreInformationException - * - * @return The UI that will be displayed in the page being generated, or - * null if all required information is not yet - * available. - */ - public UI getUI() { - return UI.getCurrent(); - } } diff --git a/server/src/com/vaadin/server/CommunicationManager.java b/server/src/com/vaadin/server/CommunicationManager.java index 9b56e20fd4..3c594eaf02 100644 --- a/server/src/com/vaadin/server/CommunicationManager.java +++ b/server/src/com/vaadin/server/CommunicationManager.java @@ -22,7 +22,6 @@ import java.net.URL; import javax.servlet.ServletContext; import com.vaadin.Application; -import com.vaadin.external.json.JSONException; import com.vaadin.ui.UI; /** @@ -107,12 +106,6 @@ public class CommunicationManager extends AbstractCommunicationManager { } return themeName; } - - @Override - protected String getInitialUIDL(WrappedRequest request, UI uI) - throws PaintException, JSONException { - return CommunicationManager.this.getInitialUIDL(request, uI); - } }; } diff --git a/server/src/com/vaadin/server/DefaultUIProvider.java b/server/src/com/vaadin/server/DefaultUIProvider.java index d4490b1642..93128aad28 100644 --- a/server/src/com/vaadin/server/DefaultUIProvider.java +++ b/server/src/com/vaadin/server/DefaultUIProvider.java @@ -17,14 +17,13 @@ package com.vaadin.server; import com.vaadin.Application; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.ui.UI; public class DefaultUIProvider extends AbstractUIProvider { @Override public Class getUIClass(Application application, - WrappedRequest request) throws UIRequiresMoreInformationException { + WrappedRequest request) { Object uiClassNameObj = application .getProperty(Application.UI_PARAMETER); diff --git a/server/src/com/vaadin/server/PortletCommunicationManager.java b/server/src/com/vaadin/server/PortletCommunicationManager.java index f7d9371022..697095d691 100644 --- a/server/src/com/vaadin/server/PortletCommunicationManager.java +++ b/server/src/com/vaadin/server/PortletCommunicationManager.java @@ -137,13 +137,6 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { null); } - @Override - protected String getInitialUIDL(WrappedRequest request, UI uI) - throws PaintException, JSONException { - return PortletCommunicationManager.this.getInitialUIDL(request, - uI); - } - @Override protected JSONObject getApplicationParameters( BootstrapContext context) throws JSONException, diff --git a/server/src/com/vaadin/server/UIProvider.java b/server/src/com/vaadin/server/UIProvider.java index 890809fdd5..36bb164845 100644 --- a/server/src/com/vaadin/server/UIProvider.java +++ b/server/src/com/vaadin/server/UIProvider.java @@ -17,12 +17,11 @@ package com.vaadin.server; import com.vaadin.Application; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.ui.UI; public interface UIProvider { public Class getUIClass(Application application, - WrappedRequest request) throws UIRequiresMoreInformationException; + WrappedRequest request); public UI instantiateUI(Application application, Class type, WrappedRequest request); diff --git a/server/src/com/vaadin/server/WrappedRequest.java b/server/src/com/vaadin/server/WrappedRequest.java index 8ae5335763..e95b2d599b 100644 --- a/server/src/com/vaadin/server/WrappedRequest.java +++ b/server/src/com/vaadin/server/WrappedRequest.java @@ -26,8 +26,6 @@ import javax.portlet.PortletRequest; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; -import com.vaadin.Application; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.annotations.EagerInit; import com.vaadin.ui.UI; @@ -218,11 +216,8 @@ public interface WrappedRequest extends Serializable { * for instance using javascript in the browser. * * This information is only guaranteed to be available in some special - * cases, for instance when - * {@link Application#getUIForRequest(WrappedRequest)} is called again after - * throwing {@link UIRequiresMoreInformationException} or in - * {@link UI#init(WrappedRequest)} for a UI class not annotated with - * {@link EagerInit} + * cases, for instance in {@link UI#init(WrappedRequest)} for a UI class not + * annotated with {@link EagerInit} * * @return the browser details, or null if details are not * available diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index d86d46c155..b6ac271942 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -85,7 +85,7 @@ import com.vaadin.tools.ReflectTools; *

* * @see #init(WrappedRequest) - * @see Application#getUI(WrappedRequest) + * @see Application#createUI(WrappedRequest) * * @since 7.0 */ @@ -98,7 +98,6 @@ public abstract class UI extends AbstractComponentContainer implements * window in Vaadin 6 with {@link com.vaadin.Application.LegacyApplication} */ @Deprecated - @EagerInit public static class LegacyWindow extends UI { private String name; @@ -709,28 +708,6 @@ public abstract class UI extends AbstractComponentContainer implements } } - /** - * Sets the id of this UI within its application. The UI id is used to route - * requests to the right UI. - *

- * This method is mainly intended for internal use by the framework. - *

- * - * @param uiId - * the id of this UI - * - * @throws IllegalStateException - * if the UI id has already been set - * - * @see #getUIId() - */ - public void setUIId(int uiId) { - if (this.uiId != -1) { - throw new IllegalStateException("UI id has already been defined"); - } - this.uiId = uiId; - } - /** * Gets the id of the UI, used to identify this UI within its application * when processing requests. The UI id should be present in every request to @@ -748,8 +725,8 @@ public abstract class UI extends AbstractComponentContainer implements * Adds a window as a subwindow inside this UI. To open a new browser window * or tab, you should instead use {@link open(Resource)} with an url * pointing to this application and ensure - * {@link Application#getUI(WrappedRequest)} returns an appropriate UI for - * the request. + * {@link Application#createUI(WrappedRequest)} returns an appropriate UI + * for the request. * * @param window * @throws IllegalArgumentException @@ -831,6 +808,8 @@ public abstract class UI extends AbstractComponentContainer implements private boolean resizeLazy = false; + private String theme; + /** * This method is used by Component.Focusable objects to request focus to * themselves. Focus renders must be handled at window level (instead of @@ -959,8 +938,16 @@ public abstract class UI extends AbstractComponentContainer implements * * @param request * the initialization request + * @param uiId + * the id of the new ui */ - public void doInit(WrappedRequest request) { + public void doInit(WrappedRequest request, int uiId) { + if (this.uiId != -1) { + throw new IllegalStateException("UI id has already been defined"); + } + this.uiId = uiId; + theme = getApplication().getThemeForUI(request, getClass()); + getPage().init(request); // Call the init overridden by the application developer @@ -1352,4 +1339,13 @@ public abstract class UI extends AbstractComponentContainer implements public void setLastUidlRequestTime(long lastUidlRequest) { this.lastUidlRequest = lastUidlRequest; } + + /** + * Gets the theme that was used when the UI was initialized. + * + * @return the theme name + */ + public String getTheme() { + return theme; + } } diff --git a/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java b/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java index 906d6ccebd..89da55a31f 100644 --- a/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java +++ b/server/tests/src/com/vaadin/tests/server/component/root/CustomUIClassLoader.java @@ -10,7 +10,6 @@ import org.easymock.EasyMock; import com.vaadin.Application; import com.vaadin.Application.ApplicationStartEvent; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.server.DefaultUIProvider; import com.vaadin.server.DeploymentConfiguration; import com.vaadin.server.WrappedRequest; @@ -56,8 +55,11 @@ public class CustomUIClassLoader extends TestCase { application.start(new ApplicationStartEvent(null, createConfigurationMock(), null)); - UI uI = application.getUIForRequest(createRequestMock(null)); - assertTrue(uI instanceof MyUI); + DefaultUIProvider uiProvider = new DefaultUIProvider(); + Class uiClass = uiProvider.getUIClass(application, + createRequestMock(null)); + + assertEquals(MyUI.class, uiClass); } private static DeploymentConfiguration createConfigurationMock() { @@ -101,9 +103,11 @@ public class CustomUIClassLoader extends TestCase { application.start(new ApplicationStartEvent(null, createConfigurationMock(), null)); - UI uI = application - .getUIForRequest(createRequestMock(loggingClassLoader)); - assertTrue(uI instanceof MyUI); + DefaultUIProvider uiProvider = new DefaultUIProvider(); + Class uiClass = uiProvider.getUIClass(application, + createRequestMock(loggingClassLoader)); + + assertEquals(MyUI.class, uiClass); assertEquals(1, loggingClassLoader.requestedClasses.size()); assertEquals(MyUI.class.getName(), loggingClassLoader.requestedClasses.get(0)); @@ -112,10 +116,6 @@ public class CustomUIClassLoader extends TestCase { private Application createStubApplication() { return new Application() { - { - addUIProvider(new DefaultUIProvider()); - } - @Override public String getProperty(String name) { if (name.equals(UI_PARAMETER)) { @@ -124,14 +124,6 @@ public class CustomUIClassLoader extends TestCase { return super.getProperty(name); } } - - @Override - public UI getUIForRequest(WrappedRequest request) - throws UIRequiresMoreInformationException { - // Always create a new root for testing (can't directly use - // getRoot as it's protected) - return getUI(request); - } }; } } diff --git a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java index e05979ede0..bceecaf35a 100644 --- a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java +++ b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java @@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.vaadin.Application; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.server.AbstractApplicationServlet; import com.vaadin.server.AbstractUIProvider; import com.vaadin.server.WrappedHttpServletRequest; @@ -116,8 +115,7 @@ public class ApplicationRunnerServlet extends AbstractApplicationServlet { @Override public Class getUIClass( - Application application, WrappedRequest request) - throws UIRequiresMoreInformationException { + Application application, WrappedRequest request) { return (Class) classToRun; } }); diff --git a/uitest/src/com/vaadin/tests/application/RefreshStatePreserve.java b/uitest/src/com/vaadin/tests/application/RefreshStatePreserve.java index 3013659ed7..8962f5de9a 100644 --- a/uitest/src/com/vaadin/tests/application/RefreshStatePreserve.java +++ b/uitest/src/com/vaadin/tests/application/RefreshStatePreserve.java @@ -1,7 +1,7 @@ package com.vaadin.tests.application; import com.vaadin.Application; -import com.vaadin.UIRequiresMoreInformationException; +import com.vaadin.annotations.PreserveOnRefresh; import com.vaadin.server.AbstractUIProvider; import com.vaadin.server.WrappedRequest; import com.vaadin.tests.components.AbstractTestApplication; @@ -9,6 +9,7 @@ import com.vaadin.ui.Label; import com.vaadin.ui.UI; public class RefreshStatePreserve extends AbstractTestApplication { + @PreserveOnRefresh public static class RefreshStateUI extends UI { @Override public void init(WrappedRequest request) { @@ -22,12 +23,10 @@ public class RefreshStatePreserve extends AbstractTestApplication { @Override public void init() { super.init(); - setUiPreserved(true); addUIProvider(new AbstractUIProvider() { @Override public Class getUIClass(Application application, - WrappedRequest request) - throws UIRequiresMoreInformationException { + WrappedRequest request) { return RefreshStateUI.class; } }); diff --git a/uitest/src/com/vaadin/tests/application/ThreadLocalInstances.java b/uitest/src/com/vaadin/tests/application/ThreadLocalInstances.java index 0e7dd1b242..89cbf5d3ff 100644 --- a/uitest/src/com/vaadin/tests/application/ThreadLocalInstances.java +++ b/uitest/src/com/vaadin/tests/application/ThreadLocalInstances.java @@ -1,9 +1,9 @@ package com.vaadin.tests.application; import com.vaadin.Application; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.server.DownloadStream; import com.vaadin.server.PaintException; +import com.vaadin.server.UIProvider; import com.vaadin.server.WrappedRequest; import com.vaadin.tests.components.AbstractTestApplication; import com.vaadin.tests.integration.FlagSeResource; @@ -73,12 +73,19 @@ public class ThreadLocalInstances extends AbstractTestApplication { @Override public void init() { reportCurrentStatus("app init"); - } + addUIProvider(new UIProvider() { + @Override + public UI instantiateUI(Application application, + Class type, WrappedRequest request) { + return mainWindow; + } - @Override - protected UI getUI(WrappedRequest request) - throws UIRequiresMoreInformationException { - return mainWindow; + @Override + public Class getUIClass(Application application, + WrappedRequest request) { + return mainWindow.getClass(); + } + }); } @Override diff --git a/uitest/src/com/vaadin/tests/components/loginform/LoginFormWithMultipleWindows.java b/uitest/src/com/vaadin/tests/components/loginform/LoginFormWithMultipleWindows.java index ac4c3c8ea3..84c14763ab 100644 --- a/uitest/src/com/vaadin/tests/components/loginform/LoginFormWithMultipleWindows.java +++ b/uitest/src/com/vaadin/tests/components/loginform/LoginFormWithMultipleWindows.java @@ -1,6 +1,7 @@ package com.vaadin.tests.components.loginform; import com.vaadin.Application; +import com.vaadin.server.AbstractUIProvider; import com.vaadin.server.WrappedRequest; import com.vaadin.ui.LoginForm; import com.vaadin.ui.LoginForm.LoginEvent; @@ -12,11 +13,17 @@ import com.vaadin.ui.UI.LegacyWindow; public class LoginFormWithMultipleWindows extends Application { @Override - protected UI getUI(WrappedRequest request) { - return new LoginFormWindow(); + public void init() { + addUIProvider(new AbstractUIProvider() { + @Override + public Class getUIClass(Application application, + WrappedRequest request) { + return LoginFormWindow.class; + } + }); } - public class LoginFormWindow extends LegacyWindow { + public static class LoginFormWindow extends LegacyWindow { public LoginFormWindow() { super(); diff --git a/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java b/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java index 34bf8f6715..4cd786593a 100644 --- a/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java +++ b/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java @@ -1,10 +1,10 @@ package com.vaadin.tests.components.ui; -import com.vaadin.UIRequiresMoreInformationException; +import com.vaadin.Application; import com.vaadin.annotations.EagerInit; import com.vaadin.server.ExternalResource; +import com.vaadin.server.UIProvider; import com.vaadin.server.WrappedRequest; -import com.vaadin.server.WrappedRequest.BrowserDetails; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.tests.components.AbstractTestApplication; import com.vaadin.ui.Label; @@ -22,23 +22,33 @@ public class LazyInitUIs extends AbstractTestApplication { } @Override - public UI getUI(WrappedRequest request) - throws UIRequiresMoreInformationException { + public void init() { + addUIProvider(new UIProvider() { + + @Override + public UI instantiateUI(Application application, + Class type, WrappedRequest request) { + return getUI(request); + } + + @Override + public Class getUIClass(Application application, + WrappedRequest request) { + return getUI(request).getClass(); + } + }); + } + + private UI getUI(WrappedRequest request) { if (request.getParameter("lazyCreate") != null) { // UI created on second request - BrowserDetails browserDetails = request.getBrowserDetails(); - if (browserDetails == null - || browserDetails.getUriFragment() == null) { - throw new UIRequiresMoreInformationException(); - } else { - UI uI = new UI() { - @Override - protected void init(WrappedRequest request) { - addComponent(getRequestInfo("LazyCreateUI", request)); - } - }; - return uI; - } + UI uI = new UI() { + @Override + protected void init(WrappedRequest request) { + addComponent(getRequestInfo("LazyCreateUI", request)); + } + }; + return uI; } else if (request.getParameter("eagerInit") != null) { // UI inited on first request return new EagerInitUI(); diff --git a/uitest/src/com/vaadin/tests/components/ui/UIsInMultipleTabs.java b/uitest/src/com/vaadin/tests/components/ui/UIsInMultipleTabs.java index 022db1bf3e..fe2fe16d93 100644 --- a/uitest/src/com/vaadin/tests/components/ui/UIsInMultipleTabs.java +++ b/uitest/src/com/vaadin/tests/components/ui/UIsInMultipleTabs.java @@ -1,7 +1,6 @@ package com.vaadin.tests.components.ui; import com.vaadin.Application; -import com.vaadin.UIRequiresMoreInformationException; import com.vaadin.server.AbstractUIProvider; import com.vaadin.server.WrappedRequest; import com.vaadin.tests.components.AbstractTestApplication; @@ -26,8 +25,7 @@ public class UIsInMultipleTabs extends AbstractTestApplication { addUIProvider(new AbstractUIProvider() { @Override public Class getUIClass(Application application, - WrappedRequest request) - throws UIRequiresMoreInformationException { + WrappedRequest request) { return TabUI.class; } }); diff --git a/uitest/src/com/vaadin/tests/minitutorials/v7a1/CreatingPreserveState.java b/uitest/src/com/vaadin/tests/minitutorials/v7a1/CreatingPreserveState.java index a96b8957c6..cfb24c732f 100644 --- a/uitest/src/com/vaadin/tests/minitutorials/v7a1/CreatingPreserveState.java +++ b/uitest/src/com/vaadin/tests/minitutorials/v7a1/CreatingPreserveState.java @@ -16,9 +16,10 @@ package com.vaadin.tests.minitutorials.v7a1; +import com.vaadin.annotations.PreserveOnRefresh; import com.vaadin.server.WrappedRequest; -import com.vaadin.ui.UI; import com.vaadin.ui.TextField; +import com.vaadin.ui.UI; /** * Mini tutorial code for @@ -28,6 +29,7 @@ import com.vaadin.ui.TextField; * @author Vaadin Ltd * @since 7.0.0 */ +@PreserveOnRefresh public class CreatingPreserveState extends UI { private static int windowCounter = 0; @@ -36,7 +38,6 @@ public class CreatingPreserveState extends UI { TextField tf = new TextField("Window #" + (++windowCounter)); tf.setImmediate(true); getContent().addComponent(tf); - getApplication().setUiPreserved(true); } } diff --git a/uitest/src/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java b/uitest/src/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java index ba3042c48e..54cf8a94e0 100644 --- a/uitest/src/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java +++ b/uitest/src/com/vaadin/tests/minitutorials/v7a1/DifferentFeaturesForDifferentClients.java @@ -17,10 +17,9 @@ package com.vaadin.tests.minitutorials.v7a1; import com.vaadin.Application; -import com.vaadin.UIRequiresMoreInformationException; +import com.vaadin.server.UIProvider; import com.vaadin.server.WebBrowser; import com.vaadin.server.WrappedRequest; -import com.vaadin.server.WrappedRequest.BrowserDetails; import com.vaadin.ui.Label; import com.vaadin.ui.UI; @@ -35,21 +34,32 @@ import com.vaadin.ui.UI; public class DifferentFeaturesForDifferentClients extends Application { @Override - protected UI getUI(WrappedRequest request) - throws UIRequiresMoreInformationException { - BrowserDetails browserDetails = request.getBrowserDetails(); - // This is a limitation of 7.0.0.alpha1 that there is no better way to - // check if WebBrowser has been fully initialized - if (browserDetails.getUriFragment() == null) { - throw new UIRequiresMoreInformationException(); - } + public void init() { + super.init(); + addUIProvider(new UIProvider() { + @Override + public Class getUIClass(Application application, + WrappedRequest request) { + // could also use browser version etc. + if (request.getHeader("user-agent").contains("mobile")) { + return TouchRoot.class; + } else { + return DefaultRoot.class; + } + } - // could also use screen size, browser version etc. - if (browserDetails.getWebBrowser().isTouchDevice()) { - return new TouchRoot(); - } else { - return new DefaultRoot(); - } + // Must override as default implementation isn't allowed to + // instantiate our non-public classes + @Override + public UI instantiateUI(Application application, + Class type, WrappedRequest request) { + try { + return type.newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }); } } diff --git a/uitest/src/com/vaadin/tests/vaadincontext/TestAddonContextListener.java b/uitest/src/com/vaadin/tests/vaadincontext/TestAddonContextListener.java index 9f3019b21c..1f50110330 100644 --- a/uitest/src/com/vaadin/tests/vaadincontext/TestAddonContextListener.java +++ b/uitest/src/com/vaadin/tests/vaadincontext/TestAddonContextListener.java @@ -42,9 +42,8 @@ public class TestAddonContextListener implements AddonContextListener { } private boolean shouldModify(BootstrapResponse response) { - UI uI = response.getUI(); - boolean shouldModify = uI != null - && uI.getClass() == BootstrapModifyUI.class; + Class uiClass = response.getUiClass(); + boolean shouldModify = uiClass == BootstrapModifyUI.class; return shouldModify; } -- cgit v1.2.3 From f85c152a48686a8a0dca38ca12b4f3509cac056f Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Fri, 31 Aug 2012 12:14:52 +0300 Subject: Remove @EagerInit (#9445) --- server/src/com/vaadin/Application.java | 7 ---- server/src/com/vaadin/annotations/EagerInit.java | 42 ---------------------- server/src/com/vaadin/server/BootstrapHandler.java | 7 ---- server/src/com/vaadin/server/WrappedRequest.java | 4 +-- server/src/com/vaadin/ui/UI.java | 14 ++------ .../vaadin/tests/components/ui/LazyInitUIs.java | 3 +- 6 files changed, 4 insertions(+), 73 deletions(-) delete mode 100644 server/src/com/vaadin/annotations/EagerInit.java (limited to 'uitest/src') diff --git a/server/src/com/vaadin/Application.java b/server/src/com/vaadin/Application.java index b1a9ae1d26..cd34fb7540 100644 --- a/server/src/com/vaadin/Application.java +++ b/server/src/com/vaadin/Application.java @@ -40,7 +40,6 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.vaadin.annotations.EagerInit; import com.vaadin.annotations.PreserveOnRefresh; import com.vaadin.annotations.Theme; import com.vaadin.annotations.Title; @@ -2287,10 +2286,4 @@ public class Application implements Terminal.ErrorListener, Serializable { return titleAnnotation.value(); } } - - public boolean isEagerInit(WrappedRequest request, - Class uiClass) { - EagerInit eagerInit = getAnnotationFor(uiClass, EagerInit.class); - return eagerInit != null; - } } diff --git a/server/src/com/vaadin/annotations/EagerInit.java b/server/src/com/vaadin/annotations/EagerInit.java deleted file mode 100644 index f08d46b551..0000000000 --- a/server/src/com/vaadin/annotations/EagerInit.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011 Vaadin Ltd. - * - * 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.vaadin.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import com.vaadin.server.WrappedRequest; -import com.vaadin.ui.UI; - -/** - * Indicates that the init method in a UI class can be called before full - * browser details ({@link WrappedRequest#getBrowserDetails()}) are available. - * This will make the UI appear more quickly, as ensuring the availability of - * this information typically requires an additional round trip to the client. - * - * @see UI#init(com.vaadin.server.WrappedRequest) - * @see WrappedRequest#getBrowserDetails() - * - * @since 7.0 - * - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface EagerInit { - // No values -} diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java index 2b31d5d3bc..60ac40916c 100644 --- a/server/src/com/vaadin/server/BootstrapHandler.java +++ b/server/src/com/vaadin/server/BootstrapHandler.java @@ -406,13 +406,6 @@ public abstract class BootstrapHandler implements RequestHandler { appConfig.put("widgetset", context.getWidgetsetName()); - if (application.isEagerInit(context.getRequest(), context.getUIClass())) { - throw new RuntimeException( - "Eager UI init is currently not supported"); - // write the initial UIDL into the config - // appConfig.put("uidl", - // getInitialUIDL(context.getRequest(), context.getUI())); - } appConfig.put("initialPath", context.getRequest().getRequestPathInfo()); Map parameterMap = context.getRequest() diff --git a/server/src/com/vaadin/server/WrappedRequest.java b/server/src/com/vaadin/server/WrappedRequest.java index e95b2d599b..0714f73cad 100644 --- a/server/src/com/vaadin/server/WrappedRequest.java +++ b/server/src/com/vaadin/server/WrappedRequest.java @@ -26,7 +26,6 @@ import javax.portlet.PortletRequest; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; -import com.vaadin.annotations.EagerInit; import com.vaadin.ui.UI; /** @@ -216,8 +215,7 @@ public interface WrappedRequest extends Serializable { * for instance using javascript in the browser. * * This information is only guaranteed to be available in some special - * cases, for instance in {@link UI#init(WrappedRequest)} for a UI class not - * annotated with {@link EagerInit} + * cases, for instance in {@link UI#init(WrappedRequest)}. * * @return the browser details, or null if details are not * available diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index b6ac271942..d1ccaacde3 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -28,7 +28,6 @@ import java.util.LinkedHashSet; import java.util.Map; import com.vaadin.Application; -import com.vaadin.annotations.EagerInit; import com.vaadin.event.Action; import com.vaadin.event.Action.Handler; import com.vaadin.event.ActionManager; @@ -77,12 +76,6 @@ import com.vaadin.tools.ReflectTools; * passing a {@link ComponentContainer} with the main layout of the view to * {@link #setContent(ComponentContainer)}. *

- *

- * If a {@link EagerInit} annotation is present on a class extending - * UI, the framework will use a faster initialization method which - * will not ensure that {@link BrowserDetails} are present in the - * {@link WrappedRequest} passed to the init method. - *

* * @see #init(WrappedRequest) * @see Application#createUI(WrappedRequest) @@ -961,11 +954,8 @@ public abstract class UI extends AbstractComponentContainer implements * state of the UI is not properly set up when the constructor is invoked. *

* The {@link WrappedRequest} can be used to get information about the - * request that caused this UI to be created. By default, the - * {@link BrowserDetails} will be available in the request. If the browser - * details are not required, loading the application in the browser can take - * some shortcuts giving a faster initial rendering. This can be indicated - * by adding the {@link EagerInit} annotation to the UI class. + * request that caused this UI to be created. {@link BrowserDetails} will be + * available in the request. *

* * @param request diff --git a/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java b/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java index 4cd786593a..18267e90b6 100644 --- a/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java +++ b/uitest/src/com/vaadin/tests/components/ui/LazyInitUIs.java @@ -1,7 +1,6 @@ package com.vaadin.tests.components.ui; import com.vaadin.Application; -import com.vaadin.annotations.EagerInit; import com.vaadin.server.ExternalResource; import com.vaadin.server.UIProvider; import com.vaadin.server.WrappedRequest; @@ -13,7 +12,7 @@ import com.vaadin.ui.UI; public class LazyInitUIs extends AbstractTestApplication { - @EagerInit + // @EagerInit private static class EagerInitUI extends UI { @Override public void init(WrappedRequest request) { -- cgit v1.2.3