├── addressbook ├── .gitignore ├── addressbook_screenshot.png ├── src │ └── main │ │ ├── resources │ │ └── com │ │ │ └── vaadin │ │ │ └── tutorial │ │ │ └── addressbook │ │ │ ├── MainLayout.html │ │ │ ├── LeftPanel.html │ │ │ └── ContactForm.html │ │ └── java │ │ └── com │ │ └── vaadin │ │ └── tutorial │ │ └── addressbook │ │ ├── AddressbookUI.java │ │ ├── MainLayout.java │ │ ├── backend │ │ ├── Contact.java │ │ └── ContactService.java │ │ ├── LeftPanel.java │ │ └── ContactForm.java ├── pom.xml └── README.md ├── tree-database-example ├── screenshot.png ├── src │ └── main │ │ ├── java │ │ └── org │ │ │ └── vaadin │ │ │ └── example │ │ │ └── treegrid │ │ │ └── jdbc │ │ │ ├── pojo │ │ │ ├── Company.java │ │ │ ├── Department.java │ │ │ ├── NamedItem.java │ │ │ └── Person.java │ │ │ ├── DBEngine.java │ │ │ ├── TreeUI.java │ │ │ └── PeopleDataProvider.java │ │ └── resources │ │ └── org │ │ └── vaadin │ │ └── example │ │ └── treegrid │ │ └── jdbc │ │ └── db_ddl.sql └── README.md ├── .travis.before_install.sh ├── spring-demo ├── spring-demo-ui │ ├── src │ │ ├── main │ │ │ ├── webapp │ │ │ │ └── VAADIN │ │ │ │ │ └── themes │ │ │ │ │ └── mytheme │ │ │ │ │ ├── favicon.ico │ │ │ │ │ ├── img │ │ │ │ │ ├── table-logo.png │ │ │ │ │ └── archetype-login-bg.jpg │ │ │ │ │ ├── addons.scss │ │ │ │ │ ├── layouts │ │ │ │ │ └── aboutview.html │ │ │ │ │ └── styles.scss │ │ │ ├── resources │ │ │ │ ├── application.properties │ │ │ │ └── com │ │ │ │ │ └── vaadin │ │ │ │ │ └── framework8 │ │ │ │ │ └── samples │ │ │ │ │ └── crud │ │ │ │ │ └── ProductFormDesign.html │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── vaadin │ │ │ │ └── framework8 │ │ │ │ └── samples │ │ │ │ ├── authentication │ │ │ │ ├── AccessControl.java │ │ │ │ ├── BasicAccessControl.java │ │ │ │ ├── CurrentUser.java │ │ │ │ └── LoginScreen.java │ │ │ │ ├── crud │ │ │ │ ├── ProductDataProvider.java │ │ │ │ ├── ProductFormDesign.java │ │ │ │ ├── EuroConverter.java │ │ │ │ ├── ProductGrid.java │ │ │ │ ├── SampleCrudLogic.java │ │ │ │ ├── ProductDataProviderImpl.java │ │ │ │ ├── SampleCrudView.java │ │ │ │ └── ProductForm.java │ │ │ │ ├── ErrorView.java │ │ │ │ ├── about │ │ │ │ └── AboutView.java │ │ │ │ ├── SampleApplication.java │ │ │ │ ├── SampleUI.java │ │ │ │ └── Menu.java │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── vaadin │ │ │ └── framework8 │ │ │ └── samples │ │ │ └── TestConfig.java │ └── pom.xml ├── spring-demo-backend │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── vaadin │ │ │ │ └── framework8 │ │ │ │ └── samples │ │ │ │ └── backend │ │ │ │ ├── data │ │ │ │ ├── Availability.java │ │ │ │ ├── Category.java │ │ │ │ └── Product.java │ │ │ │ ├── repository │ │ │ │ ├── CategoryRepository.java │ │ │ │ └── ProductRepository.java │ │ │ │ ├── DataService.java │ │ │ │ └── MockDataGenerator.java │ │ └── test │ │ │ └── java │ │ │ └── com │ │ │ └── vaadin │ │ │ └── framework8 │ │ │ └── samples │ │ │ └── backend │ │ │ ├── TestConfig.java │ │ │ └── DataServiceTest.java │ └── pom.xml ├── pom.xml └── README.md ├── todomvc ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── vaadin │ │ │ │ └── tutorial │ │ │ │ └── todomvc │ │ │ │ ├── TodoView.java │ │ │ │ ├── TaskFilter.java │ │ │ │ ├── TodoPresenter.java │ │ │ │ ├── TodoMvcUI.java │ │ │ │ ├── Todo.java │ │ │ │ ├── PreparedJDBCDataProvider.java │ │ │ │ ├── SimpleJDBCDataProvider.java │ │ │ │ ├── TodoJDBCDataProvider.java │ │ │ │ ├── AbstractJDBCDataProvider.java │ │ │ │ └── TodoModel.java │ │ └── webapp │ │ │ └── VAADIN │ │ │ └── themes │ │ │ └── todo │ │ │ └── styles.scss │ └── test │ │ └── java │ │ └── com │ │ └── vaadin │ │ └── tutorial │ │ └── todomvc │ │ └── TestDataProviderLimits.java ├── README.md └── pom.xml ├── registration-form ├── src │ └── main │ │ ├── webapp │ │ └── VAADIN │ │ │ └── themes │ │ │ └── registration │ │ │ ├── addons.scss │ │ │ ├── styles.scss │ │ │ └── registration.scss │ │ └── java │ │ └── com │ │ └── vaadin │ │ └── demo │ │ └── registration │ │ ├── Person.java │ │ ├── PasswordValidator.java │ │ ├── EmailOrPhoneValidator.java │ │ └── RegistrationFormUI.java └── pom.xml ├── .travis.yml ├── .gitignore ├── rest-json-dataprovider-demo ├── README.md ├── pom.xml └── src │ ├── test │ └── java │ │ └── com │ │ └── vaadin │ │ └── framework8 │ │ └── demo │ │ └── restjson │ │ └── RestDemoIT.java │ └── main │ └── java │ └── com │ └── vaadin │ └── framework8 │ └── demo │ └── restjson │ ├── RESTDemoUI.java │ └── RestDataProvider.java ├── rest-dataprovider-demo ├── README.md ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── vaadin │ │ │ └── framework8 │ │ │ └── demo │ │ │ └── rest │ │ │ ├── model │ │ │ ├── PersonsWrapper.java │ │ │ ├── Name.java │ │ │ ├── Address.java │ │ │ └── Person.java │ │ │ ├── backend │ │ │ └── PersonService.java │ │ │ └── RESTDemoUI.java │ └── test │ │ └── java │ │ └── com │ │ └── vaadin │ │ └── framework8 │ │ └── demo │ │ └── rest │ │ └── RestDemoIT.java └── pom.xml ├── .travis.script.sh └── test-util ├── pom.xml └── src └── main └── java └── com └── vaadin └── demo └── testutil └── FixedPhantomJSDriver.java /addressbook/.gitignore: -------------------------------------------------------------------------------- 1 | addressbook.iml 2 | target 3 | -------------------------------------------------------------------------------- /tree-database-example/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaadin/framework8-demo/HEAD/tree-database-example/screenshot.png -------------------------------------------------------------------------------- /addressbook/addressbook_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vaadin/framework8-demo/HEAD/addressbook/addressbook_screenshot.png -------------------------------------------------------------------------------- /.travis.before_install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Disable all Travis default repositories 4 | sed -i "s/activeByDefault>truefalse 2 | 3 | 4 | 5 | 6 | 7 | 8 |

About

