com.github.czyzby.lml.annotation.LmlInject Maven / Gradle / Ivy
package com.github.czyzby.lml.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** When a view is filled by a LML parser, its fields (and their annotations) are processed. However, complex views
* might contain many actors with unique IDs that should be injected and view classes might get messy really fast. This
* annotation allows to "delegate" some of the injection to a container class. For example:
*
*
*
*
* public class SomeView implements LmlView {
* {@literal @}LmlActor("someId") Button button;
* {@literal @}LmlInject MyContainer container;
* (...)
* }
*
* public class MyContainer {
* {@literal @}LmlActor("someOtherId") Button button;
* {@literal @}LmlActor("labelId") Label label;
* {@literal @}OnChange("loading") float progress;
* // Getters, etc.
* (...)
* }
*
*
*
Upon filling {@code SomeView} instance after LML template parsing, an instance of {@code MyContainer}
* will be created with public no-arg constructor, its fields will be filled and it will be injected in to
* {@code SomeView "container"} field.
*
*
* This annotation basically allows to process fields of foreign classes that are referenced in view's fields. New
* instances of objects are created only when current field value is null or {@link #newInstance()} returns true;
* otherwise current field value will be processed and filled.
*
*
* Note that while injected containers can have {@link LmlInject}-annotated fields, circular references are not
* detected. If, for example, {@code SomeView} has {@link LmlInject}-annotated field of {@code SomeView} type, injection
* would never finish correctly and an exception would be eventually thrown.
*
*
* This annotation can also annotate a field with {@link com.github.czyzby.lml.parser.LmlParser} type (or with LmlParser
* class in {@link #value()}, which will have the same effect, but will let you use a more specific parser type). Parser
* used to fill the view will be injected. For example:
*
*
*
*
* {@literal @}LmlInject LmlParser parser;
* {@literal @}LmlInject(LmlParser.class) DefaultLmlParser castedParser;
*
*
*
*
* @author MJ */
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface LmlInject {
/** @return exact class of the object that should be injected. This is an optional setting that allows to keep a
* different field type than the actual injected object class. For example, you might want to keep field's
* type as an interface and inject the actual implementation. */
Class>value() default void.class;
/** Defaults to false.
*
* @return if true, a new instance will be created, filled and injected each time the view is filled. If false and
* current field value is not null, current field value will be processed and filled. */
boolean newInstance() default false;
}