com.crabshue.commons.properties.validation.PropertiesValidator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of commons-properties Show documentation
Show all versions of commons-properties Show documentation
Library for properties files operations.
package com.crabshue.commons.properties.validation;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import com.crabshue.commons.exceptions.ValidationException;
import com.crabshue.commons.file.nio.FileIOUtils;
import com.crabshue.commons.properties.exceptions.PropertiesErrorContext;
import com.crabshue.commons.properties.exceptions.PropertiesErrorType;
import lombok.NonNull;
/**
* Validator for properties files.
*
*/
public class PropertiesValidator {
private static final String REGEX = "^[a-zA-Z0-9._-]+$";
/**
* Validate a properties file.
*
* @param propertiesFile the properties file
* @see #validateProperties(Path, boolean)
*/
public void validateProperties(@NonNull final Path propertiesFile) {
validateProperties(propertiesFile, false);
}
/**
* Validate a properties file with option to accept empty values.
*
* @param propertiesFile the properties file.
* @param acceptEmptyValues the option to accept empty values.
* @see #validatePropertiesFormat(Path, boolean)
* @see #validateNoDuplicatedKeys(Path)
*/
public void validateProperties(@NonNull final Path propertiesFile,
@NonNull final boolean acceptEmptyValues) {
validatePropertiesFormat(propertiesFile, acceptEmptyValues);
validateNoDuplicatedKeys(propertiesFile);
}
/**
* Validate the properties file containing non empty key and value separated by
* '=' and where each keys matches the regex {@link PropertiesValidator#REGEX}.
*
* @param propertiesFile Properties file to be validated
* @see #validatePropertiesLine(Path, String, boolean)
*/
private void validatePropertiesFormat(@NonNull final Path propertiesFile,
@NonNull final boolean acceptEmptyValues) {
final Collection lines = FileIOUtils.readLines(propertiesFile);
for (String line : lines) {
final String trimmedLine = StringUtils.trim(line);
validatePropertiesLine(propertiesFile, trimmedLine, acceptEmptyValues);
}
}
private void validatePropertiesLine(@NonNull final Path propertiesFile,
@NonNull final String line,
@NonNull final boolean acceptEmptyValues) {
if (StringUtils.isEmpty(line)) {
return;
}
final boolean isCommentedLine = StringUtils.startsWithAny(line, new String[]{"#", "!"});
if (isCommentedLine) {
return;
}
final boolean containsEqual = StringUtils.contains(line, "=");
if (!containsEqual) {
throw new ValidationException(PropertiesErrorType.PROPERTIES_FILE_MISSING_EQUAL, "Error in properties file")
.addContextValue(PropertiesErrorContext.PROPERTIES, propertiesFile)
.addContextValue(PropertiesErrorContext.LINE, line);
}
final String key = StringUtils.substringBefore(line, "=");
final String trimmedKey = StringUtils.trim(key);
final String value = StringUtils.substringAfter(line, "=");
// Validate empty value
if (!acceptEmptyValues && StringUtils.isEmpty(value)) {
throw new ValidationException(PropertiesErrorType.PROPERTIES_FILE_MISSING_VALUE, "Error in properties file")
.addContextValue(PropertiesErrorContext.PROPERTIES, propertiesFile)
.addContextValue(PropertiesErrorContext.LINE, line);
}
validateKey(propertiesFile, trimmedKey);
}
private void validateKey(@NonNull final Path propertiesFile,
@NonNull final String key) {
if (!key.matches(REGEX)) {
throw new ValidationException(PropertiesErrorType.PROPERTIES_WRONGLY_FORMATTED_KEY, "Error in properties file")
.addContextValue(PropertiesErrorContext.PROPERTIES, propertiesFile)
.addContextValue(PropertiesErrorContext.KEY, key)
.addContextValue(PropertiesErrorContext.REGEX, REGEX);
}
}
private void validateNoDuplicatedKeys(@NonNull final Path propertiesFile) {
final Collection lines = FileIOUtils.readLines(propertiesFile);
final Set setOfKeys = new HashSet<>();
for (String line : lines) {
if (StringUtils.isEmpty(line)) {
continue;
}
final boolean isCommentedLine = StringUtils.startsWithAny(line, new String[]{"#", "!"});
if (isCommentedLine) {
continue;
}
final String key = line.split("=")[0];
if (setOfKeys.contains(key)) {
throw new ValidationException(PropertiesErrorType.PROPERTIES_FILE_DUPLICATE_KEY, "Error in properties validation")
.addContextValue(PropertiesErrorContext.PROPERTIES, propertiesFile)
.addContextValue(PropertiesErrorContext.KEY, key)
;
}
setOfKeys.add(key);
}
}
}