1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.myfaces.view.facelets.tag.composite;
20
21 import java.util.logging.Level;
22 import java.util.logging.Logger;
23
24 import javax.faces.component.UIComponent;
25 import javax.faces.view.facelets.FaceletContext;
26 import javax.faces.view.facelets.MetaRule;
27 import javax.faces.view.facelets.Metadata;
28 import javax.faces.view.facelets.MetadataTarget;
29 import javax.faces.view.facelets.TagAttribute;
30
31 /**
32 * Copy of org.apache.myfaces.view.facelets.tag.jsf.ComponentRule
33 * used for composite components.
34 *
35 * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
36 * @version $Revision: 1067286 $ $Date: 2011-02-04 16:10:39 -0500 (Fri, 04 Feb 2011) $
37 */
38 final class CompositeComponentRule extends MetaRule
39 {
40
41 final class LiteralAttributeMetadata extends Metadata
42 {
43 private final String _name;
44 private final String _value;
45
46 public LiteralAttributeMetadata(String name, String value)
47 {
48 _name = name;
49 _value = value;
50 }
51
52 public void applyMetadata(FaceletContext ctx, Object instance)
53 {
54 ((UIComponent) instance).getAttributes().put(_name, _value);
55 //((UIComponent) instance).setValueExpression(_name,
56 // ctx.getFacesContext().getApplication().getExpressionFactory().createValueExpression(_value, Object.class));
57 }
58 }
59
60 final class TypedLiteralAttributeMetadata extends Metadata
61 {
62 private final String _name;
63 private final TagAttribute _attr;
64 private final Class<?> _type;
65
66 public TypedLiteralAttributeMetadata(String name, Class<?> type, TagAttribute attr)
67 {
68 _name = name;
69 _attr = attr;
70 _type = type;
71 }
72
73 public void applyMetadata(FaceletContext ctx, Object instance)
74 {
75 ((UIComponent) instance).getAttributes().put(_name, _attr.getObject(ctx, _type));
76 }
77 }
78
79 final static class ValueExpressionMetadata extends Metadata
80 {
81 private final String _name;
82
83 private final TagAttribute _attr;
84
85 private final Class<?> _type;
86
87 public ValueExpressionMetadata(String name, Class<?> type, TagAttribute attr)
88 {
89 _name = name;
90 _attr = attr;
91 _type = type;
92 }
93
94 public void applyMetadata(FaceletContext ctx, Object instance)
95 {
96 // Call setValueExpression to set ValueExpression instances
97 // cause problems later because when getAttributes().get() is called
98 // it is evaluated. put the ValueExpression directly on the map
99 // prevents it and does not cause any side effects.
100 // Maybe we should call setValueExpression when the getter and
101 // setter exists on the component class.
102 //((UIComponent) instance).getAttributes().put(_name, _attr.getValueExpression(ctx, _type));
103 ((UIComponent) instance).setValueExpression(_name, _attr.getValueExpression(ctx, _type));
104 //((UIComponent) instance).setValueExpression(_name,
105 // ctx.getFacesContext().getApplication().
106 // getExpressionFactory().createValueExpression(
107 // _attr.getValueExpression(ctx, _type), ValueExpression.class));
108 }
109 }
110
111 //private final static Logger log = Logger.getLogger("facelets.tag.component");
112 private final static Logger log = Logger.getLogger(CompositeComponentRule.class.getName());
113
114 public final static CompositeComponentRule Instance = new CompositeComponentRule();
115
116 public CompositeComponentRule()
117 {
118 super();
119 }
120
121 public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta)
122 {
123 if (meta.isTargetInstanceOf(UIComponent.class))
124 {
125 // if component and dynamic, then must set expression
126 if (!attribute.isLiteral())
127 {
128 Class<?> type = meta.getPropertyType(name);
129 if (type == null)
130 {
131 type = Object.class;
132 }
133
134 return new ValueExpressionMetadata(name, type, attribute);
135 }
136 else if (meta.getWriteMethod(name) == null)
137 {
138 Class<?> type = meta.getPropertyType(name);
139 if (type == null)
140 {
141 if (meta.getProperty(name) == null)
142 {
143 // this was an attribute literal, but not property
144 warnAttr(attribute, meta.getTargetClass(), name);
145 }
146
147 return new LiteralAttributeMetadata(name, attribute.getValue());
148 }
149 else
150 {
151 return new TypedLiteralAttributeMetadata(name, type, attribute);
152 }
153 }
154 }
155 return null;
156 }
157
158 private static void warnAttr(TagAttribute attr, Class<?> type, String n)
159 {
160 if (log.isLoggable(Level.FINER))
161 {
162 log.finer(attr + " Property '" + n + "' is not on type: " + type.getName());
163 }
164 }
165
166 }