]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add selective data write support to AbstractSelect (#17148)
authorLeif Åstrand <leif@vaadin.com>
Sun, 15 Mar 2015 12:32:38 +0000 (14:32 +0200)
committerVaadin Code Review <review@vaadin.com>
Tue, 7 Apr 2015 10:35:52 +0000 (10:35 +0000)
Change-Id: I06f82fe05f3b370af85538c0a85f2e60ee28d72d

server/src/com/vaadin/ui/AbstractSelect.java
server/src/com/vaadin/ui/declarative/DesignContext.java
server/src/com/vaadin/ui/declarative/ShouldWriteDataDelegate.java [new file with mode: 0644]
server/tests/src/com/vaadin/tests/design/DeclarativeTestBaseBase.java
server/tests/src/com/vaadin/tests/server/component/abstractselect/AbstractSelectDeclarativeTest.java

index 06790ca78d016763b66c9324270c7829866a2a2e..4c5e6b6ea35394d6eb43d96695ff0402ab52c0b4 100644 (file)
@@ -2222,4 +2222,30 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
             }
         }
     }
+
+    @Override
+    public void writeDesign(Element design, DesignContext designContext) {
+        // Write default attributes
+        super.writeDesign(design, designContext);
+
+        // Write options if warranted
+        if (designContext.shouldWriteData(this)) {
+            for (Object itemId : getItemIds()) {
+                Element optionElement = design.appendElement("option");
+
+                optionElement.html(getItemCaption(itemId));
+
+                Resource icon = getItemIcon(itemId);
+                if (icon != null) {
+                    DesignAttributeHandler.writeAttribute("icon",
+                            optionElement.attributes(), icon, null,
+                            Resource.class);
+                }
+
+                if (isSelected(itemId)) {
+                    optionElement.attr("selected", "");
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
index f991b3013ad44fcf8b4b8187d971f77c6fc029ec..54be5dcea3b600d6645b90dbb496bc50b569e282 100644 (file)
@@ -75,6 +75,8 @@ public class DesignContext implements Serializable {
     // component creation listeners
     private List<ComponentCreationListener> listeners = new ArrayList<ComponentCreationListener>();
 
+    private ShouldWriteDataDelegate shouldWriteDataDelegate = ShouldWriteDataDelegate.DEFAULT;
+
     public DesignContext(Document doc) {
         this.doc = doc;
         // Initialize the mapping between prefixes and package names.
@@ -661,4 +663,56 @@ public class DesignContext implements Serializable {
 
         return true;
     }
+
+    /**
+     * Determines whether the container data of a component should be written
+     * out by delegating to a {@link ShouldWriteDataDelegate}. The default
+     * delegate assumes that all component data is provided by a data source
+     * connected to a back end system and that the data should thus not be
+     * written.
+     * 
+     * @since
+     * @see #setShouldWriteDataDelegate(ShouldWriteDataDelegate)
+     * @param component
+     *            the component to check
+     * @return <code>true</code> if container data should be written out for the
+     *         provided component; otherwise <code>false</code>.
+     */
+    public boolean shouldWriteData(Component component) {
+        return getShouldWriteDataDelegate().shouldWriteData(component);
+    }
+
+    /**
+     * Sets the delegate that determines whether the container data of a
+     * component should be written out.
+     * 
+     * @since
+     * @see #shouldWriteChildren(Component, Component)
+     * @see #getShouldWriteDataDelegate()
+     * @param shouldWriteDataDelegate
+     *            the delegate to set, not <code>null</code>
+     * @throws IllegalArgumentException
+     *             if the provided delegate is <code>null</code>
+     */
+    public void setShouldWriteDataDelegate(
+            ShouldWriteDataDelegate shouldWriteDataDelegate) {
+        if (shouldWriteDataDelegate == null) {
+            throw new IllegalArgumentException("Delegate cannot be null");
+        }
+        this.shouldWriteDataDelegate = shouldWriteDataDelegate;
+    }
+
+    /**
+     * Gets the delegate that determines whether the container data of a
+     * component should be written out.
+     * 
+     * @since
+     * @see #setShouldWriteDataDelegate(ShouldWriteDataDelegate)
+     * @see #shouldWriteChildren(Component, Component)
+     * @return the shouldWriteDataDelegate the currently use delegate
+     */
+    public ShouldWriteDataDelegate getShouldWriteDataDelegate() {
+        return shouldWriteDataDelegate;
+    }
+
 }
diff --git a/server/src/com/vaadin/ui/declarative/ShouldWriteDataDelegate.java b/server/src/com/vaadin/ui/declarative/ShouldWriteDataDelegate.java
new file mode 100644 (file)
index 0000000..29a78e1
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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.declarative;
+
+import java.io.Serializable;
+
+import com.vaadin.ui.Component;
+
+/**
+ * Delegate used by {@link DesignContext} to determine whether container data
+ * should be written out for a component.
+ * 
+ * @see DesignContext#shouldWriteData(Component)
+ * 
+ * @since
+ * @author Vaadin Ltd
+ */
+public interface ShouldWriteDataDelegate extends Serializable {
+
+    /**
+     * The default delegate implementation that assumes that all component data
+     * is provided by a data source connected to a back end system and that the
+     * data should thus not be written.
+     */
+    public static final ShouldWriteDataDelegate DEFAULT = new ShouldWriteDataDelegate() {
+        @Override
+        public boolean shouldWriteData(Component component) {
+            return false;
+        }
+    };
+
+    /**
+     * Determines whether the container data of a component should be written
+     * out.
+     * 
+     * @param component
+     *            the component to check
+     * @return <code>true</code> if container data should be written out for the
+     *         provided component; otherwise <code>false</code>.
+     */
+    boolean shouldWriteData(Component component);
+}
index 8dc32e00d671139765f3c79e7ff893f12c55d298..b2da98bd30213457c9339e55b615b3ad21197217 100644 (file)
@@ -32,6 +32,8 @@ import org.junit.Assert;
 
 import com.vaadin.ui.Component;
 import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.ui.declarative.ShouldWriteDataDelegate;
 
 public abstract class DeclarativeTestBaseBase<T extends Component> {
     public interface EqualsAsserter<TT> {
@@ -47,10 +49,21 @@ public abstract class DeclarativeTestBaseBase<T extends Component> {
         }
     }
 
-    protected String write(T object) {
+    protected String write(T object, boolean writeData) {
         try {
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-            Design.write(object, outputStream);
+
+            DesignContext dc = new DesignContext();
+            if (writeData) {
+                dc.setShouldWriteDataDelegate(new ShouldWriteDataDelegate() {
+                    @Override
+                    public boolean shouldWriteData(Component component) {
+                        return true;
+                    }
+                });
+            }
+            dc.setRootComponent(object);
+            Design.write(dc, outputStream);
             return outputStream.toString("UTF-8");
         } catch (Exception e) {
             throw new RuntimeException(e);
@@ -121,7 +134,11 @@ public abstract class DeclarativeTestBaseBase<T extends Component> {
     }
 
     public void testWrite(String design, T expected) {
-        String written = write(expected);
+        testWrite(design, expected, false);
+    }
+
+    public void testWrite(String design, T expected, boolean writeData) {
+        String written = write(expected, writeData);
 
         Element producedElem = Jsoup.parse(written).body().child(0);
         Element comparableElem = Jsoup.parse(design).body().child(0);
index 61128a1803f1aafbeb2a9a4729d646a1a1ba93cf..b3867a7a3a53188e9c71c9fda049ac55f39e5309 100644 (file)
@@ -137,12 +137,18 @@ public class AbstractSelectDeclarativeTest extends
     }
 
     @Test
-    public void testWriteInlineData() {
+    public void testWriteInlineDataIgnored() {
         // No data is written by default
         testWrite(stripOptionTags(getDesignForInlineData()),
                 getExpectedComponentForInlineData());
     }
 
+    @Test
+    public void testWriteInlineData() {
+        testWrite(getDesignForInlineData(),
+                getExpectedComponentForInlineData(), true);
+    }
+
     private String getDesignForInlineData() {
         return "<v-list-select>\n"
                 + "        <option icon='http://some.url/icon.png'>Value 1</option>\n" //