com.torodb.backend.AbstractIdentifierConstraints.java Source code

Java tutorial

Introduction

Here is the source code for com.torodb.backend.AbstractIdentifierConstraints.java

Source

/*
 * ToroDB
 * Copyright  2014 8Kdata Technology (www.8kdata.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package com.torodb.backend;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.torodb.backend.meta.TorodbSchema;
import com.torodb.backend.tables.MetaDocPartTable.DocPartTableFields;
import com.torodb.core.backend.IdentifierConstraints;
import com.torodb.core.exceptions.SystemException;
import com.torodb.core.transaction.metainf.FieldType;

import java.util.HashSet;
import java.util.Set;

import javax.annotation.Nonnull;
import javax.inject.Singleton;

@Singleton
public abstract class AbstractIdentifierConstraints implements IdentifierConstraints {

    private static final char SEPARATOR = '_';
    private static final char ARRAY_DIMENSION_SEPARATOR = '$';

    private final ImmutableMap<FieldType, Character> fieldTypeIdentifiers;
    private final ImmutableMap<FieldType, String> scalarFieldTypeIdentifiers;
    private final ImmutableSet<String> restrictedSchemaNames;
    private final ImmutableSet<String> restrictedColumnNames;

    protected AbstractIdentifierConstraints(ImmutableSet<String> restrictedSchemaNames,
            ImmutableSet<String> restrictedColumnNames) {
        this.fieldTypeIdentifiers = Maps
                .immutableEnumMap(ImmutableMap.<FieldType, Character>builder().put(FieldType.BINARY, 'r') // [r]aw bytes
                        .put(FieldType.BOOLEAN, 'b') // [b]oolean
                        .put(FieldType.DOUBLE, 'd') // [d]ouble float
                        .put(FieldType.INSTANT, 't') // [t]imestamp
                        .put(FieldType.INTEGER, 'i') // [i]nteger
                        .put(FieldType.LONG, 'l') // [l]ong
                        .put(FieldType.DECIMAL128, 'q') // [q]uad float
                        .put(FieldType.NULL, 'n') // [n]ull
                        .put(FieldType.STRING, 's') // [s]tring
                        .put(FieldType.CHILD, 'e') // child [e]lement

                        // Mongo types
                        .put(FieldType.MONGO_OBJECT_ID, 'x').put(FieldType.MONGO_TIME_STAMP, 'y')
                        // No-Mongo types
                        .put(FieldType.DATE, 'c') // [c]alendar
                        .put(FieldType.TIME, 'm') // ti[m]e
                        .put(FieldType.JAVASCRIPT, 'j') // [j]avascript
                        .put(FieldType.JAVASCRIPT_WITH_SCOPE, 'w') // javascript [w]ith scope
                        .put(FieldType.MIN_KEY, 'k') //min [k]ey
                        .put(FieldType.MAX_KEY, 'a') //m[a]x key
                        .put(FieldType.UNDEFINED, 'u') //[u]ndefined
                        .put(FieldType.MONGO_REGEX, 'g') //Re[g]Ex
                        .put(FieldType.MONGO_DB_POINTER, 'p') //DB [p]ointer
                        .put(FieldType.DEPRECATED, 'z') //running out of available chars; z means "the last".
                        .build());
        //Letters left: f h o v
        ImmutableMap.Builder<FieldType, String> scalarFieldTypeIdentifiersBuilder = ImmutableMap
                .<FieldType, String>builder();
        Set<Character> fieldTypeIdentifierSet = new HashSet<>();
        for (FieldType fieldType : FieldType.values()) {
            if (!this.fieldTypeIdentifiers.containsKey(fieldType)) {
                throw new SystemException("FieldType " + fieldType + " has not been mapped to an identifier.");
            }

            char identifier = this.fieldTypeIdentifiers.get(fieldType);

            if ((identifier < 'a' || identifier > 'z') && (identifier < '0' || identifier > '9')) {
                throw new SystemException("FieldType " + fieldType + " has an unallowed identifier " + identifier);
            }

            if (fieldTypeIdentifierSet.contains(identifier)) {
                throw new SystemException(
                        "FieldType " + fieldType + " identifier " + identifier + " was used by another FieldType.");
            }

            fieldTypeIdentifierSet.add(identifier);

            scalarFieldTypeIdentifiersBuilder.put(fieldType,
                    DocPartTableFields.SCALAR.fieldName + SEPARATOR + identifier);
        }

        this.scalarFieldTypeIdentifiers = Maps.immutableEnumMap(scalarFieldTypeIdentifiersBuilder.build());

        this.restrictedSchemaNames = ImmutableSet.<String>builder().add(TorodbSchema.IDENTIFIER)
                .addAll(restrictedSchemaNames).build();

        this.restrictedColumnNames = ImmutableSet.<String>builder().add(DocPartTableFields.DID.fieldName)
                .add(DocPartTableFields.RID.fieldName).add(DocPartTableFields.PID.fieldName)
                .add(DocPartTableFields.SEQ.fieldName).addAll(scalarFieldTypeIdentifiers.values())
                .addAll(restrictedColumnNames).build();
    }

    @Override
    public char getSeparator() {
        return SEPARATOR;
    }

    @Override
    public char getArrayDimensionSeparator() {
        return ARRAY_DIMENSION_SEPARATOR;
    }

    @Override
    public boolean isAllowedSchemaIdentifier(@Nonnull String schemaName) {
        return !restrictedSchemaNames.contains(schemaName);
    }

    @Override
    public boolean isAllowedTableIdentifier(@Nonnull String columnName) {
        return true;
    }

    @Override
    public boolean isAllowedColumnIdentifier(@Nonnull String columnName) {
        return !restrictedColumnNames.contains(columnName);
    }

    @Override
    public boolean isAllowedIndexIdentifier(@Nonnull String indexName) {
        return true;
    }

    @Override
    public boolean isSameIdentifier(@Nonnull String leftIdentifier, @Nonnull String rightIdentifier) {
        return leftIdentifier.equals(rightIdentifier);
        //leftIdentifier.toLowerCase(Locale.US).equals(rightIdentifier.toLowerCase(Locale.US));
    }

    @Override
    public char getFieldTypeIdentifier(FieldType fieldType) {
        return fieldTypeIdentifiers.get(fieldType);
    }

    @Override
    public String getScalarIdentifier(FieldType fieldType) {
        return scalarFieldTypeIdentifiers.get(fieldType);
    }
}