11.15. Accessing Session-Global Data

This section is mostly up-to-date with Vaadin 7, but has some information which still needs to be updated.

Applications typically need to access some objects from practically all user interface code, such as a user object, a business data model, or a database connection. This data is typically initialized and managed in the UI class of the application, or in the session or servlet.

For example, you could hold it in the UI class as follows:

class MyUI extends UI {
    UserData userData;

    public void init() {
        userData = new UserData();
    }

    public UserData getUserData() {
        return userData;
    }
}

Vaadin offers two ways to access the UI object: with getUI() method from any component and the global UI.getCurrent() method.

The getUI() works as follows:

data = ((MyUI)component.getUI()).getUserData();

This does not, however work in many cases, because it requires that the components are attached to the UI. That is not the case most of the time when the UI is still being built, such as in constructors.

class MyComponent extends CustomComponent {
    public MyComponent() {
        // This fails with NullPointerException
        Label label = new Label("Country: " +
            getApplication().getLocale().getCountry());

        setCompositionRoot(label);
    }
}

The global access methods for the currently served servlet, session, and UI allow an easy way to access the data:

data = ((MyUI) UI.getCurrent()).getUserData();

The Problem

The basic problem in accessing session-global data is that the getUI() method works only after the component has been attached to the application. Before that, it returns null. This is the case in constructors of components, such as a CustomComponent:

Using a static variable or a singleton implemented with such to give a global access to user session data is not possible, because static variables are global in the entire web application, not just the user session. This can be handy for communicating data between the concurrent sessions, but creates a problem within a session.

The data would be shared by all users and be reinitialized every time a new user opens the application.

Overview of Solutions

To get the application object or any other global data, you have the following solutions:

  • Pass a reference to the global data as a parameter

  • Initialize components in attach() method

  • Initialize components in the enter() method of the navigation view (if using navigation)

  • Store a reference to global data using the ThreadLocal Pattern

Each solution is described in the following sections.

11.15.1. Passing References Around

You can pass references to objects as parameters. This is the normal way in object-oriented programming.

class MyApplication extends Application {
    UserData userData;

    public void init() {
        Window mainWindow = new Window("My Window");
        setMainWindow(mainWindow);

        userData = new UserData();
        
        mainWindow.addComponent(new MyComponent(this));
    }

    public UserData getUserData() {
        return userData;
    }
}

class MyComponent extends CustomComponent {
    public MyComponent(MyApplication app) {
        Label label = new Label("Name: " +
            app.getUserData().getName());

        setCompositionRoot(label);
    }
}

If you need the reference in other methods, you either have to pass it again as a parameter or store it in a member variable.

The problem with this solution is that practically all constructors in the application need to get a reference to the application object, and passing it further around in the classes is another hard task.

11.15.2. Overriding attach()

The attach() method is called when the component is attached to the application component through containment hierarchy. The getApplication() method always works.

class MyComponent extends CustomComponent {
    public MyComponent() {
        // Must set a dummy root in constructor
        setCompositionRoot(new Label(""));
    }

    @Override
    public void attach() {    
        Label label = new Label("Name: " +
            ((MyApplication)component.getApplication())
                .getUserData().getName());

        setCompositionRoot(label);
    }
}

While this solution works, it is slightly messy. You may need to do some initialization in the constructor, but any construction requiring the global data must be done in the attach() method. Especially, CustomComponent requires that the setCompositionRoot() method is called in the constructor. If you can't create the actual composition root component in the constructor, you need to use a temporary dummy root, as is done in the example above.

Using getApplication() also needs casting if you want to use methods defined in your application class.

11.15.3. ThreadLocal Pattern

Vaadin uses the ThreadLocal pattern for allowing global access to the UI, and Page objects of the currently processed server request with a static getCurrent() method in all the respective classes. This section explains why the pattern is used in Vaadin and how it works. You may also need to reimplement the pattern for some purpose.

The ThreadLocal pattern gives a solution to the global access problem by solving two sub-problems of static variables.

