1 /* 2 * $Id: TilesContextBeanELResolver.java 816924 2009-09-19 13:45:40Z apetrelli $ 3 * 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 package org.apache.tiles.el; 22 23 import java.beans.FeatureDescriptor; 24 import java.util.ArrayList; 25 import java.util.Iterator; 26 import java.util.List; 27 import java.util.Map; 28 29 import javax.el.ELContext; 30 import javax.el.ELResolver; 31 32 import org.apache.tiles.TilesApplicationContext; 33 import org.apache.tiles.context.TilesRequestContext; 34 35 /** 36 * Resolves beans in request, session and application scope. 37 * 38 * @version $Rev: 816924 $ $Date: 2009-09-19 15:45:40 +0200 (sab, 19 set 2009) $ 39 * @since 2.2.1 40 */ 41 public class TilesContextBeanELResolver extends ELResolver { 42 43 /** {@inheritDoc} */ 44 @Override 45 public Class<?> getCommonPropertyType(ELContext context, Object base) { 46 // only resolve at the root of the context 47 if (base != null) { 48 return null; 49 } 50 51 return String.class; 52 } 53 54 /** {@inheritDoc} */ 55 @Override 56 public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, 57 Object base) { 58 List<FeatureDescriptor> list = new ArrayList<FeatureDescriptor>(); 59 60 TilesRequestContext request = (TilesRequestContext) context 61 .getContext(TilesRequestContext.class); 62 collectBeanInfo(request.getRequestScope(), list); 63 collectBeanInfo(request.getSessionScope(), list); 64 65 TilesApplicationContext applicationContext = (TilesApplicationContext) context 66 .getContext(TilesApplicationContext.class); 67 collectBeanInfo(applicationContext.getApplicationScope(), list); 68 return list.iterator(); 69 } 70 71 /** {@inheritDoc} */ 72 @Override 73 public Class<?> getType(ELContext context, Object base, Object property) { 74 if (base != null) { 75 return null; 76 } 77 78 Object obj = findObjectByProperty(context, property); 79 if (obj != null) { 80 context.setPropertyResolved(true); 81 return obj.getClass(); 82 } 83 return null; 84 } 85 86 /** {@inheritDoc} */ 87 @Override 88 public Object getValue(ELContext context, Object base, Object property) { 89 if (base != null) { 90 return null; 91 } 92 93 Object retValue = findObjectByProperty(context, property); 94 95 if (retValue != null) { 96 context.setPropertyResolved(true); 97 } 98 99 return retValue; 100 } 101 102 /** {@inheritDoc} */ 103 @Override 104 public boolean isReadOnly(ELContext context, Object base, Object property) { 105 if (context == null) { 106 throw new NullPointerException(); 107 } 108 109 return true; 110 } 111 112 /** {@inheritDoc} */ 113 @Override 114 public void setValue(ELContext context, Object base, Object property, 115 Object value) { 116 // Does nothing for the moment. 117 } 118 119 /** 120 * Collects bean infos from a map's values and filling a list. 121 * 122 * @param map The map containing the bean to be inspected. 123 * @param list The list to fill. 124 * @since 2.2.1 125 */ 126 protected void collectBeanInfo(Map<String, ? extends Object> map, 127 List<FeatureDescriptor> list) { 128 if (map == null || map.isEmpty()) { 129 return; 130 } 131 132 for (Map.Entry<String, ? extends Object> entry : map.entrySet()) { 133 FeatureDescriptor descriptor = new FeatureDescriptor(); 134 descriptor.setDisplayName(entry.getKey()); 135 descriptor.setExpert(false); 136 descriptor.setHidden(false); 137 descriptor.setName(entry.getKey()); 138 descriptor.setPreferred(true); 139 descriptor.setShortDescription(""); 140 descriptor.setValue("type", String.class); 141 descriptor.setValue("resolvableAtDesignTime", Boolean.FALSE); 142 list.add(descriptor); 143 } 144 } 145 146 /** 147 * Finds an object in request, session or application scope, in this order. 148 * 149 * @param context The context to use. 150 * @param property The property used as an attribute name. 151 * @return The found bean, if it exists, or <code>null</code> otherwise. 152 * @since 2.2.1 153 */ 154 protected Object findObjectByProperty(ELContext context, Object property) { 155 Object retValue = null; 156 157 TilesRequestContext request = (TilesRequestContext) context 158 .getContext(TilesRequestContext.class); 159 160 String prop = property.toString(); 161 162 retValue = getObject(request.getRequestScope(), prop); 163 if (retValue == null) { 164 retValue = getObject(request.getSessionScope(), prop); 165 if (retValue == null) { 166 TilesApplicationContext applicationContext = (TilesApplicationContext) context 167 .getContext(TilesApplicationContext.class); 168 retValue = getObject(applicationContext.getApplicationScope(), 169 prop); 170 } 171 } 172 173 return retValue; 174 } 175 176 /** 177 * Returns an object from a map in a null-safe manner. 178 * 179 * @param map The map to use. 180 * @param property The property to use as a key. 181 * @return The object, if present, or <code>null</code> otherwise. 182 * @since 2.2.1 183 */ 184 protected Object getObject(Map<String, ? extends Object> map, 185 String property) { 186 Object retValue = null; 187 if (map != null) { 188 retValue = map.get(property); 189 } 190 return retValue; 191 } 192 }