/*
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
 */
package org.apache.wiki;

import org.apache.log4j.Logger;
import org.apache.wiki.auth.NoSuchPrincipalException;
import org.apache.wiki.auth.UserManager;
import org.apache.wiki.auth.WikiPrincipal;
import org.apache.wiki.auth.permissions.AllPermission;
import org.apache.wiki.auth.user.UserDatabase;
import org.apache.wiki.ui.Command;
import org.apache.wiki.ui.CommandResolver;
import org.apache.wiki.ui.GroupCommand;
import org.apache.wiki.ui.Installer;
import org.apache.wiki.ui.PageCommand;
import org.apache.wiki.ui.WikiCommand;
import org.apache.wiki.util.TextUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.PageContext;
import java.security.Permission;
import java.security.Principal;
import java.util.HashMap;
import java.util.PropertyPermission;

/**
 *  <p>Provides state information throughout the processing of a page.  A WikiContext is born when the JSP pages that are the main entry
 *  points, are invoked.  The JSPWiki engine creates the new WikiContext, which basically holds information about the page, the
 *  handling engine, and in which context (view, edit, etc) the call was done.</p>
 *  <p>A WikiContext also provides request-specific variables, which can be used to communicate between plugins on the same page, or
 *  between different instances of the same plugin.  A WikiContext variable is valid until the processing of the page has ended.  For
 *  an example, please see the Counter plugin.</p>
 *  <p>When a WikiContext is created, it automatically associates a {@link WikiSession} object with the user's HttpSession. The
 *  WikiSession contains information about the user's authentication status, and is consulted by {@link #getCurrentUser()} object.</p>
 *  <p>Do not cache the page object that you get from the WikiContext; always use getPage()!</p>
 *
 *  @see org.apache.wiki.plugin.Counter
 */
public class WikiContext implements Cloneable, Command {

    private    Command m_command;

    private    WikiPage   m_page;
    private    WikiPage   m_realPage;
    private    WikiEngine m_engine;
    private    String     m_template = "default";

    private    HashMap<String,Object> m_variableMap = new HashMap<>();

    /** Stores the HttpServletRequest.  May be null, if the request did not come from a servlet. */
    protected HttpServletRequest m_request;

    private WikiSession m_session;

    public static final String ATTR_CONTEXT = "jspwiki.context";

    /** User is administering JSPWiki (Install, SecurityConfig). */
    public static final String INSTALL = WikiCommand.INSTALL.getRequestContext();

    /** The VIEW context - the user just wants to view the page contents. */
    public static final String VIEW = PageCommand.VIEW.getRequestContext();

    /** User wants to view or administer workflows. */
    public static final String WORKFLOW = WikiCommand.WORKFLOW.getRequestContext();

    /** The EDIT context - the user is editing the page. */
    public static final String EDIT = PageCommand.EDIT.getRequestContext();

    /** User is preparing for a login/authentication. */
    public static final String LOGIN = WikiCommand.LOGIN.getRequestContext();

    /** User is preparing to log out. */
    public static final String LOGOUT = WikiCommand.LOGOUT.getRequestContext();

    /** JSPWiki wants to display a message. */
    public static final String MESSAGE = WikiCommand.MESSAGE.getRequestContext();

    /** User is viewing a DIFF between the two versions of the page. */
    public static final String DIFF = PageCommand.DIFF.getRequestContext();

    /** User is viewing page history. */
    public static final String INFO = PageCommand.INFO.getRequestContext();

    /** User is previewing the changes he just made. */
    public static final String PREVIEW = PageCommand.PREVIEW.getRequestContext();

    /** User has an internal conflict, and does quite not know what to
        do. Please provide some counseling. */
    public static final String CONFLICT = PageCommand.CONFLICT.getRequestContext();

    /** An error has been encountered and the user needs to be informed. */
    public static final String ERROR = WikiCommand.ERROR.getRequestContext();

    /** User is uploading something. */
    public static final String UPLOAD = PageCommand.UPLOAD.getRequestContext();

    /** User is commenting something. */
    public static final String COMMENT = PageCommand.COMMENT.getRequestContext();

    /** User is searching for content. */
    public static final String FIND = WikiCommand.FIND.getRequestContext();

    /** User wishes to create a new group */
    public static final String CREATE_GROUP = WikiCommand.CREATE_GROUP.getRequestContext();

