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

com.ksc.auth.profile.internal.AbstractProfilesConfigFileScanner Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014-2016 ksyun.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://ksyun.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file 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.ksc.auth.profile.internal;

import java.util.AbstractMap;
import java.util.Map.Entry;
import java.util.Scanner;

/**
 * An abstract template class for the generic operation that involves scanning
 * through a profile configuration file. Subclass should implement the abstract
 * methods to define the actions when different components of the profiles file
 * are detected.
 */
public abstract class AbstractProfilesConfigFileScanner {

    /**
     * Action to be performed when an empty or comment line is detected
     */
    protected abstract void onEmptyOrCommentLine(String profileName, String line);

    /**
     * Action to be performed when the starting line of a new profile is detected
     */
    protected abstract void onProfileStartingLine(String newProfileName, String line);

    /**
     * Action to be performed when the scanner reaches the end of a profile
     * section. This method is invoked either at the start of a new profile
     * section, or at the end of the file.
     */
    protected abstract void onProfileEndingLine(String prevProfileName);

    /**
     * Action to be performed when the scanner reaches the end of the
     * credentials file.
     */
    protected abstract void onEndOfFile();

    /**
     * Action to be performed when a property declaration is detected inside a
     * profile section.
     *
     * @param profileName
     *            The name of the profile where this property is declared.
     * @param propertyName
     *            The name of the property.
     * @param propertyValue
     *            The value of the property.
     * @param isSupportedProperty
     *            Whether this is a supported property according to the
     *            specification of credential profiles file.
     * @param line
     *            The original line of text where the property is declared.
     */
    protected abstract void onProfileProperty(String profileName,
                                              String propertyName,
                                              String propertyValue,
                                              boolean isSupportedProperty,
                                              String line);


    /**
     * Scan through the given input, and perform the defined actions.
     *
     * @param scanner
     *            The scanner for the credentials file input.
     */
    protected void run(Scanner scanner) {
        String currentProfileName = null;

        try {
            while(scanner.hasNextLine()) {
                String line = scanner.nextLine().trim();

                // Empty or comment lines
                if (line.isEmpty() || line.startsWith("#")) {
                    onEmptyOrCommentLine(currentProfileName, line);
                    continue;
                }

                // parseGroupName returns null if this line does not
                // indicate a new property group.
                String newProfileName = parseProfileName(line);
                boolean atNewProfileStartingLine = newProfileName != null;

                if (atNewProfileStartingLine) {
                    if (currentProfileName != null) {
                        onProfileEndingLine(currentProfileName);
                    }
                    onProfileStartingLine(newProfileName, line);

                    // Start the new profile
                    currentProfileName = newProfileName;
                } else {
                    // Parse the property line
                    Entry property = parsePropertyLine(line);

                    if (currentProfileName == null) {
                        throw new IllegalArgumentException(
                                "Property is defined without a preceding profile name. "
                                + "Current line: " + line);
                    }

                    onProfileProperty(currentProfileName,
                                      property.getKey(),
                                      property.getValue(),
                                      isSupportedProperty(property.getKey()),
                                      line);
                }
            }

            // EOF
            if (currentProfileName != null) {
                onProfileEndingLine(currentProfileName);
            }

            onEndOfFile();

        } finally {
            scanner.close();
        }
    }


    /**
     * Returns the profile name if this line indicates the beginning of a new
     * profile section. Otherwise, returns null.
     */
    private static String parseProfileName(String trimmedLine) {
        if (trimmedLine.startsWith("[") && trimmedLine.endsWith("]")) {
            String profileName = trimmedLine.substring(1, trimmedLine.length() - 1);
            return profileName.trim();
        }
        return null;
    }

    private static Entry parsePropertyLine(String propertyLine) {
        String[] pair = propertyLine.split("=", 2);
        if (pair.length != 2) {
            throw new IllegalArgumentException(
                    "Invalid property format: no '=' character is found in the line ["
                    + propertyLine + "].");
        }

        String propertyKey   = pair[0].trim();
        String propertyValue = pair[1].trim();

        return new AbstractMap.SimpleImmutableEntry(propertyKey, propertyValue);
    }

    private static boolean isSupportedProperty(String propertyName) {
        return Profile.AWS_ACCESS_KEY_ID.equals(propertyName)
               || Profile.AWS_SECRET_ACCESS_KEY.equals(propertyName)
               || Profile.AWS_SESSION_TOKEN.equals(propertyName)
               || Profile.EXTERNAL_ID.equals(propertyName)
               || Profile.ROLE_ARN.equals(propertyName)
               || Profile.ROLE_SESSION_NAME.equals(propertyName)
               || Profile.SOURCE_PROFILE.equals(propertyName);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy