aboutsummaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin/ui
diff options
context:
space:
mode:
authorPekka Hyvönen <pekka@vaadin.com>2015-03-06 11:56:53 +0200
committerPekka Hyvönen <pekka@vaadin.com>2015-03-06 12:29:24 +0200
commit741e798633edd584e62bcb4e6a00911a86908cdf (patch)
tree22d3b4c625376ba7f79ec82488a64f1696539d5b /server/src/com/vaadin/ui
parent3c84a54591d792b69a4d6d736714941edb1d818a (diff)
parent4db0b55aefd83d149e62a7fad2b14fb232d976c8 (diff)
downloadvaadin-framework-741e798633edd584e62bcb4e6a00911a86908cdf.tar.gz
vaadin-framework-741e798633edd584e62bcb4e6a00911a86908cdf.zip
Merge branch 'master' into grid-columnreorder
Conflicts: uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java Change-Id: Ic77c717b9bbdcc38585382d4944ee4491aba3f7d
Diffstat (limited to 'server/src/com/vaadin/ui')
-rw-r--r--server/src/com/vaadin/ui/Flash.java10
-rw-r--r--server/src/com/vaadin/ui/Grid.java15
-rw-r--r--server/src/com/vaadin/ui/JavaScriptFunction.java7
-rw-r--r--server/src/com/vaadin/ui/PushConfiguration.java47
-rw-r--r--server/src/com/vaadin/ui/Slider.java18
-rw-r--r--server/src/com/vaadin/ui/UI.java7
-rw-r--r--server/src/com/vaadin/ui/declarative/Design.java113
-rw-r--r--server/src/com/vaadin/ui/declarative/DesignContext.java51
8 files changed, 214 insertions, 54 deletions
diff --git a/server/src/com/vaadin/ui/Flash.java b/server/src/com/vaadin/ui/Flash.java
index cd7c00087e..2d0f188b84 100644
--- a/server/src/com/vaadin/ui/Flash.java
+++ b/server/src/com/vaadin/ui/Flash.java
@@ -97,7 +97,7 @@ public class Flash extends AbstractEmbedded {
* Returns the codebase.
*
* @see #setCodebase(String)
- * @since 7.4
+ * @since 7.4.1
* @return Current codebase.
*/
public String getCodebase() {
@@ -126,7 +126,7 @@ public class Flash extends AbstractEmbedded {
* Returns the current codetype.
*
* @see #setCodetype(String)
- * @since 7.4
+ * @since 7.4.1
* @return Current codetype.
*/
public String getCodetype() {
@@ -157,7 +157,7 @@ public class Flash extends AbstractEmbedded {
* Returns current archive.
*
* @see #setArchive(String)
- * @since 7.4
+ * @since 7.4.1
* @return Current archive.
*/
public String getArchive() {
@@ -181,7 +181,7 @@ public class Flash extends AbstractEmbedded {
/**
* Returns standby.
*
- * @since
+ * @since 7.4.1
* @return Standby string.
*/
public String getStandby() {
@@ -247,7 +247,7 @@ public class Flash extends AbstractEmbedded {
*
* @see #setParameter(String, String)
* @see #getParameter(String)
- * @since 7.4
+ * @since 7.4.1
* @return An iterable with declared parameter names.
*/
public Iterable<String> getParameterNames() {
diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java
index df64ee85ed..77b57bceda 100644
--- a/server/src/com/vaadin/ui/Grid.java
+++ b/server/src/com/vaadin/ui/Grid.java
@@ -2251,7 +2251,7 @@ public class Grid extends AbstractComponent implements SelectionNotifier,
public Column setLastFrozenColumn() {
checkColumnIsAttached();
grid.setFrozenColumnCount(grid.getState(false).columnOrder
- .indexOf(this) + 1);
+ .indexOf(getState().id) + 1);
return this;
}
@@ -5229,4 +5229,17 @@ public class Grid extends AbstractComponent implements SelectionNotifier,
public void removeListener(ItemClickListener listener) {
removeItemClickListener(listener);
}
+
+ /**
+ * Requests that the column widths should be recalculated.
+ * <p>
+ * In most cases Grid will know when column widths need to be recalculated
+ * but this method can be used to force recalculation in situations when
+ * grid does not recalculate automatically.
+ *
+ * @since 7.4.1
+ */
+ public void recalculateColumnWidths() {
+ getRpcProxy(GridClientRpc.class).recalculateColumnWidths();
+ }
}
diff --git a/server/src/com/vaadin/ui/JavaScriptFunction.java b/server/src/com/vaadin/ui/JavaScriptFunction.java
index c006a36d58..071c88350b 100644
--- a/server/src/com/vaadin/ui/JavaScriptFunction.java
+++ b/server/src/com/vaadin/ui/JavaScriptFunction.java
@@ -19,6 +19,7 @@ package com.vaadin.ui;
import java.io.Serializable;
import com.vaadin.server.AbstractJavaScriptExtension;
+
import elemental.json.JsonArray;
/**
@@ -26,9 +27,9 @@ import elemental.json.JsonArray;
* the corresponding JavaScript function is called, the {@link #call(JsonArray)}
* method is invoked.
*
- * @see JavaScript#addFunction(String, JavaScriptCallback)
- * @see AbstractJavaScriptComponent#addFunction(String, JavaScriptCallback)
- * @see AbstractJavaScriptExtension#addFunction(String, JavaScriptCallback)
+ * @see JavaScript#addFunction(String, JavaScriptFunction)
+ * @see AbstractJavaScriptComponent#addFunction(String, JavaScriptFunction)
+ * @see AbstractJavaScriptExtension#addFunction(String, JavaScriptFunction)
*
* @author Vaadin Ltd
* @since 7.0.0
diff --git a/server/src/com/vaadin/ui/PushConfiguration.java b/server/src/com/vaadin/ui/PushConfiguration.java
index 90ad28542c..d5e89b4b14 100644
--- a/server/src/com/vaadin/ui/PushConfiguration.java
+++ b/server/src/com/vaadin/ui/PushConfiguration.java
@@ -105,6 +105,26 @@ public interface PushConfiguration extends Serializable {
public void setFallbackTransport(Transport fallbackTransport);
/**
+ * Sets the path that is used with push.
+ *
+ * @since 7.4.1
+ * @param pushPath
+ * The path to be used with push
+ *
+ * @throws IllegalArgumentException
+ * if the argument is null or empty.
+ */
+ public void setPushPath(String pushPath);
+
+ /**
+ * Returns the path used with push.
+ *
+ * @since 7.4.1
+ * @return The path that is used with push
+ */
+ public String getPushPath();
+
+ /**
* Returns the given parameter, if set.
* <p>
* This method provides low level access to push parameters and is typically
@@ -258,6 +278,32 @@ class PushConfigurationImpl implements PushConfiguration {
/*
* (non-Javadoc)
*
+ * @see com.vaadin.ui.PushConfiguration#setPushPath(java.lang.String)
+ */
+ @Override
+ public void setPushPath(String pushPath) {
+ if (pushPath != null && !pushPath.isEmpty()) {
+ getState().pushPath = pushPath;
+ } else {
+ throw new IllegalArgumentException(
+ "Push path can't be empty or null");
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.ui.PushConfiguration#getPushPath()
+ */
+ @Override
+ public String getPushPath() {
+ return getState(false).pushPath;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
* @see com.vaadin.ui.PushConfiguration#getParameter(java.lang.String)
*/
@Override
@@ -290,5 +336,4 @@ class PushConfigurationImpl implements PushConfiguration {
return Collections.unmodifiableCollection(getState(false).parameters
.keySet());
}
-
}
diff --git a/server/src/com/vaadin/ui/Slider.java b/server/src/com/vaadin/ui/Slider.java
index 66ed1a48f4..dad4d295bf 100644
--- a/server/src/com/vaadin/ui/Slider.java
+++ b/server/src/com/vaadin/ui/Slider.java
@@ -161,6 +161,11 @@ public class Slider extends AbstractField<Double> {
*/
public void setMax(double max) {
getState().maxValue = max;
+
+ if (getMin() > max) {
+ getState().minValue = max;
+ }
+
if (getValue() > max) {
setValue(max);
}
@@ -179,11 +184,16 @@ public class Slider extends AbstractField<Double> {
* Set the minimum slider value. If the current value of the slider is
* smaller than this, the value is set to the new minimum.
*
- * @param max
+ * @param min
* The new minimum slider value
*/
public void setMin(double min) {
getState().minValue = min;
+
+ if (getMax() < min) {
+ getState().maxValue = min;
+ }
+
if (getValue() < min) {
setValue(min);
}
@@ -260,12 +270,12 @@ public class Slider extends AbstractField<Double> {
newValue = (int) (v * Math.pow(10, resolution));
newValue = newValue / Math.pow(10, resolution);
if (getMin() > newValue || getMax() < newValue) {
- throw new ValueOutOfBoundsException(value);
+ throw new ValueOutOfBoundsException(newValue);
}
} else {
newValue = (int) v;
if (getMin() > newValue || getMax() < newValue) {
- throw new ValueOutOfBoundsException(value);
+ throw new ValueOutOfBoundsException(newValue);
}
}
@@ -313,6 +323,8 @@ public class Slider extends AbstractField<Double> {
* @param valueOutOfBounds
*/
public ValueOutOfBoundsException(Double valueOutOfBounds) {
+ super(String.format("Value %s is out of bounds: [%s, %s]",
+ valueOutOfBounds, getMin(), getMax()));
value = valueOutOfBounds;
}
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 66f893e04a..8dd600ddd0 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -425,7 +425,12 @@ public abstract class UI extends AbstractSingleComponentContainer implements
+ ".");
} else {
if (session == null) {
- detach();
+ try {
+ detach();
+ } catch (Exception e) {
+ getLogger().log(Level.WARNING,
+ "Error while detaching UI from session", e);
+ }
// Disable push when the UI is detached. Otherwise the
// push connection and possibly VaadinSession will live on.
getPushConfiguration().setPushMode(PushMode.DISABLED);
diff --git a/server/src/com/vaadin/ui/declarative/Design.java b/server/src/com/vaadin/ui/declarative/Design.java
index dc96e789bf..1b8585e6f6 100644
--- a/server/src/com/vaadin/ui/declarative/Design.java
+++ b/server/src/com/vaadin/ui/declarative/Design.java
@@ -57,6 +57,119 @@ import com.vaadin.ui.declarative.DesignContext.ComponentCreationListener;
* @author Vaadin Ltd
*/
public class Design implements Serializable {
+
+ /**
+ * Callback for creating instances of a given component class when reading
+ * designs. The default implementation, {@link DefaultComponentFactory} will
+ * use <code>Class.forName(className).newInstance()</code>, which might not
+ * be suitable e.g. in an OSGi environment or if the Component instances
+ * should be created as managed CDI beans.
+ * <p>
+ * Use {@link Design#setComponentFactory(ComponentFactory)} to configure
+ * Vaadin to use a custom component factory.
+ *
+ *
+ * @since 7.4.1
+ */
+ public interface ComponentFactory extends Serializable {
+ /**
+ * Creates a component based on the fully qualified name derived from
+ * the tag name in the design.
+ *
+ * @param fullyQualifiedClassName
+ * the fully qualified name of the component to create
+ * @param context
+ * the design context for which the component is created
+ *
+ * @return a newly created component
+ */
+ public Component createComponent(String fullyQualifiedClassName,
+ DesignContext context);
+ }
+
+ /**
+ * Default implementation of {@link ComponentFactory}, using
+ * <code>Class.forName(className).newInstance()</code> for finding the
+ * component class and creating a component instance.
+ *
+ * @since 7.4.1
+ */
+ public static class DefaultComponentFactory implements ComponentFactory {
+ @Override
+ public Component createComponent(String fullyQualifiedClassName,
+ DesignContext context) {
+ Class<? extends Component> componentClass = resolveComponentClass(
+ fullyQualifiedClassName, context);
+
+ assert Component.class.isAssignableFrom(componentClass) : "resolveComponentClass returned "
+ + componentClass + " which is not a Vaadin Component class";
+
+ try {
+ return componentClass.newInstance();
+ } catch (Exception e) {
+ throw new DesignException("Could not create component "
+ + fullyQualifiedClassName, e);
+ }
+ }
+
+ /**
+ * Resolves a component class based on the fully qualified name of the
+ * class.
+ *
+ * @param qualifiedClassName
+ * the fully qualified name of the resolved class
+ * @param context
+ * the design context for which the class is resolved
+ * @return a component class object representing the provided class name
+ */
+ protected Class<? extends Component> resolveComponentClass(
+ String qualifiedClassName, DesignContext context) {
+ try {
+ Class<?> componentClass = Class.forName(qualifiedClassName);
+ return componentClass.asSubclass(Component.class);
+ } catch (ClassNotFoundException e) {
+ throw new DesignException(
+ "Unable to load component for design", e);
+ }
+ }
+
+ }
+
+ private static volatile ComponentFactory componentFactory = new DefaultComponentFactory();
+
+ /**
+ * Sets the component factory that is used for creating component instances
+ * based on fully qualified class names derived from a design file.
+ * <p>
+ * Please note that this setting is global, so care should be taken to avoid
+ * conflicting changes.
+ *
+ * @param componentFactory
+ * the component factory to set; not <code>null</code>
+ *
+ * @since 7.4.1
+ */
+ public static void setComponentFactory(ComponentFactory componentFactory) {
+ if (componentFactory == null) {
+ throw new IllegalArgumentException(
+ "Cannot set null component factory");
+ }
+ Design.componentFactory = componentFactory;
+ }
+
+ /**
+ * Gets the currently used component factory.
+ *
+ * @see #setComponentFactory(ComponentFactory)
+ *
+ * @return the component factory
+ *
+ * @since 7.4.1
+ */
+ public static ComponentFactory getComponentFactory() {
+ return componentFactory;
+ }
+
/**
* Parses the given input stream into a jsoup document
*
diff --git a/server/src/com/vaadin/ui/declarative/DesignContext.java b/server/src/com/vaadin/ui/declarative/DesignContext.java
index 5f160d6f26..09fefd0a6b 100644
--- a/server/src/com/vaadin/ui/declarative/DesignContext.java
+++ b/server/src/com/vaadin/ui/declarative/DesignContext.java
@@ -31,6 +31,7 @@ import com.vaadin.annotations.DesignRoot;
import com.vaadin.shared.util.SharedUtil;
import com.vaadin.ui.Component;
import com.vaadin.ui.HasComponents;
+import com.vaadin.ui.declarative.Design.ComponentFactory;
/**
* This class contains contextual information that is collected when a component
@@ -482,14 +483,17 @@ public class DesignContext implements Serializable {
private Component instantiateComponent(Node node) {
// Extract the package and class names.
String qualifiedClassName = tagNameToClassName(node);
- try {
- Class<? extends Component> componentClass = resolveComponentClass(qualifiedClassName);
- Component newComponent = componentClass.newInstance();
- return newComponent;
- } catch (Exception e) {
- throw new DesignException("No component class could be found for "
- + node.nodeName() + ".", e);
+
+ ComponentFactory factory = Design.getComponentFactory();
+ Component component = factory.createComponent(qualifiedClassName, this);
+
+ if (component == null) {
+ throw new DesignException("Got unexpected null component from "
+ + factory.getClass().getName() + " for class "
+ + qualifiedClassName);
}
+
+ return component;
}
/**
@@ -530,39 +534,6 @@ public class DesignContext implements Serializable {
return packageName + "." + className;
}
- @SuppressWarnings("unchecked")
- private Class<? extends Component> resolveComponentClass(
- String qualifiedClassName) throws ClassNotFoundException {
- Class<?> componentClass = null;
- componentClass = Class.forName(qualifiedClassName);
-
- // Check that we're dealing with a Component.
- if (isComponent(componentClass)) {
- return (Class<? extends Component>) componentClass;
- } else {
- throw new IllegalArgumentException(String.format(
- "Resolved class %s is not a %s.", componentClass.getName(),
- Component.class.getName()));
- }
- }
-
- /**
- * Returns {@code true} if the given {@link Class} implements the
- * {@link Component} interface of Vaadin Framework otherwise {@code false}.
- *
- * @param componentClass
- * {@link Class} to check against {@link Component} interface.
- * @return {@code true} if the given {@link Class} is a {@link Component},
- * {@code false} otherwise.
- */
- private static boolean isComponent(Class<?> componentClass) {
- if (componentClass != null) {
- return Component.class.isAssignableFrom(componentClass);
- } else {
- return false;
- }
- }
-
/**
* Returns the root component of a created component hierarchy.
*