You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltaspike.apache.org by "Gerhard Petracek (JIRA)" <ji...@apache.org> on 2013/12/17 14:26:07 UTC

[jira] [Comment Edited] (DELTASPIKE-471) support external handling of navigation-cases

    [ https://issues.apache.org/jira/browse/DELTASPIKE-471?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13850398#comment-13850398 ] 

Gerhard Petracek edited comment on DELTASPIKE-471 at 12/17/13 1:24 PM:
-----------------------------------------------------------------------

workaround:

{code}
import javax.faces.application.ConfigurableNavigationHandler;
import javax.faces.application.NavigationCase;
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class EditableNavigationHandler extends ConfigurableNavigationHandler
{
    private final NavigationHandler wrapped;

    public EditableNavigationHandler(NavigationHandler wrapped)
    {
        this.wrapped = wrapped;
    }

    @Override
    public NavigationCase getNavigationCase(FacesContext facesContext, String fromAction, String outcome)
    {
        if (this.wrapped instanceof ConfigurableNavigationHandler)
        {
            return ((ConfigurableNavigationHandler)this.wrapped).getNavigationCase(facesContext, fromAction, outcome);
        }
        return null;
    }

    @Override
    public Map<String, Set<NavigationCase>> getNavigationCases()
    {
        if (this.wrapped instanceof ConfigurableNavigationHandler)
        {
            NavigationHandler navigationHandler = findInnermostHandler(this.wrapped);

            Map<String, Set<NavigationCase>> result;
            if (navigationHandler instanceof ConfigurableNavigationHandler)
            {
                result = new DelegatingMap((ConfigurableNavigationHandler)navigationHandler);
            }
            else
            {
                result = new HashMap<String, Set<NavigationCase>>();
            }

            result.putAll(((ConfigurableNavigationHandler)this.wrapped).getNavigationCases());
            return result;
        }
        return null;
    }

    private NavigationHandler findInnermostHandler(NavigationHandler wrapped)
    {
        for (Field field : wrapped.getClass().getDeclaredFields())
        {
            if (NavigationHandler.class.isAssignableFrom(field.getType()))
            {
                field.setAccessible(true);
                try
                {
                    NavigationHandler result = findInnermostHandler((NavigationHandler)field.get(wrapped));
                    if (result == null)
                    {
                        result = wrapped;
                    }
                    return result;
                }
                catch (IllegalAccessException e)
                {
                    throw new RuntimeException(e);
                }
            }
        }
        return wrapped;
    }

    @Override
    public void handleNavigation(FacesContext context, String fromAction, String outcome)
    {
        this.wrapped.handleNavigation(context, fromAction, outcome);
    }

    //currently not a complete handling, but enough to fix the issues with mojarra
    private class DelegatingMap extends HashMap<String, Set<NavigationCase>>
    {
        private static final long serialVersionUID = -955468874397821639L;
        private final ConfigurableNavigationHandler wrapped;

        private DelegatingMap(ConfigurableNavigationHandler wrapped)
        {
            this.wrapped = wrapped;
        }

        @Override
        public Set<NavigationCase> put(String key, Set<NavigationCase> value)
        {
            if (value == null)
            {
                return null;
            }

            Set<NavigationCase> result = new HashSet<NavigationCase>();

            for (NavigationCase navigationCase : value)
            {
                if (!(navigationCase.getFromOutcome() == null && navigationCase.getFromAction() == null))
                {
                    result.add(navigationCase);
                }
            }

            //delegate to the wrapped instance -> the innermost handler needs to receive it
            //(because mojarra uses ConfigurableNavigationHandler#getNavigationCases
            // to add cases for std. nav.rules from the outside)
            return this.wrapped.getNavigationCases().put(key, result);
        }

        @Override
        public Set<NavigationCase> get(Object key)
        {
            Set<NavigationCase> navigationCases = super.get(key);
            if (navigationCases == null)
            {
                navigationCases = new HashSet<NavigationCase>();
                put((String)key, navigationCases);
            }

            return new DelegatingSet(navigationCases, this.wrapped, (String)key);
        }
    }

    //currently not a complete handling, but enough to fix the issues with mojarra
    private class DelegatingSet extends HashSet<NavigationCase>
    {
        private static final long serialVersionUID = -7040572530963900394L;

        private final ConfigurableNavigationHandler wrapped;
        private String navigationCaseKey;

        private DelegatingSet(Collection<? extends NavigationCase> c,
                              ConfigurableNavigationHandler wrapped,
                              String navigationCaseKey)
        {
            super(c);
            this.wrapped = wrapped;
            this.navigationCaseKey = navigationCaseKey;
        }

        @Override
        public boolean add(NavigationCase navigationCase)
        {
            Set<NavigationCase> navigationCases = this.wrapped.getNavigationCases().get(this.navigationCaseKey);

            if (navigationCases == null)
            {
                navigationCases = new HashSet<NavigationCase>();
                this.wrapped.getNavigationCases().put(this.navigationCaseKey, navigationCases);
            }

            return navigationCases.add(navigationCase);
        }
    }
}
{code}


was (Author: gpetracek):
workaround:

{code}
import javax.faces.application.ConfigurableNavigationHandler;
import javax.faces.application.NavigationCase;
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class EditableNavigationHandler extends ConfigurableNavigationHandler
{
    private final NavigationHandler wrapped;

    public EditableNavigationHandler(NavigationHandler wrapped)
    {
        this.wrapped = wrapped;
    }

    @Override
    public NavigationCase getNavigationCase(FacesContext facesContext, String fromAction, String outcome)
    {
        if (this.wrapped instanceof ConfigurableNavigationHandler)
        {
            return ((ConfigurableNavigationHandler)this.wrapped).getNavigationCase(facesContext, fromAction, outcome);
        }
        return null;
    }

    @Override
    public Map<String, Set<NavigationCase>> getNavigationCases()
    {
        if (this.wrapped instanceof ConfigurableNavigationHandler)
        {
            NavigationHandler navigationHandler = findInnermostHandler(this.wrapped);

            Map<String, Set<NavigationCase>> result;
            if (navigationHandler instanceof ConfigurableNavigationHandler)
            {
                result = new DelegatingMap((ConfigurableNavigationHandler)navigationHandler);
            }
            else
            {
                result = new HashMap<String, Set<NavigationCase>>();
            }

            result.putAll(((ConfigurableNavigationHandler)this.wrapped).getNavigationCases());
            return result;
        }
        return null;
    }

    private NavigationHandler findInnermostHandler(NavigationHandler wrapped)
    {
        for (Field field : wrapped.getClass().getDeclaredFields())
        {
            if (NavigationHandler.class.isAssignableFrom(field.getType()))
            {
                field.setAccessible(true);
                try
                {
                    NavigationHandler result = findInnermostHandler((NavigationHandler)field.get(wrapped));
                    if (result == null)
                    {
                        result = wrapped;
                    }
                    return result;
                }
                catch (IllegalAccessException e)
                {
                    throw new RuntimeException(e);
                }
            }
        }
        return wrapped;
    }

    @Override
    public void handleNavigation(FacesContext context, String fromAction, String outcome)
    {
        this.wrapped.handleNavigation(context, fromAction, outcome);
    }

    //currently not a complete handling, but enough to fix the issues with mojarra
    private class DelegatingMap extends HashMap<String, Set<NavigationCase>>
    {
        private static final long serialVersionUID = -955468874397821639L;
        private final ConfigurableNavigationHandler wrapped;

        private DelegatingMap(ConfigurableNavigationHandler wrapped)
        {
            this.wrapped = wrapped;
        }

        @Override
        public Set<NavigationCase> put(String key, Set<NavigationCase> value)
        {
            //delegate to the wrapped instance -> the innermost handler needs to receive it
            //(because mojarra uses ConfigurableNavigationHandler#getNavigationCases
            // to add cases for std. nav.rules from the outside)
            return this.wrapped.getNavigationCases().put(key, value);
        }

        @Override
        public Set<NavigationCase> get(Object key)
        {
            Set<NavigationCase> navigationCases = super.get(key);
            if (navigationCases == null)
            {
                navigationCases = new HashSet<NavigationCase>();
                put((String)key, navigationCases);
            }

            return new DelegatingSet(navigationCases, this.wrapped, (String)key);
        }
    }

    //currently not a complete handling, but enough to fix the issues with mojarra
    private class DelegatingSet extends HashSet<NavigationCase>
    {
        private static final long serialVersionUID = -7040572530963900394L;

        private final ConfigurableNavigationHandler wrapped;
        private String navigationCaseKey;

        private DelegatingSet(Collection<? extends NavigationCase> c,
                              ConfigurableNavigationHandler wrapped,
                              String navigationCaseKey)
        {
            super(c);
            this.wrapped = wrapped;
            this.navigationCaseKey = navigationCaseKey;
        }

        @Override
        public boolean add(NavigationCase navigationCase)
        {
            Set<NavigationCase> navigationCases = this.wrapped.getNavigationCases().get(this.navigationCaseKey);

            if (navigationCases == null)
            {
                navigationCases = new HashSet<NavigationCase>();
                this.wrapped.getNavigationCases().put(this.navigationCaseKey, navigationCases);
            }

            return navigationCases.add(navigationCase);
        }
    }
}
{code}

> support external handling of navigation-cases
> ---------------------------------------------
>
>                 Key: DELTASPIKE-471
>                 URL: https://issues.apache.org/jira/browse/DELTASPIKE-471
>             Project: DeltaSpike
>          Issue Type: Bug
>          Components: JSF-Module
>    Affects Versions: 0.5
>            Reporter: Gerhard Petracek
>            Assignee: Gerhard Petracek
>            Priority: Minor
>             Fix For: 0.6
>
>
> e.g. mojarra uses manual calls to ConfigurableNavigationHandler#getNavigationCases to add the std. nav. rules (from the outside). this approach isn't backward compatible, however, we have to improve NavigationCaseMapWrapper (currently such added cases are ignored).



--
This message was sent by Atlassian JIRA
(v6.1.4#6159)