001 /*--------------------------------------------------------------------------+
002 $Id: HTMLWriter.java 28096 2010-06-09 13:12:48Z hummelb $
003 | |
004 | Copyright 2005-2010 Technische Universitaet Muenchen |
005 | |
006 | Licensed under the Apache License, Version 2.0 (the "License"); |
007 | you may not use this file except in compliance with the License. |
008 | You may obtain a copy of the License at |
009 | |
010 | http://www.apache.org/licenses/LICENSE-2.0 |
011 | |
012 | Unless required by applicable law or agreed to in writing, software |
013 | distributed under the License is distributed on an "AS IS" BASIS, |
014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015 | See the License for the specific language governing permissions and |
016 | limitations under the License. |
017 +--------------------------------------------------------------------------*/
018 package edu.tum.cs.commons.html;
019
020 import java.io.File;
021 import java.io.IOException;
022 import java.io.OutputStream;
023 import java.io.OutputStreamWriter;
024 import java.io.PrintStream;
025 import java.io.PrintWriter;
026 import java.io.UnsupportedEncodingException;
027
028 import edu.tum.cs.commons.filesystem.FileSystemUtils;
029 import edu.tum.cs.commons.string.StringUtils;
030 import edu.tum.cs.commons.xml.IXMLResolver;
031 import edu.tum.cs.commons.xml.XMLWriter;
032
033 /**
034 * This class is used for writing HTML.
035 *
036 * @author Benjamin Hummel
037 * @author $Author: hummelb $
038 * @version $Rev: 28096 $
039 * @levd.rating GREEN Hash: 8D23F1A3EAAA692885E5A25667EF254D
040 */
041 public class HTMLWriter extends XMLWriter<EHTMLElement, EHTMLAttribute> {
042
043 /** The CSS manager class used. */
044 private final CSSManagerBase cssManager;
045
046 /**
047 * Creates a new writer for HTML documents.
048 *
049 * @param file
050 * the file to write to.
051 */
052 public HTMLWriter(File file, CSSManagerBase cssManager) throws IOException {
053 this(new PrintStream(file, FileSystemUtils.UTF8_ENCODING), cssManager);
054 }
055
056 /**
057 * Creates a new writer for HTML documents.
058 *
059 * @param stream
060 * the stream to print to.
061 */
062 public HTMLWriter(OutputStream stream, CSSManagerBase cssManager) {
063 super(new PrintWriter(wrapStream(stream)), new HTMLResolver());
064 this.cssManager = cssManager;
065 }
066
067 /**
068 * Helper method for {@link #HTMLWriter(OutputStream, CSSManagerBase)} to
069 * deal with the exception.
070 */
071 private static OutputStreamWriter wrapStream(OutputStream stream) {
072 try {
073 return new OutputStreamWriter(stream, FileSystemUtils.UTF8_ENCODING);
074 } catch (UnsupportedEncodingException e) {
075 throw new AssertionError("UTF-8 should be supported!");
076 }
077 }
078
079 /**
080 * Creates a new writer for HTML documents.
081 *
082 * @param writer
083 * the writer to print to.
084 */
085 public HTMLWriter(PrintWriter writer, CSSManagerBase cssManager) {
086 super(writer, new HTMLResolver());
087 this.cssManager = cssManager;
088 }
089
090 /**
091 * This adds a default header for HTML files consisting of the XML header
092 * and a DOCTYPE of the xhtml frameset DTD.
093 * <p>
094 * XML version is set to "1.0", encoding provided by a parameter, and doc
095 * type definition to XHTML 1.0 Frameset.
096 */
097 public void addStdHeader(String encoding) {
098 addHeader("1.0", encoding);
099 addPublicDocTypeDefintion(EHTMLElement.HTML,
100 "-//W3C//DTD XHTML 1.0 Frameset//EN",
101 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd");
102 }
103
104 /**
105 * This adds a default header for HTML files consisting of the XML header
106 * and a DOCTYPE of the xhtml frameset DTD.
107 * <p>
108 * XML version is set to "1.0", encoding to "UTF-8", and doc type definition
109 * to XHTML 1.0 Frameset.
110 */
111 public void addStdHeader() {
112 addStdHeader(FileSystemUtils.UTF8_ENCODING);
113 }
114
115 /**
116 * {@inheritDoc}
117 *
118 * Made this public here.
119 */
120 @Override
121 public void addRawString(String html) {
122 super.addRawString(html);
123 }
124
125 /**
126 * Adds a line separator with closing and open tag (see
127 * {@link #addNewLine()}.
128 */
129 public void addRawNewLine() {
130 addRawString(StringUtils.CR);
131 }
132
133 /**
134 * Adds an attribute to the currently open element but checks in addition if
135 * the attribute may be added at all.
136 *
137 * @throws HTMLWriterException
138 * if the attribute is not allowed for the current element.
139 */
140 @Override
141 public void addAttribute(EHTMLAttribute attribute, Object value) {
142 if (!getCurrentElement().allowsAttribute(attribute)) {
143 throw new HTMLWriterException("Attribute " + attribute
144 + " not allowed for element " + getCurrentElement());
145 }
146
147 if (attribute == EHTMLAttribute.STYLE
148 || attribute == EHTMLAttribute.CLASS) {
149 if (!(value instanceof CSSDeclarationBlock)) {
150 throw new HTMLWriterException(
151 "The argument for STYLE and CLASS attributes must be a "
152 + CSSDeclarationBlock.class.getSimpleName()
153 + "!");
154 }
155 }
156
157 if (attribute == EHTMLAttribute.STYLE) {
158 super.addAttribute(attribute, ((CSSDeclarationBlock) value)
159 .toInlineStyle());
160 } else if (attribute == EHTMLAttribute.CLASS) {
161 super.addAttribute(attribute, cssManager
162 .getCSSClassName((CSSDeclarationBlock) value));
163 } else {
164 super.addAttribute(attribute, value);
165 }
166 }
167
168 /** The resolver used for the {@link HTMLWriter}. */
169 public static class HTMLResolver implements
170 IXMLResolver<EHTMLElement, EHTMLAttribute> {
171
172 /** {@inheritDoc} */
173 public String resolveAttributeName(EHTMLAttribute attribute) {
174 return attribute.toString();
175 }
176
177 /** {@inheritDoc} */
178 public String resolveElementName(EHTMLElement element) {
179 return element.toString();
180 }
181
182 /** {@inheritDoc} */
183 public Class<EHTMLAttribute> getAttributeClass() {
184 return EHTMLAttribute.class;
185 }
186 }
187 }