1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.myfaces.custom.roundeddiv;
22
23 import java.awt.Color;
24 import java.awt.Dimension;
25 import java.awt.image.BufferedImage;
26 import java.io.ByteArrayOutputStream;
27 import java.io.IOException;
28 import java.io.OutputStream;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Set;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39
40 import javax.faces.component.UIComponent;
41 import javax.faces.context.FacesContext;
42 import javax.faces.context.ResponseWriter;
43 import javax.imageio.ImageIO;
44 import javax.servlet.ServletContext;
45 import javax.servlet.http.HttpServletRequest;
46 import javax.servlet.http.HttpServletResponse;
47
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.apache.myfaces.component.html.util.ParameterResourceHandler;
51 import org.apache.myfaces.custom.htmlTag.HtmlTagRenderer;
52 import org.apache.myfaces.renderkit.html.util.AddResource;
53 import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
54 import org.apache.myfaces.renderkit.html.util.ResourceLoader;
55 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
56 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public class HtmlRoundedDivRenderer extends HtmlTagRenderer implements
71 ResourceLoader
72 {
73 private final static Log log = LogFactory
74 .getLog(HtmlRoundedDivRenderer.class);
75 private static Map imageCache = Collections.synchronizedMap(new HashMap());
76 private static List cacheQueue = Collections
77 .synchronizedList(new ArrayList());
78 private static Integer cacheSize;
79
80 private final static int DEFAULT_CACHE_SIZE = 20;
81 private final static String CACHE_SIZE_KEY = "org.apache.myfaces.ROUNDED_DIV_CACHE_SIZE";
82 public final static String RENDERER_TYPE = "org.apache.myfaces.HtmlRoundedDiv";
83
84
85
86
87
88
89 public void serveResource(ServletContext context,
90 HttpServletRequest request, HttpServletResponse response,
91 String resourceUri) throws IOException
92 {
93 initCache(context);
94 boolean useCache = cacheSize.intValue() > 0;
95
96 String cacheKey = null;
97 RoundedBorderGenerator borderGen = null;
98 if (useCache)
99 {
100 cacheKey = getCacheKey(request.getQueryString());
101 borderGen = (RoundedBorderGenerator) imageCache.get(cacheKey);
102 }
103
104 if (borderGen == null)
105 {
106 if (useCache)
107 {
108 borderGen = initCachedGenerator(request, cacheKey);
109 }
110 else
111 {
112 borderGen = buildGenerator(request);
113 }
114 }
115
116 String area = request.getParameter("a");
117 BufferedImage img;
118 if (request.getParameter("s") != null)
119 {
120 img = borderGen.createImage();
121 }
122 else
123 {
124 img = borderGen.createImageSection(getAreaAsSection(area));
125 }
126
127 if (cacheSize.intValue() == 0)
128 {
129 borderGen.dispose();
130 }
131
132 response.setContentType("image/png");
133
134 ByteArrayOutputStream baos = new ByteArrayOutputStream();
135 ImageIO.write(img, "png", baos);
136 byte[] data = baos.toByteArray();
137 baos = null;
138
139 response.setContentLength(data.length);
140 OutputStream out = response.getOutputStream();
141 try
142 {
143 out.write(data);
144 }
145 finally
146 {
147 out.close();
148 }
149 }
150
151
152
153
154
155
156 protected RoundedBorderGenerator initCachedGenerator(
157 HttpServletRequest request, String cacheKey)
158 {
159 RoundedBorderGenerator borderGen;
160
161 synchronized (imageCache)
162 {
163 borderGen = buildGenerator(request);
164
165 imageCache.put(cacheKey, borderGen);
166 cacheQueue.add(cacheKey);
167
168 while (cacheQueue.size() > cacheSize.intValue())
169 {
170 RoundedBorderGenerator gen = (RoundedBorderGenerator) imageCache
171 .remove(cacheQueue.remove(0));
172 gen.dispose();
173 }
174 }
175 return borderGen;
176 }
177
178 protected RoundedBorderGenerator buildGenerator(HttpServletRequest request)
179 {
180 RoundedBorderGenerator borderGen;
181 String param;
182 Color foregroundColor = Color.decode("#" + request.getParameter("c"));
183
184 Dimension size = null;
185 if ((param = request.getParameter("s")) != null)
186 {
187 int i = param.indexOf('x');
188 size = new Dimension(Integer.parseInt(param.substring(0, i)),
189 Integer.parseInt(param.substring(i + 1)));
190 }
191
192 Color backgroundColor = null, borderColor = null;
193 if ((param = request.getParameter("bgc")) != null)
194 {
195 backgroundColor = Color.decode("#" + param);
196 }
197 if ((param = request.getParameter("bc")) != null)
198 {
199 borderColor = Color.decode("#" + param);
200 }
201
202 int borderWidth = Integer.parseInt(request.getParameter("bw"));
203 int radius = Integer.parseInt(request.getParameter("r"));
204
205 boolean inverse = "t".equals(request.getParameter("i"));
206
207 borderGen = new RoundedBorderGenerator(borderColor, borderWidth,
208 radius, foregroundColor, backgroundColor, size, inverse);
209 return borderGen;
210 }
211
212
213
214
215
216 public void encodeBegin(FacesContext context, UIComponent component)
217 throws IOException
218 {
219 super.encodeBegin(context, component);
220 if (!component.isRendered())
221 return;
222
223 boolean ie = isIE(context);
224
225 HtmlRoundedDiv div = (HtmlRoundedDiv) component;
226 ResponseWriter writer = context.getResponseWriter();
227 Set areas = null;
228
229 if (div.getSize() == null)
230 {
231 areas = getAreasToRender(context, div);
232 }
233
234 if ("table".equals(div.getValue()))
235 {
236 encodeTable(context, ie, div, writer, areas);
237 }
238 else
239 {
240 encodeDivBegin(context, ie, div, writer, areas);
241 }
242 }
243
244 protected void encodeDivBegin(FacesContext context, boolean ie,
245 HtmlRoundedDiv div, ResponseWriter writer, Set areas)
246 throws IOException
247 {
248 if (div.getSize() != null)
249 {
250 addImage(writer, context, div, null, null, ie);
251 }
252 else
253 {
254 for (Iterator iter = areas.iterator(); iter.hasNext();)
255 {
256 String area = (String) iter.next();
257 addImage(writer, context, div, area, areas, ie);
258 }
259 }
260
261
262 writer.startElement(HTML.DIV_ELEM, div);
263
264 StringBuffer style = new StringBuffer("position: relative; z-index: 1;");
265 addPadding(Math.max(div.getBorderWidth().intValue(), div.getRadius()
266 .intValue()), style, areas);
267
268 String val;
269 if ((val = div.getContentStyle()) != null)
270 {
271 style.append(val);
272 }
273
274 writer.writeAttribute(HTML.STYLE_ATTR, style, null);
275 if ((val = div.getContentStyleClass()) != null)
276 {
277 writer.writeAttribute(HTML.CLASS_ATTR, val, null);
278 }
279 }
280
281 protected void encodeTable(FacesContext context, boolean ie,
282 HtmlRoundedDiv div, ResponseWriter writer, Set areas)
283 throws IOException
284 {
285 int padding = Math.max(div.getBorderWidth().intValue(), div.getRadius()
286 .intValue());
287
288 writer.writeAttribute(HTML.CELLPADDING_ATTR, "0", null);
289 writer.writeAttribute(HTML.CELLSPACING_ATTR, "0", null);
290
291 writer.startElement(HTML.TBODY_ELEM, div);
292
293 writer.startElement(HTML.TR_ELEM, div);
294 encodeImageColumn(writer, context, div, "topleft", areas, padding, ie);
295 encodeImageColumn(writer, context, div, "top", areas, padding, ie);
296 encodeImageColumn(writer, context, div, "topright", areas, padding, ie);
297 writer.endElement(HTML.TR_ELEM);
298 writer.startElement(HTML.TR_ELEM, div);
299 encodeImageColumn(writer, context, div, "left", areas, padding, ie);
300 encodeContentColumn(writer, context, div, areas, ie);
301 encodeImageColumn(writer, context, div, "right", areas, padding, ie);
302 writer.endElement(HTML.TR_ELEM);
303 writer.startElement(HTML.TR_ELEM, div);
304 encodeImageColumn(writer, context, div, "bottomleft", areas, padding,
305 ie);
306 encodeImageColumn(writer, context, div, "bottom", areas, padding, ie);
307 encodeImageColumn(writer, context, div, "bottomright", areas, padding,
308 ie);
309 writer.endElement(HTML.TR_ELEM);
310
311 writer.endElement(HTML.TBODY_ELEM);
312 }
313
314
315
316
317 public void encodeChildren(FacesContext context, UIComponent component)
318 throws IOException
319 {
320 if (!component.isRendered())
321 {
322 return;
323 }
324 HtmlRoundedDiv div = (HtmlRoundedDiv) component;
325 if ("div".equals(div.getValue()))
326 {
327 RendererUtils.renderChildren(context, component);
328 }
329 }
330
331
332
333
334 public void encodeEnd(FacesContext context, UIComponent component)
335 throws IOException
336 {
337 super.encodeEnd(context, component);
338 if (!component.isRendered())
339 {
340 return;
341 }
342 HtmlRoundedDiv div = (HtmlRoundedDiv) component;
343 if ("div".equals(div.getValue()))
344 {
345 context.getResponseWriter().endElement(HTML.DIV_ELEM);
346 }
347 }
348
349
350
351
352 public boolean getRendersChildren()
353 {
354 return true;
355 }
356
357
358
359
360
361
362
363
364 protected int getAreaAsSection(String area)
365 {
366 if ("top".equals(area))
367 {
368 return RoundedBorderGenerator.SECTION_TOP;
369 }
370 else if ("topright".equals(area))
371 {
372 return RoundedBorderGenerator.SECTION_TOPRIGHT;
373 }
374 else if ("right".equals(area))
375 {
376 return RoundedBorderGenerator.SECTION_RIGHT;
377 }
378 else if ("bottomright".equals(area))
379 {
380 return RoundedBorderGenerator.SECTION_BOTTOMRIGHT;
381 }
382 else if ("bottom".equals(area))
383 {
384 return RoundedBorderGenerator.SECTION_BOTTOM;
385 }
386 else if ("bottomleft".equals(area))
387 {
388 return RoundedBorderGenerator.SECTION_BOTTOMLEFT;
389 }
390 else if ("left".equals(area))
391 {
392 return RoundedBorderGenerator.SECTION_LEFT;
393 }
394 else if ("topleft".equals(area))
395 {
396 return RoundedBorderGenerator.SECTION_TOPLEFT;
397 }
398 else if ("center".equals(area))
399 {
400 return RoundedBorderGenerator.SECTION_CENTER;
401 }
402 else
403 {
404 throw new IllegalArgumentException("Invalid area: " + area);
405 }
406 }
407
408
409
410
411
412
413
414
415
416 protected Set getAreasToRender(FacesContext context,
417 HtmlRoundedDiv component)
418 {
419 String corners = component.getCorners();
420 Set areas = new HashSet();
421
422 if (corners != null)
423 {
424 String[] cornersArr = corners.split("\\s*,\\s*");
425 for (int i = 0; i < cornersArr.length; i++)
426 {
427 if ("topleft".equals(cornersArr[i]))
428 {
429 areas.add("top");
430 areas.add("left");
431 areas.add("topleft");
432 }
433 else if ("topright".equals(cornersArr[i]))
434 {
435 areas.add("top");
436 areas.add("right");
437 areas.add("topright");
438 }
439 else if ("bottomright".equals(cornersArr[i]))
440 {
441 areas.add("right");
442 areas.add("bottom");
443 areas.add("bottomright");
444 }
445 else if ("bottomleft".equals(cornersArr[i]))
446 {
447 areas.add("bottom");
448 areas.add("bottomleft");
449 areas.add("left");
450 }
451 else
452 {
453 throw new IllegalArgumentException("Invalid corner: "
454 + cornersArr[i]);
455 }
456 }
457 areas.add("center");
458 }
459 else
460 {
461 areas.add("top");
462 areas.add("topright");
463 areas.add("right");
464 areas.add("bottomright");
465 areas.add("bottom");
466 areas.add("bottomleft");
467 areas.add("left");
468 areas.add("topleft");
469 areas.add("center");
470 }
471 return areas;
472 }
473
474
475
476
477
478
479
480
481
482
483
484
485 protected void addImage(ResponseWriter writer, FacesContext context,
486 HtmlRoundedDiv component, String area, Set areas, boolean ie)
487 throws IOException
488 {
489 StringBuffer style = new StringBuffer(
490 "position: absolute;padding: 0px;margin: 0px;");
491 String url = getImageSource(context, component, area);
492 int padding = Math.max(component.getBorderWidth().intValue(), component
493 .getRadius().intValue());
494
495 if (ie)
496 {
497
498
499
500
501
502
503
504
505
506
507
508
509 if (areas != null)
510 {
511 setIECssPosition(padding, style, area, areas);
512 }
513 }
514 else if (areas != null)
515 {
516 setCssPosition(padding, style, area, areas);
517 }
518
519 writer.startElement(HTML.IMG_ELEM, component);
520 writer.writeAttribute(HTML.SRC_ATTR, url, null);
521 writer.writeAttribute(HTML.STYLE_ATTR, style, null);
522 writer.endElement(HTML.IMG_ELEM);
523 }
524
525
526
527
528
529
530
531
532
533 protected void setIECssPosition(int padding, StringBuffer style,
534 String area, Set areas)
535 {
536 if ("center".equals(area))
537 {
538 int p = 0;
539 if (areas.contains("left"))
540 {
541 p += padding;
542 }
543 if (areas.contains("right"))
544 {
545 p += padding;
546 }
547 style.append("width: expression((offsetParent.clientWidth - ")
548 .append(p).append(") + 'px');");
549
550 p = 0;
551 if (areas.contains("top"))
552 {
553 p += padding;
554 }
555 if (areas.contains("bottom"))
556 {
557 p += padding;
558 }
559 style.append("height: expression((offsetParent.clientHeight - ")
560 .append(p).append(") + 'px');");
561
562 style.append("top: ").append(areas.contains("top") ? padding : 0)
563 .append("px;");
564 style.append("left: ").append(areas.contains("left") ? padding : 0)
565 .append("px;");
566 }
567 else if ("top".equals(area))
568 {
569 style.append("top: 0px;");
570 style.append("left: ").append(areas.contains("left") ? padding : 0)
571 .append("px;");
572 style.append("height: ").append(padding).append("px;");
573
574 int p = 0;
575 if (areas.contains("left"))
576 {
577 p += padding;
578 }
579 if (areas.contains("right"))
580 {
581 p += padding;
582 }
583 style.append("width: expression((offsetParent.clientWidth - ")
584 .append(p).append(") + 'px');");
585 }
586 else if ("topright".equals(area))
587 {
588 style.append("top: 0px;");
589 style.append("right: 0px;");
590 }
591 else if ("right".equals(area))
592 {
593 style.append("top: ").append(areas.contains("top") ? padding : 0)
594 .append("px;");
595 style.append("right: 0px;");
596 style.append("width: ").append(padding).append("px;");
597
598 int p = 0;
599 if (areas.contains("top"))
600 {
601 p += padding;
602 }
603 if (areas.contains("bottom"))
604 {
605 p += padding;
606 }
607 style.append("height: expression((offsetParent.clientHeight - ")
608 .append(p).append(") + 'px');");
609 }
610 else if ("bottomright".equals(area))
611 {
612 style.append("right: 0px;");
613 style.append("bottom: 0px;");
614 }
615 else if ("bottom".equals(area))
616 {
617 style.append("bottom: 0px;");
618 style.append("left: ").append(areas.contains("left") ? padding : 0)
619 .append("px;");
620 style.append("height: ").append(padding).append("px;");
621
622 int p = 0;
623 if (areas.contains("left"))
624 {
625 p += padding;
626 }
627 if (areas.contains("right"))
628 {
629 p += padding;
630 }
631 style.append("width: expression((offsetParent.clientWidth - ")
632 .append(p).append(") + 'px');");
633 }
634 else if ("bottomleft".equals(area))
635 {
636 style.append("bottom: 0px;");
637 style.append("left: 0px;");
638 }
639 else if ("left".equals(area))
640 {
641 style.append("top: ").append(areas.contains("top") ? padding : 0)
642 .append("px;");
643 style.append("left: 0px;");
644 style.append("width: ").append(padding).append("px;");
645
646 int p = 0;
647 if (areas.contains("top"))
648 {
649 p += padding;
650 }
651 if (areas.contains("bottom"))
652 {
653 p += padding;
654 }
655 style.append("height: expression((offsetParent.clientHeight - ")
656 .append(p).append(") + 'px');");
657 }
658 else
659
660 {
661 style.append("top: 0px;");
662 style.append("left: 0px;");
663 }
664 }
665
666 protected void encodeContentColumn(ResponseWriter writer,
667 FacesContext context, HtmlRoundedDiv component, Set areas,
668 boolean ie) throws IOException
669 {
670 writer.startElement(HTML.TD_ELEM, component);
671 String val;
672 StringBuffer style = new StringBuffer();
673
674 if ((val = component.getContentStyle()) != null)
675 {
676 style.append(val).append(';');
677 }
678 style.append("background-image: url('").append(
679 getImageSource(context, component, "center")).append("');");
680 writer.writeAttribute(HTML.STYLE_ATTR, style, null);
681
682 if ((val = component.getContentStyleClass()) != null)
683 {
684 writer.writeAttribute(HTML.CLASS_ATTR, val, null);
685 }
686
687 RendererUtils.renderChildren(context, component);
688
689 writer.endElement(HTML.TD_ELEM);
690 }
691
692 protected void encodeImageColumn(ResponseWriter writer,
693 FacesContext context, HtmlRoundedDiv component, String area,
694 Set areas, int padding, boolean ie) throws IOException
695 {
696 writer.startElement(HTML.TD_ELEM, component);
697 writer.writeAttribute(HTML.CLASS_ATTR, area, null);
698 if (areas.contains(area))
699 {
700 StringBuffer style = new StringBuffer("font-size: 1px; background-image: url('")
701 .append(getImageSource(context,
702 component, area)).append("');")
703 .append("background-position: top left;");
704
705 if ("left".equals(area) || "right".equals(area))
706 {
707 style.append("background-repeat: repeat-y; width: ")
708 .append(padding).append("px;");
709 }
710 else if ("top".equals(area) || "bottom".equals(area))
711 {
712 style.append("background-repeat: repeat-x; height: ")
713 .append(padding).append("px;");
714 }
715
716 writer.writeAttribute(HTML.STYLE_ATTR, style, null);
717
718
719 writer.write(" ");
720 }
721 writer.endElement(HTML.TD_ELEM);
722 }
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754 protected void setCssPosition(int padding, StringBuffer style, String area,
755 Set areas)
756 {
757 if ("center".equals(area))
758 {
759 style.append("top: ").append(areas.contains("top") ? padding : 0)
760 .append("px;");
761 style.append("right: ").append(
762 areas.contains("right") ? padding : 0).append("px;");
763 style.append("bottom: ").append(
764 areas.contains("bottom") ? padding : 0).append("px;");
765 style.append("left: ").append(areas.contains("left") ? padding : 0)
766 .append("px;");
767 }
768 else if ("top".equals(area))
769 {
770 style.append("top: 0px;");
771 style.append("right: ").append(
772 areas.contains("right") ? padding : 0).append("px;");
773 style.append("left: ").append(areas.contains("left") ? padding : 0)
774 .append("px;");
775 style.append("height: ").append(padding).append("px;");
776 }
777 else if ("topright".equals(area))
778 {
779 style.append("top: 0px;");
780 style.append("right: 0px;");
781 }
782 else if ("right".equals(area))
783 {
784 style.append("top: ").append(areas.contains("top") ? padding : 0)
785 .append("px;");
786 style.append("right: 0px;");
787 style.append("bottom: ").append(
788 areas.contains("bottom") ? padding : 0).append("px;");
789 style.append("width: ").append(padding).append("px;");
790 }
791 else if ("bottomright".equals(area))
792 {
793 style.append("right: 0px;");
794 style.append("bottom: 0px;");
795 }
796 else if ("bottom".equals(area))
797 {
798 style.append("right: ").append(
799 areas.contains("right") ? padding : 0).append("px;");
800 style.append("bottom: 0px;");
801 style.append("left: ").append(areas.contains("left") ? padding : 0)
802 .append("px;");
803 style.append("height: ").append(padding).append("px;");
804 }
805 else if ("bottomleft".equals(area))
806 {
807 style.append("bottom: 0px;");
808 style.append("left: 0px;");
809 }
810 else if ("left".equals(area))
811 {
812 style.append("top: ").append(areas.contains("top") ? padding : 0)
813 .append("px;");
814 style.append("bottom: ").append(
815 areas.contains("bottom") ? padding : 0).append("px;");
816 style.append("left: 0px;");
817 style.append("width: ").append(padding).append("px;");
818 }
819 else
820
821 {
822 style.append("top: 0px;");
823 style.append("left: 0px;");
824 }
825 }
826
827
828
829
830
831
832
833
834
835
836 protected String getImageSource(FacesContext context,
837 HtmlRoundedDiv component, String area)
838 {
839 AddResource addResource = AddResourceFactory.getInstance(context);
840 return addResource.getResourceUri(context,
841 new ParameterResourceHandler(this.getClass(),
842 buildParameterMap(component, area)));
843 }
844
845
846
847
848
849
850
851
852
853 protected void addPadding(int padding, StringBuffer style, Set areas)
854 {
855 int top = 0, right = 0, bottom = 0, left = 0;
856 if (areas == null || areas.contains("top"))
857 {
858 top = padding;
859 }
860 if (areas == null || areas.contains("right"))
861 {
862 right = padding;
863 }
864 if (areas == null || areas.contains("bottom"))
865 {
866 bottom = padding;
867 }
868 if (areas == null || areas.contains("left"))
869 {
870 left = padding;
871 }
872
873 style.append(" padding: ").append(top).append("px ").append(right)
874 .append("px ").append(bottom).append("px ").append(left)
875 .append("px;");
876 }
877
878 protected Dimension _getSize(HtmlRoundedDiv component){
879 String size = component.getSize();
880
881 Matcher m = Pattern.compile("(\\d+)\\D+(\\d+)").matcher(size);
882 if (!m.find())
883 {
884 throw new IllegalArgumentException("Invalid dimension");
885 }
886 return new Dimension(Integer.parseInt(m.group(1)), Integer
887 .parseInt(m.group(2)));
888 }
889
890
891
892
893
894
895
896
897 protected Map buildParameterMap(HtmlRoundedDiv component, String area)
898 {
899 Map map = new HashMap(7);
900 if (component.getColor() != null){
901 map.put("c", colorToHtml(Color.decode(component.getColor())));
902 }
903 Color c;
904 if (component.getBackgroundColor() != null)
905 {
906 c = Color.decode(component.getBackgroundColor());
907 map.put("bgc", colorToHtml(c));
908 }
909 if ( component.getBorderColor() != null)
910 {
911 c = Color.decode(component.getBorderColor());
912 map.put("bc", colorToHtml(c));
913 }
914
915 map.put("bw", component.getBorderWidth().toString());
916 map.put("r", component.getRadius().toString());
917 Dimension d;
918 if ( component.getSize() != null)
919 {
920 d = _getSize(component);
921 map.put("s", d.width + "x"
922 + d.height);
923 }
924 if (area != null)
925 {
926 map.put("a", area);
927 }
928 map.put("i", component.getInverse().booleanValue() ? "t" : "f");
929 return map;
930 }
931
932
933
934
935
936
937
938 protected String colorToHtml(Color c)
939 {
940 int rbg = c.getRGB();
941 String[] strs = { Integer.toHexString((rbg >> 16) & 0xFF),
942 Integer.toHexString((rbg >> 8) & 0xFF),
943 Integer.toHexString(rbg & 0xFF) };
944
945 StringBuffer sb = new StringBuffer();
946 for (int i = 0; i < strs.length; i++)
947 {
948 if (strs[i].length() == 1)
949 {
950 sb.append('0');
951 }
952 sb.append(strs[i]);
953 }
954 return sb.toString();
955 }
956
957
958
959
960
961
962
963 protected boolean isIE(FacesContext context)
964 {
965 try
966 {
967 String userAgent = context.getExternalContext()
968 .getRequestHeaderMap().get("User-Agent").toString();
969
970 return userAgent.toUpperCase().indexOf("MSIE") >= 0;
971 }
972 catch (NullPointerException ex)
973 {
974
975 return false;
976 }
977 }
978
979 private void initCache(ServletContext context)
980 {
981 if (cacheSize != null)
982 {
983 return;
984 }
985 synchronized (imageCache)
986 {
987 if (cacheSize != null)
988 {
989 return;
990 }
991
992 String param = context.getInitParameter(CACHE_SIZE_KEY);
993 if (cacheSize == null)
994 {
995 cacheSize = new Integer(DEFAULT_CACHE_SIZE);
996 }
997 else
998 {
999 try
1000 {
1001 cacheSize = new Integer(Integer.parseInt(param));
1002 }
1003 catch (NumberFormatException ex)
1004 {
1005 log.error("Unabled to parse cache size, using default", ex);
1006 cacheSize = new Integer(DEFAULT_CACHE_SIZE);
1007 }
1008 }
1009 log.debug("Using a cache of size: " + cacheSize);
1010 }
1011 }
1012
1013 protected String getCacheKey(String queryString)
1014 {
1015 int from = queryString.indexOf("&a=") + 1;
1016
1017 if (from == -1)
1018 {
1019 return queryString;
1020 }
1021
1022 int to = queryString.indexOf('&', from + 1);
1023
1024 return to == -1 ? queryString.substring(0, from) : queryString.substring(
1025 0, from) + queryString.substring(to);
1026 }
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 }