001 // Copyright 2004, 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry.bean;
016
017 import java.util.Map;
018
019 import ognl.ObjectPropertyAccessor;
020 import ognl.OgnlContext;
021 import ognl.OgnlException;
022 import ognl.OgnlRuntime;
023 import ognl.PropertyAccessor;
024 import ognl.enhance.ExpressionCompiler;
025 import ognl.enhance.UnsupportedCompilationException;
026
027 import org.apache.tapestry.IBeanProvider;
028
029 /**
030 * Adapts a {@link org.apache.tapestry.IBeanProvider} to
031 * <a href="http://www.ognl.org">OGNL</a> by exposing the named
032 * beans provided by the provider as read-only properties of
033 * the provider.
034 *
035 * <p>This is registered by {@link org.apache.tapestry.AbstractComponent}.
036 *
037 * @author Howard Lewis Ship
038 * @since 2.2
039 *
040 **/
041
042 public class BeanProviderPropertyAccessor extends ObjectPropertyAccessor implements PropertyAccessor
043 {
044 /**
045 * Checks to see if the name matches the name of a bean inside
046 * the provider and returns that bean if so.
047 * Otherwise, invokes the super implementation.
048 *
049 **/
050
051 public Object getProperty(Map context, Object target, Object name) throws OgnlException
052 {
053 IBeanProvider provider = (IBeanProvider)target;
054 String beanName = (String)name;
055
056 if (provider.canProvideBean(beanName))
057 return provider.getBean(beanName);
058
059 return super.getProperty(context, target, name);
060 }
061
062 /**
063 * Returns true if the name matches a bean provided by the provider.
064 * Otherwise invokes the super implementation.
065 *
066 **/
067
068 public boolean hasGetProperty(Map context, Object target, Object oname) throws OgnlException
069 {
070 IBeanProvider provider = (IBeanProvider)target;
071 String beanName = ((String)oname).replaceAll("\"", "");
072
073 if (provider.canProvideBean(beanName))
074 return true;
075
076 return super.hasGetProperty(context, target, oname);
077 }
078
079 public Class getPropertyClass(OgnlContext context, Object target, Object name)
080 {
081 IBeanProvider provider = (IBeanProvider)target;
082 String beanName = ((String)name).replaceAll("\"", "");
083
084 if (provider.canProvideBean(beanName))
085 return provider.getBean(beanName).getClass();
086
087 return super.getPropertyClass(context, target, name);
088 }
089
090 public String getSourceAccessor(OgnlContext context, Object target, Object name)
091 {
092 IBeanProvider provider = (IBeanProvider)target;
093 String beanName = ((String)name).replaceAll("\"", "");
094
095 if (provider.canProvideBean(beanName)) {
096
097 Class type = OgnlRuntime.getCompiler().getInterfaceClass(provider.getBean(beanName).getClass());
098
099 ExpressionCompiler.addCastString(context, "((" + type.getName() + ")");
100
101 context.setCurrentAccessor(IBeanProvider.class);
102 context.setCurrentType(type);
103
104 return ".getBean(" + name + "))";
105 }
106
107 return super.getSourceAccessor(context, target, name);
108 }
109
110 public String getSourceSetter(OgnlContext context, Object target, Object name)
111 {
112 throw new UnsupportedCompilationException("Can't set beans on IBeanProvider.");
113 }
114 }