From 24c6da9ee5c5a7c464a7f3aa849356eb9885cead Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Wed, 3 Jun 2015 11:30:06 +0300 Subject: Reset heartbeat timestamp when reopening UI (#18101) Change-Id: I288bae95e364277819727a99854d94fbbc98b162 --- server/src/com/vaadin/ui/UI.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'server') diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index b16d7e32d3..2129db614b 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -718,6 +718,9 @@ public abstract class UI extends AbstractSingleComponentContainer implements page.init(request); + // Reset heartbeat timeout to avoid surprise if it's almost expired + setLastHeartbeatTimestamp(System.currentTimeMillis()); + refresh(request); URI newLocation = page.getLocation(); -- cgit v1.2.3 From 177805d898b1f6ed39ab5fb6a0c73ca98103b172 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 28 May 2015 10:55:35 +0300 Subject: Remove redundant array copy (#18040) Change-Id: I86ffcd63441ab55a4fec95b1ba7bd017cabd4c72 --- server/src/com/vaadin/server/ServerRpcManager.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'server') diff --git a/server/src/com/vaadin/server/ServerRpcManager.java b/server/src/com/vaadin/server/ServerRpcManager.java index 3a2cb3a32c..ae99622a4a 100644 --- a/server/src/com/vaadin/server/ServerRpcManager.java +++ b/server/src/com/vaadin/server/ServerRpcManager.java @@ -153,19 +153,9 @@ public class ServerRpcManager implements Serializable { public void applyInvocation(ServerRpcMethodInvocation invocation) throws RpcInvocationException { Method method = invocation.getMethod(); - Class[] parameterTypes = method.getParameterTypes(); - Object[] args = new Object[parameterTypes.length]; Object[] arguments = invocation.getParameters(); - for (int i = 0; i < args.length; i++) { - // no conversion needed for basic cases - // Class type = parameterTypes[i]; - // if (type.isPrimitive()) { - // type = boxedTypes.get(type); - // } - args[i] = arguments[i]; - } try { - method.invoke(implementation, args); + method.invoke(implementation, arguments); } catch (Exception e) { throw new RpcInvocationException("Unable to invoke method " + invocation.getMethodName() + " in " -- cgit v1.2.3 From 3deceaa2c18bdf4978edb7978ba95c7c979863bf Mon Sep 17 00:00:00 2001 From: Teppo Kurki Date: Thu, 4 Jun 2015 23:06:01 +0300 Subject: Forget GridLayout column expand ratios when removing columns (#18068) Change-Id: I49e3e54a3e408a2c82ff5d2a0d51c037f60397c5 --- server/src/com/vaadin/ui/GridLayout.java | 9 ++- .../com/vaadin/ui/GridLayoutExpandRatioTest.java | 82 ++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java (limited to 'server') diff --git a/server/src/com/vaadin/ui/GridLayout.java b/server/src/com/vaadin/ui/GridLayout.java index 35110b39ab..e510fa09fb 100644 --- a/server/src/com/vaadin/ui/GridLayout.java +++ b/server/src/com/vaadin/ui/GridLayout.java @@ -782,7 +782,14 @@ public class GridLayout extends AbstractLayout implements } } } - // TODO forget expands for removed columns + + // Forget expands for removed columns + if (columns < getColumns()) { + for (int i = columns - 1; i < getColumns(); i++) { + columnExpandRatio.remove(i); + getState().explicitColRatios.remove(i); + } + } getState().columns = columns; } diff --git a/server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java b/server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java new file mode 100644 index 0000000000..685befaab4 --- /dev/null +++ b/server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.ui; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.server.Sizeable.Unit; + +public class GridLayoutExpandRatioTest { + + private GridLayout gridLayout; + + @Test + public void testColExpandRatioIsForgotten() { + gridLayout = new GridLayout(4, 1); + gridLayout.setWidth(100, Unit.PERCENTAGE); + gridLayout.setSpacing(true); + + addComponents(true); + + gridLayout.setColumnExpandRatio(1, 1); + gridLayout.setColumnExpandRatio(3, 1); + + assertTrue(gridLayout.getColumnExpandRatio(0) == 0); + assertTrue(gridLayout.getColumnExpandRatio(1) == 1); + assertTrue(gridLayout.getColumnExpandRatio(2) == 0); + assertTrue(gridLayout.getColumnExpandRatio(3) == 1); + assertFalse(gridLayout.getState().explicitColRatios.contains(0)); + assertTrue(gridLayout.getState().explicitColRatios.contains(1)); + assertFalse(gridLayout.getState().explicitColRatios.contains(2)); + assertTrue(gridLayout.getState().explicitColRatios.contains(3)); + + remove(); + + assertTrue(gridLayout.getColumnExpandRatio(0) == 0); + assertTrue(gridLayout.getColumnExpandRatio(1) == 1); + assertTrue(gridLayout.getColumnExpandRatio(2) == 0); + assertTrue(gridLayout.getColumnExpandRatio(3) == 0); + assertFalse(gridLayout.getState().explicitColRatios.contains(0)); + assertTrue(gridLayout.getState().explicitColRatios.contains(1)); + assertFalse(gridLayout.getState().explicitColRatios.contains(2)); + assertFalse(gridLayout.getState().explicitColRatios.contains(3)); + + } + + private void remove() { + gridLayout.removeAllComponents(); + gridLayout.setColumns(3); + addComponents(false); + } + + private void addComponents(boolean includeLastOne) { + gridLayout.addComponent(label("{1}")); + gridLayout.addComponent(label("{2}")); + gridLayout.addComponent(label("{3}")); + if (includeLastOne) { + gridLayout.addComponent(label("{4}")); + } + } + + private Label label(String content) { + Label label = new Label(content); + label.setSizeUndefined(); + return label; + } +} -- cgit v1.2.3 From d5860be5b6043c9b6f9a1b5b1550b1666af2d6ef Mon Sep 17 00:00:00 2001 From: Teppo Kurki Date: Wed, 3 Jun 2015 14:26:35 +0300 Subject: Use headerCaption as default hidingToggleCaption (#18028) Change-Id: Ifaf288da98d6d1d1c02760784b832cb5b5d93c07 --- .../vaadin/client/connectors/GridConnector.java | 2 ++ client/src/com/vaadin/client/widgets/Grid.java | 4 +-- server/src/com/vaadin/ui/Grid.java | 34 ++++++++++++---------- .../tests/server/component/grid/GridColumns.java | 16 ++++++++++ .../com/vaadin/shared/ui/grid/GridColumnState.java | 3 ++ .../grid/basicfeatures/GridBasicFeatures.java | 12 ++++++++ .../server/GridColumnVisibilityTest.java | 28 ++++++++++++++++++ 7 files changed, 82 insertions(+), 17 deletions(-) (limited to 'server') diff --git a/client/src/com/vaadin/client/connectors/GridConnector.java b/client/src/com/vaadin/client/connectors/GridConnector.java index d3fa678c3e..f2246b1e5f 100644 --- a/client/src/com/vaadin/client/connectors/GridConnector.java +++ b/client/src/com/vaadin/client/connectors/GridConnector.java @@ -1198,6 +1198,8 @@ public class GridConnector extends AbstractHasComponentsConnector implements column.setSortable(state.sortable); + column.setHeaderCaption(state.headerCaption); + column.setHidden(state.hidden); column.setHidable(state.hidable); column.setHidingToggleCaption(state.hidingToggleCaption); diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index 9393ffb48c..fa74b16317 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -4390,8 +4390,8 @@ public class Grid extends ResizeComposite implements * for this column in the grid's sidebar when the column is * {@link #isHidable() hidable}. *

- * Defaults to null, when will use whatever is set with - * {@link #setHeaderCaption(String)}. + * The default value is null. In this case the header + * caption is used, see {@link #setHeaderCaption(String)}. * * @since 7.5.0 * @param hidingToggleCaption diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java index c061a81b73..96884d7fd5 100644 --- a/server/src/com/vaadin/ui/Grid.java +++ b/server/src/com/vaadin/ui/Grid.java @@ -2441,9 +2441,10 @@ public class Grid extends AbstractComponent implements SelectionNotifier, private Converter converter; /** - * A check for allowing the {@link #Column(Grid, GridColumnState, Object) - * constructor} to call {@link #setConverter(Converter)} with a - * null, even if model and renderer aren't compatible. + * A check for allowing the + * {@link #Column(Grid, GridColumnState, Object) constructor} to call + * {@link #setConverter(Converter)} with a null, even if + * model and renderer aren't compatible. */ private boolean isFirstConverterAssignment = true; @@ -2503,7 +2504,9 @@ public class Grid extends AbstractComponent implements SelectionNotifier, } /** - * Sets the caption of the header. + * Sets the caption of the header. This caption is also used as the + * hiding toggle caption, unless it is explicitly set via + * {@link #setHidingToggleCaption(String)}. * * @param caption * the text to show in the caption @@ -2515,6 +2518,9 @@ public class Grid extends AbstractComponent implements SelectionNotifier, public Column setHeaderCaption(String caption) throws IllegalStateException { checkColumnIsAttached(); + + state.headerCaption = caption; + HeaderRow row = grid.getHeader().getDefaultRow(); if (row != null) { row.getCell(grid.getPropertyIdByColumnId(state.id)).setText( @@ -2542,11 +2548,11 @@ public class Grid extends AbstractComponent implements SelectionNotifier, * toggle for this column in the grid's sidebar when the column is * {@link #isHidable() hidable}. *

- * By default, before triggering this setter, a user friendly version of - * the column's {@link #getPropertyId() property id} is used. + * The default value is null, and in that case the column's + * {@link #getHeaderCaption() header caption} is used. *

- * NOTE: setting this to null or empty string - * might cause the hiding toggle to not render correctly. + * NOTE: setting this to empty string might cause the hiding + * toggle to not render correctly. * * @since 7.5.0 * @param hidingToggleCaption @@ -3207,9 +3213,7 @@ public class Grid extends AbstractComponent implements SelectionNotifier, DesignAttributeHandler.writeAttribute("hidden", attributes, isHidden(), def.hidden, boolean.class); DesignAttributeHandler.writeAttribute("hiding-toggle-caption", - attributes, getHidingToggleCaption(), - SharedUtil.propertyIdToHumanFriendly(getPropertyId()), - String.class); + attributes, getHidingToggleCaption(), null, String.class); DesignAttributeHandler.writeAttribute("property-id", attributes, getPropertyId(), null, Object.class); } @@ -3288,7 +3292,8 @@ public class Grid extends AbstractComponent implements SelectionNotifier, private final String nullRepresentation; - protected AbstractRenderer(Class presentationType, String nullRepresentation) { + protected AbstractRenderer(Class presentationType, + String nullRepresentation) { this.presentationType = presentationType; this.nullRepresentation = nullRepresentation; } @@ -3333,6 +3338,7 @@ public class Grid extends AbstractComponent implements SelectionNotifier, /** * Null representation for the renderer + * * @return a textual representation of {@code null} */ protected String getNullRepresentation() { @@ -4303,7 +4309,6 @@ public class Grid extends AbstractComponent implements SelectionNotifier, String humanFriendlyPropertyId = SharedUtil .propertyIdToHumanFriendly(String.valueOf(datasourcePropertyId)); column.setHeaderCaption(humanFriendlyPropertyId); - column.setHidingToggleCaption(humanFriendlyPropertyId); if (datasource instanceof Sortable && ((Sortable) datasource).getSortableContainerPropertyIds() @@ -4513,8 +4518,7 @@ public class Grid extends AbstractComponent implements SelectionNotifier, * @throws IllegalArgumentException * if {@code rows} is zero or less * @throws IllegalArgumentException - * if {@code rows} is {@link Double#isInfinite(double) - * infinite} + * if {@code rows} is {@link Double#isInfinite(double) infinite} * @throws IllegalArgumentException * if {@code rows} is {@link Double#isNaN(double) NaN} */ diff --git a/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java b/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java index 35553bb406..2b960d26a0 100644 --- a/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java +++ b/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java @@ -338,4 +338,20 @@ public class GridColumns { public void testAddingColumnsWithSetColumnsNonDefaultContainer() { grid.setColumns("column1", "column2", "column50"); } + + @Test + public void testDefaultColumnHidingToggleCaption() { + Column firstColumn = grid.getColumns().get(0); + firstColumn.setHeaderCaption("headerCaption"); + assertEquals(null, firstColumn.getHidingToggleCaption()); + } + + @Test + public void testOverriddenColumnHidingToggleCaption() { + Column firstColumn = grid.getColumns().get(0); + firstColumn.setHidingToggleCaption("hidingToggleCaption"); + firstColumn.setHeaderCaption("headerCaption"); + assertEquals("hidingToggleCaption", + firstColumn.getHidingToggleCaption()); + } } diff --git a/shared/src/com/vaadin/shared/ui/grid/GridColumnState.java b/shared/src/com/vaadin/shared/ui/grid/GridColumnState.java index 5aa9ea9b65..547a4a84ca 100644 --- a/shared/src/com/vaadin/shared/ui/grid/GridColumnState.java +++ b/shared/src/com/vaadin/shared/ui/grid/GridColumnState.java @@ -85,4 +85,7 @@ public class GridColumnState implements Serializable { /** The caption for the column hiding toggle. */ public String hidingToggleCaption; + + /** Column header caption */ + public String headerCaption; } diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java index ecf3d53385..ef51cdf446 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java @@ -908,6 +908,18 @@ public class GridBasicFeatures extends AbstractComponentTest { } }, null, c); + createClickAction("Change header caption", getColumnProperty(c), + new Command() { + int count = 0; + + @Override + public void execute(Grid grid, String value, Object data) { + final String columnProperty = getColumnProperty((Integer) data); + grid.getColumn(columnProperty).setHeaderCaption( + columnProperty + " header " + count++); + } + }, null, c); + createCategory("Column " + c + " Width", getColumnProperty(c)); createClickAction("Auto", "Column " + c + " Width", diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnVisibilityTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnVisibilityTest.java index d01e689b72..e2d7468d08 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnVisibilityTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnVisibilityTest.java @@ -195,6 +195,34 @@ public class GridColumnVisibilityTest extends GridBasicFeaturesTest { assertEquals("Column 1", getColumnHidingToggle(1).getText()); } + @Test + public void testColumnHidingToggleCaption_settingColumnHeaderCaption_toggleCaptionIsEqual() { + toggleColumnHidable(1); + + selectMenuPath("Component", "Columns", "Column 1", + "Change header caption"); + + getSidebarOpenButton().click(); + assertEquals("column 1 header 0", getGridElement().getHeaderCell(0, 1) + .getText().toLowerCase()); + assertEquals("Column 1 header 0", getColumnHidingToggle(1).getText()); + } + + @Test + public void testColumnHidingToggleCaption_explicitlySet_toggleCaptionIsNotOverridden() { + toggleColumnHidable(1); + + selectMenuPath("Component", "Columns", "Column 1", + "Change hiding toggle caption"); + selectMenuPath("Component", "Columns", "Column 1", + "Change header caption"); + + getSidebarOpenButton().click(); + assertEquals("column 1 header 0", getGridElement().getHeaderCell(0, 1) + .getText().toLowerCase()); + assertEquals("Column 1 caption 0", getColumnHidingToggle(1).getText()); + } + private void toggleColumnHidingToggleCaptionChange(int index) { selectMenuPath("Component", "Columns", "Column " + index, "Change hiding toggle caption"); -- cgit v1.2.3 From 27f574154b5e27407370b6e072e5fa13d1d97797 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 2 Jun 2015 21:21:44 +0300 Subject: Better error messages for addColumn/setColumns (#18019, #17890) Change-Id: Iadf455ae6cbc60e0ce0b88fe7c12df946ed08cf0 --- server/src/com/vaadin/ui/Grid.java | 12 ++++- .../server/component/grid/GridContainerTest.java | 54 ++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) (limited to 'server') diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java index 96884d7fd5..2c442d6e43 100644 --- a/server/src/com/vaadin/ui/Grid.java +++ b/server/src/com/vaadin/ui/Grid.java @@ -4139,8 +4139,18 @@ public class Grid extends AbstractComponent implements SelectionNotifier, if (datasource.getContainerPropertyIds().contains(propertyId) && !columns.containsKey(propertyId)) { appendColumn(propertyId); - } else { + } else if (defaultContainer) { addColumnProperty(propertyId, String.class, ""); + } else { + if (columns.containsKey(propertyId)) { + throw new IllegalStateException("A column for property id '" + + propertyId.toString() + + "' already exists in this grid"); + } else { + throw new IllegalStateException("Property id '" + + propertyId.toString() + + "' does not exist in the container"); + } } // Inform the data provider of this new column. diff --git a/server/tests/src/com/vaadin/tests/server/component/grid/GridContainerTest.java b/server/tests/src/com/vaadin/tests/server/component/grid/GridContainerTest.java index cbd448618b..527568eac8 100644 --- a/server/tests/src/com/vaadin/tests/server/component/grid/GridContainerTest.java +++ b/server/tests/src/com/vaadin/tests/server/component/grid/GridContainerTest.java @@ -15,9 +15,11 @@ */ package com.vaadin.tests.server.component.grid; +import org.junit.Assert; import org.junit.Test; import com.vaadin.data.util.IndexedContainer; +import com.vaadin.ui.Grid; public class GridContainerTest { @@ -43,4 +45,56 @@ public class GridContainerTest { container.addItem(0).getItemProperty("x").setValue("y"); return container; } + + @Test + public void setColumnsOrder() { + Grid grid = new Grid(); + IndexedContainer ic = new IndexedContainer(); + ic.addContainerProperty("foo", String.class, ""); + ic.addContainerProperty("baz", String.class, ""); + ic.addContainerProperty("bar", String.class, ""); + grid.setContainerDataSource(ic); + grid.setColumns("foo", "baz", "bar"); + + Assert.assertEquals("foo", grid.getColumns().get(0).getPropertyId()); + Assert.assertEquals("baz", grid.getColumns().get(1).getPropertyId()); + Assert.assertEquals("bar", grid.getColumns().get(2).getPropertyId()); + } + + @Test + public void addColumnNotInContainer() { + Grid grid = new Grid(); + grid.setContainerDataSource(new IndexedContainer()); + try { + grid.addColumn("notInContainer"); + Assert.fail("Adding a property id not in the container should throw an exception"); + } catch (IllegalStateException e) { + Assert.assertTrue(e.getMessage().contains("notInContainer")); + Assert.assertTrue(e.getMessage().contains( + "does not exist in the container")); + } + } + + @Test + public void setColumnsForPropertyIdNotInContainer() { + Grid grid = new Grid(); + grid.setContainerDataSource(new IndexedContainer()); + try { + grid.setColumns("notInContainer", "notThereEither"); + Assert.fail("Setting columns for property ids not in the container should throw an exception"); + } catch (IllegalStateException e) { + // addColumn is run in random order.. + Assert.assertTrue(e.getMessage().contains("notInContainer") + || e.getMessage().contains("notThereEither")); + Assert.assertTrue(e.getMessage().contains( + "does not exist in the container")); + } + } + + @Test(expected = IllegalStateException.class) + public void multipleAddColumnsForDefaultContainer() { + Grid grid = new Grid(); + grid.addColumn("foo"); + grid.addColumn("foo"); + } } -- cgit v1.2.3 From 67b0e2dd3f1f520bf25b3715f9cddcefcc24689f Mon Sep 17 00:00:00 2001 From: elmot Date: Thu, 4 Jun 2015 18:13:28 +0300 Subject: GAE related fixes: another GAE app, new license, javadoc mistake fix(#18168) Google forces applications owners to migrate all applications to a new [High Replication] DataStorage. An old Vaadin application is deleted, and a new one is created because of that migration. GAE license is replaced with latest one. Change-Id: Ie6de09f0c1c621308ad8e0cfc2ba7b42bfb10429 --- WebContent/license.html | 2 +- .../google-app-engine-terms-of-service.txt | 613 --------------------- .../google-cloud-platform-terms-of-service.txt | 235 ++++++++ server/src/com/vaadin/server/GAEVaadinServlet.java | 2 +- uitest/integration_tests.xml | 2 +- 5 files changed, 238 insertions(+), 616 deletions(-) delete mode 100644 WebContent/licenses/google-app-engine-terms-of-service.txt create mode 100644 WebContent/licenses/google-cloud-platform-terms-of-service.txt (limited to 'server') diff --git a/WebContent/license.html b/WebContent/license.html index 48be15b98d..fe37813e57 100644 --- a/WebContent/license.html +++ b/WebContent/license.html @@ -76,7 +76,7 @@ Google AppEngine API* - Google App Engine Terms of Service + Google Cloud Platform Terms of Service diff --git a/WebContent/licenses/google-app-engine-terms-of-service.txt b/WebContent/licenses/google-app-engine-terms-of-service.txt deleted file mode 100644 index daaa8c2189..0000000000 --- a/WebContent/licenses/google-app-engine-terms-of-service.txt +++ /dev/null @@ -1,613 +0,0 @@ -Google App Engine Terms of Service -Your Agreement with Google - -This License Agreement for Google App Engine (the "Agreement") is made and -entered into by and between Google Inc., a Delaware corporation, with offices at -1600 Amphitheatre Parkway, Mountain View 94043 ("Google") and the business -entity agreeing to these terms ("Customer"). This Agreement is effective as of -the date Customer clicks the "I Accept" button below (the "Effective Date"). If -you are accepting on behalf of Customer, you represent and warrant that: (i) if -you have full legal authority to bind Customer to this Agreement; (ii) you have -read and understand this Agreement; and (iii) you agree, on behalf of Customer, -to this Agreement. If you do not have the legal authority to bind Customer, -please do not click the "I Accept" button below. This Agreement governs -Customer's access to and use of the Service. -1. Licenses. - -1.1 From Google to Customer. Subject to this Agreement, Google grants to -Customer a worldwide, non-sublicensable, non-transferable, non-exclusive, -terminable, limited license to (a) use the Service, (b) integrate the Service -into any Application and provide the Service, solely as integrated into the -Application, to users of the Application and (c) use any Software provided by -Google as part of the Service. - -1.2 From Customer to Google. By submitting, posting, generating or displaying -any Application and/or Customer Data on or through the Service, Customer gives -Google a worldwide, non-sublicensable, non-transferable, non-exclusive, -terminable, limited license to reproduce, adapt, modify, translate, publish, -publicly perform, publicly display and distribute any Application and/or -including Customer Data for the sole purpose of enabling Google to provide -Customer with the Service in accordance with the Agreement. -Provision of the Service. - -2.1 Console. Google will provide the Service to Customer. As part of receiving -the Service, Customer will have access to the Admin Console, through which -Customer may administer the Service. - -2.2 Facilities and Data Transfer. All facilities used to store and process an -Application and Customer Data will adhere to reasonable security standards no -less protective than the security standards at facilities where Google processes -and stores its own information of a similar type. Google has implemented at -least industry standard systems and procedures to ensure the security and -confidentiality of an Application and Customer Data, protect against anticipated -threats or hazards to the security or integrity of an Application and Customer -Data, and protect against unauthorized access to or use of an Application and -Customer Content. Google may process and store an Application and Customer Data -in the United States or any other country in which Google or its agents maintain -facilities. By using the Service, Customer consents to this processing and -storage of an Application and Customer Data. The parties agree that Google is -merely a data processor. - -2.3 Data Storage Selection. - - Data Storage. Customer may select via the Service whether the Core App -Engine End User Data will be stored permanently, at rest, in either the United -States or the European Union, and Google will store it accordingly ("App Engine -Data Location Setting"). If no selection is made, Core App Engine End User Data -will be stored permanently, at rest, in the United States. - Transient Storage. Core App Engine End User Data may be stored transiently -or cached in any country in which Google or its agents maintain facilities -before reaching permanent storage. - Limitations. No App Engine Data Location Setting will apply to Core App -Engine End User Data copied in another location or used with other Google -products and services (including any other Google Cloud Platform services). If -so, the Core App Engine End User Data will be processed and stored pursuant to -Section 2.2 of this Agreement. - -2.4 Accounts. Customer must have an Account to use the Service, and is -responsible for the information it provides to create the Account, the security -of its passwords for the Account, and for any use of its Account. If Customer -becomes aware of any unauthorized use of its password or its Account, Customer -will notify Google as promptly as possible. - -2.5 Privacy Policies. The Service is subject to Google's Privacy Policy. Changes -to the Privacy Policy will be made as stated in the applicable policy. In -addition, Google is enrolled in the U.S. Department of Commerce Safe Harbor -Program and will remain enrolled in this program or another replacement program -(or will adopt a compliance solution which achieves compliance with the terms of -Article 25 of Directive 95/46/EC) throughout the Term of the Agreement. - -2.6 New Applications. Google may make new applications, tools, features or -functionality available from time to time through the Service, the use of which -may be contingent upon Customer's agreement to additional terms. - -2.7 Modifications. - - To the Service. Subject to Section 9.4 (Termination for Convenience), Google -may make commercially reasonable Updates to the Service from time to time. If -Google makes a material change to the Service, Google will inform Customer, -provided that Customer has subscribed with Google to be informed about such -change. - To the Agreement. Google may make changes to this Agreement, including -pricing from time to time. Unless otherwise noted by Google, material changes to -the Agreement will become effective 90 days after they are posted, except if the -changes apply to new functionality in which case they will be effective -immediately. If Customer does not agree to the revised Agreement, please stop -using the Service. Google will post any modification to this Agreement to the -Terms URL. - -3. Payment Terms. - -3.1 Free Quota. The Service is provided to Customer without charge up to the Fee -Threshold. - -3.2 Online Billing. Google will issue an electronic bill to Customer for all -charges accrued above the Fee Threshold. Fees are solely based on Google's -measurements of Customer's use of the Service, may include monthly fees, and -Google's determination is final. For use above the Fee Threshold, Customer shall -be responsible for all Fees up to the amount set in the Account and shall pay -all Fees in U.S. Dollars or in such other currency as agreed to in writing by -the parties. Customer shall pay all Fees in accordance with the payment terms in -the Service FAQ. - -3.3 Delinquent Payments. Late payments may bear interest at the rate of 1.5% per -month (or the highest rate permitted by law, if less). Google reserves the right -to suspend your Account for any late payments. - -3.4 Taxes. Customer is responsible for any Taxes, and Customer will pay Google -for the Services without any reduction for Taxes. If Google is obligated to -collect or pay Taxes, the Taxes will be invoiced to Customer, unless Customer -provides Google with a timely and valid tax exemption certificate authorized by -the appropriate taxing authority. In some states the sales tax is due on the -total purchase price at the time of sale and must be invoiced and collected at -the time of the sale. If Customer is required by law to withhold any Taxes from -its payments to Google, Customer must provide Google with an official tax -receipt or other appropriate documentation to support such withholding payments. - -3.5 Invoice Disputes & Refunds. To the fullest extent permitted by law, Customer -waives all claims relating to Fees unless claimed within sixty days after -charged (this does not affect any Customer rights with its credit card issuer). -Refunds (if any) are at the discretion of Google and will only be in the form of -credit for the Service. Nothing in this Agreement obligates Google to extend -credit to any party. -4. Customer Obligations. - -4.1 Compliance. Customer is solely responsible for its Applications and Customer -Data, and for making sure its Applications or Customer Data comply with the -Acceptable Use Policy. Google reserves the right to review the Application or -Customer Data to ensure Customer's compliance with the Acceptable Use Policy. -Customer is responsible for ensuring all End Users comply with Customer's -obligations under the Agreement. - -4.2 Privacy. Customer will protect the privacy and legal rights of its End Users -under all applicable laws and regulations, which includes a legally adequate -privacy notice communicated from Customer. Customer may have the ability to -access, monitor, use, or disclose Customer Data submitted by End Users through -the Service. Customer will obtain and maintain any required consents from End -Users to allow Customer's access, monitoring, use and disclosure of Customer -Data. Further, Customer will notify its End Users that any Customer Data -provided as part of the Service will be made available to a third party as part -of Google providing the Service. - -4.3 Restrictions. Customer will not, and will not allow third parties under its -control to: (a) copy, modify, create a derivative work of, reverse engineer, -decompile, translate, disassemble, or otherwise attempt to extract the source -code of the Service or any component thereof (subject to Section 4.4 below); (b) -use the Service for High Risk Activities; (c) sublicense, resell, or distribute -the Service or any component thereof separate from any integrated Application; -(d) use the Service to create, train, or improve (directly or indirectly) a -substantially similar product or service, including any other machine -translation engine; (e) create multiple Applications or Accounts to simulate or -act as a single Application or Account (respectively) or otherwise access the -Service in a manner intended to avoid incurring Fees; (f) use the Service to -operate or enable any telecommunications service or in connection with any -Application that allows End Users to place calls to or to receive calls from any -public -switched telephone network; or (g) process or store any Customer Data that is -subject to the International Traffic in Arms Regulations maintained by the -Department of State. Customer acknowledges that the Service is not HIPAA -compliant and Customer is solely responsible for any applicable compliance with -HIPAA. - -4.4 Open Source Components. Open source software licenses for components of the -Service released under an open source license constitute separate written -agreements. Open source software is listed in the Documentation. To the limited -extent the open source software licenses expressly supersede this Agreement, the -open source license instead governs Customer's agreement with Google for the -specific included open source components of the Service, or use of the Service -(as may be applicable). - -4.5 Documentation. Google may provide Documentation for Customer's use of the -Service. The Documentation may specify restrictions (e.g. attribution of HTML -restrictions) on how the Applications may be built or the Service may be used -and Customer agrees to comply with any such restrictions specified. - -4.6 DMCA Policy. Google provides information to help copyright holders manage -their intellectual property online, but Google cannot determine whether -something is being used legally or not without their input. Google responds to -notices of alleged copyright infringement and terminates accounts of repeat -infringers according to the process set out in the U.S. Digital Millennium -Copyright Act. If Customer thinks somebody is violating Customer's or its End -Users' copyrights and wants to notify Google, Customer can find information -about submitting notices, and Google's policy about responding to notices at -http://www.google.com/dmca.html. - -4.7 Application and No Multiple Accounts, Bills. Any Application must have -material value independent from the Services. Google has no obligation to -provide multiple bills or Accounts to Customer under the Agreement. -5. Suspension and Removals. - -5.1 Suspension/Removals. If Customer becomes aware that any Application or an -End User's use of an Application, or Customer Data violates the Acceptable Use -Policy, Customer will immediately suspend the Application, remove the applicable -Customer Data, or suspend access to an End User (as may be applicable). If -Customer fails to suspend or remove as noted in the prior sentence, Google may -specifically request that Customer do so. If Customer fails to comply with -Google's request to do so within twenty-four hours, then Google may suspend -Google accounts of the applicable End Users, disable the Application, and/or -disable the Account (as may be applicable) until such violation is corrected. - -5.2 Emergency Security Issues. Despite the foregoing, if there is an Emergency -Security Issue, then Google may automatically suspend the offending End User -account, Application or the Account. Suspension will be to the minimum extent -required, and of the minimum duration, to prevent or terminate the Emergency -Security Issue. If Google suspends an End User account or the Application or -Account, for any reason, without prior notice to Customer, at Customer's -request, Google will provide Customer the reason for the suspension as soon as -is reasonably possible. -6. Intellectual Property Rights; Brand Features. - -6.1 Intellectual Property Rights. Except as expressly set forth herein, this -Agreement does not grant either party any rights, implied or otherwise, to the -other's content or any of the other's intellectual property. As between the -parties, Customer owns all Intellectual Property Rights in any Application and -Customer Content, and Google owns all Intellectual Property Rights in the -Service. - -6.2 Brand Features Limitation. If Customer wants to display Google Brand -Features in connection with its use of the Service, Customer must obtain written -permission from Google through process specified in the Trademark Guidelines. -For the sole purpose of providing the Service, Customer permits Google to -display any Brand Features that may appear in its Application. Any use of a -party's Brand Features will inure to the benefit of the party holding -Intellectual Property Rights to those Brand Features. A party may revoke the -other party's right to use its Brand Features pursuant to this Agreement with -written notice to the other and a reasonable period to stop the use. -7. Technical Support Service - -7.1 By Customer. Customer is responsible for technical support of its -Application. - -7.2 Deprecation Policy. - -Google will announce if we intend to discontinue or make backwards incompatible -changes to this API or Service. We will use commercially reasonable efforts to -continue to operate that Service without these changes until the later of: (i) -one year after the announcement or (ii) April 20, 2015, unless (as Google -determines in its reasonable good faith judgment): - - required by law or third party relationship (including if there is a change -in applicable law or relationship), or - doing so could create a security risk or substantial economic or material -technical burden. - -This Deprecation Policy doesn't apply to versions, features, and functionality -labeled as "experimental." -8. Confidential Information. - -8.1 Obligations. The recipient of the other party's Confidential Information -will not disclose the Confidential Information, except to Affiliates, employees, -agents, or professional advisors who need to know it and who have agreed in -writing (or in the case of professional advisors are otherwise bound) to keep it -confidential. The recipient will ensure that those people and entities use the -Confidential Information only to exercise rights and fulfill obligations under -this Agreement, while using reasonable care to keep it confidential. The -recipient may also disclose Confidential Information when required by law after -giving reasonable notice to the discloser if allowed by law. The recipient may -also disclose Confidential Information to the extent required by applicable -Legal Process; provided that the recipient uses commercially reasonable efforts -to: (i) promptly notify the other party of such disclosure before disclosing; -and (ii) comply with the other party's reasonable requests regarding its efforts -to -oppose the disclosure. Notwithstanding the foregoing, subsections (i) and (ii) -above will not apply if the recipient determines that complying with (i) and -(ii) could: (a) result in a violation of Legal Process; (b) obstruct a -governmental investigation; and/or (c) lead to death or serious physical harm to -an individual. As between the parties, Customer is responsible for responding to -all third party requests concerning its use and its End Users' use of the -Services. -9. Term and Termination. - -9.1 Agreement Term. The license granted in this Agreement will remain in effect, -unless terminated earlier as set forth in this Agreement. - -9.2 Termination for Breach. Either party may terminate this Agreement for breach -if: (i) the other party is in material breach of the Agreement and fails to cure -that breach within thirty days after receipt of written notice; (ii) the other -party ceases its business operations or becomes subject to insolvency -proceedings and the proceedings are not dismissed within ninety days; or (iii) -the other party is in material breach of this Agreement more than two times -notwithstanding any cure of such breaches. - -9.3 Termination for Inactivity. Google reserves the right to terminate the -Service for inactivity, if, for a period exceeding ninety days, Customer (a) has -failed to access the Admin Console, (b) an Application has not served any -requests, and (c) no electronic bills are being generated. - -9.4 Termination for Convenience. Customer may stop using the Service at any -time. Customer may terminate this Agreement for convenience at any time on prior -written notice and upon termination, must cease use of the Service. Google may -terminate this Agreement for its convenience at any time without liability to -Customer. Subject to Section 7.2, Google may discontinue the Service or any -portion or feature for any reason at any time without liability to Customer. - -9.5 Effects of Termination. If the Agreement expires or is terminated, then: (i) -the rights granted by one party to the other will immediately cease; (ii) all -Fees (including Taxes) owed by Customer to Google are immediately due upon -receipt of the final electronic bill; (iii) Customer will delete the Software, -any Application and any Customer Data; and (iv) upon request, each party will -use commercially reasonable efforts to return or destroy all Confidential -Information of the other party. -10. Publicity. - -Customer is permitted to state publicly that it is a customer of the Service, -consistent with the Trademark Guidelines. Customer agrees that Google may -include Customer's name or Brand Features in a list of Google customers, online -or promotional materials. Customer also agrees that Google may verbally -reference Customer as a customer of the Google products or services that are the -subject of this Agreement. This section is subject to the "Brand Features -Limitation" section of the Agreement. For clarification, neither party needs to -seek approval from the other if the party is repeating a public statement that -is substantially similar to a public statement that has been previously -approved. -11. Representations. - -Each party represents that: (a) it has full power and authority to enter into -the Agreement; and (b) it will comply with all laws and regulations applicable -to its provision, or use, of the Service, as applicable. Google warrants it will -provide the Service in accordance with the applicable SLA. -12. Disclaimer. - -EXCEPT AS EXPRESSLY PROVIDED FOR HEREIN, TO THE MAXIMUM EXTENT PERMITTED BY -APPLICABLE LAW, GOOGLE DOES NOT MAKE ANY OTHER WARRANTY OF ANY KIND, WHETHER -EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING WITHOUT LIMITATION -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR USE AND NONINFRINGEMENT. -GOOGLE IS NOT RESPONSIBLE OR LIABLE FOR THE DELETION OF OR FAILURE TO STORE ANY -CONTENT AND OTHER COMMUNICATIONS MAINTAINED OR TRANSMITTED THROUGH USE OF THE -SERVICE. CUSTOMER IS SOLELY RESPONSIBLE FOR SECURING AND BACKING UP ITS -APPLICATION AND CUSTOMER CONTENT. GOOGLE DOES NOT WARRANT THAT THE OPERATION OF -THE SOFTWARE OR THE SERVICE WILL BE ERROR-FREE OR UNINTERRUPTED. NEITHER THE -SOFTWARE NOR THE SERVICE ARE DESIGNED, MANUFACTURED, OR INTENDED FOR HIGH RISK -ACTIVITIES. -13. Limitation of Liability. - -13.1 Limitation on Indirect Liability. TO THE MAXIMUM EXTEND PERMITTED BY -APPLICABLE LAW, NEITHER PARTY, NOR GOOGLE'S SUPPLIERS, WILL BE LIABLE UNDER THIS -AGREEMENT FOR LOST REVENUES OR INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, -EXEMPLARY, OR PUNITIVE DAMAGES, EVEN IF THE PARTY KNEW OR SHOULD HAVE KNOWN THAT -SUCH DAMAGES WERE POSSIBLE AND EVEN IF DIRECT DAMAGES DO NOT SATISFY A REMEDY. - -13.2 Limitation on Amount of Liability. TO THE MAXIMUM EXTENT PERMITTED BY -APPLICABLE LAW, NEITHER PARTY, NOR GOOGLE'S SUPPLIER'S, MAY BE HELD LIABLE UNDER -THIS AGREEMENT FOR MORE THAN THE AMOUNT PAID BY CUSTOMER TO GOOGLE DURING THE -TWELVE MONTHS PRIOR TO THE EVENT GIVING RISE TO LIABILITY. - -13.3 Exceptions to Limitations. These limitations of liability do not apply to -breaches of confidentiality obligations, violations of a party's Intellectual -Property Rights by the other party, or indemnification obligations. -14. Indemnification. - -14.1 By Customer. Customer will indemnify, defend, and hold harmless Google from -and against all liabilities, damages, and costs (including settlement costs and -reasonable attorneys' fees) arising out of a third party claim: (i) regarding -any Application or Customer Content; (ii) that Customer Brand Features infringe -or misappropriate any patent, copyright, trade secret or trademark of a third -party; or (iii) regarding Customer's, or its End Users', use of the Service in -violation of the Acceptable Use Policy. - -14.2 By Google. Google will indemnify, defend, and hold harmless Customer from -and against all liabilities, damages, and costs (including settlement costs and -reasonable attorneys' fees) arising out of a third party claim that Google's -technology used to provide the Service (excluding any open source software) or -any Google Brand Feature infringes or misappropriates any patent, copyright, -trade secret or trademark of such third party. Notwithstanding the foregoing, in -no event shall Google have any obligations or liability under this Section -arising from: (i) use of any Service or Google Brand Features in a modified form -or in combination with materials not furnished by Google, and (ii) any Customer -Content. - -14.3 Possible Infringement. - - Repair, Replace, or Modify. If Google reasonably believes the Service -infringes a third party's Intellectual Property Rights, then Google will: (a) -obtain the right for Customer, at Google's expense, to continue using the -Service; (b) provide a non-infringing functionally equivalent replacement; or -(c) modify the Service so that it no longer infringes. - Suspension or Termination. If Google does not believe the foregoing options -are commercially reasonable, then Google may suspend or terminate Customer's use -of the impacted Service. - -14.4 General. As a condition to indemnification for a claim, the party seeking -indemnification must promptly notify the other party of the claim in writing and -cooperate with the other party in defending the claim. The indemnifying party -has full control and authority over the defense, except that: (a) any settlement -requiring the party seeking indemnification to admit liability or to pay any -money will require that party's prior written consent, such consent not to be -unreasonably withheld or delayed; and (b) the other party may join in the -defense with its own counsel at its own expense. Notwithstanding the foregoing, -if the indemnified party settles without the prior written consent of the -indemnifying party, the indemnifying party has no obligation of contribution. -THE INDEMNITIES ABOVE ARE THE ONLY REMEDY UNDER THIS AGREEMENT FOR VIOLATION OF -A THIRD PARTY'S INTELLECTUAL PROPERTY RIGHTS. -15. Government Purposes (applicable to United States government customers only). - -The Service was developed solely at private expense and is commercial computer -software and related documentation within the meaning of the applicable civilian -and military Federal acquisition regulations and any supplements thereto. If the -user of the Service is an agency, department, employee, or other entity of the -United States Government, under FAR 12.212 and DFARS 227.7202, the use, -duplication, reproduction, release, modification, disclosure, or transfer of the -Service, including technical data or manuals, is governed by the terms and -conditions contained in this Agreement, which is Google's standard commercial -license agreement. -16. Miscellaneous. - -16.1 Notices. All notices must be in writing and addressed to the other party's -legal department and primary point of contact. The email address for notices -being sent to Google's Legal Department is legal-notices@google.com. Notice will -be treated as given: (a) on receipt as verified by written automated receipt or -by electronic log (as applicable). - -16.2 Assignment. Neither party may assign any part of this Agreement without the -written consent of the other, except to an Affiliate where: (a) the assignee has -agreed in writing to be bound by the terms of this Agreement; (b) the assigning -party remains liable for obligations under the Agreement if the assignee -defaults on them; and (c) the assigning party has notified the other party of -the assignment. Any other attempt to assign is void. - -16.3 Change of Control. If a party experiences a change of Control (for example, -through a stock purchase or sale, merger, or other form of corporate -transaction): (a) that party will give written notice to the other party within -thirty days after the change of Control; and (b) the other party may immediately -terminate this Agreement any time between the change of Control and thirty days -after it receives that written notice. - -16.4 Force Majeure. Neither party will be liable for failure or delay in -performance to the extent caused by circumstances beyond its reasonable control. - -16.5 No Agency. This Agreement does not create any agency, partnership or joint -venture between the parties. - -16.6 No Waiver. Neither party will be treated as having waived any rights by not -exercising (or delaying the exercise of) any rights under this Agreement. - -16.7 Severability. If any term (or part of a term) of this Agreement is invalid, -illegal or unenforceable, the rest of the Agreement will remain in effect. - -16.8 No Third-Party Beneficiaries. This Agreement does not confer any benefits -on any third party unless it expressly states that it does. - -16.9 Equitable Relief. Nothing in this Agreement will limit either party's -ability to seek equitable relief. - -16.10 Governing Law. - - For City, County, and State Government Entities. If Customer is a city, -county or state government entity, then the parties agree to remain silent -regarding governing law and venue. - For Federal Government Entities. If Customer is a federal government entity -then the following applies: ALL CLAIMS ARISING OUT OF OR RELATING TO THIS -AGREEMENT OR THE SERVICE WILL BE GOVERNED BY THE LAWS OF THE UNITED STATES OF -AMERICA, EXCLUDING ITS CONFLICT OF LAWS RULES. SOLELY TO THE EXTENT PERMITTED BY -FEDERAL LAW: (I) THE LAWS OF THE STATE OF CALIFORNIA (EXCLUDING CALIFORNIA'S -CONFLICT OF LAWS RULES) WILL APPLY IN THE ABSENCE OF APPLICABLE FEDERAL LAW; AND -(II) FOR ALL CLAIMS ARISING OUT OF OR RELATING TO THIS AGREEMENT OR THE SERVICE, -THE PARTIES CONSENT TO PERSONAL JURISDICTION IN, AND THE EXCLUSIVE VENUE OF, THE -COURTS IN SANTA CLARA COUNTY, CALIFORNIA. - For All Other Entities. If Customer is any entity not set forth in Section -16.10(a) or (b) then the following applies: ALL CLAIMS ARISING OUT OF OR -RELATING TO THIS AGREEMENT OR THE SERVICE WILL BE GOVERNED BY CALIFORNIA LAW, -EXCLUDING THAT STATE'S CONFLICT OF LAWS RULES, AND WILL BE LITIGATED EXCLUSIVELY -IN THE FEDERAL OR STATE COURTS OF SANTA CLARA COUNTY, CALIFORNIA, USA;THE -PARTIES CONSENT TO PERSONAL JURISDICTION IN THOSE COURTS. - -16.11 Amendments. Any amendment must be in writing, signed by both parties, and -expressly state that it is amending this Agreement. - -16.12 Survival. The following Sections will survive expiration or termination of -this Agreement: 6.1 (Intellectual Property Rights), 8 (Confidential -Information), 9.5 (Effects of Termination), 13 (Limitation of Liability), 14 -(Indemnification) and 16 (Miscellaneous). - -16.13 Entire Agreement. This Agreement supersedes all other agreements between -the parties relating to its subject matter. In entering into this Agreement, -neither party has relied on, and neither party will have any right remedy based -on, any statement, representation or warranty (whether made negligently or -innocently), except those expressly set out in this Agreement. The terms located -at a URL referenced in this Agreement and the Documentation are hereby -incorporated by this reference. After the Effective Date, Google may provide -Customer with an updated URL in place of any URL in this Agreement. - -16.14 Interpretation of Conflicting Terms. If there is a conflict among the -documents that make up this Agreement, the documents will control in the -following order: the Agreement, and the terms located at any URL. - -16.15 Counterparts. The parties may execute this Agreement in counterparts, -including facsimile, PDF and other electronic copies, which taken together will -constitute one instrument. - -16.16 Definitions. - - "Acceptable Use Policy" means the acceptable use policy set forth here: -http://developers.google.com/cloud/terms/aup. - "Account" means Customer's Google account (either gmail.com address or an -Email address provided under the - "Google Apps" product line); subject to those terms of service, as may be -applicable. - "Admin Console" means the online tool provided by Google to Customer for -administering the Service. - "Affiliate" means any entity that directly or indirectly controls, is -controlled by, or is under common control with a party. - "Application(s)" means any web application Customer creates using the -Service, including any source code written by Customer to be used with the -Service. - "Brand Features" means the trade names, trademarks, service marks, logos, -domain names, and other distinctive brand features of each party, respectively, -as secured by such party from time to time. - "Confidential Information" means information that one party (or an -Affiliate) discloses to the other party under this Agreement, and which is -marked as confidential or would normally under the circumstances be considered -confidential information. It does not include information that the recipient -already rightfully knew, that becomes public through no fault of the recipient, -that was independently developed by the recipient, or that was lawfully given to -the recipient by a third party. Customer Data is considered Customer's -Confidential Information. - "Control" means control of greater than fifty percent of the voting rights -or equity interests of a party. - "Core App Engine End User Data" means content provided through the use of an -Application running on Google App Engine, by those End Users who are not acting -as Developer End Users (and information related to those End Users stored by the -Application), but excluding authentication information for those End Users' -Google accounts. - "Customer Data" means content provided, transmitted or displayed via the -Service by Customer, or its End Users; but excluding any data provided as part -of the Account. - "Documentation" means the Google documentation in the form generally made -available by Google to its customers for use with the Service, as may be found -here: https://developers.google.com/appengine/docs or such other URL as Google -may provide. - "Emergency Security Issue" means either: (a) Customer's or its End User's -use of the Service in violation of the Acceptable Use Policy, which could -disrupt: (i) the Service; (ii) other Customers' or its End Users' use of the -Service; or (iii) the Google network or servers used to provide the Service; or -(b) unauthorized third party access to the Service. - "End Users" means the individuals Customer permits to use the Application. - "Export Control Laws" means all applicable export and re-export control laws -and regulations, including the Export Administration Regulations ("EAR") -maintained by the U.S. Department of Commerce, trade and economic sanctions -maintained by the Treasury Department's Office of Foreign Assets Control, and -the International Traffic in Arms Regulations ("ITAR") maintained by the -Department of State. - "Fee Threshold" means the threshold (as may be updated from time to time), -which is more fully described here: -https://developers.google.com/appengine/docs/quotas. - "Fees" means the applicable fees for the Service and any applicable Taxes as -set forth here: https://developers.google.com/appengine/docs/billing. - "High Risk Activities" means uses such as the operation of nuclear -facilities, air traffic control, or life support systems, where the use or -failure of the Service could lead to death, personal injury, or environmental -damage. - "HIPAA" means the Health Insurance Portability and Accountability Act of -1996 as it may be amended from time to time, and any regulations issued -thereunder. - "Intellectual Property Rights" means current and future worldwide rights -under patent law, copyright law, trade secret law, trademark law, moral rights -law, and other similar rights. - "Legal Process" means a request for disclosure of data made pursuant to law, -governmental regulation, court order, subpoena, warrant, governmental regulatory -or agency request, or other valid legal authority, legal procedure, or similar -process. - "Privacy Policy" means Google's privacy policy located at: -https://www.google.com/privacypolicy.html or such other URL as Google may -provide. - "Protected Health Information" means the definition on 45 CFR 160.103, -limited to the information created or received by a business associate from on -or behalf of a covered entity. - "Service" means the Google App Engine Service as more fully described here: -https://developers.google.com/appengine/ or such other URL as Google may -provide. The APIs provided under the Service are listed here: -https://developers.google.com/appengine/appengine_services or such other URL as -Google may provide. - "Service FAQ" means those FAQs more fully described here: -https://developers.google.com/appengine/kb or such other URL as Google may -provide. - “Service Level Agreement” or “SLA” means the service level agreement then in -effect for the Service available at the following URL: -https://developers.google.com/appengine/sla or such other URL as Google may -provide. - "Software" means any downloadable tools, software development kits or other -such proprietary computer software provided by Google in connection with the -Service, which may be downloaded by Customer, and any updates Google may make to -such Software from time to time. - "Taxes" means any duties, customs fees, or taxes (other than Google's income -tax) associated with the purchase of the Service, including any related -penalties or interest. - "Terms URL" means the following URL: -https://developers.google.com/appengine/terms or such other URL as Google may -provide. - "Third Party Request" means a request from a third party for records -relating to an End User's use of the Services. Third Party Requests can be a -lawful search warrant, court order, subpoena, other valid legal order, or -written consent from the End User permitting the disclosure. - "Trademark Guidelines" means Google's Guidelines for Third Party Use of -Google Brand Features, located at the following URL: -http://www.google.com/permissions/guidelines.html or such other URL as Google -may provide. - "Updates" means the periodic software updates provided by Google to Customer -from time to time. Updates are designed to improve, enhance and further develop -the Service and may take the form of bug fixes, enhanced functions, new software -modules and completely new versions. - "Updates" means the periodic software updates provided by Google to Customer -from time to time. Updates are designed to improve, enhance and further develop -the Service and may take the form of bug fixes, enhanced functions, new software -modules and completely new versions. diff --git a/WebContent/licenses/google-cloud-platform-terms-of-service.txt b/WebContent/licenses/google-cloud-platform-terms-of-service.txt new file mode 100644 index 0000000000..f8ad5bc2ba --- /dev/null +++ b/WebContent/licenses/google-cloud-platform-terms-of-service.txt @@ -0,0 +1,235 @@ +Google Cloud Platform Terms of Service + +Last modified: May 20, 2015 + \ +If you are accessing the Google Cloud Platform Services as a customer of a Google Cloud Platform reseller, the terms below do not apply to you, and your agreement with your reseller governs your use of the Google Cloud Platform Services. +Google Cloud Platform License Agreement + +This Google Cloud Platform License Agreement (the "Agreement") is made and entered into by and between Google and the entity agreeing to these terms ("Customer"). "Google" means either (i) Google Ireland Limited, with offices at Gordon House, Barrow Street, Dublin 4, Ireland, if Customer's billing address is in any country within Europe, the Middle East, or Africa ("EMEA"), (ii) Google Asia Pacific Pte. Ltd., with offices at 8 Marina View Asia Square 1 #30-01 Singapore 018960, if Customer's billing address is in any country within the Asia Pacific region ("APAC"), or (iii) Google Inc., with offices at 1600 Amphitheatre Parkway, Mountain View, California 94043, if Customer's billing address is in any country in the world other than those in EMEA and APAC. + +This Agreement is effective as of the date Customer clicks to accept the Agreement (the "Effective Date"). If you are accepting on behalf of Customer, you represent and warrant that: (i) you have full legal authority to bind Customer to this Agreement; (ii) you have read and understand this Agreement; and (iii) you agree, on behalf of Customer, to this Agreement. If you do not have the legal authority to bind Customer, please do not click to accept. This Agreement governs Customer's access to and use of the Service. For an offline variant of this Agreement, you may contact Google for more information. + + 1. Provision of the Services. + + 1.1 Services Use. Subject to this Agreement, during the Term, Customer may: (a) use the Services, (b) integrate the Services into any Application that has material value independent of the Services and provide the Services, solely as integrated into that Application, to End Users, and (c) use any Software provided by Google as part of the Services. Customer may not sublicense or transfer these rights except as permitted under the Assignment section of the Agreement. + + 1.2 Console. Google will provide the Services to Customer. As part of receiving the Services, Customer will have access to the Admin Console, through which Customer may administer the Services. + + 1.3 Facilities and Data Transfer. All facilities used to store and process an Application and Customer Data will adhere to reasonable security standards no less protective than the security standards at facilities where Google processes and stores its own information of a similar type. Google has implemented at least industry standard systems and procedures to (i) ensure the security and confidentiality of an Application and Customer Data, (ii) protect against anticipated threats or hazards to the security or integrity of an Application and Customer Data, and (iii) protect against unauthorized access to or use of an Application and Customer Data. Except as set forth in the Service Specific Terms, Google may process and store an Application and Customer Data in the United States or any other country in which Google or its agents maintain facilities. By using the Services, Customer consents to this processing and storage of an Application and Customer Data. Under this Agreement, Google is merely a data processor. + + 1.4 Accounts. Customer must have an Account and a Token (if applicable) to use the Services, and is responsible for the information it provides to create the Account, the security of the Token and its passwords for the Account, and for any use of its Account and the Token. If Customer becomes aware of any unauthorized use of its password, its Account or the Token, Customer will notify Google as promptly as possible. Google has no obligation to provide Customer multiple Tokens or Accounts. + + 1.5 Safe Harbor. Google is enrolled in the U.S. Department of Commerce Safe Harbor Program and will remain enrolled in this program or another replacement program (or will adopt a compliance solution which achieves compliance with the terms of Article 25 of Directive 95/46/EC) throughout the Term. + + 1.6 New Applications and Services. Google may: (i) make new applications, tools, features or functionality available from time to time through the Services and (ii) add new services to the "Services" definition from time to time (by adding them at the URL set forth under that definition), the use of which may be contingent upon Customers agreement to additional terms. + + 1.7 Modifications. + + a. To the Services. Google may make commercially reasonable Updates to the Services from time to time. If Google makes a material change to the Services, Google will inform Customer, provided that Customer has subscribed with Google to be informed about such change. + + b. To the Agreement. Google may make changes to this Agreement, including pricing (and any linked documents) from time to time. Unless otherwise noted by Google, material changes to the Agreement will become effective 30 days after they are posted, except if the changes apply to new functionality in which case they will be effective immediately. If Customer does not agree to the revised Agreement, please stop using the Services. Google will post any modification to this Agreement to the Terms URL. + + 1.8 Service Specific Terms and Data Processing and Security Terms. The Service Specific Terms and Data Processing and Security Terms are incorporated by this reference into the Agreement. + + 2. Payment Terms. + + 2.1 Free Quota. Certain Services are provided to Customer without charge up to the Fee Threshold, as applicable. + + 2.2 Online Billing. Google will issue an electronic bill to Customer for all charges accrued above the Fee Threshold based on (i) Customers use of the Services during the previous month (including, if any, the relevant Fee for TSS set forth in the Fees definition below); (ii) any Reserved Units selected; (iii) any Committed Purchases selected; and/or (iv) any Package Purchases selected. For use above the Fee Threshold, Customer will be responsible for all Fees up to the amount set in the Account and will pay all Fees in the currency set forth in the invoice. Customer will pay all Fees in accordance with the payment terms applicable to the Fees. Google's measurement of Customers use of the Services is final. Google has no obligation to provide multiple bills. + + 2.3 Taxes. Customer is responsible for any Taxes, and Customer will pay Google for the Services without any reduction for Taxes. If Google is obligated to collect or pay Taxes, the Taxes will be invoiced to Customer, unless Customer provides Google with a timely and valid tax exemption certificate authorized by the appropriate taxing authority. In some states the sales tax is due on the total purchase price at the time of sale and must be invoiced and collected at the time of the sale. If Customer is required by law to withhold any Taxes from its payments to Google, Customer must provide Google with an official tax receipt or other appropriate documentation to support such withholding. + + 2.4 Invoice Disputes & Refunds. To the fullest extent permitted by law, Customer waives all claims relating to Fees unless claimed within sixty days after charged (this does not affect any Customer rights with its credit card issuer). Refunds (if any) are at the discretion of Google and will only be in the form of credit for the Services. Nothing in this Agreement obligates Google to extend credit to any party. + + 2.5 Delinquent Payments. Late payments may bear interest at the rate of 1.5% per month (or the highest rate permitted by law, if less). Google reserves the right to suspend Customers Account, for any late payments. + + 3. Customer Obligations. + + 3.1 Compliance. Customer is solely responsible for its Applications, Projects, and Customer Data and for making sure its Applications, Projects, and Customer Data comply with the AUP. Google reserves the right to review the Application, Project, and Customer Data for compliance with the AUP. Customer is responsible for ensuring all End Users comply with Customers obligations under the AUP, the Service Specific Terms, and the restrictions in Sections 3.3 and 3.5 below. + + 3.2 Privacy. Customer will protect the privacy and legal rights of its End Users under all applicable laws and regulations, which includes a legally adequate privacy notice communicated from Customer. Customer may have the ability to access, monitor, use, or disclose Customer Data submitted by End Users through the Services. Customer will obtain and maintain any required consents from End Users to allow Customers access, monitoring, use and disclosure of Customer Data. Further, Customer will notify its End Users that any Customer Data provided as part of the Services will be made available to a third party (i.e. Google) as part of Google providing the Services. + + 3.3 Restrictions. Customer will not, and will not allow third parties under its control to: (a) copy, modify, create a derivative work of, reverse engineer, decompile, translate, disassemble, or otherwise attempt to extract any or all of the source code of the Services (subject to Section 3.4 below and except to the extent such restriction is expressly prohibited by applicable law); (b) use the Services for High Risk Activities; (c) sublicense, resell, or distribute any or all of the Services separate from any integrated Application; (d) create multiple Applications, Accounts, or Projects to simulate or act as a single Application, Account, or Project (respectively) or otherwise access the Services in a manner intended to avoid incurring Fees; (e) unless otherwise set forth in the Service Specific Terms, use the Services to operate or enable any telecommunications service or in connection with any Application that allows End Users to place calls or to receive calls from any public switched telephone network; or (f) process or store any Customer Data that is subject to the International Traffic in Arms Regulations maintained by the Department of State. Unless otherwise specified in writing by Google, Google does not intend uses of the Services to create obligations under HIPAA, and makes no representations that the Services satisfy HIPAA requirements. If Customer is (or becomes) a Covered Entity or Business Associate, as defined in HIPAA, Customer will not use the Services for any purpose or in any manner involving Protected Health Information (as defined in HIPAA) unless Customer has received prior written consent to such use from Google. + + 3.4 Third Party Components. Third party components (which may include open source software) of the Services may be subject to separate license agreements. To the limited extent a third party license expressly supersedes this Agreement, that third party license governs Customers use of that third party component. + + 3.5 Documentation. Google may provide Documentation for Customers use of the Services. The Documentation may specify restrictions (e.g. attribution or HTML restrictions) on how the Applications may be built or the Services may be used and Customer will comply with any such restrictions specified. + + 3.6 DMCA Policy. Google provides information to help copyright holders manage their intellectual property online, but Google cannot determine whether something is being used legally or not without their input. Google responds to notices of alleged copyright infringement and terminates accounts of repeat infringers according to the process set out in the U.S. Digital Millennium Copyright Act. If Customer thinks somebody is violating Customers or its End Users copyrights and wants to notify Google, Customer can find information about submitting notices, and Google's policy about responding to notices at http://www.google.com/dmca.html. + + 4. Suspension and Removals. + + 4.1 Suspension/Removals. If Customer becomes aware that any Application, Project (including an End Users use of a Project), or Customer Data violates the AUP, Customer will immediately suspend the Application or Project (if applicable), remove the applicable Customer Data or suspend access to an End User (as may be applicable). If Customer fails to suspend or remove as noted in the prior sentence, Google may specifically request that Customer do so. If Customer fails to comply with Googles request to do so within twenty-four hours, then Google may suspend Google accounts of the applicable End Users, disable the Project or Application, and/or disable the Account (as may be applicable) until such violation is corrected. + + 4.2 Emergency Security Issues. Despite the foregoing, if there is an Emergency Security Issue, then Google may automatically suspend the offending, Application, Project, or End User Account. Suspension will be to the minimum extent required, and of the minimum duration, to prevent or resolve the Emergency Security Issue. If Google suspends an End User account, Application, Project, or the Customer Account, for any reason, without prior notice to Customer, at Customers request, Google will provide Customer the reason for the suspension as soon as is reasonably possible. + + 5. Intellectual Property Rights; Use of Customer Data; Feedback. + + 5.1 Intellectual Property Rights. Except as expressly set forth in this Agreement, this Agreement does not grant either party any rights, implied or otherwise, to the others content or any of the others intellectual property. As between the parties, Customer owns all Intellectual Property Rights in Customer Data and the Application or Project (if applicable), and Google owns all Intellectual Property Rights in the Services and Software. + + 5.2 Use of Customer Data. Google may use Customer Data and Applications only to provide the Services to Customer and its End Users and to help secure and improve the Services. For instance, this may include identifying and fixing problems in the Services, enhancing the Services to better protect against attacks and abuse, and making suggestions aimed at improving performance or reducing cost. + + 5.3 Customer Feedback. If Customer provides Google Feedback about the Services, then Google may use that information without obligation to Customer, and Customer hereby irrevocably assigns to Google all right, title, and interest in that Feedback. + + 6. Technical Support Services + + 6.1 By Customer. Customer is responsible for technical support of its Applications and Projects. + + 6.2 By Google. Subject to payment of applicable support Fees, Google will provide TSS to Customer during the Term in accordance with the TSS Guidelines. Certain TSS levels include a minimum recurring Fee as described in the "Fees" definition below. If Customer downgrades its TSS level during any calendar month, Google may continue to provide TSS at the same level and TSS Fees before the downgrade for the remainder of that month. + + 7. Deprecation of Services + + 7.1 Discontinuance of Services. Subject to Section 7.2, Google may discontinue any Services or any portion or feature for any reason at any time without liability to Customer. + + 7.2 Deprecation Policy. Google will announce if it intends to discontinue or make backwards incompatible changes to the Services specified at the URL in the next sentence. Google will use commercially reasonable efforts to continue to operate those Services versions and features identified at https://cloud.google.com/terms/deprecation without these changes for at least one year after that announcement, unless (as Google determines in its reasonable good faith judgment): + + (i) required by law or third party relationship (including if there is a change in applicable law or relationship), or + + (ii) doing so could create a security risk or substantial economic or material technical burden. + + The above policy is the "Deprecation Policy." + + 8. Confidential Information. + + 8.1 Obligations. The recipient will not disclose the Confidential Information, except to Affiliates, employees, agents or professional advisors who need to know it and who have agreed in writing (or in the case of professional advisors are otherwise bound) to keep it confidential. The recipient will ensure that those people and entities use the received Confidential Information only to exercise rights and fulfill obligations under this Agreement, while using reasonable care to keep it confidential. + + 8.2 Required Disclosure. Notwithstanding any provision to the contrary in this Agreement, the recipient may also disclose Confidential Information to the extent required by applicable Legal Process; provided that the recipient uses commercially reasonable efforts to: (i) promptly notify the other party of such disclosure before disclosing; and (ii) comply with the other partys reasonable requests regarding its efforts to oppose the disclosure. Notwithstanding the foregoing, subsections (i) and (ii) above will not apply if the recipient determines that complying with (i) and (ii) could: (a) result in a violation of Legal Process; (b) obstruct a governmental investigation; and/or (c) lead to death or serious physical harm to an individual. As between the parties, Customer is responsible for responding to all third party requests concerning its use and its End Users use of the Services. + + 9. Term and Termination. + + 9.1 Agreement Term. The Term of this Agreement will begin on the Effective Date and continue until the Agreement is terminated as set forth in Section 9 of this Agreement. + + 9.2 Termination for Breach. Either party may terminate this Agreement for breach if: (i) the other party is in material breach of the Agreement and fails to cure that breach within thirty days after receipt of written notice; (ii) the other party ceases its business operations or becomes subject to insolvency proceedings and the proceedings are not dismissed within ninety days; or (iii) the other party is in material breach of this Agreement more than two times notwithstanding any cure of such breaches. In addition, Google may terminate any, all, or any portion of the Services or Projects, if Customer meets any of the conditions in Section 9.2(i), (ii), and/or (iii). + + 9.3 Termination for Inactivity. Google reserves the right to terminate the Services for inactivity, if, for a period exceeding 180 days, Customer: (a) has failed to access the Admin Console; (b) a Project has no active virtual machine or storage resources or an Application has not served any requests; and (c) no electronic bills are being generated. + + 9.4 Termination for Convenience. Customer may stop using the Services at any time. Customer may terminate this Agreement for its convenience at any time on prior written notice and upon termination, must cease use of the applicable Services. Google may terminate this Agreement for its convenience at any time without liability to Customer. + + 9.5 Effect of Termination. If the Agreement is terminated, then: (i) the rights granted by one party to the other will immediately cease; (ii) all Fees owed by Customer to Google are immediately due upon receipt of the final electronic bill; (iii) Customer will delete the Software, any Application, Instance, Project, and any Customer Data; and (iv) upon request, each party will use commercially reasonable efforts to return or destroy all Confidential Information of the other party. + + 10. Publicity. Customer is permitted to state publicly that it is a customer of the Services, consistent with the Trademark Guidelines. If Customer wants to display Google Brand Features in connection with its use of the Services, Customer must obtain written permission from Google through the process specified in the Trademark Guidelines. Google may include Customers name or Brand Features in a list of Google customers, online or in promotional materials. Google may also verbally reference Customer as a customer of the Services. Neither party needs approval if it is repeating a public statement that is substantially similar to a previously-approved public statement. Any use of a partys Brand Features will inure to the benefit of the party holding Intellectual Property Rights to those Brand Features. A party may revoke the other partys right to use its Brand Features under this Section with written notice to the other party and a reasonable period to stop the use. + + 11. Representations and Warranties. Each party represents and warrants that: (a) it has full power and authority to enter into the Agreement; and (b) it will comply with all laws and regulations applicable to its provision, or use, of the Services, as applicable. Google warrants that it will provide the Services in accordance with the applicable SLA (if any). + + 12. Disclaimer. EXCEPT AS EXPRESSLY PROVIDED FOR IN THIS AGREEMENT, TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, GOOGLE AND ITS SUPPLIERS DO NOT MAKE ANY OTHER WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR USE AND NONINFRINGEMENT. GOOGLE AND ITS SUPPLIERS ARE NOT RESPONSIBLE OR LIABLE FOR THE DELETION OF OR FAILURE TO STORE ANY CUSTOMER DATA AND OTHER COMMUNICATIONS MAINTAINED OR TRANSMITTED THROUGH USE OF THE SERVICES. CUSTOMER IS SOLELY RESPONSIBLE FOR SECURING AND BACKING UP ITS APPLICATION, PROJECT, AND CUSTOMER DATA. NEITHER GOOGLE NOR ITS SUPPLIERS, WARRANTS THAT THE OPERATION OF THE SOFTWARE OR THE SERVICES WILL BE ERROR-FREE OR UNINTERRUPTED. NEITHER THE SOFTWARE NOR THE SERVICES ARE DESIGNED, MANUFACTURED, OR INTENDED FOR HIGH RISK ACTIVITIES. + + 13. Limitation of Liability. + + 13.1 Limitation on Indirect Liability. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NEITHER PARTY, NOR GOOGLES SUPPLIERS, WILL BE LIABLE UNDER THIS AGREEMENT FOR LOST REVENUES OR INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, EVEN IF THE PARTY KNEW OR SHOULD HAVE KNOWN THAT SUCH DAMAGES WERE POSSIBLE AND EVEN IF DIRECT DAMAGES DO NOT SATISFY A REMEDY. + + 13.2 Limitation on Amount of Liability. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NEITHER PARTY, NOR GOOGLES SUPPLIERS, MAY BE HELD LIABLE UNDER THIS AGREEMENT FOR MORE THAN THE AMOUNT PAID BY CUSTOMER TO GOOGLE UNDER THIS AGREEMENT DURING THE TWELVE MONTHS PRIOR TO THE EVENT GIVING RISE TO LIABILITY. + + 13.3 Exceptions to Limitations. These limitations of liability do not apply to breaches of confidentiality obligations, violations of a partys Intellectual Property Rights by the other party, or indemnification obligations. + + 14. Indemnification. + + 14.1 By Customer. Unless prohibited by applicable law, Customer will defend and indemnify Google and its Affiliates against Indemnified Liabilities in any Third-Party Legal Proceeding to the extent arising from: (i) any Application, Project, Instance, Customer Data or Customer Brand Features; or (ii) Customers, or its End Users, use of the Services in violation of the AUP. + + 14.2 By Google. Google will defend and indemnify Customer and its Affiliates against Indemnified Liabilities in any Third-Party Legal Proceeding to the extent arising solely from an Allegation that use of (a) Googles technology used to provide the Services (excluding any open source software) or (b) any Google Brand Feature infringes or misappropriates the third partys patent, copyright, trade secret, or trademark. + + 14.3 Exclusions. This Section 14 will not apply to the extent the underlying Allegation arises from: + + a. the indemnified partys breach of this Agreement; + + b. modifications to the indemnifying partys technology or Brand Features by anyone other than the indemnifying party; + + c. combination of the indemnifying partys technology or Brand Features with materials not provided by the indemnifying party; or + + d. use of non-current or unsupported versions of the Services or Brand Features; + + 14.4 Conditions. Sections 14.1 and 14.2 will apply only to the extent: + + a. The indemnified party has promptly notified the indemnifying party in writing of any Allegation(s) that preceded the Third-Party Legal Proceeding and cooperates reasonably with the indemnifying party to resolve the Allegation(s) and Third-Party Legal Proceeding. If breach of this Section 14.4(a) prejudices the defense of the Third-Party Legal Proceeding, the indemnifying partys obligations under Section 14.1 or 14.2 (as applicable) will be reduced in proportion to the prejudice. + + b. The indemnified party tenders sole control of the indemnified portion of the Third-Party Legal Proceeding to the indemnifying party, subject to the following: (i) the indemnified party may appoint its own non-controlling counsel, at its own expense; and (ii) any settlement requiring the indemnified party to admit liability, pay money, or take (or refrain from taking) any action, will require the indemnified partys prior written consent, not to be unreasonably withheld, conditioned, or delayed. + + 14.5 Remedies. + + a. If Google reasonably believes the Services might infringe a third partys Intellectual Property Rights, then Google may, at its sole option and expense: (a) procure the right for Customer to continue using the Services; (b) modify the Services to make them non-infringing without materially reducing their functionality; or (c) replace the Services with a non-infringing, functionally equivalent alternative. + + b. If Google does not believe the remedies in Section 14.5(a) are commercially reasonable, then Google may suspend or terminate Customers use of the impacted Services. + + 14.6 Sole Rights and Obligations. Without affecting either partys termination rights, this Section 14 states the parties only rights and obligations under this Agreement for any third party's Intellectual Property Rights Allegations and Third-Party Legal Proceedings. + + 15. U.S. Federal Agency Users. The Services were developed solely at private expense and are commercial computer software and related documentation within the meaning of the applicable Federal Acquisition Regulations and their agency supplements. + + 16. Miscellaneous. + + 16.1 Notices. All notices must be in writing and addressed to the other partys legal department and primary point of contact. The email address for notices being sent to Googles Legal Department is legal-notices@google.com. Notice will be treated as given on receipt as verified by written or automated receipt or by electronic log (as applicable). + + 16.2 Assignment. Neither party may assign any part of this Agreement without the written consent of the other, except to an Affiliate where: (a) the assignee has agreed in writing to be bound by the terms of this Agreement; (b) the assigning party remains liable for obligations under the Agreement if the assignee defaults on them; and (c) the assigning party has notified the other party of the assignment. Any other attempt to assign is void. + + 16.3 Change of Control. If a party experiences a change of Control (for example, through a stock purchase or sale, merger, or other form of corporate transaction): (a) that party will give written notice to the other party within thirty days after the change of Control; and (b) the other party may immediately terminate this Agreement any time between the change of Control and thirty days after it receives that written notice. + + 16.4 Force Majeure. Neither party will be liable for failure or delay in performance to the extent caused by circumstances beyond its reasonable control. + + 16.5 No Agency. This Agreement does not create any agency, partnership or joint venture between the parties. + + 16.6 No Waiver. Neither party will be treated as having waived any rights by not exercising (or delaying the exercise of) any rights under this Agreement. + + 16.7 Severability. If any term (or part of a term) of this Agreement is invalid, illegal, or unenforceable, the rest of the Agreement will remain in effect. + + 16.8 No Third-Party Beneficiaries. This Agreement does not confer any benefits on any third party unless it expressly states that it does. + + 16.9 Equitable Relief. Nothing in this Agreement will limit either partys ability to seek equitable relief. + + 16.10 U.S. Governing Law. + + a. For U.S. City, County, and State Government Entities. If Customer is a U.S. city, county or state government entity, then the Agreement will be silent regarding governing law and venue. + + b. For U.S. Federal Government Entities. If Customer is a U.S. federal government entity then the following applies: ALL CLAIMS ARISING OUT OF OR RELATING TO THIS AGREEMENT OR THE SERVICES WILL BE GOVERNED BY THE LAWS OF THE UNITED STATES OF AMERICA, EXCLUDING ITS CONFLICT OF LAWS RULES. SOLELY TO THE EXTENT PERMITTED BY FEDERAL LAW: (I) THE LAWS OF THE STATE OF CALIFORNIA (EXCLUDING CALIFORNIAS CONFLICT OF LAWS RULES) WILL APPLY IN THE ABSENCE OF APPLICABLE FEDERAL LAW; AND (II) FOR ALL CLAIMS ARISING OUT OF OR RELATING TO THIS AGREEMENT OR THE SERVICES, THE PARTIES CONSENT TO PERSONAL JURISDICTION IN, AND THE EXCLUSIVE VENUE OF, THE COURTS IN SANTA CLARA COUNTY, CALIFORNIA. + + c. For All Other Entities. If Customer is any entity not set forth in Section 16.10(a) or (b) then the following applies: ALL CLAIMS ARISING OUT OF OR RELATING TO THIS AGREEMENT OR THE SERVICES WILL BE GOVERNED BY CALIFORNIA LAW, EXCLUDING THAT STATES CONFLICT OF LAWS RULES, AND WILL BE LITIGATED EXCLUSIVELY IN THE FEDERAL OR STATE COURTS OF SANTA CLARA COUNTY, CALIFORNIA, USA; THE PARTIES CONSENT TO PERSONAL JURISDICTION IN THOSE COURTS. + + 16.11 Amendments. Except as set forth in Section 1.7(b), any amendment must be in writing, signed by both parties, and expressly state that it is amending this Agreement. + + 16.12 Survival. The following Sections will survive expiration or termination of this Agreement: 5, 8, 9.5, 13, 14, and 16. + + 16.13 Entire Agreement. This Agreement sets out all terms agreed between the parties and supersedes all other agreements between the parties relating to its subject matter. In entering into this Agreement, neither party has relied on, and neither party will have any right or remedy based on, any statement, representation or warranty (whether made negligently or innocently), except those expressly set out in this Agreement. The terms located at a URL referenced in this Agreement and the Documentation are incorporated by reference into the Agreement. After the Effective Date, Google may provide an updated URL in place of any URL in this Agreement. + + 16.14 Conflicting Terms. If there is a conflict between the documents that make up this Agreement, the documents will control in the following order: the Agreement, and the terms at any URL. + + 16.15 Definitions. + "Account" means Customers Google Cloud Platform account. + "Admin Console" means the online console(s) and/or tool(s) provided by Google to Customer for administering the Services. + "Affiliate" means any entity that directly or indirectly Controls, is Controlled by, or is under common Control with a party. + "Allegation" means an unaffiliated third partys allegation. + "Application(s)" means any web or other application Customer creates using the Services, including any source code written by Customer to be used with the Services, or hosted in an Instance. + "AUP" means the acceptable use policy set forth here for the Services: http://cloud.google.com/terms/aup + "Brand Features" means the trade names, trademarks, service marks, logos, domain names, and other distinctive brand features of each party, respectively, as secured by such party from time to time. + "Committed Purchase(s)" have the meaning set forth in the Service Specific Terms. + "Confidential Information" means information that one party (or an Affiliate) discloses to the other party under this Agreement, and which is marked as confidential or would normally under the circumstances be considered confidential information. It does not include information that is independently developed by the recipient, is rightfully given to the recipient by a third party without confidentiality obligations, or becomes public through no fault of the recipient. Customer Data is considered Customers Confidential Information. + "Control" means control of greater than fifty percent of the voting rights or equity interests of a party. + "Customer Data" means content provided, transmitted, or displayed via the Services by Customer or its End Users; but excluding any data provided when Customer creates its general Google account (either under a gmail.com address or an email address provided under the "Google Apps" product line). + "Data Processing and Security Terms" means the terms set forth at: https://cloud.google.com/terms/data-processing-terms. + "Documentation" means the Google documentation (as may be updated from time to time) in the form generally made available by Google to its customers for use with the Services including the following: (a) Google App Engine, set forth here: https://cloud.google.com/appengine/; (b) Google Cloud SQL, set forth here: https://cloud.google.com/sql; (c) Google Cloud Storage, set forth here: https://cloud.google.com/storage; (d) Google Prediction API, set forth here: https://cloud.google.com/prediction; (e) Google BigQuery Service, set forth here: https://cloud.google.com/bigquery/; (f) Google Compute Engine, set forth here: https://cloud.google.com/compute/; and (g) Google Cloud Datastore, set forth here: https://cloud.google.com/datastore/. + "Emergency Security Issue" means either: (a) Customers or its End Users use of the Services in violation of the AUP, which could disrupt: (i) the Services; (ii) other Customers or its End Users use of the Services; or (iii) the Google network or servers used to provide the Services; or (b) unauthorized third party access to the Services. + "End Users" means the individuals Customer permits to use the Services, Application, or Project. + "Fee Threshold" means the threshold (as may be updated from time to time), as applicable for certain Services, as set forth here: https://cloud.google.com/pricing/. + Feedback means feedback or suggestions about the Services provided to Google by Customer. + "Fees" means the applicable fees for each Service and any applicable Taxes. The Fees for each Service are set forth here: https://cloud.google.com/pricing/. + "High Risk Activities" means uses such as the operation of nuclear facilities, air traffic control, or life support systems, where the use or failure of the Services could lead to death, personal injury, or environmental damage. + "HIPAA" means the Health Insurance Portability and Accountability Act of 1996 as it may be amended from time to time, and any regulations issued under it. + "Indemnified Liabilities" means any (i) settlement amounts approved by the indemnifying party; and (ii) damages and costs finally awarded against the indemnified party and its Affiliates by a court of competent jurisdiction. + "Instance" means a virtual machine instance, configured and managed by Customer, which runs on the Services. Instances are more fully described in the Documentation. + "Intellectual Property Rights" means current and future worldwide rights under patent, copyright, trade secret, trademark, and moral rights laws, and other similar rights. + "Legal Process" means a data disclosure request made under law, governmental regulation, court order, subpoena, warrant, governmental regulatory or agency request, or other valid legal authority, legal procedure, or similar process. + "Package Purchase" has the meaning set forth in the Service Specific Terms. + "Project" means a grouping of computing, storage, and API resources for Customer, and via which Customer may use the Services. Projects are more fully described in the Documentation. + "Reserved Capacity Units" have the meaning set forth in the Service Specific Terms. + "Reserved Unit Term" has the meaning set forth in the Service Specific Terms. + "Reserved Units" have the meaning set forth in the Service Specific Terms. + "Services" means the, services as set forth here: https://cloud.google.com/services (including any associated application programming interfaces); and TSS, but the Services do not include Google Translate API. + "Service Specific Terms" means the terms specific to one or more Services set forth here: https://cloud.google.com/terms/service-terms, except the terms relating to (a) Google Translate API; and (b) Fees for Google Cloud Datastore set forth at that Service Specific Terms URL do not apply. + "SLA" means the Service Level Agreement as applicable to: (a) Google App Engine set forth here: https://cloud.google.com/appengine/sla; (b) Google Cloud Storage set forth here: https://cloud.google.com/storage/sla; (c) Google Prediction API set forth here: https://cloud.google.com/prediction/sla; (d) Google BigQuery Service set forth here https://cloud.google.com/bigquery/sla; (e) Google Cloud SQL set forth here: https://cloud.google.com/sql/sla; (f) Google Compute Engine set forth here: https://cloud.google.com/compute/sla; (g) VPN set forth here: https://cloud.google.com/vpn/sla; (h) Google Cloud DNS set forth here: https://cloud.google.com/dns/sla; and (i) Google Cloud Datastore set forth here: https://cloud.google.com/datastore/sla. + "Software" means any downloadable tools, software development kits or other such proprietary computer software provided by Google in connection with the Services, which may be downloaded by Customer, and any updates Google may make to such Software from time to time. + "Taxes" means any duties, customs fees, or taxes (other than Googles income tax) associated with the purchase of the Services, including any related penalties or interest. + "Term" has the meaning set forth in Section 9 of this Agreement. + "Terms URL" means the following URL set forth here: https://cloud.google.com/terms/. + "Third-Party Legal Proceeding" means any formal legal proceeding filed by an unaffiliated third party before a court or government tribunal (including any appellate proceeding). + "Token" means an alphanumeric key that is uniquely associated with Customers Account. + "Trademark Guidelines" means Googles Guidelines for Third Party Use of Google Brand Features, located at: http://www.google.com/permissions/guidelines.html. + "TSS" means the technical support service provided by Google to the administrators under the TSS Guidelines. + "TSS Guidelines" means Googles technical support services guidelines then in effect for the Services. TSS Guidelines are at the following URL: http://support.google.com/enterprise/terms (under Google Cloud Platform Services). + "Updates" means the periodic software updates provided by Google to Customer from time to time. Updates are designed to improve, enhance and further develop the Services and may take the form of bug fixes, enhanced functions, new software modules and completely new versions. + diff --git a/server/src/com/vaadin/server/GAEVaadinServlet.java b/server/src/com/vaadin/server/GAEVaadinServlet.java index df7cd0a66e..6f5c15ebdd 100644 --- a/server/src/com/vaadin/server/GAEVaadinServlet.java +++ b/server/src/com/vaadin/server/GAEVaadinServlet.java @@ -57,7 +57,7 @@ import com.google.apphosting.api.DeadlineExceededException; * <servlet-name>HelloWorld</servlet-name> * <servlet-class>com.vaadin.server.GAEApplicationServlet</servlet-class> * <init-param> - * <param-name>application</param-name> + * <param-name>UI</param-name> * <param-value>com.vaadin.demo.HelloWorld</param-value> * </init-param> * </servlet> diff --git a/uitest/integration_tests.xml b/uitest/integration_tests.xml index d9945a9a45..d28ba47320 100644 --- a/uitest/integration_tests.xml +++ b/uitest/integration_tests.xml @@ -89,7 +89,7 @@ - + -- cgit v1.2.3 From 7adec3cd86956fde2fe3670ed4b0eef97bbb0904 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 19 Jan 2015 16:16:35 +0200 Subject: Convenience Window.setPosition(x,y) (#16335) Change-Id: If574863fc24cecb9f8d17773833817d67f3a0e12 --- server/src/com/vaadin/ui/Window.java | 15 +++++++++++++++ .../vaadin/tests/server/component/window/WindowTest.java | 7 +++++++ 2 files changed, 22 insertions(+) (limited to 'server') diff --git a/server/src/com/vaadin/ui/Window.java b/server/src/com/vaadin/ui/Window.java index 61664fc95d..4d63f40043 100644 --- a/server/src/com/vaadin/ui/Window.java +++ b/server/src/com/vaadin/ui/Window.java @@ -267,6 +267,21 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, return getState(false).positionX; } + /** + * Sets the position of the window on the screen using + * {@link #setPositionX(int)} and {@link #setPositionY(int)} + * + * @since + * @param x + * The new x coordinate for the window + * @param y + * The new y coordinate for the window + */ + public void setPosition(int x, int y) { + setPositionX(x); + setPositionY(y); + } + /** * Sets the distance of Window left border in pixels from left border of the * containing (main window). Has effect only if in {@link WindowMode#NORMAL} diff --git a/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java b/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java index b74896b7a1..e9e73c1e0f 100644 --- a/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java +++ b/server/tests/src/com/vaadin/tests/server/component/window/WindowTest.java @@ -50,4 +50,11 @@ public class WindowTest { Assert.assertEquals(b2, window.getAssistiveDescription()[1]); } + + @Test + public void testSetPosition() { + window.setPosition(100, 200); + Assert.assertEquals(100, window.getPositionX()); + Assert.assertEquals(200, window.getPositionY()); + } } -- cgit v1.2.3 From 7c48ad2b38cbbdc2877ae106a7c2dfbcae512f3b Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Thu, 28 May 2015 09:01:20 +0300 Subject: Better error reporting when server has invalid URL encoding (#17948) Change-Id: I7a85a9d93e51de353e74bc08dd81a1779f94ba14 --- .../vaadin/server/ConnectorResourceHandler.java | 36 +++++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'server') diff --git a/server/src/com/vaadin/server/ConnectorResourceHandler.java b/server/src/com/vaadin/server/ConnectorResourceHandler.java index 6c486a2d65..8715134773 100644 --- a/server/src/com/vaadin/server/ConnectorResourceHandler.java +++ b/server/src/com/vaadin/server/ConnectorResourceHandler.java @@ -30,10 +30,11 @@ import com.vaadin.util.CurrentInstance; public class ConnectorResourceHandler implements RequestHandler { // APP/connector/[uiid]/[cid]/[filename.xyz] + private static final String CONNECTOR_RESOURCE_PREFIX = "/" + + ApplicationConstants.APP_PATH + "/" + + ConnectorResource.CONNECTOR_PATH + "/"; private static final Pattern CONNECTOR_RESOURCE_PATTERN = Pattern - .compile("^/?" + ApplicationConstants.APP_PATH + '/' - + ConnectorResource.CONNECTOR_PATH + '/' - + "(\\d+)/(\\d+)/(.*)"); + .compile("^" + CONNECTOR_RESOURCE_PREFIX + "(\\d+)/(\\d+)/(.*)"); private static Logger getLogger() { return Logger.getLogger(ConnectorResourceHandler.class.getName()); @@ -44,12 +45,18 @@ public class ConnectorResourceHandler implements RequestHandler { public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException { String requestPath = request.getPathInfo(); - if (requestPath == null) { + if (requestPath == null + || !requestPath.startsWith(CONNECTOR_RESOURCE_PREFIX)) { return false; } Matcher matcher = CONNECTOR_RESOURCE_PATTERN.matcher(requestPath); if (!matcher.matches()) { - return false; + // This is a connector resource request based on the prefix but the + // pattern did not match + warnAboutInvalidURLEncoding(requestPath); + response.sendError(HttpServletResponse.SC_NOT_FOUND, + "Connector resource not found"); + return true; } String uiId = matcher.group(1); String cid = matcher.group(2); @@ -102,6 +109,25 @@ public class ConnectorResourceHandler implements RequestHandler { return true; } + private boolean loggedDecodingWarning = false; + + private void warnAboutInvalidURLEncoding(String requestPath) { + if (requestPath.contains("\n") || requestPath.indexOf(0x85) != -1) { + // What, path info should not contain a new line or UTF-8 Next Line + // (NEL) character, but it does in + // Tomcat 7 with default configuration in some cases (URL is encoded + // by the browser as UTF-8 and decoded as ISO-8859-1 by Tomcat) + + if (!loggedDecodingWarning) { + loggedDecodingWarning = true; + getLogger() + .warning( + "Request path contains a new line character. This typically means that the server is incorrectly configured to use something else than UTF-8 for URL decoding (requestPath: " + + requestPath + ")"); + } + } + } + private static boolean error(VaadinRequest request, VaadinResponse response, String logMessage) throws IOException { getLogger().log(Level.WARNING, logMessage); -- cgit v1.2.3 From d7284ccfe40f7028e880328566bb825ea31ad619 Mon Sep 17 00:00:00 2001 From: Anna Miroshnik Date: Thu, 12 Mar 2015 18:56:10 +0300 Subject: Format UTF-8 filenames correctly for download (#16556) The code is the same for both FileDownloader and DownloadStream except that FileDownloader forces the content-type to be an "attachment". Change-Id: I50abf3b0f019b773bc0a44b16536a9479f9f472f --- server/src/com/vaadin/server/DownloadStream.java | 44 ++++++++++++++++----- server/src/com/vaadin/server/FileDownloader.java | 14 +++++-- .../src/com/vaadin/server/DownloadStreamTest.java | 39 ++++++++++++++++++ .../tests/components/FileDownloaderTest.java | 37 +++++------------ ...3\266-\346\227\245\346\234\254\350\252\236.pdf" | Bin 0 -> 22522 bytes 5 files changed, 93 insertions(+), 41 deletions(-) create mode 100644 server/tests/src/com/vaadin/server/DownloadStreamTest.java create mode 100644 "uitest/src/com/vaadin/tests/components/embedded/\303\245\303\244\303\266-\346\227\245\346\234\254\350\252\236.pdf" (limited to 'server') diff --git a/server/src/com/vaadin/server/DownloadStream.java b/server/src/com/vaadin/server/DownloadStream.java index 681c438967..0dfd9e42c3 100644 --- a/server/src/com/vaadin/server/DownloadStream.java +++ b/server/src/com/vaadin/server/DownloadStream.java @@ -20,9 +20,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.logging.Logger; import javax.servlet.http.HttpServletResponse; @@ -40,6 +43,8 @@ import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class DownloadStream implements Serializable { + public static final String CONTENT_DISPOSITION = "Content-Disposition"; + /** * Maximum cache time. */ @@ -280,17 +285,14 @@ public class DownloadStream implements Serializable { } } - // suggest local filename from DownloadStream if - // Content-Disposition - // not explicitly set - String contentDispositionValue = getParameter("Content-Disposition"); - if (contentDispositionValue == null) { - contentDispositionValue = "filename=\"" + getFileName() - + "\""; - response.setHeader("Content-Disposition", - contentDispositionValue); + // Content-Disposition: attachment generally forces download + String contentDisposition = getParameter(CONTENT_DISPOSITION); + if (contentDisposition == null) { + contentDisposition = getContentDispositionFilename(getFileName()); } + response.setHeader(CONTENT_DISPOSITION, contentDisposition); + int bufferSize = getBufferSize(); if (bufferSize <= 0 || bufferSize > Constants.MAX_BUFFER_SIZE) { bufferSize = Constants.DEFAULT_BUFFER_SIZE; @@ -317,6 +319,30 @@ public class DownloadStream implements Serializable { } } + /** + * Returns the filename formatted for inclusion in a Content-Disposition + * header. Includes both a plain version of the name and a UTF-8 version + * + * @since + * @param filename + * The filename to include + * @return A value for inclusion in a Content-Disposition header + */ + public static String getContentDispositionFilename(String filename) { + try { + String encodedFilename = URLEncoder.encode(filename, "UTF-8"); + return String.format("filename=\"%s\"; filename*=utf-8''%s", + encodedFilename, encodedFilename); + } catch (UnsupportedEncodingException e) { + return null; + } + + } + + public static Logger getLogger() { + return Logger.getLogger(DownloadStream.class.getName()); + } + /** * Helper method that tries to close an output stream and ignores any * exceptions. diff --git a/server/src/com/vaadin/server/FileDownloader.java b/server/src/com/vaadin/server/FileDownloader.java index 42c2f76e1a..b0c3bb1120 100644 --- a/server/src/com/vaadin/server/FileDownloader.java +++ b/server/src/com/vaadin/server/FileDownloader.java @@ -141,12 +141,17 @@ public class FileDownloader extends AbstractExtension { } stream = ((ConnectorResource) resource).getStream(); - if (stream.getParameter("Content-Disposition") == null) { - // Content-Disposition: attachment generally forces download - stream.setParameter("Content-Disposition", - "attachment; filename=\"" + stream.getFileName() + "\""); + String contentDisposition = stream + .getParameter(DownloadStream.CONTENT_DISPOSITION); + if (contentDisposition == null) { + contentDisposition = "attachment; " + + DownloadStream.getContentDispositionFilename(stream + .getFileName()); } + stream.setParameter(DownloadStream.CONTENT_DISPOSITION, + contentDisposition); + // Content-Type to block eager browser plug-ins from hijacking // the file if (isOverrideContentType()) { @@ -158,4 +163,5 @@ public class FileDownloader extends AbstractExtension { stream.writeResponse(request, response); return true; } + } diff --git a/server/tests/src/com/vaadin/server/DownloadStreamTest.java b/server/tests/src/com/vaadin/server/DownloadStreamTest.java new file mode 100644 index 0000000000..180b2e348b --- /dev/null +++ b/server/tests/src/com/vaadin/server/DownloadStreamTest.java @@ -0,0 +1,39 @@ +package com.vaadin.server; + +import static org.mockito.Matchers.contains; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; + +import org.junit.Before; +import org.junit.Test; + +public class DownloadStreamTest { + private String filename = "日本語.png"; + private DownloadStream stream; + + @Before + public void setup() { + stream = new DownloadStream(mock(InputStream.class), "", filename); + } + + @Test + public void contentDispositionFilenameIsUtf8Encoded() throws IOException { + VaadinResponse response = mock(VaadinResponse.class); + + stream.writeResponse(mock(VaadinRequest.class), response); + + String encodedFileName = URLEncoder.encode(filename, "utf-8"); + verify(response).setHeader(eq(DownloadStream.CONTENT_DISPOSITION), + contains(String.format("filename=\"%s\";", encodedFileName))); + verify(response) + .setHeader( + eq(DownloadStream.CONTENT_DISPOSITION), + contains(String.format("filename*=utf-8''%s", + encodedFileName))); + } +} diff --git a/uitest/src/com/vaadin/tests/components/FileDownloaderTest.java b/uitest/src/com/vaadin/tests/components/FileDownloaderTest.java index 6e0616b115..9eb6806d13 100644 --- a/uitest/src/com/vaadin/tests/components/FileDownloaderTest.java +++ b/uitest/src/com/vaadin/tests/components/FileDownloaderTest.java @@ -37,7 +37,6 @@ import com.vaadin.server.StreamResource; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinResponse; import com.vaadin.tests.components.embedded.EmbeddedPdf; -import com.vaadin.tests.util.Log; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; @@ -49,27 +48,18 @@ import com.vaadin.ui.Label; import com.vaadin.ui.Layout; import com.vaadin.ui.NativeButton; -public class FileDownloaderTest extends AbstractTestUI { +public class FileDownloaderTest extends AbstractTestUIWithLog { private AbstractComponent firstDownloadComponent; - private Log log = new Log(5); @Override protected void setup(VaadinRequest request) { - addComponent(log); - List> components = new ArrayList>(); components.add(Button.class); components.add(NativeButton.class); components.add(CssLayout.class); components.add(Label.class); - // Resource resource = new ExternalResource( - // "https://vaadin.com/download/prerelease/7.0/7.0.0/7.0.0.beta1/vaadin-all-7.0.0.beta1.zip"); - // addComponents(resource, components); - // resource = new ExternalResource( - // "https://vaadin.com/download/book-of-vaadin/current/pdf/book-of-vaadin.pdf"); - // addComponents(resource, components); ConnectorResource resource; resource = new StreamResource(new StreamResource.StreamSource() { @@ -105,13 +95,16 @@ public class FileDownloaderTest extends AbstractTestUI { } catch (IOException e) { e.printStackTrace(); } - // resource = new DynamicConnectorResource(this, "requestImage.png"); - // addComponents(resource, components); - // resource = new ThemeResource("favicon.ico"); - // addComponents(resource, components); resource = new ClassResource(new EmbeddedPdf().getClass(), "test.pdf"); addComponents("Class resource pdf", resource, components); + Button downloadUtf8File = new Button("Download UTF-8 named file"); + FileDownloader fd = new FileDownloader(new ClassResource( + new EmbeddedPdf().getClass(), "åäö-日本語.pdf")); + fd.setOverrideContentType(false); + fd.extend(downloadUtf8File); + addComponent(downloadUtf8File); + addComponent(new Button("Remove first download button", new ClickListener() { @@ -131,7 +124,7 @@ public class FileDownloaderTest extends AbstractTestUI { FileDownloader e = (FileDownloader) firstDownloadComponent .getExtensions().iterator().next(); e.remove(); - log.log("FileDownload detached"); + log("FileDownload detached"); } })); } @@ -213,16 +206,4 @@ public class FileDownloaderTest extends AbstractTestUI { return bi; } - @Override - protected String getTestDescription() { - // TODO Auto-generated method stub - return null; - } - - @Override - protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; - } - } diff --git "a/uitest/src/com/vaadin/tests/components/embedded/\303\245\303\244\303\266-\346\227\245\346\234\254\350\252\236.pdf" "b/uitest/src/com/vaadin/tests/components/embedded/\303\245\303\244\303\266-\346\227\245\346\234\254\350\252\236.pdf" new file mode 100644 index 0000000000..e44a87e9ad Binary files /dev/null and "b/uitest/src/com/vaadin/tests/components/embedded/\303\245\303\244\303\266-\346\227\245\346\234\254\350\252\236.pdf" differ -- cgit v1.2.3 From b6c30ed3c070eefdcb7e26d490e6d82c165ad8f3 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Sun, 15 Mar 2015 15:09:03 +0200 Subject: Extract MockUI class Change-Id: I2a85520c89b952bed3308156afa8aff3f80082bd --- server/tests/src/com/vaadin/tests/util/MockUI.java | 46 ++++++++++++++++++++++ .../src/com/vaadin/ui/LabelDataSourceTest.java | 14 +------ 2 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 server/tests/src/com/vaadin/tests/util/MockUI.java (limited to 'server') diff --git a/server/tests/src/com/vaadin/tests/util/MockUI.java b/server/tests/src/com/vaadin/tests/util/MockUI.java new file mode 100644 index 0000000000..17dc24e9e8 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/util/MockUI.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.util; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinSession; +import com.vaadin.ui.UI; + +public class MockUI extends UI { + + public MockUI() { + this(findOrcreateSession()); + } + + public MockUI(VaadinSession session) { + setSession(session); + setCurrent(this); + } + + @Override + protected void init(VaadinRequest request) { + // Do nothing + } + + private static VaadinSession findOrcreateSession() { + VaadinSession session = VaadinSession.getCurrent(); + if (session == null) { + session = new AlwaysLockedVaadinSession(null); + VaadinSession.setCurrent(session); + } + return session; + } +} diff --git a/server/tests/src/com/vaadin/ui/LabelDataSourceTest.java b/server/tests/src/com/vaadin/ui/LabelDataSourceTest.java index 8ec3ca1245..030504cf2b 100644 --- a/server/tests/src/com/vaadin/ui/LabelDataSourceTest.java +++ b/server/tests/src/com/vaadin/ui/LabelDataSourceTest.java @@ -22,9 +22,9 @@ import org.junit.Before; import org.junit.Test; import com.vaadin.data.util.ObjectProperty; -import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinSession; import com.vaadin.tests.util.AlwaysLockedVaadinSession; +import com.vaadin.tests.util.MockUI; public class LabelDataSourceTest { @@ -104,18 +104,6 @@ public class LabelDataSourceTest { Assert.assertEquals("after", label.getValue()); } - public class MockUI extends UI { - - public MockUI() { - setSession(vaadinSession); - } - - @Override - protected void init(VaadinRequest request) { - } - - } - @Test public void attachToSessionWithDifferentLocale() { label.setValue("before"); -- cgit v1.2.3 From d5381626ec2e058ac7fb31c4af789b248df92669 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 15 May 2015 15:55:59 +0300 Subject: Add setStyleName(String, boolean) shorthand for add/removeStyleName (#17825) Change-Id: I91f4faae3e40ad4cd2b3037ce64d8776f61c004e --- server/src/com/vaadin/ui/AbstractComponent.java | 28 +++++ .../AbstractComponentStyleNameTest.java | 115 +++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 uitest/src/com/vaadin/tests/components/abstractfield/AbstractComponentStyleNameTest.java (limited to 'server') diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java index 27d97d5e03..338898372a 100644 --- a/server/src/com/vaadin/ui/AbstractComponent.java +++ b/server/src/com/vaadin/ui/AbstractComponent.java @@ -243,6 +243,34 @@ public abstract class AbstractComponent extends AbstractClientConnector } } + /** + * Adds or removes a style name. Multiple styles can be specified as a + * space-separated list of style names. + * + * If the {@code add} parameter is true, the style name is added to the + * component. If the {@code add} parameter is false, the style name is + * removed from the component. + *

+ * Functionally this is equivalent to using {@link #addStyleName(String)} or + * {@link #removeStyleName(String)} + * + * @since + * @param style + * the style name to be added or removed + * @param add + * true to add the given style, false + * to remove it + * @see #addStyleName(String) + * @see #removeStyleName(String) + */ + public void setStyleName(String style, boolean add) { + if (add) { + addStyleName(style); + } else { + removeStyleName(style); + } + } + /* * Get's the component's caption. Don't add a JavaDoc comment here, we use * the default documentation from implemented interface. diff --git a/uitest/src/com/vaadin/tests/components/abstractfield/AbstractComponentStyleNameTest.java b/uitest/src/com/vaadin/tests/components/abstractfield/AbstractComponentStyleNameTest.java new file mode 100644 index 0000000000..41ba5571ad --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/abstractfield/AbstractComponentStyleNameTest.java @@ -0,0 +1,115 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.abstractfield; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.Button; + +public class AbstractComponentStyleNameTest { + + AbstractComponent c; + + @Before + public void setup() { + c = new Button(); + } + + @Test + public void add() { + c.addStyleName("foo"); + Assert.assertEquals("foo", c.getStyleName()); + } + + @Test + public void addWithHeadingSpace() { + c.addStyleName(" foo"); + Assert.assertEquals("foo", c.getStyleName()); + } + + @Test + public void addWithTrailingSpace() { + c.addStyleName("foo "); + Assert.assertEquals("foo", c.getStyleName()); + } + + @Test + public void removeWithHeadingSpace() { + c.setStyleName("foo"); + c.removeStyleName(" foo"); + Assert.assertEquals("", c.getStyleName()); + } + + @Test + public void removeWithTrailingSpace() { + c.setStyleName("foo"); + c.removeStyleName("foo "); + Assert.assertEquals("", c.getStyleName()); + } + + @Test + public void addMultipleTimes() { + c.addStyleName("foo"); + c.addStyleName("foo"); + Assert.assertEquals("foo", c.getStyleName()); + } + + @Test + public void setStyleAdd() { + c.setStyleName("foo", true); + Assert.assertEquals("foo", c.getStyleName()); + } + + @Test + public void setStyleMultipleAdd() { + c.setStyleName("foo", true); + c.setStyleName("foo", true); + Assert.assertEquals("foo", c.getStyleName()); + } + + @Test + public void setStyleRemove() { + c.addStyleName("foo"); + c.setStyleName("foo", false); + Assert.assertEquals("", c.getStyleName()); + } + + @Test + public void setStyleMultipleRemove() { + c.addStyleName("foo"); + c.setStyleName("foo", false); + c.setStyleName("foo", false); + Assert.assertEquals("", c.getStyleName()); + } + + @Test + public void remove() { + c.addStyleName("foo"); + c.removeStyleName("foo"); + Assert.assertEquals("", c.getStyleName()); + } + + @Test + public void removeMultipleTimes() { + c.addStyleName("foo"); + c.removeStyleName("foo"); + c.removeStyleName("foo"); + Assert.assertEquals("", c.getStyleName()); + } +} -- cgit v1.2.3 From 7456b6cf0c2c7e66b7040af2e793566607d2a447 Mon Sep 17 00:00:00 2001 From: Steven Spungin Date: Thu, 28 May 2015 09:35:08 -0400 Subject: Return 0 instead of throwing exception if count query returns nothing (#18043) Change-Id: If01c0653021efc85a26d9d5896a4da9d155cf777 --- .../util/sqlcontainer/query/FreeformQuery.java | 18 +++- .../util/sqlcontainer/query/FreeformQueryTest.java | 98 ++++++++++++++++++++++ 2 files changed, 112 insertions(+), 4 deletions(-) (limited to 'server') diff --git a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java b/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java index 79a5b6c067..6b800cb965 100644 --- a/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java +++ b/server/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java @@ -155,8 +155,13 @@ public class FreeformQuery extends AbstractTransactionalQuery implements pstmt = c.prepareStatement(sh.getQueryString()); sh.setParameterValuesToStatement(pstmt); rs = pstmt.executeQuery(); - rs.next(); - count = rs.getInt(1); + if (rs.next()) { + count = rs.getInt(1); + } else { + // The result can be empty when using group by and there + // are no matches (#18043) + count = 0; + } } finally { releaseConnection(c, pstmt, rs); } @@ -175,8 +180,13 @@ public class FreeformQuery extends AbstractTransactionalQuery implements try { statement = conn.createStatement(); rs = statement.executeQuery(countQuery); - rs.next(); - count = rs.getInt(1); + if (rs.next()) { + count = rs.getInt(1); + } else { + // The result can be empty when using group by and there + // are no matches (#18043) + count = 0; + } return count; } finally { releaseConnection(conn, statement, rs); diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java index e193b79df3..bbf083c158 100644 --- a/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java +++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryTest.java @@ -23,6 +23,7 @@ import com.vaadin.data.util.sqlcontainer.SQLContainer; import com.vaadin.data.util.sqlcontainer.SQLTestsConstants; import com.vaadin.data.util.sqlcontainer.SQLTestsConstants.DB; import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool; +import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper; public class FreeformQueryTest { @@ -892,6 +893,83 @@ public class FreeformQueryTest { EasyMock.verify(delegate); } + public static class NonMatchingDelegateWithGroupBy implements + FreeformQueryDelegate { + + private String fromWhere = "FROM people p1 LEFT JOIN people p2 ON p2.id = p1.id WHERE p1.\"NAME\" LIKE 'notfound' GROUP BY p1.ID"; + + @Override + public int storeRow(Connection conn, RowItem row) + throws UnsupportedOperationException, SQLException { + // Not used in this test + return 0; + } + + @Override + public void setOrderBy(List orderBys) + throws UnsupportedOperationException { + // Not used in this test + } + + @Override + public void setFilters(List filters) + throws UnsupportedOperationException { + // Not used in this test + } + + @Override + public boolean removeRow(Connection conn, RowItem row) + throws UnsupportedOperationException, SQLException { + // Not used in this test + return false; + } + + @Override + public String getQueryString(int offset, int limit) + throws UnsupportedOperationException { + return "SELECT * " + fromWhere; + } + + @Override + public String getCountQuery() throws UnsupportedOperationException { + return "SELECT COUNT(*) " + fromWhere; + } + + @Override + public String getContainsRowQueryString(Object... keys) + throws UnsupportedOperationException { + // Not used in this test + return null; + } + } + + public static class NonMatchingStatementDelegateWithGroupBy extends + NonMatchingDelegateWithGroupBy implements FreeformStatementDelegate { + + @Override + public StatementHelper getQueryStatement(int offset, int limit) + throws UnsupportedOperationException { + StatementHelper sh = new StatementHelper(); + sh.setQueryString(getQueryString(offset, limit)); + return sh; + } + + @Override + public StatementHelper getCountStatement() + throws UnsupportedOperationException { + StatementHelper sh = new StatementHelper(); + sh.setQueryString(getCountQuery()); + return sh; + } + + @Override + public StatementHelper getContainsRowQueryStatement(Object... keys) + throws UnsupportedOperationException { + // Not used in this test + return null; + } + } + @Test public void containsRowWithKeys_delegateRegisteredGetContainsRowQueryStringNotImplemented_shouldBuildQueryString() throws SQLException { @@ -909,4 +987,24 @@ public class FreeformQueryTest { EasyMock.verify(delegate); } + + @Test + public void delegateStatementCountWithGroupBy() throws SQLException { + String dummyNotUsed = "foo"; + FreeformQuery query = new FreeformQuery(dummyNotUsed, connectionPool, + "p1.ID"); + query.setDelegate(new NonMatchingStatementDelegateWithGroupBy()); + + Assert.assertEquals(0, query.getCount()); + } + + @Test + public void delegateCountWithGroupBy() throws SQLException { + String dummyNotUsed = "foo"; + FreeformQuery query = new FreeformQuery(dummyNotUsed, connectionPool, + "p1.ID"); + query.setDelegate(new NonMatchingDelegateWithGroupBy()); + + Assert.assertEquals(0, query.getCount()); + } } -- cgit v1.2.3 From b0d5315e8ba95d099f93dc2d16339033a6525b59 Mon Sep 17 00:00:00 2001 From: Teppo Kurki Date: Sun, 7 Jun 2015 23:54:37 +0300 Subject: Forget GridLayout row expand ratios for removed rows (#18166) Change-Id: I90a28fbc9c7eadac56a1d505d7cc80bb67342aae --- server/src/com/vaadin/ui/GridLayout.java | 8 ++++- .../com/vaadin/ui/GridLayoutExpandRatioTest.java | 39 +++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) (limited to 'server') diff --git a/server/src/com/vaadin/ui/GridLayout.java b/server/src/com/vaadin/ui/GridLayout.java index e510fa09fb..96b58d7e67 100644 --- a/server/src/com/vaadin/ui/GridLayout.java +++ b/server/src/com/vaadin/ui/GridLayout.java @@ -833,7 +833,13 @@ public class GridLayout extends AbstractLayout implements } } } - // TODO forget expands for removed rows + // Forget expands for removed rows + if (rows < getRows()) { + for (int i = rows - 1; i < getRows(); i++) { + rowExpandRatio.remove(i); + getState().explicitRowRatios.remove(i); + } + } getState().rows = rows; } diff --git a/server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java b/server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java index 685befaab4..617c7f54ed 100644 --- a/server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java +++ b/server/tests/src/com/vaadin/ui/GridLayoutExpandRatioTest.java @@ -30,6 +30,7 @@ public class GridLayoutExpandRatioTest { public void testColExpandRatioIsForgotten() { gridLayout = new GridLayout(4, 1); gridLayout.setWidth(100, Unit.PERCENTAGE); + gridLayout.setSizeFull(); gridLayout.setSpacing(true); addComponents(true); @@ -46,7 +47,9 @@ public class GridLayoutExpandRatioTest { assertFalse(gridLayout.getState().explicitColRatios.contains(2)); assertTrue(gridLayout.getState().explicitColRatios.contains(3)); - remove(); + gridLayout.removeAllComponents(); + gridLayout.setColumns(3); + addComponents(false); assertTrue(gridLayout.getColumnExpandRatio(0) == 0); assertTrue(gridLayout.getColumnExpandRatio(1) == 1); @@ -56,13 +59,41 @@ public class GridLayoutExpandRatioTest { assertTrue(gridLayout.getState().explicitColRatios.contains(1)); assertFalse(gridLayout.getState().explicitColRatios.contains(2)); assertFalse(gridLayout.getState().explicitColRatios.contains(3)); - } - private void remove() { + @Test + public void testRowExpandRatioIsForgotten() { + gridLayout = new GridLayout(1, 4); + gridLayout.setWidth(100, Unit.PERCENTAGE); + gridLayout.setSizeFull(); + gridLayout.setSpacing(true); + + addComponents(true); + + gridLayout.setRowExpandRatio(1, 1); + gridLayout.setRowExpandRatio(3, 1); + + assertTrue(gridLayout.getRowExpandRatio(0) == 0); + assertTrue(gridLayout.getRowExpandRatio(1) == 1); + assertTrue(gridLayout.getRowExpandRatio(2) == 0); + assertTrue(gridLayout.getRowExpandRatio(3) == 1); + assertFalse(gridLayout.getState().explicitRowRatios.contains(0)); + assertTrue(gridLayout.getState().explicitRowRatios.contains(1)); + assertFalse(gridLayout.getState().explicitRowRatios.contains(2)); + assertTrue(gridLayout.getState().explicitRowRatios.contains(3)); + gridLayout.removeAllComponents(); - gridLayout.setColumns(3); + gridLayout.setRows(3); addComponents(false); + + assertTrue(gridLayout.getRowExpandRatio(0) == 0); + assertTrue(gridLayout.getRowExpandRatio(1) == 1); + assertTrue(gridLayout.getRowExpandRatio(2) == 0); + assertTrue(gridLayout.getRowExpandRatio(3) == 0); + assertFalse(gridLayout.getState().explicitRowRatios.contains(0)); + assertTrue(gridLayout.getState().explicitRowRatios.contains(1)); + assertFalse(gridLayout.getState().explicitRowRatios.contains(2)); + assertFalse(gridLayout.getState().explicitRowRatios.contains(3)); } private void addComponents(boolean includeLastOne) { -- cgit v1.2.3 From 5ae33b641eea02b647825b27c311d4116f3be838 Mon Sep 17 00:00:00 2001 From: Matti Tahvonen Date: Fri, 29 May 2015 16:22:26 +0300 Subject: Selection is now shown although scrollToSelectedItem is false (#16673) If scrollToSelectedItem is set to false (which is needed to work properly with large datasets) the selected item caption is sent to client with a special attribute to avoid the field looking like unselected. Change-Id: Ib80355c3b52faaaeaa9ab7195644701cc3bf0d15 --- .../client/ui/combobox/ComboBoxConnector.java | 6 ++ server/src/com/vaadin/ui/ComboBox.java | 7 ++ .../combobox/ComboBoxScrollingToPageDisabled.java | 74 ++++++++++++++++++++++ .../ComboBoxScrollingToPageDisabledTest.java | 44 +++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingToPageDisabled.java create mode 100644 uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingToPageDisabledTest.java (limited to 'server') diff --git a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java index 8757f46e71..1224a2eaf2 100644 --- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java +++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java @@ -173,6 +173,12 @@ public class ComboBoxConnector extends AbstractFieldConnector implements // started. if (selectedKeys.length > 0 && !selectedKeys[0].equals("")) { performSelection(selectedKeys[0]); + } else if (!getWidget().waitingForFilteringResponse + && uidl.hasAttribute("selectedCaption")) { + // scrolling to correct page is disabled, caption is passed as a + // special parameter + getWidget().tb.setText(uidl + .getStringAttribute("selectedCaption")); } else { resetSelection(); } diff --git a/server/src/com/vaadin/ui/ComboBox.java b/server/src/com/vaadin/ui/ComboBox.java index 4af93113f9..033ec3cd14 100644 --- a/server/src/com/vaadin/ui/ComboBox.java +++ b/server/src/com/vaadin/ui/ComboBox.java @@ -288,6 +288,13 @@ public class ComboBox extends AbstractSelect implements // Paint variables target.addVariable(this, "selected", selectedKeys); + if (getValue() != null && selectedKeys[0] == null) { + // not always available, e.g. scrollToSelectedIndex=false + // Give the caption for selected item still, not to make it look + // like there is no selection at all + target.addAttribute("selectedCaption", + getItemCaption(getValue())); + } if (isNewItemsAllowed()) { target.addVariable(this, "newitem", ""); } diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingToPageDisabled.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingToPageDisabled.java new file mode 100644 index 0000000000..f94306d2fa --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingToPageDisabled.java @@ -0,0 +1,74 @@ +package com.vaadin.tests.components.combobox; + +import java.util.ArrayList; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.tests.components.ComponentTestCase; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Notification; + +public class ComboBoxScrollingToPageDisabled extends + ComponentTestCase { + + private static final Object CAPTION = "caption"; + + @Override + protected Class getTestClass() { + return ComboBox.class; + } + + @Override + protected void initializeComponents() { + ComboBox s = createSelect(null); + s.setScrollToSelectedItem(false); + populate(s, 100); + Object selection = new ArrayList(s.getItemIds()).get(50); + s.setValue(selection); + addTestComponent(s); + } + + private void populate(ComboBox s, int nr) { + for (int i = 0; i < nr; i++) { + addItem(s, "Item " + i); + } + } + + @SuppressWarnings("unchecked") + private void addItem(ComboBox s, String string) { + Object id = s.addItem(); + s.getItem(id).getItemProperty(CAPTION).setValue(string); + + } + + private ComboBox createSelect(String caption) { + final ComboBox cb = new ComboBox(); + cb.setImmediate(true); + cb.addContainerProperty(CAPTION, String.class, ""); + cb.setItemCaptionPropertyId(CAPTION); + cb.setCaption(caption); + cb.addValueChangeListener(new ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + Notification.show("Value now:" + cb.getValue() + " " + + cb.getItemCaption(cb.getValue())); + + } + }); + return cb; + } + + @Override + protected String getDescription() { + return "Test that selected value appears on the client " + + "side even though setScrollToSelectedItem(false) " + + "has been called. Textbox should containe 'Item 50'."; + } + + @Override + protected Integer getTicketNumber() { + return 16673; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingToPageDisabledTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingToPageDisabledTest.java new file mode 100644 index 0000000000..8c09279b87 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingToPageDisabledTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.combobox; + +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * When pressed down key, while positioned on the last item - should show next + * page and focus on the first item of the next page. + */ +public class ComboBoxScrollingToPageDisabledTest extends MultiBrowserTest { + + @Override + public void setup() throws Exception { + super.setup(); + openTestURL(); + } + + @Test + public void checkValueIsVidinlr() throws InterruptedException { + WebElement input = driver.findElement(By + .className("v-filterselect-input")); + String value = input.getAttribute("value"); + org.junit.Assert.assertEquals("Item 50", value); + } + +} -- cgit v1.2.3 From 3a42436fc9ce52e9689adf7166a9c5698224ec40 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Sun, 15 Mar 2015 15:09:32 +0200 Subject: Don't allow null view providers (#17028) Change-Id: I5ce4885f19aaac2d4454b5a368f3e58453cf76f9 --- server/src/com/vaadin/navigator/Navigator.java | 8 +++++++- .../vaadin/tests/server/navigator/NavigatorTest.java | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'server') diff --git a/server/src/com/vaadin/navigator/Navigator.java b/server/src/com/vaadin/navigator/Navigator.java index 65b3fec488..bd2b5711f8 100644 --- a/server/src/com/vaadin/navigator/Navigator.java +++ b/server/src/com/vaadin/navigator/Navigator.java @@ -745,9 +745,15 @@ public class Navigator implements Serializable { * the requested view name is found. * * @param provider - * provider to register + * provider to register, not null + * @throws IllegalArgumentException + * if the provided view provider is null */ public void addProvider(ViewProvider provider) { + if (provider == null) { + throw new IllegalArgumentException( + "Cannot add a null view provider"); + } providers.add(provider); } diff --git a/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java b/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java index ff6028648e..2c045d53fa 100644 --- a/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java +++ b/server/tests/src/com/vaadin/tests/server/navigator/NavigatorTest.java @@ -712,4 +712,21 @@ public class NavigatorTest extends TestCase { navigator.addView("view", view); navigator.navigateTo("view"); } + + public void testNullViewProvider() { + IMocksControl control = EasyMock.createControl(); + NavigationStateManager manager = control + .createMock(NavigationStateManager.class); + ViewDisplay display = control.createMock(ViewDisplay.class); + + // create navigator to test + Navigator navigator = createNavigator(manager, display); + + try { + navigator.addProvider(null); + fail("Should not be allowed to add a null view provider"); + } catch (IllegalArgumentException e) { + // Expected + } + } } -- cgit v1.2.3 From 4af793d06a0f4a6577aad13403ca7982c6fce224 Mon Sep 17 00:00:00 2001 From: Sauli Tähkäpää Date: Fri, 16 Jan 2015 23:19:06 +0200 Subject: Prevent field from updating when removing text change listener. (#16270) Change-Id: I65c598ae71414550eb648fabf6e94fb1dabbef97 --- .../client/ui/textfield/TextFieldConnector.java | 5 ++-- server/src/com/vaadin/ui/AbstractTextField.java | 33 ++++++++++------------ .../textfield/RemoveTextChangeListener.java | 32 +++++++++++++++++++++ .../textfield/RemoveTextChangeListenerTest.java | 24 ++++++++++++++++ 4 files changed, 73 insertions(+), 21 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/textfield/RemoveTextChangeListener.java create mode 100644 uitest/src/com/vaadin/tests/components/textfield/RemoveTextChangeListenerTest.java (limited to 'server') diff --git a/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java b/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java index 0d85e98ee3..fad094b87f 100644 --- a/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java +++ b/client/src/com/vaadin/client/ui/textfield/TextFieldConnector.java @@ -89,10 +89,9 @@ public class TextFieldConnector extends AbstractFieldConnector implements * side value). is updated only when it looses focus, so we * force updating if not focused. Lost focus issue appeared in (#15144) */ - if (!(Util.getFocusedElement() == getWidget().getElement()) + if (Util.getFocusedElement() != getWidget().getElement() || !uidl.getBooleanAttribute(TextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS) - || getWidget().valueBeforeEdit == null - || !text.equals(getWidget().valueBeforeEdit)) { + || getWidget().valueBeforeEdit == null) { getWidget().updateFieldContent(text); } diff --git a/server/src/com/vaadin/ui/AbstractTextField.java b/server/src/com/vaadin/ui/AbstractTextField.java index 93025ac0fd..14c135228c 100644 --- a/server/src/com/vaadin/ui/AbstractTextField.java +++ b/server/src/com/vaadin/ui/AbstractTextField.java @@ -126,25 +126,22 @@ public abstract class AbstractTextField extends AbstractField implements selectionPosition = -1; } - if (hasListeners(TextChangeEvent.class)) { - target.addAttribute(TextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE, - getTextChangeEventMode().toString()); - target.addAttribute(TextFieldConstants.ATTR_TEXTCHANGE_TIMEOUT, - getTextChangeTimeout()); - if (lastKnownTextContent != null) { - /* - * The field has be repainted for some reason (e.g. caption, - * size, stylename), but the value has not been changed since - * the last text change event. Let the client side know about - * the value the server side knows. Client side may then ignore - * the actual value, depending on its state. - */ - target.addAttribute( - TextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS, - true); - } + target.addAttribute(TextFieldConstants.ATTR_TEXTCHANGE_EVENTMODE, + getTextChangeEventMode().toString()); + target.addAttribute(TextFieldConstants.ATTR_TEXTCHANGE_TIMEOUT, + getTextChangeTimeout()); + if (lastKnownTextContent != null) { + /* + * The field has be repainted for some reason (e.g. caption, size, + * stylename), but the value has not been changed since the last + * text change event. Let the client side know about the value the + * server side knows. Client side may then ignore the actual value, + * depending on its state. + */ + target.addAttribute( + TextFieldConstants.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS, + true); } - } @Override diff --git a/uitest/src/com/vaadin/tests/components/textfield/RemoveTextChangeListener.java b/uitest/src/com/vaadin/tests/components/textfield/RemoveTextChangeListener.java new file mode 100644 index 0000000000..339160e6ff --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textfield/RemoveTextChangeListener.java @@ -0,0 +1,32 @@ +package com.vaadin.tests.components.textfield; + +import com.vaadin.event.FieldEvents; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.TextField; + +public class RemoveTextChangeListener extends AbstractTestUI { + @Override + protected void setup(VaadinRequest request) { + final TextField textfield = new TextField(); + + textfield.addTextChangeListener(new FieldEvents.TextChangeListener() { + @Override + public void textChange(FieldEvents.TextChangeEvent event) { + textfield.removeTextChangeListener(this); + } + }); + + addComponent(textfield); + } + + @Override + protected Integer getTicketNumber() { + return 16270; + } + + @Override + protected String getTestDescription() { + return "Removing text change listener on text change event should not reset the input."; + } +} diff --git a/uitest/src/com/vaadin/tests/components/textfield/RemoveTextChangeListenerTest.java b/uitest/src/com/vaadin/tests/components/textfield/RemoveTextChangeListenerTest.java new file mode 100644 index 0000000000..0b876864bc --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textfield/RemoveTextChangeListenerTest.java @@ -0,0 +1,24 @@ +package com.vaadin.tests.components.textfield; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.Test; + +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class RemoveTextChangeListenerTest extends MultiBrowserTest { + + @Test + public void serverValueIsUpdated() { + openTestURL(); + + TextFieldElement textfield = $(TextFieldElement.class).first(); + + textfield.sendKeys("f"); + + assertThat(textfield.getValue(), is("f")); + } + +} \ No newline at end of file -- cgit v1.2.3 From 479f1c55e0d4958c6d4fc3aa0c9aca6442b89371 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Wed, 3 Jun 2015 22:46:46 +0300 Subject: Update to Atmosphere 2.2.7 (#18069) Change-Id: I44994ffbe73cbbcf0eae67718a821ac0f883b60e --- push/build.xml | 2 +- push/ivy.xml | 2 +- server/src/com/vaadin/server/Constants.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'server') diff --git a/push/build.xml b/push/build.xml index 689ed74b4b..9a45b86cfe 100644 --- a/push/build.xml +++ b/push/build.xml @@ -18,7 +18,7 @@ location="${result.dir}/js/VAADIN/vaadinPush.debug.js" /> - + diff --git a/push/ivy.xml b/push/ivy.xml index 4eb78629a1..faf96818e1 100644 --- a/push/ivy.xml +++ b/push/ivy.xml @@ -1,7 +1,7 @@ - + ]> diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java index 122cce2e74..5a0d852299 100644 --- a/server/src/com/vaadin/server/Constants.java +++ b/server/src/com/vaadin/server/Constants.java @@ -67,7 +67,7 @@ public interface Constants { // Keep the version number in sync with push/build.xml and other locations // listed in that file - static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.2.4.vaadin8"; + static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.2.7.vaadin1"; static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n" + "=================================================================\n" -- cgit v1.2.3 From 1eba7f023bf534c8dd5d508ef5f9a5970af67885 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Tue, 9 Jun 2015 11:47:47 +0300 Subject: Add missing since, remove unused method Change-Id: I7a90d75d0fdc54abc819dbacf7f8f572c85b3913 --- server/src/com/vaadin/server/DownloadStream.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'server') diff --git a/server/src/com/vaadin/server/DownloadStream.java b/server/src/com/vaadin/server/DownloadStream.java index 0dfd9e42c3..65ef560974 100644 --- a/server/src/com/vaadin/server/DownloadStream.java +++ b/server/src/com/vaadin/server/DownloadStream.java @@ -25,7 +25,6 @@ import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import java.util.logging.Logger; import javax.servlet.http.HttpServletResponse; @@ -323,7 +322,7 @@ public class DownloadStream implements Serializable { * Returns the filename formatted for inclusion in a Content-Disposition * header. Includes both a plain version of the name and a UTF-8 version * - * @since + * @since 7.4.8 * @param filename * The filename to include * @return A value for inclusion in a Content-Disposition header @@ -336,11 +335,6 @@ public class DownloadStream implements Serializable { } catch (UnsupportedEncodingException e) { return null; } - - } - - public static Logger getLogger() { - return Logger.getLogger(DownloadStream.class.getName()); } /** -- cgit v1.2.3 From 5ebfdecb1b4eb016b674f7a01257959a50047eb3 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Mon, 8 Jun 2015 17:21:58 +0300 Subject: Better handle exceptions when opening Grid editor (#17935) Change-Id: I68103db75c422b042988c6662da268ff9d11a306 --- server/src/com/vaadin/ui/Grid.java | 35 ++++++++++---- .../server/component/grid/GridEditorTest.java | 8 +++- .../grid/GridEditorConverterNotFound.java | 56 ++++++++++++++++++++++ .../grid/GridEditorConverterNotFoundTest.java | 42 ++++++++++++++++ 4 files changed, 129 insertions(+), 12 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/grid/GridEditorConverterNotFound.java create mode 100644 uitest/src/com/vaadin/tests/components/grid/GridEditorConverterNotFoundTest.java (limited to 'server') diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java index 2c442d6e43..88a3195857 100644 --- a/server/src/com/vaadin/ui/Grid.java +++ b/server/src/com/vaadin/ui/Grid.java @@ -3868,7 +3868,7 @@ public class Grid extends AbstractComponent implements SelectionNotifier, @Override public void bind(int rowIndex) { - boolean success = false; + Exception exception = null; try { Object id = getContainerDataSource().getIdByIndex(rowIndex); if (editedItemId == null) { @@ -3876,13 +3876,20 @@ public class Grid extends AbstractComponent implements SelectionNotifier, } if (editedItemId.equals(id)) { - success = true; doEditItem(); } } catch (Exception e) { - handleError(e); + exception = e; + } + + if (exception != null) { + handleError(exception); + doCancelEditor(); + getEditorRpc().confirmBind(false); + } else { + doEditItem(); + getEditorRpc().confirmBind(true); } - getEditorRpc().confirmBind(success); } @Override @@ -5702,13 +5709,20 @@ public class Grid extends AbstractComponent implements SelectionNotifier, } Field editor = editorFieldGroup.getField(propertyId); - if (editor == null) { - editor = editorFieldGroup.buildAndBind(propertyId); - } - if (editor.getParent() != Grid.this) { - assert editor.getParent() == null; - editor.setParent(this); + try { + if (editor == null) { + editor = editorFieldGroup.buildAndBind(propertyId); + } + } finally { + if (editor == null) { + editor = editorFieldGroup.getField(propertyId); + } + + if (editor != null && editor.getParent() != Grid.this) { + assert editor.getParent() == null; + editor.setParent(this); + } } return editor; } @@ -5803,6 +5817,7 @@ public class Grid extends AbstractComponent implements SelectionNotifier, protected void doCancelEditor() { editedItemId = null; editorFieldGroup.discard(); + editorFieldGroup.setItemDataSource(null); } void resetEditor() { diff --git a/server/tests/src/com/vaadin/tests/server/component/grid/GridEditorTest.java b/server/tests/src/com/vaadin/tests/server/component/grid/GridEditorTest.java index 135d7d398c..b70f17779a 100644 --- a/server/tests/src/com/vaadin/tests/server/component/grid/GridEditorTest.java +++ b/server/tests/src/com/vaadin/tests/server/component/grid/GridEditorTest.java @@ -184,12 +184,16 @@ public class GridEditorTest { .getEditorField(); field.setValue("New Name"); + Property datasource = field.getPropertyDataSource(); + grid.cancelEditor(); assertFalse(grid.isEditorActive()); assertNull(grid.getEditedItemId()); assertFalse(field.isModified()); - assertEquals(DEFAULT_NAME, field.getValue()); - assertEquals(DEFAULT_NAME, field.getPropertyDataSource().getValue()); + assertEquals("", field.getValue()); + assertEquals(DEFAULT_NAME, datasource.getValue()); + assertNull(field.getPropertyDataSource()); + assertNull(grid.getEditorFieldGroup().getItemDataSource()); } @Test(expected = IllegalArgumentException.class) diff --git a/uitest/src/com/vaadin/tests/components/grid/GridEditorConverterNotFound.java b/uitest/src/com/vaadin/tests/components/grid/GridEditorConverterNotFound.java new file mode 100644 index 0000000000..e5532b10ad --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridEditorConverterNotFound.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.server.ErrorHandler; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Grid; + +public class GridEditorConverterNotFound extends AbstractTestUIWithLog { + + class Foo { + } + + @Override + protected void setup(VaadinRequest request) { + + Grid grid = new Grid(); + + grid.addColumn("foo", Foo.class); + grid.addRow(new Foo()); + grid.setEditorEnabled(true); + grid.setErrorHandler(new ErrorHandler() { + + @Override + public void error(com.vaadin.server.ErrorEvent event) { + log(event.getThrowable().toString()); + } + }); + + addComponent(grid); + } + + @Override + protected Integer getTicketNumber() { + return 17935; + } + + @Override + protected String getTestDescription() { + return "Grid should gracefully handle bind failures when opening editor"; + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridEditorConverterNotFoundTest.java b/uitest/src/com/vaadin/tests/components/grid/GridEditorConverterNotFoundTest.java new file mode 100644 index 0000000000..468ea8da3a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridEditorConverterNotFoundTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridEditorConverterNotFoundTest extends GridBasicFeaturesTest { + + @Override + protected Class getUIClass() { + // Use the correct UI with helpers from GridBasicFeatures + return GridEditorConverterNotFound.class; + } + + @Test + public void testConverterNotFound() { + openTestURL(); + + $(GridElement.class).first().getCell(0, 0).doubleClick(); + + assertEquals("1. com.vaadin.data.Buffered$SourceException", + getLogRow(0)); + } +} -- cgit v1.2.3 From 5b965ff478ef22a83a476eeebdf70554a776bae6 Mon Sep 17 00:00:00 2001 From: Ilya Ermakov Date: Fri, 5 Dec 2014 17:54:52 +0300 Subject: Table.setVisibleColumns() causes table to forget column headers, icons, alignment (#6245) Effect of this patch: when making column invisible and visible again, column headers, icons, alignment are preserved. Change-Id: Ia0718699f1a5fb8f60fec25a835ee64c58ca5404 --- server/src/com/vaadin/ui/Table.java | 20 ----- .../table/TableToggleColumnVisibility.java | 96 ++++++++++++++++++++++ .../table/TableToggleColumnVisibilityTest.java | 77 +++++++++++++++++ 3 files changed, 173 insertions(+), 20 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/table/TableToggleColumnVisibility.java create mode 100644 uitest/src/com/vaadin/tests/components/table/TableToggleColumnVisibilityTest.java (limited to 'server') diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java index cb61fa31ec..42c4beab6c 100644 --- a/server/src/com/vaadin/ui/Table.java +++ b/server/src/com/vaadin/ui/Table.java @@ -676,26 +676,6 @@ public class Table extends AbstractSelect implements Action.Container, } } - // Removes alignments, icons and headers from hidden columns - if (this.visibleColumns != null) { - boolean disabledHere = disableContentRefreshing(); - try { - for (final Iterator i = this.visibleColumns.iterator(); i - .hasNext();) { - final Object col = i.next(); - if (!newVC.contains(col)) { - setColumnHeader(col, null); - setColumnAlignment(col, (Align) null); - setColumnIcon(col, null); - } - } - } finally { - if (disabledHere) { - enableContentRefreshing(false); - } - } - } - this.visibleColumns = newVC; // Assures visual refresh diff --git a/uitest/src/com/vaadin/tests/components/table/TableToggleColumnVisibility.java b/uitest/src/com/vaadin/tests/components/table/TableToggleColumnVisibility.java new file mode 100644 index 0000000000..e78f247184 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableToggleColumnVisibility.java @@ -0,0 +1,96 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import com.vaadin.server.ClassResource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; + +/** + * Test that toggling column visibility does not change custom header, icon, + * alignment + */ +@SuppressWarnings("serial") +public class TableToggleColumnVisibility extends AbstractTestUI { + + private final Object[][] columnSets = new Object[][] { { "Name" }, + { "Name", "Last Name" }, { "Last Name", "Name" } }; + private int currentSetNumber = 1; + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout layout = new VerticalLayout(); + + final Table table = new Table(); + + table.addContainerProperty("Name", String.class, ""); + table.addContainerProperty("Last Name", String.class, null, + "Hello World", new ClassResource("fi.gif"), Table.Align.RIGHT); + + table.setHeight("200px"); + + table.addItem(new Object[] { "Muoso", "Virtanen" }, new Integer(1)); + table.addItem(new Object[] { "Nehemias", "Korhonen" }, new Integer(2)); + table.addItem(new Object[] { "Hannu", "Nieminen" }, new Integer(3)); + table.addItem(new Object[] { "Eelante", "Mäkinen" }, new Integer(4)); + table.setVisibleColumns(columnSets[1]); + + final Button visibToggler = new Button("visibility"); + visibToggler.setId("visib-toggler"); + visibToggler.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + currentSetNumber = (currentSetNumber == 0) ? 1 : 0; + table.setVisibleColumns(columnSets[currentSetNumber]); + } + }); + + final Button orderToggler = new Button("change order"); + orderToggler.setId("order-toggler"); + orderToggler.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + currentSetNumber = (currentSetNumber == 1) ? 2 : 1; + table.setVisibleColumns(columnSets[currentSetNumber]); + } + }); + + layout.addComponent(table); + layout.addComponent(visibToggler); + layout.addComponent(orderToggler); + + addComponent(layout); + } + + @Override + protected String getTestDescription() { + return "Toggling visibility of column should not change custom header," + + " icon, alignment"; + } + + @Override + protected Integer getTicketNumber() { + return 6245; + } + +} \ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/table/TableToggleColumnVisibilityTest.java b/uitest/src/com/vaadin/tests/components/table/TableToggleColumnVisibilityTest.java new file mode 100644 index 0000000000..4c44dcfed8 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableToggleColumnVisibilityTest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that column keeps its header, icon, alignment after toggling visibility + * (#6245). + * + * @author Vaadin Ltd + */ +public class TableToggleColumnVisibilityTest extends MultiBrowserTest { + + @Test + public void testColumnWidthRestoredAfterTogglingVisibility() { + openTestURL(); + + WebElement toggleVisibilityButton = findElement(By.id("visib-toggler")); + WebElement changeOrderButton = findElement(By.id("order-toggler")); + + checkHeaderAttributes(1); + + toggleVisibilityButton.click(); // hide column #1 + Assert.assertEquals("One column should be visible", + findElements(By.className("v-table-header-cell")).size(), 1); + + toggleVisibilityButton.click(); // restore column #1 + Assert.assertEquals("Two columns should be visible", + findElements(By.className("v-table-header-cell")).size(), 2); + checkHeaderAttributes(1); + + changeOrderButton.click(); // change column order, column #1 now becomes + // column #0 + checkHeaderAttributes(0); + + } + + /* + * Checks column header with number columnNumber. + */ + private void checkHeaderAttributes(int columnNumber) { + WebElement headerCell = findElements( + By.className("v-table-header-cell")).get(columnNumber); + + Assert.assertTrue("Column header text should be custom", headerCell + .getText().equalsIgnoreCase("Hello World")); + + Assert.assertTrue("Column should have an icon", headerCell + .findElements(By.className("v-icon")).size() > 0); + + Assert.assertTrue( + "Column should have alignment to the right", + headerCell.findElements( + By.className("v-table-caption-container-align-right")) + .size() > 0); + } + +} \ No newline at end of file -- cgit v1.2.3 From 3eee8991a2e2798b16f587b9e5fca426627e3132 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Wed, 10 Jun 2015 16:31:26 +0300 Subject: Add @since 7.5 to new API Change-Id: I7ddf9fa8200df4eb6fcd23fc79ef55d1075d41cd --- server/src/com/vaadin/ui/AbstractComponent.java | 2 +- server/src/com/vaadin/ui/Window.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'server') diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java index 338898372a..18c3509af7 100644 --- a/server/src/com/vaadin/ui/AbstractComponent.java +++ b/server/src/com/vaadin/ui/AbstractComponent.java @@ -254,7 +254,7 @@ public abstract class AbstractComponent extends AbstractClientConnector * Functionally this is equivalent to using {@link #addStyleName(String)} or * {@link #removeStyleName(String)} * - * @since + * @since 7.5 * @param style * the style name to be added or removed * @param add diff --git a/server/src/com/vaadin/ui/Window.java b/server/src/com/vaadin/ui/Window.java index 4d63f40043..61ba5826b8 100644 --- a/server/src/com/vaadin/ui/Window.java +++ b/server/src/com/vaadin/ui/Window.java @@ -271,7 +271,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, * Sets the position of the window on the screen using * {@link #setPositionX(int)} and {@link #setPositionY(int)} * - * @since + * @since 7.5 * @param x * The new x coordinate for the window * @param y -- cgit v1.2.3 From e4d7e2d500d9bb966279a6b986f65316d6b5e3d4 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Thu, 11 Jun 2015 14:16:47 +0300 Subject: Fix declarative margin reading in AbstractOrderedLayout (#18229) Change-Id: Ia212d83568e4f0c891ec1a248b6d8567c0cf0095 --- server/src/com/vaadin/ui/AbstractLayout.java | 91 ++++++++++++++++++ .../src/com/vaadin/ui/AbstractOrderedLayout.java | 51 +--------- .../AbstractLayoutDeclarativeMarginTest.java | 104 --------------------- .../server/component/DeclarativeMarginTest.java | 76 +++++++++++++++ .../AbstractOrderedLayoutDeclarativeTest.java | 49 ++++------ shared/src/com/vaadin/shared/ui/MarginInfo.java | 6 ++ 6 files changed, 191 insertions(+), 186 deletions(-) delete mode 100644 server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java create mode 100644 server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTest.java (limited to 'server') diff --git a/server/src/com/vaadin/ui/AbstractLayout.java b/server/src/com/vaadin/ui/AbstractLayout.java index 9cdb0a326a..0770670680 100644 --- a/server/src/com/vaadin/ui/AbstractLayout.java +++ b/server/src/com/vaadin/ui/AbstractLayout.java @@ -16,7 +16,12 @@ package com.vaadin.ui; +import org.jsoup.nodes.Element; + import com.vaadin.shared.ui.AbstractLayoutState; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * An abstract class that defines default implementation for the {@link Layout} @@ -33,4 +38,90 @@ public abstract class AbstractLayout extends AbstractComponentContainer return (AbstractLayoutState) super.getState(); } + /** + * Reads margin attributes from a design into a MarginInfo object. This + * helper method should be called from the + * {@link #readDesign(Element, DesignContext) readDesign} method of layouts + * that implement {@link MarginHandler}. + * + * @since 7.5 + * + * @param design + * the design from which to read + * @param defMargin + * the default margin state for edges that are not set in the + * design + * @param context + * the DesignContext instance used for parsing the design + * @return the margin info + */ + protected MarginInfo readMargin(Element design, MarginInfo defMargin, + DesignContext context) { + + if (design.hasAttr("margin")) { + boolean margin = DesignAttributeHandler.readAttribute("margin", + design.attributes(), boolean.class); + return new MarginInfo(margin); + } else { + boolean left = DesignAttributeHandler.readAttribute("margin-left", + design.attributes(), defMargin.hasLeft(), boolean.class); + + boolean right = DesignAttributeHandler.readAttribute( + "margin-right", design.attributes(), defMargin.hasRight(), + boolean.class); + + boolean top = DesignAttributeHandler.readAttribute("margin-top", + design.attributes(), defMargin.hasTop(), boolean.class); + + boolean bottom = DesignAttributeHandler.readAttribute( + "margin-bottom", design.attributes(), + defMargin.hasBottom(), boolean.class); + + return new MarginInfo(top, right, bottom, left); + } + } + + /** + * Writes margin attributes from a MarginInfo object to a design. This + * helper method should be called from the + * {@link #readDesign(Element, DesignContext) writeDesign} method of layouts + * that implement {@link MarginHandler}. + * + * + * @since 7.5 + * + * @param design + * the design to write to + * @param margin + * the margin state to write + * @param defMargin + * the default margin state to compare against + * @param context + * the DesignContext instance used for parsing the design + */ + protected void writeMargin(Element design, MarginInfo margin, + MarginInfo defMargin, DesignContext context) { + if (margin.hasAll()) { + DesignAttributeHandler.writeAttribute("margin", + design.attributes(), margin.hasAll(), defMargin.hasAll(), + boolean.class); + } else { + + DesignAttributeHandler.writeAttribute("margin-left", + design.attributes(), margin.hasLeft(), defMargin.hasLeft(), + boolean.class); + + DesignAttributeHandler.writeAttribute("margin-right", + design.attributes(), margin.hasRight(), + defMargin.hasRight(), boolean.class); + + DesignAttributeHandler.writeAttribute("margin-top", + design.attributes(), margin.hasTop(), defMargin.hasTop(), + boolean.class); + + DesignAttributeHandler.writeAttribute("margin-bottom", + design.attributes(), margin.hasBottom(), + defMargin.hasBottom(), boolean.class); + } + } } diff --git a/server/src/com/vaadin/ui/AbstractOrderedLayout.java b/server/src/com/vaadin/ui/AbstractOrderedLayout.java index 0214ff4be1..afe4717212 100644 --- a/server/src/com/vaadin/ui/AbstractOrderedLayout.java +++ b/server/src/com/vaadin/ui/AbstractOrderedLayout.java @@ -478,30 +478,7 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements // process default attributes super.readDesign(design, designContext); - // handle margins - if (design.hasAttr("margin")) { - setMargin(DesignAttributeHandler.readAttribute("margin", - design.attributes(), Boolean.class)); - } else { - boolean marginLeft = DesignAttributeHandler.readAttribute( - "margin-left", design.attributes(), getMargin().hasLeft(), - Boolean.class); - - boolean marginRight = DesignAttributeHandler.readAttribute( - "margin-right", design.attributes(), - getMargin().hasRight(), Boolean.class); - - boolean marginTop = DesignAttributeHandler.readAttribute( - "margin-top", design.attributes(), getMargin().hasTop(), - Boolean.class); - - boolean marginBottom = DesignAttributeHandler.readAttribute( - "margin-bottom", design.attributes(), getMargin() - .hasBottom(), Boolean.class); - - setMargin(new MarginInfo(marginTop, marginBottom, marginLeft, - marginRight)); - } + setMargin(readMargin(design, getMargin(), designContext)); // handle children for (Element childComponent : design.children()) { @@ -557,31 +534,7 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements AbstractOrderedLayout def = (AbstractOrderedLayout) designContext .getDefaultInstance(this); - // handle margin - MarginInfo marginInfo = getMargin(); - - if (marginInfo.hasAll()) { - DesignAttributeHandler.writeAttribute("margin", - design.attributes(), marginInfo.hasAll(), def.getMargin() - .hasAll(), Boolean.class); - } else { - - DesignAttributeHandler.writeAttribute("margin-left", design - .attributes(), marginInfo.hasLeft(), def.getMargin() - .hasLeft(), Boolean.class); - - DesignAttributeHandler.writeAttribute("margin-right", design - .attributes(), marginInfo.hasRight(), def.getMargin() - .hasRight(), Boolean.class); - - DesignAttributeHandler.writeAttribute("margin-top", design - .attributes(), marginInfo.hasTop(), def.getMargin() - .hasTop(), Boolean.class); - - DesignAttributeHandler.writeAttribute("margin-bottom", design - .attributes(), marginInfo.hasBottom(), def.getMargin() - .hasBottom(), Boolean.class); - } + writeMargin(design, getMargin(), def.getMargin(), designContext); // handle children if (!designContext.shouldWriteChildren(this, def)) { diff --git a/server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java b/server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java deleted file mode 100644 index 70855f67dc..0000000000 --- a/server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.server.component; - -import org.junit.Test; - -import com.vaadin.shared.ui.MarginInfo; -import com.vaadin.tests.design.DeclarativeTestBase; -import com.vaadin.ui.AbstractLayout; -import com.vaadin.ui.VerticalLayout; - -public class AbstractLayoutDeclarativeMarginTest extends - DeclarativeTestBase { - - @Test - public void testMarginInfo() { - VerticalLayout vl = new VerticalLayout(); - - String left = getMarginTag(true, false, false, false); - MarginInfo leftInfo = getMarginInfo(true, false, false, false); - - String right = getMarginTag(false, true, false, false); - MarginInfo rightInfo = getMarginInfo(false, true, false, false); - - String top = getMarginTag(false, false, true, false); - MarginInfo topInfo = getMarginInfo(false, false, true, false); - - String bottom = getMarginTag(false, false, false, true); - MarginInfo bottomInfo = getMarginInfo(false, false, false, true); - - String topLeft = getMarginTag(true, false, true, false); - MarginInfo topLeftInfo = getMarginInfo(true, false, true, false); - - String topRight = getMarginTag(false, true, true, false); - MarginInfo topRightInfo = getMarginInfo(false, true, true, false); - - String bottomLeft = getMarginTag(true, false, false, true); - MarginInfo bottomLeftInfo = getMarginInfo(true, false, false, true); - - String bottomRight = getMarginTag(false, true, false, true); - MarginInfo bottomRightInfo = getMarginInfo(false, true, false, true); - - testRW(vl, left, leftInfo); - testRW(vl, right, rightInfo); - testRW(vl, top, topInfo); - testRW(vl, bottom, bottomInfo); - - testRW(vl, topLeft, topLeftInfo); - testRW(vl, topRight, topRightInfo); - testRW(vl, bottomLeft, bottomLeftInfo); - testRW(vl, bottomRight, bottomRightInfo); - - // Test special case of all edges margin'ed - testRW(vl, getMarginTag(true, true, true, true), new MarginInfo(true)); - } - - private void testRW(VerticalLayout vl, String design, MarginInfo margin) { - vl.setMargin(margin); - testWrite(design, vl); - testRead(design, vl); - } - - private String getMarginTag(boolean left, boolean right, boolean top, - boolean bottom) { - String s = ""; - } - - private MarginInfo getMarginInfo(boolean left, boolean right, boolean top, - boolean bottom) { - return new MarginInfo(top, right, bottom, left); - } - -} diff --git a/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTest.java b/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTest.java new file mode 100644 index 0000000000..d31a93a68b --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Layout; +import com.vaadin.ui.Layout.MarginHandler; + +@Ignore +public abstract class DeclarativeMarginTest + extends DeclarativeTestBase { + + @Test + public void testMargins() { + + for (int i = 0; i < 16; ++i) { + boolean top = (i & 1) == 1; + boolean right = (i & 2) == 2; + boolean bottom = (i & 4) == 4; + boolean left = (i & 8) == 8; + + MarginInfo m = new MarginInfo(top, right, bottom, left); + + String design = getMarginTag(top, right, bottom, left); + + // The assertEquals machinery in DeclarativeTestBase uses bean + // introspection and MarginInfo is not a proper bean. It ends up + // considering *all* MarginInfo objects equal... (#18229) + L layout = read(design); + Assert.assertEquals(m, layout.getMargin()); + + testWrite(design, layout); + } + } + + private String getMarginTag(boolean top, boolean right, boolean bottom, + boolean left) { + String s = ""; + } +} diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java index 8ccd41f797..38bd68e6e1 100644 --- a/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java +++ b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java @@ -21,7 +21,7 @@ import java.util.List; import org.junit.Test; import com.vaadin.shared.ui.label.ContentMode; -import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.tests.server.component.DeclarativeMarginTest; import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; @@ -35,58 +35,42 @@ import com.vaadin.ui.VerticalLayout; * @author Vaadin Ltd */ public class AbstractOrderedLayoutDeclarativeTest extends - DeclarativeTestBase { + DeclarativeMarginTest { private List defaultAlignments = Arrays.asList(new String[] { ":top", ":left" }); - @Test - public void testMargin() { - String design = getDesign(0, true); - AbstractOrderedLayout layout = getLayout(0, true, null); - testRead(design, layout); - testWrite(design, layout); - design = getDesign(0, false); - layout = getLayout(0, false, null); - testRead(design, layout); - testWrite(design, layout); - } - @Test public void testExpandRatio() { - String design = getDesign(1, false); - AbstractOrderedLayout layout = getLayout(1, false, null); + String design = getDesign(1); + AbstractOrderedLayout layout = getLayout(1, null); testRead(design, layout); testWrite(design, layout); - design = getDesign(0.25f, false); - layout = getLayout(0.25f, false, null); + design = getDesign(0.25f); + layout = getLayout(0.25f, null); testRead(design, layout); testWrite(design, layout); } @Test public void testAlignment() { - String design = getDesign(0, false, ":top", ":left"); - AbstractOrderedLayout layout = getLayout(0, false, Alignment.TOP_LEFT); + String design = getDesign(0, ":top", ":left"); + AbstractOrderedLayout layout = getLayout(0, Alignment.TOP_LEFT); testRead(design, layout); testWrite(design, layout); - design = getDesign(0, false, ":middle", ":center"); - layout = getLayout(0, false, Alignment.MIDDLE_CENTER); + design = getDesign(0, ":middle", ":center"); + layout = getLayout(0, Alignment.MIDDLE_CENTER); testRead(design, layout); testWrite(design, layout); - design = getDesign(0, false, ":bottom", ":right"); - layout = getLayout(0, false, Alignment.BOTTOM_RIGHT); + design = getDesign(0, ":bottom", ":right"); + layout = getLayout(0, Alignment.BOTTOM_RIGHT); testRead(design, layout); testWrite(design, layout); } - private String getDesign(float expandRatio, boolean margin, - String... alignments) { - String result = " Date: Thu, 11 Jun 2015 13:40:30 +0300 Subject: Adds margin support to GridLayout declarative format (#18238) Change-Id: I5561ccf38f6bac3a304f6e8ab6262cb8bd391021 --- server/src/com/vaadin/ui/GridLayout.java | 5 ++ .../server/component/DeclarativeMarginTest.java | 76 ---------------------- .../component/DeclarativeMarginTestBase.java | 72 ++++++++++++++++++++ .../AbstractOrderedLayoutDeclarativeTest.java | 9 ++- .../gridlayout/GridLayoutDeclarativeTest.java | 10 ++- 5 files changed, 92 insertions(+), 80 deletions(-) delete mode 100644 server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTest.java create mode 100644 server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java (limited to 'server') diff --git a/server/src/com/vaadin/ui/GridLayout.java b/server/src/com/vaadin/ui/GridLayout.java index 96b58d7e67..6ccb272704 100644 --- a/server/src/com/vaadin/ui/GridLayout.java +++ b/server/src/com/vaadin/ui/GridLayout.java @@ -1317,6 +1317,8 @@ public class GridLayout extends AbstractLayout implements public void readDesign(Element design, DesignContext designContext) { super.readDesign(design, designContext); + setMargin(readMargin(design, getMargin(), designContext)); + // Prepare a 2D map for reading column contents Elements rowElements = design.getElementsByTag("row"); List> rows = new ArrayList>(); @@ -1447,6 +1449,9 @@ public class GridLayout extends AbstractLayout implements super.writeDesign(design, designContext); GridLayout def = designContext.getDefaultInstance(this); + + writeMargin(design, getMargin(), def.getMargin(), designContext); + if (components.isEmpty() || !designContext.shouldWriteChildren(this, def)) { return; diff --git a/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTest.java b/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTest.java deleted file mode 100644 index d31a93a68b..0000000000 --- a/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.tests.server.component; - -import org.junit.Assert; -import org.junit.Ignore; -import org.junit.Test; - -import com.vaadin.shared.ui.MarginInfo; -import com.vaadin.tests.design.DeclarativeTestBase; -import com.vaadin.ui.Layout; -import com.vaadin.ui.Layout.MarginHandler; - -@Ignore -public abstract class DeclarativeMarginTest - extends DeclarativeTestBase { - - @Test - public void testMargins() { - - for (int i = 0; i < 16; ++i) { - boolean top = (i & 1) == 1; - boolean right = (i & 2) == 2; - boolean bottom = (i & 4) == 4; - boolean left = (i & 8) == 8; - - MarginInfo m = new MarginInfo(top, right, bottom, left); - - String design = getMarginTag(top, right, bottom, left); - - // The assertEquals machinery in DeclarativeTestBase uses bean - // introspection and MarginInfo is not a proper bean. It ends up - // considering *all* MarginInfo objects equal... (#18229) - L layout = read(design); - Assert.assertEquals(m, layout.getMargin()); - - testWrite(design, layout); - } - } - - private String getMarginTag(boolean top, boolean right, boolean bottom, - boolean left) { - String s = ""; - } -} diff --git a/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java b/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java new file mode 100644 index 0000000000..9fcb64acca --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/DeclarativeMarginTestBase.java @@ -0,0 +1,72 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component; + +import org.junit.Assert; + +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.Layout; +import com.vaadin.ui.Layout.MarginHandler; + +public abstract class DeclarativeMarginTestBase + extends DeclarativeTestBase { + + protected void testMargins(String componentTag) { + + for (int i = 0; i < 16; ++i) { + boolean top = (i & 1) == 1; + boolean right = (i & 2) == 2; + boolean bottom = (i & 4) == 4; + boolean left = (i & 8) == 8; + + MarginInfo m = new MarginInfo(top, right, bottom, left); + + String design = getMarginTag(componentTag, top, right, bottom, left); + + // The assertEquals machinery in DeclarativeTestBase uses bean + // introspection and MarginInfo is not a proper bean. It ends up + // considering *all* MarginInfo objects equal... (#18229) + L layout = read(design); + Assert.assertEquals(m, layout.getMargin()); + + testWrite(design, layout); + } + } + + private String getMarginTag(String componentTag, boolean top, + boolean right, boolean bottom, boolean left) { + String s = "<" + componentTag + " "; + + if (left && right && top && bottom) { + s += "margin='true'"; + } else { + if (left) { + s += "margin-left='true' "; + } + if (right) { + s += "margin-right='true' "; + } + if (top) { + s += "margin-top='true' "; + } + if (bottom) { + s += "margin-bottom='true' "; + } + } + return s + " />"; + } +} diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java index 38bd68e6e1..28ccfa407c 100644 --- a/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java +++ b/server/tests/src/com/vaadin/tests/server/component/abstractorderedlayout/AbstractOrderedLayoutDeclarativeTest.java @@ -21,7 +21,7 @@ import java.util.List; import org.junit.Test; import com.vaadin.shared.ui.label.ContentMode; -import com.vaadin.tests.server.component.DeclarativeMarginTest; +import com.vaadin.tests.server.component.DeclarativeMarginTestBase; import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; @@ -35,11 +35,16 @@ import com.vaadin.ui.VerticalLayout; * @author Vaadin Ltd */ public class AbstractOrderedLayoutDeclarativeTest extends - DeclarativeMarginTest { + DeclarativeMarginTestBase { private List defaultAlignments = Arrays.asList(new String[] { ":top", ":left" }); + @Test + public void testMargins() { + testMargins("v-vertical-layout"); + } + @Test public void testExpandRatio() { String design = getDesign(1); diff --git a/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java b/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java index 7c9c126707..9d3b5001da 100644 --- a/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java +++ b/server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java @@ -18,13 +18,19 @@ package com.vaadin.tests.server.component.gridlayout; import org.junit.Assert; import org.junit.Test; -import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.tests.server.component.DeclarativeMarginTestBase; import com.vaadin.ui.Button; import com.vaadin.ui.Component; import com.vaadin.ui.GridLayout; import com.vaadin.ui.declarative.DesignContext; -public class GridLayoutDeclarativeTest extends DeclarativeTestBase { +public class GridLayoutDeclarativeTest extends + DeclarativeMarginTestBase { + + @Test + public void testMargins() { + testMargins("v-grid-layout"); + } @Test public void testSimpleGridLayout() { -- cgit v1.2.3 From 21427ab2a60da967c489d6cc86bf9d89eb02412a Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Wed, 20 May 2015 20:59:55 +0300 Subject: Render nested invalid layouts correctly (#17598) Change-Id: I959d62091f79c171a8c9f2c9b4ed2c7a67c65c39 --- .../com/vaadin/server/ComponentSizeValidator.java | 41 ++++++++-- .../orderedlayout/NestedInvalidLayouts.java | 87 ++++++++++++++++++++++ .../orderedlayout/NestedInvalidLayoutsTest.java | 57 ++++++++++++++ .../table/SelectAllConstantViewport.java | 2 + 4 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/orderedlayout/NestedInvalidLayouts.java create mode 100644 uitest/src/com/vaadin/tests/components/orderedlayout/NestedInvalidLayoutsTest.java (limited to 'server') diff --git a/server/src/com/vaadin/server/ComponentSizeValidator.java b/server/src/com/vaadin/server/ComponentSizeValidator.java index 2d88ae3b53..1fbd840932 100644 --- a/server/src/com/vaadin/server/ComponentSizeValidator.java +++ b/server/src/com/vaadin/server/ComponentSizeValidator.java @@ -415,7 +415,7 @@ public class ComponentSizeValidator implements Serializable { // main window, valid situation return true; } - if (parent.getHeight() < 0) { + if (isEffectiveUndefinedHeight(component)) { // Undefined height if (parent instanceof Window) { // Sub window with undefined size has a min-height @@ -513,10 +513,7 @@ public class ComponentSizeValidator implements Serializable { // Sub window with undefined size has a min-width return true; } - - if (parent.getWidth() < 0) { - // Undefined width - + if (isEffectiveUndefinedWidth(parent)) { if (parent instanceof AbstractOrderedLayout) { AbstractOrderedLayout ol = (AbstractOrderedLayout) parent; boolean horizontal = true; @@ -591,6 +588,40 @@ public class ComponentSizeValidator implements Serializable { } + /** + * Checks if this component will be rendered with undefined width, either + * because it has been set to undefined wide or because the parent forces it + * to be (100% inside undefined) + * + */ + private static boolean isEffectiveUndefinedWidth(Component parent) { + if (parent == null) { + return false; + } else if (parent.getWidth() < 0) { + return true; + } else if (parent.getWidthUnits() == Unit.PERCENTAGE) { + return isEffectiveUndefinedWidth(parent.getParent()); + } + return false; + } + + /** + * Checks if this component will be rendered with undefined Height, either + * because it has been set to undefined wide or because the parent forces it + * to be (100% inside undefined) + * + */ + private static boolean isEffectiveUndefinedHeight(Component parent) { + if (parent == null) { + return false; + } else if (parent.getHeight() < 0) { + return true; + } else if (parent.getHeightUnits() == Unit.PERCENTAGE) { + return isEffectiveUndefinedHeight(parent.getParent()); + } + return false; + } + private static boolean hasNonRelativeWidthComponent(Form form) { Layout layout = form.getLayout(); Layout footer = form.getFooter(); diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/NestedInvalidLayouts.java b/uitest/src/com/vaadin/tests/components/orderedlayout/NestedInvalidLayouts.java new file mode 100644 index 0000000000..9bc8a418da --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/NestedInvalidLayouts.java @@ -0,0 +1,87 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.orderedlayout; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.NativeButton; +import com.vaadin.ui.VerticalLayout; + +/** + * + * @since + * @author Vaadin Ltd + */ +public class NestedInvalidLayouts extends AbstractTestUI { + @Override + protected void setup(VaadinRequest request) { + fullWidthTest(getLayout(), null); + fullWidthTest(getLayout(), "100%"); + fullHeightTest(getLayout(), null); + fullHeightTest(getLayout(), "100%"); + } + + private void fullWidthTest(VerticalLayout layout, String rootWidth) { + // Contains + // HL (-1) + // * VL (100%) + // ** Button (-1) (wide) + // ** Button (100%) + + // This should be rendered just as if VL width was -1 (which it will + // become when sending width to client), i.e. both buttons should be + // equally wide + + final VerticalLayout l = new VerticalLayout(); + l.setWidth(rootWidth); + final Button c = new Button("blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + c.setWidth(null); + l.addComponent(c); + final Button b = new Button("c"); + b.setWidth("100%"); + l.addComponent(b); + layout.addComponent(new HorizontalLayout(l)); + } + + private void fullHeightTest(VerticalLayout layout, String rootHeight) { + // Contains (height) + // VL (-1) + // * HL (100%) + // ** Button (200px) (high) + // ** Button (100%) + + // This should be rendered just as if HL height was -1 (which it will + // become when sending height to client), i.e. both buttons should be + // equally high + + final HorizontalLayout l = new HorizontalLayout(); + l.setHeight(rootHeight); + + final NativeButton c = new NativeButton("hiiiigh"); + c.setWidth(null); + c.setHeight("200px"); + l.addComponent(c); + final NativeButton b = new NativeButton("c"); + b.setHeight("100%"); + l.addComponent(b); + VerticalLayout vl = new VerticalLayout(l); + vl.setHeight("100%"); + layout.addComponent(vl); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/NestedInvalidLayoutsTest.java b/uitest/src/com/vaadin/tests/components/orderedlayout/NestedInvalidLayoutsTest.java new file mode 100644 index 0000000000..cbae7acc94 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/NestedInvalidLayoutsTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.orderedlayout; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.NativeButtonElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class NestedInvalidLayoutsTest extends SingleBrowserTest { + + @Test + public void ensureCorrectSizes() { + openTestURL(); + + // All Button components should have equal width + List widths = new ArrayList(); + List all = $(ButtonElement.class).state( + "primaryStyleName", "v-button").all(); + for (ButtonElement button : all) { + widths.add(button.getSize().getWidth()); + } + assertAllEqual(widths); + + // All NativeButton components should have equal height + List heights = new ArrayList(); + for (NativeButtonElement button : $(NativeButtonElement.class).all()) { + heights.add(button.getSize().getHeight()); + } + assertAllEqual(heights); + } + + private void assertAllEqual(List values) { + Integer first = values.get(0); + for (Integer w : values) { + Assert.assertEquals(first, w); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/SelectAllConstantViewport.java b/uitest/src/com/vaadin/tests/components/table/SelectAllConstantViewport.java index 5a406eac48..3bd17c163c 100644 --- a/uitest/src/com/vaadin/tests/components/table/SelectAllConstantViewport.java +++ b/uitest/src/com/vaadin/tests/components/table/SelectAllConstantViewport.java @@ -72,6 +72,8 @@ public class SelectAllConstantViewport extends AbstractTestUIWithLog { layout.addComponent(table); layout.setSizeFull(); addComponent(layout); + getContent().setSizeFull(); + getLayout().setSizeFull(); } /* -- cgit v1.2.3