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

org.apache.jackrabbit.oak.api.Type Maven / Gradle / Ivy

There is a newer version: 1.64.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.jackrabbit.oak.api;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nonnull;
import javax.jcr.PropertyType;

/**
 * Instances of this class map Java types to {@link PropertyType property types}.
 * Passing an instance of this class to {@link PropertyState#getValue(Type)} determines
 * the return type of that method.
 * @param 
 */
public final class Type implements Comparable> {

    private static final Map> TYPES = new HashMap>();

    private static  Type create(int tag, boolean array, String string) {
        Type type = new Type(tag, array, string);
        TYPES.put(string, type);
        return type;
    }

    /** Map {@code String} to {@link PropertyType#STRING} */
    public static final Type STRING =
            create(PropertyType.STRING, false, "STRING");

    /** Map {@code Blob} to {@link PropertyType#BINARY} */
    public static final Type BINARY =
            create(PropertyType.BINARY, false, "BINARY");

    /** Map {@code Long} to {@link PropertyType#LONG} */
    public static final Type LONG =
            create(PropertyType.LONG, false, "LONG");

    /** Map {@code Double} to {@link PropertyType#DOUBLE} */
    public static final Type DOUBLE =
            create(PropertyType.DOUBLE, false, "DOUBLE");

    /** Map {@code String} to {@link PropertyType#DATE} */
    public static final Type DATE =
            create(PropertyType.DATE, false, "DATE");

    /** Map {@code Boolean} to {@link PropertyType#BOOLEAN} */
    public static final Type BOOLEAN =
            create(PropertyType.BOOLEAN, false, "BOOLEAN");

    /** Map {@code String} to {@link PropertyType#STRING} */
    public static final Type NAME =
            create(PropertyType.NAME, false, "NAME");

    /** Map {@code String} to {@link PropertyType#PATH} */
    public static final Type PATH =
            create(PropertyType.PATH, false, "PATH");

    /** Map {@code String} to {@link PropertyType#REFERENCE} */
    public static final Type REFERENCE =
            create(PropertyType.REFERENCE, false, "REFERENCE");

    /** Map {@code String} to {@link PropertyType#WEAKREFERENCE} */
    public static final Type WEAKREFERENCE =
            create(PropertyType.WEAKREFERENCE, false, "WEAKREFERENCE");

    /** Map {@code String} to {@link PropertyType#URI} */
    public static final Type URI =
            create(PropertyType.URI, false, "URI");

    /** Map {@code BigDecimal} to {@link PropertyType#DECIMAL} */
    public static final Type DECIMAL =
            create(PropertyType.DECIMAL, false, "DECIMAL");

    /** Map {@code Iterable} to array of {@link PropertyType#STRING} */
    public static final Type> STRINGS =
            create(PropertyType.STRING, true, "STRINGS");

    /** Map {@code Iterable} to array of {@link PropertyType#BINARY} */
    public static final Type> BINARIES =
            create(PropertyType.BINARY, true, "BINARIES");

    /** Map {@code Iterable} to array of {@link PropertyType#LONG} */
    public static final Type> LONGS =
            create(PropertyType.LONG, true, "LONGS");

    /** Map {@code Iterable} to array of {@link PropertyType#DOUBLE} */
    public static final Type> DOUBLES =
            create(PropertyType.DOUBLE, true, "DOUBLES");

    /** Map {@code Iterable} to array of {@link PropertyType#DATE} */
    public static final Type> DATES =
            create(PropertyType.DATE, true, "DATES");

    /** Map {@code Iterable} to array of {@link PropertyType#BOOLEAN} */
    public static final Type> BOOLEANS =
            create(PropertyType.BOOLEAN, true, "BOOLEANS");

    /** Map {@code Iterable} to array of {@link PropertyType#NAME} */
    public static final Type> NAMES =
            create(PropertyType.NAME, true, "NAMES");

    /** Map {@code Iterable} to array of {@link PropertyType#PATH} */
    public static final Type> PATHS =
            create(PropertyType.PATH, true, "PATHS");

    /** Map {@code Iterable} to array of {@link PropertyType#REFERENCE} */
    public static final Type> REFERENCES =
            create(PropertyType.REFERENCE, true, "REFERENCES");

    /** Map {@code Iterable} to array of {@link PropertyType#WEAKREFERENCE} */
    public static final Type> WEAKREFERENCES =
            create(PropertyType.WEAKREFERENCE, true, "WEAKREFERENCES");

