Compare commits

...

22 Commits

Author SHA1 Message Date
Speiger d5a47ce568 Added Iteration support.
Said support allows to use the #iterate & #argument #enditerate
parameters.
Which will duplicate the text block inside of it x amount of times with
arguments being replaced.

The idea being that if code can be replicated the iterate option would
simplify the process.

Multiple arguments can be defined (they will be not part of the output)
and it will simply insert them.
Note that all argument parameters have to be equal size.
Otherwise the iterator processor will fail.

Iterators can be stacked too to create layers upon layers.

On top of that the iterator is part of the Template parser and not of
the template processor meaning its a Pre processor step.
And all mappers still apply themselves on to the output of the
iterators!
2023-06-27 13:29:31 +02:00
Speiger d90a9ad71c Fixed that Expressions were inverted. 2022-12-16 18:10:07 +01:00
Speiger b0792532b1 A few expressions weren't supported. 2022-12-13 13:31:42 +01:00
Speiger a63defacbb Improvements to the Parsing and more options how to deal with sectioning
-Added: Sectioning of if statements are now a thing. (TESTING || VALUES)
-Added: Number Parsing is now a thing for conditions. DATE>=12
-Fixed: Logger not using println at the end.
2022-12-13 13:02:25 +01:00
Speiger 6e5e91d0bd updated readme 2022-05-21 19:45:31 +02:00
Speiger b60f4ff1fd Reduced String generation while still fixing the original bug 2022-05-21 19:45:13 +02:00
Speiger 2fe297b708 Fixed Ignore Bug 2022-05-21 19:43:35 +02:00
Speiger 9c4c33c1eb Smallbugfix 2022-05-21 19:39:50 +02:00
Speiger 4a72afdb1c Fixed Ids were limited to 10. Now it appens a random single digit number 2022-05-21 19:36:25 +02:00
Speiger d4e3da23fa Added New Feature that was really nessesary.
-Added: #ignore which allows the template process to ignore segments.
		They can be used with #if but in a ignored segment you are not allowed
to use #if/#else/#else if/#endif since it is outside of the context of
the template process. But this allows to address issues with marking
areas.
2022-05-21 14:32:02 +02:00
Speiger d3d1cb48b6 Version Bump 2021-09-28 04:37:58 +02:00
Speiger b979e9d9e8 new features.
-Added: Documentation
-Added: Function hooks that run before/while/after the process ran
2021-09-28 04:36:57 +02:00
Speiger 6f3f45d718 Got rid of all Reflection. Sadly a bit of Performance loss 2021-06-23 00:13:53 +02:00
Speiger 8937d44428 Version Bump & Added If RegexUtil crashes then program closes. 2021-06-22 19:23:49 +02:00
Speiger b165524c36 Removed Maven pom generation because not sure how to add custom maven. 2021-06-22 14:22:32 +02:00
Speiger 9aedebd317 Updated Gradle infos & Readme 2021-06-22 14:19:09 +02:00
Speiger c50e022ec2 Disabled the right file. 2021-06-21 17:02:18 +02:00
Speiger 54e66d7f53 Variouse BugFixes and additions.
-Fixed: Bugs in Mappers causing problems when parsing library.
-Fixed: IConditon should throw a error with 0 arguments.
-Added: CacheFile is now sorted so you can remove caches easier.
-Removed: Unnessesary code.
-Added: Counters.
-Added: Gitignore
2021-06-21 16:55:39 +02:00
Speiger 0f00ad1771 Logging improvements.
-Added: Improved Logging to parsing & Building
2021-01-20 04:30:18 +01:00
Speiger e752679d78 Added Debug Feature
-Added: Feature where a Mapper is no longer used at all.
2021-01-18 15:51:59 +01:00
Speiger 152dfea955 Update License 2021-01-11 17:49:54 +01:00
Speiger 7a3b6230a8 Documentation new Line fix. 2021-01-11 13:51:58 +01:00
33 changed files with 1023 additions and 167 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
# ---> Gradle
.gradle
gradle.properties
**/build/
!src/**/build/

View File

@ -1,2 +1,13 @@
arguments=
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=
jvm.arguments=
offline.mode=false
override.workspace.settings=false
show.console.view=false
show.executions.view=false

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -187,7 +187,7 @@ a file or class name and description of purpose be included on the same "printed
page" as the copyright notice for easier identification within third-party
archives.
Copyright [yyyy] [name of copyright owner]
Copyright 2021 Speiger
Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -6,14 +6,27 @@ It has a cache that keeps track of the input (if it was changed), and only cares
It is as bare bones as it can get but that also makes it flexible.
# How to install
Using Gradle:
```gradle
repositories {
maven {
url = "https://maven.speiger.com/repository/main"
}
}
dependencies {
compile 'de.speiger:Simple-Code-Generator:1.1.4'
}
```
# How to create a Template Processor
Create a class that extends TemplateProcessor.
And run the process method
SourceFolder: Is the folder that is traversed through and Files are given back.
OutputFolder: Is the folder where the Processed files get put into. If the "relativePackages" are set to true then the source folder structure is transferred.
DataFolder: Is the folder where the input cache is stored. It uses a MD5 generator to compare inputs. Right now only FileNames without extensions are stored in there. So no Duplicated FileName support for now.
Create a class that extends TemplateProcessor.
And run the process method
SourceFolder: Is the folder that is traversed through and Files are given back.
OutputFolder: Is the folder where the Processed files get put into. If the "relativePackages" are set to true then the source folder structure is transferred.
DataFolder: Is the folder where the input cache is stored. It uses a MD5 generator to compare inputs. Right now only FileNames without extensions are stored in there.
So no Duplicated FileName support for now.
##### Methods:
init: Is called when the Processes was started for the first time.

View File

