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

com.stratio.cassandra.lucene.schema.mapping.SingleColumnMapper Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2014 Stratio (http://stratio.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.stratio.cassandra.lucene.schema.mapping;

import com.google.common.base.MoreObjects;
import com.stratio.cassandra.lucene.IndexException;
import com.stratio.cassandra.lucene.column.Column;
import com.stratio.cassandra.lucene.column.Columns;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexableField;

import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * Class for mapping between Cassandra's columns and Lucene documents.
 *
 * @param  The base type.
 * @author Andres de la Pena {@literal }
 */
public abstract class SingleColumnMapper> extends Mapper {

    /** The name of the mapped column. */
    public final String column;

    /** The Lucene type for this mapper. */
    public final Class base;

    /**
     * Builds a new {@link SingleColumnMapper} supporting the specified types for indexing and clustering.
     *
     * @param field the name of the field
     * @param column the name of the column to be mapped
     * @param docValues if the mapper supports doc values
     * @param validated if the field must be validated
     * @param analyzer the name of the analyzer to be used
     * @param base the Lucene type for this mapper
     * @param supportedTypes the supported column value data types
     */
    public SingleColumnMapper(String field,
                              String column,
                              Boolean docValues,
                              Boolean validated,
                              String analyzer,
                              Class base,
                              List> supportedTypes) {
        this(field, column, docValues, validated, analyzer, base, supportedTypes, EMPTY_TYPE_LIST);
    }
    /**
     * Builds a new {@link SingleColumnMapper} supporting the specified types for indexing and clustering.
     *
     * @param field the name of the field
     * @param column the name of the column to be mapped
     * @param docValues if the mapper supports doc values
     * @param validated if the field must be validated
     * @param analyzer the name of the analyzer to be used
     * @param base the Lucene type for this mapper
     * @param supportedTypes the supported column value data types
     * @param excludedTypes the explicitly excluded value data types
     */
    public SingleColumnMapper(String field,
                              String column,
                              Boolean docValues,
                              Boolean validated,
                              String analyzer,
                              Class base,
                              List> supportedTypes,
                              List> excludedTypes) {
        super(field,
              docValues,
              validated,
              analyzer,
              Collections.singletonList(column == null ? field : column),
              supportedTypes,
              excludedTypes,
              true);

        if (StringUtils.isWhitespace(column)) {
            throw new IndexException("Column must not be whitespace, but found '{}'", column);
        }

        this.column = column == null ? field : column;
        this.base = base;
    }

    /** {@inheritDoc} */
    @Override
    public List bestEffortIndexableFields(Columns columns) {
        List fields = new LinkedList<>();
        columns.foreachWithMapper(column, c -> fields.addAll(bestEffort(c, this::indexableFields)));
        return fields;
    }

    /** {@inheritDoc} */
    @Override
    public List indexableFields(Columns columns) {
        List fields = new LinkedList<>();
        columns.foreachWithMapper(column, c -> fields.addAll(indexableFields(c)));
        return fields;
    }

    private List indexableFields(Column c) {
        String name = column.equals(field) ? c.field() : c.fieldName(field);
        Object value = c.valueOrNull();
        if (value != null) {
            T base = base(c);
            return indexableFields(name, base);
        }
        return Collections.emptyList();
    }

    /**
     * Returns the {@link Field} to search for the mapped column.
     *
     * @param name the name of the column
     * @param value the value of the column
     * @return a list of indexable fields
     */
    public abstract List indexableFields(String name, T value);

    /**
     * Returns the {@link Column} query value resulting from the mapping of the specified object.
     *
     * @param field the field name
     * @param value the object to be mapped, never is {@code null}
     * @return the {@link Column} index value resulting from the mapping of the specified object
     */
    public final T base(String field, Object value) {
        return value == null ? null : doBase(field, value);
    }

    /**
     * Returns the {@link Column} query value resulting from the mapping of the specified object.
     *
     * @param column the column
     * @return the {@link Column} index value resulting from the mapping of the specified object
     */
    public final T base(Column column) {
        return column == null ? null : column.valueOrNull() == null ? null : doBase(column);
    }

    protected abstract T doBase(@NotNull String field, @NotNull Object value);

    protected final T doBase(Column column) {
        return doBase(column.fieldName(field), column.valueOrNull());
    }

    /** {@inheritDoc} */
    @Override
    protected MoreObjects.ToStringHelper toStringHelper(Object self) {
        return super.toStringHelper(self).add("column", column);
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return toStringHelper(this).toString();
    }

    /**
     * {@link SingleColumnMapper} that produces just a single field.
     *
     * @param  the base type
     */
    public abstract static class SingleFieldMapper> extends SingleColumnMapper {

        /**
         * Builds a new {@link SingleFieldMapper} supporting the specified types for indexing and clustering.
         *
         * @param field the name of the field
         * @param column the name of the column to be mapped
         * @param docValues if the mapper supports doc values
         * @param validated if the field must be validated
         * @param analyzer the name of the analyzer to be used
         * @param base the Lucene type for this mapper
         * @param supportedTypes the supported column value data types
         */
        public SingleFieldMapper(String field,
                                 String column,
                                 Boolean docValues,
                                 Boolean validated,
                                 String analyzer,
                                 Class base,
                                 List> supportedTypes) {
            super(field, column, docValues, validated, analyzer, base, supportedTypes);
        }

        /** {@inheritDoc} */
        @Override
        public List indexableFields(String name, T value) {
            List fields = new ArrayList<>(2);
            indexedField(name, value).ifPresent(fields::add);
            sortedField(name, value).ifPresent(fields::add);
            return fields;
        }

        /**
         * Returns the {@link Field} to index by the mapped column.
         *
         * @param name the name of the column
         * @param value the value of the column
         * @return the field to sort by the mapped column
         */
        public abstract Optional indexedField(String name, T value);

        /**
         * Returns the {@link Field} to sort by the mapped column.
         *
         * @param name the name of the column
         * @param value the value of the column
         * @return the field to sort by the mapped column
         */
        public abstract Optional sortedField(String name, T value);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy