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

javax0.geci.api.Generator Maven / Gradle / Ivy

package javax0.geci.api;

import java.util.function.Supplier;

/**
 * Generators get source code information from the framework and
 * generate code. File writing and inserting the code to the existing
 * source code and mixing the manual and generated code is up to the
 * framework.
 */
@FunctionalInterface
public interface Generator {

    /**
     * Process the {@link Source} and presumably generate some code.
     *
     * @param source the object representing the source code that can
     *               also be altered by the generation during the
     *               processing. The {@code source} object is not the
     *               raw source code, rather it represents it and the
     *               generator should use the API provided by the class
     *               {@link Source} to access the text of the code as a
     *               series of lines as {@link String} objects as well
     *               as to write generated code back to the source code.
     *               The actual file manipulation will be handled by the
     *               framework.
     */
    void process(Source source);

    /**
     * Signal if a certain phase is needed by this generator.
     * 

* When a generator needs more than one phase, say {@code n * > 1} to execute then this method should return {@code true} for * {@code phase} values {@code 0...n-1} and {@code false} if {@code * phase} is larger than {@code n-1}. This is the simplest case. * (Also such a generator should implement the method {@link * #phases()} to define the number of phases it needs. *

* In a more complex situation some special generators may cooperate * with other generators. Say there are two generators {@code A} and * {@code B}. Generator {@code A} performs certain task in the first * phase (phase {@code 0}). It may be collecting information from * source code, resources etc. Then {@code B} is needed to do its * task. To ensure that the data collection performed by {@code A} * in the first phase, the generator {@code B} should be run in the * second phase (phase {@code 1}). After {@code B} is finished the * first generator, generator {@code A} can finish its work in the * third phase (phase {@code 2}). *

* In this situation the generator {@code A} should return {@code * true} from this method when {@code phase} is zero or two and * {@code B} should return {@code true} when {@code phase} is one. * That way *

     * phase       A.activeIn(phase)     B.activeIn(phase)
     *   0           true                 false
     *   1           false                true
     *   2           true                 false
     * 
*

* Other than the phasing there is no guarantee on the order of the * generators execution. *

* The default behaviour implemented in the interface is to be * active in the phase {@code 0} only. * * @param phase the current phase. This value can also be stored in * the generator instance to remember the actual phase * when {@link #process(Source)} is invoked the next time * after {@code activeIn()} returned {@code true}. * @return {@code true} if the generator needs to be invoked in * this phase. */ default boolean activeIn(int phase) { return phase == 0; } /** * Return the max number of phases this generator needs. Geci will * query this method once before it starts its work to determine the * maximum number of phases it has to call the generators. *

* Note that the number of phases returned from this method may not * be the actual number of phases the Geci will execute. If Geci is * configured to run other generators that need more phases then * Geci will execute more phases. *

* The default behaviour is to require only one phase. * * @return the maximum number of phases. * Note that when this value is {@code n} then the phase numbers * will be {@code 0...n-1}. */ default int phases() { return 1; } /** * Generators wanting to use the context should implement this * method. The default implementation simply ignores the context. * The actual implementation should store the context in an instance * variable and it is also recommended to fetch the objects using * the keys the generator intends to use calling the {@link * Context#get(Object, Supplier)} method * * @param context to be injected and to be stored by the generator */ default void context(Context context) { } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy