001/*license*\ 002 Codelet: Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com) 003 004 This software is dual-licensed under the: 005 - Lesser General Public License (LGPL) version 3.0 or, at your option, any later version; 006 - Apache Software License (ASL) version 2.0. 007 008 Either license may be applied at your discretion. More information may be found at 009 - http://en.wikipedia.org/wiki/Multi-licensing. 010 011 The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at: 012 - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt 013 - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt 014\*license*/ 015package com.github.aliteralmind.codelet.simplesig; 016 import com.github.xbn.lang.CrashIfObject; 017 import com.github.xbn.util.JavaRegexes; 018 import com.google.common.base.Joiner; 019 import java.lang.reflect.Member; 020 import java.util.ArrayList; 021 import java.util.Collections; 022 import java.util.List; 023 import java.util.Objects; 024 import java.util.regex.Matcher; 025 import java.util.regex.Pattern; 026/** 027 <p>A method or constructor signature, using only {@linkplain java.lang.Class#getSimpleName() simple} parameter-type names--this can be matched by a {@code SimpleParamSigSearchTerm}. This class is unrelated to {@link SimpleMethodSignature}.</p> 028 029 * @see SimpleParamSigSearchTerm 030 * @since 0.1.0 031 * @author Copyright (C) 2014, Jeff Epstein ({@code aliteralmind __DASH__ github __AT__ yahoo __DOT__ com}), dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <a href="http://codelet.aliteralmind.com">{@code http://codelet.aliteralmind.com}</a>, <a href="https://github.com/aliteralmind/codelet">{@code https://github.com/aliteralmind/codelet}</a> 032 **/ 033public abstract class SimpleParamNameSignature implements Comparable<SimpleParamNameSignature> { 034 private static final Matcher IDENTIFIER_MTCHR = Pattern.compile(JavaRegexes.IDENTIFIER).matcher(""); 035 private final Member cnstrOrMthd; 036 private final List<String> typeList; 037 private final String noParens; 038 private final String withParens; 039 /** 040 <p>Create a new instance from a constructor or method, and its parameter class types.</p> 041 042 * <p>Equal to 043 <br/> <code>{@link #SimpleParamNameSignature(Member, List) this}(false, cnstr_method, 044 <br/> SimpleParamNameSignature.{@link #getSimpleNameListFromClasses(Class[]) getSimpleNameListFromClasses}(param_types))</code></p> 045 */ 046 public SimpleParamNameSignature(Member cnstr_method, Class<?>[] param_types) { 047 this(false, cnstr_method, 048 SimpleParamNameSignature.getSimpleNameListFromClasses(param_types)); 049 } 050 /** 051 <p>Create a new instance from a method or constructor, and an array of its parameter simple names.</p> 052 053 <p>This sets<ol> 054 <li>{@link #getParamNameList() getParamNameList}{@code ()} to an immutable string-list of all parameter type names.</li> 055 <li>{@link #getWithParens() getWithParens}{@code ()} to a comma-delimited string of the each type's {@linkplain java.lang.Class#getSimpleName() simple names}, in the same order as in {@code types}, surrounded by parentheses.</li> 056 <li>{@link #getNoParens() getNoParens}{@code ()} to the same comma-delimited list, with no paretheses.</li> 057 </ol></p> 058 059 * @see java.lang.Class#getSimpleName() 060 */ 061 public SimpleParamNameSignature(Member cnstr_method, List<String> type_list) { 062 this(false, cnstr_method, type_list); 063 Objects.requireNonNull(cnstr_method, "cnstr_method"); 064 try { 065 for(int i = 0; i < type_list.size(); i++) { 066 try { 067 if(!IDENTIFIER_MTCHR.reset(type_list.get(i)).matches()) { 068 throw new IllegalArgumentException("type_list.get(" + i + ") (\"" + type_list.get(i) + "\") is not a valid Java identifier."); 069 } 070 } catch(RuntimeException rx) { 071 throw CrashIfObject.nullOrReturnCause(type_list.get(i), "type_list.get(" + i + ")", null, rx); 072 } 073 } 074 } catch(RuntimeException rx) { 075 throw CrashIfObject.nullOrReturnCause(type_list, "type_list", null, rx); 076 } 077 } 078 private SimpleParamNameSignature(boolean ignored, Member cnstr_method, List<String> type_list) { 079 try { 080 //Does throw NPX if null: 081 typeList = Collections.unmodifiableList(type_list); 082 } catch(RuntimeException rx) { 083 throw CrashIfObject.nullOrReturnCause(type_list, "type_list", null, rx); 084 } 085 cnstrOrMthd = cnstr_method; 086 noParens = Joiner.on(", ").join(typeList); 087 withParens = "(" + noParens + ")"; 088 } 089 /** 090 <p>The method or constructor having these parameters.</p> 091 092 * @return A non-{@code null} {@linkplain java.lang.reflect.Method method} or {@linkplain java.lang.reflect.Constructor constructor} object. 093 */ 094 public Member getMember() { 095 return cnstrOrMthd; 096 } 097 /** 098 <p>List of all parameter-type simple names.</p> 099 100 * @return An immutable list of all parameter-types, in the same order as they exist in the consructor or function. If no parameters, this is an empty list. 101 * @see #getWithParens() 102 * @see #SimpleParamNameSignature(Member, List) 103 * @see java.lang.Class#getSimpleName() 104 */ 105 public List<String> getParamNameList() { 106 return typeList; 107 } 108 /** 109 <p>Comma-delimited string of all parameter-type simple names, excluding the surrounding parentheses.</p> 110 111 * @return A non-{@code null}, comma-delimited string of all simple type names, in the same order as declared, with a single space between each comma. 112 * @see #getWithParens() 113 */ 114 public String getNoParens() { 115 return noParens; 116 } 117 /** 118 <p>Comma-delimited string of all parameter-type simple names, listed in the same order as declared, including the surrounding parentheses.</p> 119 120 * @return A non-{@code null}, comma-delimited string of all simple type names, in the same order as declared, with a single space between each comma. 121 * @see #getParamNameList() 122 * @see #getNoParens() 123 * @see #toString() 124 */ 125 public String getWithParens() { 126 return withParens; 127 } 128 /** 129 <p>If a method: its name, if a constructor: the empty string ({@code ""}).</p> 130 */ 131 public abstract String getMethodName(); 132 /** 133 * @return <code>{@link #getMethodName() getMethodName}() + {@link #getWithParens() getWithParens}()</code> 134 */ 135 public String toString() { 136 return getMethodName() + getWithParens(); 137 } 138 /** 139 * @return <code>{@link #getWithParens() getWithParens}().compareTo(to_compareTo.getWithParens())</code> <i>(This does not need to be overriden to include the constructor/function name. This is only for sorting parameter-lists within each constructor/method.)</i> 140 */ 141 public int compareTo(SimpleParamNameSignature to_compareTo) { 142 return getWithParens().compareTo(to_compareTo.getWithParens()); 143 } 144 /** 145 <p>Create a list of all simple names from a class array.</p> 146 147 * @param types May not be {@code null}. 148 * @return A non-null list having the same length as {@code types}. 149 * @see #SimpleParamNameSignature(Member, Class[]) 150 */ 151 public static final List<String> getSimpleNameListFromClasses(Class<?>[] types) { 152 List<String> typeList = null; 153 try { 154 typeList = new ArrayList<String>(types.length); 155 } catch(RuntimeException rx) { 156 throw CrashIfObject.nullOrReturnCause(types, "types", null, rx); 157 } 158 for(Class<?> type : types) { 159 typeList.add(type.getSimpleName()); 160 } 161 return typeList; 162 } 163}