diff options
author | elmot <elmot@vaadin.com> | 2016-04-13 15:01:50 +0300 |
---|---|---|
committer | elmot <elmot@vaadin.com> | 2016-04-13 15:32:47 +0300 |
commit | 980f879176696906c25e985e4f7c8e3bdc04258d (patch) | |
tree | d781a70e24eef0994ba5d371280e1cf837f94825 /server/src/main/java/com/vaadin | |
parent | f7f5ba596dbba0c2374a6d8ac10e89362cbbaeb5 (diff) | |
parent | 9b46608f6c645c4289b854e2949bae3b1a2f5147 (diff) | |
download | vaadin-framework-980f879176696906c25e985e4f7c8e3bdc04258d.tar.gz vaadin-framework-980f879176696906c25e985e4f7c8e3bdc04258d.zip |
Merge branch 'master' into feature/mavenize
Change-Id: Id7db526d07a14ac259cbb50415bbafd2a7c2ab94
Diffstat (limited to 'server/src/main/java/com/vaadin')
21 files changed, 273 insertions, 101 deletions
diff --git a/server/src/main/java/com/vaadin/annotations/PreserveOnRefresh.java b/server/src/main/java/com/vaadin/annotations/PreserveOnRefresh.java index 7f4ef3ffe5..86723b97fc 100644 --- a/server/src/main/java/com/vaadin/annotations/PreserveOnRefresh.java +++ b/server/src/main/java/com/vaadin/annotations/PreserveOnRefresh.java @@ -17,6 +17,7 @@ package com.vaadin.annotations; import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -45,6 +46,7 @@ import com.vaadin.ui.UI; */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) +@Inherited public @interface PreserveOnRefresh { // Empty marker annotation } diff --git a/server/src/main/java/com/vaadin/annotations/Push.java b/server/src/main/java/com/vaadin/annotations/Push.java index b6a28c1560..736bc4488b 100644 --- a/server/src/main/java/com/vaadin/annotations/Push.java +++ b/server/src/main/java/com/vaadin/annotations/Push.java @@ -17,6 +17,7 @@ package com.vaadin.annotations; import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -38,6 +39,7 @@ import com.vaadin.ui.UI; */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Inherited public @interface Push { /** * Returns the {@link PushMode} to use for the annotated UI. The default diff --git a/server/src/main/java/com/vaadin/annotations/Theme.java b/server/src/main/java/com/vaadin/annotations/Theme.java index 61c47389ad..03fa1179bc 100644 --- a/server/src/main/java/com/vaadin/annotations/Theme.java +++ b/server/src/main/java/com/vaadin/annotations/Theme.java @@ -17,6 +17,7 @@ package com.vaadin.annotations; import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -28,6 +29,7 @@ import com.vaadin.ui.UI; */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Inherited public @interface Theme { /** * @return simple name of the theme diff --git a/server/src/main/java/com/vaadin/annotations/Title.java b/server/src/main/java/com/vaadin/annotations/Title.java index 38a3d75f17..07eaf17e33 100644 --- a/server/src/main/java/com/vaadin/annotations/Title.java +++ b/server/src/main/java/com/vaadin/annotations/Title.java @@ -17,6 +17,7 @@ package com.vaadin.annotations; import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -28,6 +29,7 @@ import com.vaadin.ui.UI; */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Inherited public @interface Title { /** * Gets the HTML title that should be used if the UI is used on it's own. diff --git a/server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java b/server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java index 00af38ecc1..907f2c3a0c 100644 --- a/server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java +++ b/server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java @@ -18,6 +18,7 @@ package com.vaadin.annotations; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -44,6 +45,7 @@ import com.vaadin.ui.UI; */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Inherited public @interface VaadinServletConfiguration { /** * Defines the init parameter name for methods in diff --git a/server/src/main/java/com/vaadin/annotations/Widgetset.java b/server/src/main/java/com/vaadin/annotations/Widgetset.java index c6ef6a7194..2dcf93af13 100644 --- a/server/src/main/java/com/vaadin/annotations/Widgetset.java +++ b/server/src/main/java/com/vaadin/annotations/Widgetset.java @@ -17,6 +17,7 @@ package com.vaadin.annotations; import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -28,6 +29,7 @@ import com.vaadin.ui.UI; */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Inherited public @interface Widgetset { /** * @return name of the widgetset diff --git a/server/src/main/java/com/vaadin/server/UIProvider.java b/server/src/main/java/com/vaadin/server/UIProvider.java index d3d834cad7..4ed86b9c31 100644 --- a/server/src/main/java/com/vaadin/server/UIProvider.java +++ b/server/src/main/java/com/vaadin/server/UIProvider.java @@ -18,6 +18,7 @@ package com.vaadin.server; import java.io.Serializable; import java.lang.annotation.Annotation; +import java.lang.annotation.Inherited; import com.vaadin.annotations.PreserveOnRefresh; import com.vaadin.annotations.Push; @@ -43,8 +44,15 @@ public abstract class UIProvider implements Serializable { /** * Helper to get an annotation for a class. If the annotation is not present - * on the target class, its super classes and implemented interfaces are - * also searched for the annotation. + * on the target class, its super classes and directly implemented + * interfaces are also searched for the annotation. Interfaces implemented + * by superclasses are not taken into account. + * <p> + * Note that searching implemented interfaces for {@code @Inherited} + * annotations and searching for superclasses for non-inherited annotations + * do not follow the standard semantics and are supported for backwards + * compatibility. Future versions of the framework might only support the + * standard semantics of {@code @Inherited}. * * @param clazz * the class from which the annotation should be found @@ -55,18 +63,26 @@ public abstract class UIProvider implements Serializable { */ protected static <T extends Annotation> T getAnnotationFor(Class<?> clazz, Class<T> annotationType) { - // Find from the class hierarchy - Class<?> currentType = clazz; - while (currentType != Object.class) { - T annotation = currentType.getAnnotation(annotationType); + // Don't discover hierarchy if annotation is inherited + if (annotationType.getAnnotation(Inherited.class) != null) { + T annotation = clazz.getAnnotation(annotationType); if (annotation != null) { return annotation; - } else { - currentType = currentType.getSuperclass(); + } + } else { + // Find from the class hierarchy + Class<?> currentType = clazz; + while (currentType != Object.class) { + T annotation = currentType.getAnnotation(annotationType); + if (annotation != null) { + return annotation; + } else { + currentType = currentType.getSuperclass(); + } } } - // Find from an implemented interface + // Find from a directly implemented interface for (Class<?> iface : clazz.getInterfaces()) { T annotation = iface.getAnnotation(annotationType); if (annotation != null) { diff --git a/server/src/main/java/com/vaadin/server/VaadinPortlet.java b/server/src/main/java/com/vaadin/server/VaadinPortlet.java index 043f95fd7b..5c91b6669c 100644 --- a/server/src/main/java/com/vaadin/server/VaadinPortlet.java +++ b/server/src/main/java/com/vaadin/server/VaadinPortlet.java @@ -180,6 +180,14 @@ public class VaadinPortlet extends GenericPortlet implements Constants, */ public static class VaadinLiferayRequest extends VaadinHttpAndPortletRequest { + /** + * The PortalUtil class to use. Set to either + * {@link #LIFERAY_6_PORTAL_UTIL} or {@link #LIFERAY_7_PORTAL_UTIL} the + * first time it is needed. + */ + private static String portalUtilClass = null; + private static final String LIFERAY_6_PORTAL_UTIL = "com.liferay.portal.util.PortalUtil"; + private static final String LIFERAY_7_PORTAL_UTIL = "com.liferay.portal.kernel.util.PortalUtil"; public VaadinLiferayRequest(PortletRequest request, VaadinPortletService vaadinService) { @@ -247,19 +255,28 @@ public class VaadinPortlet extends GenericPortlet implements Constants, @Override protected HttpServletRequest getServletRequest(PortletRequest request) { + if (portalUtilClass == null) { + try { + invokeStaticLiferayMethod(LIFERAY_7_PORTAL_UTIL, + "getHttpServletRequest", request, + "javax.portlet.PortletRequest"); + portalUtilClass = LIFERAY_7_PORTAL_UTIL; + } catch (Exception e) { + // Liferay 6 or older + portalUtilClass = LIFERAY_6_PORTAL_UTIL; + } + } try { // httpRequest = PortalUtil.getHttpServletRequest(request); HttpServletRequest httpRequest = (HttpServletRequest) invokeStaticLiferayMethod( - "com.liferay.portal.util.PortalUtil", - "getHttpServletRequest", request, + portalUtilClass, "getHttpServletRequest", request, "javax.portlet.PortletRequest"); // httpRequest = // PortalUtil.getOriginalServletRequest(httpRequest); httpRequest = (HttpServletRequest) invokeStaticLiferayMethod( - "com.liferay.portal.util.PortalUtil", - "getOriginalServletRequest", httpRequest, - "javax.servlet.http.HttpServletRequest"); + portalUtilClass, "getOriginalServletRequest", + httpRequest, "javax.servlet.http.HttpServletRequest"); return httpRequest; } catch (Exception e) { throw new IllegalStateException("Liferay request not detected", diff --git a/server/src/main/java/com/vaadin/server/communication/ServerRpcHandler.java b/server/src/main/java/com/vaadin/server/communication/ServerRpcHandler.java index 593b1f544f..3503a2d8b1 100644 --- a/server/src/main/java/com/vaadin/server/communication/ServerRpcHandler.java +++ b/server/src/main/java/com/vaadin/server/communication/ServerRpcHandler.java @@ -316,7 +316,7 @@ public class ServerRpcHandler implements Serializable { * 6 semantics for components and add-ons that do not use Vaadin 7 RPC * directly. * - * @param uI + * @param ui * the UI receiving the invocations data * @param lastSyncIdSeenByClient * the most recent sync id the client has seen at the time the @@ -324,20 +324,21 @@ public class ServerRpcHandler implements Serializable { * @param invocationsData * JSON containing all information needed to execute all * requested RPC calls. + * @since */ - private void handleInvocations(UI uI, int lastSyncIdSeenByClient, + protected void handleInvocations(UI ui, int lastSyncIdSeenByClient, JsonArray invocationsData) { // TODO PUSH Refactor so that this is not needed - LegacyCommunicationManager manager = uI.getSession() + LegacyCommunicationManager manager = ui.getSession() .getCommunicationManager(); try { - ConnectorTracker connectorTracker = uI.getConnectorTracker(); + ConnectorTracker connectorTracker = ui.getConnectorTracker(); Set<Connector> enabledConnectors = new HashSet<Connector>(); List<MethodInvocation> invocations = parseInvocations( - uI.getConnectorTracker(), invocationsData, + ui.getConnectorTracker(), invocationsData, lastSyncIdSeenByClient); for (MethodInvocation invocation : invocations) { final ClientConnector connector = connectorTracker @@ -404,35 +405,11 @@ public class ServerRpcHandler implements Serializable { } if (invocation instanceof ServerRpcMethodInvocation) { - try { - ServerRpcManager.applyInvocation(connector, - (ServerRpcMethodInvocation) invocation); - } catch (RpcInvocationException e) { - manager.handleConnectorRelatedException(connector, e); - } + handleInvocation(ui, connector, + (ServerRpcMethodInvocation) invocation); } else { - - // All code below is for legacy variable changes LegacyChangeVariablesInvocation legacyInvocation = (LegacyChangeVariablesInvocation) invocation; - Map<String, Object> changes = legacyInvocation - .getVariableChanges(); - try { - if (connector instanceof VariableOwner) { - // The source parameter is never used anywhere - changeVariables(null, (VariableOwner) connector, - changes); - } else { - throw new IllegalStateException( - "Received legacy variable change for " - + connector.getClass().getName() - + " (" - + connector.getConnectorId() - + ") which is not a VariableOwner. The client-side connector sent these legacy varaibles: " - + changes.keySet()); - } - } catch (Exception e) { - manager.handleConnectorRelatedException(connector, e); - } + handleInvocation(ui, connector, legacyInvocation); } } } catch (JsonException e) { @@ -444,6 +421,63 @@ public class ServerRpcHandler implements Serializable { } /** + * Handles the given RPC method invocation for the given connector + * + * @since + * @param ui + * the UI containing the connector + * @param connector + * the connector the RPC is targeted to + * @param invocation + * information about the rpc to invoke + */ + protected void handleInvocation(UI ui, ClientConnector connector, + ServerRpcMethodInvocation invocation) { + try { + ServerRpcManager.applyInvocation(connector, invocation); + } catch (RpcInvocationException e) { + ui.getSession().getCommunicationManager() + .handleConnectorRelatedException(connector, e); + } + + } + + /** + * Handles the given Legacy variable change RPC method invocation for the + * given connector + * + * @since + * @param ui + * the UI containing the connector + * @param connector + * the connector the RPC is targeted to + * @param invocation + * information about the rpc to invoke + */ + protected void handleInvocation(UI ui, ClientConnector connector, + LegacyChangeVariablesInvocation legacyInvocation) { + Map<String, Object> changes = legacyInvocation.getVariableChanges(); + try { + if (connector instanceof VariableOwner) { + // The source parameter is never used anywhere + changeVariables(null, (VariableOwner) connector, changes); + } else { + throw new IllegalStateException( + "Received legacy variable change for " + + connector.getClass().getName() + + " (" + + connector.getConnectorId() + + ") which is not a VariableOwner. The client-side connector sent these legacy varaibles: " + + changes.keySet()); + } + } catch (Exception e) { + ui.getSession().getCommunicationManager() + .handleConnectorRelatedException(connector, e); + } + + } + + /** * Parse JSON from the client into a list of MethodInvocation instances. * * @param connectorTracker diff --git a/server/src/main/java/com/vaadin/server/communication/UidlRequestHandler.java b/server/src/main/java/com/vaadin/server/communication/UidlRequestHandler.java index dda3d81453..db18bb9e1e 100644 --- a/server/src/main/java/com/vaadin/server/communication/UidlRequestHandler.java +++ b/server/src/main/java/com/vaadin/server/communication/UidlRequestHandler.java @@ -51,9 +51,20 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements public static final String UIDL_PATH = "UIDL/"; - private ServerRpcHandler rpcHandler = new ServerRpcHandler(); + private ServerRpcHandler rpcHandler; public UidlRequestHandler() { + rpcHandler = createRpcHandler(); + } + + /** + * Creates the ServerRpcHandler to use + * + * @since + * @return the ServerRpcHandler to use + */ + protected ServerRpcHandler createRpcHandler() { + return new ServerRpcHandler(); } @Override diff --git a/server/src/main/java/com/vaadin/server/communication/UidlWriter.java b/server/src/main/java/com/vaadin/server/communication/UidlWriter.java index b117cb4b4d..8a4e62fb24 100644 --- a/server/src/main/java/com/vaadin/server/communication/UidlWriter.java +++ b/server/src/main/java/com/vaadin/server/communication/UidlWriter.java @@ -352,9 +352,12 @@ public class UidlWriter implements Serializable { * @throws IOException */ private void writePerformanceData(UI ui, Writer writer) throws IOException { - writer.write(String.format(", \"timings\":[%d, %d]", ui.getSession() - .getCumulativeRequestDuration(), ui.getSession() - .getLastRequestDuration())); + if (!ui.getSession().getService().getDeploymentConfiguration() + .isProductionMode()) { + writer.write(String.format(", \"timings\":[%d, %d]", ui + .getSession().getCumulativeRequestDuration(), ui + .getSession().getLastRequestDuration())); + } } private static final Logger getLogger() { diff --git a/server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java b/server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java index 063f4f5346..255f34d936 100644 --- a/server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java +++ b/server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java @@ -495,7 +495,24 @@ public class ClassPathExplorer { * @return URL */ public static URL getDefaultSourceDirectory() { + return getWidgetsetSourceDirectory(null); + } + /** + * Find and return the source directory which contains the given widgetset + * file. + * + * If not applicable or widgetsetFileName is null, return the first + * directory (not a JAR file etc.) on the classpath. + * + * TODO this could be done better... + * + * @param widgetsetFileName + * relative path for the widgetset + * + * @return URL + */ + public static URL getWidgetsetSourceDirectory(String widgetsetFileName) { if (debug) { debug("classpathLocations values:"); ArrayList<String> locations = new ArrayList<String>( @@ -505,6 +522,7 @@ public class ClassPathExplorer { } } + URL firstDirectory = null; Iterator<String> it = rawClasspathEntries.iterator(); while (it.hasNext()) { String entry = it.next(); @@ -513,13 +531,18 @@ public class ClassPathExplorer { if (directory.exists() && !directory.isHidden() && directory.isDirectory()) { try { - return new URL("file://" + directory.getCanonicalPath()); - } catch (MalformedURLException e) { - // ignore: continue to the next classpath entry - if (debug) { - e.printStackTrace(); + URL directoryUrl = directory.toURI().toURL(); + + // Store the first directory encountered. + if (firstDirectory == null) { + firstDirectory = directoryUrl; } - } catch (IOException e) { + + if (widgetsetFileName == null + || new File(directory, widgetsetFileName).exists()) { + return directoryUrl; + } + } catch (MalformedURLException e) { // ignore: continue to the next classpath entry if (debug) { e.printStackTrace(); @@ -527,7 +550,8 @@ public class ClassPathExplorer { } } } - return null; + + return firstDirectory; } /** diff --git a/server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java b/server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java index f810a63a38..b0d8cdd004 100644 --- a/server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java +++ b/server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java @@ -61,16 +61,17 @@ public class WidgetSetBuilder { Map<String, URL> availableWidgetSets = ClassPathExplorer .getAvailableWidgetSets(); + String widgetsetFileName = widgetset.replace(".", "/") + ".gwt.xml"; URL sourceUrl = availableWidgetSets.get(widgetset); if (sourceUrl == null) { // find first/default source directory - sourceUrl = ClassPathExplorer.getDefaultSourceDirectory(); + sourceUrl = ClassPathExplorer + .getWidgetsetSourceDirectory(widgetsetFileName); } - String widgetsetfilename = sourceUrl.getFile() + "/" - + widgetset.replace(".", "/") + ".gwt.xml"; + String wsFullPath = sourceUrl.getFile() + "/" + widgetsetFileName; - File widgetsetFile = new File(widgetsetfilename); + File widgetsetFile = new File(wsFullPath); if (!widgetsetFile.exists()) { // create empty gwt module file File parent = widgetsetFile.getParentFile(); @@ -137,7 +138,7 @@ public class WidgetSetBuilder { changed = changed || !content.equals(originalContent); if (changed) { - commitChanges(widgetsetfilename, content); + commitChanges(wsFullPath, content); } } else { System.out diff --git a/server/src/main/java/com/vaadin/ui/AbstractOrderedLayout.java b/server/src/main/java/com/vaadin/ui/AbstractOrderedLayout.java index e0dbcb004b..f517ab0af5 100644 --- a/server/src/main/java/com/vaadin/ui/AbstractOrderedLayout.java +++ b/server/src/main/java/com/vaadin/ui/AbstractOrderedLayout.java @@ -31,7 +31,6 @@ import com.vaadin.server.Sizeable; import com.vaadin.shared.Connector; import com.vaadin.shared.EventId; import com.vaadin.shared.MouseEventDetails; -import com.vaadin.shared.ui.AlignmentInfo; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutServerRpc; import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState; @@ -486,22 +485,8 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements Component newChild = designContext.readDesign(childComponent); addComponent(newChild); // handle alignment - int bitMask = 0; - if (attr.hasKey(":middle")) { - bitMask += AlignmentInfo.Bits.ALIGNMENT_VERTICAL_CENTER; - } else if (attr.hasKey(":bottom")) { - bitMask += AlignmentInfo.Bits.ALIGNMENT_BOTTOM; - } else { - bitMask += AlignmentInfo.Bits.ALIGNMENT_TOP; - } - if (attr.hasKey(":center")) { - bitMask += AlignmentInfo.Bits.ALIGNMENT_HORIZONTAL_CENTER; - } else if (attr.hasKey(":right")) { - bitMask += AlignmentInfo.Bits.ALIGNMENT_RIGHT; - } else { - bitMask += AlignmentInfo.Bits.ALIGNMENT_LEFT; - } - setComponentAlignment(newChild, new Alignment(bitMask)); + setComponentAlignment(newChild, + DesignAttributeHandler.readAlignment(attr)); // handle expand ratio if (attr.hasKey(":expand")) { String value = attr.get(":expand"); diff --git a/server/src/main/java/com/vaadin/ui/AbstractSelect.java b/server/src/main/java/com/vaadin/ui/AbstractSelect.java index 9babf7e876..2714e0cbf5 100644 --- a/server/src/main/java/com/vaadin/ui/AbstractSelect.java +++ b/server/src/main/java/com/vaadin/ui/AbstractSelect.java @@ -532,13 +532,16 @@ public abstract class AbstractSelect extends AbstractField<Object> implements } else { final Object id = itemIdMapper .get(clientSideSelectedKeys[0]); - if (!isNullSelectionAllowed() && id == null) { - markAsDirty(); - } else if (id != null - && id.equals(getNullSelectionItemId())) { - setValue(null, true); + + if (id != null) { + if (isNullSelectionAllowed() + && id.equals(getNullSelectionItemId())) { + setValue(null, true); + } else { + setValue(id, true); + } } else { - setValue(id, true); + markAsDirty(); } } } diff --git a/server/src/main/java/com/vaadin/ui/DragAndDropWrapper.java b/server/src/main/java/com/vaadin/ui/DragAndDropWrapper.java index 90b3b56ef6..29179ddca7 100644 --- a/server/src/main/java/com/vaadin/ui/DragAndDropWrapper.java +++ b/server/src/main/java/com/vaadin/ui/DragAndDropWrapper.java @@ -40,6 +40,7 @@ import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.ui.dd.HorizontalDropLocation; import com.vaadin.shared.ui.dd.VerticalDropLocation; import com.vaadin.shared.ui.draganddropwrapper.DragAndDropWrapperConstants; +import com.vaadin.shared.ui.draganddropwrapper.DragAndDropWrapperServerRpc; import com.vaadin.ui.declarative.DesignContext; @SuppressWarnings("serial") @@ -111,6 +112,14 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, } + private final DragAndDropWrapperServerRpc rpc = new DragAndDropWrapperServerRpc() { + + @Override + public void poll() { + // #19616 RPC to poll the server for changes + } + }; + private Map<String, ProxyReceiver> receivers = new HashMap<String, ProxyReceiver>(); public class WrapperTargetDetails extends TargetDetailsImpl { @@ -197,6 +206,7 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, @Deprecated public DragAndDropWrapper() { super(); + registerRpc(rpc); } /** diff --git a/server/src/main/java/com/vaadin/ui/FormLayout.java b/server/src/main/java/com/vaadin/ui/FormLayout.java index f6f711d658..c817300e53 100644 --- a/server/src/main/java/com/vaadin/ui/FormLayout.java +++ b/server/src/main/java/com/vaadin/ui/FormLayout.java @@ -36,7 +36,7 @@ public class FormLayout extends AbstractOrderedLayout { public FormLayout() { super(); setSpacing(true); - setMargin(new MarginInfo(true, false, true, false)); + setMargin(new MarginInfo(true, false)); setWidth(100, UNITS_PERCENTAGE); } diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java index 4074672675..036fe8b756 100644 --- a/server/src/main/java/com/vaadin/ui/Grid.java +++ b/server/src/main/java/com/vaadin/ui/Grid.java @@ -4855,8 +4855,13 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, } /** - * Sets the grid data source. - * + * Sets the grid data source.<p> + * + * <strong>Note</strong> Grid columns are based on properties and try to detect a correct converter for + * the data type. The columns are not reinitialized automatically if the container is changed, and if the same + * properties are present after container change, the columns are reused. + * Properties with same names, but different data types will lead to unpredictable behaviour. + * * @param container * The container data source. Cannot be null. * @throws IllegalArgumentException diff --git a/server/src/main/java/com/vaadin/ui/GridLayout.java b/server/src/main/java/com/vaadin/ui/GridLayout.java index 8517962e91..148fd85fff 100644 --- a/server/src/main/java/com/vaadin/ui/GridLayout.java +++ b/server/src/main/java/com/vaadin/ui/GridLayout.java @@ -1330,7 +1330,7 @@ public class GridLayout extends AbstractLayout implements } } setRows(Math.max(rows.size(), 1)); - + Map<Component, Alignment> alignments = new HashMap<Component, Alignment>(); List<Integer> columnExpandRatios = new ArrayList<Integer>(); for (int row = 0; row < rowElements.size(); ++row) { Element rowElement = rowElements.get(row); @@ -1357,7 +1357,10 @@ public class GridLayout extends AbstractLayout implements Component child = null; if (col.children().size() > 0) { - child = designContext.readDesign(col.child(0)); + Element childElement = col.child(0); + child = designContext.readDesign(childElement); + alignments.put(child, DesignAttributeHandler + .readAlignment(childElement.attributes())); // TODO: Currently ignoring any extra children. // Needs Error handling? } // Else: Empty placeholder. No child component. @@ -1441,6 +1444,7 @@ public class GridLayout extends AbstractLayout implements // Add component with area addComponent(child, j, i, j + colspan, i + rowspan); + setComponentAlignment(child, alignments.get(child)); } } // Set cursor position explicitly @@ -1511,16 +1515,8 @@ public class GridLayout extends AbstractLayout implements ChildComponentData coords = childData.get(child); Alignment alignment = getComponentAlignment(child); - if (alignment.isMiddle()) { - childElement.attr(":middle", true); - } else if (alignment.isBottom()) { - childElement.attr(":bottom", true); - } - if (alignment.isCenter()) { - childElement.attr(":center", true); - } else if (alignment.isRight()) { - childElement.attr(":right", true); - } + DesignAttributeHandler.writeAlignment(childElement, + alignment); col.appendChild(childElement); if (coords.row1 != coords.row2) { diff --git a/server/src/main/java/com/vaadin/ui/Window.java b/server/src/main/java/com/vaadin/ui/Window.java index b5cd384f53..70399ae566 100644 --- a/server/src/main/java/com/vaadin/ui/Window.java +++ b/server/src/main/java/com/vaadin/ui/Window.java @@ -1051,7 +1051,9 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, @Override public void handleAction(Object sender, Object target) { - window.close(); + if (window.isClosable()) { + window.close(); + } } public boolean equals(int keyCode, int... modifiers) { diff --git a/server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java b/server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java index cee2ebe381..bbfd90b2cc 100644 --- a/server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java +++ b/server/src/main/java/com/vaadin/ui/declarative/DesignAttributeHandler.java @@ -37,7 +37,9 @@ import org.jsoup.nodes.Element; import org.jsoup.nodes.Node; import com.vaadin.data.util.converter.Converter; +import com.vaadin.shared.ui.AlignmentInfo; import com.vaadin.shared.util.SharedUtil; +import com.vaadin.ui.Alignment; /** * Default attribute handler implementation used when parsing designs to @@ -452,4 +454,55 @@ public class DesignAttributeHandler implements Serializable { return (methods != null && methods.length > 1) ? methods[1] : null; } } + + /** + * Read the alignment from the given child component attributes. + * + * @since 7.6.4 + * @param attr + * the child component attributes + * @return the component alignment + */ + public static Alignment readAlignment(Attributes attr) { + int bitMask = 0; + if (attr.hasKey(":middle")) { + bitMask += AlignmentInfo.Bits.ALIGNMENT_VERTICAL_CENTER; + } else if (attr.hasKey(":bottom")) { + bitMask += AlignmentInfo.Bits.ALIGNMENT_BOTTOM; + } else { + bitMask += AlignmentInfo.Bits.ALIGNMENT_TOP; + } + if (attr.hasKey(":center")) { + bitMask += AlignmentInfo.Bits.ALIGNMENT_HORIZONTAL_CENTER; + } else if (attr.hasKey(":right")) { + bitMask += AlignmentInfo.Bits.ALIGNMENT_RIGHT; + } else { + bitMask += AlignmentInfo.Bits.ALIGNMENT_LEFT; + } + + return new Alignment(bitMask); + } + + /** + * Writes the alignment to the given child element attributes. + * + * @since 7.6.4 + * @param childElement + * the child element + * @param alignment + * the component alignment + */ + public static void writeAlignment(Element childElement, Alignment alignment) { + if (alignment.isMiddle()) { + childElement.attr(":middle", true); + } else if (alignment.isBottom()) { + childElement.attr(":bottom", true); + } + if (alignment.isCenter()) { + childElement.attr(":center", true); + } else if (alignment.isRight()) { + childElement.attr(":right", true); + } + } + } |