001 // Copyright 2005 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.tapestry.portlet;
016
017 import java.io.IOException;
018 import java.io.PrintWriter;
019 import java.util.ArrayList;
020 import java.util.Date;
021 import java.util.List;
022
023 import org.apache.hivemind.ApplicationRuntimeException;
024 import org.apache.tapestry.IMarkupWriter;
025 import org.apache.tapestry.IPage;
026 import org.apache.tapestry.IRequestCycle;
027 import org.apache.tapestry.PageRedirectException;
028 import org.apache.tapestry.Tapestry;
029 import org.apache.tapestry.TapestryUtils;
030 import org.apache.tapestry.asset.AssetFactory;
031 import org.apache.tapestry.engine.EngineMessages;
032 import org.apache.tapestry.markup.MarkupWriterSource;
033 import org.apache.tapestry.util.ContentType;
034 import org.apache.tapestry.util.PageRenderSupportImpl;
035 import org.apache.tapestry.web.WebResponse;
036
037 /**
038 * The guts of rendering a page as a portlet response; used by
039 * {@link org.apache.tapestry.portlet.RenderService} and
040 * {@link org.apache.tapestry.portlet.PortletHomeService}.
041 *
042 * @author Howard M. Lewis Ship
043 * @since 4.0
044 */
045 public class PortletRendererImpl implements PortletRenderer
046 {
047 private WebResponse _response;
048
049 private MarkupWriterSource _markupWriterSource;
050
051 private AssetFactory _assetFactory;
052
053 private String _applicationId;
054
055 public void renderPage(IRequestCycle cycle, String pageName) throws IOException
056 {
057 try {
058 cycle.activate(pageName);
059
060 IPage page = cycle.getPage();
061
062 ContentType contentType = page.getResponseContentType();
063
064 PrintWriter printWriter = _response.getPrintWriter(contentType);
065
066 IMarkupWriter writer = _markupWriterSource.newMarkupWriter(printWriter, contentType);
067
068 String namespace = _response.getNamespace();
069
070 PageRenderSupportImpl support = new PageRenderSupportImpl(_assetFactory, namespace, null);
071
072 TapestryUtils.storePageRenderSupport(cycle, support);
073
074 IMarkupWriter nested = writer.getNestedWriter();
075
076 cycle.renderPage(nested);
077
078 String id = "Tapestry Portlet " + _applicationId + " " + namespace;
079
080 writer.comment("BEGIN " + id);
081 writer.comment("Page: " + page.getPageName());
082 writer.comment("Generated: " + new Date());
083 writer.comment("Framework version: " + Tapestry.VERSION);
084
085 support.writeBodyScript(writer, cycle);
086
087 nested.close();
088
089 support.writeInitializationScript(writer);
090
091 writer.comment("END " + id);
092
093 writer.close();
094
095 // TODO: Trap errors and do some error reporting here?
096 }
097 catch (PageRedirectException e) {
098 handlePageRedirectException(cycle, e);
099 }
100 }
101
102 protected void handlePageRedirectException(IRequestCycle cycle, PageRedirectException exception)
103 throws IOException
104 {
105 List pageNames = new ArrayList();
106
107 String pageName = exception.getTargetPageName();
108
109 while (true)
110 {
111 if (pageNames.contains(pageName))
112 {
113 pageNames.add(pageName);
114
115 throw new ApplicationRuntimeException(EngineMessages.validateCycle(pageNames));
116 }
117
118 // Record that this page has been a target.
119
120 pageNames.add(pageName);
121
122 try
123 {
124 // Attempt to activate the new page.
125
126 cycle.activate(pageName);
127
128 break;
129 }
130 catch (PageRedirectException secondRedirectException)
131 {
132 pageName = secondRedirectException.getTargetPageName();
133 }
134 }
135
136 renderPage(cycle, pageName);
137 }
138
139 public void setMarkupWriterSource(MarkupWriterSource markupWriterSource)
140 {
141 _markupWriterSource = markupWriterSource;
142 }
143
144 public void setResponse(WebResponse response)
145 {
146 _response = response;
147 }
148
149 public void setAssetFactory(AssetFactory assetFactory)
150 {
151 _assetFactory = assetFactory;
152 }
153
154 public void setApplicationId(String applicationId)
155 {
156 _applicationId = applicationId;
157 }
158 }