content: package org.alien4cloud.tosca.model.templates;
  
  import java.util.List;
  import java.util.Map;
  
  import org.alien4cloud.tosca.model.definitions.AbstractPropertyValue;
  import org.elasticsearch.annotation.NestedObject;
  import org.elasticsearch.annotation.ObjectField;
  import org.elasticsearch.annotation.StringField;
  import org.elasticsearch.annotation.query.TermFilter;
  import org.elasticsearch.mapping.IndexType;
  
  import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
  import com.fasterxml.jackson.databind.annotation.JsonSerialize;
  
  import alien4cloud.json.deserializer.PropertyValueDeserializer;
  import alien4cloud.model.common.Tag;
  import alien4cloud.utils.jackson.ConditionalAttributes;
  import alien4cloud.utils.jackson.ConditionalOnAttribute;
  import alien4cloud.utils.jackson.JSonMapEntryArrayDeSerializer;
  import alien4cloud.utils.jackson.JSonMapEntryArraySerializer;
  import lombok.AllArgsConstructor;
  import lombok.Getter;
  import lombok.NoArgsConstructor;
  import lombok.Setter;
  
  /**
   * Abstract template is parent of both instantiable templates as nodes, relationships and groups as well as other templates as policies.
   */
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public abstract class AbstractTemplate {
      /** Name of the template. Same value as it's key in the map. */
      @StringField(indexType = IndexType.no, includeInAll = false)
      private String name;
  
      /**
       * The QName value of this attribute refers to the Node Type providing the type of the Node Template.
       *
       * Note: If the Node Type referenced by the type attribute of a Node Template is declared as abstract, no instances of the specific Node Template can be
       * created. Instead, a substitution of the Node Template with one having a specialized, derived Node Type has to be done at the latest during the
       * instantiation time of the Node Template.
       */
      @TermFilter
      @StringField(indexType = IndexType.not_analyzed, includeInAll = false)
      private String type;
  
      @StringField(indexType = IndexType.no, includeInAll = false)
      private String description;
  
      /* Tosca metadata */
      @NestedObject(nestedClass = Tag.class)
      private List<Tag> tags;
  
      /** Properties of the template. */
      @ObjectField(enabled = false)
      @ConditionalOnAttribute(ConditionalAttributes.REST)
      @JsonDeserialize(using = JSonMapEntryArrayDeSerializer.class, contentUsing = PropertyValueDeserializer.class)
      @JsonSerialize(using = JSonMapEntryArraySerializer.class)
      private Map<String, AbstractPropertyValue> properties;
  }
  