9 | 10 |
11 | 12 | Vaadin web page 13 | 14 | 15 | -------------------------------------------------------------------------------- /registration-form/src/main/webapp/VAADIN/themes/registration/styles.scss: -------------------------------------------------------------------------------- 1 | @import "addons.scss"; 2 | @import "registration.scss"; 3 | 4 | /* This file prefixes all rules with the theme name to avoid causing conflicts with other themes. */ 5 | /* The actual styles should be defined in v7_projet.scss */ 6 | .registration { 7 | @include addons; 8 | @include registration; 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | db/ 2 | # Eclipse 3 | .classpath 4 | .project 5 | .settings 6 | 7 | # / 8 | /.cvsignore 9 | /work 10 | 11 | # /tests/ 12 | /tests/junit*.properties 13 | 14 | # /bin/ 15 | /bin 16 | 17 | # Mac 18 | *.DS_Store 19 | 20 | # build result folders 21 | */result 22 | result 23 | target/ 24 | 25 | .sass-cache 26 | phantomjsdriver.log 27 | 28 | *.iml 29 | .idea 30 | 31 | */.checkstyle 32 | 33 | *.scss.cache 34 | 35 | */error-screenshots/* 36 | -------------------------------------------------------------------------------- /rest-json-dataprovider-demo/README.md: -------------------------------------------------------------------------------- 1 | Vaadin 8 Simple REST Data Provider Demo 2 | ==================== 3 | 4 | A short demonstration of how Vaadin 8 can be used to bind data from a REST API directly to a listing component. 5 | 6 | Running the example 7 | ------------------- 8 | The example can be run from the command line with the following command 9 | 10 | ``` 11 | $ mvn clean install jetty:run 12 | ``` 13 | 14 | after which the application is accessible at http://localhost:8888/ 15 | -------------------------------------------------------------------------------- /rest-dataprovider-demo/README.md: -------------------------------------------------------------------------------- 1 | Vaadin 8 + JAX-RS REST Data Provider Demo 2 | ==================== 3 | 4 | A short demonstration of how Vaadin 8 can be used to bind data from a REST API directly to a listing component. 5 | 6 | 7 | Running the example 8 | ------------------- 9 | The example can be run from the command line with the following command 10 | 11 | ``` 12 | $ mvn clean install jetty:run 13 | ``` 14 | 15 | after which the application is accessible at http://localhost:8888/ 16 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-backend/src/main/java/com/vaadin/framework8/samples/backend/data/Availability.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.backend.data; 2 | 3 | public enum Availability { 4 | COMING("Coming"), AVAILABLE("Available"), DISCONTINUED("Discontinued"); 5 | 6 | private final String name; 7 | 8 | private Availability(String name) { 9 | this.name = name; 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return name; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/webapp/VAADIN/themes/mytheme/styles.scss: -------------------------------------------------------------------------------- 1 | @import "mytheme.scss"; 2 | @import "addons.scss"; 3 | 4 | // This should be in the Valo theme as a shorthand 5 | $v-layout-margin: $v-layout-margin-top $v-layout-margin-right $v-layout-margin-bottom $v-layout-margin-left !default; 6 | 7 | // This file prefixes all rules with the theme name to avoid causing conflicts with other themes. 8 | // The actual styles should be defined in mytheme.scss 9 | 10 | .mytheme { 11 | @include addons; 12 | @include mytheme; 13 | } 14 | -------------------------------------------------------------------------------- /rest-dataprovider-demo/src/main/java/com/vaadin/framework8/demo/rest/model/PersonsWrapper.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.demo.rest.model; 2 | 3 | import java.util.List; 4 | 5 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 6 | 7 | @JsonIgnoreProperties(ignoreUnknown = true) 8 | public class PersonsWrapper { 9 | 10 | List results; 11 | 12 | public List getResults() { 13 | return results; 14 | } 15 | 16 | public void setResults(List result) { 17 | results = result; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/authentication/AccessControl.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.authentication; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Simple interface for authentication and authorization checks. 7 | */ 8 | public interface AccessControl extends Serializable { 9 | 10 | public boolean signIn(String username, String password); 11 | 12 | public boolean isUserSignedIn(); 13 | 14 | public boolean isUserInRole(String role); 15 | 16 | public String getPrincipalName(); 17 | } 18 | -------------------------------------------------------------------------------- /addressbook/src/main/resources/com/vaadin/tutorial/addressbook/MainLayout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tree-database-example/src/main/java/org/vaadin/example/treegrid/jdbc/pojo/Company.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.example.treegrid.jdbc.pojo; 2 | 3 | /** 4 | * POJO for Company entity 5 | */ 6 | public class Company extends NamedItem { 7 | private final String name; 8 | private final String email; 9 | 10 | public Company(long id,String name, String email) { 11 | super(id); 12 | this.name = name; 13 | this.email = email; 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public String getEmail() { 22 | return email; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.travis.script.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # TRAVIS_PULL_REQUEST == "false" for a normal branch commit, the PR number for a PR 4 | # TRAVIS_BRANCH == target of normal commit or target of PR 5 | # TRAVIS_SECURE_ENV_VARS == true if encrypted variables are available 6 | # TRAVIS_REPO_SLUG == the repository, e.g. vaadin/framework8-demo 7 | # TESTBENCH_LICENSE == TB4 license, defined as a secure variable in .travis.yml 8 | 9 | if [ "$TRAVIS_SECURE_ENV_VARS" == "true" ] 10 | then 11 | # Secure vars available, needed for TestBench tests 12 | # Pull request inside repository or branch build 13 | mvn -B -e -V -Dvaadin.testbench.developer.license=$TESTBENCH_LICENSE verify 14 | fi 15 | -------------------------------------------------------------------------------- /tree-database-example/src/main/java/org/vaadin/example/treegrid/jdbc/pojo/Department.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.example.treegrid.jdbc.pojo; 2 | 3 | /** 4 | * POJO for Department entity 5 | */ 6 | public class Department extends NamedItem { 7 | private final String name; 8 | private final long companyId; 9 | 10 | public Department(long id, long companyId, String name) { 11 | super(id); 12 | this.name = name; 13 | this.companyId = companyId; 14 | } 15 | 16 | private long getCompanyId() { 17 | return companyId; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tree-database-example/src/main/resources/org/vaadin/example/treegrid/jdbc/db_ddl.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE company ( 2 | company_id BIGINT PRIMARY KEY, 3 | company_name VARCHAR(50) NOT NULL, 4 | company_email VARCHAR(80) NOT NULL 5 | ); 6 | 7 | CREATE TABLE department ( 8 | department_id BIGINT PRIMARY KEY, 9 | company_id BIGINT NOT NULL FOREIGN KEY REFERENCES COMPANY(company_id), 10 | department_name VARCHAR(50) NOT NULL 11 | ); 12 | 13 | CREATE TABLE people ( 14 | id BIGINT PRIMARY KEY, 15 | department_id BIGINT NOT NULL FOREIGN KEY REFERENCES DEPARTMENT(department_id), 16 | first_name VARCHAR(50), 17 | last_name VARCHAR(50), 18 | email VARCHAR(50), 19 | gender VARCHAR(50) 20 | ); 21 | -------------------------------------------------------------------------------- /rest-dataprovider-demo/src/main/java/com/vaadin/framework8/demo/rest/model/Name.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.demo.rest.model; 2 | 3 | public class Name { 4 | 5 | private String first; 6 | private String last; 7 | private String title; 8 | 9 | public String getFirst() { 10 | return first; 11 | } 12 | 13 | public void setFirst(String firstName) { 14 | first = firstName; 15 | } 16 | 17 | public String getLast() { 18 | return last; 19 | } 20 | 21 | public void setLast(String lastName) { 22 | last = lastName; 23 | } 24 | 25 | public String getTitle() { 26 | return title; 27 | } 28 | 29 | public void setTitle(String title) { 30 | this.title = title; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /addressbook/src/main/resources/com/vaadin/tutorial/addressbook/LeftPanel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | New contact 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/crud/ProductDataProvider.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.crud; 2 | 3 | import com.vaadin.data.provider.DataProvider; 4 | import com.vaadin.framework8.samples.backend.data.Product; 5 | 6 | /** 7 | * Interface for ProductDataProvider. 8 | */ 9 | public interface ProductDataProvider extends DataProvider { 10 | 11 | /** 12 | * Store given product to the repository. 13 | * 14 | * @param product 15 | * the updated or new product 16 | */ 17 | public void save(Product product); 18 | 19 | /** 20 | * Delete given product from the repository. 21 | * 22 | * @param product 23 | * the product to be deleted 24 | */ 25 | public void delete(Product product); 26 | } 27 | -------------------------------------------------------------------------------- /tree-database-example/src/main/java/org/vaadin/example/treegrid/jdbc/pojo/NamedItem.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.example.treegrid.jdbc.pojo; 2 | 3 | /** 4 | * Base class for all the entities 5 | */ 6 | public abstract class NamedItem { 7 | private final long id; 8 | 9 | public NamedItem(long id) { 10 | this.id = id; 11 | } 12 | 13 | public long getId() { 14 | return id; 15 | } 16 | 17 | public abstract String getName(); 18 | 19 | @Override 20 | public boolean equals(Object o) { 21 | if (this == o) return true; 22 | if (o == null || getClass() != o.getClass()) return false; 23 | 24 | NamedItem namedItem = (NamedItem) o; 25 | 26 | return id == namedItem.id; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return (int) (id ^ (id >>> 32)); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /registration-form/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.vaadin.framework8 8 | framework8-demo 9 | 8.1.6 10 | 11 | registration-form 12 | war 13 | Registration Form example 14 | 15 | 16 | 17 | com.vaadin.framework8 18 | test-util 19 | test 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tree-database-example/README.md: -------------------------------------------------------------------------------- 1 | tree-database-example 2 | ============== 3 | 4 | Example of using Vaadin [TreeGrid](https://vaadin.com/docs/-/part/framework/components/components-treegrid.html) and 5 | [Tree](https://vaadin.com/docs/-/part/framework/components/components-tree.html) on top of JDBC database connection. 6 | ![Screenshot](screenshot.png)[] 7 | 8 | Workflow 9 | ======== 10 | 11 | To compile the entire project, run "mvn install". 12 | 13 | To run the application, run "mvn jetty:run" and open http://localhost:8080/ . 14 | 15 | To produce a deployable production mode WAR: 16 | - run "mvn clean package" 17 | - test the war file with "mvn jetty:run-war" 18 | 19 | Using Vaadin pre-releases 20 | ------------------------- 21 | 22 | If Vaadin pre-releases are not enabled by default, use the Maven parameter 23 | "-P vaadin-prerelease" or change the activation default value of the profile in pom.xml . 24 | -------------------------------------------------------------------------------- /rest-dataprovider-demo/src/main/java/com/vaadin/framework8/demo/rest/model/Address.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.demo.rest.model; 2 | 3 | public class Address { 4 | 5 | private String street; 6 | private String city; 7 | private String state; 8 | private String postcode; 9 | 10 | public String getStreet() { 11 | return street; 12 | } 13 | 14 | public void setStreet(String street) { 15 | this.street = street; 16 | } 17 | 18 | public String getCity() { 19 | return city; 20 | } 21 | 22 | public void setCity(String city) { 23 | this.city = city; 24 | } 25 | 26 | public String getState() { 27 | return state; 28 | } 29 | 30 | public void setState(String state) { 31 | this.state = state; 32 | } 33 | 34 | public String getPostcode() { 35 | return postcode; 36 | } 37 | 38 | public void setPostcode(String postcode) { 39 | this.postcode = postcode; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /addressbook/src/main/resources/com/vaadin/tutorial/addressbook/ContactForm.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Save 8 | 9 | 10 | Cancel 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /rest-json-dataprovider-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.vaadin.framework8 8 | framework8-demo 9 | 8.1.6 10 | 11 | rest-json-dataprovider-demo 12 | war 13 | Vaadin8 REST dataprovider example using JSON 14 | 15 | 16 | 17 | com.vaadin.framework8 18 | test-util 19 | test 20 | 21 | 22 | commons-io 23 | commons-io 24 | 2.5 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/ErrorView.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples; 2 | 3 | import com.vaadin.navigator.View; 4 | import com.vaadin.navigator.ViewChangeListener; 5 | import com.vaadin.ui.Label; 6 | import com.vaadin.ui.VerticalLayout; 7 | import com.vaadin.ui.themes.ValoTheme; 8 | 9 | /** 10 | * View shown when trying to navigate to a view that does not exist using 11 | * {@link com.vaadin.navigator.Navigator}. 12 | * 13 | * 14 | */ 15 | public class ErrorView extends VerticalLayout implements View { 16 | 17 | private Label explanation; 18 | 19 | public ErrorView() { 20 | Label header = new Label("The view could not be found"); 21 | header.addStyleName(ValoTheme.LABEL_H1); 22 | addComponent(header); 23 | addComponent(explanation = new Label()); 24 | } 25 | 26 | @Override 27 | public void enter(ViewChangeListener.ViewChangeEvent event) { 28 | explanation.setValue(String.format( 29 | "You tried to navigate to a view ('%s') that does not exist.", 30 | event.getViewName())); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test-util/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | Test helpers for demos 6 | 7 | com.vaadin.framework8 8 | framework8-demo 9 | 8.1.6 10 | 11 | test-util 12 | jar 13 | 14 | 15 | true 16 | true 17 | 18 | 19 | 20 | 21 | com.vaadin 22 | vaadin-testbench 23 | 24 | 25 | junit 26 | junit 27 | compile 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /rest-dataprovider-demo/src/test/java/com/vaadin/framework8/demo/rest/RestDemoIT.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.demo.rest; 2 | 3 | import java.util.List; 4 | import java.util.stream.IntStream; 5 | 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.openqa.selenium.WebElement; 10 | 11 | import com.vaadin.demo.testutil.AbstractDemoTest; 12 | import com.vaadin.testbench.By; 13 | 14 | public class RestDemoIT extends AbstractDemoTest { 15 | 16 | @Before 17 | public void setUp() { 18 | open(); 19 | } 20 | 21 | @Test 22 | public void rowHasCorrectData() { 23 | WebElement row = findElements(By.className("v-grid-row")).get(2); 24 | List rowCells = row 25 | .findElements(By.className("v-grid-cell")); 26 | 27 | Assert.assertEquals(7, rowCells.size()); 28 | 29 | String[] data = { "andrea", "johansen", "andrea.johansen@example.com", 30 | "allinge", "7966 ridderhatten", "48559", "nordjylland" }; 31 | IntStream.range(0, 7).forEach(i -> Assert.assertEquals(data[i], 32 | rowCells.get(i).getAttribute("innerHTML"))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /rest-json-dataprovider-demo/src/test/java/com/vaadin/framework8/demo/restjson/RestDemoIT.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.demo.restjson; 2 | 3 | import java.util.List; 4 | import java.util.stream.IntStream; 5 | 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | import org.openqa.selenium.WebElement; 10 | 11 | import com.vaadin.demo.testutil.AbstractDemoTest; 12 | import com.vaadin.testbench.By; 13 | 14 | public class RestDemoIT extends AbstractDemoTest { 15 | 16 | @Before 17 | public void setUp() { 18 | open(); 19 | } 20 | 21 | @Test 22 | public void rowHasCorrectData() { 23 | WebElement row = findElements(By.className("v-grid-row")).get(2); 24 | List rowCells = row 25 | .findElements(By.className("v-grid-cell")); 26 | 27 | Assert.assertEquals(7, rowCells.size()); 28 | 29 | String[] data = { "andrea", "johansen", "andrea.johansen@example.com", 30 | "allinge", "7966 ridderhatten", "48559", "nordjylland" }; 31 | IntStream.range(0, 7).forEach(i -> Assert.assertEquals(data[i], 32 | rowCells.get(i).getAttribute("innerHTML"))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /addressbook/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.vaadin.framework8 8 | framework8-demo 9 | 8.1.6 10 | 11 | addressbook 12 | war 13 | Vaadin Addressbook example 14 | 15 | 16 | 19 | 20 | commons-beanutils 21 | commons-beanutils 22 | 1.9.2 23 | jar 24 | 25 | 26 | com.vaadin.framework8 27 | test-util 28 | test 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /rest-dataprovider-demo/src/main/java/com/vaadin/framework8/demo/rest/model/Person.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.demo.rest.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public class Person { 7 | 8 | private Name name; 9 | private Address location; 10 | private String email; 11 | 12 | public void setName(Name name) { 13 | this.name = name; 14 | } 15 | 16 | public void setLocation(Address location) { 17 | this.location = location; 18 | } 19 | 20 | public void setEmail(String email) { 21 | this.email = email; 22 | } 23 | 24 | public String getFirstName() { 25 | return name.getFirst(); 26 | } 27 | 28 | public String getLastName() { 29 | return name.getLast(); 30 | } 31 | 32 | public String getStreet() { 33 | return location.getStreet(); 34 | } 35 | 36 | public String getPostCode() { 37 | return location.getPostcode(); 38 | } 39 | 40 | public String getCity() { 41 | return location.getCity(); 42 | } 43 | 44 | public String getState() { 45 | return location.getState(); 46 | } 47 | 48 | public String getEmail() { 49 | return email; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tree-database-example/src/main/java/org/vaadin/example/treegrid/jdbc/pojo/Person.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.example.treegrid.jdbc.pojo; 2 | 3 | /** 4 | * POJO for Person entity 5 | */ 6 | public class Person extends NamedItem { 7 | 8 | private final long departmentId; 9 | private final String firstName; 10 | private final String lastName; 11 | private final String email; 12 | private final String gender; 13 | 14 | public Person(long id,long departmentId, String firstName, String lastName, String email, String gender) { 15 | super(id); 16 | this.departmentId = departmentId; 17 | this.firstName = firstName; 18 | this.lastName = lastName; 19 | this.email = email; 20 | this.gender = gender; 21 | } 22 | 23 | public String getFirstName() { 24 | return firstName; 25 | } 26 | 27 | public String getLastName() { 28 | return lastName; 29 | } 30 | 31 | public String getEmail() { 32 | return email; 33 | } 34 | 35 | public String getGender() { 36 | return gender; 37 | } 38 | 39 | public long getDepartmentId() { 40 | return departmentId; 41 | } 42 | 43 | @Override 44 | public String getName() { 45 | return getFirstName() + " " + getLastName(); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /todomvc/src/main/java/com/vaadin/tutorial/todomvc/TaskFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.tutorial.todomvc; 17 | 18 | /** 19 | * Task state 20 | * 21 | * @author Vaadin Ltd 22 | */ 23 | public enum TaskFilter { 24 | ALL { 25 | @Override 26 | public String getText() { 27 | return "All"; 28 | } 29 | }, 30 | ACTIVE { 31 | @Override 32 | public String getText() { 33 | return "Active"; 34 | } 35 | }, 36 | COMPLETED { 37 | @Override 38 | public String getText() { 39 | return "Completed"; 40 | } 41 | }; 42 | 43 | public abstract String getText(); 44 | } 45 | -------------------------------------------------------------------------------- /todomvc/README.md: -------------------------------------------------------------------------------- 1 | # Vaadin Framework • [TodoMVC](http://todomvc.com) 2 | 3 | Vaadin is a Java framework for building modern web applications that look great, perform well and make you and your users happy. 4 | 5 | With Vaadin Framework, you'll use a familiar component based approach to build awesome single page web apps faster than with any other UI framework. Forget complex web technologies and just use Java or any other JVM language. Only a browser is needed to access your application - no plugins required. 6 | 7 | ## Resources 8 | 9 | - [Vaadin Framework](https://vaadin.com/framework) 10 | - [Documentation](https://vaadin.com/docs/-/part/framework/introduction/intro-overview.html) 11 | - [Tutorial](https://github.com/vaadin/addressbook) 12 | 13 | 14 | ### Support 15 | 16 | - [Forum](https://vaadin.com/forum) 17 | - [Twitter](http://twitter.com/vaadin) 18 | - [Google+](https://plus.google.com/u/0/communities/108116678608923665301) 19 | - [Stack Overflow](http://stackoverflow.com/questions/tagged/vaadin) 20 | 21 | ## Implementation 22 | 23 | TODO 24 | 25 | Please note this example uses and requires Java 8 to work. 26 | 27 | Running the example from the command line (requires [Maven](https://maven.apache.org/)) 28 | ------------------- 29 | ``` 30 | $ mvn jetty:run 31 | ``` 32 | 33 | Open [http://localhost:8080/](http://localhost:8080/) -------------------------------------------------------------------------------- /rest-dataprovider-demo/src/main/java/com/vaadin/framework8/demo/rest/backend/PersonService.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.demo.rest.backend; 2 | 3 | import java.util.stream.Stream; 4 | 5 | import javax.ws.rs.client.ClientBuilder; 6 | import javax.ws.rs.client.WebTarget; 7 | import javax.ws.rs.core.MediaType; 8 | 9 | import org.glassfish.jersey.jackson.JacksonFeature; 10 | 11 | import com.vaadin.framework8.demo.rest.model.Person; 12 | import com.vaadin.framework8.demo.rest.model.PersonsWrapper; 13 | 14 | public class PersonService { 15 | 16 | private final static PersonService instance = new PersonService(); 17 | 18 | private final static WebTarget resource = ClientBuilder.newBuilder() 19 | .register(JacksonFeature.class).build() 20 | .target("https://randomuser.me/api/1.1/"); 21 | 22 | public static PersonService getInstance() { 23 | return instance; 24 | } 25 | 26 | public Stream fetchPeople(int offset, int num) { 27 | PersonsWrapper res = resource.queryParam("seed", 0) 28 | .queryParam("results", 200).queryParam("page", 1) 29 | .request(MediaType.APPLICATION_JSON).get(PersonsWrapper.class); 30 | return res.getResults().stream(); 31 | } 32 | 33 | public static int getPersonCount() { 34 | return 200; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/resources/com/vaadin/framework8/samples/crud/ProductFormDesign.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Save 15 | Discard 16 | Cancel 17 | Delete 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/test/java/com/vaadin/framework8/samples/TestConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.framework8.samples; 17 | 18 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 19 | import org.springframework.boot.autoconfigure.SpringBootApplication; 20 | import org.springframework.context.annotation.ComponentScan; 21 | import org.springframework.context.annotation.Configuration; 22 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 23 | 24 | /** 25 | * @author Vaadin Ltd 26 | * 27 | */ 28 | @Configuration 29 | @EnableAutoConfiguration 30 | @SpringBootApplication 31 | @EnableJpaRepositories 32 | @ComponentScan 33 | public class TestConfig { 34 | 35 | } 36 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-backend/src/test/java/com/vaadin/framework8/samples/backend/TestConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.framework8.samples.backend; 17 | 18 | import org.springframework.boot.SpringBootConfiguration; 19 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 20 | import org.springframework.context.annotation.ComponentScan; 21 | import org.springframework.context.annotation.Configuration; 22 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 23 | 24 | /** 25 | * @author Vaadin Ltd 26 | * 27 | */ 28 | @Configuration 29 | @EnableAutoConfiguration 30 | @SpringBootConfiguration 31 | @EnableJpaRepositories 32 | @ComponentScan 33 | public class TestConfig { 34 | 35 | } 36 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/authentication/BasicAccessControl.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.authentication; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | /** 6 | * Default mock implementation of {@link AccessControl}. This implementation 7 | * accepts any string as a password, and considers the user "admin" as the only 8 | * administrator. 9 | */ 10 | @Component 11 | public class BasicAccessControl implements AccessControl { 12 | 13 | @Override 14 | public boolean signIn(String username, String password) { 15 | if (username == null || username.isEmpty()) { 16 | return false; 17 | } 18 | 19 | CurrentUser.set(username); 20 | return true; 21 | } 22 | 23 | @Override 24 | public boolean isUserSignedIn() { 25 | return !CurrentUser.get().isEmpty(); 26 | } 27 | 28 | @Override 29 | public boolean isUserInRole(String role) { 30 | if ("admin".equals(role)) { 31 | // Only the "admin" user is in the "admin" role 32 | return getPrincipalName().equals("admin"); 33 | } 34 | 35 | // All users are in all non-admin roles 36 | return true; 37 | } 38 | 39 | @Override 40 | public String getPrincipalName() { 41 | return CurrentUser.get(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-backend/src/main/java/com/vaadin/framework8/samples/backend/repository/CategoryRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.framework8.samples.backend.repository; 17 | 18 | import java.util.List; 19 | 20 | import org.springframework.data.jpa.repository.JpaRepository; 21 | 22 | import com.vaadin.framework8.samples.backend.data.Category; 23 | 24 | /** 25 | * Category domain specific repository. Provides an interface to access to 26 | * Category entities via JPA. 27 | * 28 | * @see JpaRepository 29 | * 30 | * @author Vaadin Ltd 31 | * 32 | */ 33 | public interface CategoryRepository extends JpaRepository { 34 | 35 | List findAllByNameContainingIgnoreCase(String name); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/crud/ProductFormDesign.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.crud; 2 | 3 | import com.vaadin.annotations.AutoGenerated; 4 | import com.vaadin.annotations.DesignRoot; 5 | import com.vaadin.framework8.samples.backend.data.Availability; 6 | import com.vaadin.framework8.samples.backend.data.Category; 7 | import com.vaadin.ui.Button; 8 | import com.vaadin.ui.CheckBoxGroup; 9 | import com.vaadin.ui.ComboBox; 10 | import com.vaadin.ui.CssLayout; 11 | import com.vaadin.ui.TextField; 12 | import com.vaadin.ui.declarative.Design; 13 | 14 | /** 15 | * !! DO NOT EDIT THIS FILE !! 16 | * 17 | * This class is generated by Vaadin Designer and will be overwritten. 18 | * 19 | * Please make a subclass with logic and additional interfaces as needed, e.g 20 | * class LoginView extends LoginDesign implements View { … } 21 | */ 22 | @DesignRoot 23 | @AutoGenerated 24 | @SuppressWarnings("serial") 25 | public class ProductFormDesign extends CssLayout { 26 | protected TextField productName; 27 | protected TextField price; 28 | protected TextField stockCount; 29 | protected ComboBox availability; 30 | protected CheckBoxGroup category; 31 | protected Button save; 32 | protected Button discard; 33 | protected Button cancel; 34 | protected Button delete; 35 | 36 | public ProductFormDesign() { 37 | Design.read(this); 38 | } 39 | } -------------------------------------------------------------------------------- /rest-dataprovider-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.vaadin.framework8 8 | framework8-demo 9 | 8.1.6 10 | 11 | rest-dataprovider-demo 12 | war 13 | Vaadin8 REST dataprovider example 14 | 15 | 16 | 17 | com.vaadin.framework8 18 | test-util 19 | test 20 | 21 | 22 | javax.ws.rs 23 | javax.ws.rs-api 24 | 2.0 25 | 26 | 27 | org.glassfish.jersey.core 28 | jersey-client 29 | 2.23.2 30 | 31 | 32 | org.glassfish.jersey.media 33 | jersey-media-json-jackson 34 | 2.23.2 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /registration-form/src/main/java/com/vaadin/demo/registration/Person.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.demo.registration; 17 | 18 | /** 19 | * @author Vaadin Ltd 20 | * 21 | */ 22 | public class Person { 23 | 24 | private String fullName; 25 | 26 | private String emailOrPhone; 27 | 28 | private String password; 29 | 30 | public String getFullName() { 31 | return fullName; 32 | } 33 | 34 | public void setFullName(String fullName) { 35 | this.fullName = fullName; 36 | } 37 | 38 | public String getEmailOrPhone() { 39 | return emailOrPhone; 40 | } 41 | 42 | public void setEmailOrPhone(String emailOrPhone) { 43 | this.emailOrPhone = emailOrPhone; 44 | } 45 | 46 | public String getPassword() { 47 | return password; 48 | } 49 | 50 | public void setPassword(String password) { 51 | this.password = password; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-backend/src/main/java/com/vaadin/framework8/samples/backend/data/Category.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.backend.data; 2 | 3 | import java.io.Serializable; 4 | import java.util.Objects; 5 | 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.Id; 9 | import javax.persistence.Version; 10 | import javax.validation.constraints.NotNull; 11 | 12 | @Entity 13 | public class Category implements Serializable { 14 | 15 | @NotNull 16 | @Id 17 | @GeneratedValue 18 | private int id = -1; 19 | 20 | @Version 21 | private int version; 22 | 23 | @NotNull 24 | private String name; 25 | 26 | public int getId() { 27 | return id; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return getName(); 41 | } 42 | 43 | @Override 44 | public int hashCode() { 45 | return getId(); 46 | } 47 | 48 | @Override 49 | public boolean equals(Object obj) { 50 | if (obj == null) { 51 | return false; 52 | } 53 | if (obj.getClass().equals(Category.class)) { 54 | Category category = (Category) obj; 55 | return category.getId() == getId() && category.version == version 56 | && Objects.equals(category.getName(), getName()); 57 | } 58 | return false; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/about/AboutView.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.about; 2 | 3 | import com.vaadin.icons.VaadinIcons; 4 | import com.vaadin.navigator.View; 5 | import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; 6 | import com.vaadin.shared.Version; 7 | import com.vaadin.shared.ui.ContentMode; 8 | import com.vaadin.spring.annotation.SpringView; 9 | import com.vaadin.ui.Alignment; 10 | import com.vaadin.ui.CustomLayout; 11 | import com.vaadin.ui.Label; 12 | import com.vaadin.ui.VerticalLayout; 13 | 14 | @SpringView(name = AboutView.VIEW_NAME) 15 | public class AboutView extends VerticalLayout implements View { 16 | 17 | public static final String VIEW_NAME = "About"; 18 | 19 | public AboutView() { 20 | CustomLayout aboutContent = new CustomLayout("aboutview"); 21 | aboutContent.setStyleName("about-content"); 22 | 23 | // you can add Vaadin components in predefined slots in the custom 24 | // layout 25 | aboutContent.addComponent( 26 | new Label(VaadinIcons.INFO_CIRCLE.getHtml() 27 | + " This application is using Vaadin " 28 | + Version.getFullVersion(), ContentMode.HTML), 29 | "info"); 30 | 31 | setSizeFull(); 32 | setMargin(false); 33 | setStyleName("about-view"); 34 | addComponent(aboutContent); 35 | setComponentAlignment(aboutContent, Alignment.MIDDLE_CENTER); 36 | } 37 | 38 | @Override 39 | public void enter(ViewChangeEvent event) { 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-backend/src/main/java/com/vaadin/framework8/samples/backend/DataService.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.backend; 2 | 3 | import java.io.Serializable; 4 | import java.util.Collection; 5 | 6 | import javax.transaction.Transactional; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | 11 | import com.vaadin.framework8.samples.backend.data.Category; 12 | import com.vaadin.framework8.samples.backend.data.Product; 13 | import com.vaadin.framework8.samples.backend.repository.CategoryRepository; 14 | import com.vaadin.framework8.samples.backend.repository.ProductRepository; 15 | 16 | /** 17 | * Back-end service interface for retrieving and updating product data. 18 | */ 19 | @Service 20 | @Transactional 21 | public class DataService implements Serializable { 22 | 23 | @Autowired 24 | private ProductRepository productRepository; 25 | 26 | @Autowired 27 | private CategoryRepository categoryRepository; 28 | 29 | public Collection getAllProducts() { 30 | return productRepository.findAll(); 31 | } 32 | 33 | public Collection getAllCategories() { 34 | return categoryRepository.findAll(); 35 | } 36 | 37 | public Product updateProduct(Product product) { 38 | return productRepository.save(product); 39 | } 40 | 41 | public void deleteProduct(int productId) { 42 | productRepository.delete(productId); 43 | } 44 | 45 | public Product getProduct(int productId) { 46 | return productRepository.findOne(productId); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /todomvc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.vaadin.framework8 8 | framework8-demo 9 | 8.1.6 10 | 11 | todomvc 12 | war 13 | Vaadin TodoMVC demo 14 | 15 | 16 | 19 | 20 | commons-beanutils 21 | commons-beanutils 22 | 1.9.2 23 | jar 24 | 25 | 26 | com.vaadin.framework8 27 | test-util 28 | test 29 | 30 | 31 | org.hsqldb 32 | hsqldb 33 | 2.3.4 34 | 35 | 36 | org.apache.commons 37 | commons-dbcp2 38 | 2.1.1 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/SampleApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.framework8.samples; 17 | 18 | import org.springframework.boot.SpringApplication; 19 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | import org.springframework.boot.web.support.SpringBootServletInitializer; 22 | import org.springframework.context.annotation.ComponentScan; 23 | import org.springframework.context.annotation.Configuration; 24 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 25 | 26 | /** 27 | * @author Vaadin Ltd 28 | * 29 | */ 30 | @SpringBootApplication 31 | @Configuration 32 | @EnableAutoConfiguration 33 | @EnableJpaRepositories 34 | @ComponentScan 35 | public class SampleApplication extends SpringBootServletInitializer { 36 | 37 | public static void main(String[] args) { 38 | SpringApplication.run(SampleApplication.class, args); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/crud/EuroConverter.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.crud; 2 | 3 | import java.math.BigDecimal; 4 | import java.text.DecimalFormat; 5 | import java.text.NumberFormat; 6 | import java.util.Locale; 7 | 8 | import com.vaadin.data.Result; 9 | import com.vaadin.data.ValueContext; 10 | import com.vaadin.data.converter.StringToBigDecimalConverter; 11 | 12 | /** 13 | * A converter that adds/removes the euro sign and formats currencies with two 14 | * decimal places. 15 | */ 16 | public class EuroConverter extends StringToBigDecimalConverter { 17 | 18 | public EuroConverter() { 19 | super("Cannot convert value to a number"); 20 | } 21 | 22 | @Override 23 | public Result convertToModel(String value, 24 | ValueContext context) { 25 | value = value.replaceAll("[€\\s]", "").trim(); 26 | if ("".equals(value)) { 27 | value = "0"; 28 | } 29 | return super.convertToModel(value, context); 30 | } 31 | 32 | @Override 33 | public String convertToPresentation(BigDecimal value, 34 | ValueContext context) { 35 | return super.convertToPresentation(value, context) + " €"; 36 | } 37 | 38 | @Override 39 | protected NumberFormat getFormat(Locale locale) { 40 | // Always display currency with two decimals 41 | NumberFormat format = super.getFormat(locale); 42 | if (format instanceof DecimalFormat) { 43 | ((DecimalFormat) format).setMaximumFractionDigits(2); 44 | ((DecimalFormat) format).setMinimumFractionDigits(2); 45 | } 46 | return format; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /todomvc/src/main/java/com/vaadin/tutorial/todomvc/TodoPresenter.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.tutorial.todomvc; 2 | 3 | public class TodoPresenter { 4 | 5 | private TodoView view; 6 | 7 | private TodoModel model = new TodoModel(); 8 | 9 | public TodoPresenter(TodoView view) { 10 | this.view = view; 11 | view.setDataProvider(model.getDataProvider()); 12 | view.updateCounters(model.getCompleted(), model.getActive()); 13 | } 14 | 15 | public void markCompleted(Todo todo, boolean completed) { 16 | todo.setCompleted(completed); 17 | model.persist(todo); 18 | view.updateCounters(model.getCompleted(), model.getActive()); 19 | refreshView(); 20 | } 21 | 22 | public void updateTodo(Todo todo) { 23 | model.persist(todo); 24 | refreshView(); 25 | } 26 | 27 | public void add(Todo todo) { 28 | model.persist(todo); 29 | view.updateCounters(model.getCompleted(), model.getActive()); 30 | 31 | refreshView(); 32 | } 33 | 34 | public void delete(Todo todo) { 35 | model.drop(todo); 36 | view.updateCounters(model.getCompleted(), model.getActive()); 37 | 38 | refreshView(); 39 | } 40 | 41 | public void clearCompleted() { 42 | model.clearCompleted(); 43 | 44 | view.updateCounters(model.getCompleted(), model.getActive()); 45 | refreshView(); 46 | } 47 | 48 | public void markAllCompleted(boolean completed) { 49 | model.markAllCompleted(completed); 50 | view.updateCounters(model.getCompleted(), model.getActive()); 51 | refreshView(); 52 | } 53 | 54 | public void refreshView() { 55 | view.refresh(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /todomvc/src/main/java/com/vaadin/tutorial/todomvc/TodoMvcUI.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.tutorial.todomvc; 2 | 3 | import javax.servlet.annotation.WebServlet; 4 | 5 | import com.vaadin.annotations.Theme; 6 | import com.vaadin.annotations.Title; 7 | import com.vaadin.annotations.VaadinServletConfiguration; 8 | import com.vaadin.server.VaadinRequest; 9 | import com.vaadin.server.VaadinServlet; 10 | import com.vaadin.ui.UI; 11 | 12 | /* User Interface written in Java. 13 | * 14 | * Define the user interface shown on the Vaadin generated web page by extending the UI class. 15 | * By default, a new UI instance is automatically created when the page is loaded. To reuse 16 | * the same instance, add @PreserveOnRefresh. 17 | */ 18 | @Title("TodoMVC") 19 | @Theme("todo") 20 | public class TodoMvcUI extends UI { 21 | 22 | /* 23 | * The "Main method". 24 | * 25 | * This is the entry point method executed to initialize and configure the 26 | * visible user interface. Executed on every browser reload because a new 27 | * instance is created for each web page loaded. 28 | */ 29 | @Override 30 | protected void init(VaadinRequest request) { 31 | setSizeUndefined(); 32 | setContent(new TodoViewImpl()); 33 | } 34 | 35 | /* 36 | * Deployed as a Servlet or Portlet. 37 | * 38 | * You can specify additional servlet parameters like the URI and UI class 39 | * name and turn on production mode when you have finished developing the 40 | * application. 41 | */ 42 | @WebServlet(urlPatterns = "/*") 43 | @VaadinServletConfiguration(ui = TodoMvcUI.class, productionMode = false) 44 | public static class MyUIServlet extends VaadinServlet { 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-backend/src/main/java/com/vaadin/framework8/samples/backend/repository/ProductRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.framework8.samples.backend.repository; 17 | 18 | import java.util.Collection; 19 | import java.util.List; 20 | 21 | import org.springframework.data.domain.Pageable; 22 | import org.springframework.data.jpa.repository.JpaRepository; 23 | 24 | import com.vaadin.framework8.samples.backend.data.Availability; 25 | import com.vaadin.framework8.samples.backend.data.Category; 26 | import com.vaadin.framework8.samples.backend.data.Product; 27 | 28 | /** 29 | * Product domain specific repository. Provides an interface to access to 30 | * Product entities via JPA. 31 | * 32 | * @see JpaRepository 33 | * 34 | * @author Vaadin Ltd 35 | * 36 | */ 37 | public interface ProductRepository extends JpaRepository { 38 | 39 | List findDistinctByProductNameContainingIgnoreCaseOrAvailabilityInOrCategoryIn( 40 | String productName, Collection availability, 41 | Collection category, Pageable page); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /todomvc/src/main/java/com/vaadin/tutorial/todomvc/Todo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.tutorial.todomvc; 17 | 18 | public class Todo { 19 | private int id = -1; 20 | private String text = ""; 21 | private boolean completed = false; 22 | 23 | public Todo() { 24 | 25 | } 26 | 27 | public Todo(int id, String text) { 28 | this.id = id; 29 | this.text = text; 30 | } 31 | 32 | public Todo(String text) { 33 | this.text = text; 34 | } 35 | 36 | public String getText() { 37 | return text; 38 | } 39 | 40 | public void setText(String text) { 41 | this.text = text; 42 | } 43 | 44 | public boolean isCompleted() { 45 | return completed; 46 | } 47 | 48 | public void setCompleted(boolean completed) { 49 | this.completed = completed; 50 | } 51 | 52 | public int getId() { 53 | return id; 54 | } 55 | 56 | public void setId(int id) { 57 | this.id = id; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return String.format("Todo{[%d] %s (%s)}", id, text, 63 | completed ? "Completed" : "Active"); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /registration-form/src/main/webapp/VAADIN/themes/registration/registration.scss: -------------------------------------------------------------------------------- 1 | // Global variable overrides. Must be declared before importing Valo. 2 | 3 | // Defines the plaintext font size, weight and family. Font size affects general component sizing. 4 | //$v-font-size: 16px; 5 | //$v-font-weight: 300; 6 | //$v-font-family: "Open Sans", sans-serif; 7 | 8 | // Defines the border used by all components. 9 | //$v-border: 1px solid (v-shade 0.7); 10 | //$v-border-radius: 4px; 11 | 12 | // Affects the color of some component elements, e.g Button, Panel title, etc 13 | //$v-background-color: hsl(210, 0%, 98%); 14 | // Affects the color of content areas, e.g Panel and Window content, TextField input etc 15 | //$v-app-background-color: $v-background-color; 16 | 17 | // Affects the visual appearance of all components 18 | //$v-gradient: v-linear 8%; 19 | //$v-bevel-depth: 30%; 20 | //$v-shadow-opacity: 5%; 21 | 22 | // Defines colors for indicating status (focus, success, failure) 23 | //$v-focus-color: valo-focus-color(); // Calculates a suitable color automatically 24 | //$v-friendly-color: #2c9720; 25 | //$v-error-indicator-color: #ed473b; 26 | 27 | // For more information, see: https://vaadin.com/book/-/page/themes.valo.html 28 | // Example variants can be copy/pasted from https://vaadin.com/wiki/-/wiki/Main/Valo+Examples 29 | 30 | @import "../valo/valo.scss"; 31 | 32 | @mixin registration { 33 | @include valo; 34 | 35 | .v-label.valid { 36 | display:none; 37 | } 38 | .v-caption-valid { 39 | margin-left:10px; 40 | } 41 | .v-caption-validation-message { 42 | margin-left:10px; 43 | display:inline; 44 | } 45 | .v-label.validation-message { 46 | color:red; 47 | margin-left:10px; 48 | } 49 | .valid .v-label.validation-message { 50 | color:green; 51 | } 52 | .v-icon { 53 | color:red; 54 | } 55 | .valid .v-icon { 56 | color:green; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /registration-form/src/main/java/com/vaadin/demo/registration/PasswordValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.demo.registration; 17 | 18 | import com.vaadin.data.ValidationResult; 19 | import com.vaadin.data.ValueContext; 20 | import com.vaadin.data.validator.StringLengthValidator; 21 | 22 | /** 23 | * @author Vaadin Ltd 24 | * 25 | */ 26 | public class PasswordValidator extends StringLengthValidator { 27 | 28 | public PasswordValidator() { 29 | super("", 6, Integer.MAX_VALUE); 30 | } 31 | 32 | @Override 33 | public ValidationResult apply(String value, ValueContext context) { 34 | ValidationResult result = super.apply(value, context); 35 | if (result.isError()) { 36 | return ValidationResult 37 | .error("Password should contain at least 6 characters"); 38 | } else if (!hasDigit(value) || !hasLetter(value)) { 39 | return ValidationResult 40 | .error("Password must contain a letter and a number"); 41 | } 42 | return result; 43 | } 44 | 45 | private boolean hasDigit(String pwd) { 46 | return pwd.chars().anyMatch(Character::isDigit); 47 | } 48 | 49 | private boolean hasLetter(String pwd) { 50 | return pwd.chars().anyMatch(Character::isLetter); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /todomvc/src/main/webapp/VAADIN/themes/todo/styles.scss: -------------------------------------------------------------------------------- 1 | @import "../valo/valo.scss"; 2 | 3 | .todo { 4 | @include valo; 5 | 6 | .v-grid button { 7 | background: transparent; 8 | border: none; 9 | cursor: text; 10 | font-weight: 300; 11 | outline: none; 12 | text-align: left; 13 | width: 100%; 14 | } 15 | 16 | .v-grid { 17 | background: #fff; 18 | .v-grid-row { 19 | .v-grid-cell { 20 | background: transparent; 21 | border-left-color: transparent; 22 | } 23 | td:first-child, 24 | td:nth-child(3) { 25 | button { 26 | cursor: pointer; 27 | height: inherit; 28 | position: relative; 29 | text-align: center; 30 | } 31 | } 32 | td:first-child button:before { 33 | position: absolute; 34 | top: -2px; 35 | right: 0; 36 | bottom: 0; 37 | left: 0; 38 | content: url('data:image/svg+xml;utf8,'); 39 | } 40 | } 41 | .v-grid-row:hover { 42 | td:nth-child(3) button { 43 | color: #cc9a9a; 44 | } 45 | td:nth-child(3) button:hover { 46 | color: #af5b5e; 47 | } 48 | td:nth-child(3) button:before { 49 | content: 'X'; 50 | font-size: 20px; 51 | } 52 | } 53 | .v-grid-row.done { 54 | td:first-child button:before { 55 | content: url('data:image/svg+xml;utf8,'); 56 | } 57 | 58 | td:nth-child(2) button { 59 | text-decoration: line-through; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /spring-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | framework8-demo 7 | com.vaadin.framework8 8 | 8.1.6 9 | 10 | 11 | spring-demo 12 | pom 13 | spring-demo-parent 14 | 15 | 16 | true 17 | 18 | 19 | 20 | 21 | 22 | com.vaadin 23 | vaadin-bom 24 | ${project.version} 25 | pom 26 | import 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-dependencies 32 | 1.5.1.RELEASE 33 | pom 34 | import 35 | 36 | 37 | org.springframework 38 | spring-framework-bom 39 | 4.3.6.RELEASE 40 | pom 41 | import 42 | 43 | 44 | 45 | 46 | 47 | spring-demo-backend 48 | spring-demo-ui 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /rest-dataprovider-demo/src/main/java/com/vaadin/framework8/demo/rest/RESTDemoUI.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.demo.rest; 2 | 3 | import javax.servlet.annotation.WebServlet; 4 | 5 | import com.vaadin.annotations.Theme; 6 | import com.vaadin.annotations.VaadinServletConfiguration; 7 | import com.vaadin.data.provider.CallbackDataProvider; 8 | import com.vaadin.framework8.demo.rest.backend.PersonService; 9 | import com.vaadin.framework8.demo.rest.model.Person; 10 | import com.vaadin.server.VaadinRequest; 11 | import com.vaadin.server.VaadinServlet; 12 | import com.vaadin.ui.Grid; 13 | import com.vaadin.ui.UI; 14 | import com.vaadin.ui.themes.ValoTheme; 15 | 16 | @Theme(ValoTheme.THEME_NAME) 17 | public class RESTDemoUI extends UI { 18 | 19 | @Override 20 | protected void init(VaadinRequest vaadinRequest) { 21 | Grid personGrid = new Grid<>(); 22 | personGrid.addColumn(Person::getFirstName).setCaption("First name"); 23 | personGrid.addColumn(Person::getLastName).setCaption("Last Name"); 24 | personGrid.addColumn(Person::getEmail).setCaption("Email"); 25 | personGrid.addColumn(Person::getCity).setCaption("City"); 26 | personGrid.addColumn(Person::getStreet).setCaption("Street"); 27 | personGrid.addColumn(Person::getPostCode).setCaption("Postal code"); 28 | personGrid.addColumn(Person::getState).setCaption("State"); 29 | 30 | personGrid 31 | .setDataProvider(new CallbackDataProvider( 32 | query -> PersonService.getInstance().fetchPeople( 33 | query.getOffset(), query.getLimit()), 34 | query -> PersonService.getPersonCount())); 35 | 36 | personGrid.setSizeFull(); 37 | setContent(personGrid); 38 | } 39 | 40 | @WebServlet(urlPatterns = "/*", name = "RESTDemoUIServlet", asyncSupported = true) 41 | @VaadinServletConfiguration(ui = RESTDemoUI.class, productionMode = false) 42 | public static class RESTDemoUIServlet extends VaadinServlet { 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /spring-demo/README.md: -------------------------------------------------------------------------------- 1 | spring-demo 2 | ============== 3 | 4 | Example of a full-blown Vaadin application that uses Spring. 5 | 6 | Project Structure 7 | ================= 8 | 9 | The project consists of the following three modules: 10 | 11 | - spring-demo: root project with common metadata and configuration 12 | - spring-demo-backend: backend service used by the UI 13 | - spring-demo-ui: main application module, development time 14 | 15 | Workflow 16 | ======== 17 | 18 | To compile the entire project, run "mvn install" in the parent project. 19 | 20 | Other basic workflow steps: 21 | 22 | - getting started 23 | - compiling the whole project 24 | - run "mvn install" in parent project 25 | - developing the application 26 | - edit code in the ui module 27 | - run "mvn spring-boot:run" in ui module 28 | - open http://localhost:8080/ 29 | - client side changes or add-ons 30 | - edit code/POM in widgetset module 31 | - run "mvn install" in widgetset module 32 | - if a new add-on has an embedded theme, run "mvn vaadin:update-theme" in the ui module 33 | - debugging client side code 34 | - run "mvn vaadin:run-codeserver" in widgetset module 35 | - activate Super Dev Mode in the debug window of the application 36 | - enabling production mode 37 | - set "vaadin.servlet.productionMode=true" in application.proeprties file in ui module 38 | 39 | 40 | Developing a theme using the runtime compiler 41 | ------------------------- 42 | 43 | When developing the theme, Vaadin can be configured to compile the SASS based 44 | theme at runtime in the server. This way you can just modify the scss files in 45 | your IDE and reload the browser to see changes. 46 | 47 | To use on the runtime compilation, open pom.xml of your UI project and comment 48 | out the compile-theme goal from vaadin-maven-plugin configuration. To remove 49 | an existing pre-compiled theme, remove the styles.css file in the theme directory. 50 | 51 | When using the runtime compiler, running the application in the "run" mode 52 | (rather than in "debug" mode) can speed up consecutive theme compilations 53 | significantly. 54 | -------------------------------------------------------------------------------- /todomvc/src/main/java/com/vaadin/tutorial/todomvc/PreparedJDBCDataProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.tutorial.todomvc; 17 | 18 | import java.sql.Connection; 19 | import java.sql.PreparedStatement; 20 | import java.sql.ResultSet; 21 | import java.sql.SQLException; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | /** 26 | * Vaadin DataProvider over pure JDBC. Filtering and sorting to be implemented 27 | * in subclasses. 28 | * 29 | * @author Vaadin Ltd 30 | */ 31 | @SuppressWarnings("WeakerAccess") 32 | public abstract class PreparedJDBCDataProvider 33 | extends AbstractJDBCDataProvider { 34 | 35 | protected List statements = new ArrayList<>(); 36 | 37 | public PreparedJDBCDataProvider(Connection connection, 38 | DataRetriever jdbcReader) { 39 | super(connection, jdbcReader); 40 | } 41 | 42 | @Override 43 | public void close() throws Exception { 44 | closeResources(statements); 45 | } 46 | 47 | protected PreparedStatement openStatement(String sqlQuery) { 48 | try { 49 | PreparedStatement preparedStatement = connection.prepareStatement( 50 | sqlQuery, ResultSet.TYPE_FORWARD_ONLY, 51 | ResultSet.CONCUR_READ_ONLY); 52 | statements.add(preparedStatement); 53 | return preparedStatement; 54 | } catch (SQLException e) { 55 | throw new RuntimeException(e); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /todomvc/src/main/java/com/vaadin/tutorial/todomvc/SimpleJDBCDataProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.tutorial.todomvc; 17 | 18 | import com.vaadin.data.provider.Query; 19 | 20 | import java.sql.Connection; 21 | import java.sql.PreparedStatement; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | 25 | /** 26 | * Vaadin DataProvider over pure JDBC. Only fixed SQL statements are supported, 27 | * no custom filtering or sorting. 28 | * 29 | * @author Vaadin Ltd 30 | */ 31 | @SuppressWarnings("WeakerAccess") 32 | public class SimpleJDBCDataProvider 33 | extends PreparedJDBCDataProvider { 34 | 35 | protected final PreparedStatement resultSetStatement; 36 | protected final PreparedStatement sizeStatement; 37 | 38 | public SimpleJDBCDataProvider(Connection connection, String sqlQuery, 39 | DataRetriever jdbcReader) { 40 | super(connection, jdbcReader); 41 | resultSetStatement = openStatement(sqlQuery); 42 | 43 | sizeStatement = openStatement( 44 | "select count(*) from (" + sqlQuery + ")"); 45 | } 46 | 47 | @Override 48 | protected ResultSet rowCountStatement(Query query) throws SQLException { 49 | assert query.getSortOrders() == null || query.getSortOrders().isEmpty(); 50 | return sizeStatement.executeQuery(); 51 | } 52 | 53 | @Override 54 | protected ResultSet resultSetStatement(Query query) 55 | throws SQLException { 56 | assert query.getSortOrders() == null || query.getSortOrders().isEmpty(); 57 | return resultSetStatement.executeQuery(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /addressbook/src/main/java/com/vaadin/tutorial/addressbook/AddressbookUI.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.tutorial.addressbook; 2 | 3 | import javax.servlet.annotation.WebServlet; 4 | 5 | import com.vaadin.annotations.Theme; 6 | import com.vaadin.annotations.Title; 7 | import com.vaadin.annotations.VaadinServletConfiguration; 8 | import com.vaadin.server.VaadinRequest; 9 | import com.vaadin.server.VaadinServlet; 10 | import com.vaadin.ui.UI; 11 | import com.vaadin.ui.themes.ValoTheme; 12 | 13 | /* User Interface written in Java. 14 | * 15 | * Define the user interface shown on the Vaadin generated web page by extending the UI class. 16 | * By default, a new UI instance is automatically created when the page is loaded. To reuse 17 | * the same instance, add @PreserveOnRefresh. 18 | */ 19 | @Title("Addressbook") 20 | @Theme(ValoTheme.THEME_NAME) 21 | public class AddressbookUI extends UI { 22 | 23 | /* 24 | * The "Main method". 25 | * 26 | * This is the entry point method executed to initialize and configure the 27 | * visible user interface. Executed on every browser reload because a new 28 | * instance is created for each web page loaded. 29 | */ 30 | @Override 31 | protected void init(VaadinRequest request) { 32 | buildLayout(); 33 | } 34 | 35 | @Override 36 | public MainLayout getContent() { 37 | return (MainLayout) super.getContent(); 38 | } 39 | 40 | /* 41 | * Robust layouts. 42 | * 43 | * Layouts are components that contain other components. HorizontalLayout 44 | * contains TextField and Button. It is wrapped with a Grid into 45 | * VerticalLayout for the left side of the screen. Allow user to resize the 46 | * components with a SplitPanel. 47 | * 48 | * MainLayout is set up declaratively here. See its internals and 49 | * declarative HTML files in resources folder. 50 | */ 51 | private void buildLayout() { 52 | // Split and allow resizing 53 | setContent(new MainLayout()); 54 | } 55 | 56 | /* 57 | * Deployed as a Servlet or Portlet. 58 | * 59 | * You can specify additional servlet parameters like the URI and UI class 60 | * name and turn on production mode when you have finished developing the 61 | * application. 62 | */ 63 | @WebServlet(urlPatterns = "/*") 64 | @VaadinServletConfiguration(ui = AddressbookUI.class, productionMode = false) 65 | public static class MyUIServlet extends VaadinServlet { 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-backend/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | spring-demo 6 | com.vaadin.framework8 7 | 8.1.6 8 | 9 | 4.0.0 10 | 11 | spring-demo-backend 12 | spring-demo-backend 13 | jar 14 | 15 | 16 | true 17 | 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-data-jpa 23 | 24 | 25 | 26 | 27 | javax.el 28 | javax.el-api 29 | 2.2.4 30 | 31 | 32 | org.glassfish.web 33 | javax.el 34 | 2.2.6 35 | 36 | 37 | 38 | org.hibernate 39 | hibernate-core 40 | 41 | 42 | 43 | org.hibernate 44 | hibernate-validator 45 | 46 | 47 | 48 | org.hibernate 49 | hibernate-entitymanager 50 | 51 | 52 | 53 | org.hsqldb 54 | hsqldb 55 | 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-test 60 | test 61 | 62 | 63 | junit 64 | junit 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/authentication/CurrentUser.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.authentication; 2 | 3 | import com.vaadin.server.VaadinRequest; 4 | import com.vaadin.server.VaadinService; 5 | 6 | /** 7 | * Class for retrieving and setting the name of the current user of the current 8 | * session (without using JAAS). All methods of this class require that a 9 | * {@link VaadinRequest} is bound to the current thread. 10 | * 11 | * 12 | * @see com.vaadin.server.VaadinService#getCurrentRequest() 13 | */ 14 | public final class CurrentUser { 15 | 16 | /** 17 | * The attribute key used to store the username in the session. 18 | */ 19 | public static final String CURRENT_USER_SESSION_ATTRIBUTE_KEY = CurrentUser.class 20 | .getCanonicalName(); 21 | 22 | private CurrentUser() { 23 | } 24 | 25 | /** 26 | * Returns the name of the current user stored in the current session, or an 27 | * empty string if no user name is stored. 28 | * 29 | * @throws IllegalStateException 30 | * if the current session cannot be accessed. 31 | */ 32 | public static String get() { 33 | String currentUser = (String) getCurrentRequest().getWrappedSession() 34 | .getAttribute(CURRENT_USER_SESSION_ATTRIBUTE_KEY); 35 | if (currentUser == null) { 36 | return ""; 37 | } else { 38 | return currentUser; 39 | } 40 | } 41 | 42 | /** 43 | * Sets the name of the current user and stores it in the current session. 44 | * Using a {@code null} username will remove the username from the session. 45 | * 46 | * @throws IllegalStateException 47 | * if the current session cannot be accessed. 48 | */ 49 | public static void set(String currentUser) { 50 | if (currentUser == null) { 51 | getCurrentRequest().getWrappedSession() 52 | .removeAttribute(CURRENT_USER_SESSION_ATTRIBUTE_KEY); 53 | } else { 54 | getCurrentRequest().getWrappedSession().setAttribute( 55 | CURRENT_USER_SESSION_ATTRIBUTE_KEY, currentUser); 56 | } 57 | } 58 | 59 | private static VaadinRequest getCurrentRequest() { 60 | VaadinRequest request = VaadinService.getCurrentRequest(); 61 | if (request == null) { 62 | throw new IllegalStateException( 63 | "No request bound to current thread"); 64 | } 65 | return request; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /addressbook/src/main/java/com/vaadin/tutorial/addressbook/MainLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.tutorial.addressbook; 17 | 18 | import com.vaadin.annotations.DesignRoot; 19 | import com.vaadin.tutorial.addressbook.backend.Contact; 20 | import com.vaadin.ui.HorizontalSplitPanel; 21 | import com.vaadin.ui.declarative.Design; 22 | 23 | /** 24 | * @author Vaadin Ltd 25 | * 26 | */ 27 | @DesignRoot 28 | public class MainLayout extends HorizontalSplitPanel { 29 | 30 | // ContactForm is an example of a custom component class 31 | private ContactForm contactForm; 32 | 33 | private LeftPanel left; 34 | 35 | @Override 36 | public void attach() { 37 | super.attach(); 38 | 39 | if (contactForm == null) { 40 | Design.read(this); 41 | configureComponents(); 42 | } 43 | } 44 | 45 | /* 46 | * Choose the design patterns you like. 47 | * 48 | * It is good practice to have separate data access methods that handle the 49 | * back-end access and/or the user interface updates. You can further split 50 | * your code into classes to easier maintenance. With Vaadin you can follow 51 | * MVC, MVP or any other design pattern you choose. 52 | */ 53 | void refreshContacts() { 54 | refreshContacts(null); 55 | } 56 | 57 | void deselect() { 58 | left.deselect(); 59 | } 60 | 61 | private void configureComponents() { 62 | left.addEditListener(() -> contactForm.edit(new Contact())); 63 | left.addFilterListener(this::refreshContacts); 64 | left.addSelectionListener(contactForm::edit); 65 | 66 | refreshContacts(); 67 | } 68 | 69 | private void refreshContacts(String stringFilter) { 70 | if (stringFilter == null) { 71 | left.refresh(); 72 | } else { 73 | left.refresh(stringFilter); 74 | } 75 | contactForm.setVisible(false); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /rest-json-dataprovider-demo/src/main/java/com/vaadin/framework8/demo/restjson/RESTDemoUI.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.demo.restjson; 2 | 3 | import javax.servlet.annotation.WebServlet; 4 | 5 | import com.vaadin.annotations.Theme; 6 | import com.vaadin.annotations.VaadinServletConfiguration; 7 | import com.vaadin.server.VaadinRequest; 8 | import com.vaadin.server.VaadinServlet; 9 | import com.vaadin.ui.Grid; 10 | import com.vaadin.ui.UI; 11 | import com.vaadin.ui.themes.ValoTheme; 12 | 13 | import elemental.json.JsonObject; 14 | import elemental.json.JsonValue; 15 | 16 | @Theme(ValoTheme.THEME_NAME) 17 | public class RESTDemoUI extends UI { 18 | 19 | @Override 20 | protected void init(VaadinRequest vaadinRequest) { 21 | Grid personGrid = new Grid<>(); 22 | personGrid.addColumn(json -> safeGetString(json, "name", "first")) 23 | .setCaption("First name"); 24 | personGrid.addColumn(json -> safeGetString(json, "name", "last")) 25 | .setCaption("Last name"); 26 | personGrid.addColumn(json -> safeGetString(json, "email")) 27 | .setCaption("Email"); 28 | personGrid.addColumn(json -> safeGetString(json, "location", "city")) 29 | .setCaption("City"); 30 | personGrid.addColumn(json -> safeGetString(json, "location", "street")) 31 | .setCaption("Street"); 32 | personGrid 33 | .addColumn(json -> safeGetString(json, "location", "postcode")) 34 | .setCaption("Postal code"); 35 | personGrid.addColumn(json -> safeGetString(json, "location", "state")) 36 | .setCaption("State"); 37 | 38 | personGrid.setDataProvider(new RestDataProvider( 39 | "https://randomuser.me/api/1.1/?seed=0&results=50&page=1")); 40 | 41 | personGrid.setSizeFull(); 42 | setContent(personGrid); 43 | } 44 | 45 | private String safeGetString(JsonObject json, String... path) { 46 | for (int i = 0; i < path.length - 1; i++) { 47 | json = json.get(path[i]); 48 | if (json == null) { 49 | return ""; 50 | } 51 | } 52 | JsonValue value = json.get(path[path.length - 1]); 53 | if (value == null) { 54 | return ""; 55 | } 56 | return value.asString(); 57 | } 58 | 59 | @WebServlet(urlPatterns = "/*", name = "RESTDemoUIServlet", asyncSupported = true) 60 | @VaadinServletConfiguration(ui = RESTDemoUI.class, productionMode = false) 61 | public static class RESTDemoUIServlet extends VaadinServlet { 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-backend/src/main/java/com/vaadin/framework8/samples/backend/data/Product.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.backend.data; 2 | 3 | import java.io.Serializable; 4 | import java.math.BigDecimal; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | import javax.persistence.Entity; 9 | import javax.persistence.FetchType; 10 | import javax.persistence.GeneratedValue; 11 | import javax.persistence.Id; 12 | import javax.persistence.JoinColumn; 13 | import javax.persistence.JoinTable; 14 | import javax.persistence.ManyToMany; 15 | import javax.persistence.Version; 16 | import javax.validation.constraints.Min; 17 | import javax.validation.constraints.NotNull; 18 | import javax.validation.constraints.Size; 19 | 20 | @Entity 21 | public class Product implements Serializable { 22 | 23 | @NotNull 24 | @Id 25 | @GeneratedValue 26 | private int id = -1; 27 | 28 | @Version 29 | private int version; 30 | 31 | @NotNull 32 | @Size(min = 2, message = "Product name must have at least two characters") 33 | private String productName = ""; 34 | @Min(0) 35 | private BigDecimal price = BigDecimal.ZERO; 36 | 37 | @ManyToMany(fetch = FetchType.EAGER) 38 | @JoinTable(name = "product_and_categories", joinColumns = { 39 | @JoinColumn(name = "product_id") }, inverseJoinColumns = { 40 | @JoinColumn(name = "category_id") }) 41 | private Set category = new HashSet<>(); 42 | 43 | @Min(value = 0, message = "Can't have negative amount in stock") 44 | private int stockCount = 0; 45 | @NotNull 46 | private Availability availability = Availability.COMING; 47 | 48 | public int getId() { 49 | return id; 50 | } 51 | 52 | public String getProductName() { 53 | return productName; 54 | } 55 | 56 | public void setProductName(String productName) { 57 | this.productName = productName; 58 | } 59 | 60 | public BigDecimal getPrice() { 61 | return price; 62 | } 63 | 64 | public void setPrice(BigDecimal price) { 65 | this.price = price; 66 | } 67 | 68 | public Set getCategory() { 69 | return category; 70 | } 71 | 72 | public void setCategory(Set category) { 73 | this.category = category; 74 | } 75 | 76 | public int getStockCount() { 77 | return stockCount; 78 | } 79 | 80 | public void setStockCount(int stockCount) { 81 | this.stockCount = stockCount; 82 | } 83 | 84 | public Availability getAvailability() { 85 | return availability; 86 | } 87 | 88 | public void setAvailability(Availability availability) { 89 | this.availability = availability; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /test-util/src/main/java/com/vaadin/demo/testutil/FixedPhantomJSDriver.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright 2000-2016 Vaadin Ltd. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 6 | * use this file except in compliance with the License. You may obtain a copy of 7 | * the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations under 15 | * the License. 16 | */ 17 | package com.vaadin.demo.testutil; 18 | 19 | import java.util.Map; 20 | 21 | import org.openqa.selenium.phantomjs.PhantomJSDriver; 22 | import org.openqa.selenium.remote.DesiredCapabilities; 23 | import org.openqa.selenium.remote.Response; 24 | 25 | import com.vaadin.testbench.TestBenchDriverProxy; 26 | 27 | /** 28 | * Phantom JS driver which waits for Vaadin to finish after every command and 29 | * not just after find commands. 30 | *

31 | * Workaround for https://dev.vaadin.com/ticket/19753 32 | * 33 | * @author Vaadin Ltd 34 | */ 35 | public class FixedPhantomJSDriver extends PhantomJSDriver { 36 | 37 | private TestBenchDriverProxy testBenchDriverProxy; 38 | 39 | /** 40 | * Create a new driver instance. 41 | * 42 | * @param cap 43 | * the desired capabilities 44 | */ 45 | public FixedPhantomJSDriver(DesiredCapabilities cap) { 46 | super(cap); 47 | } 48 | 49 | @Override 50 | protected Response execute(String driverCommand, 51 | Map parameters) { 52 | try { 53 | return super.execute(driverCommand, parameters); 54 | } finally { 55 | if (testBenchDriverProxy != null) { 56 | // Wait after all commands but avoid looping 57 | Object scriptParam = parameters.get("script"); 58 | if (!"quit".equals(driverCommand) 59 | && !"executeScript".equals(driverCommand) 60 | && !(scriptParam instanceof String 61 | && ((String) scriptParam) 62 | .contains("window.vaadin"))) { 63 | testBenchDriverProxy.waitForVaadin(); 64 | } 65 | } 66 | } 67 | } 68 | 69 | /** 70 | * Sets the TestBench proxy. 71 | * 72 | * @param testBenchDriverProxy 73 | * the TestBench proxy 74 | */ 75 | public void setTestBenchDriverProxy( 76 | TestBenchDriverProxy testBenchDriverProxy) { 77 | this.testBenchDriverProxy = testBenchDriverProxy; 78 | 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /registration-form/src/main/java/com/vaadin/demo/registration/EmailOrPhoneValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.demo.registration; 17 | 18 | import com.vaadin.data.ValidationResult; 19 | import com.vaadin.data.ValueContext; 20 | import com.vaadin.data.validator.AbstractValidator; 21 | import com.vaadin.data.validator.EmailValidator; 22 | 23 | class EmailOrPhoneValidator extends AbstractValidator { 24 | 25 | private final EmailValidator emailValidator; 26 | 27 | EmailOrPhoneValidator() { 28 | super(""); 29 | emailValidator = new EmailValidator( 30 | "The string '{0}' is not a valid email address"); 31 | } 32 | 33 | @Override 34 | public ValidationResult apply(String value, ValueContext context) { 35 | String val = value; 36 | // remove all spaces 37 | val = val.replace(" ", ""); 38 | // if string starts from +0-9 ignoring spaces 39 | if (!startsWithCountryCode(val)) { 40 | return emailValidator.apply(value, context); 41 | } 42 | String digits = val.substring(1); 43 | // if string contains only + and digits (ignoring spaces) 44 | if (!hasOnlyDigits(digits)) { 45 | return ValidationResult.error(String.format( 46 | "The string '%s' is not a valid phone number. " 47 | + "Phone numbers should start with a plus sign followed by digits.", 48 | value)); 49 | } 50 | // now there should be at least 10 digits 51 | if (digits.length() >= 10) { 52 | return ValidationResult.ok(); 53 | } 54 | return ValidationResult.error(String.format( 55 | "The string '%s' is not a valid phone number. " 56 | + "Phone should start with a plus sign and contain at least 10 digits", 57 | value)); 58 | } 59 | 60 | private boolean startsWithCountryCode(String phone) { 61 | return phone.length() >= 2 && phone.charAt(0) == '+' 62 | && Character.isDigit(phone.charAt(1)); 63 | } 64 | 65 | private boolean hasOnlyDigits(String phone) { 66 | return phone.chars().allMatch(Character::isDigit); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /tree-database-example/src/main/java/org/vaadin/example/treegrid/jdbc/DBEngine.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.example.treegrid.jdbc; 2 | 3 | import org.apache.commons.dbcp2.BasicDataSource; 4 | 5 | import javax.sql.DataSource; 6 | import java.io.BufferedReader; 7 | import java.io.InputStream; 8 | import java.io.InputStreamReader; 9 | import java.io.Reader; 10 | import java.sql.Connection; 11 | import java.sql.SQLException; 12 | import java.sql.Statement; 13 | import java.util.stream.Stream; 14 | 15 | /** 16 | * Database support class. 17 | * HSQLDB in-memory database is used. The data is uploaded automatically when 18 | * the database is accessed for the very first time. 19 | */ 20 | @SuppressWarnings("WeakerAccess") 21 | public class DBEngine { 22 | 23 | private DBEngine() { 24 | } 25 | 26 | /** 27 | * Initialization-on-demand 28 | * @see More details at Wikipedia 29 | */ 30 | private static class LazyHolder { 31 | static final DataSource INSTANCE = createDataSource(); 32 | } 33 | 34 | public static DataSource getDataSource() { 35 | return LazyHolder.INSTANCE; 36 | } 37 | 38 | private static DataSource createDataSource() { 39 | BasicDataSource dataSource = new BasicDataSource(); 40 | dataSource.setUrl("jdbc:hsqldb:mem:peopledb"); 41 | dataSource.setUsername("SA"); 42 | dataSource.setPassword(""); 43 | try (Connection connection = dataSource.getConnection()) { 44 | uploadData(connection); 45 | } catch (SQLException e) { 46 | throw new RuntimeException(e); 47 | } 48 | return dataSource; 49 | } 50 | 51 | private static void uploadData(Connection connection) { 52 | Stream.of("db_ddl.sql", "db_dml.sql").forEach(scriptName -> 53 | { 54 | try (Statement statement = connection.createStatement(); 55 | InputStream stream = DBEngine.class.getResourceAsStream(scriptName); 56 | Reader reader = new BufferedReader(new InputStreamReader(stream))) { 57 | StringBuilder text = new StringBuilder(); 58 | for (int c; (c = reader.read()) >= 0; ) { 59 | if (c == ';') { 60 | statement.executeQuery(text.toString()); 61 | text.setLength(0); 62 | } else { 63 | text.append((char) c); 64 | } 65 | } 66 | if (!"".equals(text.toString().trim())) { 67 | statement.executeQuery(text.toString()); 68 | } 69 | 70 | } catch (Exception e) { 71 | throw new RuntimeException(e); 72 | } 73 | } 74 | ); 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/crud/ProductGrid.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.crud; 2 | 3 | import java.util.Comparator; 4 | import java.util.stream.Collectors; 5 | 6 | import com.vaadin.framework8.samples.backend.data.Availability; 7 | import com.vaadin.framework8.samples.backend.data.Category; 8 | import com.vaadin.framework8.samples.backend.data.Product; 9 | import com.vaadin.icons.VaadinIcons; 10 | import com.vaadin.ui.Grid; 11 | import com.vaadin.ui.renderers.HtmlRenderer; 12 | import com.vaadin.ui.renderers.NumberRenderer; 13 | 14 | /** 15 | * Grid of products, handling the visual presentation and filtering of a set of 16 | * items. This version uses an in-memory data provider that is suitable for 17 | * small data sets. 18 | */ 19 | public class ProductGrid extends Grid { 20 | 21 | public ProductGrid() { 22 | setSizeFull(); 23 | 24 | addColumn(p -> String.valueOf(p.getId())).setCaption("Id") 25 | .setSortProperty("id"); 26 | addColumn(Product::getProductName).setCaption("Product Name") 27 | .setSortProperty("productName"); 28 | addColumn(Product::getPrice, new NumberRenderer()).setCaption("Price") 29 | .setStyleGenerator(c -> "align-right").setSortProperty("price"); 30 | addColumn(p -> { 31 | Availability availability = p.getAvailability(); 32 | return getTrafficLightIconHtml(availability) + " " 33 | + availability.name(); 34 | }, new HtmlRenderer()).setCaption("Availability") 35 | .setSortProperty("availability"); 36 | addColumn(Product::getStockCount, new NumberRenderer()) 37 | .setCaption("Stock Count").setStyleGenerator(c -> "align-right") 38 | .setSortProperty("stockCount"); 39 | addColumn(p -> p.getCategory().stream() 40 | .sorted(Comparator.comparing(Category::getId)) 41 | .map(Category::getName).collect(Collectors.joining(", "))) 42 | .setCaption("Category").setSortable(false); 43 | } 44 | 45 | private String getTrafficLightIconHtml(Availability availability) { 46 | String color = ""; 47 | if (availability == Availability.AVAILABLE) { 48 | color = "#2dd085"; 49 | } else if (availability == Availability.COMING) { 50 | color = "#ffc66e"; 51 | } else if (availability == Availability.DISCONTINUED) { 52 | color = "#f54993"; 53 | } 54 | 55 | String iconCode = "&#x" 58 | + Integer.toHexString(VaadinIcons.CIRCLE.getCodepoint()) 59 | + ";"; 60 | return iconCode; 61 | } 62 | 63 | public Product getSelectedRow() { 64 | return asSingleSelect().getValue(); 65 | } 66 | 67 | public void refresh(Product product) { 68 | getDataCommunicator().refresh(product); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /rest-json-dataprovider-demo/src/main/java/com/vaadin/framework8/demo/restjson/RestDataProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.framework8.demo.restjson; 17 | 18 | import java.io.IOException; 19 | import java.net.URL; 20 | import java.nio.charset.StandardCharsets; 21 | import java.util.AbstractList; 22 | import java.util.logging.Level; 23 | import java.util.logging.Logger; 24 | import java.util.stream.IntStream; 25 | import java.util.stream.Stream; 26 | 27 | import org.apache.commons.io.IOUtils; 28 | 29 | import com.vaadin.data.provider.AbstractBackEndDataProvider; 30 | import com.vaadin.data.provider.Query; 31 | 32 | import elemental.json.Json; 33 | import elemental.json.JsonArray; 34 | import elemental.json.JsonObject; 35 | import elemental.json.JsonValue; 36 | 37 | public class RestDataProvider 38 | extends AbstractBackEndDataProvider { 39 | 40 | private String restApiUrl; 41 | 42 | public RestDataProvider(String restApiUrl) { 43 | this.restApiUrl = restApiUrl; 44 | } 45 | 46 | @Override 47 | public Stream fetchFromBackEnd(Query query) { 48 | URL url; 49 | try { 50 | url = new URL(restApiUrl); 51 | String jsonData = IOUtils.toString(url, StandardCharsets.UTF_8); 52 | JsonObject json = Json.parse(jsonData); 53 | 54 | JsonArray results = json.getArray("results"); 55 | return stream(results); 56 | } catch (IOException e) { 57 | Logger.getLogger(getClass().getName()).log(Level.SEVERE, 58 | "Error fetching JSON", e); 59 | // Must return something which matches size, or grid will keep 60 | // asking and asking... 61 | return IntStream.range(0, 200).mapToObj(i -> Json.createObject()); 62 | } 63 | } 64 | 65 | @Override 66 | public int sizeInBackEnd(Query query) { 67 | return 200; 68 | } 69 | 70 | /** 71 | * Creates a stream from a JSON array. 72 | * 73 | * @param array 74 | * the JSON array to create a stream from 75 | * @return a stream of JSON values 76 | */ 77 | private static Stream stream(JsonArray array) { 78 | assert array != null; 79 | return new AbstractList() { 80 | @Override 81 | public T get(int index) { 82 | return array.get(index); 83 | } 84 | 85 | @Override 86 | public int size() { 87 | return array.length(); 88 | } 89 | }.stream(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /todomvc/src/main/java/com/vaadin/tutorial/todomvc/TodoJDBCDataProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.tutorial.todomvc; 17 | 18 | import java.sql.Connection; 19 | import java.sql.PreparedStatement; 20 | import java.sql.ResultSet; 21 | import java.sql.SQLException; 22 | 23 | import com.vaadin.data.provider.Query; 24 | 25 | /** 26 | * JDBC DataProvider implementation with filtering supported. 27 | */ 28 | class TodoJDBCDataProvider extends PreparedJDBCDataProvider { 29 | 30 | private final PreparedStatement resultSetStatement; 31 | private final PreparedStatement sizeStatement; 32 | 33 | private final PreparedStatement resultSetStatementFiltered; 34 | private final PreparedStatement sizeStatementFiltered; 35 | 36 | public TodoJDBCDataProvider(Connection connection) throws SQLException { 37 | super(connection, resultSet -> { 38 | Todo todo = new Todo(); 39 | todo.setId(resultSet.getInt("id")); 40 | todo.setText(resultSet.getString("text")); 41 | todo.setCompleted(resultSet.getBoolean("completed")); 42 | return todo; 43 | }); 44 | 45 | resultSetStatementFiltered = 46 | openStatement("SELECT * FROM todo WHERE completed = ?"); 47 | sizeStatementFiltered = 48 | openStatement("SELECT count(*) FROM todo WHERE completed = ?"); 49 | 50 | resultSetStatement = openStatement("SELECT * FROM todo"); 51 | sizeStatement = openStatement("SELECT count(*) FROM todo"); 52 | 53 | } 54 | 55 | @Override 56 | protected synchronized ResultSet rowCountStatement(Query query) throws SQLException { 57 | TaskFilter taskFilter = obtainFilterValue(query); 58 | if (taskFilter == TaskFilter.ALL) { 59 | return sizeStatement.executeQuery(); 60 | } else { 61 | sizeStatementFiltered.setBoolean(1, 62 | taskFilter == TaskFilter.COMPLETED); 63 | return sizeStatementFiltered.executeQuery(); 64 | } 65 | } 66 | 67 | @Override 68 | protected ResultSet resultSetStatement( 69 | Query query) throws SQLException { 70 | TaskFilter taskFilter = obtainFilterValue(query); 71 | if (taskFilter == TaskFilter.ALL) { 72 | return resultSetStatement.executeQuery(); 73 | } else { 74 | resultSetStatementFiltered.setBoolean(1, 75 | taskFilter == TaskFilter.COMPLETED); 76 | return resultSetStatementFiltered.executeQuery(); 77 | } 78 | } 79 | 80 | private TaskFilter obtainFilterValue(Query query) { 81 | assert query.getSortOrders() == null || query.getSortOrders().isEmpty(); 82 | return query.getFilter().orElse(TaskFilter.ALL); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /addressbook/README.md: -------------------------------------------------------------------------------- 1 | Addressbook Tutorial 2 | ==================== 3 | 4 | This tutorial teaches you some of the basic concepts in [Vaadin Framework](https://vaadin.com). It is meant to be 5 | a fast read for learning how to get started - not an example on how application should be 6 | designed. Please note this example uses and requires Java 8 to work. 7 | 8 | ![Addressbook Screenshot](addressbook_screenshot.png "Addressbook Screenshot") 9 | 10 | 11 | Running the example from the command line 12 | ------------------- 13 | ``` 14 | $ mvn jetty:run 15 | ``` 16 | 17 | Open [http://localhost:8080/](http://localhost:8080/) 18 | 19 | 20 | Importing in IntelliJ IDEA 14 21 | -------------------- 22 | These instructions were tested on IntelliJ IDEA 14 CE. You can get it from https://www.jetbrains.com/idea/ 23 | 24 | To get the project up and running in IDEA, do: 25 | - File -> New -> Project from Version Control -> Git 26 | - The URL to use is https://github.com/vaadin/addressbook.git 27 | - If you get a message about "Non-managed pom.xml file found". Choose "Add as Maven Project" 28 | - If you get a message about no JDK or SDK being selected. Choose "Configure" and select your installed JDK. You can also set the JDK using File -> Project Structure 29 | - To start the project, find the "Maven Projects" tab on the right hand side of the screen and navigate to 30 | - Vaadin Web Application -> Plugins -> jetty -> jetty:run 31 | - Click the play button or right click and select Run (Select Debug instead to run in debug mode) 32 | 33 | You should now have a Jetty server running on localhost:8888. Navigate to http://localhost:8888 to play with the application 34 | 35 | Importing in NetBeans 8 36 | -------------------- 37 | These instructions were tested on NetBeans 8.0.2. You can get it from https://www.netbeans.org 38 | 39 | To checkout and run the project in NetBeans, do: 40 | - Team -> Git -> Clone 41 | - Set repository URL to https://github.com/vaadin/addressbook.git 42 | - Finish 43 | - Right click the imported project (Vaadin Addressbook Application) and select Run 44 | - Select GlassFish Server 4.1 -> Remember in Current IDE Session -> OK 45 | 46 | You should now have a GlassFish server running on localhost:8080 and a browser tab should also be automatically opened with this location 47 | 48 | Importing in Eclipse 49 | -------------------- 50 | These instructions were tested on Eclipse IDE for Java EE Developers Luna SR2. You can get it from http://eclipse.org/downloads/ 51 | 52 | To checkout and run the project in Eclipse, do: 53 | - File -> Import... 54 | - Check out Maven Projects from SCM 55 | - Choose Git from SCM menu 56 | - If you do not see "Git" in the SCM menu, click "Find more SCM connectors in the m2e Marketplace" and install "m2e-egit". Restart Eclipse and start over. 57 | - Set the repository URL to https://github.com/vaadin/addressbook.git 58 | - Right click the imported "addressbook" and choose Run As -> Maven Build... 59 | - Set the goal to "jetty:run" and click "Run" 60 | 61 | You should now have a Jetty server running on localhost:8080. Navigate to [http://localhost:8080/](http://localhost:8080/) to play with the application 62 | 63 | To use the built in server adapters of Eclipse, instead of doing "Run As -> Maven Build..." you can do 64 | - Run As -> Run on Server 65 | - Select the server you want to run on, e.g. Apache Tomcat 8 and click ok 66 | - *Do not use the suggested J2EE Preview server* as it is outdated, deprecated and does not support Servlet 3, which is required for this application 67 | -------------------------------------------------------------------------------- /addressbook/src/main/java/com/vaadin/tutorial/addressbook/backend/Contact.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.tutorial.addressbook.backend; 2 | 3 | import org.apache.commons.beanutils.BeanUtils; 4 | 5 | import java.io.Serializable; 6 | import java.time.Instant; 7 | import java.time.LocalDate; 8 | import java.util.Objects; 9 | 10 | /** 11 | * A simple DTO for the address book example. 12 | *

13 | * Serializable and cloneable Java Object that are typically persisted in the 14 | * database and can also be easily converted to different formats like JSON. 15 | */ 16 | // Backend DTO class. This is just a typical Java backend implementation 17 | // class and nothing Vaadin specific. 18 | public class Contact implements Serializable, Cloneable { 19 | 20 | private Long id; 21 | 22 | private String firstName = ""; 23 | private String lastName = ""; 24 | private String phone = ""; 25 | private String email = ""; 26 | private LocalDate birthDate; 27 | private boolean doNotCall; 28 | private Instant createdTimestamp; 29 | 30 | public Contact() { 31 | createdTimestamp = Instant.now(); 32 | } 33 | 34 | public long getCreatedTimestamp() { 35 | return createdTimestamp.toEpochMilli(); 36 | } 37 | 38 | public boolean isDoNotCall() { 39 | return doNotCall; 40 | } 41 | 42 | public void setDoNotCall(boolean doNotCall) { 43 | this.doNotCall = doNotCall; 44 | } 45 | 46 | public Long getId() { 47 | return id; 48 | } 49 | 50 | public void setId(Long id) { 51 | this.id = id; 52 | } 53 | 54 | public String getFirstName() { 55 | return firstName; 56 | } 57 | 58 | public void setFirstName(String firstName) { 59 | this.firstName = firstName; 60 | } 61 | 62 | public String getLastName() { 63 | return lastName; 64 | } 65 | 66 | public void setLastName(String lastName) { 67 | this.lastName = lastName; 68 | } 69 | 70 | public String getPhone() { 71 | return phone; 72 | } 73 | 74 | public void setPhone(String phone) { 75 | this.phone = phone; 76 | } 77 | 78 | public String getEmail() { 79 | return email; 80 | } 81 | 82 | public void setEmail(String email) { 83 | this.email = email; 84 | } 85 | 86 | public LocalDate getBirthDate() { 87 | return birthDate; 88 | } 89 | 90 | public void setBirthDate(LocalDate birthDate) { 91 | this.birthDate = birthDate; 92 | } 93 | 94 | @Override 95 | public Contact clone() throws CloneNotSupportedException { 96 | try { 97 | Contact contact = (Contact) BeanUtils.cloneBean(this); 98 | contact.createdTimestamp = createdTimestamp; 99 | return contact; 100 | } catch (Exception ex) { 101 | throw new CloneNotSupportedException(); 102 | } 103 | } 104 | 105 | public boolean containsText(String text) { 106 | text = text.toLowerCase(); 107 | 108 | return Objects.toString(id, "").toLowerCase().contains(text) 109 | || Objects.toString(firstName, "").toLowerCase().contains(text) 110 | || Objects.toString(lastName, "").toLowerCase().contains(text) 111 | || Objects.toString(phone, "").toLowerCase().contains(text) 112 | || Objects.toString(email, "").toLowerCase().contains(text) 113 | || Objects.toString(birthDate, "").toLowerCase().contains(text); 114 | } 115 | 116 | @Override 117 | public String toString() { 118 | return "Contact{" + "id=" + id + ", firstName=" + firstName 119 | + ", lastName=" + lastName + ", phone=" + phone + ", email=" 120 | + email + ", birthDate=" + birthDate + ", createdTimestamp=" 121 | + createdTimestamp + ",doNotCall=" + doNotCall + '}'; 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-backend/src/test/java/com/vaadin/framework8/samples/backend/DataServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.backend; 2 | 3 | import java.util.Collection; 4 | import java.util.Optional; 5 | 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 11 | import org.springframework.boot.test.context.SpringBootTest; 12 | import org.springframework.test.context.junit4.SpringRunner; 13 | 14 | import com.vaadin.framework8.samples.backend.data.Category; 15 | import com.vaadin.framework8.samples.backend.data.Product; 16 | import com.vaadin.framework8.samples.backend.repository.CategoryRepository; 17 | import com.vaadin.framework8.samples.backend.repository.ProductRepository; 18 | 19 | /** 20 | * Simple unit test for the back-end data service. 21 | */ 22 | @RunWith(SpringRunner.class) 23 | @SpringBootTest 24 | @DataJpaTest 25 | public class DataServiceTest { 26 | 27 | @Autowired 28 | private DataService service; 29 | 30 | @Autowired 31 | private ProductRepository productRepository; 32 | 33 | @Autowired 34 | private CategoryRepository categoryRepository; 35 | 36 | @Test 37 | public void update_product() { 38 | long count = productRepository.count(); 39 | Product save = insertProduct("foo"); 40 | 41 | Assert.assertNotEquals(-1, save.getId()); 42 | 43 | Assert.assertEquals(count + 1, productRepository.count()); 44 | Assert.assertEquals("foo", save.getProductName()); 45 | 46 | save.setProductName("bar"); 47 | 48 | Product update = service.updateProduct(save); 49 | Assert.assertEquals("bar", update.getProductName()); 50 | } 51 | 52 | @Test 53 | public void dataServiceCanFetchProducts() { 54 | Product created = insertProduct("foo"); 55 | 56 | Collection allProducts = service.getAllProducts(); 57 | Optional found = allProducts.stream() 58 | .filter(product -> product.getId() == created.getId()) 59 | .findFirst(); 60 | Assert.assertTrue(found.isPresent()); 61 | Assert.assertEquals(created.getProductName(), 62 | found.get().getProductName()); 63 | } 64 | 65 | @Test 66 | public void dataServiceCanFetchCategories() { 67 | Category category = new Category(); 68 | category.setName("foo"); 69 | 70 | long count = categoryRepository.count(); 71 | Category created = categoryRepository.save(category); 72 | Assert.assertNotEquals(-1, created.getId()); 73 | 74 | Assert.assertEquals(count + 1, categoryRepository.count()); 75 | 76 | Collection allProducts = service.getAllCategories(); 77 | Optional found = allProducts.stream() 78 | .filter(cat -> cat.getId() == created.getId()).findFirst(); 79 | Assert.assertTrue(found.isPresent()); 80 | Assert.assertEquals(created.getName(), found.get().getName()); 81 | } 82 | 83 | @Test 84 | public void deleteProduct() { 85 | Product created = insertProduct("foo"); 86 | long count = productRepository.count(); 87 | 88 | service.deleteProduct(created.getId()); 89 | Assert.assertEquals(count - 1, productRepository.count()); 90 | 91 | Assert.assertNull(productRepository.findOne(created.getId())); 92 | } 93 | 94 | @Test 95 | public void getProduct() { 96 | Product created = insertProduct("foo"); 97 | 98 | Product product = service.getProduct(created.getId()); 99 | Assert.assertEquals(created.getId(), product.getId()); 100 | Assert.assertEquals(created.getProductName(), product.getProductName()); 101 | } 102 | 103 | private Product insertProduct(String name) { 104 | Product product = new Product(); 105 | product.setProductName(name); 106 | 107 | return productRepository.save(product); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /addressbook/src/main/java/com/vaadin/tutorial/addressbook/LeftPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.tutorial.addressbook; 17 | 18 | import com.vaadin.annotations.DesignRoot; 19 | import com.vaadin.tutorial.addressbook.backend.Contact; 20 | import com.vaadin.tutorial.addressbook.backend.ContactService; 21 | import com.vaadin.ui.Button; 22 | import com.vaadin.ui.Grid; 23 | import com.vaadin.ui.TextField; 24 | import com.vaadin.ui.VerticalLayout; 25 | import com.vaadin.ui.declarative.Design; 26 | import com.vaadin.ui.renderers.DateRenderer; 27 | 28 | import java.text.SimpleDateFormat; 29 | import java.time.ZoneId; 30 | import java.util.Date; 31 | import java.util.function.Consumer; 32 | 33 | /** 34 | * @author Vaadin Ltd 35 | */ 36 | @DesignRoot 37 | public class LeftPanel extends VerticalLayout { 38 | 39 | /* 40 | * Hundreds of widgets. Vaadin's user interface components are just Java 41 | * objects that encapsulate and handle cross-browser support and 42 | * client-server communication. The default Vaadin components are in the 43 | * com.vaadin.ui package and there are over 500 more in 44 | * vaadin.com/directory. 45 | */ 46 | private Grid contactList; 47 | private TextField filter; 48 | private Button newContact; 49 | 50 | void addEditListener(Runnable editListener) { 51 | /* 52 | * Synchronous event handling. 53 | * 54 | * Receive user interaction events on the server-side. This allows you 55 | * to synchronously handle those events. Vaadin automatically sends only 56 | * the needed changes to the web page without loading a new page. 57 | */ 58 | newContact.addClickListener(e -> editListener.run()); 59 | 60 | } 61 | 62 | void addFilterListener(Consumer listener) { 63 | filter.addValueChangeListener(e -> listener.accept(e.getValue())); 64 | } 65 | 66 | public LeftPanel() { 67 | Design.read(this); 68 | contactList.addColumn(Contact::getFirstName).setCaption("First Name"); 69 | contactList.addColumn(Contact::getLastName).setCaption("Last Name"); 70 | contactList.addColumn(Contact::getEmail).setCaption("Email"); 71 | contactList 72 | .addColumn( 73 | c -> c.getBirthDate() == null ? null : Date.from(c.getBirthDate() 74 | .atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()), 75 | new DateRenderer(new SimpleDateFormat("M/d/yy"))) 76 | .setCaption("Birth Date"); 77 | 78 | contactList.addColumn(c -> c.isDoNotCall() ? "DO NOT CALL" : "") 79 | .setCaption("Do Not Call"); 80 | } 81 | 82 | void refresh(String filter) { 83 | contactList.setItems(ContactService.getDemoService().findAll(filter)); 84 | } 85 | 86 | void refresh() { 87 | refresh(getFilterValue()); 88 | } 89 | 90 | void addSelectionListener(Consumer listener) { 91 | contactList.asSingleSelect() 92 | .addValueChangeListener(e -> listener.accept(e.getValue())); 93 | } 94 | 95 | void deselect() { 96 | Contact value = contactList.asSingleSelect().getValue(); 97 | if (value != null) { 98 | contactList.getSelectionModel().deselect(value); 99 | } 100 | } 101 | 102 | String getFilterValue() { 103 | return filter.getValue(); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/SampleUI.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | 5 | import com.vaadin.annotations.Push; 6 | import com.vaadin.annotations.Theme; 7 | import com.vaadin.annotations.Viewport; 8 | import com.vaadin.framework8.samples.about.AboutView; 9 | import com.vaadin.framework8.samples.authentication.AccessControl; 10 | import com.vaadin.framework8.samples.authentication.LoginScreen; 11 | import com.vaadin.framework8.samples.crud.SampleCrudView; 12 | import com.vaadin.icons.VaadinIcons; 13 | import com.vaadin.navigator.Navigator; 14 | import com.vaadin.navigator.ViewChangeListener; 15 | import com.vaadin.server.Responsive; 16 | import com.vaadin.server.VaadinRequest; 17 | import com.vaadin.spring.annotation.SpringUI; 18 | import com.vaadin.spring.navigator.SpringViewProvider; 19 | import com.vaadin.ui.CssLayout; 20 | import com.vaadin.ui.HorizontalLayout; 21 | import com.vaadin.ui.UI; 22 | import com.vaadin.ui.themes.ValoTheme; 23 | 24 | /** 25 | * Main UI class of the application that shows either the login screen or the 26 | * main view of the application depending on whether a user is signed in. 27 | * 28 | * The @Viewport annotation configures the viewport meta tags appropriately on 29 | * mobile devices. Instead of device based scaling (default), using responsive 30 | * layouts. 31 | */ 32 | @Viewport("user-scalable=no,initial-scale=1.0") 33 | @Theme("mytheme") 34 | @SpringUI 35 | @Push 36 | public class SampleUI extends UI { 37 | 38 | @Autowired 39 | private AccessControl accessControl; 40 | 41 | @Autowired 42 | private SpringViewProvider viewProvider; 43 | 44 | private Menu menu; 45 | 46 | @Override 47 | protected void init(VaadinRequest vaadinRequest) { 48 | Responsive.makeResponsive(this); 49 | setLocale(vaadinRequest.getLocale()); 50 | getPage().setTitle("My"); 51 | if (!accessControl.isUserSignedIn()) { 52 | setContent(new LoginScreen(accessControl, this::showMainView)); 53 | } else { 54 | showMainView(); 55 | } 56 | } 57 | 58 | protected void showMainView() { 59 | addStyleName(ValoTheme.UI_WITH_MENU); 60 | 61 | HorizontalLayout layout = new HorizontalLayout(); 62 | setContent(layout); 63 | 64 | layout.setStyleName("main-screen"); 65 | 66 | CssLayout viewContainer = new CssLayout(); 67 | viewContainer.addStyleName("valo-content"); 68 | viewContainer.setSizeFull(); 69 | 70 | Navigator navigator = new Navigator(this, viewContainer); 71 | navigator.addProvider(viewProvider); 72 | navigator.setErrorView(ErrorView.class); 73 | 74 | menu = new Menu(navigator); 75 | // View are registered automatically by Vaadin Spring support 76 | menu.addViewButton(SampleCrudView.VIEW_NAME, SampleCrudView.VIEW_NAME, 77 | VaadinIcons.EDIT); 78 | menu.addViewButton(AboutView.VIEW_NAME, AboutView.VIEW_NAME, 79 | VaadinIcons.INFO_CIRCLE); 80 | 81 | navigator.addViewChangeListener(new ViewChangeHandler()); 82 | 83 | layout.addComponent(menu); 84 | layout.addComponent(viewContainer); 85 | layout.setExpandRatio(viewContainer, 1); 86 | layout.setSizeFull(); 87 | layout.setSpacing(false); 88 | 89 | navigator.navigateTo(SampleCrudView.VIEW_NAME); 90 | } 91 | 92 | public static SampleUI get() { 93 | return (SampleUI) UI.getCurrent(); 94 | } 95 | 96 | public AccessControl getAccessControl() { 97 | return accessControl; 98 | } 99 | 100 | private class ViewChangeHandler implements ViewChangeListener { 101 | 102 | @Override 103 | public boolean beforeViewChange(ViewChangeEvent event) { 104 | return true; 105 | } 106 | 107 | @Override 108 | public void afterViewChange(ViewChangeEvent event) { 109 | menu.setActiveView(event.getViewName()); 110 | } 111 | 112 | }; 113 | 114 | } 115 | -------------------------------------------------------------------------------- /todomvc/src/test/java/com/vaadin/tutorial/todomvc/TestDataProviderLimits.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.tutorial.todomvc; 17 | 18 | import static org.junit.Assert.assertEquals; 19 | 20 | import java.sql.Connection; 21 | import java.sql.DriverManager; 22 | import java.sql.PreparedStatement; 23 | import java.sql.SQLException; 24 | import java.sql.Statement; 25 | import java.util.Collections; 26 | import java.util.List; 27 | import java.util.stream.Collectors; 28 | 29 | import org.junit.AfterClass; 30 | import org.junit.BeforeClass; 31 | import org.junit.Test; 32 | 33 | import com.vaadin.data.provider.Query; 34 | 35 | /** 36 | * Test JDBC 37 | * 38 | * @author Vaadin Ltd 39 | */ 40 | public class TestDataProviderLimits { 41 | private static Connection conn; 42 | private static SimpleJDBCDataProvider dataProvider; 43 | 44 | @BeforeClass 45 | public static void setUpAll() throws SQLException { 46 | DriverManager.registerDriver(org.hsqldb.jdbc.JDBCDriver.driverInstance); 47 | conn = DriverManager.getConnection("jdbc:hsqldb:mem:dataproviderdb", 48 | "SA", ""); 49 | // For safety sake 50 | try (Statement statement = conn.createStatement()) { 51 | statement.executeUpdate("DROP TABLE long_table"); 52 | } catch (SQLException ignored) { 53 | } 54 | try (Statement statement = conn.createStatement()) { 55 | statement.executeUpdate( 56 | "CREATE TABLE long_table (i INTEGER PRIMARY KEY)"); 57 | } 58 | try (PreparedStatement preparedStatement = conn 59 | .prepareStatement("INSERT INTO long_table VALUES (?)")) { 60 | for (int i = 0; i < 100; i++) { 61 | preparedStatement.setInt(1, i); 62 | preparedStatement.executeUpdate(); 63 | } 64 | } 65 | dataProvider = new SimpleJDBCDataProvider<>(conn, 66 | "SELECT i FROM long_table ORDER BY i", 67 | resultSet -> resultSet.getInt(1)); 68 | } 69 | 70 | private void doRetrieveTest(int offset, int limit, int expectedFirst, 71 | int expectedLast) { 72 | Query query = new Query<>(offset, limit, 73 | Collections.emptyList(), null, null); 74 | int size = dataProvider.size(query); 75 | assertEquals("Response size", expectedLast - expectedFirst + 1, size); 76 | List values = dataProvider.fetch(query) 77 | .collect(Collectors.toList()); 78 | assertEquals(size, values.size()); 79 | for (int i = 0; i < values.size(); i++) { 80 | assertEquals(i + expectedFirst, values.get(i).intValue()); 81 | } 82 | } 83 | 84 | @Test 85 | public void retrieveInfinite() { 86 | doRetrieveTest(0, Integer.MAX_VALUE, 0, 99); 87 | } 88 | 89 | @Test 90 | public void retrieve100() { 91 | doRetrieveTest(0, 100, 0, 99); 92 | } 93 | 94 | @Test 95 | public void retrieve20() { 96 | doRetrieveTest(0, 20, 0, 19); 97 | } 98 | 99 | @Test 100 | public void retrieve20Shift() { 101 | doRetrieveTest(5, 20, 5, 24); 102 | } 103 | 104 | @Test 105 | public void retrieveEndOfRange() { 106 | doRetrieveTest(90, 20, 90, 99); 107 | } 108 | 109 | @AfterClass 110 | public static void tearDown() throws Exception { 111 | try (Statement statement = conn.createStatement()) { 112 | statement.executeUpdate("DROP TABLE long_table"); 113 | } 114 | dataProvider.close(); 115 | conn.close(); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /addressbook/src/main/java/com/vaadin/tutorial/addressbook/backend/ContactService.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.tutorial.addressbook.backend; 2 | 3 | import java.time.LocalDate; 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.Comparator; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Random; 10 | import java.util.logging.Level; 11 | import java.util.logging.Logger; 12 | 13 | /** 14 | * Separate Java service class. Backend implementation for the address book 15 | * application, with "detached entities" simulating real world DAO. Typically 16 | * these something that the Java EE or Spring backend services provide. 17 | */ 18 | // Backend service class. This is just a typical Java backend implementation 19 | // class and nothing Vaadin specific. 20 | public class ContactService { 21 | 22 | // Create dummy data by randomly combining first and last names 23 | static String[] fnames = { "Peter", "Alice", "John", "Mike", "Olivia", 24 | "Nina", "Alex", "Rita", "Dan", "Umberto", "Henrik", "Rene", "Lisa", 25 | "Linda", "Timothy", "Daniel", "Brian", "George", "Scott", 26 | "Jennifer" }; 27 | static String[] lnames = { "Smith", "Johnson", "Williams", "Jones", "Brown", 28 | "Davis", "Miller", "Wilson", "Moore", "Taylor", "Anderson", 29 | "Thomas", "Jackson", "White", "Harris", "Martin", "Thompson", 30 | "Young", "King", "Robinson" }; 31 | 32 | private static final ContactService INSTANCE = createDemoService(); 33 | 34 | public static ContactService getDemoService() { 35 | return INSTANCE; 36 | } 37 | 38 | private static ContactService createDemoService() { 39 | final ContactService contactService = new ContactService(); 40 | 41 | Random r = new Random(0); 42 | for (int i = 0; i < 100; i++) { 43 | Contact contact = new Contact(); 44 | contact.setFirstName(fnames[r.nextInt(fnames.length)]); 45 | contact.setLastName(lnames[r.nextInt(fnames.length)]); 46 | contact.setEmail(contact.getFirstName().toLowerCase() + "@" 47 | + contact.getLastName().toLowerCase() + ".com"); 48 | contact.setPhone("+ 358 555 " + (100 + r.nextInt(900))); 49 | LocalDate birthday = LocalDate.of(1930 + r.nextInt(70), 50 | 1 + r.nextInt(11), 1 + r.nextInt(27)); 51 | contact.setBirthDate(birthday); 52 | contact.setDoNotCall(r.nextBoolean()); 53 | contactService.save(contact); 54 | } 55 | return contactService; 56 | } 57 | 58 | private HashMap contacts = new HashMap<>(); 59 | private long nextId = 0; 60 | 61 | public synchronized List findAll(String stringFilter) { 62 | ArrayList arrayList = new ArrayList<>(); 63 | for (Contact contact : contacts.values()) { 64 | try { 65 | boolean passesFilter = stringFilter == null 66 | || stringFilter.isEmpty() 67 | || contact.containsText(stringFilter); 68 | if (passesFilter) { 69 | arrayList.add(contact.clone()); 70 | } 71 | } catch (CloneNotSupportedException ex) { 72 | Logger.getLogger(ContactService.class.getName()) 73 | .log(Level.SEVERE, null, ex); 74 | } 75 | } 76 | Collections.sort(arrayList, new Comparator() { 77 | 78 | @Override 79 | public int compare(Contact o1, Contact o2) { 80 | return (int) (o2.getId() - o1.getId()); 81 | } 82 | }); 83 | return arrayList; 84 | } 85 | 86 | public synchronized long count() { 87 | return contacts.size(); 88 | } 89 | 90 | public synchronized void delete(Contact value) { 91 | contacts.remove(value.getId()); 92 | } 93 | 94 | public synchronized void save(Contact entry) { 95 | if (entry.getId() == null) { 96 | entry.setId(nextId++); 97 | } 98 | try { 99 | entry = entry.clone(); 100 | } catch (Exception ex) { 101 | throw new RuntimeException(ex); 102 | } 103 | contacts.put(entry.getId(), entry); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /todomvc/src/main/java/com/vaadin/tutorial/todomvc/AbstractJDBCDataProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.tutorial.todomvc; 17 | 18 | import com.vaadin.data.provider.AbstractBackEndDataProvider; 19 | import com.vaadin.data.provider.Query; 20 | 21 | import java.sql.Connection; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | import java.sql.SQLFeatureNotSupportedException; 25 | import java.util.List; 26 | import java.util.Objects; 27 | import java.util.logging.Level; 28 | import java.util.logging.Logger; 29 | import java.util.stream.Stream; 30 | 31 | /** 32 | * Vaadin DataProvider over pure JDBC, base class. 33 | * 34 | * @param data transfer object. Might be POJO or Map. 35 | * @author Vaadin Ltd 36 | */ 37 | @SuppressWarnings("WeakerAccess") 38 | public abstract class AbstractJDBCDataProvider 39 | extends AbstractBackEndDataProvider implements AutoCloseable { 40 | private static final Logger LOGGER = Logger 41 | .getLogger(AbstractJDBCDataProvider.class.getName()); 42 | protected final java.sql.Connection connection; 43 | protected final DataRetriever jdbcReader; 44 | 45 | private int cachedSize = -1; 46 | 47 | public AbstractJDBCDataProvider(Connection connection, 48 | DataRetriever jdbcReader) { 49 | this.connection = Objects.requireNonNull(connection); 50 | this.jdbcReader = Objects.requireNonNull(jdbcReader); 51 | } 52 | 53 | protected static void closeResources(List statements) { 54 | for (AutoCloseable closeable : statements) { 55 | try { 56 | closeable.close(); 57 | } catch (Exception e) { 58 | LOGGER.log(Level.WARNING, 59 | "Prepared closeable was closed with error", e); 60 | } 61 | } 62 | } 63 | 64 | @Override 65 | protected int sizeInBackEnd(Query query) { 66 | if (cachedSize < 0) { 67 | try (ResultSet resultSet = rowCountStatement(query)) { 68 | resultSet.next(); 69 | cachedSize = resultSet.getInt(1); 70 | } catch (SQLException e) { 71 | throw new RuntimeException("Size SQL query failed", e); 72 | } 73 | } 74 | int size = cachedSize - query.getOffset(); 75 | if (size < 0) { 76 | return 0; 77 | } 78 | return Math.min(size, query.getLimit()); 79 | } 80 | 81 | protected abstract ResultSet rowCountStatement(Query query) throws SQLException; 82 | 83 | protected abstract ResultSet resultSetStatement(Query query) throws SQLException; 84 | 85 | @Override 86 | protected Stream fetchFromBackEnd(Query query) { 87 | try (ResultSet resultSet = resultSetStatement(query)){ 88 | try { 89 | resultSet.absolute(query.getOffset()); 90 | } catch (SQLFeatureNotSupportedException e) { 91 | for (int i = query.getOffset(); i > 0; i--) { 92 | resultSet.next(); 93 | } 94 | } 95 | Stream.Builder builder = Stream.builder(); 96 | for(int i =0; i < query.getLimit() && resultSet.next();i++) { 97 | builder.add(jdbcReader.readRow(resultSet)); 98 | } 99 | return builder.build(); 100 | } catch (SQLException e) { 101 | throw new RuntimeException("Data SQL query failed", e); 102 | } 103 | } 104 | 105 | @Override 106 | public void refreshAll() { 107 | cachedSize = -1; 108 | super.refreshAll(); 109 | } 110 | 111 | @FunctionalInterface 112 | public interface DataRetriever { 113 | T readRow(ResultSet resultSet) throws SQLException; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /addressbook/src/main/java/com/vaadin/tutorial/addressbook/ContactForm.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.tutorial.addressbook; 2 | 3 | import com.vaadin.annotations.DesignRoot; 4 | import com.vaadin.data.Binder; 5 | import com.vaadin.data.Binder.Binding; 6 | import com.vaadin.data.validator.EmailValidator; 7 | import com.vaadin.event.ShortcutAction; 8 | import com.vaadin.server.SerializablePredicate; 9 | import com.vaadin.tutorial.addressbook.backend.Contact; 10 | import com.vaadin.tutorial.addressbook.backend.ContactService; 11 | import com.vaadin.ui.Button; 12 | import com.vaadin.ui.CheckBox; 13 | import com.vaadin.ui.DateField; 14 | import com.vaadin.ui.FormLayout; 15 | import com.vaadin.ui.Notification; 16 | import com.vaadin.ui.Notification.Type; 17 | import com.vaadin.ui.TextField; 18 | import com.vaadin.ui.declarative.Design; 19 | import com.vaadin.ui.themes.ValoTheme; 20 | 21 | /** 22 | * Create custom UI Components. 23 | * 24 | * Create your own Vaadin components by inheritance and composition. This is a 25 | * form component inherited from FormLayout. Use new Binder(Bean.class) and 26 | * binder.bindInstanceFields(form), to bind data fields from DTO to UI fields. 27 | * Similarly named field by naming convention or customized with @PropertyId 28 | * annotation. 29 | * 30 | * @author Vaadin Ltd 31 | */ 32 | @DesignRoot 33 | public class ContactForm extends FormLayout { 34 | 35 | private TextField firstName; 36 | private TextField lastName; 37 | private TextField phone; 38 | private TextField email; 39 | private DateField birthDate; 40 | private CheckBox doNotCall; 41 | protected Button save; 42 | protected Button cancel; 43 | 44 | private final Binder binder = new Binder<>(); 45 | private Contact contactBeingEdited; 46 | 47 | public ContactForm() { 48 | Design.read(this); 49 | configureComponents(); 50 | } 51 | 52 | private void configureComponents() { 53 | 54 | final SerializablePredicate phoneOrEmailPredicate = v -> !phone 55 | .getValue().trim().isEmpty() 56 | || !email.getValue().trim().isEmpty(); 57 | 58 | Binding emailBinding = binder.forField(email) 59 | .withValidator(phoneOrEmailPredicate, 60 | "Both phone and email cannot be empty") 61 | .withValidator(new EmailValidator("Incorrect email address")) 62 | .bind(Contact::getEmail, Contact::setEmail); 63 | 64 | Binding phoneBinding = binder.forField(phone) 65 | .withValidator(phoneOrEmailPredicate, 66 | "Both phone and email cannot be empty") 67 | .bind(Contact::getPhone, Contact::setPhone); 68 | 69 | // Trigger cross-field validation when the other field is changed 70 | email.addValueChangeListener(event -> phoneBinding.validate()); 71 | phone.addValueChangeListener(event -> emailBinding.validate()); 72 | 73 | firstName.setRequiredIndicatorVisible(true); 74 | lastName.setRequiredIndicatorVisible(true); 75 | 76 | binder.bind(firstName, Contact::getFirstName, Contact::setFirstName); 77 | binder.bind(lastName, Contact::getLastName, Contact::setLastName); 78 | binder.bind(doNotCall, Contact::isDoNotCall, Contact::setDoNotCall); 79 | binder.bind(birthDate, Contact::getBirthDate, Contact::setBirthDate); 80 | 81 | /* 82 | * Highlight primary actions. 83 | * 84 | * With Vaadin built-in styles you can highlight the primary save button 85 | * and give it a keyboard shortcut for a better UX. 86 | */ 87 | save.setStyleName(ValoTheme.BUTTON_PRIMARY); 88 | save.setClickShortcut(ShortcutAction.KeyCode.ENTER); 89 | 90 | save.addClickListener(this::save); 91 | cancel.addClickListener(this::cancel); 92 | 93 | setVisible(false); 94 | } 95 | 96 | void edit(Contact contact) { 97 | contactBeingEdited = contact; 98 | if (contact != null) { 99 | binder.readBean(contact); 100 | firstName.focus(); 101 | } 102 | setVisible(contact != null); 103 | } 104 | 105 | public void save(Button.ClickEvent event) { 106 | if (binder.writeBeanIfValid(contactBeingEdited)) { 107 | ContactService.getDemoService().save(contactBeingEdited); 108 | 109 | String msg = String.format("Saved '%s %s'.", 110 | contactBeingEdited.getFirstName(), 111 | contactBeingEdited.getLastName()); 112 | Notification.show(msg, Type.TRAY_NOTIFICATION); 113 | getUI().getContent().refreshContacts(); 114 | } 115 | 116 | } 117 | 118 | public void cancel(Button.ClickEvent event) { 119 | Notification.show("Cancelled", Type.TRAY_NOTIFICATION); 120 | getUI().getContent().deselect(); 121 | } 122 | 123 | @Override 124 | public AddressbookUI getUI() { 125 | return (AddressbookUI) super.getUI(); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /tree-database-example/src/main/java/org/vaadin/example/treegrid/jdbc/TreeUI.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.example.treegrid.jdbc; 2 | 3 | import com.vaadin.annotations.VaadinServletConfiguration; 4 | import com.vaadin.data.ValueProvider; 5 | import com.vaadin.icons.VaadinIcons; 6 | import com.vaadin.server.Resource; 7 | import com.vaadin.server.VaadinRequest; 8 | import com.vaadin.server.VaadinServlet; 9 | import com.vaadin.ui.HorizontalLayout; 10 | import com.vaadin.ui.IconGenerator; 11 | import com.vaadin.ui.Panel; 12 | import com.vaadin.ui.Tree; 13 | import com.vaadin.ui.TreeGrid; 14 | import com.vaadin.ui.UI; 15 | import org.vaadin.example.treegrid.jdbc.pojo.Company; 16 | import org.vaadin.example.treegrid.jdbc.pojo.Department; 17 | import org.vaadin.example.treegrid.jdbc.pojo.NamedItem; 18 | import org.vaadin.example.treegrid.jdbc.pojo.Person; 19 | 20 | import javax.servlet.annotation.WebServlet; 21 | import java.util.Objects; 22 | 23 | /** 24 | * This UI is the application entry point. 25 | */ 26 | @SuppressWarnings("unused") 27 | public class TreeUI extends UI { 28 | 29 | @Override 30 | protected void init(VaadinRequest vaadinRequest) { 31 | final HorizontalLayout layout = new HorizontalLayout(); 32 | layout.setMargin(true); 33 | layout.setSizeFull(); 34 | TreeGrid treeGrid = setupTreeGrid(); 35 | treeGrid.setHeight("50%"); 36 | 37 | Tree tree = setupTree(); 38 | Panel treePanel = new Panel(tree); 39 | treePanel.setHeight("50%"); 40 | 41 | layout.addComponentsAndExpand(treeGrid, treePanel); 42 | 43 | /* Next four listeners keep Tree and TreeGrid in sync - folders are open 44 | and closed synchronously in both components*/ 45 | treeGrid.addExpandListener(expandEvent -> tree.expand(expandEvent.getExpandedItem())); 46 | treeGrid.addCollapseListener(expandEvent -> tree.collapse(expandEvent.getCollapsedItem())); 47 | 48 | tree.addExpandListener(expandEvent -> treeGrid.expand(expandEvent.getExpandedItem())); 49 | tree.addCollapseListener(expandEvent -> treeGrid.collapse(expandEvent.getCollapsedItem())); 50 | 51 | setContent(layout); 52 | } 53 | 54 | private TreeGrid setupTreeGrid() { 55 | TreeGrid treeGrid = new TreeGrid<>(); 56 | 57 | treeGrid.addColumn(NamedItem::getName).setId("name").setCaption("Name"); 58 | treeGrid.setHierarchyColumn("name"); 59 | 60 | treeGrid.addColumn(ofPerson(Person::getFirstName)).setCaption("First Name"); 61 | treeGrid.addColumn(ofPerson(Person::getLastName)).setCaption("Last Name"); 62 | treeGrid.addColumn(new EmailGenerator()).setCaption("e-mail"); 63 | treeGrid.addColumn(ofPerson(Person::getGender)).setCaption("Gender"); 64 | treeGrid.setDataProvider(new PeopleDataProvider()); 65 | return treeGrid; 66 | } 67 | 68 | private Tree setupTree() { 69 | Tree tree = new Tree<>(); 70 | tree.setDataProvider(new PeopleDataProvider()); 71 | tree.setItemCaptionGenerator(NamedItem::getName); 72 | tree.setItemIconGenerator(new PeopleIconGenerator()); 73 | return tree; 74 | } 75 | 76 | @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) 77 | @VaadinServletConfiguration(ui = TreeUI.class, productionMode = false) 78 | public static class MyUIServlet extends VaadinServlet { 79 | } 80 | 81 | private static ValueProvider ofPerson(ValueProvider personExtractor) { 82 | return (NamedItem item) -> { 83 | if (item instanceof Person) { 84 | return personExtractor.apply((Person) item); 85 | } else { 86 | return "--"; 87 | } 88 | }; 89 | } 90 | 91 | private static class PeopleIconGenerator implements IconGenerator { 92 | @Override 93 | public Resource apply(NamedItem p) { 94 | if (p instanceof Person) { 95 | String gender = Objects.toString(((Person) p).getGender(), ""); 96 | switch (gender.toUpperCase()) { 97 | case "MALE": 98 | return VaadinIcons.MALE; 99 | case "FEMALE": 100 | return VaadinIcons.FEMALE; 101 | default: 102 | return VaadinIcons.USER; 103 | } 104 | } else if (p instanceof Department) { 105 | return VaadinIcons.GROUP; 106 | } else { 107 | return VaadinIcons.OFFICE; 108 | } 109 | } 110 | } 111 | 112 | public static class EmailGenerator implements ValueProvider { 113 | 114 | @Override 115 | public String apply(NamedItem namedItem) { 116 | if (namedItem instanceof Company) return ((Company) namedItem).getEmail(); 117 | if (namedItem instanceof Person) return ((Person) namedItem).getEmail(); 118 | return "--"; 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/crud/SampleCrudLogic.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.crud; 2 | 3 | import java.io.Serializable; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.config.ConfigurableBeanFactory; 7 | import org.springframework.context.ApplicationContext; 8 | import org.springframework.context.annotation.Scope; 9 | 10 | import com.vaadin.framework8.samples.SampleUI; 11 | import com.vaadin.framework8.samples.backend.DataService; 12 | import com.vaadin.framework8.samples.backend.data.Product; 13 | import com.vaadin.server.Page; 14 | import com.vaadin.spring.annotation.SpringComponent; 15 | 16 | /** 17 | * This class provides an interface for the logical operations between the CRUD 18 | * view, its parts like the product editor form and the data provider, including 19 | * fetching and saving products. 20 | * 21 | * Having this separate from the view makes it easier to test various parts of 22 | * the system separately, and to e.g. provide alternative views for the same 23 | * data. 24 | */ 25 | @SpringComponent 26 | public class SampleCrudLogic implements Serializable { 27 | 28 | private SampleCrudView view; 29 | 30 | @Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON) 31 | @SpringComponent 32 | public static class SampleCrudLogicFactory { 33 | 34 | @Autowired 35 | private ApplicationContext context; 36 | 37 | public SampleCrudLogic createLogic(SampleCrudView view) { 38 | SampleCrudLogic logic = context.getBean(SampleCrudLogic.class); 39 | logic.init(view); 40 | return logic; 41 | } 42 | } 43 | 44 | @Autowired 45 | private DataService dataService; 46 | 47 | private SampleCrudLogic() { 48 | } 49 | 50 | public void init() { 51 | editProduct(null); 52 | // Hide and disable if not admin 53 | if (!SampleUI.get().getAccessControl().isUserInRole("admin")) { 54 | view.setNewProductEnabled(false); 55 | } 56 | } 57 | 58 | public void cancelProduct() { 59 | setFragmentParameter(""); 60 | view.clearSelection(); 61 | view.editProduct(null); 62 | } 63 | 64 | /** 65 | * Update the fragment without causing navigator to change view 66 | */ 67 | private void setFragmentParameter(String productId) { 68 | String fragmentParameter; 69 | if (productId == null || productId.isEmpty()) { 70 | fragmentParameter = ""; 71 | } else { 72 | fragmentParameter = productId; 73 | } 74 | 75 | Page page = SampleUI.get().getPage(); 76 | page.setUriFragment( 77 | "!" + SampleCrudView.VIEW_NAME + "/" + fragmentParameter, 78 | false); 79 | } 80 | 81 | public void enter(String productId) { 82 | if (productId != null && !productId.isEmpty()) { 83 | if (productId.equals("new")) { 84 | newProduct(); 85 | } else { 86 | // Ensure this is selected even if coming directly here from 87 | // login 88 | try { 89 | int pid = Integer.parseInt(productId); 90 | Product product = findProduct(pid); 91 | view.selectRow(product); 92 | } catch (NumberFormatException e) { 93 | } 94 | } 95 | } 96 | } 97 | 98 | private Product findProduct(int productId) { 99 | return dataService.getProduct(productId); 100 | } 101 | 102 | public void saveProduct(Product product) { 103 | view.showSaveNotification(product.getProductName() + " (" 104 | + product.getId() + ") updated"); 105 | view.clearSelection(); 106 | view.editProduct(null); 107 | view.updateProduct(product); 108 | setFragmentParameter(""); 109 | } 110 | 111 | public void deleteProduct(Product product) { 112 | dataService.deleteProduct(product.getId()); 113 | view.showSaveNotification(product.getProductName() + " (" 114 | + product.getId() + ") removed"); 115 | 116 | view.clearSelection(); 117 | view.editProduct(null); 118 | view.removeProduct(product); 119 | setFragmentParameter(""); 120 | } 121 | 122 | public void editProduct(Product product) { 123 | if (product == null) { 124 | setFragmentParameter(""); 125 | } else { 126 | setFragmentParameter(product.getId() + ""); 127 | } 128 | view.editProduct(product); 129 | } 130 | 131 | public void newProduct() { 132 | view.clearSelection(); 133 | setFragmentParameter("new"); 134 | view.editProduct(new Product()); 135 | } 136 | 137 | public void rowSelected(Product product) { 138 | if (SampleUI.get().getAccessControl().isUserInRole("admin")) { 139 | view.editProduct(product); 140 | } 141 | } 142 | 143 | private void init(SampleCrudView view) { 144 | this.view = view; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-backend/src/main/java/com/vaadin/framework8/samples/backend/MockDataGenerator.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.backend; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.ArrayList; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Random; 8 | import java.util.Set; 9 | 10 | import javax.annotation.PostConstruct; 11 | 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.beans.factory.config.ConfigurableBeanFactory; 14 | import org.springframework.context.annotation.Scope; 15 | import org.springframework.stereotype.Component; 16 | 17 | import com.vaadin.framework8.samples.backend.data.Availability; 18 | import com.vaadin.framework8.samples.backend.data.Category; 19 | import com.vaadin.framework8.samples.backend.data.Product; 20 | import com.vaadin.framework8.samples.backend.repository.CategoryRepository; 21 | import com.vaadin.framework8.samples.backend.repository.ProductRepository; 22 | 23 | /** 24 | * Mock data initializer. 25 | *

26 | * Fills in-memory data base each time when application is started. 27 | * 28 | * @author Vaadin Ltd 29 | * 30 | */ 31 | @Component 32 | @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) 33 | public class MockDataGenerator { 34 | 35 | @Autowired 36 | private ProductRepository productRespoitory; 37 | 38 | @Autowired 39 | private CategoryRepository categoryRepository; 40 | 41 | private static final Random random = new Random(1); 42 | private static final String categoryNames[] = new String[] { 43 | "Children's books", "Best sellers", "Romance", "Mystery", 44 | "Thriller", "Sci-fi", "Non-fiction", "Cookbooks" }; 45 | 46 | private static String[] word1 = new String[] { "The art of", "Mastering", 47 | "The secrets of", "Avoiding", "For fun and profit: ", 48 | "How to fail at", "10 important facts about", 49 | "The ultimate guide to", "Book of", "Surviving", "Encyclopedia of", 50 | "Very much", "Learning the basics of", "The cheap way to", 51 | "Being awesome at", "The life changer:", "The Vaadin way:", 52 | "Becoming one with", "Beginners guide to", 53 | "The complete visual guide to", "The mother of all references:" }; 54 | 55 | private static String[] word2 = new String[] { "gardening", 56 | "living a healthy life", "designing tree houses", "home security", 57 | "intergalaxy travel", "meditation", "ice hockey", 58 | "children's education", "computer programming", "Vaadin TreeTable", 59 | "winter bathing", "playing the cello", "dummies", "rubber bands", 60 | "feeling down", "debugging", "running barefoot", 61 | "speaking to a big audience", "creating software", "giant needles", 62 | "elephants", "keeping your wife happy" }; 63 | 64 | @PostConstruct 65 | private void init() { 66 | List categories = createCategories(); 67 | createProducts(categories); 68 | } 69 | 70 | private List createCategories() { 71 | List categories = new ArrayList<>(); 72 | for (String name : categoryNames) { 73 | Category c = createCategory(name); 74 | categories.add(c); 75 | } 76 | return categories; 77 | 78 | } 79 | 80 | private void createProducts(List categories) { 81 | List products = new ArrayList<>(); 82 | for (int i = 0; i < 100; i++) { 83 | Product p = createProduct(categories); 84 | products.add(p); 85 | } 86 | } 87 | 88 | private Category createCategory(String name) { 89 | Category category = new Category(); 90 | category.setName(name); 91 | return categoryRepository.save(category); 92 | } 93 | 94 | private Product createProduct(List categories) { 95 | Product product = new Product(); 96 | product.setProductName(generateName()); 97 | 98 | product.setPrice(new BigDecimal((random.nextInt(250) + 50) / 10.0)); 99 | product.setAvailability(Availability.values()[random 100 | .nextInt(Availability.values().length)]); 101 | if (product.getAvailability() == Availability.AVAILABLE) { 102 | product.setStockCount(random.nextInt(523)); 103 | } 104 | 105 | product.setCategory(getCategory(categories, 1, 2)); 106 | return productRespoitory.save(product); 107 | } 108 | 109 | private Set getCategory(List categories, int min, 110 | int max) { 111 | int nr = random.nextInt(max) + min; 112 | HashSet productCategories = new HashSet<>(); 113 | for (int i = 0; i < nr; i++) { 114 | productCategories 115 | .add(categories.get(random.nextInt(categories.size()))); 116 | } 117 | 118 | return productCategories; 119 | } 120 | 121 | private String generateName() { 122 | return word1[random.nextInt(word1.length)] + " " 123 | + word2[random.nextInt(word2.length)]; 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/Menu.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.vaadin.icons.VaadinIcons; 7 | import com.vaadin.navigator.Navigator; 8 | import com.vaadin.server.Page; 9 | import com.vaadin.server.Resource; 10 | import com.vaadin.server.ThemeResource; 11 | import com.vaadin.server.VaadinSession; 12 | import com.vaadin.ui.Alignment; 13 | import com.vaadin.ui.Button; 14 | import com.vaadin.ui.Button.ClickEvent; 15 | import com.vaadin.ui.Button.ClickListener; 16 | import com.vaadin.ui.CssLayout; 17 | import com.vaadin.ui.HorizontalLayout; 18 | import com.vaadin.ui.Image; 19 | import com.vaadin.ui.Label; 20 | import com.vaadin.ui.MenuBar; 21 | import com.vaadin.ui.MenuBar.Command; 22 | import com.vaadin.ui.MenuBar.MenuItem; 23 | import com.vaadin.ui.themes.ValoTheme; 24 | 25 | /** 26 | * Responsive navigation menu presenting a list of available views to the user. 27 | */ 28 | public class Menu extends CssLayout { 29 | 30 | private static final String VALO_MENUITEMS = "valo-menuitems"; 31 | private static final String VALO_MENU_TOGGLE = "valo-menu-toggle"; 32 | private static final String VALO_MENU_VISIBLE = "valo-menu-visible"; 33 | private Navigator navigator; 34 | private Map viewButtons = new HashMap<>(); 35 | 36 | private CssLayout menuItemsLayout; 37 | private CssLayout menuPart; 38 | 39 | public Menu(Navigator navigator) { 40 | this.navigator = navigator; 41 | setPrimaryStyleName(ValoTheme.MENU_ROOT); 42 | menuPart = new CssLayout(); 43 | menuPart.addStyleName(ValoTheme.MENU_PART); 44 | 45 | // header of the menu 46 | final HorizontalLayout top = new HorizontalLayout(); 47 | top.setDefaultComponentAlignment(Alignment.MIDDLE_LEFT); 48 | top.addStyleName(ValoTheme.MENU_TITLE); 49 | Label title = new Label("My CRUD"); 50 | title.addStyleName(ValoTheme.LABEL_H3); 51 | title.setSizeUndefined(); 52 | Image image = new Image(null, new ThemeResource("img/table-logo.png")); 53 | image.setStyleName("logo"); 54 | top.addComponent(image); 55 | top.addComponent(title); 56 | menuPart.addComponent(top); 57 | 58 | // logout menu item 59 | MenuBar logoutMenu = new MenuBar(); 60 | logoutMenu.addItem("Logout", VaadinIcons.SIGN_OUT, new Command() { 61 | 62 | @Override 63 | public void menuSelected(MenuItem selectedItem) { 64 | VaadinSession.getCurrent().getSession().invalidate(); 65 | Page.getCurrent().reload(); 66 | } 67 | }); 68 | 69 | logoutMenu.addStyleName("user-menu"); 70 | menuPart.addComponent(logoutMenu); 71 | 72 | // button for toggling the visibility of the menu when on a small screen 73 | final Button showMenu = new Button("Menu", new ClickListener() { 74 | @Override 75 | public void buttonClick(final ClickEvent event) { 76 | if (menuPart.getStyleName().contains(VALO_MENU_VISIBLE)) { 77 | menuPart.removeStyleName(VALO_MENU_VISIBLE); 78 | } else { 79 | menuPart.addStyleName(VALO_MENU_VISIBLE); 80 | } 81 | } 82 | }); 83 | showMenu.addStyleName(ValoTheme.BUTTON_PRIMARY); 84 | showMenu.addStyleName(ValoTheme.BUTTON_SMALL); 85 | showMenu.addStyleName(VALO_MENU_TOGGLE); 86 | showMenu.setIcon(VaadinIcons.MENU); 87 | menuPart.addComponent(showMenu); 88 | 89 | // container for the navigation buttons, which are added by addView() 90 | menuItemsLayout = new CssLayout(); 91 | menuItemsLayout.setPrimaryStyleName(VALO_MENUITEMS); 92 | menuPart.addComponent(menuItemsLayout); 93 | 94 | addComponent(menuPart); 95 | } 96 | 97 | /** 98 | * Creates a navigation button to the view identified by {@code name} using 99 | * {@code caption} and {@code icon}. 100 | * 101 | * @param name 102 | * view name 103 | * @param caption 104 | * view caption in the menu 105 | * @param icon 106 | * view icon in the menu 107 | */ 108 | public void addViewButton(final String name, String caption, 109 | Resource icon) { 110 | Button button = new Button(caption, new ClickListener() { 111 | 112 | @Override 113 | public void buttonClick(ClickEvent event) { 114 | navigator.navigateTo(name); 115 | 116 | } 117 | }); 118 | button.setPrimaryStyleName(ValoTheme.MENU_ITEM); 119 | button.setIcon(icon); 120 | menuItemsLayout.addComponent(button); 121 | viewButtons.put(name, button); 122 | } 123 | 124 | /** 125 | * Highlights a view navigation button as the currently active view in the 126 | * menu. This method does not perform the actual navigation. 127 | * 128 | * @param viewName 129 | * the name of the view to show as active 130 | */ 131 | public void setActiveView(String viewName) { 132 | for (Button button : viewButtons.values()) { 133 | button.removeStyleName("selected"); 134 | } 135 | Button selected = viewButtons.get(viewName); 136 | if (selected != null) { 137 | selected.addStyleName("selected"); 138 | } 139 | menuPart.removeStyleName(VALO_MENU_VISIBLE); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/authentication/LoginScreen.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.authentication; 2 | 3 | import java.io.Serializable; 4 | 5 | import com.vaadin.event.ShortcutAction; 6 | import com.vaadin.server.Page; 7 | import com.vaadin.shared.ui.ContentMode; 8 | import com.vaadin.ui.Alignment; 9 | import com.vaadin.ui.Button; 10 | import com.vaadin.ui.Component; 11 | import com.vaadin.ui.CssLayout; 12 | import com.vaadin.ui.FormLayout; 13 | import com.vaadin.ui.Label; 14 | import com.vaadin.ui.Notification; 15 | import com.vaadin.ui.PasswordField; 16 | import com.vaadin.ui.TextField; 17 | import com.vaadin.ui.VerticalLayout; 18 | import com.vaadin.ui.themes.ValoTheme; 19 | 20 | /** 21 | * UI content when the user is not logged in yet. 22 | */ 23 | public class LoginScreen extends CssLayout { 24 | 25 | private TextField username; 26 | private PasswordField password; 27 | private Button login; 28 | private Button forgotPassword; 29 | private LoginListener loginListener; 30 | private AccessControl accessControl; 31 | 32 | public LoginScreen(AccessControl accessControl, 33 | LoginListener loginListener) { 34 | this.loginListener = loginListener; 35 | this.accessControl = accessControl; 36 | buildUI(); 37 | username.focus(); 38 | } 39 | 40 | private void buildUI() { 41 | addStyleName("login-screen"); 42 | 43 | // login form, centered in the available part of the screen 44 | Component loginForm = buildLoginForm(); 45 | 46 | // layout to center login form when there is sufficient screen space 47 | // - see the theme for how this is made responsive for various screen 48 | // sizes 49 | VerticalLayout centeringLayout = new VerticalLayout(); 50 | centeringLayout.setStyleName("centering-layout"); 51 | centeringLayout.addComponent(loginForm); 52 | centeringLayout.setMargin(false); 53 | centeringLayout.setComponentAlignment(loginForm, 54 | Alignment.MIDDLE_CENTER); 55 | 56 | // information text about logging in 57 | CssLayout loginInformation = buildLoginInformation(); 58 | 59 | addComponent(centeringLayout); 60 | addComponent(loginInformation); 61 | } 62 | 63 | private Component buildLoginForm() { 64 | FormLayout loginForm = new FormLayout(); 65 | 66 | loginForm.addStyleName("login-form"); 67 | loginForm.setSizeUndefined(); 68 | loginForm.setMargin(false); 69 | 70 | loginForm.addComponent(username = new TextField("Username", "admin")); 71 | username.setWidth(15, Unit.EM); 72 | loginForm.addComponent(password = new PasswordField("Password")); 73 | password.setWidth(15, Unit.EM); 74 | password.setDescription("Write anything"); 75 | CssLayout buttons = new CssLayout(); 76 | buttons.setStyleName("buttons"); 77 | loginForm.addComponent(buttons); 78 | 79 | buttons.addComponent(login = new Button("Login")); 80 | login.setDisableOnClick(true); 81 | login.addClickListener(new Button.ClickListener() { 82 | @Override 83 | public void buttonClick(Button.ClickEvent event) { 84 | try { 85 | login(); 86 | } finally { 87 | login.setEnabled(true); 88 | } 89 | } 90 | }); 91 | login.setClickShortcut(ShortcutAction.KeyCode.ENTER); 92 | login.addStyleName(ValoTheme.BUTTON_FRIENDLY); 93 | 94 | buttons.addComponent(forgotPassword = new Button("Forgot password?")); 95 | forgotPassword.addClickListener(new Button.ClickListener() { 96 | @Override 97 | public void buttonClick(Button.ClickEvent event) { 98 | showNotification(new Notification("Hint: Try anything")); 99 | } 100 | }); 101 | forgotPassword.addStyleName(ValoTheme.BUTTON_LINK); 102 | return loginForm; 103 | } 104 | 105 | private CssLayout buildLoginInformation() { 106 | CssLayout loginInformation = new CssLayout(); 107 | loginInformation.setStyleName("login-information"); 108 | Label loginInfoText = new Label( 109 | "

Login Information

" 110 | + "Log in as "admin" to have full access. Log in with any other username to have read-only access. For all users, any password is fine", 111 | ContentMode.HTML); 112 | loginInfoText.setWidth("100%"); 113 | loginInformation.addComponent(loginInfoText); 114 | return loginInformation; 115 | } 116 | 117 | private void login() { 118 | if (accessControl.signIn(username.getValue(), password.getValue())) { 119 | loginListener.loginSuccessful(); 120 | } else { 121 | showNotification(new Notification("Login failed", 122 | "Please check your username and password and try again.", 123 | Notification.Type.HUMANIZED_MESSAGE)); 124 | username.focus(); 125 | } 126 | } 127 | 128 | private void showNotification(Notification notification) { 129 | // keep the notification visible a little while after moving the 130 | // mouse, or until clicked 131 | notification.setDelayMsec(2000); 132 | notification.show(Page.getCurrent()); 133 | } 134 | 135 | public interface LoginListener extends Serializable { 136 | void loginSuccessful(); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /tree-database-example/src/main/java/org/vaadin/example/treegrid/jdbc/PeopleDataProvider.java: -------------------------------------------------------------------------------- 1 | package org.vaadin.example.treegrid.jdbc; 2 | 3 | import com.vaadin.data.provider.AbstractBackEndHierarchicalDataProvider; 4 | import com.vaadin.data.provider.HierarchicalQuery; 5 | import org.vaadin.example.treegrid.jdbc.pojo.Company; 6 | import org.vaadin.example.treegrid.jdbc.pojo.Department; 7 | import org.vaadin.example.treegrid.jdbc.pojo.NamedItem; 8 | import org.vaadin.example.treegrid.jdbc.pojo.Person; 9 | 10 | import java.sql.Connection; 11 | import java.sql.PreparedStatement; 12 | import java.sql.ResultSet; 13 | import java.sql.SQLException; 14 | import java.sql.SQLFeatureNotSupportedException; 15 | import java.util.stream.Stream; 16 | 17 | /** 18 | * Example of AbstractHierarchicalDataProvider, based on top of pure JDBC. 19 | */ 20 | public class PeopleDataProvider extends AbstractBackEndHierarchicalDataProvider { 21 | 22 | @Override 23 | public int getChildCount(HierarchicalQuery query) { 24 | NamedItem parent = query.getParent(); 25 | int count; 26 | if (parent instanceof Person) { 27 | return 0; 28 | } else if (parent instanceof Department) { 29 | count = readInt("SELECT COUNT(*) FROM people WHERE department_id=?", parent); 30 | } else if (parent instanceof Company) { 31 | count = readInt("SELECT COUNT(*) FROM department WHERE company_id=?", parent); 32 | } else { 33 | count = readInt("SELECT COUNT(*) FROM company", null); 34 | } 35 | return count - query.getOffset(); 36 | } 37 | 38 | @Override 39 | protected Stream fetchChildrenFromBackEnd(HierarchicalQuery query) { 40 | NamedItem parent = query.getParent(); 41 | if (parent instanceof Person) { 42 | return Stream.empty(); 43 | } 44 | DataRetriever retriever; 45 | String sql; 46 | if (parent instanceof Department) { 47 | sql = "SELECT * FROM people WHERE department_id=?"; 48 | retriever = resultSet -> new Person(resultSet.getLong("id"), 49 | resultSet.getLong("department_id"), 50 | resultSet.getString("first_name"), 51 | resultSet.getString("last_name"), 52 | resultSet.getString("email"), 53 | resultSet.getString("gender") 54 | ); 55 | } else if (parent instanceof Company) { 56 | sql = "SELECT * FROM department WHERE company_id=?"; 57 | retriever = resultSet -> new Department( 58 | resultSet.getLong("department_id"), 59 | resultSet.getLong("company_id"), 60 | resultSet.getString("department_name")); 61 | } else { 62 | sql = "SELECT * FROM company"; 63 | retriever = resultSet -> new Company(resultSet.getLong("company_id"), 64 | resultSet.getString("company_name"), 65 | resultSet.getString("company_email")); 66 | } 67 | try (Connection connection = DBEngine.getDataSource().getConnection(); 68 | PreparedStatement statement = connection.prepareStatement(sql)) { 69 | if (parent != null) { 70 | statement.setLong(1, parent.getId()); 71 | } 72 | 73 | return readResultSet(query, retriever, statement); 74 | } catch (SQLException e) { 75 | throw new RuntimeException(e); 76 | } 77 | } 78 | 79 | private Stream readResultSet(HierarchicalQuery query, DataRetriever retriever, PreparedStatement statement) throws SQLException { 80 | try (ResultSet resultSet = statement.executeQuery()) { 81 | safeSkipRows(resultSet, query.getOffset()); 82 | if (resultSet.isAfterLast()) { 83 | return Stream.empty(); 84 | } 85 | Stream.Builder builder = Stream.builder(); 86 | int limit = query.getLimit(); 87 | for (int i = 0; i < limit && resultSet.next(); i++) { 88 | builder.add(retriever.readRow(resultSet)); 89 | } 90 | return builder.build(); 91 | } 92 | } 93 | 94 | private void safeSkipRows(ResultSet resultSet, int skipRowCount) throws SQLException { 95 | try { 96 | resultSet.relative(skipRowCount); 97 | } catch (SQLFeatureNotSupportedException e) { 98 | for (int i = 0; i < skipRowCount; i++) { 99 | if (!resultSet.next()) return; 100 | } 101 | } 102 | } 103 | 104 | @Override 105 | public boolean hasChildren(NamedItem item) { 106 | return getChildCount(new HierarchicalQuery<>(null, item)) > 0; 107 | } 108 | 109 | @Override 110 | public Object getId(NamedItem item) { 111 | return item.getClass().getCanonicalName() + item.getId(); 112 | } 113 | 114 | @FunctionalInterface 115 | public interface DataRetriever { 116 | T readRow(ResultSet resultSet) throws SQLException; 117 | } 118 | 119 | private int readInt(String sql, NamedItem parent) { 120 | try (Connection connection = DBEngine.getDataSource().getConnection(); 121 | PreparedStatement statement = connection.prepareStatement(sql)) { 122 | if (parent != null) statement.setLong(1, parent.getId()); 123 | try (ResultSet resultSet = statement.executeQuery()) { 124 | resultSet.next(); 125 | return resultSet.getInt(1); 126 | } 127 | } catch (SQLException e) { 128 | throw new RuntimeException(e); 129 | } 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/crud/ProductDataProviderImpl.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.crud; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collection; 5 | import java.util.List; 6 | import java.util.Locale; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.Stream; 9 | import java.util.stream.StreamSupport; 10 | 11 | import javax.transaction.Transactional; 12 | 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.data.domain.PageRequest; 15 | import org.springframework.data.domain.Pageable; 16 | import org.springframework.data.domain.Sort; 17 | import org.springframework.data.domain.Sort.Direction; 18 | import org.springframework.data.domain.Sort.Order; 19 | import org.springframework.stereotype.Service; 20 | 21 | import com.vaadin.data.provider.AbstractBackEndDataProvider; 22 | import com.vaadin.data.provider.Query; 23 | import com.vaadin.framework8.samples.backend.data.Availability; 24 | import com.vaadin.framework8.samples.backend.data.Category; 25 | import com.vaadin.framework8.samples.backend.data.Product; 26 | import com.vaadin.framework8.samples.backend.repository.CategoryRepository; 27 | import com.vaadin.framework8.samples.backend.repository.ProductRepository; 28 | import com.vaadin.shared.data.sort.SortDirection; 29 | import com.vaadin.ui.UI; 30 | 31 | /** 32 | * DataProvider implementation for managing {@code ProductRepository} and 33 | * filtering. 34 | */ 35 | @Service 36 | public class ProductDataProviderImpl 37 | extends AbstractBackEndDataProvider 38 | implements ProductDataProvider { 39 | 40 | private static class PageQuery { 41 | Pageable pageable; 42 | int pageOffset; 43 | } 44 | 45 | @Autowired 46 | private ProductRepository productRepo; 47 | 48 | @Autowired 49 | private CategoryRepository categoryRepo; 50 | 51 | @Override 52 | @Transactional 53 | public int sizeInBackEnd(Query t) { 54 | return (int) getItems(getPaging(t).pageable, getFilter(t)).count(); 55 | } 56 | 57 | private String getFilter(Query t) { 58 | return t.getFilter().orElse(null); 59 | } 60 | 61 | @Override 62 | @Transactional 63 | public Stream fetchFromBackEnd(Query t) { 64 | PageQuery pageQuery = getPaging(t); 65 | return getItems(pageQuery.pageable, getFilter(t)) 66 | .skip(pageQuery.pageOffset).limit(t.getLimit()); 67 | } 68 | 69 | @Transactional 70 | @Override 71 | public void save(Product product) { 72 | productRepo.save(product); 73 | refreshAll(); 74 | } 75 | 76 | @Transactional 77 | @Override 78 | public void delete(Product product) { 79 | productRepo.delete(product); 80 | refreshAll(); 81 | } 82 | 83 | private Collection getFilteredCategories(String string) { 84 | return categoryRepo.findAllByNameContainingIgnoreCase(string); 85 | } 86 | 87 | private List getFilteredAvailabilities(String string) { 88 | Locale locale = UI.getCurrent().getLocale(); 89 | return Arrays.stream(Availability.values()) 90 | .filter(a -> a.name().toLowerCase(locale).contains(string)) 91 | .collect(Collectors.toList()); 92 | } 93 | 94 | private Stream getItems(Pageable page, String filterText) { 95 | if (filterText == null || filterText.isEmpty()) { 96 | return StreamSupport.stream(productRepo.findAll(page).spliterator(), 97 | false); 98 | } 99 | String filter = filterText.toLowerCase(UI.getCurrent().getLocale()); 100 | return productRepo 101 | .findDistinctByProductNameContainingIgnoreCaseOrAvailabilityInOrCategoryIn( 102 | filter, getFilteredAvailabilities(filter), 103 | getFilteredCategories(filter), page) 104 | .stream(); 105 | } 106 | 107 | /** 108 | * Return a PageQuery object containing page request and offset in page. 109 | * 110 | * @param q 111 | * the original query 112 | * @return paged query 113 | */ 114 | private PageQuery getPaging(Query q) { 115 | final PageQuery p = new PageQuery(); 116 | int start = q.getOffset(); 117 | int end = q.getOffset() + q.getLimit(); 118 | 119 | if (start < end - start) { 120 | p.pageable = getPageRequest(q, 0, end); 121 | p.pageOffset = q.getOffset(); 122 | } else { 123 | // Calculate the page that fits the full requested index range 124 | int size = end - start; 125 | while (start / size != (end - 1) / size) { 126 | ++size; 127 | } 128 | p.pageable = getPageRequest(q, start / size, size); 129 | // Set the offset on page to filter out unneeded results 130 | p.pageOffset = start % size; 131 | } 132 | 133 | return p; 134 | } 135 | 136 | private PageRequest getPageRequest(Query q, int pageIndex, 137 | int pageLength) { 138 | if (!q.getSortOrders().isEmpty()) { 139 | return new PageRequest(pageIndex, pageLength, getSorting(q)); 140 | } else { 141 | return new PageRequest(pageIndex, pageLength); 142 | } 143 | } 144 | 145 | private Sort getSorting(Query q) { 146 | return new Sort(q.getSortOrders().stream() 147 | .map(so -> new Order( 148 | so.getDirection() == SortDirection.ASCENDING 149 | ? Direction.ASC : Direction.DESC, 150 | so.getSorted())) 151 | .collect(Collectors.toList())); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/crud/SampleCrudView.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.crud; 2 | 3 | import javax.annotation.PostConstruct; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | 7 | import com.vaadin.data.provider.ConfigurableFilterDataProvider; 8 | import com.vaadin.framework8.samples.backend.DataService; 9 | import com.vaadin.framework8.samples.backend.data.Product; 10 | import com.vaadin.framework8.samples.crud.ProductForm.ProductFormFactory; 11 | import com.vaadin.framework8.samples.crud.SampleCrudLogic.SampleCrudLogicFactory; 12 | import com.vaadin.icons.VaadinIcons; 13 | import com.vaadin.navigator.View; 14 | import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; 15 | import com.vaadin.spring.annotation.SpringView; 16 | import com.vaadin.ui.Alignment; 17 | import com.vaadin.ui.Button; 18 | import com.vaadin.ui.CssLayout; 19 | import com.vaadin.ui.HorizontalLayout; 20 | import com.vaadin.ui.Notification; 21 | import com.vaadin.ui.Notification.Type; 22 | import com.vaadin.ui.TextField; 23 | import com.vaadin.ui.VerticalLayout; 24 | import com.vaadin.ui.themes.ValoTheme; 25 | 26 | /** 27 | * A view for performing create-read-update-delete operations on products. 28 | * 29 | * See also {@link SampleCrudLogic} for fetching the data, the actual CRUD 30 | * operations and controlling the view based on events from outside. 31 | */ 32 | @SpringView(name = SampleCrudView.VIEW_NAME) 33 | public class SampleCrudView extends CssLayout implements View { 34 | 35 | public static final String VIEW_NAME = "Inventory"; 36 | private ProductGrid grid; 37 | 38 | @Autowired 39 | private ProductFormFactory formFactory; 40 | 41 | @Autowired 42 | private DataService dataService; 43 | 44 | @Autowired 45 | private ProductDataProvider dataProvider; 46 | 47 | private ProductForm form; 48 | 49 | private SampleCrudLogic viewLogic; 50 | private Button newProduct; 51 | 52 | @Autowired 53 | private SampleCrudLogicFactory logicFactory; 54 | private TextField filter; 55 | private ConfigurableFilterDataProvider filterDataProvider; 56 | 57 | public HorizontalLayout createTopBar() { 58 | filter = new TextField(); 59 | filter.setStyleName("filter-textfield"); 60 | filter.setPlaceholder("Filter"); 61 | // Trigger a refresh of data when the filter is updated 62 | filter.addValueChangeListener( 63 | event -> filterDataProvider.setFilter(event.getValue())); 64 | 65 | newProduct = new Button("New product"); 66 | newProduct.addStyleName(ValoTheme.BUTTON_PRIMARY); 67 | newProduct.setIcon(VaadinIcons.PLUS_CIRCLE); 68 | newProduct.addClickListener(event -> viewLogic.newProduct()); 69 | 70 | HorizontalLayout topLayout = new HorizontalLayout(); 71 | topLayout.setWidth("100%"); 72 | topLayout.addComponent(filter); 73 | topLayout.addComponent(newProduct); 74 | topLayout.setComponentAlignment(filter, Alignment.MIDDLE_LEFT); 75 | topLayout.setExpandRatio(filter, 1); 76 | topLayout.setStyleName("top-bar"); 77 | return topLayout; 78 | } 79 | 80 | @Override 81 | public void enter(ViewChangeEvent event) { 82 | viewLogic.enter(event.getParameters()); 83 | } 84 | 85 | public void showError(String msg) { 86 | Notification.show(msg, Type.ERROR_MESSAGE); 87 | } 88 | 89 | public void showSaveNotification(String msg) { 90 | Notification.show(msg, Type.TRAY_NOTIFICATION); 91 | } 92 | 93 | public void setNewProductEnabled(boolean enabled) { 94 | newProduct.setEnabled(enabled); 95 | } 96 | 97 | public void clearSelection() { 98 | grid.getSelectionModel().deselectAll(); 99 | } 100 | 101 | public void selectRow(Product row) { 102 | grid.getSelectionModel().select(row); 103 | } 104 | 105 | public Product getSelectedRow() { 106 | return grid.getSelectedRow(); 107 | } 108 | 109 | public void editProduct(Product product) { 110 | if (product != null) { 111 | form.addStyleName("visible"); 112 | form.setEnabled(true); 113 | } else { 114 | form.removeStyleName("visible"); 115 | // Issue #286 116 | // form.setEnabled(false); 117 | } 118 | form.editProduct(product); 119 | } 120 | 121 | public void updateProduct(Product product) { 122 | dataProvider.save(product); 123 | // TODO: Grid used to scroll to the updated item 124 | } 125 | 126 | public void removeProduct(Product product) { 127 | dataProvider.delete(product); 128 | } 129 | 130 | @PostConstruct 131 | private void init() { 132 | viewLogic = logicFactory.createLogic(this); 133 | 134 | setSizeFull(); 135 | addStyleName("crud-view"); 136 | HorizontalLayout topLayout = createTopBar(); 137 | 138 | grid = new ProductGrid(); 139 | grid.asSingleSelect().addValueChangeListener( 140 | event -> viewLogic.rowSelected(grid.getSelectedRow())); 141 | 142 | filterDataProvider = dataProvider.withConfigurableFilter(); 143 | grid.setDataProvider(filterDataProvider); 144 | 145 | VerticalLayout barAndGridLayout = new VerticalLayout(); 146 | barAndGridLayout.addComponent(topLayout); 147 | barAndGridLayout.addComponent(grid); 148 | barAndGridLayout.setSizeFull(); 149 | barAndGridLayout.setMargin(false); 150 | barAndGridLayout.setSpacing(false); 151 | barAndGridLayout.setExpandRatio(grid, 1); 152 | barAndGridLayout.setStyleName("crud-main-layout"); 153 | 154 | addComponent(barAndGridLayout); 155 | 156 | form = formFactory.createForm(viewLogic); 157 | form.setCategories(dataService.getAllCategories()); 158 | addComponent(form); 159 | 160 | viewLogic.init(); 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/src/main/java/com/vaadin/framework8/samples/crud/ProductForm.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.framework8.samples.crud; 2 | 3 | import java.text.DecimalFormat; 4 | import java.text.NumberFormat; 5 | import java.util.Collection; 6 | import java.util.Locale; 7 | 8 | import javax.annotation.PostConstruct; 9 | 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.beans.factory.config.ConfigurableBeanFactory; 12 | import org.springframework.context.ApplicationContext; 13 | import org.springframework.context.annotation.Scope; 14 | 15 | import com.vaadin.data.BeanValidationBinder; 16 | import com.vaadin.data.Binder; 17 | import com.vaadin.data.Result; 18 | import com.vaadin.data.StatusChangeEvent; 19 | import com.vaadin.data.ValueContext; 20 | import com.vaadin.data.converter.StringToIntegerConverter; 21 | import com.vaadin.framework8.samples.backend.data.Availability; 22 | import com.vaadin.framework8.samples.backend.data.Category; 23 | import com.vaadin.framework8.samples.backend.data.Product; 24 | import com.vaadin.server.Page; 25 | import com.vaadin.spring.annotation.SpringComponent; 26 | 27 | /** 28 | * A form for editing a single product. 29 | * 30 | * Using responsive layouts, the form can be displayed either sliding out on the 31 | * side of the view or filling the whole screen - see the theme for the related 32 | * CSS rules. 33 | */ 34 | @SpringComponent 35 | @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 36 | public class ProductForm extends ProductFormDesign { 37 | 38 | private SampleCrudLogic viewLogic; 39 | private final Binder binder = new BeanValidationBinder<>(Product.class); 40 | 41 | @SpringComponent 42 | @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) 43 | public static class ProductFormFactory { 44 | 45 | @Autowired 46 | private ApplicationContext context; 47 | 48 | public ProductForm createForm(SampleCrudLogic logic) { 49 | ProductForm form = context.getBean(ProductForm.class); 50 | form.init(logic); 51 | return form; 52 | } 53 | } 54 | 55 | private static class StockPriceConverter extends StringToIntegerConverter { 56 | 57 | public StockPriceConverter() { 58 | super("Could not convert value to " + Integer.class.getName()); 59 | } 60 | 61 | @Override 62 | protected NumberFormat getFormat(Locale locale) { 63 | // do not use a thousands separator, as HTML5 input type 64 | // number expects a fixed wire/DOM number format regardless 65 | // of how the browser presents it to the user (which could 66 | // depend on the browser locale) 67 | DecimalFormat format = new DecimalFormat(); 68 | format.setMaximumFractionDigits(0); 69 | format.setDecimalSeparatorAlwaysShown(false); 70 | format.setParseIntegerOnly(true); 71 | format.setGroupingUsed(false); 72 | return format; 73 | } 74 | 75 | @Override 76 | public Result convertToModel(String value, 77 | ValueContext context) { 78 | Result result = super.convertToModel(value, context); 79 | return result.map(stock -> stock == null ? 0 : stock); 80 | } 81 | 82 | } 83 | 84 | private Product currentProduct; 85 | 86 | private ProductForm() { 87 | } 88 | 89 | public void setCategories(Collection categories) { 90 | category.setItems(categories); 91 | } 92 | 93 | public void editProduct(Product product) { 94 | currentProduct = product; 95 | setUpData(); 96 | 97 | delete.setEnabled(product != null && product.getId() != -1); 98 | 99 | // Scroll to the top 100 | // As this is not a Panel, using JavaScript 101 | String scrollScript = "window.document.getElementById('" + getId() 102 | + "').scrollTop = 0;"; 103 | Page.getCurrent().getJavaScript().execute(scrollScript); 104 | } 105 | 106 | @PostConstruct 107 | private void init() { 108 | addStyleName("product-form"); 109 | 110 | availability.setItems(Availability.values()); 111 | 112 | binder.forField(price).withConverter(new EuroConverter()).bind("price"); 113 | binder.forField(productName).bind("productName"); 114 | 115 | binder.forField(availability).bind("availability"); 116 | 117 | save.addClickListener(event -> onSave()); 118 | 119 | cancel.addClickListener(event -> viewLogic.cancelProduct()); 120 | delete.addClickListener(event -> onDelete()); 121 | discard.addClickListener(event -> setUpData()); 122 | 123 | category.setItemCaptionGenerator(Category::getName); 124 | binder.forField(category).bind("category"); 125 | binder.forField(stockCount).withConverter(new StockPriceConverter()) 126 | .bind("stockCount"); 127 | 128 | binder.addStatusChangeListener(this::updateButtons); 129 | } 130 | 131 | private void onSave() { 132 | if (binder.writeBeanIfValid(currentProduct)) { 133 | viewLogic.saveProduct(currentProduct); 134 | } 135 | } 136 | 137 | private void onDelete() { 138 | if (currentProduct != null) { 139 | viewLogic.deleteProduct(currentProduct); 140 | } 141 | } 142 | 143 | private void init(SampleCrudLogic logic) { 144 | viewLogic = logic; 145 | } 146 | 147 | private void updateButtons(StatusChangeEvent event) { 148 | boolean changes = event.getBinder().hasChanges(); 149 | boolean validationErrors = event.hasValidationErrors(); 150 | 151 | save.setEnabled(!validationErrors && changes); 152 | discard.setEnabled(changes); 153 | } 154 | 155 | private void setUpData() { 156 | if (currentProduct != null) { 157 | binder.readBean(currentProduct); 158 | } else { 159 | binder.removeBean(); 160 | } 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /spring-demo/spring-demo-ui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | spring-demo 6 | com.vaadin.framework8 7 | 8.1.6 8 | 9 | 4.0.0 10 | 11 | spring-demo-ui 12 | spring-demo-ui 13 | war 14 | 15 | 16 | 17 | 18 | ${project.groupId} 19 | spring-demo-backend 20 | ${project.version} 21 | 22 | 23 | 24 | com.vaadin 25 | vaadin-spring-boot-starter 26 | 27 | 28 | 29 | com.vaadin 30 | vaadin-shared 31 | 32 | 33 | com.vaadin 34 | vaadin-push 35 | 36 | 37 | com.vaadin 38 | vaadin-client-compiled 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-test 44 | test 45 | 46 | 47 | 48 | com.vaadin.framework8 49 | test-util 50 | test 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-war-plugin 60 | 61 | 64 | true 65 | 67 | WEB-INF/classes/VAADIN/gwt-unitCache/**, 68 | WEB-INF/classes/VAADIN/widgetsets/WEB-INF/** 69 | 70 | 71 | 72 | com.vaadin 73 | vaadin-maven-plugin 74 | 75 | 76 | 77 | update-theme 78 | 80 | compile-theme 81 | 82 | 83 | 84 | 85 | 86 | org.springframework.boot 87 | spring-boot-maven-plugin 88 | 1.5.1.RELEASE 89 | 90 | ${skipTests} 91 | 96 | true 97 | -Djava.security.egd=file:/dev/./urandom 98 | -Dserver.port=8888 99 | 100 | 101 | 102 | pre-integration-test 103 | 104 | start 105 | 106 | 107 | 108 | post-integration-test 109 | 110 | stop 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 120 | 121 | org.eclipse.m2e 122 | lifecycle-mapping 123 | 1.0.0 124 | 125 | 126 | 127 | 128 | 129 | com.vaadin 130 | 131 | vaadin-maven-plugin 132 | 133 | 134 | [7.6.8,) 135 | 136 | 137 | update-theme 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /todomvc/src/main/java/com/vaadin/tutorial/todomvc/TodoModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2016 Vaadin Ltd. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.vaadin.tutorial.todomvc; 17 | 18 | import java.sql.Connection; 19 | import java.sql.DriverManager; 20 | import java.sql.PreparedStatement; 21 | import java.sql.ResultSet; 22 | import java.sql.SQLException; 23 | import java.sql.Statement; 24 | 25 | import javax.sql.DataSource; 26 | 27 | import org.apache.commons.dbcp2.BasicDataSource; 28 | 29 | /** 30 | * Model for the database, HSQLDB dialect is used, in-memory database 31 | * 32 | * @author Vaadin Ltd 33 | */ 34 | public class TodoModel { 35 | 36 | /* 37 | * Basic pollable DataSource is used here. That is mandatory for any web 38 | * application: In case of high load application the pool limits number of 39 | * physical database connections. In case of low load application, 40 | * connection pool fixes stall jdbc connection problem. 41 | */ 42 | private volatile static BasicDataSource dataSource; 43 | 44 | private final Connection conn; 45 | private final TodoJDBCDataProvider dataProvider; 46 | 47 | public TodoModel() { 48 | try { 49 | DriverManager 50 | .registerDriver(org.hsqldb.jdbc.JDBCDriver.driverInstance); 51 | conn = getDataSource().getConnection(); 52 | dataProvider = setupDataProvider(); 53 | } catch (SQLException e) { 54 | throw new RuntimeException("Model initialization failed", e); 55 | } 56 | } 57 | 58 | private static DataSource getDataSource() { 59 | if (dataSource == null) { 60 | synchronized (TodoModel.class) { 61 | // Standard double check trick to avoid double initialization 62 | // in case of race conditions 63 | if (dataSource == null) { 64 | dataSource = new BasicDataSource(); 65 | dataSource.setUrl("jdbc:hsqldb:mem:tododb"); 66 | dataSource.setUsername("SA"); 67 | dataSource.setPassword(""); 68 | try (Connection connection = dataSource.getConnection()) { 69 | setupDatabase(connection); 70 | } catch (SQLException e) { 71 | throw new RuntimeException(e); 72 | } 73 | } 74 | } 75 | } 76 | return dataSource; 77 | } 78 | 79 | private TodoJDBCDataProvider setupDataProvider() throws SQLException { 80 | return new TodoJDBCDataProvider(conn); 81 | } 82 | 83 | private static void setupDatabase(Connection connection) { 84 | try (Statement s = connection.createStatement()) { 85 | s.execute( 86 | "CREATE TABLE todo (id INTEGER IDENTITY PRIMARY KEY, text VARCHAR(255) , completed BOOLEAN)"); 87 | } catch (SQLException ignored) { 88 | // Nothing to do here, because 89 | // the table already exists, re-creation failed 90 | } 91 | } 92 | 93 | public int getCompleted() { 94 | return readInteger("select count(*) from todo where COMPLETED"); 95 | } 96 | 97 | private int readInteger(String sql) { 98 | try (Statement s = conn.createStatement()) { 99 | ResultSet resultSet = s.executeQuery(sql); 100 | resultSet.next(); 101 | return resultSet.getInt(1); 102 | } catch (SQLException e) { 103 | throw new RuntimeException( 104 | String.format("Data retrieve failed(%s)", sql), e); 105 | } 106 | } 107 | 108 | public int getActive() { 109 | return readInteger("select count(*) from todo where not COMPLETED"); 110 | } 111 | 112 | public TodoJDBCDataProvider getDataProvider() { 113 | return dataProvider; 114 | } 115 | 116 | public Todo persist(Todo todo) { 117 | if (todo.getId() < 0) { 118 | try (PreparedStatement s = conn.prepareStatement( 119 | "INSERT INTO todo(id, text, completed) VALUES (NULL, ?, ?)", 120 | Statement.RETURN_GENERATED_KEYS)) { 121 | s.setString(1, todo.getText()); 122 | s.setBoolean(2, todo.isCompleted()); 123 | s.executeUpdate(); 124 | ResultSet generatedKeys = s.getGeneratedKeys(); 125 | generatedKeys.next(); 126 | todo.setId(generatedKeys.getInt(1)); 127 | } catch (SQLException e) { 128 | throw new RuntimeException("ToDo insertion failed", e); 129 | } 130 | } else { 131 | try (PreparedStatement s = conn.prepareStatement( 132 | "UPDATE todo SET text= ?,completed=? WHERE id = ?")) { 133 | s.setString(1, todo.getText()); 134 | s.setBoolean(2, todo.isCompleted()); 135 | s.setInt(3, todo.getId()); 136 | s.execute(); 137 | if (s.getUpdateCount() != 1) { 138 | throw new RuntimeException( 139 | "Todo update failed (non-existing id?): " + todo); 140 | } 141 | } catch (SQLException e) { 142 | throw new RuntimeException("Todo update failed", e); 143 | } 144 | } 145 | return todo; 146 | } 147 | 148 | public void drop(Todo todo) { 149 | try (Statement s = conn.createStatement()) { 150 | s.execute("DELETE FROM todo WHERE id = " + todo.getId()); 151 | if (s.getUpdateCount() != 1) { 152 | throw new RuntimeException( 153 | "Deletion failed(non-existing id?): " + todo); 154 | } 155 | } catch (SQLException e) { 156 | throw new RuntimeException("Deletion failed", e); 157 | } 158 | } 159 | 160 | public void clearCompleted() { 161 | try (Statement s = conn.createStatement()) { 162 | s.execute("DELETE FROM todo WHERE completed"); 163 | } catch (SQLException e) { 164 | throw new RuntimeException("Deletion of completed items failed", e); 165 | } 166 | } 167 | 168 | public void markAllCompleted(boolean completed) { 169 | try (PreparedStatement s = conn 170 | .prepareStatement("UPDATE todo SET completed=?")) { 171 | s.setBoolean(1, completed); 172 | s.execute(); 173 | } catch (SQLException e) { 174 | throw new RuntimeException("Update failed", e); 175 | } 176 | } 177 | 178 | } 179 | -------------------------------------------------------------------------------- /registration-form/src/main/java/com/vaadin/demo/registration/RegistrationFormUI.java: -------------------------------------------------------------------------------- 1 | package com.vaadin.demo.registration; 2 | 3 | import java.util.Objects; 4 | 5 | import javax.servlet.annotation.WebServlet; 6 | 7 | import com.vaadin.annotations.Theme; 8 | import com.vaadin.annotations.Title; 9 | import com.vaadin.annotations.VaadinServletConfiguration; 10 | import com.vaadin.data.Binder; 11 | import com.vaadin.data.Binder.Binding; 12 | import com.vaadin.data.BindingValidationStatus; 13 | import com.vaadin.data.BindingValidationStatus.Status; 14 | import com.vaadin.data.HasValue; 15 | import com.vaadin.data.Validator; 16 | import com.vaadin.icons.VaadinIcons; 17 | import com.vaadin.server.VaadinRequest; 18 | import com.vaadin.server.VaadinServlet; 19 | import com.vaadin.ui.AbstractTextField; 20 | import com.vaadin.ui.Button; 21 | import com.vaadin.ui.HorizontalLayout; 22 | import com.vaadin.ui.Label; 23 | import com.vaadin.ui.Layout; 24 | import com.vaadin.ui.Notification; 25 | import com.vaadin.ui.Notification.Type; 26 | import com.vaadin.ui.PasswordField; 27 | import com.vaadin.ui.TextField; 28 | import com.vaadin.ui.UI; 29 | import com.vaadin.ui.VerticalLayout; 30 | import com.vaadin.ui.themes.ValoTheme; 31 | 32 | @Title("Registration Form") 33 | @Theme("registration") 34 | public class RegistrationFormUI extends UI { 35 | 36 | private static final int WIDTH = 350; 37 | 38 | private final Binder binder = new Binder<>(); 39 | 40 | private Binding passwordBinding; 41 | private Binding confirmPasswordBinding; 42 | 43 | private boolean showConfirmPasswordStatus; 44 | 45 | private static final String VALID = "valid"; 46 | 47 | private void addToLayout(Layout layout, AbstractTextField textField, 48 | String placeHolderText) { 49 | textField.setPlaceholder(placeHolderText); 50 | Label statusMessage = new Label(); 51 | statusMessage.setVisible(false); 52 | statusMessage.addStyleName("validation-message"); 53 | textField.setData(statusMessage); 54 | HorizontalLayout horizontalLayout = new HorizontalLayout(); 55 | horizontalLayout.setSpacing(false); 56 | horizontalLayout.addComponent(textField); 57 | textField.setWidth(WIDTH, Unit.PIXELS); 58 | horizontalLayout.addComponent(statusMessage); 59 | layout.addComponent(horizontalLayout); 60 | } 61 | 62 | @Override 63 | protected void init(VaadinRequest request) { 64 | VerticalLayout layout = new VerticalLayout(); 65 | layout.setWidth(100, Unit.PERCENTAGE); 66 | setContent(layout); 67 | 68 | TextField fullNameField = new TextField(); 69 | addToLayout(layout, fullNameField, "Full name"); 70 | 71 | binder.forField(fullNameField).asRequired("Full name may not be empty") 72 | .withValidationStatusHandler( 73 | status -> commonStatusChangeHandler(status, 74 | fullNameField)) 75 | .bind(Person::getFullName, Person::setFullName); 76 | 77 | TextField phoneOrEmailField = new TextField(); 78 | addToLayout(layout, phoneOrEmailField, "Phone or Email"); 79 | binder.forField(phoneOrEmailField) 80 | .withValidator(new EmailOrPhoneValidator()) 81 | .withValidationStatusHandler( 82 | status -> commonStatusChangeHandler(status, 83 | phoneOrEmailField)) 84 | .bind(Person::getEmailOrPhone, Person::setEmailOrPhone); 85 | 86 | PasswordField passwordField = new PasswordField(); 87 | addToLayout(layout, passwordField, "Password"); 88 | passwordBinding = binder.forField(passwordField) 89 | .withValidator(new PasswordValidator()) 90 | .withValidationStatusHandler( 91 | status -> commonStatusChangeHandler(status, 92 | passwordField)) 93 | .bind(Person::getPassword, Person::setPassword); 94 | passwordField.addValueChangeListener( 95 | event -> confirmPasswordBinding.validate()); 96 | 97 | PasswordField confirmPasswordField = new PasswordField(); 98 | addToLayout(layout, confirmPasswordField, "Password again"); 99 | 100 | confirmPasswordBinding = binder.forField(confirmPasswordField) 101 | .withValidator(Validator.from(this::validateConfirmPasswd, 102 | "Password doesn't match")) 103 | .withValidationStatusHandler( 104 | status -> confirmPasswordStatusChangeHandler(status, 105 | confirmPasswordField)) 106 | .bind(Person::getPassword, (person, pwd) -> { 107 | }); 108 | 109 | layout.addComponent(createButton()); 110 | 111 | fullNameField.focus(); 112 | 113 | binder.setBean(new Person()); 114 | } 115 | 116 | private Button createButton() { 117 | Button button = new Button("Sign Up", event -> save()); 118 | button.addStyleName(ValoTheme.BUTTON_PRIMARY); 119 | button.setWidth(WIDTH, Unit.PIXELS); 120 | return button; 121 | } 122 | 123 | private void commonStatusChangeHandler(BindingValidationStatus event, 124 | AbstractTextField field) { 125 | Label statusLabel = (Label) field.getData(); 126 | statusLabel.setVisible(!event.getStatus().equals(Status.UNRESOLVED)); 127 | switch (event.getStatus()) { 128 | case OK: 129 | statusLabel.setValue(""); 130 | statusLabel.setIcon(VaadinIcons.CHECK); 131 | statusLabel.getParent().addStyleName(VALID); 132 | break; 133 | case ERROR: 134 | statusLabel.setIcon(VaadinIcons.CLOSE); 135 | statusLabel.setValue(event.getMessage().orElse("Unknown error")); 136 | statusLabel.getParent().removeStyleName(VALID); 137 | default: 138 | break; 139 | } 140 | } 141 | 142 | private void confirmPasswordStatusChangeHandler( 143 | BindingValidationStatus event, AbstractTextField field) { 144 | commonStatusChangeHandler(event, field); 145 | Label statusLabel = (Label) field.getData(); 146 | statusLabel.setVisible(showConfirmPasswordStatus); 147 | } 148 | 149 | private boolean validateConfirmPasswd(String confirmPasswordValue) { 150 | showConfirmPasswordStatus = false; 151 | if (confirmPasswordValue.isEmpty()) { 152 | return true; 153 | 154 | } 155 | BindingValidationStatus status = passwordBinding.validate(); 156 | if (status.isError()) { 157 | return true; 158 | } 159 | showConfirmPasswordStatus = true; 160 | HasValue pwdField = passwordBinding.getField(); 161 | return Objects.equals(pwdField.getValue(), confirmPasswordValue); 162 | } 163 | 164 | private void save() { 165 | Person person = new Person(); 166 | if (binder.writeBeanIfValid(person)) { 167 | Notification.show("Registration data saved successfully", 168 | String.format("Full name '%s', email or phone '%s'", 169 | person.getFullName(), person.getEmailOrPhone()), 170 | Type.HUMANIZED_MESSAGE); 171 | } else { 172 | Notification.show( 173 | "Registration could not be saved, please check all fields", 174 | Type.ERROR_MESSAGE); 175 | } 176 | } 177 | 178 | @WebServlet(urlPatterns = "/*") 179 | @VaadinServletConfiguration(ui = RegistrationFormUI.class, productionMode = false) 180 | public static class MyUIServlet extends VaadinServlet { 181 | } 182 | } 183 | --------------------------------------------------------------------------------