// Path: olastic-core/src/main/java/com/hevelian/olastic/core/api/edm/annotations/AnnotationProvider.java
// public class AnnotationProvider {
//     /** Analyzed term name. */
//     public static final String ANALYZED_TERM_NAME = "Analyzed";
// 
//     private HashMap<String, TermAnnotation> annotations = new HashMap<>();
// 
//     // declaring terms and annotations
//     private CsdlAnnotation analyzedAnnotation = new CsdlAnnotation().setTerm("OData.Analyzed")
//             .setExpression(new CsdlConstantExpression(
//                     CsdlConstantExpression.ConstantExpressionType.Bool, "true"));
// 
//     private CsdlTerm analyzedTerm = new CsdlTerm().setAppliesTo(Arrays.asList("Property"))
//             .setName(ANALYZED_TERM_NAME).setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()
//                     .getFullQualifiedNameAsString());
// 
//     /**
//      * Default constructor. Sets default annotation.
//      */
//     public AnnotationProvider() {
//         annotations.put(ANALYZED_TERM_NAME, new TermAnnotation(analyzedTerm, analyzedAnnotation));
//     }
// 
//     /**
//      * Gets annotation by term name.
//      * 
//      * @param termName
//      *            term name
//      * @return found annotation, otherwise null
//      */
//     public CsdlAnnotation getAnnotation(String termName) {
//         TermAnnotation temAnnotation = annotations.get(termName);
//         if (temAnnotation != null) {
//             return annotations.get(termName).annotation;
//         } else {
//             return null;
//         }
//     }
// 
//     /**
//      * Gets term by term name.
//      * 
//      * @param termName
//      *            term name
//      * @return found term, otherwise null
//      */
//     public CsdlTerm getTerm(String termName) {
//         TermAnnotation temAnnotation = annotations.get(termName);
//         if (temAnnotation != null) {
//             return annotations.get(termName).term;
//         } else {
//             return null;
//         }
//     }
// 
//     public List<CsdlTerm> getTerms() {
//         return annotations.entrySet().stream().map(entry -> entry.getValue().term)
//                 .collect(Collectors.toList());
//     }
// 
//     /**
//      * Class represents container for term and annotation.
//      */
//     private class TermAnnotation {
//         private CsdlAnnotation annotation;
//         private CsdlTerm term;
// 
//         TermAnnotation(CsdlTerm term, CsdlAnnotation annotation) {
//             this.term = term;
//             this.annotation = annotation;
//         }
//     }
// }
// 
// Path: olastic-core/src/main/java/com/hevelian/olastic/core/elastic/ElasticConstants.java
// public final class ElasticConstants {
// 
//     /** Field data type property. */
//     public static final String FIELD_DATATYPE_PROPERTY = "type";
//     /** Properties property name. */
//     public static final String PROPERTIES_PROPERTY = "properties";
//     /** Parent property name. */
//     public static final String PARENT_PROPERTY = "_parent";
//     /** ID field name. */
//     public static final String ID_FIELD_NAME = "_id";
//     /** Suffix for keyword (not-analyzed) field. */
//     public static final String KEYWORD_SUFFIX = "keyword";
//     /** Field suffix delimiter. */
//     public static final String SUFFIX_DELIMITER = ".";
//     /** Nested path separator. */
//     public static final String NESTED_PATH_SEPARATOR = ".";
//     /** Wildcard character. */
//     public static final String WILDCARD_CHAR = "*";
//     /**
//      * The _all field is a special catch-all field which concatenates the values
//      * of all of the other fields into one big string.
//      */
//     public static final String ALL_FIELD = "_all";
// 
//     private ElasticConstants() {
//     }
// }


import com.hevelian.olastic.core.api.edm.annotations.AnnotationProvider;
import com.hevelian.olastic.core.elastic.ElasticConstants;
import org.apache.olingo.commons.api.edm.EdmAnnotation;
import java.util.List;
import java.util.Optional;

package com.hevelian.olastic.core.elastic.utils;



/**
 * Elasticsearch utils.
 */
public final class ElasticUtils {

    private ElasticUtils() {
    }

    /**
     * Returns keyword field name if needed. Keyword field is non analyzed
     * field.
     *
     * @param name
     *            field name
     * @param annotations
     *            field edm type
     * @return property's keyword field name
     */
    public static String addKeywordIfNeeded(String name, List<EdmAnnotation> annotations) {
        boolean isAnalyzed = false;
        Optional<EdmAnnotation> analyzedAnnotation = annotations.stream()
                .filter(annotation -> annotation.getTerm().getName()
                        .equals(AnnotationProvider.ANALYZED_TERM_NAME))
                .findFirst();
        if (analyzedAnnotation.isPresent()) {
            isAnalyzed = (Boolean) (analyzedAnnotation.get().getExpression().asConstant()
                    .asPrimitive());
        }
        return isAnalyzed ? addKeyword(name) : name;
    }