@ -5,7 +5,8 @@ repositories {
}
archivesBaseName = 'Simple Code Generator'
version = '1.0'
version = '1.3.0'
apply plugin: 'maven'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
@ -21,4 +22,34 @@ task srcJar(type: Jar) {
artifacts {
archives srcJar
}
uploadArchives {
repositories.mavenDeployer {
repository(url: 'https://maven.speiger.com/repository/main') {
authentication(userName: project.properties.mavenUser, password: project.properties.mavenPassword)
}
snapshotRepository(url: 'https://maven.speiger.com/repository/main') {
authentication(userName: project.properties.mavenUser, password: project.properties.mavenPassword)
}
pom {
version = project.version
artifactId = project.archivesBaseName.replace(" ", "-")
groupId = 'de.speiger'
project {
licenses {
license {
name = 'The Apache License, Version 2.0'
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id = 'speiger'
name = 'Speiger'
}
}
}
}
}
}

1
example/cache.bin Normal file
View File

@ -0,0 +1 @@
test=ddb9367ebd61888ab31a658dd6f6df86

View File

@ -0,0 +1,53 @@
Hello this is my test
#ignore
TESTING should not be overriden
#endignore
TESTING should be overriden
#if TEST0
#ignore
TESTING should not be overriden too
#endignore
TESTING should be overriden too
#endif
#if TEST1
#ignore
TESTING should not be overriden
#endignore
TESTING should not be overriden
#endif
#iterate
#argument NUMBER 1 2 3 4 5 6 7 8 9
Lets test number NUMBER
#enditerate
#if TEST0
Lets test a true condition.
#iterate
#argument NUMBER 1 2 3 4 5 6 7 8 9
Lets test number NUMBER
#enditerate
#endif
#if TEST1
Lets test a false condition.
#iterate
#argument NUMBER 1 2 3 4 5 6 7 8 9
Lets test number NUMBER
#enditerate
#endif
Lets test stacked iterators
#iterate
#argument NUMBER1 1 2 3
#iterate
#argument NUMBER2 4 5 6
Lets test numbers NUMBER1 NUMBER2
#enditerate
#enditerate

41
example/output/test.txt Normal file
View File

@ -0,0 +1,41 @@
Hello this is my test
TESTING should not be overriden
Test2 should be overriden
TESTING should not be overriden too
Test2 should be overriden too
Lets test number 1
Lets test number 2
Lets test number 3
Lets test number 4
Lets test number 5
Lets test number 6
Lets test number 7
Lets test number 8
Lets test number 9
Lets test a true condition.
Lets test number 1
Lets test number 2
Lets test number 3
Lets test number 4
Lets test number 5
Lets test number 6
Lets test number 7
Lets test number 8
Lets test number 9
Lets test stacked iterators
Lets test numbers 1 4
Lets test numbers 1 5
Lets test numbers 1 6
Lets test numbers 2 4
Lets test numbers 2 5
Lets test numbers 2 6
Lets test numbers 3 4
Lets test numbers 3 5
Lets test numbers 3 6

View File

@ -2,11 +2,12 @@ package speiger.src.builder.base;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;
import java.util.regex.Pattern;
import speiger.src.builder.conditions.ICondition;
import speiger.src.builder.misc.IdGenerator;
import speiger.src.builder.processor.CompiledArguments;
public class ConditionedSegment
{
@ -26,23 +27,28 @@ public class ConditionedSegment
segments.add(segment);
}
public int build(Set<String> parsePool, StringBuilder builder, int baseIndex)
public int build(CompiledArguments process, StringBuilder builder, int baseIndex)
{
baseIndex += index;
int length = builder.length();
for(int i = 0,m=segments.size();i<m;i++)
{
if(segments.get(i).build(parsePool, builder, baseIndex)) break;
if(segments.get(i).build(process, builder, baseIndex)) break;
}
return builder.length() - length;
}
public static int parse(String currentLine, List<String> lines, int currentIndex, int startIndex, List<ConditionedSegment> segments) throws IllegalStateException
public static int parse(String fileName, String currentLine, List<String> lines, int currentIndex, int startIndex, IdGenerator ignoreCounter, List<ConditionedSegment> segments, List<PostSegment> postSegments) throws IllegalStateException
{
String ignoreSegmentId = ignoreCounter.getId();
ConditionedSegment segment = new ConditionedSegment(startIndex);
ICondition condition = ICondition.parse(currentLine);
ICondition condition = currentLine == null ? null : ICondition.parse(currentLine);
List<ConditionedSegment> childSegments = new ArrayList<>();
StringJoiner segmentText = new StringJoiner("\n", "\n", "");
StringJoiner segmentText = new StringJoiner("\n", (currentIndex <= 0 || includeStartNewLine(lines.get(currentIndex-1).trim())) ? "\n" : "", "");
if(currentLine == null) {
lines.set(currentIndex, ignoreSegmentId);
}
for(int i = currentIndex+1;i<lines.size();i++)
{
String s = lines.get(i);
@ -51,6 +57,7 @@ public class ConditionedSegment
{
if(trimmed.startsWith("#else if"))
{
if(currentLine == null) throw new IllegalStateException("#else if isn't working while in a ignore segment");
segment.addSegment(new Segment(segmentText.toString(), condition, childSegments));
condition = ICondition.parse(trimmed.substring(8).trim());
childSegments = new ArrayList<>();
@ -58,6 +65,7 @@ public class ConditionedSegment
}
else if(trimmed.startsWith("#else"))
{
if(currentLine == null) throw new IllegalStateException("#else isn't working while in a ignore segment");
segment.addSegment(new Segment(segmentText.toString(), condition, childSegments));
condition = ICondition.ALWAYS_TRUE;
childSegments = new ArrayList<>();
@ -65,19 +73,43 @@ public class ConditionedSegment
}
else if(trimmed.startsWith("#endif"))
{
if(currentLine == null) throw new IllegalStateException("#endif isn't working while in a ignore segment");
segment.addSegment(new Segment(segmentText.toString(), condition, childSegments));
segments.add(segment);
return i - currentIndex;
}
else if(trimmed.startsWith("#endignore"))
{
postSegments.add(new PostSegment(segmentText.toString(), ignoreSegmentId));
segments.add(segment);
return i - currentIndex;
}
else if(trimmed.startsWith("#if"))
{
i += parse(trimmed.substring(3).trim(), lines, i, segmentText.length(), childSegments);
if(currentLine == null) throw new IllegalStateException("#if isn't working while in a ignore segment");
i += parse(fileName, trimmed.substring(3).trim(), lines, i, segmentText.length(), ignoreCounter, childSegments, postSegments);
}
else if(trimmed.startsWith("#ignore"))
{
if(currentLine == null) throw new IllegalStateException("#ignore lines can't be applied Recursively");
ignoreCounter.appendId();
int prev = i;
i += parse(fileName, null, lines, i, segmentText.length(), ignoreCounter, childSegments, postSegments);
segmentText.add(lines.get(prev));
}
else if(trimmed.startsWith("#iterate")) {
SegmentIterator.iterateSegment(fileName, trimmed, lines, i, segmentText.length());
i--;
}
continue;
}
segmentText.add(s);
}
throw new IllegalStateException("Unclosed #If found!");
throw new IllegalStateException("Unclosed #If found in ["+fileName+"] at line ["+startIndex+"]");
}
static boolean includeStartNewLine(String s)
{
return !s.startsWith("#") || s.equalsIgnoreCase("#endif") || s.equalsIgnoreCase("#endignore");
}
}