    /** User is deleting an existing group. */
    public static final String DELETE_GROUP = GroupCommand.DELETE_GROUP.getRequestContext();

    /** User is editing an existing group. */
    public static final String EDIT_GROUP = GroupCommand.EDIT_GROUP.getRequestContext();

    /** User is viewing an existing group */
    public static final String VIEW_GROUP = GroupCommand.VIEW_GROUP.getRequestContext();

    /** User is editing preferences */
    public static final String PREFS = WikiCommand.PREFS.getRequestContext();

    /** User is renaming a page. */
    public static final String RENAME = PageCommand.RENAME.getRequestContext();

    /** User is deleting a page or an attachment. */
    public static final String DELETE = PageCommand.DELETE.getRequestContext();

    /** User is downloading an attachment. */
    public static final String ATTACH = PageCommand.ATTACH.getRequestContext();

    /** RSS feed is being generated. */
    public static final String RSS = PageCommand.RSS.getRequestContext();

    /** This is not a JSPWiki context, use it to access static files. */
    public static final String NONE = PageCommand.NONE.getRequestContext();

    /** Same as NONE; this is just a clarification. */
    public static final String OTHER = PageCommand.OTHER.getRequestContext();

    /** User is doing administrative things. */
    public static final String ADMIN = WikiCommand.ADMIN.getRequestContext();

    private static final Logger log = Logger.getLogger( WikiContext.class );

    private static final Permission DUMMY_PERMISSION = new PropertyPermission( "os.name", "read" );

    /**
     *  Create a new WikiContext for the given WikiPage. Delegates to {@link #WikiContext(WikiEngine, HttpServletRequest, WikiPage)}.
     *
     *  @param engine The WikiEngine that is handling the request.
     *  @param page The WikiPage. If you want to create a WikiContext for an older version of a page, you must use this constructor.
     */
    public WikiContext( final WikiEngine engine, final WikiPage page )
    {
        this( engine, null, findCommand( engine, null, page ) );
    }

    /**
     * <p>
     * Creates a new WikiContext for the given WikiEngine, Command and HttpServletRequest.
     * </p>
     * <p>
     * This constructor will also look up the HttpSession associated with the request, and determine if a WikiSession object is present.
     * If not, a new one is created.
     * </p>
     * @param engine The WikiEngine that is handling the request
     * @param request The HttpServletRequest that should be associated with this context. This parameter may be <code>null</code>.
     * @param command the command
     * @throws IllegalArgumentException if <code>engine</code> or <code>command</code> are <code>null</code>
     */
    public WikiContext( final WikiEngine engine, final HttpServletRequest request, final Command command ) throws IllegalArgumentException {
        if ( engine == null || command == null ) {
            throw new IllegalArgumentException( "Parameter engine and command must not be null." );
        }

        m_engine = engine;
        m_request = request;
        m_session = WikiSession.getWikiSession( engine, request );
        m_command = command;

        // If PageCommand, get the WikiPage
        if( command instanceof PageCommand ) {
            m_page = ( WikiPage )command.getTarget();
        }

        // If page not supplied, default to front page to avoid NPEs
        if( m_page == null ) {
            m_page = m_engine.getPageManager().getPage( m_engine.getFrontPage() );

            // Front page does not exist?
            if( m_page == null ) {
                m_page = new WikiPage( m_engine, m_engine.getFrontPage() );
            }
        }

        m_realPage = m_page;

        // Special case: retarget any empty 'view' PageCommands to the front page
        if ( PageCommand.VIEW.equals( command ) && command.getTarget() == null ) {
            m_command = command.targetedCommand( m_page );
        }

        // Debugging...
        if( log.isDebugEnabled() ) {
            final HttpSession session = ( request == null ) ? null : request.getSession( false );
            final String sid = session == null ? "(null)" : session.getId();
            log.debug( "Creating WikiContext for session ID=" + sid + "; target=" + getName() );
        }

        // Figure out what template to use
        setDefaultTemplate( request );
    }

