use of com.vaadin.flow.router.RouterLayout in project flow by vaadin.
the class NavigationStateRendererTest method getRouterLayoutForSingle.
@Test
public void getRouterLayoutForSingle() throws Exception {
NavigationStateRenderer childRenderer = new NavigationStateRenderer(navigationStateFromTarget(RouteParentLayout.class));
List<Class<? extends RouterLayout>> routerLayoutTypes = childRenderer.getRouterLayoutTypes(RouteParentLayout.class);
Assert.assertEquals("Found layout even though RouteParentLayout doesn't have any parents.", 0, routerLayoutTypes.size());
}
use of com.vaadin.flow.router.RouterLayout in project flow by vaadin.
the class AbstractRouteRegistryInitializer method validateRouteAnnotation.
/* Route validator methods for bootstrap annotations */
private void validateRouteAnnotation(Class<?> route, Class<? extends Annotation> annotation) {
Route routeAnnotation = route.getAnnotation(Route.class);
if (!UI.class.equals(routeAnnotation.layout())) {
if (route.isAnnotationPresent(annotation)) {
throw new InvalidRouteLayoutConfigurationException(String.format("%s annotation needs to be on the top parent layout '%s' not on '%s'", annotation.getSimpleName(), RouterUtil.getTopParentLayout(route, routeAnnotation.value()).getName(), route.getName()));
}
List<Class<? extends RouterLayout>> parentLayouts = RouterUtil.getParentLayouts(route, routeAnnotation.value());
Class<? extends RouterLayout> topParentLayout = RouterUtil.getTopParentLayout(route, routeAnnotation.value());
validateParentAnnotation(parentLayouts, topParentLayout, annotation);
}
}
use of com.vaadin.flow.router.RouterLayout in project flow by vaadin.
the class AbstractNavigationStateRenderer method handle.
@Override
public int handle(NavigationEvent event) {
UI ui = event.getUI();
Class<? extends Component> routeTargetType = navigationState.getNavigationTarget();
List<Class<? extends RouterLayout>> routeLayoutTypes = getRouterLayoutTypes(routeTargetType);
assert routeTargetType != null;
assert routeLayoutTypes != null;
clearContinueNavigationAction(ui);
RouterUtil.checkForDuplicates(routeTargetType, routeLayoutTypes);
if (eventActionsSupported()) {
BeforeLeaveEvent beforeNavigationDeactivating = new BeforeLeaveEvent(event, routeTargetType);
Deque<BeforeLeaveHandler> leaveHandlers;
if (postponed != null) {
leaveHandlers = postponed.getLeaveObservers();
if (!leaveHandlers.isEmpty()) {
postponed = null;
}
} else {
List<BeforeLeaveHandler> beforeLeaveHandlers = new ArrayList<>(ui.getNavigationListeners(BeforeLeaveHandler.class));
beforeLeaveHandlers.addAll(EventUtil.collectBeforeLeaveObservers(ui.getElement()));
leaveHandlers = new ArrayDeque<>(beforeLeaveHandlers);
}
TransitionOutcome transitionOutcome = executeBeforeLeaveNavigation(beforeNavigationDeactivating, leaveHandlers);
if (transitionOutcome == TransitionOutcome.REROUTED) {
return reroute(event, beforeNavigationDeactivating);
} else if (transitionOutcome == TransitionOutcome.POSTPONED) {
ContinueNavigationAction currentAction = beforeNavigationDeactivating.getContinueNavigationAction();
currentAction.setReferences(this, event);
storeContinueNavigationAction(ui, currentAction);
return HttpServletResponse.SC_OK;
}
}
Component componentInstance = getRouteTarget(routeTargetType, event);
List<HasElement> chain = new ArrayList<>();
chain.add(componentInstance);
for (Class<? extends RouterLayout> parentType : routeLayoutTypes) {
chain.add(getRouteTarget(parentType, event));
}
BeforeEnterEvent beforeNavigationActivating = new BeforeEnterEvent(event, routeTargetType);
LocationChangeEvent locationChangeEvent = RouterUtil.createEvent(event, chain);
notifyNavigationTarget(componentInstance, event, beforeNavigationActivating, locationChangeEvent);
if (beforeNavigationActivating.hasRerouteTarget()) {
return reroute(event, beforeNavigationActivating);
}
@SuppressWarnings("unchecked") List<RouterLayout> routerLayouts = (List<RouterLayout>) (List<?>) chain.subList(1, chain.size());
List<BeforeEnterHandler> enterHandlers = new ArrayList<>(ui.getNavigationListeners(BeforeEnterHandler.class));
enterHandlers.addAll(EventUtil.collectEnterObservers(componentInstance, routerLayouts));
TransitionOutcome transitionOutcome = executeBeforeEnterNavigation(beforeNavigationActivating, enterHandlers);
if (eventActionsSupported() && TransitionOutcome.REROUTED.equals(transitionOutcome)) {
return reroute(event, beforeNavigationActivating);
}
ui.getInternals().showRouteTarget(event.getLocation(), navigationState.getResolvedPath(), componentInstance, routerLayouts);
RouterUtil.updatePageTitle(event, componentInstance);
int statusCode = locationChangeEvent.getStatusCode();
validateStatusCode(statusCode, routeTargetType);
List<AfterNavigationHandler> afterNavigationHandlers = new ArrayList<>(ui.getNavigationListeners(AfterNavigationHandler.class));
afterNavigationHandlers.addAll(EventUtil.collectAfterNavigationObservers(componentInstance, routerLayouts));
fireAfterNavigationListeners(new AfterNavigationEvent(locationChangeEvent), afterNavigationHandlers);
return statusCode;
}
use of com.vaadin.flow.router.RouterLayout in project flow by vaadin.
the class UIInternals method showRouteTarget.
/**
* Shows a route target in the related UI. This method is intended for
* framework use only. Use {@link UI#navigate(String)} to change the route
* target that is shown in a UI.
*
* @param viewLocation
* the location of the route target relative to the servlet
* serving the UI, not <code>null</code>
* @param path
* the resolved route path so we can determine what the rendered
* target is for
* @param target
* the component to show, not <code>null</code>
* @param layouts
* the parent layouts
*/
public void showRouteTarget(Location viewLocation, String path, Component target, List<RouterLayout> layouts) {
assert target != null;
assert viewLocation != null;
updateTheme(target, path);
this.viewLocation = viewLocation;
Element uiElement = ui.getElement();
// Assemble previous parent-child relationships to enable detecting
// changes
Map<RouterLayout, HasElement> oldChildren = new HashMap<>();
for (int i = 0; i < routerTargetChain.size() - 1; i++) {
HasElement child = routerTargetChain.get(i);
RouterLayout parent = (RouterLayout) routerTargetChain.get(i + 1);
oldChildren.put(parent, child);
}
routerTargetChain = new ArrayList<>();
routerTargetChain.add(target);
if (layouts != null) {
routerTargetChain.addAll(layouts);
}
// Ensure the entire chain is connected
HasElement root = null;
for (HasElement part : routerTargetChain) {
if (root != null) {
assert part instanceof RouterLayout : "All parts of the chain except the first must implement " + RouterLayout.class.getSimpleName();
RouterLayout parent = (RouterLayout) part;
HasElement oldChild = oldChildren.get(parent);
if (oldChild != root) {
removeFromParent(oldChild);
parent.showRouterLayoutContent(root);
}
} else if (part instanceof RouterLayout && oldChildren.containsKey(part)) {
// Remove old child view from leaf view if it had one
removeFromParent(oldChildren.get(part));
((RouterLayout) part).showRouterLayoutContent(null);
}
root = part;
}
if (root == null) {
throw new IllegalArgumentException("Root can't be null here since we know there's at least one item in the chain");
}
Element rootElement = root.getElement();
if (!uiElement.equals(rootElement.getParent())) {
removeServerSideChildrenFromUI(uiElement);
rootElement.removeFromParent();
uiElement.appendChild(rootElement);
}
}
use of com.vaadin.flow.router.RouterLayout in project flow by vaadin.
the class AbstractRouteRegistryInitializer method validateRouteImplementation.
/* Route validator methods for bootstrap implementations */
private void validateRouteImplementation(Class<?> route, Class<?> implementation) {
Route annotation = route.getAnnotation(Route.class);
if (!UI.class.equals(annotation.layout())) {
if (implementation.isAssignableFrom(route)) {
throw new InvalidRouteLayoutConfigurationException(String.format("%s needs to be the top parent layout '%s' not '%s'", implementation.getSimpleName(), RouterUtil.getTopParentLayout(route, annotation.value()).getName(), route.getName()));
}
List<Class<? extends RouterLayout>> parentLayouts = RouterUtil.getParentLayouts(route, annotation.value());
Class<? extends RouterLayout> topParentLayout = RouterUtil.getTopParentLayout(route, annotation.value());
validateParentImplementation(parentLayouts, topParentLayout, implementation);
}
}
Aggregations