Coverage Report - net.sf.echobinding.binding.OgnlPropertyAdapter
 
Classes in this File Line Coverage Branch Coverage Complexity
OgnlPropertyAdapter
100%
75/75
N/A
0
 
 1  
 /**
 2  
  * Copyright (C) 2006 Philipp Mpalampanis
 3  
  *
 4  
  * License: MPL 1.1/GPL 2.0/LGPL 2.1
 5  
  *
 6  
  * The contents of this file are subject to the Mozilla Public License Version
 7  
  * 1.1 (the "License"); you may not use this file except in compliance with
 8  
  * the License. You may obtain a copy of the License at
 9  
  * http://www.mozilla.org/MPL/
 10  
  *
 11  
  * Software distributed under the License is distributed on an "AS IS" basis,
 12  
  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 13  
  * for the specific language governing rights and limitations under the
 14  
  * License.
 15  
  *
 16  
  * Alternatively, the contents of this file may be used under the terms of
 17  
  * either the GNU General Public License Version 2 or later (the "GPL"), or
 18  
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 19  
  * in which case the provisions of the GPL or the LGPL are applicable instead
 20  
  * of those above. If you wish to allow use of your version of this file only
 21  
  * under the terms of either the GPL or the LGPL, and not to allow others to
 22  
  * use your version of this file under the terms of the MPL, indicate your
 23  
  * decision by deleting the provisions above and replace them with the notice
 24  
  * and other provisions required by the GPL or the LGPL. If you do not delete
 25  
  * the provisions above, a recipient may use your version of this file under
 26  
  * the terms of any one of the MPL, the GPL or the LGPL.
 27  
  */
 28  
 
 29  
 package net.sf.echobinding.binding;
 30  
 
 31  
 import java.util.StringTokenizer;
 32  
 import java.util.regex.Matcher;
 33  
 import java.util.regex.Pattern;
 34  
 
 35  
 import net.sf.echobinding.validation.BeanValidator;
 36  
 import net.sf.echobinding.validation.ValidationReport;
 37  
 import ognl.*;
 38  
 
 39  
 import org.apache.log4j.Logger;
 40  
 import org.hibernate.Hibernate;
 41  
 
 42  
 /**
 43  
  * This is an implemenation of the <code>PropertyAdaper</code> interface using OGNL
 44  
  * expressions for accessing domain model properties.
 45  
  * 
 46  
  */
 47  
 public class OgnlPropertyAdapter extends AbstractPropertyAdapter {
 48  
 
 49  
         @SuppressWarnings("unused")
 50  82
         private final Logger _logger = Logger.getLogger(OgnlPropertyAdapter.class);
 51  
         
 52  
         private String _expression;
 53  
         
 54  
         private Object _parsedExpression;
 55  
         
 56  
         /**
 57  
          * Creates a new PropertyAdapter using OGNL expressions for accessing model properties.
 58  
          * 
 59  
          * @param expression The OGNL expression
 60  
          */
 61  82
         public OgnlPropertyAdapter(String expression) {
 62  82
                 setExpression(expression);
 63  81
         }
 64  
         
 65  
 
 66  
         /* (non-Javadoc)
 67  
          * @see echobinding.Binding#setValue(java.lang.Object, java.lang.Object)
 68  
          */
 69  
         public void setValue(Object bean, Object value) {
 70  4
                 setValue(null, bean, value);
 71  2
         }
 72  
 
 73  
         /* (non-Javadoc)
 74  
          * @see echobinding.Binding#getValue(java.lang.Object)
 75  
          */
 76  
         public Object getValue(Object bean) throws BindingException {
 77  5
                 return getValue(null, bean);
 78  
         }
 79  
 
 80  
 
 81  
         /**
 82  
          * Sets the value. 
 83  
          * 
 84  
          * @param context
 85  
          * @param bean
 86  
          * @param value
 87  
          * @throws BindingException
 88  
          */
 89  
         public void setValue(OgnlContext context, Object bean, Object value) throws BindingException {
 90  
                 
 91  18
                 Object newValue = parse(value);        
 92  
                 try {
 93  18
                         if(context != null)
 94  14
                                 Ognl.setValue(_parsedExpression, context, bean, newValue);
 95  
                         else
 96  4
                                 Ognl.setValue(_parsedExpression, bean, newValue);
 97  
         }
 98  2
         catch (OgnlException e) {
 99  
                 // e.printStackTrace();
 100  2
                 throw new BindingException(e.getMessage(), e);
 101  
         }
 102  16
         }
 103  
         
 104  
         
 105  
         /**
 106  
          * 
 107  
          * @param context
 108  
          * @param bean
 109  
          * @return
 110  
          */
 111  
         public Object getValue(OgnlContext context, Object bean) {
 112  170
                 if (context == null && bean == null)
 113  1
                         throw new BindingException("Bean and context must not be null!");
 114  
                 
 115  
                 // _logger.debug( "Looking up property '" + getExpression() + "' bean class = " + bean.getClass() + " OgnlContext =  "+context);
 116  
                 
 117  169
                 Object value = null;
 118  
         try {
 119  169
                 if(context != null)
 120  165
                         value = Ognl.getValue( _parsedExpression, context, bean );
 121  
                 else
 122  4
                         value = Ognl.getValue( _parsedExpression, bean );
 123  
         }
 124  2
         catch (OgnlException e) {
 125  2
                 _logger.debug( "Property '" + getExpression() + "' not found. Exception = " + e.getMessage() );
 126  2
                 String hint ="An error has occured.";
 127  2
                 if(e instanceof ognl.NoSuchPropertyException) {
 128  1
                         if(bean != null) {
 129  1
                                 hint="Property not found in class "+bean.getClass().getName()+". ";
 130  
                         }
 131  
                 }
 132  2
             throw new BindingException("Could not get value for property adapter '"+getId()+"' (expression='"+getExpression()+"')! "+hint+"", e);
 133  
         }
 134  
        //  _logger.debug( "Property '" + getExpression() + "' was found. Value = " + value );
 135  167
         return value == null ? null : format(value);
 136  
         }
 137  
 
 138  
         
 139  
         /**
 140  
          * Validates a bean property by examing its annotated contraints. 
 141  
          * 
 142  
          * @param bean 
 143  
          * @param value 
 144  
          * @return 
 145  
          * 
 146  
          * @see Hibernate Validation Framework 
 147  
          * 
 148  
          * @throws OgnlException 
 149  
          */
 150  
         public ValidationReport validateBean(Object bean, Object value) {
 151  
                 
 152  51
                 Node node = (Node) _parsedExpression;
 153  
 
 154  51
                 String ognlContextName = getOgnlContextName();
 155  51
                 if(ognlContextName!=null) {
 156  2
                         String expression = getExpression().replaceFirst( "#"+ognlContextName+"\\.", "" );
 157  2
                         node = (Node) parseExpression( expression );
 158  
                 }
 159  
                 
 160  
                 String propertyName;
 161  
                 Node child;
 162  
                 
 163  51
                 ValidationReport validationReport = null;
 164  133
                 for( int i = 0; i < node.jjtGetNumChildren(); i++ ) {
 165  
                         
 166  82
                         child = node.jjtGetChild(i);
 167  82
                         propertyName = child.toString().replaceAll("\"", "");
 168  
         
 169  82
                         validationReport = BeanValidator.validate(bean, propertyName, value);
 170  
                         
 171  82
                         OgnlContext context = (OgnlContext) Ognl.createDefaultContext(bean);
 172  
                         try {
 173  82
                                 bean = child.getValue( context, bean);
 174  
                         } catch (OgnlException e) {
 175  
                                 e.printStackTrace();
 176  
                         }
 177  
                 }
 178  
                 
 179  51
                 return validationReport;
 180  
         }
 181  
         
 182  
         
 183  
         
 184  
         /* (non-Javadoc)
 185  
          * @see echobinding.binding.AbstractPropertyAdapter#validate(java.lang.Object, java.lang.Object)
 186  
          */
 187  
         @Override
 188  
         public ValidationReport validate(Object bean, Object value) {
 189  55
                 ValidationReport report = super.validate( bean, value );
 190  
                 
 191  
                 // validate bean
 192  55
                 if(report.isValid())
 193  51
                         report = validateBean(bean, parse( value ));
 194  
                 
 195  55
                 return report;
 196  
         }
 197  
 
 198  
 
 199  
         public PropertyAdapter newInstance() {
 200  
                 
 201  2
                 OgnlPropertyAdapter binding = new OgnlPropertyAdapter(getExpression());
 202  2
                 binding.setDecorator(getDecorator());
 203  2
                 binding.setFormat(getFormat());
 204  2
                 binding.setLabel(getLabel());
 205  2
                 binding.setSubContext(getSubContext());
 206  2
                 binding.setValidators(getValidators());
 207  2
                 binding.setValidationHandler(getValidationHandler());
 208  
 
 209  2
                 return binding;
 210  
         }
 211  
 
 212  
 
 213  
         @Override
 214  
         public String toString() {
 215  
                 return "OgnlPropertyAdapter#"+getExpression()+"#"+hashCode();
 216  
         }
 217  
 
 218  
 
 219  
         /**
 220  
          * @return Returns the parsedExpression.
 221  
          */
 222  
         protected Object getParsedExpression() {
 223  
                 return _parsedExpression;
 224  
         }
 225  
 
 226  
         /** 
 227  
          * Returns the OGNL expression.
 228  
          * 
 229  
          * @return The OGNL expression
 230  
          */
 231  
         public String getExpression() {
 232  102
                 return _expression;
 233  
         }
 234  
 
 235  
         /**
 236  
          * Sets the OGNL expression.
 237  
          * 
 238  
          * @param the OGNL expression
 239  
          * @return the property adapter
 240  
          */
 241  
         public void setExpression(String expression) {
 242  82
                 _expression = expression;
 243  82
                 _parsedExpression = parseExpression( expression );
 244  81
         }
 245  
 
 246  
 
 247  
         /**
 248  
          * @param expression
 249  
          * @return
 250  
          */
 251  
         private Object parseExpression(String expression) {
 252  84
                 Object parsedExpression = null;
 253  
                 try {
 254  84
                         parsedExpression = Ognl.parseExpression(expression);
 255  1
                 } catch (OgnlException e) {
 256  
                         // e.printStackTrace();
 257  1
                         throw new BindingException(e.getMessage(), e);
 258  
                 }
 259  83
                 return parsedExpression;
 260  
         }
 261  
         
 262  
         
 263  
         @Override
 264  
         public String getLabel() {
 265  2
                 if(super.getLabel() == null)
 266  2
                         return createLabel();
 267  
                 return super.getLabel();
 268  
         }
 269  
         /**
 270  
          * 
 271  
          * @return
 272  
          */
 273  
         private String createLabel() {
 274  
                 
 275  2
                 String label ="";
 276  2
                 StringTokenizer tokenizer = new StringTokenizer(_expression, ".");
 277  8
                 while(tokenizer.hasMoreTokens()) {
 278  4
                         String token = tokenizer.nextToken();
 279  4
                         label += token.substring(0,1).toUpperCase() + token.substring(1, token.length()).toLowerCase();
 280  
                 }
 281  
                 
 282  2
                 return label;
 283  
         }
 284  
 
 285  
 
 286  
         /**
 287  
          * @return
 288  
          */
 289  
         public String getOgnlContextName() {
 290  
 
 291  93
                 Pattern pattern = Pattern.compile( "#(.*?)\\..*" );
 292  93
                 Matcher matcher = pattern.matcher( getExpression() );
 293  93
                 if(matcher.matches())
 294  7
                         return matcher.group( 1 );
 295  86
                 return null;
 296  
         }
 297  
         
 298  
 }