forked from leandronunes85/log-format-enforcer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e0345ac
Showing
15 changed files
with
948 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2016 Leandro Nunes | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<artifactId>log-format-enforcer</artifactId> | ||
<groupId>com.leandronunes85</groupId> | ||
<version>1.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>log-format-enforcer-generator</artifactId> | ||
|
||
<properties> | ||
<!--dependencies--> | ||
<stringtemplate.version>4.0.2</stringtemplate.version> | ||
<commons-lang3.version>3.4</commons-lang3.version> | ||
<guava.version>19.0</guava.version> | ||
<!--test dependencies--> | ||
<junit.version>4.12</junit.version> | ||
<assertj-core.version>3.3.0</assertj-core.version> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.antlr</groupId> | ||
<artifactId>stringtemplate</artifactId> | ||
<version>${stringtemplate.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.commons</groupId> | ||
<artifactId>commons-lang3</artifactId> | ||
<version>${commons-lang3.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava</artifactId> | ||
<version>${guava.version}</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<version>${junit.version}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.assertj</groupId> | ||
<artifactId>assertj-core</artifactId> | ||
<version>${assertj-core.version}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
24 changes: 24 additions & 0 deletions
24
log-format-enforcer-generator/src/main/java/com/leandronunes85/lfe/FieldInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.leandronunes85.lfe; | ||
|
||
public class FieldInfo { | ||
|
||
public static FieldInfo of(String fieldName, String fieldText) { | ||
return new FieldInfo(fieldName, fieldText); | ||
} | ||
|
||
private final String fieldName; | ||
private final String fieldText; | ||
|
||
protected FieldInfo(String fieldName, String fieldText) { | ||
this.fieldName = fieldName; | ||
this.fieldText = fieldText; | ||
} | ||
|
||
public String getFieldName() { | ||
return fieldName; | ||
} | ||
|
||
public String getFieldText() { | ||
return fieldText; | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
...mat-enforcer-generator/src/main/java/com/leandronunes85/lfe/LogFormatEnforcerCreator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package com.leandronunes85.lfe; | ||
|
||
import com.google.common.base.Preconditions; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.apache.commons.lang3.tuple.Pair; | ||
import org.stringtemplate.v4.STGroupFile; | ||
|
||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
import static com.google.common.base.Preconditions.checkArgument; | ||
import static com.leandronunes85.lfe.utils.Utils.capitalizeIt; | ||
import static com.leandronunes85.lfe.utils.Utils.pairingWithNextElement; | ||
import static java.util.regex.Pattern.compile; | ||
import static java.util.stream.Collectors.toList; | ||
import static org.apache.commons.lang3.StringUtils.isNotEmpty; | ||
|
||
public class LogFormatEnforcerCreator { | ||
|
||
private static final Pattern PACKAGE_PATTERN = compile("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)*[a-zA-Z_$][a-zA-Z\\d_$]*"); | ||
private static final String GENERIC_INTERFACE_NAME = "OptionalFields"; | ||
private static final STGroupFile TEMPLATE = new STGroupFile("templates/LogFormatEnforcer.stg"); | ||
|
||
|
||
public String createALogFormatEnforcer(String withPackageName, | ||
List<FieldInfo> withMandatoryFields, | ||
List<FieldInfo> withOptionalFields, | ||
String withEntrySeparator, | ||
String withValueDelimiter, | ||
String withKeyValueSeparator) { | ||
|
||
checkArguments(withPackageName, withMandatoryFields, withOptionalFields, | ||
withEntrySeparator, withValueDelimiter, withKeyValueSeparator); | ||
|
||
List<MandatoryFieldInfo> mandatoryFieldInfos = getMandatoryFieldInfos(withMandatoryFields); | ||
|
||
String builderEntryPoint = !mandatoryFieldInfos.isEmpty() ? | ||
mandatoryFieldInfos.get(0).getInterfaceName() : GENERIC_INTERFACE_NAME; | ||
|
||
return TEMPLATE.getInstanceOf("logFormatEnforcer") | ||
.add("package", withPackageName) | ||
.add("mandatoryFieldInfos", mandatoryFieldInfos) | ||
.add("optionalFields", withOptionalFields) | ||
.add("entrySeparator", withEntrySeparator) | ||
.add("valueDelimiter", withValueDelimiter) | ||
.add("keyValueSeparator", withKeyValueSeparator) | ||
.add("builderEntryPoint", builderEntryPoint) | ||
.render(); | ||
} | ||
|
||
private void checkArguments(String withPackageName, | ||
List<FieldInfo> withMandatoryFields, | ||
List<FieldInfo> withOptionalFields, | ||
String withEntrySeparator, | ||
String withValueDelimiter, | ||
String withKeyValueSeparator) { | ||
|
||
checkPackageName(withPackageName); | ||
|
||
checkArgument(withMandatoryFields != null, "mandatoryFields must not be null"); | ||
|
||
checkArgument(withOptionalFields != null, "optionalFields must not be null"); | ||
|
||
checkArgument(withEntrySeparator != null, "entrySeparator must not be null"); | ||
|
||
checkArgument(withValueDelimiter != null, "valueDelimiter must not be null"); | ||
|
||
checkArgument(withKeyValueSeparator != null, "keyValueSeparator must not be null"); | ||
|
||
} | ||
|
||
private void checkPackageName(String withPackageName) { | ||
checkArgument(isNotEmpty(withPackageName), "packageName must not be empty"); | ||
Matcher packageNameMatcher = PACKAGE_PATTERN.matcher(withPackageName); | ||
checkArgument(packageNameMatcher.find(), "packageName doesn't seem to be a valid package name"); | ||
checkArgument(packageNameMatcher.matches(), "packageName doesn't seem to be a valid package name"); | ||
} | ||
|
||
private List<MandatoryFieldInfo> getMandatoryFieldInfos(List<FieldInfo> withMandatoryFields) { | ||
return pairingWithNextElement(withMandatoryFields, GENERIC_INTERFACE_NAME, fieldInfo -> fieldInfo.getFieldName()) | ||
.map(MandatoryFieldInfo::of) | ||
.collect(toList()); | ||
} | ||
} | ||
|
33 changes: 33 additions & 0 deletions
33
log-format-enforcer-generator/src/main/java/com/leandronunes85/lfe/MandatoryFieldInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.leandronunes85.lfe; | ||
|
||
import org.apache.commons.lang3.tuple.Pair; | ||
|
||
import static com.leandronunes85.lfe.utils.Utils.capitalizeIt; | ||
|
||
public class MandatoryFieldInfo extends FieldInfo { | ||
|
||
public static MandatoryFieldInfo of(FieldInfo fieldInfo, String returnType) { | ||
return new MandatoryFieldInfo(fieldInfo.getFieldName(), fieldInfo.getFieldText(), returnType); | ||
} | ||
|
||
public static MandatoryFieldInfo of(Pair<FieldInfo, String> fieldInfoAndReturnType) { | ||
return of(fieldInfoAndReturnType.getLeft(), fieldInfoAndReturnType.getRight()); | ||
} | ||
|
||
private final String interfaceName; | ||
private final String returnType; | ||
|
||
protected MandatoryFieldInfo(String fieldName, String fieldText, String returnType) { | ||
super(fieldName, fieldText); | ||
this.interfaceName = capitalizeIt(fieldName); | ||
this.returnType = capitalizeIt(returnType); | ||
} | ||
|
||
public String getInterfaceName() { | ||
return interfaceName; | ||
} | ||
|
||
public String getReturnType() { | ||
return returnType; | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
log-format-enforcer-generator/src/main/java/com/leandronunes85/lfe/utils/Utils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.leandronunes85.lfe.utils; | ||
|
||
import org.apache.commons.lang3.tuple.Pair; | ||
|
||
import java.util.List; | ||
import java.util.function.Function; | ||
import java.util.stream.Stream; | ||
|
||
import static java.util.stream.IntStream.rangeClosed; | ||
|
||
public final class Utils { | ||
|
||
private Utils() { | ||
} | ||
|
||
public static String capitalizeIt(String input) { | ||
return input.substring(0, 1).toUpperCase() + input.substring(1); | ||
} | ||
|
||
public static <L, R> Stream<Pair<L, R>> pairingWithNextElement(List<L> input, | ||
R pairForLastElement, | ||
Function<L, R> mapper) { | ||
if (input == null || input.isEmpty()) { | ||
return Stream.empty(); | ||
} | ||
|
||
int size = input.size(); | ||
return rangeClosed(1, size) | ||
.mapToObj(i -> Pair.of(input.get(i - 1), i < size ? mapper.apply(input.get(i)) : pairForLastElement)); | ||
} | ||
} |
120 changes: 120 additions & 0 deletions
120
log-format-enforcer-generator/src/main/resources/templates/LogFormatEnforcer.stg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
logFormatEnforcer(package, | ||
mandatoryFieldInfos, | ||
optionalFields, | ||
entrySeparator, | ||
valueDelimiter, | ||
keyValueSeparator, | ||
builderEntryPoint) ::= << | ||
package <package>; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.slf4j.event.Level; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.function.BiConsumer; | ||
import java.util.function.BooleanSupplier; | ||
|
||
import static java.util.stream.Collectors.joining; | ||
|
||
public class LogFormatEnforcer { | ||
|
||
public static LogFormatEnforcer loggerFor(Class\<?\> clazz) { | ||
return new LogFormatEnforcer(clazz.getName()); | ||
} | ||
|
||
private final HashMap\<Level, BooleanSupplier\> logEnabledLookup = new HashMap\<\>(Level.values().length); | ||
private final HashMap\<Level, BiConsumer\<String, Object[]\>\> logLookup = new HashMap\<\>(Level.values().length); | ||
|
||
private LogFormatEnforcer(String logName) { | ||
Logger logger = LoggerFactory.getLogger(logName); | ||
|
||
this.logEnabledLookup.put(Level.ERROR, logger::isErrorEnabled); | ||
this.logEnabledLookup.put(Level.WARN, logger::isWarnEnabled); | ||
this.logEnabledLookup.put(Level.INFO, logger::isInfoEnabled); | ||
this.logEnabledLookup.put(Level.DEBUG, logger::isDebugEnabled); | ||
this.logEnabledLookup.put(Level.TRACE, logger::isTraceEnabled); | ||
|
||
this.logLookup.put(Level.ERROR, logger::error); | ||
this.logLookup.put(Level.WARN, logger::warn); | ||
this.logLookup.put(Level.INFO, logger::info); | ||
this.logLookup.put(Level.DEBUG, logger::debug); | ||
this.logLookup.put(Level.TRACE, logger::trace); | ||
} | ||
|
||
public void log(Level level, ToBuild willBuild) { | ||
|
||
if (this.logEnabledLookup.get(level).getAsBoolean()) { | ||
ActualBuilder builder = new ActualBuilder(); | ||
willBuild.buildIt(builder); | ||
this.logLookup.get(level).accept(builder.getMessage(), builder.getArguments()); | ||
} | ||
|
||
} | ||
|
||
public interface ToBuild { | ||
OptionalFields buildIt(<builderEntryPoint> builder); | ||
} | ||
|
||
<mandatoryFieldInfos:interface(); separator="\n\n"> | ||
|
||
public interface OptionalFields { | ||
<optionalFields:optionalFieldMethod(); separator="\n"> | ||
OptionalFields other(String name, Object value); | ||
} | ||
|
||
private class ActualBuilder implements <mandatoryFieldInfos:interfaceName(); separator=", ">, OptionalFields { | ||
|
||
private final ArrayList\<String\> messages = new ArrayList\<\>(); | ||
private final ArrayList\<Object\> values = new ArrayList\<\>(); | ||
|
||
<mandatoryFieldInfos:actualBuilderMandatoryMethod();separator="\n\n"> | ||
|
||
<optionalFields:actualBuilderOptionalMethod();separator="\n\n"> | ||
|
||
public OptionalFields other(String name, Object value) { | ||
return newField(name, value); | ||
} | ||
|
||
private ActualBuilder newField(String name, Object value) { | ||
this.messages.add(name + "<keyValueSeparator><valueDelimiter>{}<valueDelimiter>"); | ||
this.values.add(value); | ||
return this; | ||
} | ||
|
||
public String getMessage() { | ||
return messages.stream().collect(joining("<entrySeparator>")); | ||
} | ||
|
||
public Object[] getArguments() { | ||
return values.toArray(); | ||
} | ||
} | ||
} | ||
|
||
>> | ||
|
||
interface(mandatoryFieldInfo) ::= << | ||
public interface <mandatoryFieldInfo.interfaceName> { | ||
<mandatoryFieldInfo.returnType> <mandatoryFieldInfo.fieldName>(Object <mandatoryFieldInfo.fieldName>); | ||
} | ||
>> | ||
|
||
optionalFieldMethod(fieldInfo) ::= <<OptionalFields <fieldInfo.fieldName>(Object <fieldInfo.fieldName>);>> | ||
|
||
interfaceName(mandatoryFieldInfo) ::= << | ||
<mandatoryFieldInfo.interfaceName> | ||
>> | ||
|
||
actualBuilderMandatoryMethod(mandatoryFieldInfo) ::= << | ||
public <mandatoryFieldInfo.returnType> <mandatoryFieldInfo.fieldName>(Object <mandatoryFieldInfo.fieldName>) { | ||
return newField("<mandatoryFieldInfo.fieldText>", <mandatoryFieldInfo.fieldName>); | ||
} | ||
>> | ||
|
||
actualBuilderOptionalMethod(fieldInfo) ::= << | ||
public OptionalFields <fieldInfo.fieldName>(Object <fieldInfo.fieldName>) { | ||
return newField("<fieldInfo.fieldText>", <fieldInfo.fieldName>); | ||
} | ||
>> |
Oops, something went wrong.