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