summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/data/Container.java2
-rw-r--r--server/src/com/vaadin/data/Item.java2
-rw-r--r--server/src/com/vaadin/data/Property.java2
-rw-r--r--server/src/com/vaadin/data/fieldgroup/FieldGroup.java3
-rw-r--r--server/src/com/vaadin/data/util/AbstractBeanContainer.java2
-rw-r--r--server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java2
-rw-r--r--server/src/com/vaadin/data/util/ContainerOrderedWrapper.java2
-rw-r--r--server/src/com/vaadin/data/util/FilesystemContainer.java4
-rw-r--r--server/src/com/vaadin/data/util/IndexedContainer.java14
-rw-r--r--server/src/com/vaadin/data/util/MethodProperty.java11
-rw-r--r--server/src/com/vaadin/data/util/NestedMethodProperty.java10
-rw-r--r--server/src/com/vaadin/data/util/ObjectProperty.java13
-rw-r--r--server/src/com/vaadin/data/util/PropertyFormatter.java2
-rw-r--r--server/src/com/vaadin/data/util/PropertysetItem.java2
-rw-r--r--server/src/com/vaadin/data/util/TextFileProperty.java2
-rw-r--r--server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java2
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/RowItem.java2
-rw-r--r--server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java2
-rw-r--r--server/src/com/vaadin/server/BrowserPopupOpener.java168
-rw-r--r--server/src/com/vaadin/server/BrowserPopupUIProvider.java50
-rw-r--r--server/src/com/vaadin/server/FileDownloader.java143
-rw-r--r--server/src/com/vaadin/server/VaadinService.java2
-rw-r--r--server/src/com/vaadin/ui/AbstractField.java31
-rw-r--r--server/src/com/vaadin/ui/AbstractSelect.java2
-rw-r--r--server/src/com/vaadin/ui/AbstractTextField.java2
-rw-r--r--server/src/com/vaadin/ui/DefaultFieldFactory.java4
-rw-r--r--server/src/com/vaadin/ui/Form.java4
-rw-r--r--server/src/com/vaadin/ui/Label.java9
-rw-r--r--server/src/com/vaadin/ui/ProgressIndicator.java2
-rw-r--r--server/src/com/vaadin/ui/Slider.java9
-rw-r--r--server/tests/src/com/vaadin/data/util/filter/AbstractFilterTest.java2
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java54
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java8
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java6
-rw-r--r--server/tests/src/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java2
35 files changed, 442 insertions, 135 deletions
diff --git a/server/src/com/vaadin/data/Container.java b/server/src/com/vaadin/data/Container.java
index 47a0f9e7c8..1a453c7cd6 100644
--- a/server/src/com/vaadin/data/Container.java
+++ b/server/src/com/vaadin/data/Container.java
@@ -132,7 +132,7 @@ public interface Container extends Serializable {
* ID of the Property to retrieve
* @return Property with the given ID or <code>null</code>
*/
- public Property<?> getContainerProperty(Object itemId, Object propertyId);
+ public Property getContainerProperty(Object itemId, Object propertyId);
/**
* Gets the data type of all Properties identified by the given Property ID.
diff --git a/server/src/com/vaadin/data/Item.java b/server/src/com/vaadin/data/Item.java
index 8bdf963835..bff046bd38 100644
--- a/server/src/com/vaadin/data/Item.java
+++ b/server/src/com/vaadin/data/Item.java
@@ -40,7 +40,7 @@ public interface Item extends Serializable {
* identifier of the Property to get
* @return the Property with the given ID or <code>null</code>
*/
- public Property<?> getItemProperty(Object id);
+ public Property getItemProperty(Object id);
/**
* Gets the collection of IDs of all Properties stored in the Item.
diff --git a/server/src/com/vaadin/data/Property.java b/server/src/com/vaadin/data/Property.java
index 7e46af09b7..146355cb48 100644
--- a/server/src/com/vaadin/data/Property.java
+++ b/server/src/com/vaadin/data/Property.java
@@ -76,7 +76,7 @@ public interface Property<T> extends Serializable {
* @throws Property.ReadOnlyException
* if the object is in read-only mode
*/
- public void setValue(Object newValue) throws Property.ReadOnlyException;
+ public void setValue(T newValue) throws Property.ReadOnlyException;
/**
* Returns the type of the Property. The methods <code>getValue</code> and
diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
index 5d0c23e779..6bef69fe5b 100644
--- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java
@@ -274,8 +274,7 @@ public class FieldGroup implements Serializable {
* If the property was not found in the item or no item has been
* set
*/
- protected Property<?> getItemProperty(Object propertyId)
- throws BindException {
+ protected Property getItemProperty(Object propertyId) throws BindException {
Item item = getItemDataSource();
if (item == null) {
throw new BindException("Could not lookup property with id "
diff --git a/server/src/com/vaadin/data/util/AbstractBeanContainer.java b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
index cb09cdad46..3767f816e9 100644
--- a/server/src/com/vaadin/data/util/AbstractBeanContainer.java
+++ b/server/src/com/vaadin/data/util/AbstractBeanContainer.java
@@ -274,7 +274,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
* java.lang.Object)
*/
@Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+ public Property getContainerProperty(Object itemId, Object propertyId) {
Item item = getItem(itemId);
if (item == null) {
return null;
diff --git a/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java b/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java
index fdfb296186..ade8c22745 100644
--- a/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java
+++ b/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java
@@ -671,7 +671,7 @@ public class ContainerHierarchicalWrapper implements Container.Hierarchical,
* documentation from implemented interface.
*/
@Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+ public Property getContainerProperty(Object itemId, Object propertyId) {
return container.getContainerProperty(itemId, propertyId);
}
diff --git a/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java b/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java
index ad1eda9a8d..a44da84ae8 100644
--- a/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java
+++ b/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java
@@ -463,7 +463,7 @@ public class ContainerOrderedWrapper implements Container.Ordered,
* documentation from implemented interface.
*/
@Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+ public Property getContainerProperty(Object itemId, Object propertyId) {
return container.getContainerProperty(itemId, propertyId);
}
diff --git a/server/src/com/vaadin/data/util/FilesystemContainer.java b/server/src/com/vaadin/data/util/FilesystemContainer.java
index 4c27169409..dbfe3bb6e8 100644
--- a/server/src/com/vaadin/data/util/FilesystemContainer.java
+++ b/server/src/com/vaadin/data/util/FilesystemContainer.java
@@ -481,7 +481,7 @@ public class FilesystemContainer implements Container.Hierarchical {
* @return the requested property's value, or <code>null</code>
*/
@Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+ public Property getContainerProperty(Object itemId, Object propertyId) {
if (!(itemId instanceof File)) {
return null;
@@ -633,7 +633,7 @@ public class FilesystemContainer implements Container.Hierarchical {
* here, we use the default documentation from implemented interface.
*/
@Override
- public Property<?> getItemProperty(Object id) {
+ public Property getItemProperty(Object id) {
return getContainerProperty(file, id);
}
diff --git a/server/src/com/vaadin/data/util/IndexedContainer.java b/server/src/com/vaadin/data/util/IndexedContainer.java
index 7273b28b66..6326d494b2 100644
--- a/server/src/com/vaadin/data/util/IndexedContainer.java
+++ b/server/src/com/vaadin/data/util/IndexedContainer.java
@@ -163,7 +163,7 @@ public class IndexedContainer extends
* java.lang.Object)
*/
@Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+ public Property getContainerProperty(Object itemId, Object propertyId) {
if (!containsId(itemId)) {
return null;
}
@@ -734,7 +734,7 @@ public class IndexedContainer extends
* @see com.vaadin.data.Item#getItemProperty(java.lang.Object)
*/
@Override
- public Property<?> getItemProperty(Object id) {
+ public Property getItemProperty(Object id) {
return new IndexedContainerProperty(itemId, id);
}
@@ -841,7 +841,7 @@ public class IndexedContainer extends
*
* @since 3.0
*/
- private class IndexedContainerProperty implements Property<Object>,
+ private class IndexedContainerProperty<T> implements Property<T>,
Property.ValueChangeNotifier {
/**
@@ -881,8 +881,8 @@ public class IndexedContainer extends
* @see com.vaadin.data.Property#getType()
*/
@Override
- public Class<?> getType() {
- return types.get(propertyId);
+ public Class<T> getType() {
+ return (Class<T>) types.get(propertyId);
}
/*
@@ -891,8 +891,8 @@ public class IndexedContainer extends
* @see com.vaadin.data.Property#getValue()
*/
@Override
- public Object getValue() {
- return items.get(itemId).get(propertyId);
+ public T getValue() {
+ return (T) items.get(itemId).get(propertyId);
}
/*
diff --git a/server/src/com/vaadin/data/util/MethodProperty.java b/server/src/com/vaadin/data/util/MethodProperty.java
index 1ae60daac0..52ea2b0347 100644
--- a/server/src/com/vaadin/data/util/MethodProperty.java
+++ b/server/src/com/vaadin/data/util/MethodProperty.java
@@ -651,21 +651,14 @@ public class MethodProperty<T> extends AbstractProperty<T> {
* @see #invokeSetMethod(Object)
*/
@Override
- @SuppressWarnings("unchecked")
- public void setValue(Object newValue) throws Property.ReadOnlyException {
+ public void setValue(T newValue) throws Property.ReadOnlyException {
// Checks the mode
if (isReadOnly()) {
throw new Property.ReadOnlyException();
}
- // Checks the type of the value
- if (newValue != null && !type.isAssignableFrom(newValue.getClass())) {
- throw new IllegalArgumentException(
- "Invalid value type for ObjectProperty.");
- }
-
- invokeSetMethod((T) newValue);
+ invokeSetMethod(newValue);
fireValueChange();
}
diff --git a/server/src/com/vaadin/data/util/NestedMethodProperty.java b/server/src/com/vaadin/data/util/NestedMethodProperty.java
index 692e6a085f..3961358c4b 100644
--- a/server/src/com/vaadin/data/util/NestedMethodProperty.java
+++ b/server/src/com/vaadin/data/util/NestedMethodProperty.java
@@ -217,19 +217,13 @@ public class NestedMethodProperty<T> extends AbstractProperty<T> {
* @see #invokeSetMethod(Object)
*/
@Override
- public void setValue(Object newValue) throws ReadOnlyException {
+ public void setValue(T newValue) throws ReadOnlyException {
// Checks the mode
if (isReadOnly()) {
throw new Property.ReadOnlyException();
}
- // Checks the type of the value
- if (newValue != null && !type.isAssignableFrom(newValue.getClass())) {
- throw new IllegalArgumentException(
- "Invalid value type for NestedMethodProperty.");
- }
-
- invokeSetMethod((T) newValue);
+ invokeSetMethod(newValue);
fireValueChange();
}
diff --git a/server/src/com/vaadin/data/util/ObjectProperty.java b/server/src/com/vaadin/data/util/ObjectProperty.java
index 9e9687b2d5..b0ab18eec2 100644
--- a/server/src/com/vaadin/data/util/ObjectProperty.java
+++ b/server/src/com/vaadin/data/util/ObjectProperty.java
@@ -128,23 +128,14 @@ public class ObjectProperty<T> extends AbstractProperty<T> {
* read-only mode
*/
@Override
- @SuppressWarnings("unchecked")
- public void setValue(Object newValue) throws Property.ReadOnlyException {
+ public void setValue(T newValue) throws Property.ReadOnlyException {
// Checks the mode
if (isReadOnly()) {
throw new Property.ReadOnlyException();
}
- // Checks the type of the value
- if (newValue != null && !type.isAssignableFrom(newValue.getClass())) {
- throw new IllegalArgumentException("Invalid value type "
- + newValue.getClass().getName()
- + " for ObjectProperty of type " + type.getName() + ".");
- }
-
- // the cast is safe after an isAssignableFrom check
- this.value = (T) newValue;
+ this.value = newValue;
fireValueChange();
}
diff --git a/server/src/com/vaadin/data/util/PropertyFormatter.java b/server/src/com/vaadin/data/util/PropertyFormatter.java
index 26f93b9582..58a53cd7da 100644
--- a/server/src/com/vaadin/data/util/PropertyFormatter.java
+++ b/server/src/com/vaadin/data/util/PropertyFormatter.java
@@ -212,7 +212,7 @@ public abstract class PropertyFormatter<T> extends AbstractProperty<String>
}
@Override
- public void setValue(Object newValue) throws ReadOnlyException {
+ public void setValue(String newValue) throws ReadOnlyException {
if (dataSource == null) {
return;
}
diff --git a/server/src/com/vaadin/data/util/PropertysetItem.java b/server/src/com/vaadin/data/util/PropertysetItem.java
index b423c72f43..7ca0fc6973 100644
--- a/server/src/com/vaadin/data/util/PropertysetItem.java
+++ b/server/src/com/vaadin/data/util/PropertysetItem.java
@@ -68,7 +68,7 @@ public class PropertysetItem implements Item, Item.PropertySetChangeNotifier,
* @return the Property with the given ID or <code>null</code>
*/
@Override
- public Property<?> getItemProperty(Object id) {
+ public Property getItemProperty(Object id) {
return map.get(id);
}
diff --git a/server/src/com/vaadin/data/util/TextFileProperty.java b/server/src/com/vaadin/data/util/TextFileProperty.java
index 05d0c6f683..9c93a75c82 100644
--- a/server/src/com/vaadin/data/util/TextFileProperty.java
+++ b/server/src/com/vaadin/data/util/TextFileProperty.java
@@ -129,7 +129,7 @@ public class TextFileProperty extends AbstractProperty<String> {
* @see com.vaadin.data.Property#setValue(java.lang.Object)
*/
@Override
- public void setValue(Object newValue) throws ReadOnlyException {
+ public void setValue(String newValue) throws ReadOnlyException {
if (isReadOnly()) {
throw new ReadOnlyException();
}
diff --git a/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java b/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
index c03a4ce959..d8d27ae4c8 100644
--- a/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
+++ b/server/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
@@ -74,7 +74,7 @@ public class TransactionalPropertyWrapper<T> extends AbstractProperty<T>
}
@Override
- public void setValue(Object newValue) throws ReadOnlyException {
+ public void setValue(T newValue) throws ReadOnlyException {
// Causes a value change to be sent to this listener which in turn fires
// a new value change event for this property
wrappedProperty.setValue(newValue);
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/RowItem.java b/server/src/com/vaadin/data/util/sqlcontainer/RowItem.java
index ed256b2b5a..461900b27b 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/RowItem.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/RowItem.java
@@ -61,7 +61,7 @@ public final class RowItem implements Item {
}
@Override
- public Property<?> getItemProperty(Object id) {
+ public Property getItemProperty(Object id) {
if (id instanceof String && id != null) {
for (ColumnProperty cp : properties) {
if (id.equals(cp.getPropertyId())) {
diff --git a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
index 64014cd254..69186fc310 100644
--- a/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
+++ b/server/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
@@ -248,7 +248,7 @@ public class SQLContainer implements Container, Container.Filterable,
*/
@Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+ public Property getContainerProperty(Object itemId, Object propertyId) {
Item item = getItem(itemId);
if (item == null) {
return null;
diff --git a/server/src/com/vaadin/server/BrowserPopupOpener.java b/server/src/com/vaadin/server/BrowserPopupOpener.java
new file mode 100644
index 0000000000..c55fa65931
--- /dev/null
+++ b/server/src/com/vaadin/server/BrowserPopupOpener.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2012 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.server;
+
+import com.vaadin.shared.ApplicationConstants;
+import com.vaadin.shared.ui.BrowserPopupExtensionState;
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.UI;
+
+/**
+ * Component extension that opens a browser popup window when the extended
+ * component is clicked.
+ *
+ * @author Vaadin Ltd
+ * @since 7.0.0
+ */
+public class BrowserPopupOpener extends AbstractExtension {
+
+ private final BrowserPopupUIProvider uiProvider;
+
+ /**
+ * Creates a popup opener that will open popups containing the provided UI
+ * class
+ *
+ * @param uiClass
+ * the UI class that should be opened when the extended component
+ * is clicked
+ */
+ public BrowserPopupOpener(Class<? extends UI> uiClass) {
+ this(uiClass, generateUIClassUrl(uiClass));
+ }
+
+ /**
+ * Creates a popup opener that will open popups containing the provided UI
+ * using the provided path
+ *
+ * @param uiClass
+ * the UI class that should be opened when the extended component
+ * is clicked
+ * @param path
+ * the path that the UI should be bound to
+ */
+ public BrowserPopupOpener(Class<? extends UI> uiClass, String path) {
+ // Create a Resource with a translated URL going to the VaadinService
+ this(new ExternalResource(ApplicationConstants.APP_PROTOCOL_PREFIX
+ + path), new BrowserPopupUIProvider(uiClass, path));
+ }
+
+ /**
+ * Creates a popup opener that will open popups to the provided URL
+ *
+ * @param url
+ * the URL to open in the popup
+ */
+ public BrowserPopupOpener(String url) {
+ this(new ExternalResource(url));
+ }
+
+ /**
+ * Creates a popup opener that will open popups to the provided resource
+ *
+ * @param resource
+ * the resource to open in the popup
+ */
+ public BrowserPopupOpener(Resource resource) {
+ this(resource, null);
+ }
+
+ private BrowserPopupOpener(Resource resource,
+ BrowserPopupUIProvider uiProvider) {
+ this.uiProvider = uiProvider;
+ setResource("popup", resource);
+ }
+
+ public void extend(AbstractComponent target) {
+ super.extend(target);
+ }
+
+ /**
+ * Sets the target window name that will be used when opening the popup. If
+ * a popup has already been opened with the same name, the contents of that
+ * window will be replaced instead of opening a new window. If the name is
+ * <code>null</code> or <code>"blank"</code>, the popup will always be
+ * opened in a new window.
+ *
+ * @param popupName
+ * the target name for the popups
+ */
+ public void setPopupName(String popupName) {
+ getState().target = popupName;
+ }
+
+ /**
+ * Gets the popup target name.
+ *
+ * @see #setPopupName(String)
+ *
+ * @return the popup target string
+ */
+ public String getPopupName() {
+ return getState().target;
+ }
+
+ // Avoid breaking url to multiple lines
+ // @formatter:off
+ /**
+ * Sets the features for opening the popup. See e.g.
+ * {@link https://developer.mozilla.org/en-US/docs/DOM/window.open#Position_and_size_features}
+ * for a description of the commonly supported features.
+ *
+ * @param features a string with popup features, or <code>null</code> to use the default features.
+ */
+ // @formatter:on
+ public void setFeatures(String features) {
+ getState().features = features;
+ }
+
+ /**
+ * Gets the popup features.
+ *
+ * @see #setFeatures(String)
+ * @return
+ */
+ public String getFeatures() {
+ return getState().features;
+ }
+
+ @Override
+ protected BrowserPopupExtensionState getState() {
+ return (BrowserPopupExtensionState) super.getState();
+ }
+
+ @Override
+ public void attach() {
+ super.attach();
+ if (uiProvider != null
+ && !getSession().getUIProviders().contains(uiProvider)) {
+ getSession().addUIProvider(uiProvider);
+ }
+ }
+
+ @Override
+ public void detach() {
+ if (uiProvider != null) {
+ getSession().removeUIProvider(uiProvider);
+ }
+ super.detach();
+ }
+
+ private static String generateUIClassUrl(Class<? extends UI> uiClass) {
+ return "popup/" + uiClass.getSimpleName();
+ }
+
+}
diff --git a/server/src/com/vaadin/server/BrowserPopupUIProvider.java b/server/src/com/vaadin/server/BrowserPopupUIProvider.java
new file mode 100644
index 0000000000..23036dabed
--- /dev/null
+++ b/server/src/com/vaadin/server/BrowserPopupUIProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 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.server;
+
+import com.vaadin.ui.UI;
+
+public class BrowserPopupUIProvider extends UIProvider {
+
+ private final String path;
+ private final Class<? extends UI> uiClass;
+
+ public BrowserPopupUIProvider(Class<? extends UI> uiClass, String path) {
+ this.path = ensureInitialSlash(path);
+ this.uiClass = uiClass;
+ }
+
+ private static String ensureInitialSlash(String path) {
+ if (path == null) {
+ return null;
+ } else if (!path.startsWith("/")) {
+ return '/' + path;
+ } else {
+ return path;
+ }
+ }
+
+ @Override
+ public Class<? extends UI> getUIClass(UIClassSelectionEvent event) {
+ String requestPathInfo = event.getRequest().getRequestPathInfo();
+ if (path.equals(requestPathInfo)) {
+ return uiClass;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/server/src/com/vaadin/server/FileDownloader.java b/server/src/com/vaadin/server/FileDownloader.java
new file mode 100644
index 0000000000..a5f450c28b
--- /dev/null
+++ b/server/src/com/vaadin/server/FileDownloader.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2012 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.server;
+
+import java.io.IOException;
+
+import com.vaadin.ui.AbstractComponent;
+
+/**
+ * Extension that starts a download when the extended component is clicked. This
+ * is used to overcome two challenges:
+ * <ul>
+ * <li>Resource should be bound to a component to allow it to be garbage
+ * collected when there are no longer any ways of reaching the resource.</li>
+ * <li>Download should be started directly when the user clicks e.g. a Button
+ * without going through a server-side click listener to avoid triggering
+ * security warnings in some browsers.</li>
+ * </ul>
+ * <p>
+ * Please note that the download will be started in an iframe, which means that
+ * care should be taken to avoid serving content types that might make the
+ * browser attempt to show the content using a plugin instead of downloading it.
+ * Connector resources (e.g. {@link FileResource} and {@link ClassResource})
+ * will automatically be served using a
+ * <code>Content-Type: application/octet-stream</code> header unless
+ * {@link #setOverrideContentType(boolean)} has been set to <code>false</code>
+ * while files served in other ways, (e.g. {@link ExternalResource} or
+ * {@link ThemeResource}) will not automatically get this treatment.
+ * </p>
+ *
+ * @author Vaadin Ltd
+ * @since 7.0.0
+ */
+public class FileDownloader extends AbstractExtension {
+
+ private boolean overrideContentType = true;
+
+ /**
+ * Creates a new file downloader for the given resource. To use the
+ * downloader, you should also {@link #extend(AbstractClientConnector)} the
+ * component.
+ *
+ * @param resource
+ * the resource to download when the user clicks the extended
+ * component.
+ */
+ public FileDownloader(Resource resource) {
+ if (resource == null) {
+ throw new IllegalArgumentException("resource may not be null");
+ }
+ setResource("dl", resource);
+ }
+
+ public void extend(AbstractComponent target) {
+ super.extend(target);
+ }
+
+ /**
+ * Gets the resource set for download.
+ *
+ * @return the resource that will be downloaded if clicking the extended
+ * component
+ */
+ public Resource getFileDownloadResource() {
+ return getResource("dl");
+ }
+
+ /**
+ * Sets whether the content type of served resources should be overriden to
+ * <code>application/octet-stream</code> to reduce the risk of a browser
+ * plugin choosing to display the resource instead of downloading it. This
+ * is by default set to <code>true</code>.
+ * <p>
+ * Please note that this only affects Connector resources (e.g.
+ * {@link FileResource} and {@link ClassResource}) but not other resource
+ * types (e.g. {@link ExternalResource} or {@link ThemeResource}).
+ * </p>
+ *
+ * @param overrideContentType
+ * <code>true</code> to override the content type if possible;
+ * <code>false</code> to use the original content type.
+ */
+ public void setOverrideContentType(boolean overrideContentType) {
+ this.overrideContentType = overrideContentType;
+ }
+
+ /**
+ * Checks whether the content type should be overridden.
+ *
+ * @see #setOverrideContentType(boolean)
+ *
+ * @return <code>true</code> if the content type will be overridden when
+ * possible; <code>false</code> if the original content type will be
+ * used.
+ */
+ public boolean isOverrideContentType() {
+ return overrideContentType;
+ }
+
+ @Override
+ public boolean handleConnectorRequest(VaadinRequest request,
+ VaadinResponse response, String path) throws IOException {
+ if (!path.matches("dl(/.*)?")) {
+ // Ignore if it isn't for us
+ return false;
+ }
+
+ Resource resource = getFileDownloadResource();
+ if (resource instanceof ConnectorResource) {
+ DownloadStream stream = ((ConnectorResource) resource).getStream();
+
+ if (stream.getParameter("Content-Disposition") == null) {
+ // Content-Disposition: attachment generally forces download
+ stream.setParameter("Content-Disposition",
+ "attachment; filename=\"" + stream.getFileName() + "\"");
+ }
+
+ // Content-Type to block eager browser plug-ins from hijacking the
+ // file
+ if (isOverrideContentType()) {
+ stream.setContentType("application/octet-stream;charset=UTF-8");
+ }
+ stream.writeResponse(request, response);
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index 44e82b5898..05e79500bb 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -423,6 +423,8 @@ public abstract class VaadinService implements Serializable {
throws ServiceException {
VaadinServiceSession session = createVaadinSession(request);
+ VaadinServiceSession.setCurrent(session);
+
session.storeInSession(this, request.getWrappedSession());
// Initial locale comes from the request
diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/com/vaadin/ui/AbstractField.java
index d6dd03c171..53301f093a 100644
--- a/server/src/com/vaadin/ui/AbstractField.java
+++ b/server/src/com/vaadin/ui/AbstractField.java
@@ -427,17 +427,9 @@ public abstract class AbstractField<T> extends AbstractComponent implements
* @throws Property.ReadOnlyException
*/
@Override
- public void setValue(Object newFieldValue)
- throws Property.ReadOnlyException, Converter.ConversionException {
- // This check is needed as long as setValue accepts Object instead of T
- if (newFieldValue != null) {
- if (!getType().isAssignableFrom(newFieldValue.getClass())) {
- throw new Converter.ConversionException("Value of type "
- + newFieldValue.getClass() + " cannot be assigned to "
- + getType().getName());
- }
- }
- setValue((T) newFieldValue, false);
+ public void setValue(T newFieldValue) throws Property.ReadOnlyException,
+ Converter.ConversionException {
+ setValue(newFieldValue, false);
}
/**
@@ -695,19 +687,18 @@ public abstract class AbstractField<T> extends AbstractComponent implements
*/
private Object convertToModel(T fieldValue)
throws Converter.ConversionException {
+ Class<?> modelType = null;
+ Property pd = getPropertyDataSource();
+ if (pd != null) {
+ modelType = pd.getType();
+ } else if (getConverter() != null) {
+ modelType = getConverter().getModelType();
+ }
try {
- Class<?> modelType = null;
- Property pd = getPropertyDataSource();
- if (pd != null) {
- modelType = pd.getType();
- } else if (getConverter() != null) {
- modelType = getConverter().getModelType();
- }
return ConverterUtil.convertToModel(fieldValue,
(Class<Object>) modelType, getConverter(), getLocale());
} catch (ConversionException e) {
- throw new ConversionException(
- getConversionError(converter.getModelType()), e);
+ throw new ConversionException(getConversionError(modelType), e);
}
}
diff --git a/server/src/com/vaadin/ui/AbstractSelect.java b/server/src/com/vaadin/ui/AbstractSelect.java
index 78fab068dd..d2092ceb2c 100644
--- a/server/src/com/vaadin/ui/AbstractSelect.java
+++ b/server/src/com/vaadin/ui/AbstractSelect.java
@@ -784,7 +784,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
* @see com.vaadin.data.Container#getContainerProperty(Object, Object)
*/
@Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
+ public Property getContainerProperty(Object itemId, Object propertyId) {
return items.getContainerProperty(itemId, propertyId);
}
diff --git a/server/src/com/vaadin/ui/AbstractTextField.java b/server/src/com/vaadin/ui/AbstractTextField.java
index 3dd2b4dae8..e8618a33ee 100644
--- a/server/src/com/vaadin/ui/AbstractTextField.java
+++ b/server/src/com/vaadin/ui/AbstractTextField.java
@@ -429,7 +429,7 @@ public abstract class AbstractTextField extends AbstractField<String> implements
}
@Override
- public void setValue(Object newValue) throws ReadOnlyException {
+ public void setValue(String newValue) throws ReadOnlyException {
super.setValue(newValue);
/*
* Make sure w reset lastKnownTextContent field on value change. The
diff --git a/server/src/com/vaadin/ui/DefaultFieldFactory.java b/server/src/com/vaadin/ui/DefaultFieldFactory.java
index 28a5b6c669..5072503428 100644
--- a/server/src/com/vaadin/ui/DefaultFieldFactory.java
+++ b/server/src/com/vaadin/ui/DefaultFieldFactory.java
@@ -57,9 +57,9 @@ public class DefaultFieldFactory implements FormFieldFactory, TableFieldFactory
}
@Override
- public Field<?> createField(Container container, Object itemId,
+ public Field createField(Container container, Object itemId,
Object propertyId, Component uiContext) {
- Property<?> containerProperty = container.getContainerProperty(itemId,
+ Property containerProperty = container.getContainerProperty(itemId,
propertyId);
Class<?> type = containerProperty.getType();
Field<?> field = createFieldByPropertyType(type);
diff --git a/server/src/com/vaadin/ui/Form.java b/server/src/com/vaadin/ui/Form.java
index dd804ef67a..4b7782e0a9 100644
--- a/server/src/com/vaadin/ui/Form.java
+++ b/server/src/com/vaadin/ui/Form.java
@@ -572,7 +572,7 @@ public class Form extends AbstractField<Object> implements Item.Editor,
* @see com.vaadin.data.Item#getItemProperty(Object)
*/
@Override
- public Property<?> getItemProperty(Object id) {
+ public Property getItemProperty(Object id) {
final Field<?> field = fields.get(id);
if (field == null) {
// field does not exist or it is not (yet) created for this property
@@ -593,7 +593,7 @@ public class Form extends AbstractField<Object> implements Item.Editor,
* @param propertyId
* the id of the property.
*/
- public Field<?> getField(Object propertyId) {
+ public Field getField(Object propertyId) {
return fields.get(propertyId);
}
diff --git a/server/src/com/vaadin/ui/Label.java b/server/src/com/vaadin/ui/Label.java
index 89281e0c27..27145946d8 100644
--- a/server/src/com/vaadin/ui/Label.java
+++ b/server/src/com/vaadin/ui/Label.java
@@ -192,14 +192,9 @@ public class Label extends AbstractComponent implements Property<String>,
* the New value of the label.
*/
@Override
- public void setValue(Object newStringValue) {
- if (newStringValue != null && newStringValue.getClass() != String.class) {
- throw new Converter.ConversionException("Value of type "
- + newStringValue.getClass() + " cannot be assigned to "
- + String.class.getName());
- }
+ public void setValue(String newStringValue) {
if (getPropertyDataSource() == null) {
- getState().text = (String) newStringValue;
+ getState().text = newStringValue;
} else {
throw new IllegalStateException(
"Label is only a Property.Viewer and cannot update its data source");
diff --git a/server/src/com/vaadin/ui/ProgressIndicator.java b/server/src/com/vaadin/ui/ProgressIndicator.java
index fa51197a8b..1c35d3d1d8 100644
--- a/server/src/com/vaadin/ui/ProgressIndicator.java
+++ b/server/src/com/vaadin/ui/ProgressIndicator.java
@@ -153,7 +153,7 @@ public class ProgressIndicator extends AbstractField<Number> implements
* @see com.vaadin.ui.AbstractField#setValue()
*/
@Override
- public void setValue(Object newValue) {
+ public void setValue(Number newValue) {
if (dataSource == null) {
throw new IllegalStateException("Datasource must be set");
}
diff --git a/server/src/com/vaadin/ui/Slider.java b/server/src/com/vaadin/ui/Slider.java
index fe913f6b2c..4c829a7cb4 100644
--- a/server/src/com/vaadin/ui/Slider.java
+++ b/server/src/com/vaadin/ui/Slider.java
@@ -289,14 +289,9 @@ public class Slider extends AbstractField<Double> {
}
@Override
- public void setValue(Object newFieldValue) {
- if (newFieldValue instanceof Number) {
- // Support setting all types of Numbers
- newFieldValue = ((Number) newFieldValue).doubleValue();
- }
+ public void setValue(Double newFieldValue) {
super.setValue(newFieldValue);
- // The cast is safe if the above call returned without throwing
- getState().value = (Double) newFieldValue;
+ getState().value = newFieldValue;
}
/**
diff --git a/server/tests/src/com/vaadin/data/util/filter/AbstractFilterTest.java b/server/tests/src/com/vaadin/data/util/filter/AbstractFilterTest.java
index 6f96c3a51a..96673ff608 100644
--- a/server/tests/src/com/vaadin/data/util/filter/AbstractFilterTest.java
+++ b/server/tests/src/com/vaadin/data/util/filter/AbstractFilterTest.java
@@ -30,7 +30,7 @@ public abstract class AbstractFilterTest<FILTERTYPE extends Filter> extends
}
@Override
- public void setValue(Object newValue) throws ReadOnlyException {
+ public void setValue(String newValue) throws ReadOnlyException {
throw new ReadOnlyException();
}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java
index 8d4cdc3c7c..83224861b6 100644
--- a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java
@@ -2,10 +2,15 @@ package com.vaadin.tests.server.component.abstractfield;
import java.util.Locale;
+import junit.framework.Assert;
import junit.framework.TestCase;
+import org.junit.Test;
+
import com.vaadin.data.util.MethodProperty;
+import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.converter.Converter;
+import com.vaadin.data.util.converter.Converter.ConversionException;
import com.vaadin.data.util.converter.StringToIntegerConverter;
import com.vaadin.server.VaadinServiceSession;
import com.vaadin.tests.data.bean.Address;
@@ -67,40 +72,6 @@ public class AbstractFieldValueConversions extends TestCase {
assertEquals("abc", paulaBean.getFirstName());
}
- public void testFailingConversion() {
- TextField tf = new TextField();
- tf.setConverter(new Converter<String, Integer>() {
-
- @Override
- public Integer convertToModel(String value, Locale locale) {
- throw new ConversionException("Failed");
- }
-
- @Override
- public String convertToPresentation(Integer value, Locale locale) {
- throw new ConversionException("Failed");
- }
-
- @Override
- public Class<Integer> getModelType() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Class<String> getPresentationType() {
- // TODO Auto-generated method stub
- return null;
- }
- });
- try {
- tf.setValue(1);
- fail("setValue(Integer) should throw an exception");
- } catch (Converter.ConversionException e) {
- // OK, expected
- }
- }
-
public void testIntegerStringConversion() {
TextField tf = new TextField();
@@ -213,4 +184,19 @@ public class AbstractFieldValueConversions extends TestCase {
}
+ @Test
+ public void testNullConverter() {
+ TextField tf = new TextField("foo");
+ tf.setPropertyDataSource(new ObjectProperty<Integer>(12));
+ tf.setConverter((Converter) null);
+ try {
+ Object v = tf.getConvertedValue();
+ System.out.println(v);
+ Assert.fail("Trying to convert String -> Integer should fail when there is no converter");
+ } catch (ConversionException e) {
+ // ok, should happen when there is no converter but conversion is
+ // needed
+ }
+ }
+
}
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java
index 83bb7c4613..e81f4ac6f7 100644
--- a/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java
@@ -63,20 +63,20 @@ public class RemoveListenersOnDetach {
};
};
- Property property = new AbstractProperty() {
+ Property<String> property = new AbstractProperty<String>() {
@Override
- public Object getValue() {
+ public String getValue() {
return null;
}
@Override
- public void setValue(Object newValue) throws ReadOnlyException,
+ public void setValue(String newValue) throws ReadOnlyException,
ConversionException {
fireValueChange();
}
@Override
- public Class<?> getType() {
+ public Class<String> getType() {
return String.class;
}
};
diff --git a/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java b/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java
index b969bf5e53..d1dd87d923 100644
--- a/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java
+++ b/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java
@@ -10,12 +10,12 @@ public class SliderTest extends TestCase {
public void testOutOfBounds() {
Slider s = new Slider(0, 10);
- s.setValue(0);
+ s.setValue(0.0);
Assert.assertEquals(0.0, s.getValue());
- s.setValue(10);
+ s.setValue(10.0);
Assert.assertEquals(10.0, s.getValue());
try {
- s.setValue(20);
+ s.setValue(20.0);
fail("Should throw out of bounds exception");
} catch (ValueOutOfBoundsException e) {
// TODO: handle exception
diff --git a/server/tests/src/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java b/server/tests/src/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java
index f2de4f3c04..c8d6ecce9c 100644
--- a/server/tests/src/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java
+++ b/server/tests/src/com/vaadin/tests/server/components/AbstractTestFieldValueChange.java
@@ -123,7 +123,7 @@ public abstract class AbstractTestFieldValueChange<T> extends TestCase {
* Override in subclasses to set value with changeVariables().
*/
protected void setValue(AbstractField<T> field) {
- field.setValue("newValue");
+ field.setValue((T) "newValue");
}
}