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.forms;
020
021import org.apache.logging.log4j.LogManager;
022import org.apache.logging.log4j.Logger;
023import org.apache.wiki.api.core.Context;
024import org.apache.wiki.api.core.ContextEnum;
025import org.apache.wiki.api.exceptions.PluginException;
026import org.apache.wiki.api.plugin.Plugin;
027import org.apache.wiki.preferences.Preferences;
028
029import java.text.MessageFormat;
030import java.util.Map;
031import java.util.ResourceBundle;
032
033/**
034 *  Opens a WikiForm.
035 *
036 * Builds the HTML code for opening a FORM.
037 *
038 * <p>Since we're only providing an opening FORM tag, we can't use
039 * the ECS utilities.
040 *
041 * A Form plugin line that produces one looks like this:
042 * <p><pre>
043 *   [{FormOpen name='formname' handler='pluginname'
044 *          submit='submitservlet'
045 *          show='always'
046 *   }]
047 * </pre>
048 *
049 * <p>Mandatory parameters:
050 * <br>The <i>name</i> field identifies this particular form to the
051 * Form plugin across pages.
052 * <br>The <i>handler</i> field is a WikiPlugin name; it will be
053 * invoked with the form field values.
054 *
055 * <p>Optional parameters:
056 * <p>The submitservlet is the name of a JSP/servlet capable of
057 * handling the input from this form. It is optional; the default
058 * value is the current page (which can handle the input by using
059 * this Plugin.)
060 *
061 * <p>The <i>hide</i> parameter affects the visibility of this
062 * form. If left out, the form is always shown. If set to
063 * 'onsuccess', the form is not shown if it was submitted
064 * successfully. (Note that a reload of the page would cause the
065 * context to reset, and the form would be shown again. This may
066 * be a useless option.)
067 *
068 */
069public class FormOpen extends FormElement {
070
071    private static final Logger log = LogManager.getLogger( FormOpen.class );
072
073    /** Parameter name for setting the method (GET or POST).  Value is <tt>{@value}</tt>. */
074    public static final String PARAM_METHOD = "method";
075
076    /**
077     *  {@inheritDoc}
078     */
079    @Override
080    public String execute( final Context ctx, final Map< String, String > params ) throws PluginException {
081        final ResourceBundle rb = Preferences.getBundle( ctx, Plugin.CORE_PLUGINS_RESOURCEBUNDLE );
082        final String formName = params.get( PARAM_FORM );
083        if( formName == null ) {
084            throw new PluginException( MessageFormat.format( rb.getString( "formopen.missingparam" ), PARAM_FORM ) );
085        }
086        final String hide     = params.get( PARAM_HIDEFORM );
087        final String sourcePage = ctx.getPage().getName();
088        String submitServlet = params.get( PARAM_SUBMITHANDLER );
089        if( submitServlet == null )
090            submitServlet = ctx.getURL( ContextEnum.PAGE_VIEW.getRequestContext(), sourcePage );
091
092        String method = params.get( PARAM_METHOD );
093        if( method == null ) method="post";
094
095        if( !( method.equalsIgnoreCase( "get" ) || method.equalsIgnoreCase( "post" ) ) ) {
096            throw new PluginException( rb.getString( "formopen.postorgetonly" ) );
097        }
098
099        FormInfo info = getFormInfo( ctx );
100        if( info != null ) {
101            // Previous information may be the result of submitting
102            // this form, or of a FormSet plugin, or both. If it
103            // exists and is for this form, fine.
104            if( formName.equals( info.getName() ) ) {
105                log.debug( "Previous FormInfo for this form was found in context." );
106                // If the FormInfo exists, and if we're supposed to display on error only, we need to exit now.
107                if( HIDE_SUCCESS.equals( hide ) && info.getStatus() == FormInfo.EXECUTED ) {
108                    info.setHide( true );
109                    return "<p>" + rb.getString( "formopen.noneedtoshow" ) + "</p>";
110                }
111            } else {
112                // This would mean that a new form was started without closing an old one.  Get rid of the garbage.
113                info = new FormInfo();
114            }
115        } else {
116            // No previous FormInfo available; store now, so it'll be available for upcoming Form input elements.
117            info = new FormInfo();
118            storeFormInfo( ctx, info );
119        }
120
121        info.setName( formName );
122        info.setAction( submitServlet );
123
124        return "<div class=\"wikiform\">\n" +
125                  "<form action=\"" + submitServlet + "\" name=\"" + formName + "\" " +
126                        "accept-charset=\"" + ctx.getEngine().getContentEncoding() + "\" " +
127                        "method=\"" + method + "\" enctype=\"application/x-www-form-urlencoded\">\n" +
128                  "  <input type=\"hidden\" name=\"" + PARAM_FORMNAMEHIDDEN + "\" value=\"" + formName + "\"/>\n";
129    }
130
131}