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.tag.composite;
20
21 import org.apache.myfaces.view.facelets.tag.BeanPropertyTagRule;
22 import org.apache.myfaces.view.facelets.tag.MetadataImpl;
23 import org.apache.myfaces.view.facelets.tag.MetadataTargetImpl;
24 import org.apache.myfaces.view.facelets.util.ParameterCheck;
25
26 import javax.faces.context.FacesContext;
27 import javax.faces.view.facelets.FaceletContext;
28 import javax.faces.view.facelets.MetaRule;
29 import javax.faces.view.facelets.MetaRuleset;
30 import javax.faces.view.facelets.Metadata;
31 import javax.faces.view.facelets.MetadataTarget;
32 import javax.faces.view.facelets.Tag;
33 import javax.faces.view.facelets.TagAttribute;
34 import javax.faces.view.facelets.TagException;
35 import java.beans.BeanInfo;
36 import java.beans.IntrospectionException;
37 import java.util.ArrayList;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.logging.Level;
42 import java.util.logging.Logger;
43
44 public class CompositeMetaRulesetImpl extends MetaRuleset
45 {
46 private final static Metadata NONE = new NullMetadata();
47
48
49 private final static Logger log = Logger.getLogger(CompositeMetadataTargetImpl.class.getName());
50
51 private static final String METADATA_KEY
52 = "org.apache.myfaces.view.facelets.tag.composite.CompositeMetaRulesetImpl.METADATA";
53
54 private static Map<String, MetadataTarget> getMetaData()
55 {
56 FacesContext facesContext = FacesContext.getCurrentInstance();
57 Map<String, Object> applicationMap = facesContext
58 .getExternalContext().getApplicationMap();
59
60 Map<String, MetadataTarget> metadata =
61 (Map<String, MetadataTarget>) applicationMap.get(METADATA_KEY);
62
63 if (metadata == null)
64 {
65 metadata = new HashMap<String, MetadataTarget>();
66 applicationMap.put(METADATA_KEY, metadata);
67 }
68
69 return metadata;
70 }
71
72 private final Map<String, TagAttribute> _attributes;
73
74 private final List<Metadata> _mappers;
75
76 private final List<MetaRule> _rules;
77
78 private final Tag _tag;
79
80 private final Class<?> _type;
81
82 private final MetadataTarget _meta;
83
84 public CompositeMetaRulesetImpl(Tag tag, Class<?> type, BeanInfo beanInfo)
85 {
86 _tag = tag;
87 _type = type;
88 _attributes = new HashMap<String, TagAttribute>();
89 _mappers = new ArrayList<Metadata>();
90 _rules = new ArrayList<MetaRule>();
91
92
93 for (TagAttribute attribute : _tag.getAttributes().getAll())
94 {
95 _attributes.put(attribute.getLocalName(), attribute);
96 }
97
98
99 _rules.add(BeanPropertyTagRule.INSTANCE);
100
101 try
102 {
103 _meta = new CompositeMetadataTargetImpl(_getBaseMetadataTarget(), beanInfo);
104 }
105 catch (IntrospectionException e)
106 {
107 throw new TagException(_tag, "Error Creating TargetMetadata", e);
108 }
109 }
110
111 public MetaRuleset add(Metadata mapper)
112 {
113 ParameterCheck.notNull("mapper", mapper);
114
115 if (!_mappers.contains(mapper))
116 {
117 _mappers.add(mapper);
118 }
119
120 return this;
121 }
122
123 public MetaRuleset addRule(MetaRule rule)
124 {
125 ParameterCheck.notNull("rule", rule);
126
127 _rules.add(rule);
128
129 return this;
130 }
131
132 public MetaRuleset alias(String attribute, String property)
133 {
134 ParameterCheck.notNull("attribute", attribute);
135 ParameterCheck.notNull("property", property);
136
137 TagAttribute attr = (TagAttribute) _attributes.remove(attribute);
138 if (attr != null)
139 {
140 _attributes.put(property, attr);
141 }
142
143 return this;
144 }
145
146 public Metadata finish()
147 {
148 assert !_rules.isEmpty();
149
150 if (!_attributes.isEmpty())
151 {
152 MetadataTarget target = this._getMetadataTarget();
153 int ruleEnd = _rules.size() - 1;
154
155
156 for (Map.Entry<String, TagAttribute> entry : _attributes.entrySet())
157 {
158 Metadata data = null;
159
160 int i = ruleEnd;
161
162
163 do
164 {
165 MetaRule rule = _rules.get(i);
166 data = rule.applyRule(entry.getKey(), entry.getValue(), target);
167 i--;
168 } while (data == null && i >= 0);
169
170 if (data == null)
171 {
172 if (log.isLoggable(Level.SEVERE))
173 {
174 log.severe(entry.getValue() + " Unhandled by MetaTagHandler for type " + _type.getName());
175 }
176 }
177 else
178 {
179 _mappers.add(data);
180 }
181 }
182 }
183
184 if (_mappers.isEmpty())
185 {
186 return NONE;
187 }
188 else
189 {
190 return new MetadataImpl(_mappers.toArray(new Metadata[_mappers.size()]));
191 }
192 }
193
194 public MetaRuleset ignore(String attribute)
195 {
196 ParameterCheck.notNull("attribute", attribute);
197
198 _attributes.remove(attribute);
199
200 return this;
201 }
202
203 public MetaRuleset ignoreAll()
204 {
205 _attributes.clear();
206
207 return this;
208 }
209
210 private final MetadataTarget _getMetadataTarget()
211 {
212 return _meta;
213 }
214
215 private final MetadataTarget _getBaseMetadataTarget()
216 {
217 Map<String, MetadataTarget> metadata = getMetaData();
218 String key = _type.getName();
219
220 MetadataTarget meta = metadata.get(key);
221 if (meta == null)
222 {
223 try
224 {
225 meta = new MetadataTargetImpl(_type);
226 }
227 catch (IntrospectionException e)
228 {
229 throw new TagException(_tag, "Error Creating TargetMetadata", e);
230 }
231
232 metadata.put(key, meta);
233 }
234
235 return meta;
236 }
237
238 private static class NullMetadata extends Metadata
239 {
240
241
242
243 @Override
244 public void applyMetadata(FaceletContext ctx, Object instance)
245 {
246
247 }
248 }
249 }