11
22package org .scijava .param ;
33
4- import java .lang .annotation .Annotation ;
54import java .lang .reflect .AnnotatedElement ;
6- import java .lang .reflect .AnnotatedType ;
75import java .lang .reflect .Field ;
86import java .lang .reflect .Method ;
97import java .lang .reflect .Modifier ;
@@ -156,6 +154,44 @@ public static List<Member<?>> parse(final Field field) throws ValidityException
156154
157155 return items ;
158156 }
157+
158+ /**
159+ * Returns a list of {@link FunctionalMethodType}s describing the input and output
160+ * types of the functional method of the specified functional type. In doing so,
161+ * the return type of the method will me marked as {@link ItemIO#OUTPUT} and the
162+ * all method parameters as {@link ItemIO#OUTPUT}, except for parameters annotated
163+ * with {@link Mutable} which will be marked as {@link ItemIO#BOTH}. If the specified
164+ * type does not have a functional method in its hierarchy, null will be
165+ * returned.<br>
166+ * The order will be the following: method parameters from left to right, return type
167+ *
168+ * @param functionalType
169+ * @return
170+ */
171+ public static List <FunctionalMethodType > findFunctionalMethodTypes (Type functionalType ) {
172+ Method functionalMethod = findFunctionalMethod (Types .raw (functionalType ));
173+ if (functionalMethod == null ) return null ;
174+
175+ Type paramfunctionalType = functionalType ;
176+ if (functionalType instanceof Class ) {
177+ paramfunctionalType = Types .parameterizeRaw ((Class <?>) functionalType );
178+ }
179+
180+ List <FunctionalMethodType > out = new ArrayList <>();
181+ int i = 0 ;
182+ for (Type t : Types .getExactParameterTypes (functionalMethod , paramfunctionalType )) {
183+ boolean isMutable = AnnotationUtils .getMethodParameterAnnotation (functionalMethod , i , Mutable .class ) != null ;
184+ out .add (new FunctionalMethodType (t , isMutable ? ItemIO .BOTH : ItemIO .INPUT ));
185+ i ++;
186+ }
187+
188+ Type returnType = Types .getExactReturnType (functionalMethod , paramfunctionalType );
189+ if (!returnType .equals (void .class )) {
190+ out .add (new FunctionalMethodType (returnType , ItemIO .OUTPUT ));
191+ }
192+
193+ return out ;
194+ }
159195
160196 // -- Helper methods --
161197
@@ -392,7 +428,7 @@ public static Class<?> findFunctionalInterface(Class<?> type) {
392428 return findFunctionalInterface (type .getSuperclass ());
393429 }
394430
395- public static boolean checkValidity (Parameter param , String name ,
431+ private static boolean checkValidity (Parameter param , String name ,
396432 Class <?> type , boolean isFinal , Set <String > names ,
397433 ArrayList <ValidityProblem > problems )
398434 {
@@ -425,64 +461,6 @@ public static boolean checkValidity(Parameter param, String name,
425461 return valid ;
426462 }
427463
428- /**
429- * Returns a list of {@link FunctionalMethodType}s describing the input and output
430- * types of the functional method of the specified functional type. In doing so,
431- * the return type of the method will me marked as {@link ItemIO#OUTPUT} and the
432- * all method parameters as {@link ItemIO#OUTPUT}, except for parameters annotated
433- * with {@link Mutable} which will be marked as {@link ItemIO#BOTH}. If the specified
434- * type does not have a functional method in its hierarchy, null will be
435- * returned.<br>
436- * The order will be the following: method parameters from left to right, return type
437- *
438- * @param functionalType
439- * @return
440- */
441- public static List <FunctionalMethodType > findFunctionalMethodTypes (Type functionalType ) {
442- Method functionalMethod = findFunctionalMethod (Types .raw (functionalType ));
443- if (functionalMethod == null ) return null ;
444-
445- Type paramfunctionalType = functionalType ;
446- if (functionalType instanceof Class ) {
447- paramfunctionalType = Types .parameterizeRaw ((Class <?>) functionalType );
448- }
449-
450- List <FunctionalMethodType > out = new ArrayList <>();
451- int i = 0 ;
452- for (Type t : Types .getExactParameterTypes (functionalMethod , paramfunctionalType )) {
453- boolean isMutable = getMethodParameterAnnotation (functionalMethod , i , Mutable .class ) != null ;
454- out .add (new FunctionalMethodType (t , isMutable ? ItemIO .BOTH : ItemIO .INPUT ));
455- i ++;
456- }
457-
458- Type returnType = Types .getExactReturnType (functionalMethod , paramfunctionalType );
459- if (!returnType .equals (void .class )) {
460- out .add (new FunctionalMethodType (returnType , ItemIO .OUTPUT ));
461- }
462-
463- return out ;
464- }
465-
466- /**
467- * Attempt to retrieve the specified annotation from the i'th parameter
468- * of the specified method. This method will only find annotations with:
469- * <pre>@Target(ElementType.TYPE_USE)</pre>
470- * If the ElementType is different or no annotation with specified type
471- * is present, null is returned.
472- *
473- * @param method
474- * @param i
475- * @param annotationClass
476- * @return
477- */
478- public static <A extends Annotation > A getMethodParameterAnnotation (Method method , int i , Class <A > annotationClass ) {
479- AnnotatedType [] params = method .getAnnotatedParameterTypes ();
480- if (i >= params .length ) {
481- return null ;
482- }
483- return params [i ].getAnnotation (annotationClass );
484- }
485-
486464 /**
487465 * Attempts to find the single functional method of the specified
488466 * class, by scanning the for functional interfaces. If there
@@ -491,7 +469,7 @@ public static <A extends Annotation> A getMethodParameterAnnotation(Method metho
491469 * @param cls
492470 * @return
493471 */
494- public static Method findFunctionalMethod (Class <?> cls ) {
472+ private static Method findFunctionalMethod (Class <?> cls ) {
495473 Class <?> iFace = findFunctionalInterface (cls );
496474 if (iFace == null ) {
497475 return null ;
0 commit comments