    /**
     * Creates a new WikiContext for the given WikiEngine, WikiPage and HttpServletRequest. This method simply looks up the appropriate
     * Command using {@link #findCommand(WikiEngine, HttpServletRequest, WikiPage)} and delegates to
     * {@link #WikiContext(WikiEngine, HttpServletRequest, Command)}.
     *
     * @param engine The WikiEngine that is handling the request
     * @param request The HttpServletRequest that should be associated with this context. This parameter may be <code>null</code>.
     * @param page The WikiPage. If you want to create a WikiContext for an older version of a page, you must supply this parameter
     */
    public WikiContext( final WikiEngine engine, final HttpServletRequest request, final WikiPage page ) {
        this( engine, request, findCommand( engine, request, page ) );
    }

    /**
     * {@inheritDoc}
     * @see org.apache.wiki.ui.Command#getContentTemplate()
     */
    @Override
	public String getContentTemplate()
    {
        return m_command.getContentTemplate();
    }

    /**
     * {@inheritDoc}
     * @see org.apache.wiki.ui.Command#getJSP()
     */
    @Override
	public String getJSP()
    {
        return m_command.getContentTemplate();
    }

    /**
     *  Sets a reference to the real page whose content is currently being rendered.
     *  <p>
     *  Sometimes you may want to render the page using some other page's context. In those cases, it is highly recommended that you set
     *  the setRealPage() to point at the real page you are rendering.  Please see InsertPageTag for an example.
     *  <p>
     *  Also, if your plugin e.g. does some variable setting, be aware that if it is embedded in the LeftMenu or some other page added
     *  with InsertPageTag, you should consider what you want to do - do you wish to really reference the "master" page or the included
     *  page.
     *
     *  @param page  The real page which is being rendered.
     *  @return The previous real page
     *  @since 2.3.14
     *  @see org.apache.wiki.tags.InsertPageTag
     */
    public WikiPage setRealPage( final WikiPage page ) {
        final WikiPage old = m_realPage;
        m_realPage = page;
        updateCommand( m_command.getRequestContext() );
        return old;
    }

    /**
     *  Gets a reference to the real page whose content is currently being rendered. If your plugin e.g. does some variable setting, be
     *  aware that if it is embedded in the LeftMenu or some other page added with InsertPageTag, you should consider what you want to
     *  do - do you wish to really reference the "master" page or the included page.
     *  <p>
     *  For example, in the default template, there is a page called "LeftMenu". Whenever you access a page, e.g. "Main", the master
     *  page will be Main, and that's what the getPage() will return - regardless of whether your plugin resides on the LeftMenu or on
     *  the Main page.  However, getRealPage() will return "LeftMenu".
     *
     *  @return A reference to the real page.
     *  @see org.apache.wiki.tags.InsertPageTag
     *  @see org.apache.wiki.parser.JSPWikiMarkupParser
     */
    public WikiPage getRealPage()
    {
        return m_realPage;
    }

    /**
     *  Figure out to which page we are really going to.  Considers special page names from the jspwiki.properties, and possible aliases.
     *  This method forwards requests to {@link org.apache.wiki.ui.CommandResolver#getSpecialPageReference(String)}.
     *  @return A complete URL to the new page to redirect to
     *  @since 2.2
     */
    public String getRedirectURL() {
        final String pagename = m_page.getName();
        String redirURL = m_engine.getCommandResolver().getSpecialPageReference( pagename );
        if( redirURL == null ) {
            final String alias = m_page.getAttribute( WikiPage.ALIAS );
            if( alias != null ) {
                redirURL = getViewURL( alias );
            } else {
                redirURL = m_page.getAttribute( WikiPage.REDIRECT );
            }
        }

        return redirURL;
    }

    /**
     *  Returns the handling engine.
     *
     *  @return The wikiengine owning this context.
     */
    public WikiEngine getEngine()
    {
        return m_engine;
    }

    /**
     *  Returns the page that is being handled.
     *
     *  @return the page which was fetched.
     */
    public WikiPage getPage()
    {
        return m_page;
    }

    /**
     *  Sets the page that is being handled.
     *
     *  @param page The wikipage
     *  @since 2.1.37.
     */
    public void setPage( final WikiPage page ) {
        m_page = page;
        updateCommand( m_command.getRequestContext() );
    }

    /**
     *  Returns the request context.
     *
     *  @return The name of the request context (e.g. VIEW).
     */
    @Override
	public String getRequestContext()
    {
        return m_command.getRequestContext();
    }

