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.reflect.RTNoSuchMethodException; 017 import com.github.xbn.lang.reflect.Declared; 018 import com.github.xbn.lang.CrashIfObject; 019 import com.github.xbn.list.ImmutableValues; 020 import com.github.xbn.list.MapUtil; 021 import com.github.xbn.list.SortListValues; 022 import java.lang.reflect.Constructor; 023 import java.lang.reflect.Method; 024 import java.util.ArrayList; 025 import java.util.Collections; 026 import java.util.List; 027 import java.util.Map; 028 import java.util.TreeMap; 029 import static com.github.xbn.lang.XbnConstants.*; 030/** 031 <p>All constructors and methods in a class.</p> 032 033 * @since 0.1.0 034 * @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> 035 **/ 036public class AllSimpleParamSignatures { 037 private final Class<?> containing; 038 private final List<ConstructorSimpleParamSig> cnstrList; 039 private final Map<String,List<MethodSimpleParamSig>> methodMap; 040 /** 041 <p>Create a new instance from a class.</p> 042 043 <p>Sets<ol> 044 <li>{@link #getConstructorList() getConstructorList}{@code ()} to an {@linkplain java.util.Collections#unmodifiableList(List) immutable} version of 045 <br/> <code>AllSimpleParamSignatures.{@link AllSimpleParamSignatures#newConstructorList(Class, Declared, Sorted) newConstructorList}(containing_cls, declared, {@link Sorted Sorted}.{@link Sorted#YES YES})</code></li> 046 <li>{@link #getMethodMap() getMethodMap}{@code ()} to an {@linkplain java.util.Collections#unmodifiableMap(Map) immutable} version of 047 <br/> <code>AllSimpleParamSignatures.{@link #newMethodMap(Class, Declared, SortListValues, ImmutableValues) newMethodMap}(containing_cls, declared, {@link com.github.xbn.list.SortListValues}.{@link com.github.xbn.list.SortListValues#ORIGINAL ORIGINAL}, {@link com.github.xbn.list.ImmutableValues ImmutableValues}.{@link com.github.xbn.list.ImmutableValues#YES YES})</code></li> 048 </ol></p> 049 050 * @param containing_cls The class containing the methods. May not be {@code null} and <i>should</i> be the class whose methods are in {@code map}. Get with {@link #getContainingClass() getContainingClass}{@code ()}. Get with {@link #getMethodMap() getMethodMap}{@code ()}. 051 */ 052 public AllSimpleParamSignatures(Class<?> containing_cls, Declared declared) { 053 containing = containing_cls; 054 055 List<ConstructorSimpleParamSig> cnstrList2 = AllSimpleParamSignatures. 056 newConstructorList(containing_cls, declared, Sorted.YES); 057 Map<String,List<MethodSimpleParamSig>> methodMap2 = AllSimpleParamSignatures. 058 newMethodMap(containing_cls, declared, SortListValues.ORIGINAL, ImmutableValues.YES); 059 060 //Both throw NPX if null (doesn't apply, just FYI) 061 cnstrList = Collections.<ConstructorSimpleParamSig>unmodifiableList(cnstrList2); 062 methodMap = Collections.<String,List<MethodSimpleParamSig>>unmodifiableMap(methodMap2); 063 } 064 /** 065 <p>All constructors.</p> 066 067 * @return A non-{@code null}, immutable list of all constructors in the {@link #getContainingClass() class}. 068 * @see #getMethodMap() 069 * @see #AllSimpleParamSignatures(Class, Declared) 070 */ 071 public List<ConstructorSimpleParamSig> getConstructorList() { 072 return cnstrList; 073 } 074 /** 075 <p>All methods.</p> 076 077 * @return A non-{@code null}, immutable map of all methods in the {@link #getContainingClass() class}. 078 * @see #getConstructorList() 079 * @see #AllSimpleParamSignatures(Class, Declared) 080 * @see #getMethodListForNameCrashIfNone(String) 081 */ 082 public Map<String,List<MethodSimpleParamSig>> getMethodMap() { 083 return methodMap; 084 } 085 /** 086 <p>Get the methods with a name, or crash if no methods have that name.</p> 087 088 * @return <code>{@link #getMethodMap() getMethodMap}().{@link java.util.Map#get(Object) get}(name)</code> 089 * @exception RTNoSuchMethodException If no methods have the name {@code name}. 090 */ 091 public List<MethodSimpleParamSig> getMethodListForNameCrashIfNone(String name) { 092 List<MethodSimpleParamSig> match = getMethodMap().get(name); 093 if(match == null) { 094 throw new RTNoSuchMethodException("name=\"" + name + "\""); 095 } 096 return match; 097 } 098 /** 099 <p>The class containing the constructors and methods.</p> 100 101 * @see #AllSimpleParamSignatures(Class, Declared) 102 */ 103 public Class<?> getContainingClass() { 104 return containing; 105 } 106 /** 107 * @return <code>{@link #appendToString(StringBuilder) appendToString}(new StringBuilder()).toString()</code> 108 */ 109 public String toString() { 110 return appendToString(new StringBuilder()).toString(); 111 } 112 /** 113 <p>A summary of all constructors and functions.</p> 114 115 * @param to_appendTo May not be {@code null}. 116 * @see #toString() 117 */ 118 public StringBuilder appendToString(StringBuilder to_appendTo) { 119 try { 120 to_appendTo.append(getContainingClass().getName()).append(": ").append("constructors=" + getConstructorList().size()).append(", "); 121 } catch(RuntimeException rx) { 122 throw CrashIfObject.nullOrReturnCause(to_appendTo, "to_appendTo", null, rx); 123 } 124 125 int i = 0; 126 int sizeMinus1 = getMethodMap().size() - 1; 127 for (Map.Entry<String,List<MethodSimpleParamSig>> entry : methodMap.entrySet()) { 128 to_appendTo.append(entry.getKey()).append("=").append(entry.getValue().size()); 129 if(i < sizeMinus1) { 130 to_appendTo.append(", "); 131 } 132 } 133 134 return to_appendTo; 135 } 136 /** 137 * @return <code>{@link #appendFullToString(StringBuilder) appendFullToString}(new StringBuilder()).toString()</code> 138 */ 139 public String fullToString() { 140 return appendFullToString(new StringBuilder()).toString(); 141 } 142 /** 143 <p>A full listing of all constructors and functions.</p> 144 145 * @param to_appendTo May not be {@code null}. 146 * @see #fullToString() 147 */ 148 public StringBuilder appendFullToString(StringBuilder to_appendTo) { 149 try { 150 to_appendTo.append(getContainingClass().getName()).append(":").append(LINE_SEP).append("Constructors (").append(getConstructorList().size()).append("):").append(LINE_SEP); 151 } catch(RuntimeException rx) { 152 throw CrashIfObject.nullOrReturnCause(to_appendTo, "to_appendTo", null, rx); 153 } 154 155 AllSimpleParamSignatures.appendToStringForAllListsInList(to_appendTo, " - ", getConstructorList(), LINE_SEP); 156 157 to_appendTo.append(LINE_SEP).append("All methods:").append(LINE_SEP); 158 159// int i = 0; 160// int sizeMinus1 = getMethodMap().size() - 1; 161 for (Map.Entry<String,List<MethodSimpleParamSig>> entry : methodMap.entrySet()) { 162 List<MethodSimpleParamSig> value = entry.getValue(); 163 if(value.size() == 1) { 164 to_appendTo.append(" - ").append(value.get(0)).append(LINE_SEP); 165 166 } else { 167 to_appendTo.append(" - ").append(entry.getKey()). 168 append(" (").append(value.size()).append(")").append(LINE_SEP); 169 AllSimpleParamSignatures.appendToStringForAllListsInList(to_appendTo, " - ", value, LINE_SEP); 170 to_appendTo.append(LINE_SEP); 171 } 172 } 173 return to_appendTo; 174 } 175 /** 176 <p>For displaying all parameter-lists in a list.</p> 177 178 * @return <code>{@link #appendToStringForAllListsInList(StringBuilder, String, List, String) appendToStringForAllListsInArray}((new StringBuilder()), prefix, param_listList, between).toString()</code> 179 */ 180 public static final String toStringForAllListsInList(String prefix, List<? extends SimpleParamNameSignature> param_listList, String between) { 181 return appendToStringForAllListsInList((new StringBuilder()), prefix, param_listList, between).toString(); 182 } 183 /** 184 <p>For displaying all parameter-lists in a list.</p> 185 186 * @return <code>{@link #appendToStringForAllListsInArray(StringBuilder, String, SimpleParamNameSignature[], String) appendToStringForAllListsInArray}(new StringBuilder(), prefix, methods, between).toString()</code> 187 */ 188 public static final StringBuilder appendToStringForAllListsInList(StringBuilder to_appendTo, String prefix, List<? extends SimpleParamNameSignature> param_listList, String between) { 189 try { 190 return appendToStringForAllListsInArray(to_appendTo, prefix, 191 param_listList.toArray(new SimpleParamNameSignature[param_listList.size()]), 192 between); 193 } catch(RuntimeException rx) { 194 throw CrashIfObject.nullOrReturnCause(param_listList, "param_listList", null, rx); 195 } 196 } 197 /** 198 <p>For displaying all parameter-lists in an array.</p> 199 200 * @return <code>{@link #appendToStringForAllListsInArray(StringBuilder, String, SimpleParamNameSignature[], String) appendToStringForAllListsInArray}(new StringBuilder(), prefix, methods, between).toString()</code> 201 */ 202 public static final String toStringForAllListsInArray(String prefix, SimpleParamNameSignature[] param_lists, String between) { 203 return appendToStringForAllListsInArray(new StringBuilder(), prefix, param_lists, between).toString(); 204 } 205 /** 206 <p>For displaying all parameter-lists in an array.</p> 207 208 * @param to_appendTo May not be {@code null}. 209 * @param prefix What to print before each method. Setting this to {@code null} is the same as setting it to the empty-string ({@code ""}). 210 * @param param_lists May not be {@code null}, and no element may be {@code null}. 211 * @param between What to print between each method. <i>Should</i> not be {@code null} or empty. 212 */ 213 public static final StringBuilder appendToStringForAllListsInArray(StringBuilder to_appendTo, String prefix, SimpleParamNameSignature[] param_lists, String between) { 214 int sizeMinus1 = -1; 215 try { 216 sizeMinus1 = param_lists.length - 1; 217 } catch(RuntimeException rx) { 218 throw CrashIfObject.nullOrReturnCause(param_lists, "param_lists", null, rx); 219 } 220 221 if(prefix == null) { 222 prefix = ""; 223 } 224 225 int i = 0; 226 try { 227 for(; i < param_lists.length; i++) { 228 try { 229 to_appendTo.append(prefix).append(param_lists[i].toString()); 230 } catch(RuntimeException rx) { 231 throw CrashIfObject.nullOrReturnCause(to_appendTo, "to_appendTo", null, rx); 232 } 233 if(i < sizeMinus1) { 234 to_appendTo.append(between); 235 } 236 } 237 } catch(RuntimeException rx) { 238 throw CrashIfObject.nullOrReturnCause(param_lists[i], "param_lists[i]", null, rx); 239 } 240 return to_appendTo; 241 } 242 /** 243 <p>Create a new list of all constructors in a class.</p> 244 245 * @param containing_cls May not be {@code null}. 246 * @param declared If {@link com.github.xbn.lang.reflect.Declared Declared}.{@link com.github.xbn.lang.reflect.Declared#YES YES}, then {@linkplain java.lang.Class#getDeclaredMethods() declared} methods are retrieved. If {@link com.github.xbn.lang.reflect.Declared#NO NO}, {@linkplain java.lang.Class#getMethods() non-declared}. 247 * @param sort If {@link com.github.xbn.list.SortListValues#ORIGINAL ORIGINAL} or {@link com.github.xbn.list.SortListValues#DUPLICATE DUPLICATE}, then the returned list is sorted. 248 */ 249 public static final List<ConstructorSimpleParamSig> newConstructorList(Class<?> containing_cls, Declared declared, Sorted sort) { 250 Constructor<?>[] cnstrs = null; 251 try { 252 cnstrs = (declared.isYes() ? containing_cls.getDeclaredConstructors() 253 : containing_cls.getConstructors()); 254 } catch(RuntimeException rx) { 255 CrashIfObject.nnull(containing_cls, "containing_cls", null); 256 throw CrashIfObject.nullOrReturnCause(declared, "declared", null, rx); 257 } 258 List<ConstructorSimpleParamSig> list = new ArrayList<ConstructorSimpleParamSig>(cnstrs.length); 259 for(Constructor<?> cnstr : cnstrs) { 260 list.add(new ConstructorSimpleParamSig(cnstr)); 261 } 262 263 try { 264 if(sort.isYes()) { 265 Collections.<ConstructorSimpleParamSig>sort(list); 266 } 267 268 return list; 269 } catch(RuntimeException rx) { 270 throw CrashIfObject.nullOrReturnCause(sort, "sort", null, rx); 271 } 272 } 273 /** 274 <p>Create a new map of all methods in a class.</p> 275 276 * @param containing_cls May not be {@code null}. 277 * @param declared If {@link com.github.xbn.lang.reflect.Declared Declared}.{@link com.github.xbn.lang.reflect.Declared#YES YES}, then {@linkplain java.lang.Class#getDeclaredMethods() declared} methods are retrieved. If {@link com.github.xbn.lang.reflect.Declared#NO NO}, {@linkplain java.lang.Class#getMethods() non-declared}. 278 * @return A non-null map containing all methods. This ends by returning 279 <br/> <code>{@link com.github.xbn.list.MapUtil MapUtil}.<MethodSimpleParamSig,String>{@link com.github.xbn.list.MapUtil#getWithModifiedListValues(Map, SortListValues, ImmutableValues) getWithModifiedListValues}(<i>[the-map]</i>, sort_lists, immutable_lists)</code> 280 */ 281 public static final Map<String,List<MethodSimpleParamSig>> newMethodMap(Class<?> containing_cls, Declared declared, SortListValues sort_lists, ImmutableValues immutable_lists) { 282 Method[] methods = null; 283 try { 284 methods = (declared.isYes() ? containing_cls.getDeclaredMethods() 285 : containing_cls.getMethods()); 286 } catch(RuntimeException rx) { 287 CrashIfObject.nnull(containing_cls, "containing_cls", null); 288 throw CrashIfObject.nullOrReturnCause(declared, "declared", null, rx); 289 } 290 Map<String,List<MethodSimpleParamSig>> map = new TreeMap<String,List<MethodSimpleParamSig>>(); 291 for(Method m : methods) { 292 String name = m.getName(); 293 if(!map.containsKey(name)) { 294 List<MethodSimpleParamSig> list = new ArrayList<MethodSimpleParamSig>(3); 295 list.add(new MethodSimpleParamSig(m)); 296 map.put(name, list); 297 } else { 298 map.get(name).add(new MethodSimpleParamSig(m)); 299 } 300 } 301 302 return MapUtil.<MethodSimpleParamSig,String>getWithModifiedListValues(map, sort_lists, immutable_lists); 303 } 304}