View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.tobago.internal.webapp;
21  
22  import org.apache.myfaces.tobago.component.Attributes;
23  import org.apache.myfaces.tobago.internal.util.FastStringWriter;
24  import org.apache.myfaces.tobago.internal.util.HtmlWriterUtils;
25  import org.apache.myfaces.tobago.internal.util.JsonWriterUtils;
26  import org.apache.myfaces.tobago.internal.util.WriterUtils;
27  import org.apache.myfaces.tobago.renderkit.css.Style;
28  import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
29  import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
30  import org.apache.myfaces.tobago.util.FacesVersion;
31  
32  import javax.faces.component.UIComponent;
33  import javax.faces.context.ResponseWriter;
34  import java.io.IOException;
35  import java.io.Writer;
36  import java.util.Arrays;
37  import java.util.Map;
38  
39  public class HtmlResponseWriter extends TobagoResponseWriterBase {
40  
41    private static final String HTML_DOCTYPE =
42        "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">";
43  
44    private final WriterUtils helper;
45    private FastStringWriter javascriptWriter;
46    private boolean javascriptMode;
47  
48    public HtmlResponseWriter(
49        Writer writer, String contentType, String characterEncoding) {
50      super(writer, contentType, characterEncoding);
51      if ("application/json".equals(contentType)) {
52        this.helper = new JsonWriterUtils(writer, characterEncoding);
53      } else {
54        this.helper = new HtmlWriterUtils(writer, characterEncoding);
55      }
56      this.javascriptWriter = new FastStringWriter();
57    }
58  
59    @Override
60    public void endJavascript() throws IOException {
61      javascriptMode = false;
62    }
63  
64    @Override
65    public void startJavascript() throws IOException {
66      javascriptMode = true;
67    }
68  
69    @Override
70    public void write(String string) throws IOException {
71      if (javascriptMode) {
72        writeJavascript(string);
73      } else {
74        writeInternal(getWriter(), string);
75      }
76    }
77  
78    @Override
79    public void writeJavascript(String script) throws IOException {
80      writeInternal(javascriptWriter, script);
81    }
82  
83    public String getJavascript() {
84      return javascriptWriter.toString();
85    }
86  
87    public final WriterUtils getHelper() {
88      return helper;
89    }
90  
91    public void writeText(final Object text, final String property)
92        throws IOException {
93      closeOpenTag();
94      final String value = findValue(text, property);
95      helper.writeText(value);
96    }
97  
98    public void writeText(final char[] text, final int offset, final int length)
99        throws IOException {
100     closeOpenTag();
101     helper.writeText(text, offset, length);
102   }
103 
104   @Override
105   public void write(final char[] cbuf, final int off, final int len) throws IOException {
106     // Related to http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-696
107     if (!FacesVersion.supports21() && Arrays.equals(cbuf, XML_VERSION_1_0_ENCODING_UTF_8_CHARS)) {
108       // drop
109     } else {
110       super.write(cbuf, off, len);
111     }
112   }
113 
114   @Override
115   protected final void closeEmptyTag() throws IOException {
116     getWriter().write("\n>");
117   }
118 
119   @Override
120   protected void writerAttributeValue(String value, boolean escape) throws IOException {
121     if (escape) {
122       helper.writeAttributeValue(value);
123     } else {
124       getWriter().write(value);
125     }
126   }
127 
128   public ResponseWriter cloneWithWriter(final Writer originalWriter) {
129     return new HtmlResponseWriter(
130         originalWriter, getContentType(), getCharacterEncoding());
131   }
132 
133   /**
134    * @deprecated
135    */
136   @Deprecated
137   public static Style ensureHtmlStyleMap(UIComponent component, Style styles) {
138     if (styles == null) {
139       styles = new Style();
140       ((Map<String, Object>) component.getAttributes()).put(Attributes.STYLE, styles);
141     }
142     return styles;
143   }
144 
145   @Override
146   public void startDocument() throws IOException {
147     getWriter().write(HTML_DOCTYPE);
148     getWriter().write('\n');
149     startElement(HtmlElements.HTML, null);
150   }
151 
152   @Override
153   public void endElement(String name) throws IOException {
154     if (name == HtmlElements.BODY) {
155       String javascript = getJavascript();
156       if (org.apache.commons.lang.StringUtils.isNotEmpty(javascript)) {
157         startElement(HtmlElements.SCRIPT, null);
158         writeAttribute(HtmlAttributes.TYPE, "text/javascript", false);
159         write(getJavascript());
160         super.endElement(HtmlElements.SCRIPT);
161       }
162     }
163     super.endElement(name);
164   }
165 
166   @Override
167   public void endDocument() throws IOException {
168 
169     endElement(HtmlElements.HTML);
170   }
171 }