From e16434057b20f5861567c751fa274d06a9d062b5 Mon Sep 17 00:00:00 2001 From: Peter Gafert Date: Sun, 5 Feb 2023 21:46:52 +0700 Subject: [PATCH] Review: Improve documentation Signed-off-by: Peter Gafert --- .../freeze/TextFileBasedViolationStore.java | 82 +++++++++++-------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/archunit/src/main/java/com/tngtech/archunit/library/freeze/TextFileBasedViolationStore.java b/archunit/src/main/java/com/tngtech/archunit/library/freeze/TextFileBasedViolationStore.java index a3c98e8a44..37d3ef56ee 100644 --- a/archunit/src/main/java/com/tngtech/archunit/library/freeze/TextFileBasedViolationStore.java +++ b/archunit/src/main/java/com/tngtech/archunit/library/freeze/TextFileBasedViolationStore.java @@ -36,17 +36,31 @@ import static com.google.common.base.Preconditions.checkState; import static com.google.common.io.Files.toByteArray; import static com.tngtech.archunit.PublicAPI.Usage.ACCESS; +import static com.tngtech.archunit.PublicAPI.Usage.INHERITANCE; import static com.tngtech.archunit.library.freeze.FreezingArchRule.ensureUnixLineBreaks; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.stream.Collectors.toList; /** - * An implementation of {@link ViolationStore} that stores violations instances in a text file, one such file for each rule that is frozen. - * - *

- * The files are all stored in a single directory and so their names must be sufficient unique from each other. The out-of-the box implementation (no-arg constructor) - * simply uses a UUID. However, this can be overridden by passing in an instance of {@link TextFileBasedViolationStore.FileNameStrategy} to the appropriate constructor. - *

+ * A text file based implementation of a {@link ViolationStore}.
+ * This {@link ViolationStore} will store the violations of every single {@link FreezingArchRule} in a dedicated file.
+ * It will keep an index of all stored rules as well as a mapping to the individual rule violation files in the same folder.
+ * By default, the layout within the configured store folder will look like: + *

+ * storeFolder
+ *   |-- stored.rules (the index file of all stored rules)
+ *   |-- 6fc2fd04-b3ab-44e0-8f78-215c66f2174a (a rule violation file named randomly by UUID and referenced from stored.rules)
+ *   |-- 2186b43a-c24c-417d-bd96-547e2dfdba1c (another rule violation file)
+ *   |-- ... (more rule violation files for every rule that has been stored so far)
+ * 
+ * To adjust the strategy how the individual rule violation files are named use the constructor + * {@link TextFileBasedViolationStore#TextFileBasedViolationStore(RuleViolationFileNameStrategy) TextFileBasedViolationStore(RuleViolationFileNameStrategy)}.
+ * This {@link ViolationStore} can be configured through the following properties: + *

+ * default.path=...               # string: the path of the folder where violation files will be stored
+ * default.allowStoreCreation=... # boolean: whether to allow creating a new index file
+ * default.allowStoreUpdate=...   # boolean: whether to allow updating any store file
+ * 
*/ @PublicAPI(usage = ACCESS) public final class TextFileBasedViolationStore implements ViolationStore { @@ -61,44 +75,29 @@ public final class TextFileBasedViolationStore implements ViolationStore { private static final String ALLOW_STORE_UPDATE_PROPERTY_NAME = "default.allowStoreUpdate"; private static final String ALLOW_STORE_UPDATE_DEFAULT = "true"; - private final FileNameStrategy fileNameStrategy; + private final RuleViolationFileNameStrategy ruleViolationFileNameStrategy; private boolean storeCreationAllowed; private boolean storeUpdateAllowed; private File storeFolder; private FileSyncedProperties storedRules; - public TextFileBasedViolationStore() { - this(__ -> UUID.randomUUID().toString()); - } - /** - * Provides a mechanism to allow the file name that stores the violations of a particular rule to be customised, based on the description of that rule. + * Creates a standard {@link TextFileBasedViolationStore} that names rule violation files by random {@link UUID}s * - *

- * An instance of this interface is passed into the constructor. - *

+ * @see #TextFileBasedViolationStore(RuleViolationFileNameStrategy) */ - @FunctionalInterface - public interface FileNameStrategy { - /** - * Based on the description of a rule file, return a name to be used as the file name contianing the frozen violations of that rule. - * - *

- * The returned name must be sufficiently unique from any others; since the descriptions themselves are unique, this typically means sanitizing the description into some sort of file name. - *

- * - * @param description - of the rule whose frozen violations are to be stored - * @return - the name of a file to store these frozen violations. - */ - String fileName(String description); + public TextFileBasedViolationStore() { + this(__ -> UUID.randomUUID().toString()); } /** - * @param fileNameStrategy - to override the default strategy for naming the files that contain frozen violation instances for a given rule. + * Creates a {@link TextFileBasedViolationStore} with a custom strategy for rule violation file naming + * + * @param ruleViolationFileNameStrategy controls how the rule violation file name is derived from the rule description */ - public TextFileBasedViolationStore(FileNameStrategy fileNameStrategy) { - this.fileNameStrategy = fileNameStrategy; + public TextFileBasedViolationStore(RuleViolationFileNameStrategy ruleViolationFileNameStrategy) { + this.ruleViolationFileNameStrategy = ruleViolationFileNameStrategy; } @Override @@ -180,7 +179,7 @@ private String ensureRuleFileName(ArchRule rule) { ruleFileName = storedRules.getProperty(ruleDescription); log.debug("Rule '{}' is already stored in file {}", ruleDescription, ruleFileName); } else { - ruleFileName = this.fileNameStrategy.fileName(ruleDescription); + ruleFileName = ruleViolationFileNameStrategy.createRuleFileName(ruleDescription); log.debug("Assigning new file {} to rule '{}'", ruleFileName, ruleDescription); storedRules.setProperty(ruleDescription, ruleFileName); } @@ -265,4 +264,23 @@ private void syncFileSystem() { } } } + + /** + * Allows to adjust the rule violation file names of {@link TextFileBasedViolationStore} + * + * @see #TextFileBasedViolationStore(RuleViolationFileNameStrategy) + */ + @FunctionalInterface + @PublicAPI(usage = INHERITANCE) + public interface RuleViolationFileNameStrategy { + /** + * Returns the file name to store violations of an {@link ArchRule}, possibly based on the rule description.
+ * The returned names must be sufficiently unique from any others; + * as long as the descriptions themselves are unique, this can be achieved by sanitizing the description into some sort of file name. + * + * @param ruleDescription The description of the {@link ArchRule} to store + * @return The file name the respective rule violation file will have (see {@link TextFileBasedViolationStore}) + */ + String createRuleFileName(String ruleDescription); + } }