1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.view.facelets.compiler;
20
21 import java.io.IOException;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28
29 import java.util.Set;
30 import javax.el.ValueExpression;
31 import javax.faces.FacesException;
32 import javax.faces.component.ContextCallback;
33 import javax.faces.component.UIComponent;
34 import javax.faces.component.UINamingContainer;
35 import javax.faces.component.UIViewRoot;
36 import javax.faces.component.UniqueIdVendor;
37 import javax.faces.component.visit.VisitCallback;
38 import javax.faces.component.visit.VisitContext;
39 import javax.faces.context.FacesContext;
40 import javax.faces.el.ValueBinding;
41 import javax.faces.event.AbortProcessingException;
42 import javax.faces.event.ComponentSystemEvent;
43 import javax.faces.event.FacesEvent;
44 import javax.faces.event.FacesListener;
45 import javax.faces.render.Renderer;
46
47 import javax.faces.view.Location;
48 import org.apache.commons.collections.iterators.EmptyIterator;
49 import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
50
51 class UILeaf extends UIComponent implements Map<String, Object>
52 {
53
54 private static final String _STRING_BUILDER_KEY
55 = "javax.faces.component.UIComponentBase.SHARED_STRING_BUILDER";
56
57 private String _clientId = null;
58
59 private String _id = null;
60
61 public String getClientId(FacesContext context)
62 {
63 if (context == null)
64 {
65 throw new NullPointerException("context");
66 }
67
68 if (_clientId != null)
69 {
70 return _clientId;
71 }
72
73
74 String id = getId();
75 if (id == null)
76 {
77
78
79
80
81
82
83
84
85 UniqueIdVendor parentUniqueIdVendor = _ComponentUtils.findParentUniqueIdVendor(this);
86 if (parentUniqueIdVendor == null)
87 {
88 UIViewRoot viewRoot = context.getViewRoot();
89 if (viewRoot != null)
90 {
91 id = viewRoot.createUniqueId();
92 }
93 else
94 {
95
96 String location = getComponentLocation(this);
97 throw new FacesException("Cannot create clientId. No id is assigned for component"
98 + " to create an id and UIViewRoot is not defined: "
99 + getPathToComponent(this)
100 + (location != null ? " created from: " + location : ""));
101 }
102 }
103 else
104 {
105 id = parentUniqueIdVendor.createUniqueId(context, null);
106 }
107 setId(id);
108
109
110 }
111
112 UIComponent namingContainer = _ComponentUtils.findParentNamingContainer(this, false);
113 if (namingContainer != null)
114 {
115 String containerClientId = namingContainer.getContainerClientId(context);
116 if (containerClientId != null)
117 {
118 StringBuilder bld = _getSharedStringBuilder(context);
119 _clientId = bld.append(containerClientId).append(
120 UINamingContainer.getSeparatorChar(context)).append(id).toString();
121 }
122 else
123 {
124 _clientId = id;
125 }
126 }
127 else
128 {
129 _clientId = id;
130 }
131
132 Renderer renderer = getRenderer(context);
133 if (renderer != null)
134 {
135 _clientId = renderer.convertClientId(context, _clientId);
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151 return _clientId;
152 }
153
154 public String getId()
155 {
156 return _id;
157 }
158
159 @Override
160 public void setId(String id)
161 {
162 isIdValid(id);
163 _id = id;
164 _clientId = null;
165 }
166
167 private void isIdValid(String string)
168 {
169
170
171 if (string == null)
172 {
173 return;
174 }
175
176
177
178 if (string.length() == 0)
179 {
180 throw new IllegalArgumentException("component identifier must not be a zero-length String");
181 }
182
183
184 if (string.equals(_id))
185 {
186 return;
187 }
188
189
190 if (!Character.isLetter(string.charAt(0)) && string.charAt(0) != '_')
191 {
192 throw new IllegalArgumentException("component identifier's first character must be a letter "
193 + "or an underscore ('_')! But it is \""
194 + string.charAt(0) + "\"");
195 }
196 for (int i = 1; i < string.length(); i++)
197 {
198 char c = string.charAt(i);
199
200 if (!Character.isLetterOrDigit(c) && c != '-' && c != '_')
201 {
202 throw new IllegalArgumentException("Subsequent characters of component identifier must be a letter, "
203 + "a digit, an underscore ('_'), or a dash ('-')! "
204 + "But component identifier contains \""
205 + c + "\"");
206 }
207 }
208 }
209
210 private String getComponentLocation(UIComponent component)
211 {
212 Location location = (Location) component.getAttributes()
213 .get(UIComponent.VIEW_LOCATION_KEY);
214 if (location != null)
215 {
216 return location.toString();
217 }
218 return null;
219 }
220
221 private String getPathToComponent(UIComponent component)
222 {
223 StringBuffer buf = new StringBuffer();
224
225 if (component == null)
226 {
227 buf.append("{Component-Path : ");
228 buf.append("[null]}");
229 return buf.toString();
230 }
231
232 getPathToComponent(component, buf);
233
234 buf.insert(0, "{Component-Path : ");
235 buf.append("}");
236
237 return buf.toString();
238 }
239
240 private void getPathToComponent(UIComponent component, StringBuffer buf)
241 {
242 if (component == null)
243 {
244 return;
245 }
246
247 StringBuffer intBuf = new StringBuffer();
248
249 intBuf.append("[Class: ");
250 intBuf.append(component.getClass().getName());
251 if (component instanceof UIViewRoot)
252 {
253 intBuf.append(",ViewId: ");
254 intBuf.append(((UIViewRoot) component).getViewId());
255 }
256 else
257 {
258 intBuf.append(",Id: ");
259 intBuf.append(component.getId());
260 }
261 intBuf.append("]");
262
263 buf.insert(0, intBuf.toString());
264
265 getPathToComponent(component.getParent(), buf);
266 }
267
268 static StringBuilder _getSharedStringBuilder(FacesContext facesContext)
269 {
270 Map<Object, Object> attributes = facesContext.getAttributes();
271
272 StringBuilder sb = (StringBuilder) attributes.get(_STRING_BUILDER_KEY);
273
274 if (sb == null)
275 {
276 sb = new StringBuilder();
277 attributes.put(_STRING_BUILDER_KEY, sb);
278 }
279 else
280 {
281
282
283 sb.setLength(0);
284 }
285
286 return sb;
287 }
288
289
290
291
292 private static Map<String, UIComponent> facets = new HashMap<String, UIComponent>()
293 {
294
295 @Override
296 public void putAll(Map<? extends String, ? extends UIComponent> map)
297 {
298
299 }
300
301 @Override
302 public UIComponent put(String name, UIComponent value)
303 {
304 return null;
305 }
306 };
307
308 private UIComponent parent;
309
310
311
312 @Override
313 public Map<String, Object> getAttributes()
314 {
315
316
317
318
319
320
321
322 return this;
323 }
324
325 @Override
326 public void clearInitialState()
327 {
328
329 }
330
331 @Override
332 public boolean initialStateMarked()
333 {
334
335 return false;
336 }
337
338 @Override
339 public void markInitialState()
340 {
341
342 }
343
344
345 @Override
346 public void processEvent(ComponentSystemEvent event)
347 throws AbortProcessingException
348 {
349
350 }
351
352 @Override
353 @SuppressWarnings("deprecation")
354 public ValueBinding getValueBinding(String binding)
355 {
356 return null;
357 }
358
359 @Override
360 @SuppressWarnings("deprecation")
361 public void setValueBinding(String name, ValueBinding binding)
362 {
363
364 }
365
366 @Override
367 public ValueExpression getValueExpression(String name)
368 {
369 return null;
370 }
371
372 @Override
373 public void setValueExpression(String name, ValueExpression arg1)
374 {
375
376 }
377
378 public String getFamily()
379 {
380 return "facelets.LiteralText";
381 }
382
383 @Override
384 public UIComponent getParent()
385 {
386 return this.parent;
387 }
388
389 @Override
390 public void setParent(UIComponent parent)
391 {
392 this.parent = parent;
393 }
394
395 @Override
396 public boolean isRendered()
397 {
398 return true;
399 }
400
401 @Override
402 public void setRendered(boolean rendered)
403 {
404
405 }
406
407 @Override
408 public String getRendererType()
409 {
410 return null;
411 }
412
413 @Override
414 public void setRendererType(String rendererType)
415 {
416
417 }
418
419 @Override
420 public boolean getRendersChildren()
421 {
422 return true;
423 }
424
425 @Override
426 public List<UIComponent> getChildren()
427 {
428 List<UIComponent> children = Collections.emptyList();
429 return children;
430 }
431
432 @Override
433 public int getChildCount()
434 {
435 return 0;
436 }
437
438 @Override
439 public UIComponent findComponent(String id)
440 {
441 return null;
442 }
443
444 @Override
445 public Map<String, UIComponent> getFacets()
446 {
447 return facets;
448 }
449
450 @Override
451 public int getFacetCount()
452 {
453 return 0;
454 }
455
456 @Override
457 public UIComponent getFacet(String name)
458 {
459 return null;
460 }
461
462 @SuppressWarnings("unchecked")
463 @Override
464 public Iterator<UIComponent> getFacetsAndChildren()
465 {
466
467
468
469 return EmptyIterator.INSTANCE;
470 }
471
472 @Override
473 public void broadcast(FacesEvent event) throws AbortProcessingException
474 {
475
476 }
477
478 @Override
479 public void decode(FacesContext faces)
480 {
481
482 }
483
484 @Override
485 public void encodeBegin(FacesContext faces) throws IOException
486 {
487
488 }
489
490 @Override
491 public void encodeChildren(FacesContext faces) throws IOException
492 {
493
494 }
495
496 @Override
497 public void encodeEnd(FacesContext faces) throws IOException
498 {
499
500 }
501
502 @Override
503 public void encodeAll(FacesContext faces) throws IOException
504 {
505 this.encodeBegin(faces);
506 }
507
508 @Override
509 protected void addFacesListener(FacesListener faces)
510 {
511
512 }
513
514 @Override
515 protected FacesListener[] getFacesListeners(Class faces)
516 {
517 return null;
518 }
519
520 @Override
521 protected void removeFacesListener(FacesListener faces)
522 {
523
524 }
525
526 @Override
527 public void queueEvent(FacesEvent event)
528 {
529
530 }
531
532 @Override
533 public void processRestoreState(FacesContext faces, Object state)
534 {
535
536 }
537
538 @Override
539 public void processDecodes(FacesContext faces)
540 {
541
542 }
543
544 @Override
545 public void processValidators(FacesContext faces)
546 {
547
548 }
549
550 @Override
551 public void processUpdates(FacesContext faces)
552 {
553
554 }
555
556 @Override
557 public Object processSaveState(FacesContext faces)
558 {
559 return null;
560 }
561
562 @Override
563 protected FacesContext getFacesContext()
564 {
565 return FacesContext.getCurrentInstance();
566 }
567
568 @Override
569 protected Renderer getRenderer(FacesContext faces)
570 {
571 return null;
572 }
573
574 public Object saveState(FacesContext faces)
575 {
576 return null;
577 }
578
579 public void restoreState(FacesContext faces, Object state)
580 {
581
582 }
583
584 public boolean isTransient()
585 {
586 return true;
587 }
588
589 public void setTransient(boolean tranzient)
590 {
591
592 }
593
594 @Override
595 public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
596 throws FacesException
597 {
598
599 return false;
600 }
601
602 @Override
603 public boolean visitTree(VisitContext context, VisitCallback callback)
604 {
605
606
607 return false;
608 }
609
610
611
612 private Map<String, Object> _attributes = null;
613 private String _markCreated = null;
614
615 public void setMarkCreated(String markCreated)
616 {
617 _markCreated = markCreated;
618 }
619
620 public int size()
621 {
622 return _attributes == null ? 0 : _attributes.size();
623 }
624
625 public void clear()
626 {
627 if (_attributes != null)
628 {
629 _attributes.clear();
630 _markCreated = null;
631 }
632 }
633
634 public boolean isEmpty()
635 {
636 if (_markCreated == null)
637 {
638 return _attributes == null ? false : _attributes.isEmpty();
639 }
640 else
641 {
642 return false;
643 }
644 }
645
646 public boolean containsKey(Object key)
647 {
648 checkKey(key);
649
650 if (ComponentSupport.MARK_CREATED.equals(key))
651 {
652 return _markCreated != null;
653 }
654 else
655 {
656 return (_attributes == null ? false :_attributes.containsKey(key));
657 }
658 }
659
660 public boolean containsValue(Object value)
661 {
662 if (_markCreated != null && _markCreated.equals(value))
663 {
664 return true;
665 }
666 return (_attributes == null) ? false : _attributes.containsValue(value);
667 }
668
669 public Collection<Object> values()
670 {
671 return getUnderlyingMap().values();
672 }
673
674 public void putAll(Map<? extends String, ? extends Object> t)
675 {
676 for (Map.Entry<? extends String, ? extends Object> entry : t.entrySet())
677 {
678 put(entry.getKey(), entry.getValue());
679 }
680 }
681
682 public Set<Entry<String, Object>> entrySet()
683 {
684 return getUnderlyingMap().entrySet();
685 }
686
687 public Set<String> keySet()
688 {
689 return getUnderlyingMap().keySet();
690 }
691
692 public Object get(Object key)
693 {
694 checkKey(key);
695
696 if ("rendered".equals(key))
697 {
698 return true;
699 }
700 if ("transient".equals(key))
701 {
702 return true;
703 }
704 if (ComponentSupport.MARK_CREATED.equals(key))
705 {
706 return _markCreated;
707 }
708 return (_attributes == null) ? null : _attributes.get(key);
709 }
710
711 public Object remove(Object key)
712 {
713 checkKey(key);
714
715 if (ComponentSupport.MARK_CREATED.equals(key))
716 {
717 _markCreated = null;
718 }
719 return (_attributes == null) ? null : _attributes.remove(key);
720 }
721
722 public Object put(String key, Object value)
723 {
724 checkKey(key);
725
726 if (ComponentSupport.MARK_CREATED.equals(key))
727 {
728 String old = _markCreated;
729 _markCreated = (String) value;
730 return old;
731 }
732 return getUnderlyingMap().put(key, value);
733 }
734
735 private void checkKey(Object key)
736 {
737 if (key == null)
738 {
739 throw new NullPointerException("key");
740 }
741 if (!(key instanceof String))
742 {
743 throw new ClassCastException("key is not a String");
744 }
745 }
746
747 Map<String, Object> getUnderlyingMap()
748 {
749 if (_attributes == null)
750 {
751 _attributes = new HashMap<String, Object>(2,1);
752 }
753 return _attributes;
754 }
755
756 }