    /**
     *  Sets the request context.  See above for the different request contexts (VIEW, EDIT, etc.)
     *
     *  @param arg The request context (one of the predefined contexts.)
     */
    public void setRequestContext( final String arg )
    {
        updateCommand( arg );
    }

    /**
     * {@inheritDoc}
     * @see org.apache.wiki.ui.Command#getTarget()
     */
    @Override
	public Object getTarget()
    {
        return m_command.getTarget();
    }

    /**
     * {@inheritDoc}
     * @see org.apache.wiki.ui.Command#getURLPattern()
     */
    @Override
	public String getURLPattern()
    {
        return m_command.getURLPattern();
    }

    /**
     *  Gets a previously set variable.
     *
     *  @param key The variable name.
     *  @return The variable contents.
     */
    public Object getVariable( final String key )
    {
        return m_variableMap.get( key );
    }

    /**
     *  Sets a variable.  The variable is valid while the WikiContext is valid, i.e. while page processing continues.  The variable data
     *  is discarded once the page processing is finished.
     *
     *  @param key The variable name.
     *  @param data The variable value.
     */
    public void setVariable( final String key, final Object data ) {
        m_variableMap.put( key, data );
        updateCommand( m_command.getRequestContext() );
    }

    /**
     * This is just a simple helper method which will first check the context if there is already an override in place, and if there is not,
     * it will then check the given properties.
     *
     * @param key What key are we searching for?
     * @param defValue Default value for the boolean
     * @return {@code true} or {@code false}.
     */
    public boolean getBooleanWikiProperty( final String key, final boolean defValue ) {
        final Object bool = getVariable( key );
        if( bool != null ) {
            return TextUtil.isPositive( (String) bool );
        }

        return TextUtil.getBooleanProperty( getEngine().getWikiProperties(), key, defValue );
    }

    /**
     *  This method will safely return any HTTP parameters that might have been defined.  You should use this method instead
     *  of peeking directly into the result of getHttpRequest(), since this method is smart enough to do all of the right things,
     *  figure out UTF-8 encoded parameters, etc.
     *
     *  @since 2.0.13.
     *  @param paramName Parameter name to look for.
     *  @return HTTP parameter, or null, if no such parameter existed.
     */
    public String getHttpParameter( final String paramName ) {
        String result = null;
        if( m_request != null ) {
            result = m_request.getParameter( paramName );
        }

        return result;
    }

    /**
     *  If the request did originate from a HTTP request, then the HTTP request can be fetched here.  However, it the request
     *  did NOT originate from a HTTP request, then this method will return null, and YOU SHOULD CHECK FOR IT!
     *
     *  @return Null, if no HTTP request was done.
     *  @since 2.0.13.
     */
    public HttpServletRequest getHttpRequest()
    {
        return m_request;
    }

    /**
     *  Sets the template to be used for this request.
     *
     *  @param dir The template name
     *  @since 2.1.15.
     */
    public void setTemplate( final String dir )
    {
        m_template = dir;
    }

    /**
     * Returns the target of this wiki context: a page, group name or JSP. If the associated Command is a PageCommand, this method
     * returns the page's name. Otherwise, this method delegates to the associated Command's {@link org.apache.wiki.ui.Command#getName()}
     * method. Calling classes can rely on the results of this method for looking up canonically-correct page or group names. Because it
     * does not automatically assume that the wiki context is a PageCommand, calling this method is inherently safer than calling
     * {@code getPage().getName()}.
     *
     * @return the name of the target of this wiki context
     * @see org.apache.wiki.ui.PageCommand#getName()
     * @see org.apache.wiki.ui.GroupCommand#getName()
     */
    @Override
	public String getName() {
        if ( m_command instanceof PageCommand ) {
            return m_page != null ? m_page.getName() : "<no page>";
        }
        return m_command.getName();
    }

    /**
     *  Gets the template that is to be used throughout this request.
     *
     *  @since 2.1.15.
     *  @return template name
     */
    public String getTemplate()
    {
        return m_template;
    }

    /**
     *  Convenience method that gets the current user. Delegates the lookup to the WikiSession associated with this WikiContect.
     *  May return null, in case the current user has not yet been determined; or this is an internal system. If the WikiSession has not
     *  been set, <em>always</em> returns null.
     *
     *  @return The current user; or maybe null in case of internal calls.
     */
    public Principal getCurrentUser() {
        if (m_session == null) {
            // This shouldn't happen, really...
            return WikiPrincipal.GUEST;
        }
        return m_session.getUserPrincipal();
    }

