com.amazonaws.auth.profile.internal.AbstractProfilesConfigFileScanner Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-java-sdk-core Show documentation
Show all versions of aws-java-sdk-core Show documentation
The AWS SDK for Java - Core module holds the classes that are used by the individual service clients to interact with Amazon Web Services. Users need to depend on aws-java-sdk artifact for accessing individual client classes.
/*
* Copyright 2014-2024 Amazon.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://aws.amazon.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.amazonaws.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);
/**
* Hook to allow subclasses to determine which properties are supported and which aren't.
*
* @return True if property is supported by scanner implementation, false otherwise.
*/
protected boolean isSupportedProperty(String propertyName) {
return true;
}
/**
* 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 {
int lineNumber = 0;
while(scanner.hasNextLine()) {
++lineNumber;
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, lineNumber);
if (currentProfileName == null) {
throw new IllegalArgumentException("Property is defined without a preceding profile name on line " +
lineNumber);
}
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, int lineNumber) {
String[] pair = propertyLine.split("=", 2);
if (pair.length != 2) {
throw new IllegalArgumentException("Invalid property format: no '=' character is found on line " + lineNumber);
}
String propertyKey = pair[0].trim();
String propertyValue = pair[1].trim();
return new AbstractMap.SimpleImmutableEntry(propertyKey, propertyValue);
}
}