summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/navigator/Navigator.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/vaadin/navigator/Navigator.java')
-rw-r--r--src/com/vaadin/navigator/Navigator.java656
1 files changed, 0 insertions, 656 deletions
diff --git a/src/com/vaadin/navigator/Navigator.java b/src/com/vaadin/navigator/Navigator.java
deleted file mode 100644
index 1813301fe6..0000000000
--- a/src/com/vaadin/navigator/Navigator.java
+++ /dev/null
@@ -1,656 +0,0 @@
-package com.vaadin.navigator;
-
-/*
- @VaadinApache2LicenseForJavaFiles@
- */
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
-import com.vaadin.terminal.Page;
-import com.vaadin.terminal.Page.FragmentChangedEvent;
-import com.vaadin.terminal.Page.FragmentChangedListener;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.ComponentContainer;
-import com.vaadin.ui.CssLayout;
-import com.vaadin.ui.CustomComponent;
-
-/**
- * Navigator utility that allows switching of views in a part of an application.
- *
- * The view switching can be based e.g. on URI fragments containing the view
- * name and parameters to the view. There are two types of parameters for views:
- * an optional parameter string that is included in the fragment (may be
- * bookmarkable).
- *
- * Views can be explicitly registered or dynamically generated and listening to
- * view changes is possible.
- *
- * Note that {@link Navigator} is not a component itself but comes with
- * {@link SimpleViewDisplay} which is a component that displays the selected
- * view as its contents.
- *
- * @author Vaadin Ltd
- * @since 7.0
- */
-public class Navigator implements Serializable {
-
- // TODO divert navigation e.g. if no permissions? Or just show another view
- // but keep URL? how best to intercept
- // TODO investigate relationship with TouchKit navigation support
-
- /**
- * Empty view component.
- */
- public static class EmptyView extends CssLayout implements View {
- /**
- * Create minimally sized empty view.
- */
- public EmptyView() {
- setWidth("0px");
- setHeight("0px");
- }
-
- @Override
- public void navigateTo(String fragmentParameters) {
- // nothing to do
- }
- }
-
- /**
- * Fragment manager using URI fragments of a Page to track views and enable
- * listening to view changes.
- *
- * This class is mostly for internal use by Navigator, and is only public
- * and static to enable testing.
- */
- public static class UriFragmentManager implements FragmentManager,
- FragmentChangedListener {
- private final Page page;
- private final Navigator navigator;
-
- /**
- * Create a new URIFragmentManager and attach it to listen to URI
- * fragment changes of a {@link Page}.
- *
- * @param page
- * page whose URI fragment to get and modify
- * @param navigator
- * {@link Navigator} to notify of fragment changes (using
- * {@link Navigator#navigateTo(String)}
- */
- public UriFragmentManager(Page page, Navigator navigator) {
- this.page = page;
- this.navigator = navigator;
-
- page.addListener(this);
- }
-
- @Override
- public String getFragment() {
- return page.getFragment();
- }
-
- @Override
- public void setFragment(String fragment) {
- page.setFragment(fragment, false);
- }
-
- @Override
- public void fragmentChanged(FragmentChangedEvent event) {
- UriFragmentManager.this.navigator.navigateTo(getFragment());
- }
- }
-
- /**
- * View display that is a component itself and replaces its contents with
- * the view.
- *
- * This display only supports views that are {@link Component}s themselves.
- * Attempting to display a view that is not a component causes an exception
- * to be thrown.
- *
- * By default, the view display has full size.
- */
- public static class SimpleViewDisplay extends CustomComponent implements
- ViewDisplay {
-
- /**
- * Create new {@link ViewDisplay} that is itself a component displaying
- * the view.
- */
- public SimpleViewDisplay() {
- setSizeFull();
- }
-
- @Override
- public void showView(View view) {
- if (view instanceof Component) {
- setCompositionRoot((Component) view);
- } else {
- throw new IllegalArgumentException("View is not a component: "
- + view);
- }
- }
- }
-
- /**
- * View display that replaces the contents of a {@link ComponentContainer}
- * with the active {@link View}.
- *
- * All components of the container are removed before adding the new view to
- * it.
- *
- * This display only supports views that are {@link Component}s themselves.
- * Attempting to display a view that is not a component causes an exception
- * to be thrown.
- */
- public static class ComponentContainerViewDisplay implements ViewDisplay {
-
- private final ComponentContainer container;
-
- /**
- * Create new {@link ViewDisplay} that updates a
- * {@link ComponentContainer} to show the view.
- */
- public ComponentContainerViewDisplay(ComponentContainer container) {
- this.container = container;
- }
-
- @Override
- public void showView(View view) {
- if (view instanceof Component) {
- container.removeAllComponents();
- container.addComponent((Component) view);
- } else {
- throw new IllegalArgumentException("View is not a component: "
- + view);
- }
- }
- }
-
- /**
- * View provider which supports mapping a single view name to a single
- * pre-initialized view instance.
- *
- * For most cases, ClassBasedViewProvider should be used instead of this.
- */
- public static class StaticViewProvider implements ViewProvider {
- private final String viewName;
- private final View view;
-
- /**
- * Create a new view provider which returns a pre-created view instance.
- *
- * @param viewName
- * name of the view (not null)
- * @param view
- * view instance to return (not null), reused on every
- * request
- */
- public StaticViewProvider(String viewName, View view) {
- this.viewName = viewName;
- this.view = view;
- }
-
- @Override
- public String getViewName(String viewAndParameters) {
- if (null == viewAndParameters) {
- return null;
- }
- if (viewAndParameters.startsWith(viewName)) {
- return viewName;
- }
- return null;
- }
-
- @Override
- public View getView(String viewName) {
- if (this.viewName.equals(viewName)) {
- return view;
- }
- return null;
- }
-
- /**
- * Get the view name for this provider.
- *
- * @return view name for this provider
- */
- public String getViewName() {
- return viewName;
- }
- }
-
- /**
- * View provider which maps a single view name to a class to instantiate for
- * the view.
- *
- * Note that the view class must be accessible by the class loader used by
- * the provider. This may require its visibility to be public.
- *
- * This class is primarily for internal use by {@link Navigator}.
- */
- public static class ClassBasedViewProvider implements ViewProvider {
-
- private final String viewName;
- private final Class<? extends View> viewClass;
-
- /**
- * Create a new view provider which creates new view instances based on
- * a view class.
- *
- * @param viewName
- * name of the views to create (not null)
- * @param viewClass
- * class to instantiate when a view is requested (not null)
- */
- public ClassBasedViewProvider(String viewName,
- Class<? extends View> viewClass) {
- if (null == viewName || null == viewClass) {
- throw new IllegalArgumentException(
- "View name and class should not be null");
- }
- this.viewName = viewName;
- this.viewClass = viewClass;
- }
-
- @Override
- public String getViewName(String viewAndParameters) {
- if (null == viewAndParameters) {
- return null;
- }
- if (viewAndParameters.equals(viewName)
- || viewAndParameters.startsWith(viewName + "/")) {
- return viewName;
- }
- return null;
- }
-
- @Override
- public View getView(String viewName) {
- if (this.viewName.equals(viewName)) {
- try {
- View view = viewClass.newInstance();
- return view;
- } catch (InstantiationException e) {
- // TODO error handling
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- // TODO error handling
- throw new RuntimeException(e);
- }
- }
- return null;
- }
-
- /**
- * Get the view name for this provider.
- *
- * @return view name for this provider
- */
- public String getViewName() {
- return viewName;
- }
-
- /**
- * Get the view class for this provider.
- *
- * @return {@link View} class
- */
- public Class<? extends View> getViewClass() {
- return viewClass;
- }
- }
-
- private final FragmentManager fragmentManager;
- private final ViewDisplay display;
- private View currentView = null;
- private List<ViewChangeListener> listeners = new LinkedList<ViewChangeListener>();
- private List<ViewProvider> providers = new LinkedList<ViewProvider>();
-
- /**
- * Create a navigator that is tracking the active view using URI fragments
- * of the current {@link Page} and replacing the contents of a
- * {@link ComponentContainer} with the active view.
- *
- * In case the container is not on the current page, use another
- * {@link Navigator#Navigator(Page, ViewDisplay)} with an explicitly created
- * {@link ComponentContainerViewDisplay}.
- *
- * All components of the container are removed each time before adding the
- * active {@link View}. Views must implement {@link Component} when using
- * this constructor.
- *
- * <p>
- * After all {@link View}s and {@link ViewProvider}s have been registered,
- * the application should trigger navigation to the current fragment using
- * e.g.
- *
- * <pre>
- * navigator.navigateTo(Page.getCurrent().getFragment());
- * </pre>
- *
- * @param container
- * ComponentContainer whose contents should be replaced with the
- * active view on view change
- */
- public Navigator(ComponentContainer container) {
- display = new ComponentContainerViewDisplay(container);
- fragmentManager = new UriFragmentManager(Page.getCurrent(), this);
- }
-
- /**
- * Create a navigator that is tracking the active view using URI fragments.
- *
- * <p>
- * After all {@link View}s and {@link ViewProvider}s have been registered,
- * the application should trigger navigation to the current fragment using
- * e.g.
- *
- * <pre>
- * navigator.navigateTo(Page.getCurrent().getFragment());
- * </pre>
- *
- * @param page
- * whose URI fragments are used
- * @param display
- * where to display the views
- */
- public Navigator(Page page, ViewDisplay display) {
- this.display = display;
- fragmentManager = new UriFragmentManager(page, this);
- }
-
- /**
- * Create a navigator.
- *
- * When a custom fragment manager is not needed, use the constructor
- * {@link #Navigator(Page, ViewDisplay)} which uses a URI fragment based
- * fragment manager.
- *
- * Note that navigation to the initial view must be performed explicitly by
- * the application after creating a Navigator using this constructor.
- *
- * @param fragmentManager
- * fragment manager keeping track of the active view and enabling
- * bookmarking and direct navigation
- * @param display
- * where to display the views
- */
- public Navigator(FragmentManager fragmentManager, ViewDisplay display) {
- this.display = display;
- this.fragmentManager = fragmentManager;
- }
-
- /**
- * Navigate to a view and initialize the view with given parameters.
- *
- * The view string consists of a view name optionally followed by a slash
- * and (fragment) parameters. ViewProviders are used to find and create the
- * correct type of view.
- *
- * If multiple providers return a matching view, the view with the longest
- * name is selected. This way, e.g. hierarchies of subviews can be
- * registered like "admin/", "admin/users", "admin/settings" and the longest
- * match is used.
- *
- * If the view being deactivated indicates it wants a confirmation for the
- * navigation operation, the user is asked for the confirmation.
- *
- * Registered {@link ViewChangeListener}s are called upon successful view
- * change.
- *
- * @param viewAndParameters
- * view name and parameters
- */
- public void navigateTo(String viewAndParameters) {
- String longestViewName = null;
- View viewWithLongestName = null;
- for (ViewProvider provider : providers) {
- String viewName = provider.getViewName(viewAndParameters);
- if (null != viewName
- && (longestViewName == null || viewName.length() > longestViewName
- .length())) {
- View view = provider.getView(viewName);
- if (null != view) {
- longestViewName = viewName;
- viewWithLongestName = view;
- }
- }
- }
- if (viewWithLongestName != null) {
- String parameters = null;
- if (viewAndParameters.length() > longestViewName.length() + 1) {
- parameters = viewAndParameters.substring(longestViewName
- .length() + 1);
- }
- navigateTo(viewWithLongestName, longestViewName, parameters);
- }
- // TODO if no view is found, what to do?
- }
-
- /**
- * Internal method activating a view, setting its parameters and calling
- * listeners.
- *
- * This method also verifies that the user is allowed to perform the
- * navigation operation.
- *
- * @param view
- * view to activate
- * @param viewName
- * (optional) name of the view or null not to set the fragment
- * @param fragmentParameters
- * parameters passed in the fragment for the view
- */
- protected void navigateTo(View view, String viewName,
- String fragmentParameters) {
- ViewChangeEvent event = new ViewChangeEvent(this, currentView, view,
- viewName, fragmentParameters);
- if (!isViewChangeAllowed(event)) {
- return;
- }
-
- if (null != viewName && getFragmentManager() != null) {
- String currentFragment = viewName;
- if (fragmentParameters != null) {
- currentFragment += "/" + fragmentParameters;
- }
- if (!currentFragment.equals(getFragmentManager().getFragment())) {
- getFragmentManager().setFragment(currentFragment);
- }
- }
-
- view.navigateTo(fragmentParameters);
- currentView = view;
-
- if (display != null) {
- display.showView(view);
- }
-
- fireViewChange(event);
- }
-
- /**
- * Check whether view change is allowed.
- *
- * All related listeners are called. The view change is blocked if any of
- * them wants to block the navigation operation.
- *
- * The view change listeners may also e.g. open a warning or question dialog
- * and save the parameters to re-initiate the navigation operation upon user
- * action.
- *
- * @param event
- * view change event (not null, view change not yet performed)
- * @return true if the view change should be allowed, false to silently
- * block the navigation operation
- */
- protected boolean isViewChangeAllowed(ViewChangeEvent event) {
- for (ViewChangeListener l : listeners) {
- if (!l.isViewChangeAllowed(event)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Return the fragment manager that is used to get, listen to and manipulate
- * the URI fragment or other source of navigation information.
- *
- * @return fragment manager in use
- */
- protected FragmentManager getFragmentManager() {
- return fragmentManager;
- }
-
- /**
- * Returns the ViewDisplay used by the navigator. Unless another display is
- * specified, a {@link SimpleViewDisplay} (which is a {@link Component}) is
- * used by default.
- *
- * @return current ViewDisplay
- */
- public ViewDisplay getDisplay() {
- return display;
- }
-
- /**
- * Fire an event when the current view has changed.
- *
- * @param event
- * view change event (not null)
- */
- protected void fireViewChange(ViewChangeEvent event) {
- for (ViewChangeListener l : listeners) {
- l.navigatorViewChanged(event);
- }
- }
-
- /**
- * Register a static, pre-initialized view instance for a view name.
- *
- * Registering another view with a name that is already registered
- * overwrites the old registration of the same type.
- *
- * @param viewName
- * String that identifies a view (not null nor empty string)
- * @param view
- * {@link View} instance (not null)
- */
- public void addView(String viewName, View view) {
-
- // Check parameters
- if (viewName == null || view == null) {
- throw new IllegalArgumentException(
- "view and viewName must be non-null");
- }
-
- removeView(viewName);
- registerProvider(new StaticViewProvider(viewName, view));
- }
-
- /**
- * Register for a view name a view class.
- *
- * Registering another view with a name that is already registered
- * overwrites the old registration of the same type.
- *
- * A new view instance is created every time a view is requested.
- *
- * @param viewName
- * String that identifies a view (not null nor empty string)
- * @param viewClass
- * {@link View} class to instantiate when a view is requested
- * (not null)
- */
- public void addView(String viewName, Class<? extends View> viewClass) {
-
- // Check parameters
- if (viewName == null || viewClass == null) {
- throw new IllegalArgumentException(
- "view and viewClass must be non-null");
- }
-
- removeView(viewName);
- registerProvider(new ClassBasedViewProvider(viewName, viewClass));
- }
-
- /**
- * Remove view from navigator.
- *
- * This method only applies to views registered using
- * {@link #addView(String, View)} or {@link #addView(String, Class)}.
- *
- * @param viewName
- * name of the view to remove
- */
- public void removeView(String viewName) {
- Iterator<ViewProvider> it = providers.iterator();
- while (it.hasNext()) {
- ViewProvider provider = it.next();
- if (provider instanceof StaticViewProvider) {
- StaticViewProvider staticProvider = (StaticViewProvider) provider;
- if (staticProvider.getViewName().equals(viewName)) {
- it.remove();
- }
- } else if (provider instanceof ClassBasedViewProvider) {
- ClassBasedViewProvider classBasedProvider = (ClassBasedViewProvider) provider;
- if (classBasedProvider.getViewName().equals(viewName)) {
- it.remove();
- }
- }
- }
- }
-
- /**
- * Register a view provider (factory).
- *
- * Providers are called in order of registration until one that can handle
- * the requested view name is found.
- *
- * @param provider
- * provider to register
- */
- public void registerProvider(ViewProvider provider) {
- providers.add(provider);
- }
-
- /**
- * Unregister a view provider (factory).
- *
- * @param provider
- * provider to unregister
- */
- public void unregisterProvider(ViewProvider provider) {
- providers.remove(provider);
- }
-
- /**
- * Listen to changes of the active view.
- *
- * The listener will get notified after the view has changed.
- *
- * @param listener
- * Listener to invoke after view changes.
- */
- public void addListener(ViewChangeListener listener) {
- listeners.add(listener);
- }
-
- /**
- * Remove a view change listener.
- *
- * @param listener
- * Listener to remove.
- */
- public void removeListener(ViewChangeListener listener) {
- listeners.remove(listener);
- }
-
-}