    /**
     *  A shortcut to generate a VIEW url.
     *
     *  @param page The page to which to link.
     *  @return An URL to the page.  This honours the current absolute/relative setting.
     */
    public String getViewURL( final String page )
    {
        return getURL( VIEW, page, null );
    }

    /**
     *  Creates an URL for the given request context.
     *
     *  @param context e.g. WikiContext.EDIT
     *  @param page The page to which to link
     *  @return An URL to the page, honours the absolute/relative setting in jspwiki.properties
     */
    public String getURL( final String context, final String page ) {
        return getURL( context, page, null );
    }

    /**
     *  Returns an URL from a page. It this WikiContext instance was constructed with an actual HttpServletRequest, we will attempt to
     *  construct the URL using HttpUtil, which preserves the HTTPS portion if it was used.
     *
     *  @param context The request context (e.g. WikiContext.UPLOAD)
     *  @param page The page to which to link
     *  @param params A list of parameters, separated with "&amp;"
     *
     *  @return An URL to the given context and page.
     */
    public String getURL( final String context, final String page, final String params ) {
        final boolean absolute = "absolute".equals(m_engine.getVariableManager().getVariable( this, WikiEngine.PROP_REFSTYLE ));

        // FIXME: is rather slow
        return m_engine.getURL( context, page, params, absolute );
    }

    /**
     * Returns the Command associated with this WikiContext.
     *
     * @return the command
     */
    public Command getCommand()
    {
        return m_command;
    }

    /**
     *  Returns a shallow clone of the WikiContext.
     *
     *  @since 2.1.37.
     *  @return A shallow clone of the WikiContext
     */
    @Override
	public Object clone() {
        try {
            // super.clone() must always be called to make sure that inherited objects
            // get the right type
            final WikiContext copy = (WikiContext)super.clone();

            copy.m_engine = m_engine;
            copy.m_command = m_command;

            copy.m_template    = m_template;
            copy.m_variableMap = m_variableMap;
            copy.m_request     = m_request;
            copy.m_session     = m_session;
            copy.m_page        = m_page;
            copy.m_realPage    = m_realPage;
            return copy;
        } catch( final CloneNotSupportedException e ){} // Never happens

        return null;
    }

    /**
     *  Creates a deep clone of the WikiContext.  This is useful when you want to be sure that you don't accidentally mess with page
     *  attributes, etc.
     *
     *  @since  2.8.0
     *  @return A deep clone of the WikiContext.
     */
    @SuppressWarnings("unchecked")
    public WikiContext deepClone() {
        try {
            // super.clone() must always be called to make sure that inherited objects
            // get the right type
            final WikiContext copy = (WikiContext)super.clone();

            //  No need to deep clone these
            copy.m_engine  = m_engine;
            copy.m_command = m_command; // Static structure

            copy.m_template    = m_template;
            copy.m_variableMap = (HashMap<String,Object>)m_variableMap.clone();
            copy.m_request     = m_request;
            copy.m_session     = m_session;
            copy.m_page        = (WikiPage)m_page.clone();
            copy.m_realPage    = (WikiPage)m_realPage.clone();
            return copy;
        }
        catch( final CloneNotSupportedException e ){} // Never happens

        return null;
    }

    /**
     *  Returns the WikiSession associated with the context. This method is guaranteed to always return a valid WikiSession.
     *  If this context was constructed without an associated HttpServletRequest, it will return {@link WikiSession#guestSession(WikiEngine)}.
     *
     *  @return The WikiSession associate with this context.
     */
    public WikiSession getWikiSession()
    {
        return m_session;
    }

    /**
     *  This method can be used to find the WikiContext programmatically from a JSP PageContext. We check the request context.
     *  The wiki context, if it exists, is looked up using the key {@link #ATTR_CONTEXT}.
     *
     *  @since 2.4
     *  @param pageContext the JSP page context
     *  @return Current WikiContext, or null, of no context exists.
     */
    public static WikiContext findContext( final PageContext pageContext ) {
        final HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        return (WikiContext)request.getAttribute( ATTR_CONTEXT );
    }

