org.apache.aurora.common.args.Parsers.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.aurora.common.args.Parsers.java

Source

/**
 * 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 org.apache.aurora.common.args;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.reflect.TypeToken;

import org.apache.aurora.common.args.apt.Configuration;
import org.apache.aurora.common.args.apt.Configuration.ParserInfo;

import static com.google.common.base.Preconditions.checkArgument;

import static org.apache.aurora.common.args.apt.Configuration.ConfigurationException;

/**
 * A registry of Parsers for different supported argument types.
 *
 * @author William Farner
 */
public final class Parsers implements ParserOracle {

    public static final Splitter MULTI_VALUE_SPLITTER = Splitter.on(",").trimResults().omitEmptyStrings();

    private static final Function<ParserInfo, Class<?>> INFO_TO_PARSED_TYPE = parserInfo -> {
        try {
            return Class.forName(parserInfo.parsedType);
        } catch (ClassNotFoundException e) {
            throw new ConfigurationException(e);
        }
    };

    @VisibleForTesting
    static final Function<ParserInfo, Parser<?>> INFO_TO_PARSER = parserInfo -> {
        try {
            Class<?> parserClass = Class.forName(parserInfo.parserClass);
            Constructor<?> constructor = parserClass.getDeclaredConstructor();
            constructor.setAccessible(true);
            return (Parser<?>) constructor.newInstance();
        } catch (ClassNotFoundException e) {
            throw new ConfigurationException(e);
        } catch (InstantiationException e) {
            throw new ConfigurationException(e);
        } catch (IllegalAccessException e) {
            throw new ConfigurationException(e);
        } catch (NoSuchMethodException e) {
            throw new ConfigurationException(e);
        } catch (InvocationTargetException e) {
            throw new ConfigurationException(e);
        }
    };

    private final ImmutableMap<Class<?>, Parser<?>> registry;

    /**
     * Creates a new parser registry over the specified {@code parsers}.
     *
     * @param parsers The parsers to register.
     */
    public Parsers(Map<Class<?>, Parser<?>> parsers) {
        Preconditions.checkNotNull(parsers);
        registry = ImmutableMap.copyOf(parsers);
    }

    @Override
    public <T> Parser<T> get(TypeToken<T> type) throws IllegalArgumentException {
        Parser<?> parser;
        Class<?> explicitClass = type.getRawType();
        while (((parser = registry.get(explicitClass)) == null) && (explicitClass != null)) {
            explicitClass = explicitClass.getSuperclass();
        }
        checkArgument(parser != null, "No parser found for " + type);

        // We control loading of the registry which ensures a proper mapping of class -> parser
        @SuppressWarnings("unchecked")
        Parser<T> parserT = (Parser<T>) parser;

        return parserT;
    }

    static Parsers fromConfiguration(Configuration configuration) {
        Map<Class<?>, Parser<?>> parsers = Maps
                .transformValues(Maps.uniqueIndex(configuration.parserInfo(), INFO_TO_PARSED_TYPE), INFO_TO_PARSER);
        return new Parsers(parsers);
    }
}