summaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin
diff options
context:
space:
mode:
authorJohannes Dahlström <johannesd@vaadin.com>2012-09-20 14:07:14 +0300
committerJohannes Dahlström <johannesd@vaadin.com>2012-09-20 14:08:51 +0300
commit2079e8525df2b12aa8f1103755c91ec2ab1fca95 (patch)
tree59a22f56d1096f4ef96bc8a969f0bf99c0f5e829 /server/src/com/vaadin
parent6b28dc7bf41b8590fcab3d60afd5aa407f1f1401 (diff)
downloadvaadin-framework-2079e8525df2b12aa8f1103755c91ec2ab1fca95.tar.gz
vaadin-framework-2079e8525df2b12aa8f1103755c91ec2ab1fca95.zip
Add a means to handle missing views in Navigator (#9060)
Diffstat (limited to 'server/src/com/vaadin')
-rw-r--r--server/src/com/vaadin/navigator/Navigator.java90
1 files changed, 84 insertions, 6 deletions
diff --git a/server/src/com/vaadin/navigator/Navigator.java b/server/src/com/vaadin/navigator/Navigator.java
index 257dfa208f..c9f6946ce5 100644
--- a/server/src/com/vaadin/navigator/Navigator.java
+++ b/server/src/com/vaadin/navigator/Navigator.java
@@ -112,7 +112,7 @@ public class Navigator implements Serializable {
public String getState() {
String fragment = page.getFragment();
if (fragment.startsWith("!")) {
- return page.getFragment().substring(1);
+ return fragment.substring(1);
} else {
return "";
}
@@ -338,6 +338,7 @@ public class Navigator implements Serializable {
private View currentView = null;
private List<ViewChangeListener> listeners = new LinkedList<ViewChangeListener>();
private List<ViewProvider> providers = new LinkedList<ViewProvider>();
+ private ViewProvider errorProvider;
/**
* Creates a navigator that is tracking the active view using URI fragments
@@ -443,6 +444,8 @@ public class Navigator implements Serializable {
*
* @param navigationState
* view name and parameters
+ *
+ * @throws IllegalArgumentException
*/
public void navigateTo(String navigationState) {
String longestViewName = null;
@@ -459,6 +462,10 @@ public class Navigator implements Serializable {
}
}
}
+ if (viewWithLongestName == null && errorProvider != null) {
+ longestViewName = errorProvider.getViewName(navigationState);
+ viewWithLongestName = errorProvider.getView(longestViewName);
+ }
if (viewWithLongestName != null) {
String parameters = "";
if (navigationState.length() > longestViewName.length() + 1) {
@@ -466,8 +473,12 @@ public class Navigator implements Serializable {
.substring(longestViewName.length() + 1);
}
navigateTo(viewWithLongestName, longestViewName, parameters);
+ } else {
+ throw new IllegalArgumentException(
+ "Trying to navigate to an unknown state '"
+ + navigationState
+ + "' and an error view provider not present");
}
- // TODO if no view is found, what to do?
}
/**
@@ -600,11 +611,11 @@ public class Navigator implements Serializable {
}
/**
- * Register a view class for a view name.
+ * Registers a view class for a view name.
* <p>
* Registering another view with a name that is already registered
* overwrites the old registration of the same type.
- *
+ * <p>
* A new view instance is created every time a view is requested.
*
* @param viewName
@@ -676,9 +687,76 @@ public class Navigator implements Serializable {
}
/**
- * Adds a listener for listening to changes of the active view.
+ * Registers a view class that is instantiated when no other view matches
+ * the navigation state. This implicitly sets an appropriate error view
+ * provider and overrides any previous
+ * {@link #setErrorProvider(ViewProvider)} call.
+ *
+ * @param viewClass
+ * The View class whose instance should be used as the error
+ * view.
+ */
+ public void setErrorView(final Class<? extends View> viewClass) {
+ setErrorProvider(new ViewProvider() {
+ @Override
+ public View getView(String viewName) {
+ try {
+ return viewClass.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String getViewName(String navigationState) {
+ return navigationState;
+ }
+ });
+ }
+
+ /**
+ * Registers a view that is displayed when no other view matches the
+ * navigation state. This implicitly sets an appropriate error view provider
+ * and overrides any previous {@link #setErrorProvider(ViewProvider)} call.
+ *
+ * @param view
+ * The View that should be used as the error view.
+ */
+ public void setErrorView(final View view) {
+ setErrorProvider(new ViewProvider() {
+ @Override
+ public View getView(String viewName) {
+ return view;
+ };
+
+ @Override
+ public String getViewName(String navigationState) {
+ return navigationState;
+ }
+ });
+ }
+
+ /**
+ * Registers a view provider that is queried for a view when no other view
+ * matches the navigation state. An error view provider should match any
+ * navigation state, but could return different views for different states.
+ * Its <code>getViewName(String navigationState)</code> should return
+ * <code>navigationState</code>.
+ *
+ * @param provider
+ */
+ public void setErrorProvider(ViewProvider provider) {
+ errorProvider = provider;
+ }
+
+ /**
+ * Listen to changes of the active view.
* <p>
- * The listener will get notified after the view has changed.
+ * Registered listeners are invoked in registration order before (
+ * {@link ViewChangeListener#beforeViewChange(ViewChangeEvent)
+ * beforeViewChange()}) and after (
+ * {@link ViewChangeListener#afterViewChange(ViewChangeEvent)
+ * afterViewChange()}) a view change occurs.
*
* @param listener
* Listener to invoke during a view change.