Coverage Report - org.apache.tapestry.enhance.MethodSignatureImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
MethodSignatureImpl
0%
0/91
0%
0/62
3.6
 
 1  
 // Copyright 2004, 2005 The Apache Software Foundation
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 package org.apache.tapestry.enhance;
 15  
 
 16  
 import org.apache.hivemind.service.ClassFabUtils;
 17  
 
 18  
 import java.lang.reflect.Method;
 19  
 
 20  
 
 21  
 /**
 22  
  * JDK 1.4 based version of {@link MethodSignature}. 
 23  
  */
 24  
 public class MethodSignatureImpl implements MethodSignature
 25  
 {
 26  0
     protected int _hashCode = -1;
 27  
 
 28  
     protected Class _returnType;
 29  
 
 30  
     protected String _name;
 31  
 
 32  
     protected Class[] _parameterTypes;
 33  
 
 34  
     protected Class[] _exceptionTypes;
 35  
 
 36  
     public MethodSignatureImpl(Class returnType, String name, 
 37  
             Class[] parameterTypes, Class[] exceptionTypes)
 38  0
     {
 39  0
         _returnType = returnType;
 40  0
         _name = name;
 41  0
         _parameterTypes = parameterTypes;
 42  0
         _exceptionTypes = exceptionTypes;
 43  0
     }
 44  
     
 45  
     public MethodSignatureImpl(Method m)
 46  
     {
 47  0
         this(m.getReturnType(), m.getName(), m.getParameterTypes(), m.getExceptionTypes());
 48  0
     }
 49  
     
 50  
     public Class[] getExceptionTypes()
 51  
     {
 52  0
         return _exceptionTypes;
 53  
     }
 54  
 
 55  
     public String getName()
 56  
     {
 57  0
         return _name;
 58  
     }
 59  
     
 60  
     public Class[] getParameterTypes()
 61  
     {
 62  0
         return _parameterTypes;
 63  
     }
 64  
 
 65  
     public Class getReturnType()
 66  
     {
 67  0
         return _returnType;
 68  
     }
 69  
 
 70  
     public int hashCode()
 71  
     {
 72  0
         if (_hashCode == -1)
 73  
         {
 74  0
             _hashCode = _returnType.hashCode();
 75  
 
 76  0
             _hashCode = 31 * _hashCode + _name.hashCode();
 77  
 
 78  0
             int count = count(_parameterTypes);
 79  
 
 80  0
             for (int i = 0; i < count; i++)
 81  0
                 _hashCode = 31 * _hashCode + _parameterTypes[i].hashCode();
 82  
 
 83  0
             count = count(_exceptionTypes);
 84  
 
 85  0
             for (int i = 0; i < count; i++)
 86  0
                 _hashCode = 31 * _hashCode + _exceptionTypes[i].hashCode();
 87  
         }
 88  
 
 89  0
         return _hashCode;
 90  
     }
 91  
 
 92  
     protected static int count(Object[] array)
 93  
     {
 94  0
         return array == null ? 0 : array.length;
 95  
     }
 96  
 
 97  
     /**
 98  
      * Returns true if the other object is an instance of MethodSignature with identical values for
 99  
      * return type, name, parameter types and exception types.
 100  
      */
 101  
     public boolean equals(Object o)
 102  
     {
 103  0
         if (o == null || !(o instanceof MethodSignatureImpl))
 104  0
             return false;
 105  
 
 106  0
         MethodSignatureImpl ms = (MethodSignatureImpl) o;
 107  
 
 108  0
         if (_returnType != ms._returnType)
 109  0
             return false;
 110  
         
 111  0
         if (!_name.equals(ms._name))
 112  0
             return false;
 113  
 
 114  0
         if (mismatch(_parameterTypes, ms._parameterTypes))
 115  0
             return false;
 116  
 
 117  0
         return !mismatch(_exceptionTypes, ms._exceptionTypes);
 118  
     }
 119  
 
 120  
     protected boolean mismatch(Class[] a1, Class[] a2)
 121  
     {
 122  0
         int a1Count = count(a1);
 123  0
         int a2Count = count(a2);
 124  
 
 125  0
         if (a1Count != a2Count)
 126  0
             return true;
 127  
 
 128  
         // Hm. What if order is important (for exceptions)? We're really saying here that they
 129  
         // were derived from the name Method.
 130  
 
 131  0
         for (int i = 0; i < a1Count; i++)
 132  
         {
 133  0
             if (!a1[i].isAssignableFrom(a2[i]))
 134  0
                 return true;
 135  
         }
 136  
 
 137  0
         return false;
 138  
     }
 139  
 
 140  
     public String toString()
 141  
     {
 142  0
         StringBuffer buffer = new StringBuffer();
 143  
 
 144  0
         buffer.append(ClassFabUtils.getJavaClassName(_returnType));
 145  0
         buffer.append(" ");
 146  0
         buffer.append(_name);
 147  0
         buffer.append("(");
 148  
 
 149  0
         for (int i = 0; i < count(_parameterTypes); i++)
 150  
         {
 151  0
             if (i > 0)
 152  0
                 buffer.append(", ");
 153  
 
 154  0
             buffer.append(ClassFabUtils.getJavaClassName(_parameterTypes[i]));
 155  
         }
 156  
 
 157  0
         buffer.append(")");
 158  
 
 159  0
         for (int i = 0; i < count(_exceptionTypes); i++)
 160  
         {
 161  0
             if (i == 0)
 162  0
                 buffer.append(" throws ");
 163  
             else
 164  0
                 buffer.append(", ");
 165  
 
 166  0
             buffer.append(_exceptionTypes[i].getName());
 167  
         }
 168  
 
 169  0
         return buffer.toString();
 170  
     }
 171  
 
 172  
     public String getUniqueId()
 173  
     {
 174  0
         StringBuffer buffer = new StringBuffer(_name);
 175  0
         buffer.append("(");
 176  
 
 177  0
         for (int i = 0; i < count(_parameterTypes); i++)
 178  
         {
 179  0
             if (i > 0)
 180  0
                 buffer.append(",");
 181  
 
 182  0
             buffer.append(ClassFabUtils.getJavaClassName(_parameterTypes[i]));
 183  
         }
 184  
 
 185  0
         buffer.append(")");
 186  
 
 187  0
         return buffer.toString();
 188  
     }
 189  
     
 190  
     public boolean isGeneric()
 191  
     {
 192  0
         return false;
 193  
     }
 194  
     
 195  
     public boolean isOverridingSignatureOf(MethodSignature ms)
 196  
     {
 197  0
         if (!(ms instanceof MethodSignatureImpl))
 198  0
             return false;
 199  
         
 200  0
         MethodSignatureImpl sig = (MethodSignatureImpl)ms;
 201  
 
 202  0
         if (!sig._returnType.isAssignableFrom(_returnType))
 203  0
             return false;
 204  
 
 205  0
         if (!_name.equals(sig._name))
 206  0
             return false;
 207  
 
 208  0
         if (mismatch(_parameterTypes, sig._parameterTypes))
 209  0
             return false;
 210  
 
 211  0
         return exceptionsEncompass(sig._exceptionTypes);
 212  
     }
 213  
 
 214  
     /**
 215  
      * The nuts and bolts of checking that another method signature's exceptions are a subset of
 216  
      * this signature's.
 217  
      */
 218  
 
 219  
     protected boolean exceptionsEncompass(Class[] otherExceptions)
 220  
     {
 221  0
         int ourCount = count(_exceptionTypes);
 222  0
         int otherCount = count(otherExceptions);
 223  
 
 224  
         // If we have no exceptions, then ours encompass theirs only if they
 225  
         // have no exceptions, either.
 226  
 
 227  0
         if (ourCount == 0)
 228  0
             return otherCount == 0;
 229  
 
 230  0
         boolean[] matched = new boolean[otherCount];
 231  0
         int unmatched = otherCount;
 232  
 
 233  0
         for (int i = 0; i < ourCount && unmatched > 0; i++)
 234  
         {
 235  0
             for (int j = 0; j < otherCount; j++)
 236  
             {
 237  
                 // Ignore exceptions that have already been matched
 238  
                 
 239  0
                 if (matched[j])
 240  0
                     continue;
 241  
 
 242  
                 // When one of our exceptions is a super-class of one of their exceptions,
 243  
                 // then their exceptions is matched.
 244  
                 
 245  0
                 if (_exceptionTypes[i].isAssignableFrom(otherExceptions[j]))
 246  
                 {
 247  0
                     matched[j] = true;
 248  0
                     unmatched--;
 249  
                 }
 250  
             }
 251  
         }
 252  
 
 253  0
         return unmatched == 0;
 254  
     }
 255  
 }