As the first problem, assume that the servlet container processes requests for many users (sessions) sequentially. If a static variable is set in a request belonging one user, it could be read or re-set by the next incoming request belonging to another user. This can be solved by setting the global reference at the beginning of each HTTP request to point to data of the current user, as illustrated in Figure 11.13.

Figure 11.13. Switching a static (or ThreadLocal) reference during sequential processing of requests

Switching a static (or ThreadLocal) reference during sequential processing of requests

The second problem is that servlet containers typically do thread pooling with multiple worker threads that process requests. Therefore, setting a static reference would change it in all threads running concurrently, possibly just when another thread is processing a request for another user. The solution is to store the reference in a thread-local variable instead of a static. You can do so by using the ThreadLocal class in Java for the switch reference.

Figure 11.14. Switching ThreadLocal references during concurrent processing of requests

Switching ThreadLocal references during concurrent processing of requests

Preface
I. Introduction
1. Introduction
1.1. Overview
1.2. Example Application Walkthrough
1.3. Support for the Eclipse IDE
1.4. Goals and Philosophy
1.5. Background
2. Getting Started with Vaadin
2.1. Overview
2.2. Setting up the Development Environment
2.3. Overview of Vaadin Libraries
2.4. Installing Vaadin Plugin for Eclipse
2.5. Creating and Running a Project with Eclipse
2.6. Using Vaadin with Maven
2.7. Creating a Project with NetBeans IDE
2.8. Creating a Project with IntelliJ IDEA
2.9. Vaadin Installation Package
2.10. Using Vaadin with Scala
3. Architecture
3.1. Overview
3.2. Technological Background
3.3. Client-Side Engine
3.4. Events and Listeners
II. Server-Side Framework
4. Writing a Server-Side Web Application
4.1. Overview
4.2. Building the UI
4.3. Handling Events with Listeners
4.4. Images and Other Resources
4.5. Handling Errors
4.6. Notifications
4.7. Application Lifecycle
4.8. Deploying an Application
5. User Interface Components
5.1. Overview
5.2. Interfaces and Abstractions
5.3. Common Component Features
5.4. Field Components
5.5. Component Extensions
5.6. Label
5.7. Link
5.8. TextField
5.9. TextArea
5.10. PasswordField
5.11. RichTextArea
5.12. Date and Time Input with DateField
5.13. Button
5.14. CheckBox
5.15. Selecting Items
5.16. Table
5.17. Tree
5.18. MenuBar
5.19. Embedded Resources
5.20. Upload
5.21. ProgressBar
5.22. Slider
5.23. Calendar
5.24. Component Composition with CustomComponent
5.25. Composite Fields with CustomField
6. Managing Layout
6.1. Overview
6.2. UI, Window, and Panel Content
6.3. VerticalLayout and HorizontalLayout
6.4. GridLayout
6.5. FormLayout
6.6. Panel
6.7. Sub-Windows
6.8. HorizontalSplitPanel and VerticalSplitPanel
6.9. TabSheet
6.10. Accordion
6.11. AbsoluteLayout
6.12. CssLayout
6.13. Layout Formatting
6.14. Custom Layouts
7. Visual User Interface Design with Eclipse
7.1. Overview
7.2. Creating a New Composite
7.3. Using The Visual Editor
7.4. Structure of a Visually Editable Component
8. Themes
8.1. Overview
8.2. Introduction to Cascading Style Sheets
8.3. Syntactically Awesome Stylesheets (Sass)
8.4. Creating and Using Themes
8.5. Creating a Theme in Eclipse
8.6. Responsive Themes
9. Binding Components to Data
9.1. Overview
9.2. Properties
9.3. Holding properties in Items
9.4. Creating Forms by Binding Fields to Items
9.5. Collecting Items in Containers
10. Vaadin SQLContainer
10.1. Architecture
10.2. Getting Started with SQLContainer
10.3. Filtering and Sorting
10.4. Editing
10.5. Caching, Paging and Refreshing
10.6. Referencing Another SQLContainer
10.7. Using FreeformQuery and FreeformStatementDelegate
10.8. Non-implemented methods of Vaadin container interfaces
10.9. Known Issues and Limitations
11. Advanced Web Application Topics
11.1. Handling Browser Windows
11.2. Embedding UIs in Web Pages
11.3. Debug Mode and Window
11.4. Request Handlers
11.5. Shortcut Keys
11.6. Printing
11.7. Google App Engine Integration
11.8. Common Security Issues
11.9. Navigating in an Application
11.10. Advanced Application Architectures
11.11. Managing URI Fragments
11.12. Drag and Drop
11.13. Logging
11.14. JavaScript Interaction
11.15. Accessing Session-Global Data
11.16. Server Push
12. Portal Integration
12.1. Overview
12.2. Creating a Portlet Project in Eclipse
12.3. Portlet UI
12.4. Deploying to a Portal
12.5. Installing Vaadin in Liferay
12.6. Handling Portlet Requests
12.7. Handling Portlet Mode Changes
12.8. Non-Vaadin Portlet Modes
12.9. Vaadin IPC for Liferay
III. Client-Side Framework
13. Client-Side Vaadin Development
13.1. Overview
13.2. Installing the Client-Side Development Environment
13.3. Client-Side Module Descriptor
13.4. Compiling a Client-Side Module
13.5. Creating a Custom Widget
13.6. Debugging Client-Side Code
14. Client-Side Applications
14.1. Overview
14.2. Client-Side Module Entry-Point
14.3. Compiling and Running a Client-Side Application
14.4. Loading a Client-Side Application
15. Client-Side Widgets
15.1. Overview
15.2. GWT Widgets
15.3. Vaadin Widgets
16. Integrating with the Server-Side
16.1. Overview
16.2. Starting It Simple With Eclipse
16.3. Creating a Server-Side Component
16.4. Integrating the Two Sides with a Connector
16.5. Shared State
16.6. RPC Calls Between Client- and Server-Side
16.7. Component and UI Extensions
16.8. Styling a Widget
16.9. Component Containers
16.10. Creating Add-ons
16.11. Migrating from Vaadin 6
16.12. Integrating JavaScript Components and Extensions
IV. Vaadin Add-ons
17. Using Vaadin Add-ons
17.1. Overview
17.2. Downloading Add-ons from Vaadin Directory
17.3. Installing Add-ons in Eclipse with Ivy
17.4. Using Add-ons in a Maven Project
17.5. Troubleshooting
18. Vaadin Charts
18.1. Overview
18.2. Installing Vaadin Charts
18.3. Basic Use
18.4. Chart Types
18.5. Chart Configuration
18.6. Chart Data
18.7. Advanced Uses
18.8. Timeline
19. Vaadin JPAContainer
19.1. Overview
19.2. Installing
19.3. Defining a Domain Model
19.4. Basic Use of JPAContainer
19.5. Entity Providers
19.6. Filtering JPAContainer
19.7. Querying with the Criteria API
19.8. Automatic Form Generation
19.9. Using JPAContainer with Hibernate
20. Mobile Applications with TouchKit
20.1. Overview
20.2. Considerations Regarding Mobile Browsing
20.3. Installing Vaadin TouchKit
20.4. Importing the Vornitologist Demo
20.5. Creating a New TouchKit Project
20.6. Elements of a TouchKit Application
20.7. Mobile User Interface Components
20.8. Advanced Mobile Features
20.9. Offline Mode
20.10. Building an Optimized Widget Set
20.11. Testing and Debugging on Mobile Devices
21. Vaadin TestBench
21.1. Overview
21.2. Installing Vaadin TestBench
21.3. Preparing an Application for Testing
21.4. Using Vaadin TestBench Recorder
21.5. Developing JUnit Tests
21.6. Taking and Comparing Screenshots
21.7. Running Tests in a Distributed Environment
21.8. Headless Testing
21.9. Known Issues
A. Songs of Vaadin
Index