001 // Copyright Aug 2, 2006 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 package org.apache.tapestry.html;
015
016 import org.apache.hivemind.ApplicationRuntimeException;
017 import org.apache.tapestry.AbstractComponent;
018 import org.apache.tapestry.IAsset;
019 import org.apache.tapestry.IMarkupWriter;
020 import org.apache.tapestry.IRequestCycle;
021 import org.apache.tapestry.markup.MarkupWriterSource;
022 import org.apache.tapestry.util.ContentType;
023
024 import java.io.PrintWriter;
025 import java.io.StringWriter;
026
027 /**
028 * Works with the {@link Shell} component to define and append a
029 * relationship between documents (typically a stylesheet) to
030 * the HTML response.
031 *
032 * @author Andreas Andreou
033 * @since 4.1.1
034 */
035 public abstract class Relation extends AbstractComponent
036 {
037 /**
038 * {@inheritDoc}
039 */
040 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
041 {
042 if (!cycle.isRewinding())
043 {
044 Shell shell = Shell.get(cycle);
045
046 if (shell == null)
047 throw new ApplicationRuntimeException(
048 HTMLMessages.shellComponentRequired(),
049 this.getLocation(), null);
050
051 if (getUseBody() && getHref() == null)
052 {
053 renderStyleTag(shell, writer, cycle);
054 }
055 else
056 {
057 renderLinkTag(shell, writer, cycle);
058 }
059 }
060 }
061
062 protected void renderLinkTag(Shell shell, IMarkupWriter writer, IRequestCycle cycle)
063 {
064 Object href = getHref();
065 boolean ok = (href instanceof String) || (href instanceof IAsset);
066 if (!ok)
067 throw new ApplicationRuntimeException(HTMLMessages.stringOrIAssetExpected(), getLocation(), null);
068
069 String url;
070 if (href instanceof String)
071 {
072 url = (String) href;
073 }
074 else
075 {
076 url = ((IAsset)href).buildURL();
077 }
078
079 RelationBean bean = new RelationBean();
080 bean.setHref(url);
081 bean.setMedia(getMedia());
082 bean.setRel(getRel());
083 bean.setRev(getRev());
084 bean.setTitle(getTitle());
085 bean.setType(getType());
086 shell.addRelation(bean);
087 }
088
089 protected void renderStyleTag(Shell shell, IMarkupWriter writer, IRequestCycle cycle)
090 {
091 // see if nothing (or nowhere) to include
092 if (getBody() == null || writer.getContentType() == null)
093 {
094 return;
095 }
096
097 StringWriter sWriter = new StringWriter();
098 IMarkupWriter nested = getMarkupWriterSource().newMarkupWriter(new PrintWriter(sWriter),
099 new ContentType(writer.getContentType()));
100
101 nested.begin("style");
102 nested.attribute("type", "text/css");
103
104 if (getMedia()!=null)
105 nested.attribute("media", getMedia());
106 if (getTitle()!=null)
107 nested.attribute("title", getTitle());
108
109 renderBody(nested, cycle);
110 nested.close();
111
112 shell.includeAdditionalContent(sWriter.toString());
113 }
114
115 public abstract boolean getUseBody();
116
117 public abstract Object getHref();
118
119 public abstract String getRel();
120
121 public abstract String getRev();
122
123 public abstract String getType();
124
125 public abstract String getTitle();
126
127 public abstract String getMedia();
128
129 /* injected */
130 public abstract MarkupWriterSource getMarkupWriterSource();
131
132 }