001 // Copyright 2004, 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.html;
016
017 import java.util.Date;
018 import java.util.Iterator;
019
020 import org.apache.hivemind.HiveMind;
021 import org.apache.tapestry.AbstractComponent;
022 import org.apache.tapestry.IAsset;
023 import org.apache.tapestry.IMarkupWriter;
024 import org.apache.tapestry.IPage;
025 import org.apache.tapestry.IRender;
026 import org.apache.tapestry.IRequestCycle;
027 import org.apache.tapestry.Tapestry;
028 import org.apache.tapestry.coerce.ValueConverter;
029 import org.apache.tapestry.engine.IEngineService;
030 import org.apache.tapestry.engine.ILink;
031 import org.apache.tapestry.spec.IApplicationSpecification;
032
033 /**
034 * Component for creating a standard 'shell' for a page, which comprises the <html> and
035 * <head> portions of the page. [ <a
036 * href="../../../../../ComponentReference/Shell.html">Component Reference </a>]
037 * <p>
038 * Specifically does <em>not</em> provide a <body> tag, that is usually accomplished using a
039 * {@link Body} component.
040 *
041 * @author Howard Lewis Ship
042 */
043
044 public abstract class Shell extends AbstractComponent
045 {
046 private static final String GENERATOR_CONTENT = "Tapestry Application Framework, version "
047 + Tapestry.VERSION;
048
049 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
050 {
051 long startTime = 0;
052
053 boolean rewinding = cycle.isRewinding();
054
055 if (!rewinding)
056 {
057 startTime = System.currentTimeMillis();
058
059 writeDocType(writer, cycle);
060
061 IPage page = getPage();
062
063 writer.comment("Application: " + getApplicationSpecification().getName());
064
065 writer.comment("Page: " + page.getPageName());
066 writer.comment("Generated: " + new Date());
067
068 writer.begin("html");
069 writer.println();
070 writer.begin("head");
071 writer.println();
072
073 writeMetaTag(writer, "name", "generator", GENERATOR_CONTENT);
074
075 if (getRenderContentType())
076 writeMetaTag(writer, "http-equiv", "Content-Type", writer.getContentType());
077
078 if (getRenderBaseTag())
079 getBaseTagWriter().render(writer, cycle);
080
081 writer.begin("title");
082
083 writer.print(getTitle(), getRaw());
084 writer.end(); // title
085 writer.println();
086
087 IRender delegate = getDelegate();
088
089 if (delegate != null)
090 delegate.render(writer, cycle);
091
092 IRender ajaxDelegate = getAjaxDelegate();
093
094 if (isAjaxEnabled() && ajaxDelegate != null)
095 ajaxDelegate.render(writer, cycle);
096
097 IAsset stylesheet = getStylesheet();
098
099 if (stylesheet != null)
100 writeStylesheetLink(writer, cycle, stylesheet);
101
102 Iterator i = (Iterator) getValueConverter().coerceValue(
103 getStylesheets(),
104 Iterator.class);
105
106 while (i.hasNext())
107 {
108 stylesheet = (IAsset) i.next();
109
110 writeStylesheetLink(writer, cycle, stylesheet);
111 }
112
113 writeRefresh(writer, cycle);
114
115 writer.end(); // head
116 }
117
118 // Render the body, the actual page content
119
120 renderBody(writer, cycle);
121
122 if (!rewinding)
123 {
124 writer.end(); // html
125 writer.println();
126
127 long endTime = System.currentTimeMillis();
128
129 writer.comment("Render time: ~ " + (endTime - startTime) + " ms");
130 }
131
132 }
133
134 private void writeDocType(IMarkupWriter writer, IRequestCycle cycle)
135 {
136 // This is the real code
137 String doctype = getDoctype();
138 if (HiveMind.isNonBlank(doctype))
139 {
140 writer.printRaw("<!DOCTYPE " + doctype + ">");
141 writer.println();
142 }
143 }
144
145 private void writeStylesheetLink(IMarkupWriter writer, IRequestCycle cycle, IAsset stylesheet)
146 {
147 writer.beginEmpty("link");
148 writer.attribute("rel", "stylesheet");
149 writer.attribute("type", "text/css");
150 writer.attribute("href", stylesheet.buildURL());
151 writer.println();
152 }
153
154 private void writeRefresh(IMarkupWriter writer, IRequestCycle cycle)
155 {
156 int refresh = getRefresh();
157
158 if (refresh <= 0)
159 return;
160
161 // Here comes the tricky part ... have to assemble a complete URL
162 // for the current page.
163
164 IEngineService pageService = getPageService();
165 String pageName = getPage().getPageName();
166
167 ILink link = pageService.getLink(false, pageName);
168
169 StringBuffer buffer = new StringBuffer();
170 buffer.append(refresh);
171 buffer.append("; URL=");
172 buffer.append(link.getAbsoluteURL());
173
174 writeMetaTag(writer, "http-equiv", "Refresh", buffer.toString());
175 }
176
177 private void writeMetaTag(IMarkupWriter writer, String key, String value, String content)
178 {
179 writer.beginEmpty("meta");
180 writer.attribute(key, value);
181 writer.attribute("content", content);
182 writer.println();
183 }
184
185 public abstract boolean isAjaxEnabled();
186
187 public abstract IRender getAjaxDelegate();
188
189 public abstract IRender getDelegate();
190
191 public abstract int getRefresh();
192
193 public abstract IAsset getStylesheet();
194
195 public abstract Object getStylesheets();
196
197 public abstract String getTitle();
198
199 public abstract String getDoctype();
200
201 public abstract boolean getRenderContentType();
202
203 /** @since 4.0 */
204 public abstract ValueConverter getValueConverter();
205
206 /** @since 4.0 */
207
208 public abstract IEngineService getPageService();
209
210 /** @since 4.0 */
211
212 public abstract IApplicationSpecification getApplicationSpecification();
213
214 /** @since 4.0 */
215
216 public abstract IRender getBaseTagWriter();
217
218 /** @since 4.0.1 */
219
220 public abstract boolean getRenderBaseTag();
221
222 /** @since 4.0.3 */
223
224 public abstract boolean getRaw();
225
226 }