View Javadoc

    1   /***************************************************************************************
    2    * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
    3    * http://aspectwerkz.codehaus.org                                                    *
    4    * ---------------------------------------------------------------------------------- *
    5    * The software in this package is published under the terms of the LGPL license      *
    6    * a copy of which has been included with this distribution in the license.txt file.  *
    7    **************************************************************************************/
    8   package org.codehaus.aspectwerkz.reflect;
    9
    10  import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
    11  import org.codehaus.aspectwerkz.transform.TransformationConstants;
    12  import org.codehaus.aspectwerkz.util.Strings;
    13
    14  import java.lang.reflect.Method;
    15  import java.util.Comparator;
    16
    17  /***
    18   * Compares Methods. To be used when sorting methods.
    19   *
    20   * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
    21   */
    22  public final class MethodComparator implements java.util.Comparator {
    23      /***
    24       * Compares normal method names.
    25       */
    26      public static final int NORMAL_METHOD = 0;
    27
    28      /***
    29       * Compares prefixed method names.
    30       */
    31      public static final int PREFIXED_METHOD = 1;
    32
    33      /***
    34       * Compares method infos.
    35       */
    36      public static final int METHOD_INFO = 2;
    37
    38      /***
    39       * Defines the type of comparator.
    40       */
    41      private final int m_type;
    42
    43      /***
    44       * Sets the type.
    45       *
    46       * @param type the type
    47       */
    48      private MethodComparator(final int type) {
    49          m_type = type;
    50      }
    51
    52      /***
    53       * Returns the comparator instance.
    54       *
    55       * @param type the type of the method comparison
    56       * @return the instance
    57       */
    58      public static Comparator getInstance(final int type) {
    59          return new MethodComparator(type);
    60      }
    61
    62      /***
    63       * Compares two objects.
    64       *
    65       * @param o1
    66       * @param o2
    67       * @return int
    68       */
    69      public int compare(final Object o1, final Object o2) {
    70          switch (m_type) {
    71              case NORMAL_METHOD:
    72                  return compareNormal((Method) o1, (Method) o2);
    73              case PREFIXED_METHOD:
    74                  return comparePrefixed((Method) o1, (Method) o2);
    75              case METHOD_INFO:
    76                  return compareMethodInfo((MethodInfo) o1, (MethodInfo) o2);
    77              default:
    78                  throw new RuntimeException("invalid method comparison type");
    79          }
    80      }
    81
    82      /***
    83       * Compares two methods.
    84       *
    85       * @param m1
    86       * @param m2
    87       * @return int
    88       */
    89      private int compareNormal(final Method m1, final Method m2) {
    90          try {
    91              if (m1.equals(m2)) {
    92                  return 0;
    93              }
    94              final String m1Name = m1.getName();
    95              final String m2Name = m2.getName();
    96              if (!m1Name.equals(m2Name)) {
    97                  return m1Name.compareTo(m2Name);
    98              }
    99              final Class[] args1 = m1.getParameterTypes();
    100             final Class[] args2 = m2.getParameterTypes();
    101             if (args1.length < args2.length) {
    102                 return -1;
    103             }
    104             if (args1.length > args2.length) {
    105                 return 1;
    106             }
    107             if (args1.length == 0) {
    108                 return 0;
    109             }
    110             for (int i = 0; i < args1.length; i++) {
    111                 //handles array types - AW-104
    112                 int result = TypeConverter.convertTypeToJava(args1[i]).compareTo(
    113                         TypeConverter.convertTypeToJava(args2[i])
    114                 );
    115                 if (result != 0) {
    116                     return result;
    117                 }
    118             }
    119         } catch (Throwable e) {
    120             throw new WrappedRuntimeException(e);
    121         }
    122         java.lang.System.err.println(m1.getName());
    123         java.lang.System.err.println(m2.getName());
    124         throw new Error("should be unreachable");
    125     }
    126
    127     /***
    128      * Compares two prefixed methods. Assumes the the prefixed methods looks like this: "somePrefix SEP methodName SEP"
    129      *
    130      * @param m1
    131      * @param m2
    132      * @return int
    133      */
    134     private int comparePrefixed(final Method m1, final Method m2) {
    135         try {
    136             if (m1.equals(m2)) {
    137                 return 0;
    138             }
    139
    140             // compare only the original method names, i.e. remove the prefix and suffix
    141             final String[] m1Tokens = Strings.splitString(m1.getName(), TransformationConstants.DELIMITER);
    142             final String[] m2Tokens = Strings.splitString(m2.getName(), TransformationConstants.DELIMITER);
    143             final String m1Name = m1Tokens[1];
    144             final String m2Name = m2Tokens[1];
    145             if (!m1Name.equals(m2Name)) {
    146                 return m1Name.compareTo(m2Name);
    147             }
    148             final Class[] args1 = m1.getParameterTypes();
    149             final Class[] args2 = m2.getParameterTypes();
    150             if (args1.length < args2.length) {
    151                 return -1;
    152             }
    153             if (args1.length > args2.length) {
    154                 return 1;
    155             }
    156             if (args1.length == 0) {
    157                 return 0;
    158             }
    159             for (int i = 0; i < args1.length; i++) {
    160                 //handles array types - AW-104
    161                 int result = TypeConverter.convertTypeToJava(args1[i]).compareTo(
    162                         TypeConverter.convertTypeToJava(args2[i])
    163                 );
    164                 if (result != 0) {
    165                     return result;
    166                 }
    167             }
    168         } catch (Throwable e) {
    169             throw new WrappedRuntimeException(e);
    170         }
    171         java.lang.System.err.println(m1.getName());
    172         java.lang.System.err.println(m2.getName());
    173         throw new Error("should be unreachable");
    174     }
    175
    176     /***
    177      * Compares two methods meta-data.
    178      *
    179      * @param m1
    180      * @param m2
    181      * @return int
    182      */
    183     private int compareMethodInfo(final MethodInfo m1, final MethodInfo m2) {
    184         try {
    185             if (m1.equals(m2)) {
    186                 return 0;
    187             }
    188             final String m1Name = m1.getName();
    189             final String m2Name = m2.getName();
    190             if (!m1Name.equals(m2Name)) {
    191                 return m1Name.compareTo(m2Name);
    192             }
    193             final ClassInfo[] args1 = m1.getParameterTypes();
    194             final ClassInfo[] args2 = m2.getParameterTypes();
    195             if (args1.length < args2.length) {
    196                 return -1;
    197             }
    198             if (args1.length > args2.length) {
    199                 return 1;
    200             }
    201             if (args1.length == 0) {
    202                 return 0;
    203             }
    204             for (int i = 0; i < args1.length; i++) {
    205                 int result;
    206                 if (args1[i].getName().equals(args2[i].getName())) {
    207                     result = 0;
    208                 } else {
    209                     result = args1[i].getName().compareTo(args2[i].getName());
    210                 }
    211                 if (result != 0) {
    212                     return result;
    213                 }
    214             }
    215         } catch (Throwable e) {
    216             throw new WrappedRuntimeException(e);
    217         }
    218         java.lang.System.err.println(m1.getName());
    219         java.lang.System.err.println(m2.getName());
    220         throw new Error("should be unreachable");
    221     }
    222 }