View File

@ -0,0 +1,18 @@
package speiger.src.builder.base;
public class PostSegment
{
String text;
String identifier;
public PostSegment(String text, String identifier)
{
this.text = text;
this.identifier = identifier;
}
public String build(String input)
{
return input.replaceAll("\n"+identifier, text);
}
}

View File

@ -2,9 +2,9 @@ package speiger.src.builder.base;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import speiger.src.builder.conditions.ICondition;
import speiger.src.builder.processor.CompiledArguments;
public class Segment
{
@ -19,14 +19,14 @@ public class Segment
this.segments = segments;
}
public boolean build(Set<String> parsePool, StringBuilder builder, int index)
public boolean build(CompiledArguments process, StringBuilder builder, int index)
{
if(condition.isValid(parsePool))
if(condition.isValid(process))
{
builder.insert(index, text);
for(int i = 0,offset=0,m=segments.size();i<m;i++)
{
offset += segments.get(i).build(parsePool, builder, index+offset);
offset += segments.get(i).build(process, builder, index+offset);
}
return true;
}

View File

@ -0,0 +1,61 @@
package speiger.src.builder.base;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;
public class SegmentIterator {
public static void iterateSegment(String fileName, String currentLine, List<String> lines, int currentIndex, int startIndex) {
List<String[]> arguments = new ArrayList<>();
StringJoiner toIterate = new StringJoiner("\n");
int skip = 0;
int end = 1;
for(int i = currentIndex+1;i<lines.size();i++, end++)
{
String s = lines.get(i);
String trimmed = s.trim();
if(trimmed.startsWith("#"))
{
if(trimmed.startsWith("#enditerate"))
{
skip--;
if(skip < 0)
{
end++;
break;
}
}
if(trimmed.startsWith("#iterate")) skip++;
if(skip > 0)
{
toIterate.add(s);
continue;
}
if(trimmed.startsWith("#argument"))
{
arguments.add(trimmed.substring(9).trim().split(" "));
continue;
}
}
toIterate.add(s);
}
int size = arguments.get(0).length;
for(int i = 1,m=arguments.size();i<m;i++) {
if(arguments.get(i).length != size) throw new RuntimeException("Iteration arguments in file ["+fileName+"] are not equal size. Arugments="+arguments.stream().flatMap(Arrays::stream).collect(Collectors.toList()));
}
for(int i = 0;i<end;i++) {
lines.remove(currentIndex);
}
String toInsert = toIterate.toString();
for(int i = size-1;i>=1;i--) {
String temp = toInsert;
for(int j = 0;j<arguments.size();j++) {
String[] argument = arguments.get(j);
temp = temp.replace(argument[0], argument[i]);
}
lines.addAll(currentIndex, Arrays.asList(temp.split("\n", -1)));
}
}
}

View File

@ -7,21 +7,25 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;
import java.util.function.UnaryOperator;
import speiger.src.builder.mappers.IMapper;
import speiger.src.builder.misc.FileUtils;
import speiger.src.builder.misc.IdGenerator;
import speiger.src.builder.processor.CompiledArguments;
public class Template
{
String fileName;
String textFile;
List<ConditionedSegment> segments;
List<PostSegment> postSegments;
public Template(String fileName, String textFile, List<ConditionedSegment> segments)
public Template(String fileName, String textFile, List<ConditionedSegment> segments, List<PostSegment> postSegments)
{
this.fileName = fileName;
this.textFile = textFile;
this.segments = segments;
this.postSegments = postSegments;
}
public String getFileName()
@ -29,24 +33,44 @@ public class Template
return fileName;
}
public String build(Set<String> parsePool, List<UnaryOperator<String>> mappers)
public String build(CompiledArguments process, boolean printNoWork, Set<IMapper> done)
{
StringBuilder builder = new StringBuilder(textFile);
for(int i = 0,offset=0,m=segments.size();i<m;i++)
{
offset += segments.get(i).build(parsePool, builder, offset);
offset += segments.get(i).build(process, builder, offset);
}
List<IMapper> mappers = process.getMapper();
String result = builder.toString();
for(int i = 0,m=mappers.size();i<m;i++)
{
result = mappers.get(i).apply(result);
if(printNoWork)
{
String previous = result;
result = mappers.get(i).apply(result);
if(previous.equals(result))
{
done.add(mappers.get(i));
}
}
else
{
result = mappers.get(i).apply(result);
}
}
for(int i = 0,m=postSegments.size();i<m;i++)
{
result = postSegments.get(i).build(result);
}
return result;
}
public static Template parse(Path file) throws IOException
{
List<ConditionedSegment> segments = new ArrayList<ConditionedSegment>();
String fileName = FileUtils.getFileName(file.getFileName());
IdGenerator segmentIds = new IdGenerator();
List<ConditionedSegment> segments = new ArrayList<>();
List<PostSegment> postSegments = new ArrayList<>();
StringJoiner joiner = new StringJoiner("\n");
List<String> lines = Files.readAllLines(file);
for(int i = 0;i<lines.size();i++)
@ -57,7 +81,20 @@ public class Template
{
if(trimmed.startsWith("#if"))
{
i += ConditionedSegment.parse(s.trim().substring(3).trim(), lines, i, joiner.length(), segments);
i += ConditionedSegment.parse(fileName, s.trim().substring(3).trim(), lines, i, joiner.length(), segmentIds, segments, postSegments);
continue;
}
else if(trimmed.startsWith("#ignore"))
{
segmentIds.appendId();
int prev = i;
i += ConditionedSegment.parse(fileName, null, lines, i, joiner.length(), segmentIds, segments, postSegments);
joiner.add(lines.get(prev));
continue;
}
else if(trimmed.startsWith("#iterate")) {
SegmentIterator.iterateSegment(fileName, trimmed, lines, i, joiner.length());
i--;
continue;
}
else if(trimmed.startsWith("#symlink"))
@ -67,6 +104,6 @@ public class Template
}
joiner.add(s);
}
return new Template(FileUtils.getFileName(file.getFileName()), joiner.toString(), segments);
return new Template(fileName, joiner.toString(), segments, postSegments);
}
}