    /**
     * Returns keyword field name. Keyword field is non analyzed field.
     *
     * @param fieldName
     *            name of the field
     * @return property's keyword field name
     */
    public static String addKeyword(String fieldName) {

// Path: olastic-core/src/main/java/com/hevelian/olastic/core/api/edm/annotations/AnnotationProvider.java
// public class AnnotationProvider {
//     /** Analyzed term name. */
//     public static final String ANALYZED_TERM_NAME = "Analyzed";
// 
//     private HashMap<String, TermAnnotation> annotations = new HashMap<>();
// 
//     // declaring terms and annotations
//     private CsdlAnnotation analyzedAnnotation = new CsdlAnnotation().setTerm("OData.Analyzed")
//             .setExpression(new CsdlConstantExpression(
//                     CsdlConstantExpression.ConstantExpressionType.Bool, "true"));
// 
//     private CsdlTerm analyzedTerm = new CsdlTerm().setAppliesTo(Arrays.asList("Property"))
//             .setName(ANALYZED_TERM_NAME).setType(EdmPrimitiveTypeKind.String.getFullQualifiedName()
//                     .getFullQualifiedNameAsString());
// 
//     /**
//      * Default constructor. Sets default annotation.
//      */
//     public AnnotationProvider() {
//         annotations.put(ANALYZED_TERM_NAME, new TermAnnotation(analyzedTerm, analyzedAnnotation));
//     }
// 
//     /**
//      * Gets annotation by term name.
//      * 
//      * @param termName
//      *            term name
//      * @return found annotation, otherwise null
//      */
//     public CsdlAnnotation getAnnotation(String termName) {
//         TermAnnotation temAnnotation = annotations.get(termName);
//         if (temAnnotation != null) {
//             return annotations.get(termName).annotation;
//         } else {
//             return null;
//         }
//     }
// 
//     /**
//      * Gets term by term name.
//      * 
//      * @param termName
//      *            term name
//      * @return found term, otherwise null
//      */
//     public CsdlTerm getTerm(String termName) {
//         TermAnnotation temAnnotation = annotations.get(termName);
//         if (temAnnotation != null) {
//             return annotations.get(termName).term;
//         } else {
//             return null;
//         }
//     }
// 
//     public List<CsdlTerm> getTerms() {
//         return annotations.entrySet().stream().map(entry -> entry.getValue().term)
//                 .collect(Collectors.toList());
//     }
// 
//     /**
//      * Class represents container for term and annotation.
//      */
//     private class TermAnnotation {
//         private CsdlAnnotation annotation;
//         private CsdlTerm term;
// 
//         TermAnnotation(CsdlTerm term, CsdlAnnotation annotation) {
//             this.term = term;
//             this.annotation = annotation;
//         }
//     }
// }
// 
// Path: olastic-core/src/main/java/com/hevelian/olastic/core/elastic/ElasticConstants.java
// public final class ElasticConstants {
// 
//     /** Field data type property. */
//     public static final String FIELD_DATATYPE_PROPERTY = "type";
//     /** Properties property name. */
//     public static final String PROPERTIES_PROPERTY = "properties";
//     /** Parent property name. */
//     public static final String PARENT_PROPERTY = "_parent";
//     /** ID field name. */
//     public static final String ID_FIELD_NAME = "_id";
//     /** Suffix for keyword (not-analyzed) field. */
//     public static final String KEYWORD_SUFFIX = "keyword";
//     /** Field suffix delimiter. */
//     public static final String SUFFIX_DELIMITER = ".";
//     /** Nested path separator. */
//     public static final String NESTED_PATH_SEPARATOR = ".";
//     /** Wildcard character. */
//     public static final String WILDCARD_CHAR = "*";
//     /**
//      * The _all field is a special catch-all field which concatenates the values
//      * of all of the other fields into one big string.
//      */
//     public static final String ALL_FIELD = "_all";
// 
//     private ElasticConstants() {
//     }
// }


// Path: olastic-core/src/main/java/com/hevelian/olastic/core/elastic/utils/ElasticUtils.java
import com.hevelian.olastic.core.api.edm.annotations.AnnotationProvider;
import com.hevelian.olastic.core.elastic.ElasticConstants;
import org.apache.olingo.commons.api.edm.EdmAnnotation;
import java.util.List;
import java.util.Optional;

package com.hevelian.olastic.core.elastic.utils;



/**
 * Elasticsearch utils.
 */
public final class ElasticUtils {

    private ElasticUtils() {
    }

    /**
     * Returns keyword field name if needed. Keyword field is non analyzed
     * field.
     *
     * @param name
     *            field name
     * @param annotations
     *            field edm type
     * @return property's keyword field name
     */
    public static String addKeywordIfNeeded(String name, List<EdmAnnotation> annotations) {
        boolean isAnalyzed = false;
        Optional<EdmAnnotation> analyzedAnnotation = annotations.stream()
                .filter(annotation -> annotation.getTerm().getName()
                        .equals(AnnotationProvider.ANALYZED_TERM_NAME))
                .findFirst();
        if (analyzedAnnotation.isPresent()) {
            isAnalyzed = (Boolean) (analyzedAnnotation.get().getExpression().asConstant()
                    .asPrimitive());
        }
        return isAnalyzed ? addKeyword(name) : name;
    }

    /**
     * Returns keyword field name. Keyword field is non analyzed field.
     *
     * @param fieldName
     *            name of the field
     * @return property's keyword field name
     */
    public static String addKeyword(String fieldName) {

        return fieldName + ElasticConstants.SUFFIX_DELIMITER + ElasticConstants.KEYWORD_SUFFIX;
