Directory

← Back

URI Fragment Actions for Vaadin

Wrapper around a Vaadin Navigator which allows interpreting complex parameterized URI fragments.

Author

Rating

Popularity

<100

This add-on enhances the standard Navigator component with a sophisticated interpreter for URI fragments. Using this add-on, you can design the URI fragments used by your application in an arbitrarily complex hierarchy. Furthermore, your URI fragments can contain any number of parameter values which will be interpreted and converted automatically so that these values can be handled in a type-safe way.

Note that this add-on requires Java 8.

For example, it is possible to use URI fragments like in the following example:

#!home
#!admin/settings
#!admin/users
#!showHistory/start/2017-01-01/end/2017-01-31
#!admin/users/id/4711/profile/activeTab/address

As you can see, these URI fragments form a hierarchy where each individual path element can have an arbitrary number of parameters. Parameter values are converted automatically. So in the example above, the application will only deal with Long and Date objects (and Strings for the activeTab parameter).

The Navigator wrapper from this add-on interprets a URI fragment completely, extracts and converts all parameter values found in it, and at the end of this process creates and executes a predefined action command object which runs the required tasks for this URI fragment.

Such an action command could, for instance, activate some specific view and display data on that view the source of which has been specified through a parameter value in the URI fragment. In addition to that, the action command might configure the displayed view in some specific way, e. g. by bringing a particular tab of a tab sheet to the foreground, depending on some additional parameter value in the URI fragment.

Sample code

package de.oio.vaadin;

import com.vaadin.annotations.Theme;
import com.vaadin.server.ExternalResource;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Label;
import com.vaadin.ui.Link;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
import org.roklib.urifragmentrouting.UriActionCommand;
import org.roklib.urifragmentrouting.UriActionMapperTree;
import org.roklib.urifragmentrouting.annotation.AllCapturedParameters;
import org.roklib.urifragmentrouting.annotation.RoutingContext;
import org.roklib.urifragmentrouting.mapper.UriPathSegmentActionMapper;
import org.roklib.urifragmentrouting.parameter.value.CapturedParameterValues;
import org.roklib.urifragmentrouting.parameter.value.ParameterValue;
import org.vaadin.uriactions.UriFragmentActionNavigatorWrapper;

import java.util.HashMap;
import java.util.Map;

@Theme("valo")
public class URIFragmentActionsDemoUI extends UI {

    private static final String HOME = "home";
    private static final String PROFILE = "profile";
    private static final String USERNAME_PARAM = "username";
    private static final String USER = "user";

    private static UriActionMapperTree actionMapperTree;
    private static Map<String, UriPathSegmentActionMapper> mappers;

    static {
        // Registry for the action mappers. Will be needed later for assembling HTML links.
        mappers = new HashMap<>();

        // build a URI action mapper tree which can handle the following URI fragments
        // #!home
        // #!user/username/john.doe/profile
        // #!user/username/joe.average/profile
        // etc.
        actionMapperTree = UriActionMapperTree.create()
                // redirect to '#!home' by default when no URI fragment is present
                // use lambda in a lambda construct
                .setRootActionCommandFactory(() -> () -> UI.getCurrent().getNavigator().navigateTo(HOME))
                // start building the active URI fragment hierarchy
                .buildMapperTree()
                // build mapper for '#!home'
                .map(HOME).onActionFactory(() -> new LogToLabelCommand("Welcome to the home screen."))
                    // store mapper for later reference
                    .finishMapper(mapper -> mappers.put(HOME, mapper))
                // build mapper for the '#!user' hierarchy
                .mapSubtree(USER)
                    // add a single-valued parameter 'username' to the 'user' action mapper
                    .withSingleValuedParameter(USERNAME_PARAM).forType(String.class).noDefault().onSubtree()
                    // build mapper for '#!user/.../profile'
                    .map(PROFILE).onActionFactory(
                            () -> new LogToLabelCommand("This is a user profile page"))
                    // finish the 'profile' mapper and store it for later reference
                    .finishMapper(mapper -> mappers.put(PROFILE, mapper))
                // finish the 'user' mapper
                .finishMapper()
                // finish and build the action mapper tree
                .build();
    }