View File

@ -2,28 +2,32 @@ package speiger.src.builder.conditions;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import speiger.src.builder.processor.CompiledArguments;
public class AndCondition implements ICondition
{
List<ICondition> conditions = new ArrayList<>();
public AndCondition() {}
public AndCondition(ICondition base)
{
conditions.add(base);
addCondition(base);
}
public void addCondition(ICondition e)
{
if(e == null) return;
conditions.add(e);
}
@Override
public boolean isValid(Set<String> parsePool)
public boolean isValid(CompiledArguments args)
{
for(int i = 0,m=conditions.size();i<m;i++)
{
if(!conditions.get(i).isValid(parsePool))
if(!conditions.get(i).isValid(args))
{
return false;
}

View File

@ -1,6 +1,6 @@
package speiger.src.builder.conditions;
import java.util.Set;
import speiger.src.builder.processor.CompiledArguments;
public class FlagCondition implements ICondition
{
@ -14,8 +14,8 @@ public class FlagCondition implements ICondition
}
@Override
public boolean isValid(Set<String> parsePool)
public boolean isValid(CompiledArguments args)
{
return parsePool.contains(flag) != inverted;
return args.test(flag) != inverted;
}
}

View File

@ -1,61 +1,74 @@
package speiger.src.builder.conditions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import speiger.src.builder.misc.RegexUtil;
import speiger.src.builder.processor.CompiledArguments;
public interface ICondition
{
public static final Set<Character> VALID_CHARACTERS = new HashSet<>(Arrays.asList('(', ')'));
public static final ICondition ALWAYS_TRUE = T -> true;
public boolean isValid(Set<String> parsePool);
public static ICondition parse(String condition)
{
String[] elements = condition.split(" ");
List<ICondition> conditions = new ArrayList<ICondition>();
for(int i = 0;i<elements.length;i++)
{
if(elements[i].equalsIgnoreCase("&&"))
{
if(i==elements.length-1)
{
continue;
}
if(condition.isEmpty())
{
conditions.add(new AndCondition(parseSimpleCondition(elements[++i])));
}
else
{
ICondition con = conditions.get(conditions.size() - 1);
if(con instanceof AndCondition)
{
((AndCondition)con).addCondition(parseSimpleCondition(elements[++i]));
}
else
{
AndCondition replacement = new AndCondition(con);
replacement.addCondition(parseSimpleCondition(elements[++i]));
conditions.set(conditions.size()-1, replacement);
public boolean isValid(CompiledArguments args);
public static ICondition parse(List<String> elements) {
List<ICondition> conditions = new ArrayList<>();
AndCondition activeAnd = null;
for(int i = 0,m=elements.size();i<m;i++) {
String entry = elements.get(i);
if(entry.equalsIgnoreCase("(")) {
int endIndex = RegexUtil.lastIndexOf(elements, i, "(", ")");
if(endIndex == -1) throw new IllegalStateException("A Condition Closer [ ) ] is missing");
ICondition result = parse(elements.subList(i+1, endIndex));
if(activeAnd != null) activeAnd.addCondition(result);
else conditions.add(result);
i = endIndex+1;
}
else if(entry.equalsIgnoreCase("&&")) {
if(activeAnd != null) continue;
if(i != 0) {
ICondition prev = conditions.get(conditions.size()-1);
if(prev instanceof AndCondition) activeAnd = (AndCondition)prev;
else {
activeAnd = new AndCondition(prev);
conditions.set(conditions.size()-1, activeAnd);
}
}
else {
activeAnd = new AndCondition();
conditions.add(activeAnd);
}
}
else if(!elements[i].equalsIgnoreCase("||"))
{
conditions.add(parseSimpleCondition(elements[i]));
else if(entry.equalsIgnoreCase("||")) {
activeAnd = null;
}
else {
if(activeAnd != null) activeAnd.addCondition(parseCondition(entry));
else conditions.add(parseCondition(entry));
}
}
switch(conditions.size())
{
case 0: return ALWAYS_TRUE;
case 0: throw new IllegalStateException("Empty Conditions are not allowed");
case 1: return conditions.get(0);
default: return new OrCondition(conditions);
}
}
static ICondition parseSimpleCondition(String s)
public static ICondition parse(String condition)
{
return parse(Arrays.asList(RegexUtil.ensureWhitespaces(condition, VALID_CHARACTERS).split(" ")));
}
static ICondition parseCondition(String s)
{
ICondition numbers = NumberCondition.tryBuild(s);
if(numbers != null) return numbers;
return s.startsWith("!") ? new FlagCondition(s.substring(1), true) : new FlagCondition(s, false);
}
}

View File

@ -0,0 +1,115 @@
package speiger.src.builder.conditions;
import java.util.Arrays;
import java.util.Map;
import java.util.StringJoiner;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import speiger.src.builder.processor.CompiledArguments;
public class NumberCondition implements ICondition
{
private static final Pattern SCANNER = Pattern.compile(Operation.buildReggex());
String flag;
Operation op;
int number;
boolean flipped;
public NumberCondition(String flag, Operation op, int number, boolean flipped)
{
this.flag = flag;
this.op = op;
this.number = number;
this.flipped = flipped;
}
@Override
public boolean isValid(CompiledArguments args)
{
return op.matches(flipped ? number : args.get(flag), flipped ? args.get(flag) : number);
}
public static NumberCondition tryBuild(String arg)
{
Matcher match = SCANNER.matcher(arg);
if(!match.find()) return null;
int start = match.start();
int end = match.end();
Operation op = Operation.byId(arg.substring(start, end));
if(op == null) throw new IllegalArgumentException("Operation ["+arg.substring(start, end)+"] is unknown");
String key = arg.substring(0, start);
String value = arg.substring(end);
int[] result = new int[1];
if(parse(key, result)) return new NumberCondition(value, op, result[0], true);
if(parse(value, result)) return new NumberCondition(key, op, result[0], false);
throw new IllegalStateException("Neither key or value are parsable");
}
private static boolean parse(String arg, int[] output) {
try { output[0] = Integer.parseInt(arg); }
catch(Exception e) { return false;}
return true;
}
public static enum Operation
{
EQUALS("=="),
GREATER_EQUALS(">="),
GREATER(">"),
SMALLER_EQUALS("<="),
SMALLER("<"),
NOT_EQUALS("!="),
BIT_EQUALS_ALL("&="),
BIT_EQUALS_ANY("|="),
BIT_EQUALS_NOT("~=");
static final Map<String, Operation> DATA = Arrays.stream(values()).collect(Collectors.toMap(Operation::getId, Function.identity()));
String key;
private Operation(String key)
{
this.key = key;
}
public static String buildReggex()
{
StringJoiner joiner = new StringJoiner("|\\", "\\", "");
for(Operation entry : values())
{
joiner.add(entry.getId());
}
return joiner.toString();
}
public String getId()
{
return key;
}
public boolean matches(int key, int value)
{
switch(this)
{
case EQUALS: return key == value;
case NOT_EQUALS: return key != value;
case GREATER: return key > value;
case GREATER_EQUALS: return key >= value;
case SMALLER: return key < value;
case SMALLER_EQUALS: return key <= value;
case BIT_EQUALS_ALL: return (key & value) == value;
case BIT_EQUALS_ANY: return (key & value) != 0;
case BIT_EQUALS_NOT: return (key & value) == 0;
default: return true;
}
}
public static Operation byId(String key)
{
return DATA.get(key);
}
}
}

View File

@ -1,7 +1,8 @@
package speiger.src.builder.conditions;
import java.util.List;
import java.util.Set;
import speiger.src.builder.processor.CompiledArguments;
public class OrCondition implements ICondition
{
@ -13,11 +14,11 @@ public class OrCondition implements ICondition
}
@Override
public boolean isValid(Set<String> parsePool)
public boolean isValid(CompiledArguments args)
{
for(int i = 0,m=conditions.size();i<m;i++)
{
if(conditions.get(i).isValid(parsePool))
if(conditions.get(i).isValid(args))
{
return true;
}

View File

@ -1,13 +1,13 @@
package speiger.src.builder.mappers;
import java.util.function.UnaryOperator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import speiger.src.builder.misc.RegexMatcher;
import speiger.src.builder.misc.RegexUtil;
public class ArgumentMapper implements UnaryOperator<String>
public class ArgumentMapper implements IMapper
{
String searchValue;
Pattern pattern;
String replacement;
String argumentBreaker;
@ -16,6 +16,12 @@ public class ArgumentMapper implements UnaryOperator<String>
public ArgumentMapper(String pattern, String replacement, String argumentBreaker)
{
this(pattern, pattern, replacement, argumentBreaker);
}
public ArgumentMapper(String searchValue, String pattern, String replacement, String argumentBreaker)
{
this.searchValue = searchValue;
this.pattern = Pattern.compile(pattern);
this.replacement = replacement;
this.argumentBreaker = argumentBreaker;
@ -34,25 +40,43 @@ public class ArgumentMapper implements UnaryOperator<String>
return this;
}
@Override
public String getSearchValue()
{
return searchValue;
}
@Override
public String apply(String t)
{
Matcher matcher = pattern.matcher(t);
if(matcher.find())
RegexMatcher matcher = new RegexMatcher(pattern, t);
try
{
StringBuffer buffer = new StringBuffer();
do
if(matcher.find())
{
String text = RegexUtil.searchUntil(t, matcher.end()-1, braces.charAt(0), braces.charAt(1));
if(!text.isEmpty())
StringBuffer buffer = new StringBuffer();
do
{
RegexUtil.skip(matcher.appendReplacement(buffer, ""), text.length());
buffer.append(String.format(replacement, (Object[])getString(text).split(argumentBreaker)));
String text = RegexUtil.searchUntil(t, matcher.end()-1, braces.charAt(0), braces.charAt(1));
if(!text.isEmpty())
{
matcher.appendReplacement(buffer, "").skip(text.length());
buffer.append(String.format(replacement, (Object[])getString(text).split(argumentBreaker)));
}
}
while(matcher.find());
matcher.appendTail(buffer);
return apply(buffer.toString());
}
while(matcher.find());
matcher.appendTail(buffer);
return buffer.toString();
}
catch(Exception e)
{
e.printStackTrace();
}
catch(Error error)
{
System.out.println("Error with ["+pattern.pattern()+"] pattern");
throw error;
}
return t;
}

View File

@ -0,0 +1,8 @@
package speiger.src.builder.mappers;
import java.util.function.UnaryOperator;
public interface IMapper extends UnaryOperator<String>
{
public String getSearchValue();
}

View File

@ -1,13 +1,13 @@
package speiger.src.builder.mappers;
import java.util.function.UnaryOperator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import speiger.src.builder.misc.RegexMatcher;
import speiger.src.builder.misc.RegexUtil;
public class InjectMapper implements UnaryOperator<String>
public class InjectMapper implements IMapper
{
String searchValue;
Pattern pattern;
String replacement;
String braces = "()";
@ -15,6 +15,12 @@ public class InjectMapper implements UnaryOperator<String>
public InjectMapper(String pattern, String replacement)
{
this(pattern, pattern, replacement);
}
public InjectMapper(String searchValue, String pattern, String replacement)
{
this.searchValue = searchValue;
this.pattern = Pattern.compile(pattern);
this.replacement = replacement;
}
@ -32,24 +38,42 @@ public class InjectMapper implements UnaryOperator<String>
return this;
}
@Override
public String getSearchValue()
{
return searchValue;
}
@Override
public String apply(String t)
{
Matcher matcher = pattern.matcher(t);
if(matcher.find())
RegexMatcher matcher = new RegexMatcher(pattern, t);
try
{
StringBuffer buffer = new StringBuffer();
do
if(matcher.find())
{
String text = RegexUtil.searchUntil(t, matcher.end()-1, braces.charAt(0), braces.charAt(1));
if(!text.isEmpty())
StringBuffer buffer = new StringBuffer();
do
{
RegexUtil.skip(matcher.appendReplacement(buffer, ""), text.length());
buffer.append(String.format(replacement, getString(text)));
}
} while (matcher.find());
matcher.appendTail(buffer);
return buffer.toString();
String text = RegexUtil.searchUntil(t, matcher.end()-1, braces.charAt(0), braces.charAt(1));
if(!text.isEmpty())
{
matcher.appendReplacement(buffer, "").skip(text.length());
buffer.append(String.format(replacement, getString(text)));
}
} while (matcher.find());
matcher.appendTail(buffer);
return apply(buffer.toString());
}
}
catch(Exception e)
{
e.printStackTrace();
}
catch(Error error)
{
System.out.println("Error with ["+pattern.pattern()+"] pattern");
throw error;
}
return t;
}

View File

@ -1,40 +1,64 @@
package speiger.src.builder.mappers;
import java.util.function.UnaryOperator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import speiger.src.builder.misc.RegexMatcher;
import speiger.src.builder.misc.RegexUtil;
public class LineMapper implements UnaryOperator<String>
public class LineMapper implements IMapper
{
String searchValue;
Pattern pattern;
public LineMapper(String pattern)
{
this(pattern, pattern);
}
public LineMapper(String searchValue, String pattern)
{
this.searchValue = searchValue;
this.pattern = Pattern.compile(pattern, Pattern.LITERAL);
}
@Override
public String getSearchValue()
{
return searchValue;
}
@Override
public String apply(String t)
{
Matcher matcher = pattern.matcher(t);
if(matcher.find())
RegexMatcher matcher = new RegexMatcher(pattern, t);
try
{
StringBuffer buffer = new StringBuffer();
do
if(matcher.find())
{
int start = matcher.end() - 1;
int[] result = RegexUtil.findFullLine(t, start);
if(result != null)
StringBuffer buffer = new StringBuffer();
do
{
matcher.appendReplacement(buffer, pattern.pattern());
buffer.setLength(buffer.length() - (start - result[0]));
RegexUtil.skip(matcher, result[1] - start);
}
} while (matcher.find());
matcher.appendTail(buffer);
return buffer.toString();
int start = matcher.end() - 1;
int[] result = RegexUtil.findFullLine(t, start);
if(result != null)
{
matcher.appendReplacement(buffer, pattern.pattern());
buffer.setLength(buffer.length() - (start - result[0]));
matcher.skip(result[1] - start);
}
} while (matcher.find());
matcher.appendTail(buffer);
return apply(buffer.toString());
}
}
catch(Exception e)
{
e.printStackTrace();
}
catch(Error error)
{
System.out.println("Error with ["+pattern.pattern()+"] pattern");
throw error;
}
return t;
}

View File

@ -1,22 +1,47 @@
package speiger.src.builder.mappers;
import java.util.function.UnaryOperator;
import java.util.regex.Pattern;
public class SimpleMapper implements UnaryOperator<String>
public class SimpleMapper implements IMapper
{
String searchValue;
Pattern pattern;
String replacement;
public SimpleMapper(String pattern, String replacement)
{
this(pattern, pattern, replacement);
}
public SimpleMapper(String searchValue, String pattern, String replacement)
{
this.searchValue = searchValue;
this.pattern = Pattern.compile(pattern, Pattern.LITERAL);
this.replacement = replacement;
}
@Override
public String getSearchValue()
{
return searchValue;
}
@Override
public String apply(String t)
{
return pattern.matcher(t).replaceAll(replacement);
try
{
return pattern.matcher(t).replaceAll(replacement);
}
catch(Exception e)
{
e.printStackTrace();
}
catch(Error error)
{
System.out.println("Error with ["+pattern.pattern()+"] pattern");
throw error;
}
return t;
}
}

View File

@ -6,9 +6,10 @@ import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class FileUtils
{
@ -40,9 +41,11 @@ public class FileUtils
{
try(BufferedWriter writer = Files.newBufferedWriter(dataFolder.resolve("cache.bin")))
{
for(Entry<String, String> entry : mappings.entrySet())
List<String> keys = new ArrayList<String>(mappings.keySet());
keys.sort(String.CASE_INSENSITIVE_ORDER);
for(String s : keys)
{
writer.write(entry.getKey()+"="+entry.getValue());
writer.write(s+"="+mappings.get(s));
writer.newLine();
}
writer.flush();

View File

@ -0,0 +1,18 @@
package speiger.src.builder.misc;
import java.util.concurrent.atomic.AtomicInteger;
public class IdGenerator
{
AtomicInteger integer = new AtomicInteger();
public void appendId()
{
integer.incrementAndGet();
}
public String getId()
{
return "#ignoreLine"+integer.get()+"suffix";
}
}

View File

@ -0,0 +1,84 @@
package speiger.src.builder.misc;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatcher
{
Matcher match;
StringWrapper text;
public RegexMatcher(Pattern pattern, String text)
{
this.text = new StringWrapper(text);
match = pattern.matcher(this.text);
}
public boolean find()
{
return match.find();
}
public int end()
{
return match.end()+text.getOffset();
}
public RegexMatcher appendReplacement(StringBuffer sb, String replacement)
{
match.appendReplacement(sb, replacement);
return this;
}
public RegexMatcher appendTail(StringBuffer sb)
{
match.appendTail(sb);
return this;
}
public RegexMatcher skip(int amount)
{
text.offset(amount+match.end());
match.reset();
return this;
}
public static class StringWrapper implements CharSequence
{
String s;
int offset;
public StringWrapper(String s)
{
this.s = s;
}
@Override
public int length()
{
return s.length() - offset;
}
@Override
public char charAt(int index)
{
return s.charAt(index+offset);
}
@Override
public CharSequence subSequence(int start, int end)
{
return s.subSequence(start+offset, end+offset);
}
public void offset(int offset)
{
this.offset += offset;
}
public int getOffset()
{
return offset;
}
}
}

View File

@ -1,25 +1,10 @@
package speiger.src.builder.misc;
import java.lang.reflect.Field;
import java.util.regex.Matcher;
import java.util.List;
import java.util.Set;
public class RegexUtil
{
static Field LAST_POS;
public static Matcher skip(Matcher matcher, int amount)
{
try
{
LAST_POS.setInt(matcher, LAST_POS.getInt(matcher) + amount);
}
catch(Exception e)
{
e.printStackTrace();
}
return matcher;
}
public static String searchUntil(String text, int startIndex, char increase, char decrease)
{
if(text.charAt(startIndex + 1) != increase)
@ -61,17 +46,31 @@ public class RegexUtil
return new int[]{start, offset};
}
static
public static int lastIndexOf(List<String> list, int startIndex, String increase, String decrease)
{
try
if(!list.get(startIndex).equalsIgnoreCase(increase)) return -1;
int inc = 0;
for(int i = startIndex;i<list.size();i++)
{
Field field = Matcher.class.getDeclaredField("lastAppendPosition");
field.setAccessible(true);
LAST_POS = field;
}
catch(Exception e)
{
e.printStackTrace();
String entry = list.get(i);
if(entry.equalsIgnoreCase(increase)) inc++;
else if(entry.equalsIgnoreCase(decrease)) {
inc--;
if(inc <= 0) return i;
}
}
return -1;
}
}
public static String ensureWhitespaces(String s, Set<Character> set) {
StringBuilder builder = new StringBuilder(s);
for(int i = s.length()-1;i>=0;i--) {
char entry = builder.charAt(i);
if(entry != ' ' && set.contains(entry)) {
if(builder.charAt(i+1) != ' ') builder.insert(i+1, ' ');
if(builder.charAt(i-1) != ' ') builder.insert(i, ' ');
}
}
return builder.toString();
}
}

View File

@ -3,26 +3,36 @@ package speiger.src.builder.processor;
import java.io.BufferedWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Set;
import speiger.src.builder.base.Template;
import speiger.src.builder.mappers.IMapper;
public class BuildTask implements Runnable
{
Path basePath;
Template template;
TemplateProcess process;
Set<IMapper>[] mappers;
boolean silencedSuccess;
public BuildTask(Path basePath, Template template, TemplateProcess process)
public BuildTask(Path basePath, Template template, TemplateProcess process, boolean silencedSuccess, Set<IMapper>[] mappers)
{
this.basePath = basePath;
this.template = template;
this.process = process;
this.silencedSuccess = silencedSuccess;
this.mappers = mappers;
}
@Override
public void run()
{
String s = template.build(process.parsePool, process.mappers);
String s = template.build(new CompiledArguments(process), mappers != null, mappers != null ? mappers[1] : null);
if(mappers != null)
{
mappers[0].addAll(process.mappers);
}
Path path = (process.pathBuilder != null ? process.pathBuilder.apply(basePath) : basePath).resolve(process.fileName);
try
{
@ -30,17 +40,17 @@ public class BuildTask implements Runnable
}
catch(Exception e)
{
e.printStackTrace();
}
try(BufferedWriter writer = Files.newBufferedWriter(path))
{
writer.write(s);
writer.flush();
System.out.println("Created: "+process.fileName);
if(!silencedSuccess) System.out.println("Created: "+process.fileName);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,36 @@
package speiger.src.builder.processor;
import java.util.List;
import java.util.Map;
import java.util.Set;
import speiger.src.builder.mappers.IMapper;
public class CompiledArguments
{
List<IMapper> mapper;
Set<String> flags;
Map<String, Integer> flaggedValues;
public CompiledArguments(TemplateProcess process)
{
mapper = process.mappers;
flags = process.parsePool;
flaggedValues = process.parseValues;
}
public List<IMapper> getMapper()
{
return mapper;
}
public boolean test(String key)
{
return flags.contains(key);
}
public int get(String key)
{
return flaggedValues.getOrDefault(key, 0);
}
}

View File

@ -4,45 +4,67 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.UnaryOperator;
import speiger.src.builder.mappers.IMapper;
public class TemplateProcess
{
UnaryOperator<Path> pathBuilder;
String fileName;
Set<String> parsePool = new HashSet<>();
List<UnaryOperator<String>> mappers = new ArrayList<>();
Map<String, Integer> parseValues = new HashMap<>();
List<IMapper> mappers = new ArrayList<>();
public TemplateProcess(String fileName)
{
this.fileName = fileName;
}
public void setPathBuilder(UnaryOperator<Path> pathBuilder)
public TemplateProcess setPathBuilder(UnaryOperator<Path> pathBuilder)
{
this.pathBuilder = pathBuilder;
return this;
}
public void addFlags(String...flags)
public TemplateProcess addFlags(String...flags)
{
parsePool.addAll(Arrays.asList(flags));
return this;
}
public void addFlags(Collection<String> flags)
public TemplateProcess addFlags(Collection<String> flags)
{
parsePool.addAll(flags);
return this;
}
public void addMapper(UnaryOperator<String> mapper)
public TemplateProcess addValue(String key, int value)
{
parseValues.put(key, value);
return this;
}
public TemplateProcess addValues(Map<String, Integer> values)
{
parseValues.putAll(values);
return this;
}
public TemplateProcess addMapper(IMapper mapper)
{
mappers.add(mapper);
return this;
}
public void addMappers(Collection<UnaryOperator<String>> mappers)
public TemplateProcess addMappers(Collection<IMapper> mappers)
{
this.mappers.addAll(mappers);
return this;
}
}

View File

@ -3,15 +3,20 @@ package speiger.src.builder.processor;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import speiger.src.builder.base.Template;
import speiger.src.builder.mappers.IMapper;
import speiger.src.builder.misc.FileUtils;
public abstract class TemplateProcessor
@ -19,23 +24,79 @@ public abstract class TemplateProcessor
Path sourceFolder;
Path outputFolder;
Path dataFolder;
boolean silencedSuccess;
boolean init = false;
public TemplateProcessor(Path sourceFolder, Path outputFolder, Path dataFolder)
{
this(false, sourceFolder, outputFolder, dataFolder);
}
public TemplateProcessor(boolean silencedSuccess, Path sourceFolder, Path outputFolder, Path dataFolder)
{
this.silencedSuccess = silencedSuccess;
this.sourceFolder = sourceFolder;
this.outputFolder = outputFolder;
this.dataFolder = dataFolder;
}
/**
* Function that is called before the initial run of the template processor.
* It is only called once to basically initialize the program and then run as needed.
*/
protected abstract void init();
/**
* Function that decides which file is going to be used and which not. Basically black/white list as needed
* @param fileName FileName without folder structure. Since this is designed to have 0 duplicated file names.
* @return true if it is valid to be processed or false if it isn't
*/
protected abstract boolean isFileValid(Path fileName);
/**
* Main function that processes a filename to its target
* @param fileName name of the file that should be processed without the type of file. (.template or .json etc etc)
* @param process all modifications to the file that should be executed
*/
public abstract void createProcesses(String fileName, Consumer<TemplateProcess> process);
/**
* Function that asks if the folder structure on the source folder should be kept or not
* @return true if the source-structure should be kept or flattened.
*/
protected abstract boolean relativePackages();
/**
* Function that tests if a Mapper was used or not. Useful for small scale projects that barely have any mappers
* but sadly more like to cause not needed warnings for large scale projects.
* @return true if it should be enabled
*/
protected abstract boolean debugUnusedMappers();
/**
* Function called before the Template Processor runs.
* But after init is called and All files are loaded in and the task queue is already ready.
*/
protected void beforeStart() {}
/**
* Function that is called while the template generation is running and all after the File hashes for the memory are being generated.
* If you have anything to do while the processor is running this would be the ideal time to do it.
*/
protected void whileProcessing() {}
/**
* Function that is being called after the template processor is called and after the file cache has been updated
* Basically just before "Saved Changes" is called.
*/
protected void afterFinish() {}
protected Path getSourceFolder() { return sourceFolder; }
protected Path getOutputFolder() { return outputFolder; }
protected Path getDataFolder() { return dataFolder; }
protected boolean isSilencedSuccess() { return silencedSuccess; }
@SuppressWarnings("unchecked")
public final boolean process(boolean force) throws IOException, InterruptedException
{
if(!init)
@ -50,18 +111,24 @@ public abstract class TemplateProcessor
System.out.println("Nothing has changed");
return false;
}
AtomicLong[] counters = new AtomicLong[]{new AtomicLong(), new AtomicLong(), new AtomicLong()};
final boolean relative = relativePackages();
Set<IMapper>[] mappers = debugUnusedMappers() ? new Set[]{Collections.synchronizedSet(new HashSet<>()), Collections.synchronizedSet(new HashSet<>())} : null;
ThreadPoolExecutor service = (ThreadPoolExecutor)Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
service.setKeepAliveTime(10, TimeUnit.MILLISECONDS);
service.allowCoreThreadTimeOut(true);
beforeStart();
service.submit(() -> {
for(int i = 0,m=pathsLeft.size();i<m;i++)
{
Path path = pathsLeft.get(i);
try
{
long startTime = System.currentTimeMillis();
Template template = Template.parse(path);
createProcesses(FileUtils.getFileName(path), T -> service.execute(new BuildTask(relative ? outputFolder.resolve(sourceFolder.relativize(path).getParent()) : outputFolder, template, T)));
counters[2].addAndGet(System.currentTimeMillis() - startTime);
counters[1].addAndGet(1);
createProcesses(FileUtils.getFileName(path), T -> {service.execute(new BuildTask(relative ? outputFolder.resolve(sourceFolder.relativize(path).getParent()) : outputFolder, template, T, silencedSuccess, mappers));counters[0].addAndGet(1);});
}
catch(Exception e)
{
@ -76,13 +143,23 @@ public abstract class TemplateProcessor
Path path = pathsLeft.get(i);
existing.put(FileUtils.getFileName(path), FileUtils.getMD5String(path));
}
whileProcessing();
while(service.getActiveCount() > 0)
{
Thread.sleep(10);
}
System.out.println("Finished Tasks: "+(System.currentTimeMillis() - start)+"ms");
if(mappers != null && mappers[0].size() != mappers[1].size())
{
mappers[0].removeAll(mappers[1]);
for(IMapper mapper : mappers[0])
{
System.out.println("Mapper ["+mapper.getSearchValue()+"] is not used in the Entire Build Process");
}
}
System.out.println("Finished Building ["+counters[0].get()+"] Files from ["+counters[1].get()+"] in "+(System.currentTimeMillis() - start)+"ms (Template Parsing: "+counters[2].get()+"ms (avg: "+((counters[2].get() / Math.max(1D, counters[1].get())))+"ms)");
FileUtils.saveMappings(existing, dataFolder);
System.out.print("Saved Changes");
afterFinish();
System.out.println("Saved Changes");
return true;
}
}

View File

@ -0,0 +1,68 @@
package example;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.Consumer;
import speiger.src.builder.mappers.SimpleMapper;
import speiger.src.builder.processor.TemplateProcess;
import speiger.src.builder.processor.TemplateProcessor;
public class ExampleBuilder extends TemplateProcessor
{
public static void main(String...args)
{
try
{
new ExampleBuilder().process(true);
}
catch(IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch(InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ExampleBuilder()
{
super(Paths.get("example/input"), Paths.get("example/output"), Paths.get("example"));
}
@Override
protected void init()
{
}
@Override
protected boolean isFileValid(Path fileName)
{
return true;
}
@Override
public void createProcesses(String fileName, Consumer<TemplateProcess> process)
{
process.accept(new TemplateProcess(fileName+".txt").addFlags("TEST0").addMapper(new SimpleMapper("TESTING", "Test2")));
}
@Override
protected boolean relativePackages()
{
return false;
}
@Override
protected boolean debugUnusedMappers()
{
return false;
}
}