1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.inputHtml;
20
21 import java.io.IOException;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.faces.component.UIComponent;
26 import javax.faces.component.UIForm;
27 import javax.faces.component.UINamingContainer;
28 import javax.faces.context.FacesContext;
29 import javax.faces.context.ResponseWriter;
30 import javax.faces.convert.ConverterException;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
35 import org.apache.myfaces.component.UserRoleUtils;
36 import org.apache.myfaces.custom.tabbedpane.HtmlPanelTab;
37 import org.apache.myfaces.custom.tabbedpane.HtmlPanelTabbedPane;
38 import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
39 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
40 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
41 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
42 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
43 import org.apache.myfaces.shared_tomahawk.renderkit.html.util.HTMLEncoder;
44
45
46
47
48
49
50 @JSFRenderer(
51 renderKitId = "HTML_BASIC",
52 family = "javax.faces.Input",
53 type = "org.apache.myfaces.InputHtml")
54 public class InputHtmlRenderer extends HtmlRenderer{
55
56
57
58
59
60
61
62
63 private static final Log log = LogFactory.getLog(HtmlRendererUtils.class);
64
65 protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent) {
66 if( !UserRoleUtils.isEnabledOnUserRole(uiComponent) )
67 return false;
68
69 return ((InputHtml)uiComponent).isDisabled();
70 }
71
72 private static boolean useFallback(InputHtml editor){
73
74 return editor.getFallback().equals("true");
75 }
76
77 public boolean getRendersChildren()
78 {
79 return true;
80 }
81
82 public void encodeBegin(FacesContext context, UIComponent component)
83 throws IOException
84 {
85 }
86
87 public void encodeChildren(FacesContext context, UIComponent component)
88 throws IOException
89 {
90 }
91
92 public void encodeEnd(FacesContext context, UIComponent uiComponent) throws IOException {
93 RendererUtils.checkParamValidity(context, uiComponent, InputHtml.class);
94
95 UIComponent compositeFacet = (UIComponent) uiComponent
96 .getFacet(UIComponent.COMPOSITE_FACET_NAME);
97
98 if (compositeFacet == null)
99 {
100 if (log.isErrorEnabled())
101 {
102 log
103 .error("facet UIComponent.COMPOSITE_FACET_NAME not found when rendering composite component "
104 + uiComponent.getClientId(context));
105 }
106 return;
107 }
108 InputHtml editor = (InputHtml) uiComponent;
109 if( HtmlRendererUtils.isDisplayValueOnly(editor) )
110 encodeDisplayValueOnly(context, editor);
111 else if( useFallback(editor) )
112 encodeEndFallBackMode(context, editor);
113 else{
114
115
116
117
118
119 if( ! isVisible(editor) ){
120 encodeHidden(context, editor);
121 }else if( ! hasThisPageAlreadyRenderedAnInputHtml( context ) ){
122 compositeFacet.encodeAll(context);
123 setThisPageAlreadyRenderedAnInputHtml( context );
124 }else{
125 log.warn("Only one inputHtml can be displayed at the same time. The component will be rendered isung a textarea." +
126 "\nConpoment : "+RendererUtils.getPathToComponent( editor ));
127 encodeEndFallBackMode(context, editor);
128 }
129 }
130 }
131
132 static private boolean hasThisPageAlreadyRenderedAnInputHtml(FacesContext context){
133 return context.getExternalContext().getRequestMap().containsKey( InputHtmlRenderer.class.getName() );
134 }
135
136 static private void setThisPageAlreadyRenderedAnInputHtml(FacesContext context){
137 context.getExternalContext().getRequestMap().put(InputHtmlRenderer.class.getName(), Boolean.TRUE);
138 }
139
140
141
142
143 private boolean isVisible(InputHtml editor){
144 for(UIComponent parent = editor.getParent(); parent != null ; parent = parent.getParent()){
145 if( parent instanceof HtmlPanelTab ){
146 HtmlPanelTab panelTab = (HtmlPanelTab) parent;
147 HtmlPanelTabbedPane panelTabbedPane = null;
148 for(UIComponent panelAncestor=panelTab.getParent(); panelAncestor!=null ; panelAncestor=panelAncestor.getParent()){
149 if( panelAncestor instanceof HtmlPanelTabbedPane ){
150 panelTabbedPane = (HtmlPanelTabbedPane)panelAncestor;
151 break;
152 }
153 }
154
155 if( panelTabbedPane != null ){
156 if( panelTabbedPane.isClientSide() ){
157 parent = panelTabbedPane;
158 continue;
159 }
160
161
162
163 int selectedIndex = panelTabbedPane.getSelectedIndex();
164 List children = panelTabbedPane.getChildren();
165 int tabIdx = 0;
166 for (int i = 0, len = children.size(); i < len && tabIdx <= selectedIndex ; i++){
167 UIComponent child = htmlTabbedPaneRenderer_getUIComponent((UIComponent)children.get(i));
168 if (child instanceof HtmlPanelTab){
169 if( child == panelTab ){
170 if( ! child.isRendered() || tabIdx != selectedIndex){
171 return false;
172 }else{
173
174 parent = panelTabbedPane;
175 continue;
176 }
177 }
178 tabIdx++;
179 }
180 }
181 }else{
182 log.debug("pannelTabbedPane == null for component "+RendererUtils.getPathToComponent(panelTab));
183 }
184 }
185 }
186
187 return true;
188 }
189
190
191
192
193 private UIComponent htmlTabbedPaneRenderer_getUIComponent(UIComponent uiComponent)
194 {
195
196 if (uiComponent instanceof UIForm || uiComponent instanceof UINamingContainer)
197 {
198 List children = uiComponent.getChildren();
199 for (int i = 0, len = children.size(); i < len; i++)
200 {
201 uiComponent = htmlTabbedPaneRenderer_getUIComponent((UIComponent)children.get(i));
202 }
203 }
204 return uiComponent;
205 }
206
207 private void encodeHidden(FacesContext context, InputHtml editor) throws IOException {
208 String clientId = editor.getClientId(context);
209
210 ResponseWriter writer = context.getResponseWriter();
211 writer.startElement(HTML.TEXTAREA_ELEM, editor);
212
213 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
214 writer.writeAttribute(HTML.STYLE_ATTR, "display:none", null);
215
216 String text = RendererUtils.getStringValue(context, editor);
217 writer.writeText(text, JSFAttr.VALUE_ATTR);
218
219 writer.endElement(HTML.TEXTAREA_ELEM);
220 }
221
222 private void encodeDisplayValueOnly(FacesContext context, InputHtml editor) throws IOException {
223
224 ResponseWriter writer = context.getResponseWriter();
225 writer.startElement(HTML.SPAN_ELEM, editor);
226 HtmlRendererUtils.writeIdIfNecessary(writer, editor, context);
227
228 HtmlRendererUtils.renderDisplayValueOnlyAttributes(editor, writer);
229
230 String text = RendererUtils.getStringValue(context, editor);
231 writer.write( editor.getHtmlBody( text ) );
232
233 writer.endElement(HTML.SPAN_ELEM);
234 }
235
236 private void encodeEndFallBackMode(FacesContext context, InputHtml editor) throws IOException {
237 String clientId = editor.getClientId(context);
238
239 ResponseWriter writer = context.getResponseWriter();
240 writer.startElement(HTML.TEXTAREA_ELEM, editor);
241
242 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
243 HtmlRendererUtils.writeIdIfNecessary(writer, editor, context);
244
245 if( editor.getStyle()!=null )
246 writer.writeAttribute(HTML.STYLE_ATTR, editor.getStyle(), null);
247 if( editor.getStyleClass()!=null )
248 writer.writeAttribute(HTML.CLASS_ATTR, editor.getStyleClass(), null);
249
250 if (isDisabled(context, editor))
251 writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
252
253 String text = RendererUtils.getStringValue(context, editor);
254 writer.write( htmlToPlainText(text, editor) );
255
256 writer.endElement(HTML.TEXTAREA_ELEM);
257 }
258
259 private static String htmlToPlainText(String html, InputHtml editor){
260 return editor.getHtmlBody( html )
261 .replaceAll("<br.*>","\n")
262 .replaceAll("<.+?>", "");
263 }
264
265 public void decode(FacesContext facesContext, UIComponent uiComponent) {
266 RendererUtils.checkParamValidity(facesContext, uiComponent, InputHtml.class);
267 InputHtml editor = (InputHtml) uiComponent;
268
269 Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
270 String clientId = uiComponent.getClientId(facesContext);
271
272 if (paramMap.containsKey(clientId)) {
273
274 String submitedText = (String)paramMap.get(clientId);
275 String htmlText = useFallback(editor) ? HTMLEncoder.encode(submitedText, true, true) : submitedText;
276
277 editor.setSubmittedValue( htmlText );
278 } else {
279 log.warn(HtmlRendererUtils.NON_SUBMITTED_VALUE_WARNING + " Component : "+
280 RendererUtils.getPathToComponent( editor ));
281 }
282 }
283
284 public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue) throws ConverterException {
285 RendererUtils.checkParamValidity(facesContext, uiComponent, InputHtml.class);
286 InputHtml editor = (InputHtml) uiComponent;
287 String submittedDocument = editor.getValueFromDocument((String)submittedValue);
288 return RendererUtils.getConvertedUIOutputValue(facesContext, editor, submittedDocument);
289 }
290 }