1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.webapp;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.Stack;
29 import java.util.concurrent.atomic.AtomicInteger;
30 import java.util.logging.Level;
31
32 import javax.faces.component.NamingContainer;
33 import javax.faces.component.UIComponent;
34 import javax.faces.component.UIOutput;
35 import javax.faces.component.UIViewRoot;
36 import javax.faces.context.FacesContext;
37 import javax.faces.render.ResponseStateManager;
38 import javax.servlet.jsp.JspException;
39 import javax.servlet.jsp.JspWriter;
40 import javax.servlet.jsp.PageContext;
41 import javax.servlet.jsp.jstl.core.LoopTag;
42 import javax.servlet.jsp.tagext.BodyContent;
43 import javax.servlet.jsp.tagext.BodyTag;
44 import javax.servlet.jsp.tagext.JspIdConsumer;
45 import javax.servlet.jsp.tagext.Tag;
46
47
48
49
50
51
52
53
54
55
56 public abstract class UIComponentClassicTagBase extends UIComponentTagBase
57 implements BodyTag, JspIdConsumer
58 {
59
60
61 private static final String COMPONENT_STACK_ATTR = "org.apache.myfaces.COMPONENT_STACK";
62
63 private static final String REQUEST_FACES_CONTEXT = "org.apache.myfaces.REQUEST_FACES_CONTEXT";
64
65 private static final String VIEW_IDS = "org.apache.myfaces.VIEW_IDS";
66
67 private static final String FORMER_CHILD_IDS_SET_ATTR = "org.apache.myfaces.FORMER_CHILD_IDS";
68 private static final String FORMER_FACET_NAMES_SET_ATTR = "org.apache.myfaces.FORMER_FACET_NAMES";
69
70 private static final String PREVIOUS_JSP_IDS_SET = "org.apache.myfaces.PREVIOUS_JSP_IDS_SET";
71
72 private static final String BOUND_VIEW_ROOT = "org.apache.myfaces.BOUND_VIEW_ROOT";
73
74 private static final String LOGICAL_PAGE_ID = "org.apache.myfaces.LOGICAL_PAGE_ID";
75
76 private static final String LOGICAL_PAGE_COUNTER = "org.apache.myfaces.LOGICAL_PAGE_COUNTER";
77
78 protected static final String UNIQUE_ID_PREFIX = UIViewRoot.UNIQUE_ID_PREFIX + "_";
79
80 protected PageContext pageContext = null;
81 protected BodyContent bodyContent = null;
82
83 private boolean _created = false;
84
85 private String _jspId = null;
86 private String _facesJspId = null;
87
88 private List<String> _childrenAdded = null;
89 private List<String> _facetsAdded = null;
90
91 private UIComponent _componentInstance = null;
92 private String _id = null;
93
94 private boolean isInAnIterator;
95
96
97 private Tag _parent = null;
98
99
100 private UIComponentClassicTagBase _parentClassicTag = null;
101
102 private FacesContext _facesContext = null;
103
104 protected abstract void setProperties(UIComponent component);
105
106 protected abstract UIComponent createComponent(FacesContext context,
107 String newId) throws JspException;
108
109 public void release()
110 {
111 internalRelease();
112
113
114
115 pageContext = null;
116 _parent = null;
117 _jspId = null;
118 _id = null;
119 _facesJspId = null;
120 bodyContent = null;
121 }
122
123
124
125
126
127
128
129
130 private void internalRelease()
131 {
132 _facesContext = null;
133 _componentInstance = null;
134 _created = false;
135
136 _childrenAdded = null;
137 _facetsAdded = null;
138 }
139
140
141
142
143 public boolean getCreated()
144 {
145 return _created;
146 }
147
148 protected List<String> getCreatedComponents() {
149 return _childrenAdded;
150 }
151
152
153
154
155
156
157 public static UIComponentClassicTagBase getParentUIComponentClassicTagBase(
158 PageContext pageContext)
159 {
160 Stack<UIComponentClassicTagBase> stack = getStack(pageContext);
161
162 int size = stack.size();
163
164 return size > 0 ? stack.get(size - 1) : null;
165 }
166
167
168
169
170
171 public String getJspId()
172 {
173 return _jspId;
174 }
175
176 public void setJspId(String jspId)
177 {
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 Integer logicalPageId = (Integer) pageContext.getAttribute(LOGICAL_PAGE_ID);
212
213 if (logicalPageId != null)
214 {
215 if (logicalPageId.intValue() == 1)
216 {
217
218 _jspId = jspId;
219 }
220 else
221 {
222
223 _jspId = jspId + "pc" + logicalPageId;
224 }
225 }
226 else
227 {
228 Map<String,Object> requestMap = getFacesContext().getExternalContext().getRequestMap();
229 AtomicInteger logicalPageCounter = (AtomicInteger) requestMap.get(LOGICAL_PAGE_COUNTER);
230
231 if (logicalPageCounter == null)
232 {
233
234 logicalPageCounter = new AtomicInteger(1);
235 logicalPageId = 1;
236 requestMap.put(LOGICAL_PAGE_COUNTER, logicalPageCounter);
237 pageContext.setAttribute(LOGICAL_PAGE_ID, logicalPageId);
238 }
239 else
240 {
241
242 logicalPageId = logicalPageCounter.incrementAndGet();
243 pageContext.setAttribute(LOGICAL_PAGE_ID, logicalPageId);
244 _jspId = jspId + "pc" + logicalPageId;
245 }
246 }
247 _facesJspId = null;
248 checkIfItIsInAnIterator(_jspId);
249 }
250
251
252
253
254
255
256
257 protected void addChild(UIComponent child)
258 {
259 if (_childrenAdded == null)
260 {
261 _childrenAdded = new ArrayList<String>();
262 }
263
264 _childrenAdded.add(child.getId());
265 }
266
267
268
269
270
271 protected void addFacet(String name)
272 {
273 if (_facetsAdded == null)
274 {
275 _facetsAdded = new ArrayList<String>();
276 }
277
278 _facetsAdded.add(name);
279 }
280
281
282
283
284
285 public UIComponent getComponentInstance()
286 {
287 return _componentInstance;
288 }
289
290
291
292
293
294
295 protected FacesContext getFacesContext()
296 {
297 if (_facesContext != null)
298 {
299 return _facesContext;
300 }
301
302 _facesContext = pageContext == null ? null : (FacesContext) pageContext.getAttribute(REQUEST_FACES_CONTEXT);
303
304 if (_facesContext != null)
305 {
306 return _facesContext;
307 }
308
309 _facesContext = FacesContext.getCurrentInstance();
310
311 if (_facesContext != null)
312 {
313 if(pageContext != null)
314 {
315 pageContext.setAttribute(REQUEST_FACES_CONTEXT, _facesContext);
316 }
317 return _facesContext;
318 }
319
320
321 throw new RuntimeException("FacesContext not found");
322 }
323
324
325
326
327
328
329 protected int getIndexOfNextChildTag()
330 {
331 if (_childrenAdded == null)
332 {
333 return 0;
334 }
335
336 return _childrenAdded.size();
337 }
338
339
340
341
342
343 public void setId(String id)
344 {
345 if (id != null && id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
346 {
347 throw new IllegalArgumentException("Id is non-null and starts with UIViewRoot.UNIQUE_ID_PREFIX: "+id);
348 }
349
350 _id = id;
351 }
352
353
354
355
356 protected String getId()
357 {
358 return _id;
359 }
360
361 protected String getFacesJspId() {
362 if (_facesJspId == null)
363 {
364 if (_jspId != null)
365 {
366 _facesJspId = UNIQUE_ID_PREFIX + _jspId;
367
368 if (isIdDuplicated(_facesJspId)) {
369 _facesJspId = createNextId(_facesJspId);
370 }
371 }
372 else
373 {
374 _facesJspId = _facesContext.getViewRoot().createUniqueId();
375 }
376 }
377
378 return _facesJspId;
379 }
380
381 public void setBodyContent(BodyContent bodyContent)
382 {
383 this.bodyContent = bodyContent;
384 }
385
386 public void doInitBody() throws JspException
387 {
388
389 }
390
391 public int doAfterBody() throws JspException
392 {
393 UIComponentClassicTagBase parentTag = getParentUIComponentClassicTagBase(pageContext);
394
395 if (isRootTag(parentTag) || isInRenderedChildrenComponent(parentTag))
396 {
397 UIComponent verbatimComp = createVerbatimComponentFromBodyContent();
398
399 if (verbatimComp != null)
400 {
401 List<String> childrenAddedIds = (List<String>)
402 _componentInstance.getAttributes().get(FORMER_CHILD_IDS_SET_ATTR);
403
404 if (childrenAddedIds == null)
405 {
406 _componentInstance.getChildren().add(verbatimComp);
407 }
408 else
409 {
410 int index = _componentInstance.getChildCount();
411 if (childrenAddedIds.size() == index)
412 {
413
414 _componentInstance.getChildren().add(index-1, verbatimComp);
415 }
416 else
417 {
418 _componentInstance.getChildren().add(verbatimComp);
419 }
420 }
421
422
423 if(parentTag!=null) {
424 parentTag.addChild(verbatimComp);
425 }
426 }
427 }
428
429 return getDoAfterBodyValue();
430 }
431
432
433
434
435
436
437 public void setPageContext(PageContext pageContext)
438 {
439 this.pageContext = pageContext;
440 }
441
442
443
444
445
446 public Tag getParent()
447 {
448 return _parent;
449 }
450
451
452
453
454
455 public void setParent(Tag tag)
456 {
457 this._parent = tag;
458 }
459
460 public BodyContent getBodyContent()
461 {
462 return bodyContent;
463 }
464
465 public int doStartTag() throws JspException
466 {
467 this._facesContext = getFacesContext();
468
469 if (_facesContext == null)
470 {
471 throw new JspException("FacesContext not found");
472 }
473
474 _childrenAdded = null;
475 _facetsAdded = null;
476
477 _parentClassicTag = getParentUIComponentClassicTagBase(pageContext);
478
479 UIComponent verbatimComp = null;
480
481
482
483 if (!isFacet())
484 {
485 Tag parent = getParent();
486
487
488 if (parent != null && parent instanceof LoopTag)
489 {
490 JspWriter outWriter = pageContext.getOut();
491 boolean insideJspTag = (outWriter instanceof BodyContent);
492
493 if (!insideJspTag)
494 {
495 try
496 {
497 outWriter.flush();
498 }
499 catch (IOException e)
500 {
501 throw new JspException("Exception flushing when creating verbatim _componentInstance", e);
502 }
503 }
504 }
505
506
507 if (_parentClassicTag != null)
508 {
509 verbatimComp = _parentClassicTag.createVerbatimComponentFromBodyContent();
510 }
511 }
512
513
514 _componentInstance = findComponent(_facesContext);
515
516
517 if (verbatimComp != null && _parentClassicTag != null)
518 {
519 addVerbatimBeforeComponent(_parentClassicTag, verbatimComp, _componentInstance);
520 }
521
522 Map<String,Object> viewComponentIds = getViewComponentIds();
523
524
525
526 Object tagInstance = null;
527 String clientId = null;
528 if (_id != null) {
529 clientId = _componentInstance.getClientId(_facesContext);
530 tagInstance = (viewComponentIds.get(clientId) == this) ? this : null;
531 }
532
533 if (tagInstance == null)
534 {
535
536 if (_id != null)
537 {
538 if (clientId != null)
539 {
540 if (viewComponentIds.containsKey(clientId))
541 {
542 throw new JspException("Duplicated component Id: '"+clientId+"' " +
543 "for component: '"+getPathToComponent(_componentInstance)+"'.");
544 }
545
546 viewComponentIds.put(clientId, this);
547 }
548 }
549
550
551 if (_parentClassicTag != null)
552 {
553 if (isFacet())
554 {
555 _parentClassicTag.addFacet(getFacetName());
556 }
557 else
558 {
559 _parentClassicTag.addChild(_componentInstance);
560 }
561 }
562 }
563
564
565 pushTag();
566
567 return getDoStartValue();
568 }
569
570 public int doEndTag() throws JspException
571 {
572 popTag();
573 UIComponent component = getComponentInstance();
574
575 removeFormerChildren(component);
576 removeFormerFacets(component);
577
578 try
579 {
580 UIComponentClassicTagBase parentTag =
581 getParentUIComponentClassicTagBase(pageContext);
582
583 UIComponent verbatimComp = createVerbatimComponentFromBodyContent();
584
585 if (verbatimComp != null)
586 {
587 component.getChildren().add(verbatimComp);
588
589 if (parentTag != null)
590 {
591 parentTag.addChild(verbatimComp);
592 }
593 }
594 }
595 catch (Throwable e)
596 {
597 throw new JspException(e);
598 }
599 finally
600 {
601 component = null;
602 }
603
604 int retValue = getDoEndValue();
605
606 internalRelease();
607
608 return retValue;
609 }
610
611 protected int getDoAfterBodyValue() throws javax.servlet.jsp.JspException
612 {
613 return SKIP_BODY;
614 }
615
616
617
618
619
620
621
622
623
624
625 protected int getDoStartValue()
626 throws JspException
627 {
628 return BodyTag.EVAL_BODY_BUFFERED;
629 }
630
631
632
633
634
635
636
637
638
639
640 protected int getDoEndValue()
641 throws JspException
642 {
643 return Tag.EVAL_PAGE;
644 }
645
646 protected String getFacetName()
647 {
648 return isFacet() ? ((FacetTag)_parent).getName() : null;
649 }
650
651
652
653
654
655 protected UIComponent createVerbatimComponentFromBodyContent()
656 {
657 UIOutput verbatimComp = null;
658
659 if (bodyContent != null)
660 {
661 String strContent = bodyContent.getString();
662
663 if (strContent != null)
664 {
665 String trimmedContent = strContent.trim();
666 if (trimmedContent.length() > 0 && !isComment(strContent))
667 {
668 verbatimComp = createVerbatimComponent();
669 verbatimComp.setValue(strContent);
670 }
671 }
672
673 bodyContent.clearBody();
674 }
675
676 return verbatimComp;
677 }
678
679 private static boolean isComment(String bodyContent)
680 {
681 return (bodyContent.startsWith("<!--") && bodyContent.endsWith("-->"));
682 }
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697 protected UIOutput createVerbatimComponent()
698 {
699 UIOutput verbatimComp = (UIOutput) getFacesContext().getApplication()
700 .createComponent("javax.faces.HtmlOutputText");
701 verbatimComp.setTransient(true);
702 verbatimComp.getAttributes().put("escape", Boolean.FALSE);
703 verbatimComp.setId(getFacesContext().getViewRoot().createUniqueId());
704
705 return verbatimComp;
706 }
707
708 protected void addVerbatimBeforeComponent(
709 UIComponentClassicTagBase parentTag,
710 UIComponent verbatimComp,
711 UIComponent component)
712 {
713 UIComponent parent = component.getParent();
714
715 if (parent == null)
716 {
717 return;
718 }
719
720 List<UIComponent> children = parent.getChildren();
721
722
723
724
725
726
727
728
729
730 List<String> childrenAddedIds = (List<String>)
731 parent.getAttributes().get(FORMER_CHILD_IDS_SET_ATTR);
732
733
734 int parentIndex = children.indexOf(component);
735
736 if (childrenAddedIds != null)
737 {
738 if (parentIndex > 0 && childrenAddedIds.size() == parentIndex)
739 {
740 UIComponent formerVerbatim = children.get(parentIndex - 1);
741
742 if (formerVerbatim instanceof UIOutput && formerVerbatim.isTransient())
743 {
744 children.set(parentIndex - 1, verbatimComp);
745 }
746 }
747 }
748
749 children.add(parentIndex, verbatimComp);
750
751 parentTag.addChild(verbatimComp);
752 }
753
754
755
756
757
758
759
760
761 protected void addVerbatimAfterComponent(UIComponentClassicTagBase parentTag,
762 UIComponent verbatim,
763 UIComponent component)
764 {
765 int indexOfComponentInParent = 0;
766 UIComponent parent = component.getParent();
767
768
769
770
771
772 if (null == parent)
773 {
774 return;
775 }
776 List<UIComponent> children = parent.getChildren();
777 indexOfComponentInParent = children.indexOf(component);
778 if (children.size() - 1 == indexOfComponentInParent)
779 {
780 children.add(verbatim);
781 }
782 else
783 {
784 children.add(indexOfComponentInParent + 1, verbatim);
785 }
786 parentTag.addChild(verbatim);
787 }
788
789
790
791
792
793 protected void setupResponseWriter() {
794 }
795
796
797
798
799
800
801 protected void encodeBegin()
802 throws IOException
803 {
804 if (log.isLoggable(Level.FINE))
805 log.fine("Entered encodeBegin for client-Id: " + _componentInstance.getClientId(getFacesContext()));
806 _componentInstance.encodeBegin(getFacesContext());
807 if (log.isLoggable(Level.FINE))
808 log.fine("Exited encodeBegin");
809 }
810
811
812
813
814
815
816
817 protected void encodeChildren()
818 throws IOException
819 {
820 if (log.isLoggable(Level.FINE))
821 log.fine("Entered encodeChildren for client-Id: " + _componentInstance.getClientId(getFacesContext()));
822 _componentInstance.encodeChildren(getFacesContext());
823 if (log.isLoggable(Level.FINE))
824 log.fine("Exited encodeChildren for client-Id: " + _componentInstance.getClientId(getFacesContext()));
825 }
826
827
828
829
830
831
832 protected void encodeEnd()
833 throws IOException
834 {
835 if (log.isLoggable(Level.FINE))
836 log.fine("Entered encodeEnd for client-Id: " + _componentInstance.getClientId(getFacesContext()));
837 _componentInstance.encodeEnd(getFacesContext());
838 if (log.isLoggable(Level.FINE))
839 log.fine("Exited encodeEnd for client-Id: " + _componentInstance.getClientId(getFacesContext()));
840
841 }
842
843
844
845 private boolean isRootTag(UIComponentClassicTagBase parentTag)
846 {
847 return (parentTag == this);
848 }
849
850 private boolean isInRenderedChildrenComponent (UIComponentClassicTagBase tag)
851 {
852 return (_parentClassicTag != null && tag.getComponentInstance().getRendersChildren());
853 }
854
855 private boolean isFacet()
856 {
857 return _parent != null && _parent instanceof FacetTag;
858 }
859
860
861 @SuppressWarnings("unchecked")
862 private Map<String, Object> getViewComponentIds()
863 {
864 Map<String, Object> requestMap = _facesContext.getExternalContext().getRequestMap();
865 Map<String, Object> viewComponentIds;
866
867 if (_parent == null)
868 {
869
870 viewComponentIds = new HashMap<String, Object>();
871 requestMap.put(VIEW_IDS, viewComponentIds);
872 }
873 else
874 {
875 viewComponentIds = (Map<String, Object>)requestMap.get(VIEW_IDS);
876
877
878
879 if (viewComponentIds == null)
880 {
881 viewComponentIds = new HashMap<String, Object>();
882 requestMap.put(VIEW_IDS, viewComponentIds);
883 }
884 }
885
886 return viewComponentIds;
887 }
888
889
890 private static final Stack<UIComponentClassicTagBase> getStack(PageContext pageContext)
891 {
892 Stack<UIComponentClassicTagBase> stack = (Stack<UIComponentClassicTagBase>) pageContext.getAttribute(COMPONENT_STACK_ATTR,
893 PageContext.REQUEST_SCOPE);
894
895 if (stack == null)
896 {
897 stack = new Stack<UIComponentClassicTagBase>();
898 pageContext.setAttribute(COMPONENT_STACK_ATTR,
899 stack, PageContext.REQUEST_SCOPE);
900 }
901
902 return stack;
903 }
904
905
906
907
908
909
910
911
912 private void popTag()
913 {
914 Stack<UIComponentClassicTagBase> stack = getStack(pageContext);
915
916 int size = stack.size();
917 stack.remove(size -1);
918 if (size <= 1)
919 pageContext.removeAttribute(COMPONENT_STACK_ATTR,
920 PageContext.REQUEST_SCOPE);
921
922 }
923
924 private void pushTag()
925 {
926 getStack(pageContext).add(this);
927 }
928
929
930
931
932
933
934
935 private String getPathToComponent(UIComponent component)
936 {
937 StringBuffer buf = new StringBuffer();
938
939 if(component == null)
940 {
941 buf.append("{Component-Path : ");
942 buf.append("[null]}");
943 return buf.toString();
944 }
945
946 getPathToComponent(component,buf);
947
948 buf.insert(0,"{Component-Path : ");
949 buf.append("}");
950
951 return buf.toString();
952 }
953
954
955 private static void getPathToComponent(UIComponent component, StringBuffer buf)
956 {
957 if(component == null)
958 return;
959
960 StringBuffer intBuf = new StringBuffer();
961
962 intBuf.append("[Class: ");
963 intBuf.append(component.getClass().getName());
964 if(component instanceof UIViewRoot)
965 {
966 intBuf.append(",ViewId: ");
967 intBuf.append(((UIViewRoot) component).getViewId());
968 }
969 else
970 {
971 intBuf.append(",Id: ");
972 intBuf.append(component.getId());
973 }
974 intBuf.append("]");
975
976 buf.insert(0,intBuf);
977
978 getPathToComponent(component.getParent(),buf);
979 }
980
981
982
983
984
985
986
987
988
989
990
991
992 private void removeFormerChildren(UIComponent component)
993 {
994 List<String> formerChildIds = (List<String>)component.getAttributes().get(FORMER_CHILD_IDS_SET_ATTR);
995 if (formerChildIds != null)
996 {
997 for (String childId : formerChildIds)
998 {
999 if (_childrenAdded == null || !_childrenAdded.contains(childId))
1000 {
1001 UIComponent childToRemove = component.findComponent(childId);
1002 if (childToRemove != null)
1003 {
1004 component.getChildren().remove(childToRemove);
1005 }
1006 }
1007 }
1008 if (_childrenAdded == null)
1009 {
1010 component.getAttributes().remove(FORMER_CHILD_IDS_SET_ATTR);
1011 }
1012 else
1013 {
1014 component.getAttributes().put(FORMER_CHILD_IDS_SET_ATTR, _childrenAdded);
1015 }
1016 }
1017 else
1018 {
1019 if (_childrenAdded != null)
1020 {
1021 component.getAttributes().put(FORMER_CHILD_IDS_SET_ATTR, _childrenAdded);
1022 }
1023 }
1024 }
1025
1026
1027 private void removeFormerFacets(UIComponent component)
1028 {
1029 List<String> formerFacetNames = (List<String>)component.getAttributes().get(FORMER_FACET_NAMES_SET_ATTR);
1030 if (formerFacetNames != null)
1031 {
1032 for (String facetName : formerFacetNames)
1033 {
1034 if (_facetsAdded == null || !_facetsAdded.contains(facetName)) {
1035 component.getFacets().remove(facetName);
1036 }
1037 }
1038 if (_facetsAdded == null)
1039 {
1040 component.getAttributes().remove(FORMER_FACET_NAMES_SET_ATTR);
1041 }
1042 else
1043 {
1044 component.getAttributes().put(FORMER_FACET_NAMES_SET_ATTR, _facetsAdded);
1045 }
1046 }
1047 else
1048 {
1049 if (_facetsAdded != null)
1050 {
1051 component.getAttributes().put(FORMER_FACET_NAMES_SET_ATTR, _facetsAdded);
1052 }
1053 }
1054 }
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082 protected UIComponent findComponent(FacesContext context)
1083 throws JspException
1084 {
1085
1086 if (_componentInstance != null)
1087 {
1088 return _componentInstance;
1089 }
1090
1091
1092
1093
1094 UIComponentClassicTagBase parentTag = getParentUIComponentClassicTagBase(pageContext);
1095
1096 if (parentTag == null)
1097 {
1098
1099 _componentInstance = context.getViewRoot();
1100
1101
1102 Object alreadyBoundViewRootFlag = _componentInstance.getAttributes().get(BOUND_VIEW_ROOT);
1103
1104 if (alreadyBoundViewRootFlag == null)
1105 {
1106 try
1107 {
1108 setProperties(_componentInstance);
1109 }
1110 catch (Throwable e)
1111 {
1112 throw new JspException(e);
1113 }
1114
1115 if (_id != null)
1116 {
1117 _componentInstance.setId(_id);
1118 }
1119 else
1120 {
1121 _componentInstance.setId(getFacesJspId());
1122 }
1123 _componentInstance.getAttributes().put(BOUND_VIEW_ROOT, true);
1124 _created = true;
1125
1126 }
1127 else if (hasBinding())
1128 {
1129 setProperties(_componentInstance);
1130 }
1131
1132 return _componentInstance;
1133 }
1134
1135 UIComponent parent = parentTag.getComponentInstance();
1136
1137 if (parent == null)
1138 {
1139 throw new IllegalStateException("parent is null?");
1140 }
1141
1142 String facetName = getFacetName();
1143 if (facetName != null)
1144 {
1145
1146 String id = createUniqueId(context, parent);
1147 _componentInstance = parent.getFacet(facetName);
1148 if (_componentInstance == null)
1149 {
1150 _componentInstance = createComponent(context, id);
1151 _created = true;
1152 parent.getFacets().put(facetName, _componentInstance);
1153 }
1154 else
1155 {
1156 if (checkFacetNameOnParentExists(parentTag, facetName))
1157 {
1158 throw new IllegalStateException("facet '" + facetName + "' already has a child associated. current associated _componentInstance id: "
1159 + _componentInstance.getClientId(context) + " class: " + _componentInstance.getClass().getName());
1160 }
1161 }
1162
1163 addFacetNameToParentTag(parentTag, facetName);
1164 return _componentInstance;
1165 }
1166
1167
1168
1169
1170
1171
1172
1173
1174 String id = createUniqueId(context, parent);
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184 if(parentTag._childrenAdded != null && parentTag._childrenAdded.contains(id))
1185 {
1186 if(log.isLoggable(Level.WARNING))
1187 log.warning("There is more than one JSF tag with an id : " + id);
1188 }
1189
1190 _componentInstance = findComponent(parent,id);
1191 if (_componentInstance == null)
1192 {
1193 _componentInstance = createComponent(context, id);
1194 if (id.equals(_componentInstance.getId()) )
1195 {
1196 _created = true;
1197 int index = parentTag.getIndexOfNextChildTag();
1198 if (index > parent.getChildCount())
1199 {
1200 index = parent.getChildCount();
1201 }
1202
1203 List<UIComponent> children = parent.getChildren();
1204 children.add(index, _componentInstance);
1205 }
1206
1207
1208
1209
1210
1211 else if (null == findComponent(parent,_componentInstance.getId()))
1212 {
1213 _created = true;
1214 int index = parentTag.getIndexOfNextChildTag();
1215 if (index > parent.getChildCount())
1216 {
1217 index = parent.getChildCount();
1218 }
1219
1220 List<UIComponent> children = parent.getChildren();
1221 children.add(index, _componentInstance);
1222 }
1223 }
1224
1225 return _componentInstance;
1226
1227 }
1228
1229 private UIComponent findComponent(UIComponent parent, String id)
1230 {
1231 List li = parent.getChildren();
1232
1233 for (int i = 0; i < li.size(); i++)
1234 {
1235 UIComponent uiComponent = (UIComponent) li.get(i);
1236 if(uiComponent.getId()!=null && uiComponent.getId().equals(id))
1237 {
1238 return uiComponent;
1239 }
1240 }
1241
1242 return null;
1243 }
1244
1245
1246 private String createUniqueId(FacesContext context, UIComponent parent)
1247 throws JspException
1248 {
1249 String id = getId();
1250 if (id == null)
1251 {
1252 id = getFacesJspId();
1253 }
1254 else if (isIdDuplicated(id))
1255 {
1256 if (isInAnIterator)
1257 {
1258 setId(createNextId(id));
1259 id = getId();
1260 }
1261 else
1262 {
1263 if (parent != null)
1264 {
1265
1266 UIComponent namingContainer;
1267
1268 if (parent instanceof NamingContainer)
1269 {
1270 namingContainer = parent;
1271 }
1272 else
1273 {
1274 namingContainer = parent.getParent();
1275 }
1276
1277 if (namingContainer != null)
1278 {
1279 UIComponent component = namingContainer.findComponent(id);
1280
1281 if (component == null || isPostBack(context))
1282 {
1283 return id;
1284 }
1285 }
1286 }
1287
1288 throw new JspException("Duplicated Id found in the view: " + id);
1289 }
1290 }
1291
1292 return id;
1293 }
1294
1295 private String createNextId(String componentId)
1296 {
1297 Integer currentCounter = (Integer) getFacesContext().getExternalContext().getRequestMap().get(componentId);
1298
1299 int iCurrentCounter = 1;
1300
1301 if (currentCounter != null)
1302 {
1303 iCurrentCounter = currentCounter.intValue();
1304 iCurrentCounter++;
1305 }
1306
1307 getFacesContext().getExternalContext().getRequestMap().put(componentId, new Integer(iCurrentCounter));
1308
1309
1310
1311
1312
1313
1314
1315 componentId = componentId + UNIQUE_ID_PREFIX + iCurrentCounter;
1316
1317
1318 return componentId;
1319 }
1320
1321 private void checkIfItIsInAnIterator(String jspId)
1322 {
1323 Set<String> previousJspIdsSet = getPreviousJspIdsSet();
1324
1325 if (previousJspIdsSet.contains(jspId))
1326 {
1327 isInAnIterator = true;
1328 }
1329 else
1330 {
1331 previousJspIdsSet.add(jspId);
1332 isInAnIterator = false;
1333 }
1334 }
1335
1336 private Set<String> getPreviousJspIdsSet()
1337 {
1338 Set<String> previousJspIdsSet = (Set<String>) getFacesContext().getExternalContext()
1339 .getRequestMap().get(PREVIOUS_JSP_IDS_SET);
1340
1341 if (previousJspIdsSet == null)
1342 {
1343 previousJspIdsSet = new HashSet<String>();
1344
1345
1346 getFacesContext().getExternalContext().getRequestMap()
1347 .put(PREVIOUS_JSP_IDS_SET, previousJspIdsSet);
1348 }
1349
1350 return previousJspIdsSet;
1351 }
1352
1353 private boolean isIdDuplicated(String componentId)
1354 {
1355 boolean result = false;
1356 if (_parentClassicTag != null)
1357 {
1358 if (_parentClassicTag.isInAnIterator)
1359 {
1360 return true;
1361 }
1362 List childComponents = _parentClassicTag.getCreatedComponents();
1363
1364 if (childComponents != null)
1365 {
1366 result = childComponents.contains(componentId);
1367 if (result && (!isInAnIterator))
1368 {
1369 return true;
1370 }
1371 }
1372 }
1373
1374 return result;
1375 }
1376
1377 private boolean isPostBack(FacesContext facesContext)
1378 {
1379 return facesContext.getExternalContext().getRequestParameterMap().
1380 containsKey(ResponseStateManager.VIEW_STATE_PARAM);
1381 }
1382
1383
1384
1385
1386
1387 private boolean checkFacetNameOnParentExists(UIComponentClassicTagBase parentTag, String facetName)
1388 {
1389 return parentTag._facetsAdded != null && parentTag._facetsAdded.contains(facetName);
1390 }
1391
1392
1393
1394
1395
1396
1397 private void addFacetNameToParentTag(UIComponentClassicTagBase parentTag, String facetName)
1398 {
1399 if (parentTag._facetsAdded == null)
1400 {
1401 parentTag._facetsAdded = new ArrayList<String>();
1402 }
1403 parentTag._facetsAdded.add(facetName);
1404 }
1405
1406 protected abstract boolean hasBinding();
1407
1408 public JspWriter getPreviousOut() {
1409 return bodyContent.getEnclosingWriter();
1410 }
1411 }