    001/*
    002    Licensed to the Apache Software Foundation (ASF) under one
    003    or more contributor license agreements.  See the NOTICE file
    004    distributed with this work for additional information
    005    regarding copyright ownership.  The ASF licenses this file
    006    to you under the Apache License, Version 2.0 (the
    007    "License"); you may not use this file except in compliance
    008    with the License.  You may obtain a copy of the License at
    009
    010       http://www.apache.org/licenses/LICENSE-2.0
    011
    012    Unless required by applicable law or agreed to in writing,
    013    software distributed under the License is distributed on an
    014    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015    KIND, either express or implied.  See the License for the
    016    specific language governing permissions and limitations
    017    under the License.
    018 */
    019package org.apache.wiki.api.core;
    020
    021import javax.servlet.http.HttpServletRequest;
    022import javax.servlet.jsp.PageContext;
    023import java.security.Principal;
    024
    025
    026/**
    027 *  <p>Provides state information throughout the processing of a page.  A Context is born when the JSP pages that are the main entry
    028 *  points, are invoked.  The JSPWiki engine creates the new Context, which basically holds information about the page, the
    029 *  handling engine, and in which context (view, edit, etc) the call was done.</p>
    030 *  <p>A Context also provides request-specific variables, which can be used to communicate between plugins on the same page, or
    031 *  between different instances of the same plugin. A Context variable is valid until the processing of the WikiPage has ended. For
    032 *  an example, please see the Counter plugin.</p>
    033 *  <p>When a Context is created, it automatically associates a {@link Session} object with the user's
    034 *  HttpSession. The Session contains information about the user's authentication status, and is consulted by {@link #getCurrentUser()}
    035 *  object.</p>
    036 *  <p>Do not cache the WikiPage object that you get from the WikiContext; always use getPage()!</p>
    037 *
    038 *  @see {@code org.apache.wiki.plugin.Counter}
    039 */
    040public interface Context extends Cloneable, Command {
    041
    042    String ATTR_CONTEXT = "jspwiki.context";
    043
    044    /**
    045     *  Variable name which tells whether plugins should be executed or not. Value can be either {@code Boolean.TRUE} or
    046     *  {@code Boolean.FALSE}. While not set its value is {@code null}.
    047     */
    048    String VAR_EXECUTE_PLUGINS = "_PluginContent.execute";
    049
    050    /** Name of the variable which is set to Boolean.TRUE or Boolean.FALSE depending on whether WYSIWYG is currently in effect. */
    051    String VAR_WYSIWYG_EDITOR_MODE = "WYSIWYG_EDITOR_MODE";
    052
    053    /**
    054     *  Returns the WikiPage that is being handled.
    055     *
    056     *  @return the WikiPage which was fetched.
    057     */
    058    Page getPage();
    059
    060    /**
    061     *  Sets the WikiPage that is being handled.
    062     *
    063     *  @param wikiPage The wikipage
    064     *  @since 2.1.37.
    065     */
    066    void setPage( Page wikiPage );
    067
    068    /**
    069     *  Gets a reference to the real WikiPage whose content is currently being rendered. If your plugin e.g. does some variable setting, be
    070     *  aware that if it is embedded in the LeftMenu or some other WikiPage added with InsertPageTag, you should consider what you want to
    071     *  do - do you wish to really reference the "master" WikiPage or the included page.
    072     *  <p>
    073     *  For example, in the default template, there is a WikiPage called "LeftMenu". Whenever you access a page, e.g. "Main", the master
    074     *  WikiPage will be Main, and that's what the getPage() will return - regardless of whether your plugin resides on the LeftMenu or on
    075     *  the Main page.  However, getRealPage() will return "LeftMenu".
    076     *
    077     *  @return A reference to the real page.
    078     *  @see {@code org.apache.wiki.tags.InsertPageTag}
    079     *  @see {@code org.apache.wiki.parser.JSPWikiMarkupParser}
    080     */
    081    Page getRealPage();
    082
    083    /**
    084     *  Sets a reference to the real WikiPage whose content is currently being rendered.
    085     *  <p>
    086     *  Sometimes you may want to render the WikiPage using some other page's context. In those cases, it is highly recommended that you set
    087     *  the setRealPage() to point at the real WikiPage you are rendering.  Please see InsertPageTag for an example.
    088     *  <p>
    089     *  Also, if your plugin e.g. does some variable setting, be aware that if it is embedded in the LeftMenu or some other WikiPage added
    090     *  with InsertPageTag, you should consider what you want to do - do you wish to really reference the "master" WikiPage or the included
    091     *  page.
    092     *
    093     *  @param wikiPage  The real WikiPage which is being rendered.
    094     *  @return The previous real page
    095     *  @since 2.3.14
    096     *  @see {@code org.apache.wiki.tags.InsertPageTag}
    097     */
    098    Page setRealPage( Page wikiPage );
    099
    100    /**
    101     *  Returns the handling engine.
    102     *
    103     *  @return The wikiengine owning this context.
    104     */
    105    Engine getEngine();
    106
    107    /**
    108     *  Sets the request context.  See above for the different request contexts (VIEW, EDIT, etc.)
    109     *
    110     *  @param context The request context (one of the predefined contexts.)
    111     */
    112    void setRequestContext( String context );
    113
    114    /**
    115     *  Gets a previously set variable.
    116     *
    117     *  @param key The variable name.
    118     *  @return The variable contents.
    119     */
    120    < T > T getVariable( String key );
    121
    122    /**
    123     *  Sets a variable.  The variable is valid while the WikiContext is valid, i.e. while WikiPage processing continues.  The variable data
    124     *  is discarded once the WikiPage processing is finished.
    125     *
    126     *  @param key The variable name.
    127     *  @param data The variable value.
    128     */
    129    void setVariable( String key, Object data );
    130
    131    /**
    132     * 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,
    133     * it will then check the given properties.
    134     *
    135     * @param key What key are we searching for?
    136     * @param defValue Default value for the boolean
    137     * @return {@code true} or {@code false}.
    138     */
    139    boolean getBooleanWikiProperty( String key, boolean defValue );
    140
    141    /**
    142     *  This method will safely return any HTTP parameters that might have been defined.  You should use this method instead
    143     *  of peeking directly into the result of getHttpRequest(), since this method is smart enough to do all the right things,
    144     *  figure out UTF-8 encoded parameters, etc.
    145     *
    146     *  @since 2.0.13.
    147     *  @param paramName Parameter name to look for.
    148     *  @return HTTP parameter, or null, if no such parameter existed.
    149     */
    150    String getHttpParameter( String paramName );
    151
    152    /**
    153     *  If the request did originate from an HTTP request, then the HTTP request can be fetched here.  However, if the request
    154     *  did NOT originate from an HTTP request, then this method will return null, and YOU SHOULD CHECK FOR IT!
    155     *
    156     *  @return Null, if no HTTP request was done.
    157     *  @since 2.0.13.
    158     */
    159    HttpServletRequest getHttpRequest();
    160
    161    /**
    162     *  Sets the template to be used for this request.
    163     *
    164     *  @param dir The template name
    165     *  @since 2.1.15.
    166     */
    167    void setTemplate( String dir );
    168
    169    /**
    170     *  Gets the template that is to be used throughout this request.
    171     *
    172     *  @since 2.1.15.
    173     *  @return template name
    174     */
    175    String getTemplate();
    176
    177    /**
    178     *  Returns the Session associated with the context. This method is guaranteed to always return a valid Session.
    179     *  If this context was constructed without an associated HttpServletRequest, it will return a guest session.
    180     *
    181     *  @return The Session associate with this context.
    182     */
    183    Session getWikiSession();
    184
    185    /**
    186     *  Convenience method that gets the current user. Delegates the lookup to the Session associated with this Context.
    187     *  May return null, in case the current user has not yet been determined; or this is an internal system. If the Session has not
    188     *  been set, <em>always</em> returns null.
    189     *
    190     *  @return The current user; or maybe null in case of internal calls.
    191     */
    192    Principal getCurrentUser();
    193
    194    /**
    195     *  Returns true, if the current user has administrative permissions (i.e. the omnipotent AllPermission).
    196     *
    197     *  @since 2.4.46
    198     *  @return true, if the user has all permissions.
    199     */
    200    boolean hasAdminPermissions();
    201
    202    /**
    203     *  A shortcut to generate a VIEW url.
    204     *
    205     *  @param WikiPage The WikiPage to which to link.
    206     *  @return A URL to the page.  This honours the current absolute/relative setting.
    207     */
    208    String getViewURL( String WikiPage );
    209
    210    /**
    211     *  Figure out to which WikiPage we are really going to.  Considers special WikiPage names from the jspwiki.properties, and possible aliases.
    212     *
    213     *  @return A complete URL to the new WikiPage to redirect to
    214     *  @since 2.2
    215     */
    216    String getRedirectURL();
    217
    218    /**
    219     * Returns the Command associated with this Context.
    220     *
    221     * @return the command
    222     */
    223    Command getCommand();
    224
    225    /**
    226     *  Creates a URL for the given request context.
    227     *
    228     *  @param context e.g. WikiContext.EDIT
    229     *  @param page The WikiPage to which to link
    230     *  @return A URL to the page.
    231     */
    232    default String getURL( final String context, final String page ) {
    233        return getURL( context, page, null );
    234    }
    235
    236    /**
    237     *  Returns a URL from a page. It this Context instance was constructed with an actual HttpServletRequest, we will attempt to
    238     *  construct the URL using HttpUtil, which preserves the HTTPS portion if it was used.
    239     *
    240     *  @param context The request context (e.g. WikiContext.UPLOAD)
    241     *  @param page The WikiPage to which to link
    242     *  @param params A list of parameters, separated with "&amp;"
    243     *
    244     *  @return A URL to the given context and page.
    245     */
    246    default String getURL( final String context, final String page, final String params ) {
    247        // FIXME: is rather slow
    248        return getEngine().getURL( context, page, params );
    249    }
    250
    251    /** {@inheritDoc} */
    252    Context clone();
    253
    254    /**
    255     *  Creates a deep clone of the Context. This is useful when you want to be sure that you don't accidentally mess with page
    256     *  attributes, etc.
    257     *
    258     *  @since  2.8.0
    259     *  @return A deep clone of the Context.
    260     */
    261    Context deepClone();
    262
    263    /**
    264     *  This method can be used to find the WikiContext programmatically from a JSP PageContext. We check the request context.
    265     *  The wiki context, if it exists, is looked up using the key {@link #ATTR_CONTEXT}.
    266     *
    267     *  @since 2.4
    268     *  @param pageContext the JSP page context
    269     *  @return Current WikiContext, or null, of no context exists.
    270     */
    271    static Context findContext( final PageContext pageContext ) {
    272        final HttpServletRequest request = ( HttpServletRequest )pageContext.getRequest();
    273        return ( Context )request.getAttribute( ATTR_CONTEXT );
    274    }
    275
    276}