Coverage Report - org.apache.commons.ognl.ObjectIndexedPropertyDescriptor
 
Classes in this File Line Coverage Branch Coverage Complexity
ObjectIndexedPropertyDescriptor
25%
7/27
0%
0/30
4
 
 1  
 package org.apache.commons.ognl;
 2  
 
 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  
 
 22  
 import java.beans.IntrospectionException;
 23  
 import java.beans.PropertyDescriptor;
 24  
 import java.lang.reflect.Method;
 25  
 
 26  
 /**
 27  
  * <p>
 28  
  * PropertyDescriptor subclass that describes an indexed set of read/write methods to get a property. Unlike
 29  
  * IndexedPropertyDescriptor this allows the "key" to be an arbitrary object rather than just an int. Consequently it
 30  
  * does not have a "readMethod" or "writeMethod" because it only expects a pattern like:
 31  
  * </p>
 32  
  * 
 33  
  * <pre>
 34  
  *    public void set<i>Property</i>(<i>KeyType</i>, <i>ValueType</i>);
 35  
  *    public <i>ValueType</i> get<i>Property</i>(<i>KeyType</i>);
 36  
  * </pre>
 37  
  * <p>
 38  
  * and does not require the methods that access it as an array. OGNL can get away with this without losing functionality
 39  
  * because if the object does expose the properties they are most probably in a Map and that case is handled by the
 40  
  * normal OGNL property accessors.
 41  
  * </p>
 42  
  * <p>
 43  
  * For example, if an object were to have methods that accessed and "attributes" property it would be natural to index
 44  
  * them by String rather than by integer and expose the attributes as a map with a different property name:
 45  
  * 
 46  
  * <pre>
 47  
  * public void setAttribute( String name, Object value );
 48  
  * 
 49  
  * public Object getAttribute( String name );
 50  
  * 
 51  
  * public Map getAttributes();
 52  
  * </pre>
 53  
  * <p>
 54  
  * Note that the index get/set is called get/set <code>Attribute</code> whereas the collection getter is called
 55  
  * <code>Attributes</code>. This case is handled unambiguously by the OGNL property accessors because the set/get
 56  
  * <code>Attribute</code> methods are detected by this object and the "attributes" case is handled by the
 57  
  * <code>MapPropertyAccessor</code>. Therefore OGNL expressions calling this code would be handled in the following way:
 58  
  * </p>
 59  
  * <table>
 60  
  * <tr>
 61  
  * <th>OGNL Expression</th>
 62  
  * <th>Handling</th>
 63  
  * </tr>
 64  
  * <tr>
 65  
  * <td><code>attribute["name"]</code></td>
 66  
  * <td>Handled by an index getter, like <code>getAttribute(String)</code>.</td>
 67  
  * </tr>
 68  
  * <tr>
 69  
  * <td><code>attribute["name"] = value</code></td>
 70  
  * <td>Handled by an index setter, like <code>setAttribute(String, Object)</code>.</td>
 71  
  * </tr>
 72  
  * <tr>
 73  
  * <td><code>attributes["name"]</code></td>
 74  
  * <td>Handled by <code>MapPropertyAccessor</code> via a <code>Map.get()</code>. This will <b>not</b> go through the
 75  
  * index get accessor.</td>
 76  
  * </tr>
 77  
  * <tr>
 78  
  * <td><code>attributes["name"] = value</code></td>
 79  
  * <td>Handled by <code>MapPropertyAccessor</code> via a <code>Map.put()</code>. This will <b>not</b> go through the
 80  
  * index set accessor.</td>
 81  
  * </tr>
 82  
  * </table>
 83  
  * 
 84  
  * @author Luke Blanshard (blanshlu@netscape.net)
 85  
  * @author Drew Davidson (drew@ognl.org)
 86  
  */
 87  
 public class ObjectIndexedPropertyDescriptor
 88  
     extends PropertyDescriptor
 89  
 {
 90  
     private Method indexedReadMethod;
 91  
 
 92  
     private Method indexedWriteMethod;
 93  
 
 94  
     private Class<?> propertyType;
 95  
 
 96  
     public ObjectIndexedPropertyDescriptor( String propertyName, Class<?> propertyType, Method indexedReadMethod,
 97  
                                             Method indexedWriteMethod )
 98  
         throws IntrospectionException
 99  
     {
 100  21
         super( propertyName, null, null );
 101  21
         this.propertyType = propertyType;
 102  21
         this.indexedReadMethod = indexedReadMethod;
 103  21
         this.indexedWriteMethod = indexedWriteMethod;
 104  21
     }
 105  
 
 106  
     public Method getIndexedReadMethod()
 107  
     {
 108  30
         return indexedReadMethod;
 109  
     }
 110  
 
 111  
     public Method getIndexedWriteMethod()
 112  
     {
 113  8
         return indexedWriteMethod;
 114  
     }
 115  
 
 116  
     @Override
 117  
     public Class<?> getPropertyType()
 118  
     {
 119  0
         return propertyType;
 120  
     }
 121  
 
 122  
     @Override
 123  
     public boolean equals(Object o) {
 124  0
         if (this == o)
 125  
         {
 126  0
             return true;
 127  
         }
 128  
 
 129  0
         if (!(o instanceof ObjectIndexedPropertyDescriptor))
 130  
         {
 131  0
             return false;
 132  
         }
 133  
 
 134  0
         if (!super.equals(o))
 135  
         {
 136  0
             return false;
 137  
         }
 138  
 
 139  0
         ObjectIndexedPropertyDescriptor that = (ObjectIndexedPropertyDescriptor) o;
 140  
 
 141  0
         if (indexedReadMethod != null ? !indexedReadMethod.equals(that.indexedReadMethod) : that.indexedReadMethod != null)
 142  
         {
 143  0
             return false;
 144  
         }
 145  
 
 146  0
         if (indexedWriteMethod != null ? !indexedWriteMethod.equals(that.indexedWriteMethod) : that.indexedWriteMethod != null)
 147  
         {
 148  0
             return false;
 149  
         }
 150  
 
 151  0
         if (propertyType != null ? !propertyType.equals(that.propertyType) : that.propertyType != null)
 152  
         {
 153  0
             return false;
 154  
         }
 155  
 
 156  0
         return true;
 157  
     }
 158  
 
 159  
     @Override
 160  
     public int hashCode() {
 161  0
         int result = super.hashCode();
 162  0
         result = 31 * result + (indexedReadMethod != null ? indexedReadMethod.hashCode() : 0);
 163  0
         result = 31 * result + (indexedWriteMethod != null ? indexedWriteMethod.hashCode() : 0);
 164  0
         result = 31 * result + (propertyType != null ? propertyType.hashCode() : 0);
 165  0
         return result;
 166  
     }
 167  
 }