All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax0.geci.jamal.macros.Methods Maven / Gradle / Ivy

There is a newer version: 1.6.5
Show newest version
package javax0.geci.jamal.macros;

import javax0.geci.jamal.util.EntityStringer;
import javax0.geci.jamal.util.MacroReader;
import javax0.geci.tools.GeciReflectionTools;
import javax0.geci.tools.reflection.Selector;
import javax0.jamal.api.BadSyntax;
import javax0.jamal.api.InnerScopeDependent;
import javax0.jamal.api.Input;
import javax0.jamal.api.Macro;
import javax0.jamal.api.Processor;

import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * Macro to get all the methods of a class. Templates utilizing this macro can best use the output in a multi-variable
 * for a loop.
 * 

* The macro looks up the methods (inherited and declared) of a class and returns a list of the methods. The format of * the information, the selection criteria, which methods to include in the output, and the separator characters are all * defined in user defined macros. *

* The format of the data about the individual methods is driven by the user defined macro {@code $mformat}. It can be * set in the code template file using the macro {@code mformat} or {@code format} defined in {@code res:geci.jim}. (The * macro {@code format} sets also the user defined macro {@code fformat}, which is used by the macro {@link Fields}. *

* The format can contain the following placeholders: *

    *
  • {@code $class} is replaced by the declaring class of the field.
  • *
  • {@code $name} is replaced by the name of the field.
  • *
  • {@code $type} is replaced by the type of the field.
  • *
  • {@code $modifiers} is replaced by the space-separated list of the field's modifiers. This string will * also contain a trailing space of the string if it is not empty.
  • *
  • {@code $exceptions} is replaced by the list of the exceptions that the method throws.
  • *
  • {@code $args} is replaced by the list of argument types the method has. If the method is a vararg * method then the last type will end with {@code ...} instead of {@code []}.
  • *
  • {@code $exsep} is used as separator in the list of exceptions. The default value is '{@code :}'.
  • *
  • {@code $argsep} is used as separator in the list of arguments. The default value is '{@code :}'.
  • *
*

* The selector is defined by the user defined macro {@code $selector}. You can set it using the macro {@code * selector}. All these user defined macros are defined in the {@code res:geci.jim} file. *

* The class is defined by {@code $class}, again use {@code class} macro. *

* The macro is inner scope dependent, which means that these macros can be used inside the opening and closing {@code * {% %}} strings. This is the recommended use unless you want to reuse the same values in the same file. Using the * macros inside the {@code methods} macro will limit the effect of the macros to the actual {@code methods} macro. This * use also assumes that the {@code methods} macro is used with the {@code #} character as *

{@code
 * {%#methods ...%}
 * }
* to ensure that these macros inside are evaluated before the {@code methods} macro starts to be evaluated. *

* The information about the methods are joined using coma. * */ public class Methods implements Macro, InnerScopeDependent { @Override public String evaluate(Input in, Processor processor) throws BadSyntax { final var reader = new MacroReader(processor); final var selector = Selector.compile(reader.readValue("$selector").orElse("true")); final var klassName = reader.readValue("$class").orElseThrow( () -> new BadSyntax("There is no $class defined for the macro `methods`") ); final Class klass; try { klass = GeciReflectionTools.classForName(klassName); } catch (ClassNotFoundException e) { throw new BadSyntax("Class " + klassName + "cannot be found for the macro `methods`"); } final var format = reader.readValue("$mformat").orElse("$class|$name|$args"); final var argsep = reader.readValue("$argsep").orElse(":"); final var exsep = reader.readValue("$exsep").orElse(":"); var allMethods = GeciReflectionTools.getAllMethodsSorted(klass); return Arrays.stream(allMethods).filter(selector::match) .map(m -> EntityStringer.method2Fingerprint(m, format, argsep, exsep)) .collect(Collectors.joining(",")); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy