aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorPeter Lehto <peter@vaadin.com>2017-06-13 12:41:36 +0300
committerArtur <artur@vaadin.com>2017-06-13 12:41:36 +0300
commitcb1a2b99472faabba3596d673dbdbc377fb1628a (patch)
tree5d314656198c06b6411fce5a6b6a62214fa59197 /server
parent2f5e484a12f25d10ac6034d8ee9176b553b96c2d (diff)
downloadvaadin-framework-cb1a2b99472faabba3596d673dbdbc377fb1628a.tar.gz
vaadin-framework-cb1a2b99472faabba3596d673dbdbc377fb1628a.zip
Add getStateParameterMap to Navigator to get parameters as a map (#9517)
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/navigator/Navigator.java87
-rw-r--r--server/src/test/java/com/vaadin/tests/server/navigator/NavigatorTest.java127
2 files changed, 188 insertions, 26 deletions
diff --git a/server/src/main/java/com/vaadin/navigator/Navigator.java b/server/src/main/java/com/vaadin/navigator/Navigator.java
index 2341479832..8b9e39b354 100644
--- a/server/src/main/java/com/vaadin/navigator/Navigator.java
+++ b/server/src/main/java/com/vaadin/navigator/Navigator.java
@@ -17,9 +17,13 @@ package com.vaadin.navigator;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+import java.util.Objects;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.server.Page;
@@ -53,6 +57,11 @@ public class Navigator implements Serializable {
// TODO investigate relationship with TouchKit navigation support
+ private static final String DEFAULT_VIEW_SEPARATOR = "/";
+
+ private static final String DEFAULT_STATE_PARAMETER_SEPARATOR = "&";
+ private static final String DEFAULT_STATE_PARAMETER_KEY_VALUE_SEPARATOR = "=";
+
/**
* Empty view component.
*/
@@ -340,23 +349,17 @@ public class Navigator implements Serializable {
/**
* The {@link UI} bound with the Navigator.
- *
- * @since 8.0.3
*/
protected UI ui;
/**
* The {@link NavigationStateManager} that is used to get, listen to and
* manipulate the navigation state used by the Navigator.
- *
- * @since 8.0.3
*/
protected NavigationStateManager stateManager;
/**
* The {@link ViewDisplay} used by the Navigator.
- *
- * @since 8.0.3
*/
protected ViewDisplay display;
@@ -742,6 +745,76 @@ public class Navigator implements Serializable {
}
/**
+ * Returns the current navigation state reported by this Navigator's
+ * {@link NavigationStateManager} as Map<String, String> where each key
+ * represents a parameter in the state.
+ *
+ * Uses {@literal &} as parameter separator. If the state contains
+ * {@literal #!view/foo&bar=baz} then this method will return a map
+ * containing {@literal foo => ""} and {@literal bar => baz}.
+ *
+ * @return The parameters from the navigation state as a map
+ * @see #getStateParameterMap(String)
+ */
+ public Map<String, String> getStateParameterMap() {
+ return getStateParameterMap(DEFAULT_STATE_PARAMETER_SEPARATOR);
+ }
+
+ /**
+ * Returns the current navigation state reported by this Navigator's
+ * {@link NavigationStateManager} as Map<String, String> where each key
+ * represents a parameter in the state. The state parameter separator
+ * character needs to be specified with the separator.
+ *
+ * @param separator
+ * the string (typically one character) used to separate values
+ * from each other
+ * @return The parameters from the navigation state as a map
+ * @see #getStateParameterMap()
+ */
+ public Map<String, String> getStateParameterMap(String separator) {
+ return parseStateParameterMap(Objects.requireNonNull(separator));
+ }
+
+ /**
+ * Parses the state parameter map using given separator String.
+ *
+ * @param separator
+ * the string (typically one character) used to separate values
+ * from each other
+ * @return The navigation state as Map<String, String>.
+ */
+ protected Map<String, String> parseStateParameterMap(String separator) {
+ Map<String, String> parameterMap = new HashMap<>();
+ if (getState() == null || getState().isEmpty()) {
+ return Collections.emptyMap();
+ }
+
+ String state = getState();
+ int viewSeparatorLocation = state.indexOf(DEFAULT_VIEW_SEPARATOR);
+
+ String parameterString;
+ if (viewSeparatorLocation == -1) {
+ parameterString = "";
+ } else {
+ parameterString = state.substring(viewSeparatorLocation + 1,
+ state.length());
+ }
+ if (parameterString.isEmpty()) {
+ return Collections.emptyMap();
+ }
+ String[] parameters = parameterString.split(separator);
+ for (int i = 0; i < parameters.length; i++) {
+ String[] keyAndValue = parameters[i]
+ .split(DEFAULT_STATE_PARAMETER_KEY_VALUE_SEPARATOR);
+ parameterMap.put(keyAndValue[0],
+ keyAndValue.length > 1 ? keyAndValue[1] : "");
+ }
+
+ return parameterMap;
+ }
+
+ /**
* Return the {@link ViewDisplay} used by the navigator.
*
* @return the ViewDisplay used for displaying views
@@ -993,8 +1066,6 @@ public class Navigator implements Serializable {
* @param state
* state string
* @return suitable provider
- *
- * @since 8.0.3
*/
protected ViewProvider getViewProvider(String state) {
String longestViewName = null;
diff --git a/server/src/test/java/com/vaadin/tests/server/navigator/NavigatorTest.java b/server/src/test/java/com/vaadin/tests/server/navigator/NavigatorTest.java
index 6991fd1b9e..022b388840 100644
--- a/server/src/test/java/com/vaadin/tests/server/navigator/NavigatorTest.java
+++ b/server/src/test/java/com/vaadin/tests/server/navigator/NavigatorTest.java
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
import org.easymock.EasyMock;
import org.easymock.IArgumentMatcher;
@@ -51,6 +53,25 @@ import com.vaadin.ui.VerticalLayout;
public class NavigatorTest {
+ private final class TestNavigationStateManager
+ implements NavigationStateManager {
+ private String state;
+
+ @Override
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ @Override
+ public void setNavigator(Navigator navigator) {
+ }
+
+ @Override
+ public String getState() {
+ return state;
+ }
+ }
+
// TODO test internal parameters (and absence of them)
// TODO test listeners blocking navigation, multiple listeners
@@ -854,24 +875,7 @@ public class NavigatorTest {
@Test
public void testNavigateTo_navigateSameUriTwice_secondNavigationDoesNothing() {
- NavigationStateManager manager = new NavigationStateManager() {
-
- private String state;
-
- @Override
- public void setState(String state) {
- this.state = state;
- }
-
- @Override
- public void setNavigator(Navigator navigator) {
- }
-
- @Override
- public String getState() {
- return state;
- }
- };
+ NavigationStateManager manager = new TestNavigationStateManager();
final String viewName = "view";
@@ -969,4 +973,91 @@ public class NavigatorTest {
((Label) ((HorizontalLayout) ui.getContent()).getComponent(0))
.getValue());
}
+
+ @Test
+ public void parameterMap_noViewSeparator() {
+ Navigator navigator = createNavigatorWithState("fooview");
+ Assert.assertTrue(navigator.getStateParameterMap().isEmpty());
+ Assert.assertTrue(navigator.getStateParameterMap("foo").isEmpty());
+ }
+
+ @Test
+ public void parameterMap_noParameters() {
+ Navigator navigator = createNavigatorWithState("fooview/");
+ Assert.assertTrue(navigator.getStateParameterMap().isEmpty());
+ }
+
+ @Test
+ public void parameterMap_oneParameterNoValue() {
+ Navigator navigator = createNavigatorWithState("fooview/bar");
+ assertMap(navigator.getStateParameterMap(), entry("bar", ""));
+ }
+
+ @Test
+ public void parameterMap_oneParameterNoValueButEquals() {
+ Navigator navigator = createNavigatorWithState("fooview/bar=");
+ assertMap(navigator.getStateParameterMap(), entry("bar", ""));
+ }
+
+ @Test
+ public void parameterMap_oneParameterWithValue() {
+ Navigator navigator = createNavigatorWithState("fooview/bar=baz");
+ assertMap(navigator.getStateParameterMap(), entry("bar", "baz"));
+ }
+
+ @Test
+ public void parameterMap_twoParameters() {
+ Navigator navigator = createNavigatorWithState("fooview/foo=bar&baz");
+ assertMap(navigator.getStateParameterMap(), entry("foo", "bar"),
+ entry("baz", ""));
+ }
+
+ @Test
+ public void parameterMap_customSeparator() {
+ Navigator navigator = createNavigatorWithState("fooview/foo=bar&baz");
+ assertMap(navigator.getStateParameterMap("a"), entry("foo", "b"),
+ entry("r&b", ""), entry("z", ""));
+ }
+
+ @SafeVarargs
+ private final void assertMap(Map<String, String> map,
+ Entry<String, String>... entries) {
+ Assert.assertEquals(entries.length, map.size());
+ for (Entry<String, String> entry : entries) {
+ Assert.assertTrue(
+ "Map should contain a key called '" + entry.getKey() + "'",
+ map.containsKey(entry.getKey()));
+ Assert.assertEquals(entry.getValue(), map.get(entry.getKey()));
+ }
+
+ }
+
+ private Entry<String, String> entry(String key, String value) {
+ return new Entry<String, String>() {
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String setValue(String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ };
+ }
+
+ private Navigator createNavigatorWithState(String state) {
+ TestNavigationStateManager manager = new TestNavigationStateManager();
+ Navigator navigator = new Navigator(createMockUI(), manager,
+ EasyMock.createMock(ViewDisplay.class));
+ manager.setState(state);
+ return navigator;
+ }
}