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     */
019    
020    package org.apache.wiki.forms;
021    
022    import org.apache.wiki.WikiContext;
023    import org.apache.wiki.api.engine.PluginManager;
024    import org.apache.wiki.api.exceptions.PluginException;
025    import org.apache.wiki.api.plugin.WikiPlugin;
026    import org.apache.wiki.plugin.DefaultPluginManager;
027    import org.apache.wiki.preferences.Preferences;
028    import org.apache.wiki.util.FormUtil;
029    
030    import java.text.MessageFormat;
031    import java.util.Map;
032    import java.util.ResourceBundle;
033    
034    /**
035     */
036    public class FormOutput
037            extends FormElement
038    {
039        /**
040         * Executes the FormHandler specified in a Form 'output' plugin,
041         * using entries provided in the HttpRequest as FormHandler
042         * parameters.
043         * <p>
044         * If the parameter 'populate' was given, the WikiPlugin it names
045         * is used to get default values. (It probably makes a lot of
046         * sense for this to be the same plugin as the handler.) 
047         * Information for the populator can be given with the FormSet
048         * plugin. If 'populate' is not specified, the form is not
049         * displayed.
050         * <p>
051         * Should there be no HTTP request associated with this request,
052         * the method will return immediately with an empty string.
053         * 
054         * @param ctx {@inheritDoc}
055         * @param params {@inheritDoc}
056         * @return {@inheritDoc}
057         */
058        public String execute( WikiContext ctx, Map< String, String > params )
059            throws PluginException
060        {
061            //
062            //  If there is no HTTP request, returns immediately.
063            //
064            if( ctx.getHttpRequest() == null )
065            {
066                return "";
067            }
068            ResourceBundle rb = Preferences.getBundle( ctx, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
069            
070            // If we are NOT here due to this form being submitted, we do nothing.
071            // The submitted form MUST have parameter 'formname' equal to the name
072            // parameter of this Form plugin.
073    
074            String formName   = params.get( PARAM_FORM );
075            String submitForm = ctx.getHttpParameter( PARAM_FORMNAMEHIDDEN );
076            String populator  = params.get( PARAM_POPULATE );
077    
078            if( submitForm == null || formName == null || 
079                !formName.equals( submitForm ) )
080            {
081                // No submitForm -> this was not a submission from the
082                // generated form.  If populate is specified, we'll go
083                // ahead and let the handler (populator) put stuff into
084                // the context, otherwise we'll just hide.
085                if( populator == null || !PARAM_HANDLER.equals( populator ) )
086                    return "";
087                // If population was allowed, we should first  
088            }
089    
090            String handler = params.get( PARAM_HANDLER );
091            if( handler == null || handler.length() == 0 )
092            {
093                // Need to print out an error here as this form is misconfigured
094                return "<p class=\"error\">" + MessageFormat.format( rb.getString( "formoutput.missingargument" ), PARAM_HANDLER ) + "</p>";
095            }
096    
097            String sourcePage = ctx.getPage().getName();
098            String submitServlet = ctx.getURL( WikiContext.VIEW, sourcePage );
099    
100            // If there is previous FormInfo available - say, from a
101            // FormSet plugin - use it.
102            FormInfo info = getFormInfo( ctx );
103            if( info == null )
104            {
105                // Reconstruct the form info from post data
106                info = new FormInfo();
107                info.setName( formName );
108            }
109            // Force override of handler and submit.
110            info.setHandler( handler );
111            info.setAction( submitServlet );
112    
113            // Sift out all extra parameters, leaving only those submitted
114            // in the HTML FORM.
115            Map< String, String > handlerParams = FormUtil.requestToMap( ctx.getHttpRequest(), 
116                                                                         HANDLERPARAM_PREFIX );
117            // Previous submission info may be available from FormSet
118            // plugin - add, don't replace.
119            info.addSubmission( handlerParams );
120    
121            // Pass the _body parameter from FormOutput on to the handler
122            info.getSubmission().put( DefaultPluginManager.PARAM_BODY, 
123                                      params.get(DefaultPluginManager.PARAM_BODY)); 
124    
125            String handlerOutput = null;
126            String error = null;
127            try
128            {
129                // The plugin _can_ modify the parameters, so we make sure
130                // they stay with us.
131                PluginManager pm = ctx.getEngine().getPluginManager();
132                handlerOutput = pm.execute( ctx, handler, info.getSubmission() );
133                info.setResult( handlerOutput );
134                info.setStatus( FormInfo.EXECUTED );
135            }
136            catch( PluginException pe )
137            {
138                error = "<p class=\"error\">" + pe.getMessage() + "</p>";
139                info.setError( error );
140                info.setStatus( FormInfo.ERROR );
141            }
142    
143            // We store the forminfo, so following Form plugin invocations on this
144            // page can decide what to do based on its values.
145            storeFormInfo( ctx, info );
146    
147            if( error != null )
148                return error;
149    
150            return handlerOutput != null ? handlerOutput : "";
151        }
152    
153    }