1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.renderkit;
21
22 import org.apache.myfaces.tobago.internal.webapp.DebugResponseWriterWrapper;
23 import org.apache.myfaces.tobago.internal.webapp.HtmlResponseWriter;
24 import org.apache.myfaces.tobago.internal.webapp.XmlResponseWriter;
25 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 import javax.faces.FactoryFinder;
30 import javax.faces.application.ProjectStage;
31 import javax.faces.context.FacesContext;
32 import javax.faces.context.ResponseStream;
33 import javax.faces.context.ResponseWriter;
34 import javax.faces.render.ClientBehaviorRenderer;
35 import javax.faces.render.RenderKit;
36 import javax.faces.render.RenderKitFactory;
37 import javax.faces.render.Renderer;
38 import javax.faces.render.ResponseStateManager;
39 import java.io.OutputStream;
40 import java.io.Writer;
41 import java.lang.invoke.MethodHandles;
42 import java.nio.charset.Charset;
43 import java.util.HashMap;
44 import java.util.Iterator;
45 import java.util.Map;
46
47 public class TobagoRenderKit extends RenderKit {
48
49 private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
50
51 private static final String CONTENT_TYPE_TEXT_HTML = "text/html";
52 private static final String CONTENT_TYPE_TEXT_XML = "text/xml";
53
54 private final RenderKit htmlBasicRenderKit;
55
56 private Map<Key, Renderer> renderers = new HashMap<>();
57
58 public TobagoRenderKit() {
59 final RenderKitFactory rkFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
60 htmlBasicRenderKit =
61 rkFactory.getRenderKit(FacesContext.getCurrentInstance(), RenderKitFactory.HTML_BASIC_RENDER_KIT);
62 if (LOG.isDebugEnabled()) {
63 LOG.debug("Creating TobagoRenderKit with base: {}", htmlBasicRenderKit);
64 }
65 }
66
67 @Override
68 public Renderer getRenderer(final String family, final String rendererType) {
69 Renderer renderer = renderers.get(new Key(family, rendererType));
70 if (renderer == null) {
71 renderer = htmlBasicRenderKit.getRenderer(family, rendererType);
72 }
73
74 if (renderer == null) {
75 LOG.error("The class which was found by the ResourceManager cannot be "
76 + "found or instantiated: classname='" + rendererType + "'");
77 }
78
79 return renderer;
80 }
81
82 @Override
83 public ResponseWriter createResponseWriter(
84 final Writer writer, final String contentType, final String characterEncoding) {
85 final FacesContext facesContext = FacesContext.getCurrentInstance();
86 final Charset charset = Charset.forName(characterEncoding);
87 TobagoResponseWriter responseWriter;
88 if (facesContext.getPartialViewContext().isAjaxRequest()) {
89 responseWriter = new XmlResponseWriter(writer, CONTENT_TYPE_TEXT_XML, charset);
90 } else {
91 if (contentType != null && !contentType.contains(CONTENT_TYPE_TEXT_HTML)) {
92 LOG.warn("Content-Type '{}' not supported! Using '{}'", contentType, CONTENT_TYPE_TEXT_HTML);
93 }
94 responseWriter = new HtmlResponseWriter(writer, CONTENT_TYPE_TEXT_HTML, charset);
95
96
97 }
98 if (facesContext.isProjectStage(ProjectStage.Development)) {
99 responseWriter = new DebugResponseWriterWrapper(responseWriter);
100 }
101 return responseWriter;
102 }
103
104 @Override
105 public void addRenderer(final String family, final String rendererType, final Renderer renderer) {
106 renderers.put(new Key(family, rendererType), renderer);
107 }
108
109 @Override
110 public ResponseStateManager getResponseStateManager() {
111 return htmlBasicRenderKit.getResponseStateManager();
112 }
113
114 @Override
115 public ResponseStream createResponseStream(final OutputStream outputStream) {
116 return htmlBasicRenderKit.createResponseStream(outputStream);
117 }
118
119 @Override
120 public void addClientBehaviorRenderer(final String type, final ClientBehaviorRenderer renderer) {
121 htmlBasicRenderKit.addClientBehaviorRenderer(type, renderer);
122 }
123
124 @Override
125 public ClientBehaviorRenderer getClientBehaviorRenderer(final String type) {
126 return htmlBasicRenderKit.getClientBehaviorRenderer(type);
127 }
128
129 @Override
130 public Iterator<String> getClientBehaviorRendererTypes() {
131 return htmlBasicRenderKit.getClientBehaviorRendererTypes();
132 }
133
134 private static final class Key {
135 private final String family;
136 private final String rendererType;
137
138 private Key(final String family, final String rendererType) {
139 this.family = family;
140 this.rendererType = rendererType;
141 }
142
143 public boolean equals(final Object o) {
144 if (this == o) {
145 return true;
146 }
147 if (o == null || getClass() != o.getClass()) {
148 return false;
149 }
150
151 final Key key = (Key) o;
152
153 if (!family.equals(key.family)) {
154 return false;
155 }
156 if (!rendererType.equals(key.rendererType)) {
157 return false;
158 }
159
160 return true;
161 }
162
163 public int hashCode() {
164 int result;
165 result = family.hashCode();
166 result = 31 * result + rendererType.hashCode();
167 return result;
168 }
169 }
170 }