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: struberg $)
36   * @version $Revision: 1194849 $ $Date: 2011-10-29 04:28:45 -0500 (Sat, 29 Oct 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          }
56      }
57      
58      final class TypedLiteralAttributeMetadata extends Metadata
59      {
60          private final String _name;
61          private final TagAttribute _attr;
62          private final Class<?> _type;
63  
64          public TypedLiteralAttributeMetadata(String name, Class<?> type, TagAttribute attr)
65          {
66              _name = name;
67              _attr = attr;
68              _type = type;
69          }
70  
71          public void applyMetadata(FaceletContext ctx, Object instance)
72          {
73              ((UIComponent) instance).getAttributes().put(_name, _attr.getObject(ctx, _type));
74          }
75      }
76  
77      final static class ValueExpressionMetadata extends Metadata
78      {
79          private final String _name;
80  
81          private final TagAttribute _attr;
82  
83          private final Class<?> _type;
84  
85          public ValueExpressionMetadata(String name, Class<?> type, TagAttribute attr)
86          {
87              _name = name;
88              _attr = attr;
89              _type = type;
90          }
91  
92          public void applyMetadata(FaceletContext ctx, Object instance)
93          {
94              // Call setValueExpression to set ValueExpression instances
95              // cause problems later because when getAttributes().get() is called
96              // it is evaluated. put the ValueExpression directly on the map
97              // prevents it and does not cause any side effects.
98              // Maybe we should call setValueExpression when the getter and 
99              // setter exists on the component class.
100             //((UIComponent) instance).getAttributes().put(_name, _attr.getValueExpression(ctx, _type));
101             ((UIComponent) instance).setValueExpression(_name, _attr.getValueExpression(ctx, _type));
102             //((UIComponent) instance).setValueExpression(_name, 
103             //        ctx.getFacesContext().getApplication().
104             //        getExpressionFactory().createValueExpression(
105             //                _attr.getValueExpression(ctx, _type), ValueExpression.class));
106         }
107     }
108 
109     //private final static Logger log = Logger.getLogger("facelets.tag.component");
110     private final static Logger log = Logger.getLogger(CompositeComponentRule.class.getName());
111 
112     public final static CompositeComponentRule INSTANCE = new CompositeComponentRule();
113 
114     public CompositeComponentRule()
115     {
116         super();
117     }
118 
119     public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta)
120     {
121         if (meta.isTargetInstanceOf(UIComponent.class))
122         {
123             // if component and dynamic, then must set expression
124             if (!attribute.isLiteral())
125             {
126                 Class<?> type = meta.getPropertyType(name);
127                 if (type == null)
128                 {
129                     type = Object.class;
130                 }
131                 
132                 return new ValueExpressionMetadata(name, type, attribute);
133             }
134             else if (meta.getWriteMethod(name) == null)
135             {
136                 Class<?> type = meta.getPropertyType(name);
137                 if (type == null)
138                 {
139                     if (meta.getProperty(name) == null)
140                     {
141                         // this was an attribute literal, but not property
142                         warnAttr(attribute, meta.getTargetClass(), name);
143                     }
144 
145                     return new LiteralAttributeMetadata(name, attribute.getValue());
146                 }
147                 else
148                 {
149                     return new TypedLiteralAttributeMetadata(name, type, attribute);
150                 }
151             }
152         }
153         return null;
154     }
155 
156     private static void warnAttr(TagAttribute attr, Class<?> type, String n)
157     {
158         if (log.isLoggable(Level.FINER))
159         {
160             log.finer(attr + " Property '" + n + "' is not on type: " + type.getName());
161         }
162     }
163 
164 }