All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dynodao.processor.schema.index.TableIndexParser Maven / Gradle / Ivy

package com.github.dynodao.processor.schema.index;

import com.github.dynodao.annotation.DynoDaoHashKey;
import com.github.dynodao.annotation.DynoDaoRangeKey;
import com.github.dynodao.annotation.DynoDaoSchema;
import com.github.dynodao.processor.context.ProcessorMessager;
import com.github.dynodao.processor.schema.attribute.DocumentDynamoAttribute;
import com.github.dynodao.processor.schema.attribute.DynamoAttribute;

import javax.inject.Inject;
import java.util.LinkedHashSet;
import java.util.Set;

import static java.util.Collections.singleton;

/**
 * Extracts the overall table "index" from the schema document.
 */
class TableIndexParser implements DynamoIndexParser {

    private final ProcessorMessager processorMessager;

    @Inject TableIndexParser(ProcessorMessager processorMessager) {
        this.processorMessager = processorMessager;
    }

    @Override
    public Set getIndexesFrom(DocumentDynamoAttribute document) {
        Set hashKeys = new LinkedHashSet<>();
        Set rangeKeys = new LinkedHashSet<>();
        Set attributes = new LinkedHashSet<>();

        for (DynamoAttribute attribute : document.getAttributes()) {
            if (attribute.getElement().getAnnotation(DynoDaoHashKey.class) != null) {
                hashKeys.add(attribute);
            }
            if (attribute.getElement().getAnnotation(DynoDaoRangeKey.class) != null) {
                rangeKeys.add(attribute);
            }
            attributes.add(attribute);
        }

        validate(document, hashKeys, rangeKeys);

        return singleton(toIndex(hashKeys, rangeKeys, attributes));
    }

    /**
     * TODO validate scalar hash and range keys
     */
    private void validate(DocumentDynamoAttribute document, Set hashKeys, Set rangeKeys) {
        if (hashKeys.size() != 1) {
            if (hashKeys.isEmpty()) {
                processorMessager.submitError("@%s must exist on exactly one scalar attribute, but none found.", DynoDaoHashKey.class.getSimpleName())
                        .atElement(document.getElement())
                        .atAnnotation(DynoDaoSchema.class);
            }
            hashKeys.forEach(hashKey -> processorMessager.submitError("@%s must exist on exactly one attribute.", DynoDaoHashKey.class.getSimpleName())
                    .atElement(hashKey.getElement())
                    .atAnnotation(DynoDaoHashKey.class));
        }
        if (rangeKeys.size() > 1) {
            processorMessager.submitError("@%s must exist on at most one attribute, but found %s", DynoDaoRangeKey.class.getSimpleName(), rangeKeys);
        }
    }

    private DynamoIndex toIndex(Set hashKeys, Set rangeKeys, Set attributes) {
        return DynamoIndex.builder()
                .indexType(IndexType.TABLE)
                .name("")
                .hashKey(hashKeys.iterator().next())
                .rangeKey(rangeKeys.stream().findAny())
                .projectedAttributes(attributes)
                .build();
    }

}