Package com.blackbuild.klum.ast.layer3
Annotation Interface LinkTo
@Target({FIELD,TYPE})
@Retention(RUNTIME)
@WriteAccess(LIFECYCLE)
@MutuallyExclusive({"provider","providerType"}) @MutuallyExclusive({"field","fieldId","selector"})
@Inherited
@Documented
public @interface LinkTo
Provides mechanisms to automatically fill a field with an existing object from somewhere else in the model tree.
Example
Consider an environment model where you define different, interdependent services. Service 'provider' defines multiple users for various tasks, one being the one used by consumer. So we want the consumer object to use the same User object as the provider. This might look like this:
@DSL abstract class Service {
@Owner Environment env
}
@DSL class Producer extends Service {
User admin
User internal
User monitoring
}
@DSL class Consumer extends Service {
@LinkTo(provider={env.services.consumer}) User internal
}
The LinkTo annotation on the internal field of the Consumer class will cause the internal field to be filled with the
same User object as the internal field of the Producer class.
Usage
LinkTo is handled in the AutoLink phase, i.e. after owners have been set and auto-create objects have been created. It will work on any annotated field that is not yet set.provider
The link mechanism is centered around the provider object, i.e. the object that contains the field to be linked. This is determined the following way:- provider: contains a code closure that is run relative to the annotated field's instance to access the owner (like in the example)
- providerType: contains a type of owner. Finds the first element of the given type in the owner hierarchy
- otherwise, the single owner field of the annotated field's class is used
Map provider
If the provider is a map, the field name is used as the key to access the provider. If the key does not exist, the link is not set.Target field
Once the provider is determined, the field of the provider to be used as the provider of the link is resolved. This is done the following way:- If the field member is set, the field with the given name is used
- if the fieldId member is set, the field with the matching LinkSource annotation is taken
- if the selector member is set, the field of the provider is determined by the value of the selector field of the annotated field's instance
- It is illegal to have more than one of field, fieldId and selector set together
- if neither field, fieldId nor selector is set, the field with the same name as the annotated field is used
- if no field with the given name exists and exactly one field not annotated with LinkSource and of the correct type exists, that one is used
- if no matching field is found, an exception is thrown
-
Nested Class Summary
Nested Classes -
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescriptionThe field of the target owner object to be used as the target for the link.If set use the field of the owner with a matching LinkSource annotation with the same id.If set, is added to automatically determined names (i.e.The owner of the link.Class<?>If set, the owner is determined by walking the owner hierarchy up until the given type is found.If set, the field of the provider is determined by the given selector.If set, determines the strategy to determine which field of the provider is to be used as the link source.
-
Element Details
-
field
String fieldThe field of the target owner object to be used as the target for the link.- Default:
- ""
-
fieldId
String fieldIdIf set use the field of the owner with a matching LinkSource annotation with the same id. Only one of field and targetId can be used at most.- Default:
- ""
-
selector
String selectorIf set, the field of the provider is determined by the given selector. The selector is the name of a field of the receiver. If the selector field is empty or null, the link is not set.- Default:
- ""
-
provider
The owner of the link. By default, the owner of the annotated field's instance is used.- Default:
- com.blackbuild.klum.ast.NoClosure.class
-
providerType
Class<?> providerTypeIf set, the owner is determined by walking the owner hierarchy up until the given type is found.- Default:
- java.lang.Object.class
-
strategy
LinkTo.Strategy strategyIf set, determines the strategy to determine which field of the provider is to be used as the link source. FIELD_NAME: use the field with the same name as the annotated field, i.e. if the annotated field is called 'admin', the field 'admin' of the provider is used. OWNER_PATH: use the field with the same name as the instance name of the annotated field's owner, i.e. the name of the field of the annotated field's classes owner pointing to the instance of the annotated field's container. Can only be set together with one of provider or providerType.- Default:
- AUTO
-
nameSuffix
String nameSuffixIf set, is added to automatically determined names (i.e. FIELD_NAME or OWNER_PATH).- Default:
- ""
-