View Javadoc

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 }