    /** Map {@code Iterable} to array of {@link PropertyType#URI} */
    public static final Type> URIS =
            create(PropertyType.URI, true, "URIS");

    /** Map {@code Iterable} to array of {@link PropertyType#DECIMAL} */
    public static final Type> DECIMALS =
            create(PropertyType.DECIMAL, true, "DECIMALS");

    /** The special "undefined" type, never encountered in normal values */
    public static final Type UNDEFINED =
            create(PropertyType.UNDEFINED, false, "UNDEFINED");

    /** Multi-valued "undefined" type, never encountered in normal values */
    public static final Type> UNDEFINEDS =
            create(PropertyType.UNDEFINED, true, "UNDEFINEDS");

    private final int tag;

    private final boolean array;

    private final String string;

    private Type(int tag, boolean array, String string) {
        this.tag = tag;
        this.array = array;
        this.string = string;
    }

    /**
     * Corresponding type tag as defined in {@link PropertyType}.
     * @return  type tag
     */
    public int tag() {
        return tag;
    }

    /**
     * Determine whether this is an array type
     * @return  {@code true} if and only if this is an array type
     */
    public boolean isArray() {
        return array;
    }

    /**
     * Corresponding {@code Type} for a given type tag and array flag.
     * @param tag  type tag as defined in {@link PropertyType}.
     * @param array  whether this is an array or not
     * @return  {@code Type} instance
     * @throws IllegalArgumentException if tag is not valid as per definition in {@link PropertyType}.
     */
    public static Type fromTag(int tag, boolean array) {
        switch (tag) {
            case PropertyType.STRING: return array ? STRINGS : STRING;
            case PropertyType.BINARY: return array ? BINARIES : BINARY;
            case PropertyType.LONG: return array ? LONGS : LONG;
            case PropertyType.DOUBLE: return array ? DOUBLES : DOUBLE;
            case PropertyType.DATE: return array ? DATES: DATE;
            case PropertyType.BOOLEAN: return array ? BOOLEANS: BOOLEAN;
            case PropertyType.NAME: return array ? NAMES : NAME;
            case PropertyType.PATH: return array ? PATHS: PATH;
            case PropertyType.REFERENCE: return array ? REFERENCES : REFERENCE;
            case PropertyType.WEAKREFERENCE: return array ? WEAKREFERENCES : WEAKREFERENCE;
            case PropertyType.URI: return array ? URIS: URI;
            case PropertyType.DECIMAL: return array ? DECIMALS : DECIMAL;
            case PropertyType.UNDEFINED: return array ? UNDEFINEDS : UNDEFINED;
            default: throw new IllegalArgumentException("Invalid type tag: " + tag);
        }
    }

    /**
     * Returns the {@code Type} with the given string representation.
     *
     * @param string type string
     * @return matching type
     */
    public static Type fromString(String string) {
        Type type = TYPES.get(string);
        if (type == null) {
            throw new IllegalArgumentException("Invalid type name: " + string);
        }
        return type;
    }

    /**
     * Determine the base type of array types
     * @return  base type
     * @throws IllegalStateException if {@code isArray} is false.
     */
    public Type getBaseType() {
        checkState(isArray(), "Not an array");
        return fromTag(tag, false);
    }

    /**
     * Determine the array type which has this type as base type
     * @return  array type with this type as base type
     * @throws IllegalStateException if {@code isArray} is true.
     */
    public Type getArrayType() {
        checkState(!isArray(), "Not a simply type");
        return fromTag(tag, true);
    }

    //--------------------------------------------------------< Comparable >--

    @Override
    public int compareTo(@Nonnull Type that) {
        if (tag < that.tag) {
            return -1;
        }

        if (tag > that.tag) {
            return 1;
        }

        if (!array && that.array) {
            return -1;
        }

        if (array && !that.array) {
            return 1;
        }

        return 0;
    }

    //------------------------------------------------------------< Object >--

    @Override
    public String toString() {
        return string;
    }

    @Override
    public int hashCode() {
        int result = 1;

        result = result + 31 * tag;
        result = result + 31 * hashCode(array);

        return result;
    }

    private int hashCode(boolean value) {
        return value ? 1231 : 1237;
    }

    private void checkState(boolean condition, String message) {
        if (!condition) {
            throw new IllegalStateException(message);
        }
    }

    @Override
    public boolean equals(Object other) {
        return this == other;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy