001 /*** 002 * 003 * Copyright (c) 2007 Paul Hammant 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions 008 * are met: 009 * 1. Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 2. Redistributions in binary form must reproduce the above copyright 012 * notice, this list of conditions and the following disclaimer in the 013 * documentation and/or other materials provided with the distribution. 014 * 3. Neither the name of the copyright holders nor the names of its 015 * contributors may be used to endorse or promote products derived from 016 * this software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 028 * THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030 031 package com.thoughtworks.paranamer; 032 033 import com.thoughtworks.paranamer.BytecodeReadingParanamer; 034 035 import java.lang.reflect.AccessibleObject; 036 import java.lang.reflect.Method; 037 import java.lang.reflect.Constructor; 038 039 /** 040 * Implementation of Paranamer which automatically chooses between two Paranamer implementations depending on which can supply data 041 * 042 * @author Paul Hammant 043 * @author Mauro Talevi 044 */ 045 public class AdaptiveParanamer implements Paranamer { 046 047 public static final String __PARANAMER_DATA = "v1.0 \n" 048 + "com.thoughtworks.paranamer.AdaptiveParanamer AdaptiveParanamer \n" 049 + "com.thoughtworks.paranamer.AdaptiveParanamer AdaptiveParanamer com.thoughtworks.paranamer.Paranamer,com.thoughtworks.paranamer.Paranamer delegate,fallback\n" 050 + "com.thoughtworks.paranamer.AdaptiveParanamer toString \n" 051 + "com.thoughtworks.paranamer.AdaptiveParanamer lookupParameterNames java.lang.AccessibleObject methodOrCtor \n"; 052 053 private Paranamer delegate; 054 private Paranamer fallback; 055 056 /** 057 * Cache a DefaultParanamer's lookups. 058 */ 059 public AdaptiveParanamer() { 060 this(new DefaultParanamer(), new BytecodeReadingParanamer()); 061 } 062 063 064 /** 065 * Cache a primary and secondary Paranamer instance (the second is a fallback to the first) 066 * @param delegate first 067 * @param fallback second 068 */ 069 public AdaptiveParanamer(Paranamer delegate, Paranamer fallback) { 070 this.delegate = delegate; 071 this.fallback = fallback; 072 if (delegate == null || fallback == null || delegate == fallback) { 073 throw new RuntimeException("must supply delegate and fallback (which must be different)"); 074 } 075 } 076 077 public String[] lookupParameterNames(AccessibleObject methodOrConstructor) { 078 return lookupParameterNames(methodOrConstructor, true); 079 } 080 081 public String[] lookupParameterNames(AccessibleObject methodOrCtor, boolean throwExceptionIfMissing) { 082 083 Class declaringClass = null; 084 String name = null; 085 if (methodOrCtor instanceof Method) { 086 Method method = (Method) methodOrCtor; 087 declaringClass = method.getDeclaringClass(); 088 name = method.getName(); 089 } else { 090 Constructor constructor = (Constructor) methodOrCtor; 091 declaringClass = constructor.getDeclaringClass(); 092 name = constructor.getName(); 093 } 094 095 String[] names = delegate.lookupParameterNames(methodOrCtor, false); 096 if (names == Paranamer.EMPTY_NAMES) { 097 names = fallback.lookupParameterNames(methodOrCtor, throwExceptionIfMissing); 098 } 099 return names; 100 101 } 102 103 /** 104 * @Deperecated Use 'new CachingParanamer(new AdaptiveParanamer())' instead. 105 */ 106 public int areParameterNamesAvailable(Class clazz, String ctorOrMethodName) { 107 int i = delegate.areParameterNamesAvailable(clazz, ctorOrMethodName); 108 if (i != Paranamer.PARAMETER_NAMES_FOUND) { 109 i = fallback.areParameterNamesAvailable(clazz, ctorOrMethodName); 110 } 111 return i; 112 } 113 114 public String toString() { 115 return new StringBuffer("[AdaptiveParanamer delegate=") 116 .append(delegate).append(", fallback=").append(fallback).append("]").toString(); 117 } 118 119 }