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