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