# Annotations

## Basic Mapping

We start by defining two classes, our source class `SimpleEntity` and our destination class `SimpleEntityDisplay`.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntity(
    val name: String,
    val description: String,
    val privateData: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntity {
    private String name;
    private String description;
    private String privateData;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getPrivateData() {
        return privateData;
    }

    public void setPrivateData(String privateData) {
        this.privateData = privateData;
    }
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntityDisplay(
    val name: String = "",
    val description: String = ""
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntityDisplay {
    private String name = "";
    private String description = "";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
```

{% endtab %}
{% endtabs %}

We can now start adding our annotations to the `SimpleEntity` class. In this example, we want to map the `name` and `description` fields to the `name` and `description` fields of the `SimpleEntityDisplay` class, but not the `privateData` field.

To achieve this, we will use the @MappedField annotation on both of these fields. Additionally, we will define `@DefaultMappingTarget` on the `SimpleEntity` class, which will indicate that all fields annotated with `@MappedField` that do not specify a target should be mapped to the `SimpleEntityDisplay` class.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@DefaultMappingTarget(SimpleEntityDisplay::class)
data class SimpleEntity(
    @MappedField
    val name: String,
    @MappedField
    val description: String,
    val privateData: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
@DefaultMappingTarget(SimpleEntityDisplay.class)
public class SimpleEntity {
    @MappedField
    private String name;
    @MappedField
    private String description;
    private String privateData;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

### Default Mapping Target

`@DefaultMappingTarget` on a class, indicates that all fields annotated with `@MappedField` that do not specify a target should be mapped to this class by default.

## Mapping Target

The mapping target comes into play when you want to map a single source to multiple destinations. The `target` attribute is used to indicate to which class the field should be mapped. If no target is specified the target will be determined by the `@DefaultMappingTarget` on the class.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@DefaultMappingTarget(SimpleEntityDisplay::class)
data class SimpleEntity(
    @MappedField
    @MappedField(target = SimpleEntityExport::class)
    val name: String,
    @MappedField
    val description: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
@DefaultMappingTarget(SimpleEntityDisplay.class)
public class SimpleEntity {
    @MappedField
    @MappedField(target = SimpleEntityExport.class)
    private String name;
    @MappedField
    private String description;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

In the above code name is mapped once to the `SimpleEntityDisplay` class using the default mapping target, and once to the `SimpleEntityExport` class using the `target` attribute.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntityDisplay(
    val name: String = "",
    val description: String = ""
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntityDisplay {
    private String name = "";
    private String description = "";
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntityExport(
    val name: String = ""
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntityExport {
    private String name = "";
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

## Map To Field

By default each `@MappedField` is mapped to a field with the same name in the target class. To change it use the `mapTo` value. For example:

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@DefaultMappingTarget(SimpleEntityDisplay::class)
data class SimpleEntity(
    @MappedField(mapTo = "fullName")
    val name: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
@DefaultMappingTarget(SimpleEntityDisplay.class)
public class SimpleEntity {
    @MappedField(mapTo = "fullName")
    private String name;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntityDisplay(
    val fullName: String = ""
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntityDisplay {
    private String fullName = "";
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

## Map From Field

The field name to map the value from.&#x20;

### Field Level

When `mapFrom` is used at the field level, it allows for mapping of nested values.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@DefaultMappingTarget(AdvancedEntityDisplay::class)
data class AdvancedEntity(
    // This field will be mapped to the "firstChildName" field in the default target class
    @MappedField(mapFrom = "childName", mapTo = "firstChildName")
    val firstChild: AdvancedChildEntity,

    // This field will be mapped to the "secondChildName" field in the default target class
    @MappedField(mapFrom = "childName", mapTo = "secondChildName")
    val secondChild: AdvancedChildEntity
)
```

{% endtab %}

{% tab title="Java" %}

```java
@DefaultMappingTarget(AdvancedEntityDisplay.class)
public class AdvancedEntity {
    // This field will be mapped to the "firstChildName" field in the default target class
    @MappedField(mapFrom = "childName", mapTo = "firstChildName")
    private AdvancedChildEntity firstChild;

    // This field will be mapped to the "secondChildName" field in the default target class
    @MappedField(mapFrom = "childName", mapTo = "secondChildName")
    private AdvancedChildEntity secondChild;
    
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

As you can see above, we use the `mapFrom` attribute to access the `childName` field in `AdvancedChildEntity`.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class AdvancedChildEntity(
    val childName: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class AdvancedChildEntity {
    private String childName;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

And we use the `mapTo` attribute to map the values to the appropriate fields in  `AdvancedEntityDisplay.`

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class AdvancedEntityDisplay(
    val firstChildName: String = "",
    val secondChildName: String = ""
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class AdvancedEntityDisplay {
    private String firstChildName = "";
    private String secondChildName = "";
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

### Type Level

The `@MappedField` annotation can also be used at the type level. When used at the type level, the `mapFrom` attribute is required to indicate the name of the field to use, if left empty an exception will be thrown.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@MappedField(target = SimpleEntityDisplay::class, mapFrom = "firstName")
@MappedField(target = SimpleEntityDisplay::class, mapFrom = "lastName")
data class SimpleEntity(
    val firstName: String,
    val lastName: String,
)
```

{% endtab %}

{% tab title="Java" %}

```java
@MappedField(target = SimpleEntityDisplay.class, mapFrom = "firstName")
@MappedField(target = SimpleEntityDisplay.class, mapFrom = "lastName")
public class SimpleEntity {
    private String firstName;
    private String lastName;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntityDisplay(
    val firstName: String = "",
    val lastName: String = ""
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntityDisplay {
    private String firstName = "";
    private String lastName = "";
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

## Transformer

Field transformers are a way to transform a field from one type to another when mapping it to a destination class. More about the ins-and-outs of transformers is available here:

{% content-ref url="/pages/PORlxG7l4elFH65ncAPT" %}
[Transformers](/features/transformers.md)
{% endcontent-ref %}

To configure a transformer for a field use the `transformer` attribute. The `transformer` attribute receives the transformer's class.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@DefaultMappingTarget(SimpleEntityDisplay::class)
data class SimpleEntity(
    @MappedField(transformer = StringToListMappingTransformer::class, mapTo = "stringList")
    val commaDelimitedString: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
@DefaultMappingTarget(SimpleEntityDisplay.class)
public class SimpleEntity {
    @MappedField(transformer = StringToListMappingTransformer.class, mapTo = "stringList")
    private String commaDelimitedString;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntityDisplay(
    val stringList: List<String> = emptyList()
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntityDisplay {
    private List<String> stringList = new ArrayList<>();
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Transformers must be registered to the `ShapeShift` instance in order to be used. More info about registering transformers is available in the [transformers page](/features/transformers.md#registering-transformers).
{% endhint %}

{% content-ref url="/pages/PORlxG7l4elFH65ncAPT" %}
[Transformers](/features/transformers.md)
{% endcontent-ref %}

## Auto Mapping

Auto mapping is used to reduce the amount of boiler-place code required to configure mapping between two classes. More info about auto mapping is available here:

{% content-ref url="/pages/Hdz67wjrvmcwYJuGHOjL" %}
[Auto Mapping](/features/auto-mapping.md)
{% endcontent-ref %}

Auto mapping can be added using the `@AutoMapping` annotation.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@AutoMapping(SimpleEntityDisplay::class, strategy = AutoMappingStrategy.BY_NAME)
@DefaultMappingTarget(SimpleEntityDisplay::class)
data class SimpleEntity(
    val id: String,
    val name: String,
    val birthDate: Date,
    val email: String,
    val telephone: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
@AutoMapping(target = SimpleEntityDisplay.class, strategy = AutoMappingStrategy.BY_NAME)
@DefaultMappingTarget(SimpleEntityDisplay.class)
public class SimpleEntity {
    private String id;
    private String name;
    private Date birthDate;
    private String email;
    private String telephone;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

The `@AutoMapping` annotation has two attributes:

1. `target` - If no target is added then the auto mapping will be configured to any target class. It is possible to add multiple `@AutoMapping` annotation for multiple target classes.
2. `strategy` - The [auto mapping strategy](/features/auto-mapping.md#auto-mapping-strategy). Default value `NONE`.

## Mapping Condition

Conditions are used to determine wether a field should be mapped according to certain logic. More info about conditions is available here:

{% content-ref url="/pages/wjmGCYTgvi7GKMu2iTUj" %}
[Conditions](/features/conditions.md)
{% endcontent-ref %}

A condition can be added to annotation mapping using the `condition` attribute.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@DefaultMappingTarget(SimpleEntityDisplay::class)
data class SimpleEntity(
    @MappedField(condition = NotBlankStringCondition::class)
    val name: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
@DefaultMappingTarget(SimpleEntityDisplay.class)
public class SimpleEntity {
    @MappedField(condition = NotBlankStringCondition.class)
    private String name;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

We mapped the name field and added a condition for the mapping.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntityDisplay(
    val name: String = ""
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntityDisplay {
    private String name = "";
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

The condition receives context with the original value of the field and checks that it is not null or blank.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
class NotBlankStringCondition : MappingCondition<String> {
    override fun isValid(context: MappingConditionContext<String>): Boolean {
        return !context.originalValue.isNullOrBlank()
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
public class NotBlankStringCondition implements MappingCondition<String> {
    @Override
    public boolean isValid(@NonNull MappingConditionContext<String> context) {
        return context.getOriginalValue() != null && !context.getOriginalValue().trim().isEmpty();
    }
}
```

{% endtab %}
{% endtabs %}

## Override Mapping Strategy

The `overrideMappingStrategy` attribute allows you to override the default mapping strategy configured on the `ShapeShift` instance.&#x20;

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@DefaultMappingTarget(SimpleEntityDisplay::class)
data class SimpleEntity(
    @MappedField(overrideMappingStrategy = MappingStrategy.MAP_ALL)
    val name: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
@DefaultMappingTarget(SimpleEntityDisplay.class)
public class SimpleEntity {
    @MappedField(overrideMappingStrategy = MappingStrategy.MAP_ALL)
    private String name;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

More info about mapping strategy is available here:

{% content-ref url="/pages/hLLVGHqU7X5FWCz5eewp" %}
[Mapping Strategy](/features/mapping-strategy.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://shapeshift.krud.dev/api-documentation/annotations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
