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.webapp;
21  
22  import org.apache.myfaces.tobago.ajax.AjaxUtils;
23  import org.apache.myfaces.tobago.renderkit.css.Classes;
24  import org.apache.myfaces.tobago.renderkit.css.Style;
25  import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
26  import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
27  import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
28  
29  import javax.faces.component.UIComponent;
30  import javax.faces.context.FacesContext;
31  import javax.faces.context.ResponseWriter;
32  import java.io.IOException;
33  import java.io.Writer;
34  
35  /**
36   * This provides an alternative ResponseWriter interfaces, which allows optimizations.
37   * E. g. some attributes needed to to be escaped.
38   * <p/>
39   */
40  public abstract class TobagoResponseWriter extends ResponseWriter {
41  
42    // same as in ResponseWriter
43  
44    @Override
45    public abstract void startElement(String name, UIComponent component) throws IOException;
46  
47    /**
48     * @deprecated Use {@link #startElement(String, UIComponent) startElement(name, null)} instead.
49     */
50    @Deprecated
51    public void startElement(final String name) throws IOException {
52      startElement(name, null);
53    }
54  
55    @Override
56    public abstract void endElement(String name) throws IOException;
57      
58    public abstract void write(String string) throws IOException;
59  
60    @Override
61    public abstract void writeComment(Object comment) throws IOException;
62  
63    @Override
64    public abstract ResponseWriter cloneWithWriter(Writer writer);
65  
66    /**
67     * @deprecated Should not directly called via this interface. There is be a special method which might be better.
68     */
69    @Deprecated
70    public abstract void writeAttribute(String name, Object value, final String property) throws IOException;
71  
72    /**
73     * @deprecated Should not directly called via this interface. There is be a special method which might be better.
74     */
75    @Deprecated
76    public abstract void writeText(Object text, String property) throws IOException;
77  
78    @Override
79    public abstract void flush() throws IOException;
80  
81    // others (not from ResponseWriter)
82  
83    /**
84     * Writes a string attribute. The renderer may set escape=false to switch of escaping of the string,
85     * if it is not necessary.
86     */
87    public abstract void writeAttribute(String name, String string, boolean escape) throws IOException;
88  
89    /**
90     * Writes a boolean attribute. The value will not escaped.
91     */
92    public void writeAttribute(final String name, final boolean on) throws IOException {
93      if (on) {
94        writeAttribute(name, name, false);
95      }
96    }
97  
98    /**
99     * Writes a integer attribute. The value will not escaped.
100    */
101   public void writeAttribute(final String name, final int number) throws IOException {
102     writeAttribute(name, Integer.toString(number), false);
103   }
104 
105   /**
106    * Writes a propery as attribute. The value will be escaped.
107    */
108   public void writeAttributeFromComponent(final String name, final String property) throws IOException {
109     writeAttribute(name, null, property);
110   }
111 
112   /**
113    * Write the id attribute. The value will not escaped.
114    */
115   public void writeIdAttribute(final String id) throws IOException {
116     writeAttribute(HtmlAttributes.ID, id, false);
117   }
118 
119   /**
120    * Write the name attribute. The value will not escaped.
121    */
122   public void writeNameAttribute(final String name) throws IOException {
123     writeAttribute(HtmlAttributes.NAME, name, false);
124   }
125 
126   /**
127    * Write the class attribute. The value will not escaped.
128    * @deprecated since Tobago 1.5.0
129    */
130   @Deprecated
131   public void writeClassAttribute(final String cssClass) throws IOException {
132     writeAttribute(HtmlAttributes.CLASS, cssClass, false);
133   }
134 
135   /**
136    * Write the class attribute. The value will not escaped.
137    * @param classes The abstract representation of the css class string, normally created by the renderer.
138    */
139   public void writeClassAttribute(final Classes classes) throws IOException {
140     writeAttribute(HtmlAttributes.CLASS, classes.getStringValue(), false);
141   }
142 
143   @Deprecated
144   public abstract String getStyleClasses();
145 
146   /**
147    * Write the class attribute. The value will not escaped.
148    * @deprecated since Tobago 1.5.0
149    */
150   @Deprecated
151   public abstract void writeClassAttribute() throws IOException;
152 
153   /**
154    * Write the style attribute. The value may be escaped (depending of the content).
155    */
156   public void writeStyleAttribute(final Style style) throws IOException {
157     if (style != null) {
158       final String json = style.encodeJson();
159       if (json.length() > 2) { // empty "{}" needs not to be written
160         final FacesContext facesContext = FacesContext.getCurrentInstance();
161         writeAttribute(DataAttributes.STYLE, json, style.needsToBeEscaped() || AjaxUtils.isAjaxRequest(facesContext));
162         // in case of AJAX we need to escape the " as long we use
163         // org.apache.myfaces.tobago.internal.webapp.JsonResponseWriter
164       }
165     }
166   }
167 
168   /**
169    * Write the style attribute. The value will not escaped.
170    * @deprecated since 1.5.0, use writeStyleAttribute(Style) instead.
171    */
172   @Deprecated
173   public void writeStyleAttribute(final String style) throws IOException {
174     writeAttribute(HtmlAttributes.STYLE, style, false);
175   }
176 
177   /**
178    * @deprecated Should not be used, because it conflicts with CSP.
179    */
180   @Deprecated
181   public void writeJavascript(final String script) throws IOException {
182     startJavascript();
183     write(script);
184     endJavascript();
185   }
186 
187   /**
188    * @deprecated Should not be used, because it conflicts with CSP.
189    */
190   @Deprecated
191   public void endJavascript() throws IOException {
192 //    write("\n// -->\n"); // todo: for XHMTL we may need
193     endElement(HtmlElements.SCRIPT);
194   }
195 
196   /**
197    * @deprecated Should not be used, because it conflicts with CSP.
198    */
199   @Deprecated
200   public void startJavascript() throws IOException {
201     startElement(HtmlElements.SCRIPT, null);
202     writeAttribute(HtmlAttributes.TYPE, "text/javascript", false);
203     flush(); // is needed in some cases, e. g. TOBAGO-1094
204 //    write("\n<!--\n");
205   }
206 
207   /**
208    * Write text content. The text will be escaped.
209    */
210   public void writeText(final String text) throws IOException {
211     writeText(text, null);
212   }
213 
214   /**
215    * Writes a property as text. The text will be escaped.
216    */
217   public void writeTextFromComponent(final String property) throws IOException {
218     writeText(null, property);
219   }
220 
221   public String getContentTypeWithCharSet() {
222     String contentType = getContentType();
223     if (contentType == null) {
224       contentType = "text/html";
225     }
226     String characterEncoding = getCharacterEncoding();
227     if (characterEncoding == null) {
228       characterEncoding = "UTF-8";
229     }
230 
231     final StringBuilder builder = new StringBuilder(contentType);
232     builder.append("; charset=");
233     builder.append(characterEncoding);
234     return builder.toString();
235 
236   }
237 }