001 // Copyright 2009, 2010, 2011 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry5.internal.services.ajax; 016 017 import org.apache.tapestry5.ajax.MultiZoneUpdate; 018 import org.apache.tapestry5.internal.services.AjaxPartialResponseRenderer; 019 import org.apache.tapestry5.ioc.internal.util.InternalUtils; 020 import org.apache.tapestry5.ioc.services.TypeCoercer; 021 import org.apache.tapestry5.runtime.RenderCommand; 022 import org.apache.tapestry5.services.ComponentEventResultProcessor; 023 import org.apache.tapestry5.services.ajax.AjaxResponseRenderer; 024 025 import java.io.IOException; 026 import java.util.Map; 027 028 /** 029 * Handler for {@link org.apache.tapestry5.ajax.MultiZoneUpdate} responses from a component event handler method. Works 030 * by adding {@link SingleZonePartialRendererFilter}s for each zone to the 031 * {@linkplain org.apache.tapestry5.internal.services.PageRenderQueue#addPartialMarkupRendererFilter(org.apache.tapestry5.services.PartialMarkupRendererFilter) 032 * filter stack}. Each zone writes its content as a string in the zones object of the reply, keyed on its id. 033 * JavaScript and CSS are collected for all zones rendered in the request (not for each individual zone). The final 034 * response will have some combination of "script", "scripts", "stylesheets", "content" (which is expected to be blank) 035 * and "zones". 036 * 037 * @since 5.1.0.1 038 * @deprecated Deprecated in 5.3 039 */ 040 public class MultiZoneUpdateEventResultProcessor implements ComponentEventResultProcessor<MultiZoneUpdate> 041 { 042 private final TypeCoercer typeCoercer; 043 044 private final AjaxResponseRenderer ajaxResponseRenderer; 045 046 private final AjaxPartialResponseRenderer partialRenderer; 047 048 public MultiZoneUpdateEventResultProcessor(TypeCoercer typeCoercer, AjaxResponseRenderer ajaxResponseRenderer, AjaxPartialResponseRenderer partialRenderer) 049 { 050 this.typeCoercer = typeCoercer; 051 this.ajaxResponseRenderer = ajaxResponseRenderer; 052 this.partialRenderer = partialRenderer; 053 } 054 055 public void processResultValue(final MultiZoneUpdate value) throws IOException 056 { 057 058 Map<String, Object> map = value.getZoneToRenderMap(); 059 060 for (String zoneId : map.keySet()) 061 { 062 Object provided = map.get(zoneId); 063 064 // The AjaxResponseRenderer will convert the object to a RenderCommand, but does nothing special if there's a failure 065 // (because the stack trace will clearly identify what's going on). We do the conversion here so that we can relate 066 // a failure to a zone id. It will just be a pass-thru on the second type coercion. 067 068 RenderCommand zoneRenderCommand = toRenderer(zoneId, provided); 069 070 ajaxResponseRenderer.addRender(zoneId, zoneRenderCommand); 071 } 072 073 partialRenderer.renderPartialPageMarkup(); 074 } 075 076 private RenderCommand toRenderer(String zoneId, Object provided) 077 { 078 try 079 { 080 return typeCoercer.coerce(provided, RenderCommand.class); 081 } catch (Exception ex) 082 { 083 throw new IllegalArgumentException(String.format("Failure converting renderer for zone '%s': %s", zoneId, 084 InternalUtils.toMessage(ex)), ex); 085 } 086 } 087 }