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