1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.renderkit.html.util;
20
21 import org.apache.commons.lang.builder.EqualsBuilder;
22 import org.apache.commons.lang.builder.HashCodeBuilder;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.myfaces.shared_tomahawk.config.MyfacesConfig;
26 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
27 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
28 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlResponseWriterImpl;
29 import org.apache.myfaces.shared_tomahawk.util.ClassUtils;
30
31 import javax.faces.context.FacesContext;
32 import javax.faces.context.ResponseWriter;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletResponse;
35 import java.io.IOException;
36 import java.util.Iterator;
37 import java.util.LinkedHashSet;
38 import java.util.Set;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 public class DefaultAddResource extends NonBufferingAddResource
78 {
79 protected Log log = LogFactory.getLog(DefaultAddResource.class);
80
81
82 protected StringBuffer originalResponse;
83
84 private Set headerBeginInfo;
85 private Set bodyEndInfo;
86 private Set bodyOnloadInfo;
87
88
89 protected boolean parserCalled = false;
90 protected int headerInsertPosition = -1;
91 protected int bodyInsertPosition = -1;
92 protected int beforeBodyPosition = -1;
93 protected int afterBodyContentInsertPosition = -1;
94 protected int beforeBodyEndPosition = -1;
95
96
97 protected DefaultAddResource()
98 {
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 public void addJavaScriptAtPosition(FacesContext context, ResourcePosition position,
120 ResourceHandler resourceHandler)
121 {
122 addJavaScriptAtPosition(context, position, resourceHandler, false);
123 }
124
125
126
127
128
129
130
131
132
133
134
135
136
137 public void addJavaScriptAtPosition(FacesContext context, ResourcePosition position,
138 Class myfacesCustomComponent, String resourceName)
139 {
140 addJavaScriptAtPosition(context, position, new MyFacesResourceHandler(
141 myfacesCustomComponent, resourceName));
142 }
143
144 public void addJavaScriptAtPositionPlain(FacesContext context, ResourcePosition position, Class myfacesCustomComponent, String resourceName)
145 {
146 addJavaScriptAtPosition(context, position,
147 new MyFacesResourceHandler(myfacesCustomComponent, resourceName),
148 false, false);
149 }
150
151
152
153
154
155
156
157
158
159
160
161
162 public void addJavaScriptAtPosition(FacesContext context, ResourcePosition position,
163 Class myfacesCustomComponent, String resourceName, boolean defer)
164 {
165 addJavaScriptAtPosition(context, position, new MyFacesResourceHandler(
166 myfacesCustomComponent, resourceName), defer);
167 }
168
169
170
171
172
173
174
175
176
177 public void addJavaScriptAtPosition(FacesContext context, ResourcePosition position, String uri)
178 {
179 addJavaScriptAtPosition(context, position, uri, false);
180 }
181
182
183
184
185
186 public void addJavaScriptAtPosition(FacesContext context, ResourcePosition position, String uri,
187 boolean defer)
188 {
189 addPositionedInfo(position, getScriptInstance(context, uri, defer));
190 }
191
192 public void addJavaScriptToBodyTag(FacesContext context, String javascriptEventName,
193 String addedJavaScript)
194 {
195 AttributeInfo info = new AttributeInfo();
196 info.setAttributeName(javascriptEventName);
197 info.setAttributeValue(addedJavaScript);
198
199 addPositionedInfo(BODY_ONLOAD, info);
200 }
201
202
203
204
205
206 public void addJavaScriptAtPosition(FacesContext context, ResourcePosition position,
207 ResourceHandler resourceHandler, boolean defer)
208 {
209 validateResourceHandler(resourceHandler);
210 addPositionedInfo(position, getScriptInstance(context, resourceHandler, defer));
211 }
212
213 private void addJavaScriptAtPosition(FacesContext context, ResourcePosition position,
214 ResourceHandler resourceHandler, boolean defer, boolean encodeUrl)
215 {
216 validateResourceHandler(resourceHandler);
217 addPositionedInfo(position, getScriptInstance(context, resourceHandler, defer, encodeUrl));
218 }
219
220
221
222
223
224 public void addStyleSheet(FacesContext context, ResourcePosition position,
225 Class myfacesCustomComponent, String resourceName)
226 {
227 addStyleSheet(context, position, new MyFacesResourceHandler(myfacesCustomComponent,
228 resourceName));
229 }
230
231
232
233
234
235 public void addStyleSheet(FacesContext context, ResourcePosition position, String uri)
236 {
237 addPositionedInfo(position, getStyleInstance(context, uri));
238 }
239
240
241
242
243
244 public void addStyleSheet(FacesContext context, ResourcePosition position,
245 ResourceHandler resourceHandler)
246 {
247 validateResourceHandler(resourceHandler);
248 addPositionedInfo(position, getStyleInstance(context, resourceHandler));
249 }
250
251
252
253
254 public void addInlineStyleAtPosition(FacesContext context, ResourcePosition position, String inlineStyle)
255 {
256 addPositionedInfo(position, getInlineStyleInstance(inlineStyle));
257 }
258
259
260
261
262 public void addInlineScriptAtPosition(FacesContext context, ResourcePosition position,
263 String inlineScript)
264 {
265 addPositionedInfo(position, getInlineScriptInstance(inlineScript));
266 }
267
268
269
270 protected Set getHeaderBeginInfos()
271 {
272 if (headerBeginInfo == null)
273 {
274 headerBeginInfo = new LinkedHashSet();
275 }
276 return headerBeginInfo;
277 }
278
279 protected Set getBodyEndInfos()
280 {
281 if (bodyEndInfo == null)
282 {
283 bodyEndInfo = new LinkedHashSet();
284 }
285 return bodyEndInfo;
286 }
287
288 protected Set getBodyOnloadInfos()
289 {
290 if (bodyOnloadInfo == null)
291 {
292 bodyOnloadInfo = new LinkedHashSet();
293 }
294 return bodyOnloadInfo;
295 }
296
297 private void addPositionedInfo(ResourcePosition position, PositionedInfo info)
298 {
299 if (HEADER_BEGIN.equals(position))
300 {
301 Set set = getHeaderBeginInfos();
302 set.add(info);
303 }
304 else if (BODY_END.equals(position))
305 {
306 Set set = getBodyEndInfos();
307 set.add(info);
308
309 }
310 else if (BODY_ONLOAD.equals(position))
311 {
312 Set set = getBodyOnloadInfos();
313 set.add(info);
314 }
315 }
316
317 public boolean hasHeaderBeginInfos()
318 {
319 return headerBeginInfo != null;
320 }
321
322
323
324
325 public void parseResponse(HttpServletRequest request, String bufferedResponse,
326 HttpServletResponse response)
327 {
328
329 originalResponse = new StringBuffer(bufferedResponse);
330
331 ParseCallbackListener l = new ParseCallbackListener();
332 ReducedHTMLParser.parse(originalResponse, l);
333
334 headerInsertPosition = l.getHeaderInsertPosition();
335 bodyInsertPosition = l.getBodyInsertPosition();
336 beforeBodyPosition = l.getBeforeBodyPosition();
337 afterBodyContentInsertPosition = l.getAfterBodyContentInsertPosition();
338 beforeBodyEndPosition = l.getAfterBodyEndPosition() - 7;
339
340 parserCalled = true;
341 }
342
343
344
345
346 public void writeMyFacesJavascriptBeforeBodyEnd(HttpServletRequest request,
347 HttpServletResponse response) throws IOException
348 {
349 if (!parserCalled)
350 {
351 throw new IOException("Method parseResponse has to be called first");
352 }
353
354 if (beforeBodyEndPosition >= 0)
355 {
356 String myFacesJavascript = (String) request.getAttribute("org.apache.myfaces.myFacesJavascript");
357 if (myFacesJavascript != null)
358 {
359 originalResponse.insert(beforeBodyEndPosition, myFacesJavascript);
360 }
361 else
362 {
363 log.warn("MyFaces special javascript could not be retrieved from request-map.");
364 }
365 }
366 }
367
368
369
370
371
372
373
374
375 public void writeWithFullHeader(HttpServletRequest request,
376 HttpServletResponse response) throws IOException
377 {
378 if (!parserCalled)
379 {
380 throw new IOException("Method parseResponse has to be called first");
381 }
382
383 boolean addHeaderTags = false;
384
385 if (headerInsertPosition == -1)
386 {
387 if (beforeBodyPosition != -1)
388 {
389
390
391 addHeaderTags = true;
392 headerInsertPosition = beforeBodyPosition;
393 }
394 else
395 {
396
397 log.warn("Response has no <head> or <body> tag:\n" + originalResponse);
398 }
399 }
400
401 ResponseWriter writer = new HtmlResponseWriterImpl(response.getWriter(),
402 HtmlRendererUtils.selectContentType(request.getHeader("accept")),
403 response.getCharacterEncoding());
404
405 if (afterBodyContentInsertPosition >= 0)
406 {
407
408 HtmlBufferResponseWriterWrapper writerWrapper = HtmlBufferResponseWriterWrapper
409 .getInstance(writer);
410
411 for (Iterator i = getBodyEndInfos().iterator(); i.hasNext();)
412 {
413 writerWrapper.write("\n");
414
415 PositionedInfo positionedInfo = (PositionedInfo) i.next();
416
417 if (!(positionedInfo instanceof WritablePositionedInfo))
418 throw new IllegalStateException("positionedInfo of type : "
419 + positionedInfo.getClass().getName());
420 ((WritablePositionedInfo) positionedInfo).writePositionedInfo(response,
421 writerWrapper);
422 }
423
424 originalResponse.insert(headerInsertPosition, writerWrapper.toString());
425 }
426
427 if (bodyInsertPosition > 0)
428 {
429 StringBuffer buf = new StringBuffer();
430 Set bodyInfos = getBodyOnloadInfos();
431 if (bodyInfos.size() > 0)
432 {
433 int i = 0;
434 for (Iterator it = getBodyOnloadInfos().iterator(); it.hasNext();)
435 {
436 AttributeInfo positionedInfo = (AttributeInfo) it.next();
437 if (i == 0)
438 {
439 buf.append(positionedInfo.getAttributeName());
440 buf.append("=\"");
441 }
442 buf.append(positionedInfo.getAttributeValue());
443
444 i++;
445 }
446
447 buf.append("\"");
448 originalResponse.insert(bodyInsertPosition - 1, " " + buf.toString());
449 }
450 }
451
452 if (headerInsertPosition >= 0)
453 {
454 HtmlBufferResponseWriterWrapper writerWrapper = HtmlBufferResponseWriterWrapper
455 .getInstance(writer);
456
457 if (addHeaderTags)
458 writerWrapper.write("<head>");
459
460 for (Iterator i = getHeaderBeginInfos().iterator(); i.hasNext();)
461 {
462 writerWrapper.write("\n");
463
464 PositionedInfo positionedInfo = (PositionedInfo) i.next();
465
466 if (!(positionedInfo instanceof WritablePositionedInfo))
467 throw new IllegalStateException("positionedInfo of type : "
468 + positionedInfo.getClass().getName());
469 ((WritablePositionedInfo) positionedInfo).writePositionedInfo(response,
470 writerWrapper);
471 }
472
473 if (addHeaderTags)
474 writerWrapper.write("</head>");
475
476 originalResponse.insert(headerInsertPosition, writerWrapper.toString());
477
478 }
479
480 }
481
482
483
484
485 public void writeResponse(HttpServletRequest request,
486 HttpServletResponse response) throws IOException
487 {
488 ResponseWriter writer = new HtmlResponseWriterImpl(response.getWriter(), HtmlRendererUtils
489 .selectContentType(request.getHeader("accept")),
490 response.getCharacterEncoding());
491 writer.write(originalResponse.toString());
492 }
493
494 private PositionedInfo getStyleInstance(FacesContext context, ResourceHandler resourceHandler)
495 {
496 return new StylePositionedInfo(getResourceUri(context, resourceHandler));
497 }
498
499 private PositionedInfo getScriptInstance(FacesContext context, ResourceHandler resourceHandler,
500 boolean defer)
501 {
502 return new ScriptPositionedInfo(getResourceUri(context, resourceHandler), defer);
503 }
504
505 private PositionedInfo getScriptInstance(FacesContext context, ResourceHandler resourceHandler,
506 boolean defer, boolean encodeURL)
507 {
508 return new ScriptPositionedInfo(getResourceUri(context, resourceHandler), defer, encodeURL);
509 }
510
511 private PositionedInfo getStyleInstance(FacesContext context, String uri)
512 {
513 return new StylePositionedInfo(getResourceUri(context, uri));
514 }
515
516 protected PositionedInfo getScriptInstance(FacesContext context, String uri, boolean defer)
517 {
518 return new ScriptPositionedInfo(getResourceUri(context, uri), defer);
519 }
520
521 private PositionedInfo getInlineScriptInstance(String inlineScript)
522 {
523 return new InlineScriptPositionedInfo(inlineScript);
524 }
525
526 private PositionedInfo getInlineStyleInstance(String inlineStyle)
527 {
528 return new InlineStylePositionedInfo(inlineStyle);
529 }
530
531 protected interface PositionedInfo
532 {
533 }
534
535 protected static class AttributeInfo implements PositionedInfo
536 {
537 private String _attributeName;
538 private String _attributeValue;
539
540 public String getAttributeName()
541 {
542 return _attributeName;
543 }
544
545 public void setAttributeName(String attributeName)
546 {
547 _attributeName = attributeName;
548 }
549
550 public String getAttributeValue()
551 {
552 return _attributeValue;
553 }
554
555 public void setAttributeValue(String attributeValue)
556 {
557 _attributeValue = attributeValue;
558 }
559 }
560
561 protected interface WritablePositionedInfo extends PositionedInfo
562 {
563 public abstract void writePositionedInfo(HttpServletResponse response, ResponseWriter writer)
564 throws IOException;
565 }
566
567 private abstract class AbstractResourceUri
568 {
569 protected final String _resourceUri;
570
571 protected AbstractResourceUri(String resourceUri)
572 {
573 _resourceUri = resourceUri;
574 }
575
576 public int hashCode()
577 {
578 return _resourceUri.hashCode();
579 }
580
581 public boolean equals(Object obj)
582 {
583 if (obj == null)
584 {
585 return false;
586 }
587 if (obj == this)
588 {
589 return true;
590 }
591 if (obj instanceof AbstractResourceUri)
592 {
593 AbstractResourceUri other = (AbstractResourceUri) obj;
594 return _resourceUri.equals(other._resourceUri);
595 }
596 return false;
597 }
598
599 protected String getResourceUri()
600 {
601 return _resourceUri;
602 }
603 }
604
605 private class StylePositionedInfo extends AbstractResourceUri implements WritablePositionedInfo
606 {
607 protected StylePositionedInfo(String resourceUri)
608 {
609 super(resourceUri);
610 }
611
612 public void writePositionedInfo(HttpServletResponse response, ResponseWriter writer)
613 throws IOException
614 {
615 writeStyleReference(response, writer, this.getResourceUri());
616 }
617 }
618
619 private class ScriptPositionedInfo extends AbstractResourceUri implements
620 WritablePositionedInfo
621 {
622 protected final boolean _defer;
623 protected final boolean _encode;
624
625 public ScriptPositionedInfo(String resourceUri, boolean defer)
626 {
627 this(resourceUri, defer, true);
628 }
629
630 public ScriptPositionedInfo(String resourceUri, boolean defer, boolean encodeUrl)
631 {
632 super(resourceUri);
633 _defer = defer;
634 _encode = encodeUrl;
635 }
636
637 public int hashCode()
638 {
639 return new HashCodeBuilder()
640 .append(this.getResourceUri())
641 .append(_defer)
642 .append(_encode)
643 .toHashCode();
644 }
645
646 public boolean equals(Object obj)
647 {
648 if (super.equals(obj))
649 {
650 if (obj instanceof ScriptPositionedInfo)
651 {
652 ScriptPositionedInfo other = (ScriptPositionedInfo) obj;
653 return new EqualsBuilder()
654 .append(_defer, other._defer)
655 .append(_encode, other._encode)
656 .isEquals();
657 }
658 }
659 return false;
660 }
661
662 public void writePositionedInfo(HttpServletResponse response, ResponseWriter writer)
663 throws IOException
664 {
665 writeJavaScriptReference(response, writer, this.getResourceUri(),_encode,_defer);
666 }
667 }
668
669 private abstract class InlinePositionedInfo implements WritablePositionedInfo
670 {
671 private final String _inlineValue;
672
673 protected InlinePositionedInfo(String inlineValue)
674 {
675 _inlineValue = inlineValue;
676 }
677
678 public String getInlineValue()
679 {
680 return _inlineValue;
681 }
682
683 public int hashCode()
684 {
685 return new HashCodeBuilder().append(_inlineValue).toHashCode();
686 }
687
688 public boolean equals(Object obj)
689 {
690 if (obj == null)
691 {
692 return false;
693 }
694 if (obj == this)
695 {
696 return true;
697 }
698 if (obj instanceof InlinePositionedInfo)
699 {
700 InlinePositionedInfo other = (InlinePositionedInfo) obj;
701 return new EqualsBuilder().append(_inlineValue, other._inlineValue).isEquals();
702 }
703 return false;
704 }
705 }
706
707 private class InlineScriptPositionedInfo extends InlinePositionedInfo
708 {
709 protected InlineScriptPositionedInfo(String inlineScript)
710 {
711 super(inlineScript);
712 }
713
714 public void writePositionedInfo(HttpServletResponse response, ResponseWriter writer)
715 throws IOException
716 {
717 writeInlineScript(writer, getInlineValue());
718 }
719 }
720
721 private class InlineStylePositionedInfo extends InlinePositionedInfo
722 {
723 protected InlineStylePositionedInfo(String inlineStyle)
724 {
725 super(inlineStyle);
726 }
727
728 public void writePositionedInfo(HttpServletResponse response, ResponseWriter writer)
729 throws IOException
730 {
731 writeInlineStylesheet(writer, getInlineValue());
732 }
733 }
734
735 protected static class ParseCallbackListener implements CallbackListener
736 {
737 private int headerInsertPosition = -1;
738 private int bodyInsertPosition = -1;
739 private int beforeBodyPosition = -1;
740 private int afterBodyContentInsertPosition = -1;
741 private int afterBodyEndPosition = -1;
742
743 public ParseCallbackListener()
744 {
745 }
746
747 public void openedStartTag(int charIndex, int tagIdentifier)
748 {
749 if (tagIdentifier == ReducedHTMLParser.BODY_TAG)
750 {
751 beforeBodyPosition = charIndex;
752 }
753 }
754
755 public void closedStartTag(int charIndex, int tagIdentifier)
756 {
757 if (tagIdentifier == ReducedHTMLParser.HEAD_TAG)
758 {
759 headerInsertPosition = charIndex;
760 }
761 else if (tagIdentifier == ReducedHTMLParser.BODY_TAG)
762 {
763 bodyInsertPosition = charIndex;
764 }
765 }
766
767 public void openedEndTag(int charIndex, int tagIdentifier)
768 {
769 if (tagIdentifier == ReducedHTMLParser.BODY_TAG)
770 {
771 afterBodyContentInsertPosition = charIndex;
772 }
773 }
774
775 public void closedEndTag(int charIndex, int tagIdentifier)
776 {
777 if (tagIdentifier == ReducedHTMLParser.BODY_TAG)
778 {
779 afterBodyEndPosition = charIndex;
780 }
781 }
782
783 public void attribute(int charIndex, int tagIdentifier, String key, String value)
784 {
785 }
786
787 public int getHeaderInsertPosition()
788 {
789 return headerInsertPosition;
790 }
791
792 public int getBodyInsertPosition()
793 {
794 return bodyInsertPosition;
795 }
796
797 public int getBeforeBodyPosition()
798 {
799 return beforeBodyPosition;
800 }
801
802 public int getAfterBodyContentInsertPosition()
803 {
804 return afterBodyContentInsertPosition;
805 }
806
807 public int getAfterBodyEndPosition()
808 {
809 return afterBodyEndPosition;
810 }
811 }
812
813 public boolean requiresBuffer()
814 {
815 return true;
816 }
817
818 public void responseStarted()
819 {
820 }
821
822 public void responseFinished()
823 {
824 }
825 }