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