    @Override
    protected void init(VaadinRequest request) {
        Label label = new Label();
        label.setStyleName(ValoTheme.LABEL_H1);

        // build and configure the UriFragmentActionNavigatorWrapper
        UriFragmentActionNavigatorWrapper navigatorWrapper = new UriFragmentActionNavigatorWrapper(this);

        // set the routing context
        navigatorWrapper.setRoutingContext(new MyRoutingContext(label));

        // set the application-scoped URI action mapper tree
        navigatorWrapper.setUriActionMapperTree(actionMapperTree);

        VerticalLayout layout = new VerticalLayout();
        layout.addComponent(label);

        // add some links
        // link to home screen
        layout.addComponent(new Link("Home Screen",
                new ExternalResource("#!" + actionMapperTree.assembleUriFragment(mappers.get(HOME)))));

        // link to some user profiles
        CapturedParameterValues parameters = new CapturedParameterValues();
        parameters.setValueFor(USER, USERNAME_PARAM, ParameterValue.forValue("john.doe"));
        layout.addComponent(new Link("Visit John Doe's Profile",
                new ExternalResource("#!" + actionMapperTree.assembleUriFragment(parameters, mappers.get(PROFILE)))));

        parameters.setValueFor(USER, USERNAME_PARAM, ParameterValue.forValue("joe.average"));
        layout.addComponent(new Link("Visit Joe Average's Profile",
                new ExternalResource("#!" + actionMapperTree.assembleUriFragment(parameters, mappers.get(PROFILE)))));

        parameters.setValueFor(USER, USERNAME_PARAM, ParameterValue.forValue("dan.developer"));
        layout.addComponent(new Link("Visit Dan Developer's Profile",
                new ExternalResource("#!" + actionMapperTree.assembleUriFragment(parameters, mappers.get(PROFILE)))));
        setContent(layout);
    }

    /**
     * Context object which is used to transport current context information to the currently executed URI action
     * command. In this case, the context contains a reference to the label object of the current UI.
     */
    public static class MyRoutingContext {
        private Label label;

        public MyRoutingContext(Label label) {
            this.label = label;
        }

        public Label getLabel() {
            return label;
        }
    }

    /**
     * Action command which will be executed for each new navigator state. The command will set a new text on the label
     * object found in the routing context object.
     */
    public static class LogToLabelCommand implements UriActionCommand {
        private String text;
        private MyRoutingContext context;
        private CapturedParameterValues parameters;

        public LogToLabelCommand(String text) {
            this.text = text;
        }

        @Override
        public void run() {
            if (!parameters.isEmpty()) {
                text = text + ": " + parameters.asQueryParameterMap();
            }
            context.getLabel().setValue(text);
        }

        @RoutingContext
        public void setContext(MyRoutingContext context) {
            this.context = context;
        }

        @AllCapturedParameters
        public void setParameters(CapturedParameterValues parameters) {
            this.parameters = parameters;
        }
    }
}

Compatibility

(Loading compatibility data...)

Was this helpful? Need more help?
Leave a comment or a question below. You can also join the chat on Discord or ask questions on StackOverflow.

Version

Add-on uses most recent version 1.3.0 of library uri-fragment-routing.

Released
2017-04-22
Maturity
STABLE
License
Apache License 2.0

Compatibility

Framework
Vaadin 7.0+
Vaadin 8.0+
Vaadin 8.0 in 1.0.2
Vaadin 7.7 in 1.0.2
Vaadin 7.6 in 1.0.2
Vaadin 7.5 in 1.0.2
Vaadin 7.4 in 1.0.2
Vaadin 7.3 in 1.0.2
Vaadin 7.2 in 1.0.2
Vaadin 7.1 in 1.0.2
Vaadin 7.0 in 1.0.2
Browser
Browser Independent

URI Fragment Actions for Vaadin - Vaadin Add-on Directory

Wrapper around a Vaadin Navigator which allows interpreting complex parameterized URI fragments. URI Fragment Actions for Vaadin - Vaadin Add-on Directory
This add-on enhances the standard `Navigator` component with a sophisticated interpreter for URI fragments. Using this add-on, you can design the URI fragments used by your application in an arbitrarily complex hierarchy. Furthermore, your URI fragments can contain any number of parameter values which will be interpreted and converted automatically so that these values can be handled in a type-safe way. **Note that this add-on requires Java 8.** For example, it is possible to use URI fragments like in the following example: ``` #!home #!admin/settings #!admin/users #!showHistory/start/2017-01-01/end/2017-01-31 #!admin/users/id/4711/profile/activeTab/address ``` As you can see, these URI fragments form a hierarchy where each individual path element can have an arbitrary number of parameters. Parameter values are converted automatically. So in the example above, the application will only deal with `Long` and `Date` objects (and `Strings` for the `activeTab` parameter). The `Navigator` wrapper from this add-on interprets a URI fragment completely, extracts and converts all parameter values found in it, and at the end of this process creates and executes a predefined action command object which runs the required tasks for this URI fragment. Such an action command could, for instance, activate some specific view and display data on that view the source of which has been specified through a parameter value in the URI fragment. In addition to that, the action command might configure the displayed view in some specific way, e. g. by bringing a particular tab of a tab sheet to the foreground, depending on some additional parameter value in the URI fragment.
Online