blob: c04227aa31d56133b558114c9d5926187a7c2ddd [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* 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 com.motorolamobility.preflighting.core.validation;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.motorolamobility.preflighting.core.checker.CheckerExtension;
import com.motorolamobility.preflighting.core.checker.condition.ICondition;
import com.motorolamobility.preflighting.core.devicespecification.DeviceSpecification;
import com.motorolamobility.preflighting.core.exception.PreflightingExtensionPointException;
import com.motorolamobility.preflighting.core.i18n.PreflightingCoreNLS;
import com.motorolamobility.preflighting.core.sdk.SdkUtils;
import com.motorolamobility.preflighting.core.utils.LimitedList;
import com.motorolamobility.preflighting.core.validation.ValidationManager.InputParameter;
import com.motorolamobility.preflighting.core.validation.ValidationManager.WarningLevelAdjustmentType;
import com.motorolamobility.preflighting.core.validation.ValidationResultData.SEVERITY;
import com.motorolamobility.preflighting.core.verbose.DebugVerboseOutputter;
import com.motorolamobility.preflighting.core.verbose.DebugVerboseOutputter.VerboseLevel;
/**
* Utility class (static) which validates global parameters passed to App Validator.
*/
public final class GlobalInputParamsValidator
{
/**
* Constant for the variable that holds the system path.
*/
public static final String PATH_ENVIRONMENT_VARIABLE = "path"; //$NON-NLS-1$
private static final String WARNING_LEVEL_ADJUSTMENT_CHECKER_SEPARATOR = " "; //$NON-NLS-1$
private static final String WARNING_LEVEL_ADJUSTMENT_CHECKER_MESSAGE_SEPARATOR = ", "; //$NON-NLS-1$
/**
* Validates all global parameters passed to the application.
* Returns the ValidationResult object containing only ValidationResultData
* corresponding to errors on given parameters.
*
* @param params the global parameters passed to App Validator.
* @param adjustedWarningLevelInfo The object to hold information about warning level configuration.
* @return ValidationResult object containing the validation errors, if any.
*/
public static ValidationResult validateGlobalParams(List<Parameter> params,
Map<WarningLevelAdjustmentType, Set<String>> adjustedWarningLevelInfo,
List<DeviceSpecification> deviceSpecifications, ValidationManager validationManager)
{
ValidationResult globalResult = new ValidationResult(null, LimitedList.UNLIMITED);
ValidationResultData resultData = null;
boolean sdkParamFound = false;
boolean appPathParamFound = false;
for (Parameter param : params)
{
resultData = new ValidationResultData();
String inputParam = param.getParameterType();
String inputParamValue = param.getValue();
if (InputParameter.SDK_PATH.getAlias().equals(inputParam))
{
validateSdkParam(resultData, inputParamValue);
sdkParamFound = true;
// say that sdk path passed as parameter is being used
DebugVerboseOutputter
.printVerboseMessage(
PreflightingCoreNLS.GlobalInputParamsValidator_VerboseMessage_UsingParamSDKPath,
VerboseLevel.v1);
}
else if (InputParameter.APPLICATION_PATH.getAlias().equals(inputParam))
{
validateApplicationPathParam(resultData, inputParamValue);
appPathParamFound = true;
}
else if (InputParameter.DEVICE_DESCRIPTION.getAlias().equals(inputParam))
{
validateDescribeDeviceParam(resultData, inputParamValue, deviceSpecifications);
}
else if (InputParameter.WARNING_TO_ERROR.getAlias().equals(inputParam)
|| (InputParameter.ERROR_TO_WARNING.getAlias().equals(inputParam)))
{
validateWarningAdjustmentParameter(resultData, inputParamValue, inputParam,
adjustedWarningLevelInfo, validationManager);
}
else if (InputParameter.LIMIT.getAlias().equals(inputParam))
{
validateLimitParam(resultData, inputParamValue);
}
else
{
// unknown parameter passed
resultData.setSeverity(SEVERITY.ERROR);
resultData
.setIssueDescription(PreflightingCoreNLS.GlobalInputParamsValidator_UnknownParameterMessage
+ param.getParameterType());
}
if (!resultData.getSeverity().equals(SEVERITY.OK))
{
globalResult.addValidationResult(resultData);
}
}
resultData = new ValidationResultData();
if (!appPathParamFound)
{
resultData.setSeverity(SEVERITY.ERROR);
resultData
.setIssueDescription(PreflightingCoreNLS.GlobalInputParamsValidator_AppPathParameterMissing);
globalResult.addValidationResult(resultData);
}
else if (!sdkParamFound)
{
DebugVerboseOutputter
.printVerboseMessage(
PreflightingCoreNLS.GlobalInputParamsValidator_VerboseMessage_CheckingSystemPathForSDK,
VerboseLevel.v2);
boolean aaptFound = true;
String[] aaptCommand = new String[]
{
"aapt", "help" //$NON-NLS-1$ //$NON-NLS-2$
};
// test AAPT command
try
{
Runtime.getRuntime().exec(aaptCommand);
}
catch (IOException ioException)
{
//aapt not found
aaptFound = false;
DebugVerboseOutputter
.printVerboseMessage(
PreflightingCoreNLS.GlobalInputParamsValidator_VerboseMessage_SDKPathNotFoundOnSystemPath,
VerboseLevel.v2);
}
if (!aaptFound)
{
resultData.setSeverity(SEVERITY.ERROR);
resultData
.setIssueDescription(PreflightingCoreNLS.GlobalInputParamsValidator_SdkPathParameterMissing);
}
else
{
params.add(new Parameter(ValidationManager.InputParameter.SDK_PATH.getAlias(),
"aapt")); //$NON-NLS-1$
// say that system sdk path is being used
DebugVerboseOutputter
.printVerboseMessage(
PreflightingCoreNLS.GlobalInputParamsValidator_VerboseMessage_UsingSystemSDKPath,
VerboseLevel.v1);
}
if ((resultData.getSeverity() != null) && !resultData.getSeverity().equals(SEVERITY.OK))
{
globalResult.addValidationResult(resultData);
}
}
return globalResult;
}
private static void validateApplicationPathParam(ValidationResultData resultData,
String inputParamValue)
{
File appPath = new File(inputParamValue);
if (!appPath.exists())
{
resultData.setSeverity(SEVERITY.ERROR);
resultData
.setIssueDescription(PreflightingCoreNLS.GlobalInputParamsValidator_NonExistentApplicationPathMessage
+ inputParamValue);
}
else
{
resultData.setSeverity(SEVERITY.OK);
}
}
private static void validateLimitParam(ValidationResultData resultData, String paramValue)
{
resultData.setSeverity(SEVERITY.OK);
if (paramValue != null)
{
try
{
int limit = Integer.parseInt(paramValue);
if (limit >= 0)
{
return;
}
}
catch (NumberFormatException nfe)
{
resultData.setSeverity(SEVERITY.ERROR);
resultData.setIssueDescription(PreflightingCoreNLS.bind(
PreflightingCoreNLS.GlobalInputParamsValidator_LimitParam, paramValue));
}
}
resultData.setSeverity(SEVERITY.ERROR);
resultData.setIssueDescription(PreflightingCoreNLS.bind(
PreflightingCoreNLS.GlobalInputParamsValidator_LimitParam, paramValue));
}
/**
* Validates if SDK parameter is valid (if SDK folder exists, is a directory and have the binaries required to run App Validator).
* @param resultData result that is filled if there is any problem with SDK parameter.
* @param inputParamValue the global input value passed to run App Validator.
*/
public static void validateSdkParam(ValidationResultData resultData, String inputParamValue)
{
File sdkFolder = new File(inputParamValue);
if (!sdkFolder.exists())
{
resultData.setSeverity(SEVERITY.ERROR);
resultData
.setIssueDescription(PreflightingCoreNLS.GlobalInputParamsValidator_NonExistentSdkPathMessage
+ inputParamValue);
}
else if (!sdkFolder.isDirectory())
{
resultData.setSeverity(SEVERITY.ERROR);
resultData
.setIssueDescription(PreflightingCoreNLS.GlobalInputParamsValidator_SdkPathNotFolderMessage
+ inputParamValue);
}
// check if a particular tool is inside the folder (in this case, aapt), and
// if it isn't, assume it is not a valid sdk folder
else if (SdkUtils.getLatestAAPTToolPath(inputParamValue) == null)
{
resultData.setSeverity(SEVERITY.ERROR);
resultData
.setIssueDescription(PreflightingCoreNLS.GlobalInputParamsValidator_SdkPathNotValidSdkMessage
+ inputParamValue);
}
else
{
resultData.setSeverity(SEVERITY.OK);
}
}
private static boolean validateDescribeDeviceParam(ValidationResultData resultData,
String describeDeviceParamValue, List<DeviceSpecification> deviceSpecifications)
{
boolean deviceIdfound = false;
if (deviceSpecifications != null)
{
for (DeviceSpecification spec : deviceSpecifications)
{
if ((spec.getId() != null) && spec.getId().equals(describeDeviceParamValue))
{
deviceIdfound = true;
break;
}
}
}
return deviceIdfound;
}
private static void validateWarningAdjustmentParameter(ValidationResultData resultData,
String inputParamValue, String inputParam,
Map<WarningLevelAdjustmentType, Set<String>> adjustedWarningLevelInfo,
ValidationManager validationManager)
{
DebugVerboseOutputter
.printVerboseMessage(
PreflightingCoreNLS.GlobalInputParamsValidator_WarningLevelAdjustmentParameterFoundMessage,
VerboseLevel.v1);
WarningLevelAdjustmentType adjustmentType;
if (InputParameter.WARNING_TO_ERROR.getAlias().equals(inputParam))
{
adjustmentType = WarningLevelAdjustmentType.INCREASE;
}
else
{
adjustmentType = WarningLevelAdjustmentType.DECREASE;
}
// trim parameter value for guaranteeing there is something on it other than white spaces
if (inputParamValue != null)
{
inputParamValue = inputParamValue.trim();
}
Set<String> checkerIdsToAdjust = adjustedWarningLevelInfo.get(adjustmentType);
// if the parameter was not previously passed, create the list of checkers for it
if (checkerIdsToAdjust == null)
{
checkerIdsToAdjust = new HashSet<String>();
adjustedWarningLevelInfo.put(adjustmentType, checkerIdsToAdjust);
}
// if the parameter was previously passed, this is not allowed (return immediately to avoid complicated code)
else
{
resultData.setSeverity(SEVERITY.ERROR);
resultData.setIssueDescription(PreflightingCoreNLS.bind(
PreflightingCoreNLS.GlobalInputParamsValidator_RepeatedParameterErrorMessage,
inputParam));
return;
}
// no checker id passed; all checkers will have their warning levels adjusted;
// validation result is ok
if ((inputParamValue == null) || (inputParamValue.length() == 0))
{
DebugVerboseOutputter
.printVerboseMessage(
PreflightingCoreNLS.GlobalInputParamsValidator_WarningLevelAdjustmentAllCheckers,
VerboseLevel.v1);
resultData.setSeverity(SEVERITY.OK);
}
else
{
// retrieve passed checker ids, validate they exist, and add
// them to a list of checker ids to be adjusted for warning level
String[] completeIds =
inputParamValue.split(WARNING_LEVEL_ADJUSTMENT_CHECKER_SEPARATOR);
Map<String, CheckerExtension> knownCheckers = null;
StringBuilder unknownCheckerIdsMessage = new StringBuilder();
StringBuilder knownCheckerIdsMessage = new StringBuilder();
boolean unknownCheckerFound = false;
try
{
knownCheckers = ValidationManager.loadCheckers();
}
catch (PreflightingExtensionPointException e)
{
// do nothing; the list of checkers will fail to be validated
// and a correct message with unknown checkers will be used
}
for (String completeId : completeIds)
{
completeId = completeId.trim();
if (completeId.length() > 0)
{
//Grab the conditionID if exists, so we can verify it later.
String[] checkerCondition = completeId.split("\\.");
String checkerId = null;
String conditionId = null;
switch (checkerCondition.length)
{
case 0:
//Do nothing, checkerId is already correct
break;
case 1:
checkerId = checkerCondition[0];
break;
case 2:
checkerId = checkerCondition[0];
conditionId = checkerCondition[1];
break;
default:
unknownCheckerIdsMessage.append(completeId
+ WARNING_LEVEL_ADJUSTMENT_CHECKER_MESSAGE_SEPARATOR);
unknownCheckerFound = true;
}
//Verify if checker is valid
if ((knownCheckers == null) || !knownCheckers.containsKey(checkerId))
{
unknownCheckerIdsMessage.append(completeId
+ WARNING_LEVEL_ADJUSTMENT_CHECKER_MESSAGE_SEPARATOR);
unknownCheckerFound = true;
}
else
{
//Checker is valid now verify if the condition is valid
boolean conditionValid = true;
if (conditionId != null)
{
Map<String, ICondition> checkerConditions =
knownCheckers.get(checkerId).getChecker().getConditions();
if (checkerConditions != null)
{
conditionValid = checkerConditions.containsKey(conditionId);
}
else
{
conditionValid = false;
}
}
if (conditionValid)
{
checkerIdsToAdjust.add(completeId);
knownCheckerIdsMessage.append(completeId
+ WARNING_LEVEL_ADJUSTMENT_CHECKER_MESSAGE_SEPARATOR);
}
else
{
unknownCheckerIdsMessage.append(completeId
+ WARNING_LEVEL_ADJUSTMENT_CHECKER_MESSAGE_SEPARATOR);
unknownCheckerFound = true;
}
}
}
}
if (unknownCheckerFound)
{
// remove last comma added
unknownCheckerIdsMessage.delete(unknownCheckerIdsMessage
.lastIndexOf(WARNING_LEVEL_ADJUSTMENT_CHECKER_MESSAGE_SEPARATOR),
unknownCheckerIdsMessage.length());
String unknownCheckerIdsMessageStr = unknownCheckerIdsMessage.toString();
resultData.setSeverity(SEVERITY.ERROR);
resultData
.setIssueDescription(PreflightingCoreNLS
.bind(PreflightingCoreNLS.GlobalInputParamsValidator_UnknownCheckersForWarningLevelAdjustmentMessage,
unknownCheckerIdsMessageStr));
}
else
{
// remove last comma added
knownCheckerIdsMessage.delete(knownCheckerIdsMessage
.lastIndexOf(WARNING_LEVEL_ADJUSTMENT_CHECKER_MESSAGE_SEPARATOR),
knownCheckerIdsMessage.length());
String knownCheckerIdsMessageStr = knownCheckerIdsMessage.toString();
DebugVerboseOutputter
.printVerboseMessage(
PreflightingCoreNLS
.bind(PreflightingCoreNLS.GlobalInputParamsValidator_WarningLevelAdjustmentFollowingCheckers,
knownCheckerIdsMessageStr), VerboseLevel.v1);
resultData.setSeverity(SEVERITY.OK);
}
}
}
}