    /**
     * Returns the permission required to successfully execute this context. For example, the a wiki context of VIEW for a certain page
     * means that the PagePermission "view" is required for the page. In some cases, no particular permission is required, in which case
     * a dummy permission will be returned ({@link java.util.PropertyPermission}<code> "os.name", "read"</code>). This method is guaranteed
     * to always return a valid, non-null permission.
     *
     * @return the permission
     * @since 2.4
     */
    @Override
	public Permission requiredPermission() {
        // This is a filthy rotten hack -- absolutely putrid
        if ( WikiCommand.INSTALL.equals( m_command ) ) {
            // See if admin users exists
            try {
                final UserManager userMgr = m_engine.getUserManager();
                final UserDatabase userDb = userMgr.getUserDatabase();
                userDb.findByLoginName( Installer.ADMIN_ID );
            } catch ( final NoSuchPrincipalException e ) {
                return DUMMY_PERMISSION;
            }
            return new AllPermission( m_engine.getApplicationName() );
        }

        // TODO: we should really break the contract so that this
        // method returns null, but until then we will use this hack
        if( m_command.requiredPermission() == null ) {
            return DUMMY_PERMISSION;
        }

        return m_command.requiredPermission();
    }

    /**
     * Associates a target with the current Command and returns the new targeted Command. If the Command associated with this
     * WikiContext is already "targeted", it is returned instead.
     *
     * @see org.apache.wiki.ui.Command#targetedCommand(java.lang.Object)
     *
     * {@inheritDoc}
     */
    @Override
	public Command targetedCommand( final Object target ) {
        if ( m_command.getTarget() == null ) {
            return m_command.targetedCommand( target );
        }
        return m_command;
    }

    /**
     *  Returns true, if the current user has administrative permissions (i.e. the omnipotent AllPermission).
     *
     *  @since 2.4.46
     *  @return true, if the user has all permissions.
     */
    public boolean hasAdminPermissions() {
        return m_engine.getAuthorizationManager().checkPermission( getWikiSession(), new AllPermission( m_engine.getApplicationName() ) );
    }

    /**
     * Figures out which template a new WikiContext should be using.
     * @param request the HTTP request
     */
    protected void setDefaultTemplate( final HttpServletRequest request ) {
        final String defaultTemplate = m_engine.getTemplateDir();

        //  Figure out which template we should be using for this page.
        String template = null;
        if ( request != null ) {
            template = request.getParameter( "skin" );

            if( template != null ) {
                template = template.replaceAll("\\p{Punct}", "");
            }
        }

        // If request doesn't supply the value, extract from wiki page
        if( template == null ) {
            final WikiPage page = getPage();
            if ( page != null ) {
                template = page.getAttribute( WikiEngine.PROP_TEMPLATEDIR );
            }

        }

        // If something over-wrote the default, set the new value.
        if ( template != null ) {
            setTemplate( template );
        } else {
            setTemplate( defaultTemplate );
        }
    }

    /**
     * Looks up and returns a PageCommand based on a supplied WikiPage and HTTP request. First, the appropriate Command is obtained by
     * examining the HTTP request; the default is {@link PageCommand#VIEW}. If the Command is a PageCommand (and it should be, in most
     * cases), a targeted Command is created using the (non-<code>null</code>) WikiPage as target.
     *
     * @param engine the wiki engine
     * @param request the HTTP request
     * @param page the wiki page
     * @return the correct command
     */
    protected static Command findCommand( final WikiEngine engine, final HttpServletRequest request, final WikiPage page ) {
        final String defaultContext = PageCommand.VIEW.getRequestContext();
        Command command = engine.getCommandResolver().findCommand( request, defaultContext );
        if ( command instanceof PageCommand && page != null ) {
            command = command.targetedCommand( page );
        }
        return command;
    }

    /**
     * Protected method that updates the internally cached Command. Will always be called when the page name, request context, or variable
     * changes.
     *
     * @param requestContext the desired request context
     * @since 2.4
     */
    protected void updateCommand( final String requestContext ) {
        if ( requestContext == null ) {
            m_command = PageCommand.NONE;
        } else {
            final CommandResolver resolver = m_engine.getCommandResolver();
            m_command = resolver.findCommand( m_request, requestContext );
        }

        if ( m_command instanceof PageCommand && m_page != null ) {
            m_command = m_command.targetedCommand( m_page );
        }
    }

}
