summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenri Sara <hesara@vaadin.com>2015-09-30 11:29:45 +0300
committerHenri Sara <hesara@vaadin.com>2015-09-30 11:45:53 +0300
commit7804edf4a9228255cb7857dbd7c17d87ee976f67 (patch)
tree17f6770bfa8ce5d3d4c889724cbac41c74c336aa
parent5b4fd9305618581e62c9c8ca4f223a7f82b73600 (diff)
downloadvaadin-framework-7804edf4a9228255cb7857dbd7c17d87ee976f67.tar.gz
vaadin-framework-7804edf4a9228255cb7857dbd7c17d87ee976f67.zip
Support declarative prefix "vaadin-" (#18957)
This is a backport of 1011cff7e8139cd1b7138b2e538264c755c7482f with the old default ("v-"). Change-Id: Idafc3a071aeec6d4214e867cc5cd984ae535cb62
-rw-r--r--server/src/com/vaadin/server/Constants.java1
-rw-r--r--server/src/com/vaadin/ui/declarative/DesignContext.java81
-rw-r--r--server/tests/src/com/vaadin/tests/design/ParseNewPrefixTest.java46
-rw-r--r--server/tests/src/com/vaadin/tests/design/WriteNewDesignTest.java101
-rw-r--r--server/tests/src/com/vaadin/tests/design/all-components-new.html122
-rw-r--r--server/tests/src/com/vaadin/tests/design/testFile-new.html19
6 files changed, 359 insertions, 11 deletions
diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java
index 5a0d852299..379bfa4f2a 100644
--- a/server/src/com/vaadin/server/Constants.java
+++ b/server/src/com/vaadin/server/Constants.java
@@ -137,6 +137,7 @@ public interface Constants {
static final String SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING = "legacyPropertyToString";
static final String SERVLET_PARAMETER_SYNC_ID_CHECK = "syncIdCheck";
static final String SERVLET_PARAMETER_SENDURLSASPARAMETERS = "sendUrlsAsParameters";
+ static final String SERVLET_PARAMETER_LEGACY_DESIGN_PREFIX = "legacyDesignPrefix";
// Configurable parameter names
static final String PARAMETER_VAADIN_RESOURCES = "Resources";
diff --git a/server/src/com/vaadin/ui/declarative/DesignContext.java b/server/src/com/vaadin/ui/declarative/DesignContext.java
index 0d68c22ea0..d660011a58 100644
--- a/server/src/com/vaadin/ui/declarative/DesignContext.java
+++ b/server/src/com/vaadin/ui/declarative/DesignContext.java
@@ -30,6 +30,9 @@ import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import com.vaadin.annotations.DesignRoot;
+import com.vaadin.server.Constants;
+import com.vaadin.server.DeploymentConfiguration;
+import com.vaadin.server.VaadinService;
import com.vaadin.ui.Component;
import com.vaadin.ui.HasComponents;
import com.vaadin.ui.declarative.Design.ComponentFactory;
@@ -41,11 +44,22 @@ import com.vaadin.ui.declarative.Design.ComponentMapper;
* mappings from local ids, global ids and captions to components , as well as a
* mapping between prefixes and package names (such as "v" -> "com.vaadin.ui").
*
+ * Vaadin versions 7.5.7 and later support reading designs with either "v" or
+ * "vaadin" as the prefix, but only write "v" by default. Writing with the new
+ * prefix can be activated with value {@code false} for the property or context
+ * parameter {@link Constants#SERVLET_PARAMETER_LEGACY_DESIGN_PREFIX}. Vaadin
+ * 7.6 and later will use "vaadin" as the default prefix.
+ *
* @since 7.4
* @author Vaadin Ltd
*/
public class DesignContext implements Serializable {
+ private static final String LEGACY_PREFIX = "v";
+ private static final String VAADIN_PREFIX = "vaadin";
+
+ private static final String VAADIN_UI_PACKAGE = "com.vaadin.ui";
+
// cache for object instances
private static Map<Class<?>, Component> instanceCache = new ConcurrentHashMap<Class<?>, Component>();
@@ -67,23 +81,24 @@ public class DesignContext implements Serializable {
// namespace mappings
private Map<String, String> packageToPrefix = new HashMap<String, String>();
private Map<String, String> prefixToPackage = new HashMap<String, String>();
- // prefix names for which no package-mapping element will be created in the
- // html tree (this includes at least "v" which is always taken to refer
- // to "com.vaadin.ui".
- private Map<String, String> defaultPrefixes = new HashMap<String, String>();
// component creation listeners
private List<ComponentCreationListener> listeners = new ArrayList<ComponentCreationListener>();
private ShouldWriteDataDelegate shouldWriteDataDelegate = ShouldWriteDataDelegate.DEFAULT;
+ // this cannot be static because of testability issues
+ private Boolean legacyDesignPrefix = null;
+
public DesignContext(Document doc) {
this.doc = doc;
// Initialize the mapping between prefixes and package names.
- defaultPrefixes.put("v", "com.vaadin.ui");
- for (String prefix : defaultPrefixes.keySet()) {
- String packageName = defaultPrefixes.get(prefix);
- addPackagePrefix(prefix, packageName);
+ if (isLegacyPrefixEnabled()) {
+ addPackagePrefix(LEGACY_PREFIX, VAADIN_UI_PACKAGE);
+ prefixToPackage.put(VAADIN_PREFIX, VAADIN_UI_PACKAGE);
+ } else {
+ addPackagePrefix(VAADIN_PREFIX, VAADIN_UI_PACKAGE);
+ prefixToPackage.put(LEGACY_PREFIX, VAADIN_UI_PACKAGE);
}
}
@@ -259,6 +274,11 @@ public class DesignContext implements Serializable {
/**
* Creates a two-way mapping between a prefix and a package name.
*
+ * Note that modifying the mapping for {@value #VAADIN_UI_PACKAGE} may
+ * invalidate the backwards compatibility mechanism supporting reading such
+ * components with either {@value #LEGACY_PREFIX} or {@value #VAADIN_PREFIX}
+ * as prefix.
+ *
* @param prefix
* the prefix name without an ending dash (for instance, "v" is
* by default used for "com.vaadin.ui")
@@ -288,7 +308,11 @@ public class DesignContext implements Serializable {
* registered
*/
public String getPackagePrefix(String packageName) {
- return packageToPrefix.get(packageName);
+ if (VAADIN_UI_PACKAGE.equals(packageName)) {
+ return isLegacyPrefixEnabled() ? LEGACY_PREFIX : VAADIN_PREFIX;
+ } else {
+ return packageToPrefix.get(packageName);
+ }
}
/**
@@ -396,7 +420,7 @@ public class DesignContext implements Serializable {
for (String prefix : getPackagePrefixes()) {
// Only store the prefix-name mapping if it is not a default mapping
// (such as "v" -> "com.vaadin.ui")
- if (defaultPrefixes.get(prefix) == null) {
+ if (!VAADIN_PREFIX.equals(prefix) && !LEGACY_PREFIX.equals(prefix)) {
Node newNode = doc.createElement("meta");
newNode.attr("name", "package-mapping");
String prefixToPackageName = prefix + ":" + getPackage(prefix);
@@ -407,6 +431,31 @@ public class DesignContext implements Serializable {
}
/**
+ * Check whether the legacy prefix "v" or the default prefix "vaadin" should
+ * be used when writing designs. The property or context parameter
+ * {@link Constants#SERVLET_PARAMETER_LEGACY_DESIGN_PREFIX} can be used to
+ * switch to the legacy prefix.
+ *
+ * @since
+ * @return true to use the legacy prefix, false by default
+ */
+ protected boolean isLegacyPrefixEnabled() {
+ if (legacyDesignPrefix != null) {
+ return legacyDesignPrefix.booleanValue();
+ }
+ if (VaadinService.getCurrent() == null) {
+ // This will happen at least in JUnit tests.
+ return true;
+ }
+ DeploymentConfiguration configuration = VaadinService.getCurrent()
+ .getDeploymentConfiguration();
+ legacyDesignPrefix = configuration.getApplicationOrSystemProperty(
+ Constants.SERVLET_PARAMETER_LEGACY_DESIGN_PREFIX, "true")
+ .equals("true");
+ return legacyDesignPrefix.booleanValue();
+ }
+
+ /**
* Creates an html tree node corresponding to the given element. Also
* initializes its attributes by calling writeDesign. As a result of the
* writeDesign() call, this method creates the entire subtree rooted at the
@@ -511,11 +560,21 @@ public class DesignContext implements Serializable {
Component component = componentMapper.tagToComponent(tag,
Design.getComponentFactory(), this);
- assert tag.equals(componentMapper.componentToTag(component, this));
+ assert tagEquals(tag, componentMapper.componentToTag(component, this));
return component;
}
+ private boolean tagEquals(String tag1, String tag2) {
+ return tag1.equals(tag2)
+ || (hasVaadinPrefix(tag1) && hasVaadinPrefix(tag2));
+ }
+
+ private boolean hasVaadinPrefix(String tag) {
+ return tag.startsWith(LEGACY_PREFIX + "-")
+ || tag.startsWith(VAADIN_PREFIX + "-");
+ }
+
/**
* Instantiates given class via ComponentFactory.
*
diff --git a/server/tests/src/com/vaadin/tests/design/ParseNewPrefixTest.java b/server/tests/src/com/vaadin/tests/design/ParseNewPrefixTest.java
new file mode 100644
index 0000000000..71811dd29a
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/design/ParseNewPrefixTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.design;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import org.junit.Test;
+
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Test reading a design with all components using the legacy prefix.
+ */
+public class ParseNewPrefixTest {
+
+ @Test
+ public void allComponentsAreParsed() throws FileNotFoundException {
+ DesignContext ctx = Design
+ .read(new FileInputStream(
+ "server/tests/src/com/vaadin/tests/design/all-components-new.html"),
+ null);
+
+ assertThat(ctx, is(not(nullValue())));
+ assertThat(ctx.getRootComponent(), is(not(nullValue())));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/design/WriteNewDesignTest.java b/server/tests/src/com/vaadin/tests/design/WriteNewDesignTest.java
new file mode 100644
index 0000000000..370f4c31c0
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/design/WriteNewDesignTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.design;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.server.Constants;
+import com.vaadin.server.DefaultDeploymentConfiguration;
+import com.vaadin.server.DeploymentConfiguration;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinServletService;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignContext;
+import com.vaadin.util.CurrentInstance;
+
+/**
+ * Parse and write a new format design (using the "vaadin-" prefix).
+ */
+public class WriteNewDesignTest {
+
+ // The context is used for accessing the created component hierarchy.
+ private DesignContext ctx;
+
+ @Before
+ public void setUp() throws Exception {
+ Properties properties = new Properties();
+ properties.put(Constants.SERVLET_PARAMETER_LEGACY_DESIGN_PREFIX,
+ "false");
+ final DeploymentConfiguration configuration = new DefaultDeploymentConfiguration(
+ WriteNewDesignTest.class, properties);
+
+ VaadinService service = new VaadinServletService(null, configuration);
+
+ CurrentInstance.set(VaadinService.class, service);
+
+ ctx = Design.read(new FileInputStream(
+ "server/tests/src/com/vaadin/tests/design/testFile-new.html"),
+ null);
+ }
+
+ @After
+ public void tearDown() {
+ CurrentInstance.set(VaadinService.class, null);
+ }
+
+ private ByteArrayOutputStream serializeDesign(DesignContext context)
+ throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Design.write(context, out);
+
+ return out;
+ }
+
+ @Test
+ public void designIsSerializedWithCorrectPrefixesAndPackageNames()
+ throws IOException {
+ ByteArrayOutputStream out = serializeDesign(ctx);
+
+ Document doc = Jsoup.parse(out.toString("UTF-8"));
+ for (Node child : doc.body().childNodes()) {
+ checkNode(child);
+ }
+ }
+
+ private void checkNode(Node node) {
+ if (node instanceof Element) {
+ assertTrue("Wrong design element prefix", node.nodeName()
+ .startsWith("vaadin-"));
+ for (Node child : node.childNodes()) {
+ checkNode(child);
+ }
+ }
+ }
+
+}
diff --git a/server/tests/src/com/vaadin/tests/design/all-components-new.html b/server/tests/src/com/vaadin/tests/design/all-components-new.html
new file mode 100644
index 0000000000..6507188cd7
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/design/all-components-new.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="package-mapping" content="my:com.addon.mypackage"/>
+ </head>
+ <body>
+ <vaadin-vertical-layout>
+ <!-- abstract component -->
+ <vaadin-button primary-style-name="button" id="foo" style-name="red" caption="Some caption" icon="vaadin://themes/runo/icons/16/ok.png" description="My tooltip" error="Something went wrong" locale="en_US"></vaadin-button>
+
+ <!-- absolute layout -->
+ <vaadin-absolute-layout>
+ <vaadin-button :top="100px" :left="0px" :z-index=21>OK</vaadin-button>
+ <vaadin-button :bottom="0px" :right="0px">Cancel</vaadin-button>
+ </vaadin-absolute-layout>
+
+ <!-- vertical layout -->
+ <vaadin-vertical-layout spacing margin>
+ <vaadin-button :top>OK</vaadin-button>
+ <vaadin-table size-full :expand=1 />
+ </vaadin-vertical-layout>
+
+ <!-- horizontal layout -->
+ <vaadin-horizontal-layout spacing margin>
+ <vaadin-button :top>OK</vaadin-button>
+ <vaadin-table size-full :expand=1 />
+ </vaadin-horizontal-layout>
+
+ <!-- form layout -->
+ <vaadin-form-layout spacing margin>
+ <vaadin-button :top>OK</vaadin-button>
+ <vaadin-table size-full :expand=1 />
+ </vaadin-form-layout>
+
+ <!-- css layout -->
+ <vaadin-css-layout>
+ <vaadin-button>OK</vaadin-button>
+ <vaadin-table size-full />
+ </vaadin-css-layout>
+
+ <!-- panel -->
+ <vaadin-panel caption="Hello world" tabindex=2 scroll-left="10" scroll-top="10">
+ <vaadin-table size-full />
+ </vaadin-panel>
+
+ <!-- abstract field -->
+ <vaadin-text-field buffered validation-visible=false invalid-committed invalid-allowed=false required required-error="This is a required field" conversion-error="Input {0} cannot be parsed" tabindex=3 readonly />
+ <!-- abstract text field, text field -->
+ <vaadin-text-field null-representation="" null-setting-allowed maxlength=10 columns=5 input-prompt="Please enter a value" text-change-event-mode="eager" text-change-timeout=2 value="foo" />
+ <!-- password field -->
+ <vaadin-password-field null-representation="" null-setting-allowed maxlength=10 columns=5 input-prompt="Please enter a value" text-change-event-mode="eager" text-change-timeout=2 value="foo" />
+ <!-- text area -->
+ <vaadin-text-area rows=5 wordwrap=false >test value</vaadin-text-area>
+ <!-- button -->
+ <vaadin-button click-shortcut="ctrl-shift-o" disable-on-click tabindex=1 icon="http://vaadin.com/image.png" icon-alt="ok" plain-text>OK</vaadin-button>
+ <!-- native button -->
+ <vaadin-button click-shortcut="ctrl-shift-o" disable-on-click tabindex=1 icon="http://vaadin.com/image.png" icon-alt="ok" plain-text>OK</vaadin-button>
+
+ <!-- tabsheet -->
+ <vaadin-tab-sheet tabindex=5>
+ <tab visible=false closable caption="My first tab">
+ <vaadin-vertical-layout>
+ <vaadin-text-field/>
+ </vaadin-vertical-layout>
+ </tab>
+ <tab enabled=false caption="Disabled second tab">
+ <vaadin-button>In disabled tab - can’t be shown by default</vaadin-button>
+ </tab>
+ <tab icon="theme://../runo/icons/16/ok.png" icon-alt="Ok png from Runo - very helpful" description="Click to show a text field" style-name="red" id="uniqueDomId">
+ <vaadin-text-field input-prompt="Icon only in tab" />
+ </tab>
+ </vaadin-tab-sheet>
+
+ <!-- accordion -->
+ <vaadin-accordion tabindex=5>
+ <tab visible=false closable caption="My first tab">
+ <vaadin-vertical-layout>
+ <vaadin-text-field/>
+ </vaadin-vertical-layout>
+ </tab>
+ <tab enabled=false caption="Disabled second tab">
+ <vaadin-button>In disabled tab - can’t be shown by default</vaadin-button>
+ </tab>
+ <tab icon="theme://../runo/icons/16/ok.png" icon-alt="Ok png from Runo - very helpful" description="Click to show a text field" style-name="red" id="uniqueDomId">
+ <vaadin-text-field input-prompt="Icon only in tab" />
+ </tab>
+ </vaadin-accordion>
+
+ <!-- abstract split panel -->
+ <vaadin-horizontal-split-panel split-position="20px" min-split-position="0px" max-split-position="50px" locked>
+ <vaadin-button>First slot</vaadin-button>
+ </vaadin-horizontal-split-panel>
+ <vaadin-vertical-split-panel split-position="25%" reversed>
+ <vaadin-button :second>Second slot</vaadin-button>
+ </vaadin-vertical-split-panel>
+ <vaadin-horizontal-split-panel split-position="25%" reversed>
+ <vaadin-button>First slot</vaadin-button>
+ <vaadin-button>Second slot</vaadin-button>
+ </vaadin-horizontal-split-panel>
+
+ <!-- label -->
+ <vaadin-label>Hello world!</vaadin-label>
+ <vaadin-label>This is <b><u>Rich</u></b> content!</vaadin-label>
+ <vaadin-label plain-text>This is only <b>text</b> and will contain visible tags</vaadin-label>
+
+ <!-- checkbox -->
+ <vaadin-check-box checked/>
+
+ <!-- abstract select -->
+ <vaadin-list-select new-items-allowed multi-select
+ item-caption-mode="index"
+ null-selection-allowed=false>
+ </vaadin-list-select>
+
+ <vaadin-combo-box>
+ <option icon="http://something/my-icon.png">First value</option>
+ <option>Second value</option>
+ </vaadin-combo-box>
+
+ </vaadin-vertical-layout>
+ </body>
+</html>
diff --git a/server/tests/src/com/vaadin/tests/design/testFile-new.html b/server/tests/src/com/vaadin/tests/design/testFile-new.html
new file mode 100644
index 0000000000..ab23d1d1b2
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/design/testFile-new.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="package-mapping" content="my:com.addon.mypackage"/>
+ </head>
+ <body>
+ <vaadin-vertical-layout width="500px">
+ <vaadin-horizontal-layout>
+ <vaadin-label plain-text caption="FooBar"></vaadin-label>
+ <vaadin-native-button _id=firstButton>Native click me</vaadin-native-button>
+ <vaadin-native-button id = secondButton _id="localID">Another button</vaadin-native-button>
+ <vaadin-native-button>Yet another button</vaadin-native-button>
+ <vaadin-button plain-text width = "150px">Click me</vaadin-button>
+ </vaadin-horizontal-layout>
+ <vaadin-text-field caption = "Text input"/>
+ <vaadin-text-area caption = "Text area" height="200px" width="300px"/>
+ </vaadin-vertical-layout>
+ </body>
+</html> \ No newline at end of file