1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.facelets.extension;
21
22 import org.apache.myfaces.tobago.component.Attributes;
23 import org.apache.myfaces.tobago.util.ComponentUtils;
24
25 import javax.el.ELException;
26 import javax.faces.FacesException;
27 import javax.faces.application.Application;
28 import javax.faces.component.UIComponent;
29 import javax.faces.component.UIViewRoot;
30 import javax.faces.view.facelets.ComponentConfig;
31 import javax.faces.view.facelets.ComponentHandler;
32 import javax.faces.view.facelets.FaceletContext;
33 import javax.faces.view.facelets.MetaRuleset;
34 import javax.faces.view.facelets.Metadata;
35 import javax.faces.view.facelets.TagAttribute;
36 import java.io.IOException;
37
38
39
40
41
42 public abstract class TobagoMenuExtensionHandler extends ComponentHandler {
43
44 private Class subComponentLastType = Object.class;
45 private Metadata subComponentMapper;
46 private TagAttribute fieldIdAttribute;
47
48 public TobagoMenuExtensionHandler(ComponentConfig config) {
49 super(config);
50 fieldIdAttribute = getAttribute("fieldId");
51 }
52
53 protected abstract String getSubComponentType();
54
55 protected abstract String getSubRendererType();
56
57 protected abstract String getFacetName();
58
59 public void applyNextHandler(FaceletContext faceletContext, UIComponent menuCommand)
60 throws IOException, FacesException, ELException {
61 if (ComponentHandler.isNew(menuCommand)) {
62 UIComponent component = (UIComponent) menuCommand.getFacets().remove(getFacetName());
63 nextHandler.apply(faceletContext, component);
64 menuCommand.getFacets().put(getFacetName(), component);
65 } else {
66 nextHandler.apply(faceletContext, menuCommand.getFacet(getFacetName()));
67 }
68 }
69
70 public void onComponentCreated(FaceletContext faceletContext, UIComponent menuCommand, UIComponent parent) {
71
72 Application application = faceletContext.getFacesContext().getApplication();
73 UIViewRoot root = ComponentUtils.findViewRoot(faceletContext, parent);
74 UIComponent component = application.createComponent(getSubComponentType());
75 final String uid;
76 if (fieldIdAttribute != null) {
77 uid = fieldIdAttribute.getValue(faceletContext);
78 } else {
79 uid = root.createUniqueId();
80 }
81 component.setId(uid);
82 component.setRendererType(getSubRendererType());
83 setSubComponentAttributes(faceletContext, component);
84 menuCommand.getFacets().put(getFacetName(), component);
85 }
86
87 private void setSubComponentAttributes(FaceletContext ctx, Object instance) {
88 if (instance != null) {
89 Class type = instance.getClass();
90 if (subComponentMapper == null || !subComponentLastType.equals(type)) {
91 subComponentLastType = type;
92 subComponentMapper = createSubComponentMetaRuleset(type).finish();
93 }
94 subComponentMapper.applyMetadata(ctx, instance);
95 }
96 }
97
98 protected MetaRuleset createSubComponentMetaRuleset(Class aClass) {
99 MetaRuleset metaRuleset = super.createMetaRuleset(aClass);
100 TagAttribute [] attrs = tag.getAttributes().getAll();
101 for (int i = 0; i < attrs.length; i++) {
102 TagAttribute attr = attrs[i];
103 if (!(attr.getLocalName().equals(Attributes.CONVERTER)
104 || attr.getLocalName().equals(Attributes.VALUE))) {
105 metaRuleset.ignore(attr.getLocalName());
106 }
107 }
108 return metaRuleset;
109 }
110
111 protected MetaRuleset createMetaRuleset(Class aClass) {
112 MetaRuleset metaRuleset = super.createMetaRuleset(aClass);
113 metaRuleset.ignore(Attributes.CONVERTER);
114 metaRuleset.ignore(Attributes.VALUE);
115 return metaRuleset;
116 }
117 }