diff --git a/dumpAst/src/main/jastadd/DumpAst.relast b/dumpAst/src/main/jastadd/DumpAst.relast index 13d438ede1180d96e49a780b817e5db0ffff3050..7a3e31f2cfc389af9e9cd14228697b59c5929dc1 100644 --- a/dumpAst/src/main/jastadd/DumpAst.relast +++ b/dumpAst/src/main/jastadd/DumpAst.relast @@ -1,7 +1,9 @@ DumpAst ::= DumpNode* <PackageName> BuildConfig PrintConfig ; rel DumpAst.RootNode -> DumpNode ; -BuildConfig ::= <TypeIgnore> <TokenIgnore> <ChildIgnore> <AttributeInclude> <NonterminalAttributeInclude> <RelationIgnore> <IncludeEmptyString:boolean> <Debug:boolean> ; +BuildConfig ::= GlobalPatternCollection:PatternCollection ExcludeTypePattern:TypePatternCollectionMapping* IncludeTypePattern:TypePatternCollectionMapping* <TypeIgnorePattern> <IncludeEmptyString:boolean> <Debug:boolean> ; +TypePatternCollectionMapping ::= <TypeRegex> PatternCollection ; +PatternCollection ::= <TokenPattern> <ChildPattern> <RelationPattern> <AttributePattern> <NonterminalAttributePattern> ; PrintConfig ::= <Scale:double> <Version> Header* ; Header ::= <Value> ; DumpNode ::= <Name> <Label> <Object:Object> <Invisible:boolean> DumpChildNode* DumpToken* DumpRelation* /InvisiblePath/ ; diff --git a/dumpAst/src/main/jastadd/Generation.jadd b/dumpAst/src/main/jastadd/GenerationBackend.jadd similarity index 66% rename from dumpAst/src/main/jastadd/Generation.jadd rename to dumpAst/src/main/jastadd/GenerationBackend.jadd index d6a2a37f358923affb9fae608adc8dc8ea96b5dc..c59d1cc444f46b65ba76f6e9161138ee1f991780 100644 --- a/dumpAst/src/main/jastadd/Generation.jadd +++ b/dumpAst/src/main/jastadd/GenerationBackend.jadd @@ -1,211 +1,3 @@ -import java.lang.String;aspect GenerationFrontend { - public class Dumper { - /** - * Prepare to read in the given object. Use the <code>dump*</code> methods to actually dump its content. - * @param obj the object to dump - * @return a builder to adjust dump options - */ - public static DumpBuilder read(Object obj) { - return new DumpBuilder(obj); - } - } - public enum SkinParamBooleanSetting { - /** Print in grayscale? */ - Monochrome, - /** Use shadows? */ - Shadowing, - /** Use handwritten style? */ - Handwritten - } - public enum SkinParamStringSetting { - /** Set color of background */ - backgroundColor - } - public class DumpBuilder { - private Object target; - private String packageName; - private DumpAst result; - private BuildConfig buildConfig = new BuildConfig(); - private PrintConfig printConfig = new PrintConfig(); - - protected DumpBuilder(Object target) { - this.target = target; - printConfig.setScale(1); - printConfig.setVersion(readVersion()); - } - - /** - * Add debug information in dumped content, mainly version numbers. - * @return this - */ - public DumpBuilder enableDebug() { - buildConfig.setDebug(true); - return this; - } - - /** - * Include empty strings for all tokens - * @return this - */ - public DumpBuilder includeEmptyStringsOnTokens() { - buildConfig.setIncludeEmptyString(true); - return this; - } - - /** - * Disable all objects with types matching at least one of the given regex strings. - * Disabled objects won't be included in any output. However, their children are still processed. - * @param regexes patterns to match type names - * @return this - * @see java.util.regex.Pattern#compile(java.lang.String) - */ - public DumpBuilder disableTypes(String... regexes) { - updateRegexes(() -> buildConfig.getTypeIgnore(), s -> buildConfig.setTypeIgnore(s), regexes); - return this; - } - - /** - * Exclude tokens and their value if the token name matches at least one of the given regex strings. - * @param regexes regex patterns to match token names - * @return this - * @see java.util.regex.Pattern#compile(java.lang.String) - */ - public DumpBuilder excludeTokens(String... regexes) { - updateRegexes(() -> buildConfig.getTokenIgnore(), s -> buildConfig.setTokenIgnore(s), regexes); - return this; - } - - /** - * Include attributes (as tokens) and their value if the attribute name matches at least on of the given regex strings. - * @param regexes regex patterns to match token names - * @return this - * @see java.util.regex.Pattern#compile(java.lang.String) - */ - public DumpBuilder includeAttributes(String... regexes) { - updateRegexes(() -> buildConfig.getAttributeInclude(), s -> buildConfig.setAttributeInclude(s), regexes); - return this; - } - - /** - * Includes nonterminal-attributes (as children) and their values if - * their attribute name matches at least on of the given regex strings. - * <br> - * <b>Note</b>: A leading "get" and a trailing "List" in the name will be removed prior to matching. - * Thus, it should not be contained in the regex either. - * @param regexes regex patterns to match token names - * @return this - * @see java.util.regex.Pattern#compile(java.lang.String) - */ - public DumpBuilder includeNonterminalAttributes(String... regexes) { - updateRegexes(() -> buildConfig.getNonterminalAttributeInclude(), s -> buildConfig.setNonterminalAttributeInclude(s), regexes); - return this; - } - - /** - * Exclude every child whose name (i.e., context) matches at least on of the given regex strings. - * This means, that the complete object and its (transitive) children will never be included in any output. - * @param regexes regex patterns to match child names - * @return this - * @see java.util.regex.Pattern#compile(java.lang.String) - */ - public DumpBuilder excludeChildren(String... regexes) { - updateRegexes(() -> buildConfig.getChildIgnore(), s -> buildConfig.setChildIgnore(s), regexes); - return this; - } - /** - * Exclude every relation whose role-name matches at least on of the given regex strings. - * This means two things: a) the relation to any potential target object(s) is never shown, and b) the target - * object(s) are not shown unless they are reachable by another relation or by containment. - * @param regexes regex patterns to match child names - * @return this - * @see java.util.regex.Pattern#compile(java.lang.String) - */ - public DumpBuilder excludeRelations(String... regexes) { - updateRegexes(() -> buildConfig.getRelationIgnore(), s -> buildConfig.setRelationIgnore(s), regexes); - return this; - } - - private void updateRegexes(java.util.function.Supplier<String> getter, java.util.function.Consumer<String> setter, String... values) { - for (String value : values) { - if (getter.get().isEmpty()) { - setter.accept(value); - } else { - setter.accept(getter.get() + "|" + value); - } - } - } - - public DumpBuilder customPreamble(String option) { - printConfig.addHeader(new Header(option)); - return this; - } - - public DumpBuilder skinParam(SkinParamStringSetting setting, String value) { - customPreamble("skinparam " + setting.toString() + " " + value); - return this; - } - public DumpBuilder skinParam(SkinParamBooleanSetting setting, boolean value) { - customPreamble("skinparam " + setting.toString() + " " + value); - return this; - } - - public DumpBuilder setScale(double value) { - printConfig.setScale(value); - return this; - } - - private String readVersion() { - try { - java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("dumpAstVersion"); - return resources.getString("version"); - } catch (java.util.MissingResourceException e) { - return "version ?"; - } - } - - protected DumpAst build() { - if (result == null) { - result = new DumpAst(); - result.setPackageName(this.packageName == null ? this.target.getClass().getPackage().getName() : this.packageName); - result.setBuildConfig(this.buildConfig); - result.setPrintConfig(this.printConfig); - try { - result.transform(new TransformationTransferInformation(), this.target); - } catch (java.lang.reflect.InvocationTargetException e) { - throw new RuntimeException("Could not transform :(", e); - } catch (IllegalAccessException e) { - throw new RuntimeException("Could not transform :(", e); - } catch (NoSuchMethodException e) { - throw new RuntimeException("Could not transform :(", e); - } - } - return result; - } - - /** - * Write out content as plantuml source code. - * @param destination path of destination file - * @return this - * @throws java.io.IOException if an I/O error happend during opening or writing in that file - */ - public DumpBuilder dumpAsSource(java.nio.file.Path destination) throws java.io.IOException { - String content = build().toPlantUml(); - try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) { - writer.write(content); - } - return this; - } - - public DumpBuilder dumpAsYaml(java.nio.file.Path destination, boolean prependCreationComment) throws java.io.IOException { - String content = build().toYaml(prependCreationComment); - try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) { - writer.write(content); - } - return this; - } - } -} - aspect GenerationBackend { class DumpAst { private enum Source { @@ -238,6 +30,7 @@ aspect GenerationBackend { return null; } DumpNode node = tti.transformed.get(obj); + String objClassName = obj.getClass().getSimpleName(); if (node != null) { if (source == Source.RELATION) { return node; @@ -247,7 +40,7 @@ aspect GenerationBackend { } else { node = new DumpNode(); node.setObject(obj); - node.setLabel(obj.getClass().getSimpleName() + "@" + obj.hashCode()); + node.setLabel(objClassName + "@" + obj.hashCode()); node.setName("node" + tti.transformed.size()); tti.transformed.put(obj, node); this.addDumpNode(node); @@ -258,7 +51,7 @@ aspect GenerationBackend { tti.relationTargetsUnprocessed.put(node, true); return node; } - if (source == Source.INVISIBLE_PARENT || matches(getBuildConfig().typeIgnorePattern(), obj.getClass().getSimpleName())) { + if (source == Source.INVISIBLE_PARENT || !isTypeEnabled(objClassName)) { node.setInvisible(true); } final ClassAnalysisResult car = analyzeClass(obj.getClass()); @@ -266,7 +59,7 @@ aspect GenerationBackend { for (SingleChildMethod singleChildMethod : car.singleChildMethods()) { Object target = singleChildMethod.getMethod().invoke(obj); String childName = singleChildMethod.getName(); - DumpNode targetNode = transform(tti, target, nextSource(source, matches(getBuildConfig().childIgnorePattern(), childName))); + DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName))); if (target != null && targetNode != null) { DumpNormalChildNode normalChild = new DumpNormalChildNode(); normalChild.setName(childName); @@ -281,7 +74,7 @@ aspect GenerationBackend { DumpListChildNode listChild = new DumpListChildNode(); listChild.setComputed(listChildMethod.isNTAListChildMethod()); String childName = listChildMethod.getName(); - boolean shouldBeInvisisble = matches(getBuildConfig().childIgnorePattern(), childName); + boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName); listChild.setName(childName); for (Object target : targetList) { DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble)); @@ -354,6 +147,7 @@ aspect GenerationBackend { syn nta ClassAnalysisResult DumpAst.analyzeClass(java.lang.Class<?> clazz) { ClassAnalysisResult result = new ClassAnalysisResult(); + String clazzName = clazz.getSimpleName(); for (java.lang.reflect.Method method : clazz.getMethods()) { for (java.lang.annotation.Annotation annotation : method.getAnnotations()) { String canonicalName = annotation.annotationType().getCanonicalName(); @@ -377,7 +171,7 @@ aspect GenerationBackend { normalSingleChildMethod.setName(optChildName); result.addAnalysedMethod(normalSingleChildMethod); } catch (NoSuchMethodException e) { - System.err.println("Could not find getter for Opt-child " + optChildName + " in " + clazz.getName()); + System.err.println("Could not find getter for Opt-child " + optChildName + " in " + clazzName); throw new RuntimeException(e); } break; @@ -396,7 +190,7 @@ aspect GenerationBackend { try { java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName); // normal get + token-name -> singleRelation - if (!matches(getBuildConfig().relationIgnorePattern(), relationName)) { + if (isRelationEnabled(clazzName, relationName)) { SingleRelationMethod singleRelationMethod = new SingleRelationMethod(); singleRelationMethod.setMethod(relationMethod); singleRelationMethod.setName(relationName); @@ -410,7 +204,7 @@ aspect GenerationBackend { try { java.lang.reflect.Method relationMethod = clazz.getMethod("get" + relationName + "List"); // normal get + token-name + "List" -> listRelation - if (!matches(getBuildConfig().relationIgnorePattern(), relationName)) { + if (isRelationEnabled(clazzName, relationName)) { ListRelationMethod listRelationMethod = new ListRelationMethod(); listRelationMethod.setMethod(relationMethod); listRelationMethod.setName(relationName); @@ -421,7 +215,7 @@ aspect GenerationBackend { // ignore, but we know this is probably not a relation at all } } - if (!matches(getBuildConfig().tokenIgnorePattern(), tokenName)) { + if (isTokenEnabled(clazzName, tokenName)) { IntrinsicTokenMethod tokenMethod = new IntrinsicTokenMethod(); tokenMethod.setMethod(method); tokenMethod.setName(tokenName); @@ -440,7 +234,7 @@ aspect GenerationBackend { if (attributeName.endsWith("List")) { attributeName = attributeName.substring(0, attributeName.length() - 4); } - if (matches(getBuildConfig().ntaIncludePattern(), attributeName)) { + if (isNonterminalAttributeEnabled(clazzName, attributeName)) { if (Iterable.class.isAssignableFrom(method.getReturnType())) { NTAListChildMethod ntaListChildMethod = new NTAListChildMethod(); ntaListChildMethod.setMethod(method); @@ -453,7 +247,7 @@ aspect GenerationBackend { result.addAnalysedMethod(ntaSingleChildMethod); } } - } else if (matches(getBuildConfig().attributeIncludePattern(), attributeName)) { + } else if (isAttributeEnabled(clazzName, attributeName)) { // normal attribute AttributeMethod attributeMethod = new AttributeMethod(); attributeMethod.setMethod(method); @@ -475,12 +269,32 @@ aspect GenerationBackend { return Character.toUpperCase(s.charAt(0)) + s.substring(1); } - syn java.util.regex.Pattern BuildConfig.typeIgnorePattern() = java.util.regex.Pattern.compile(getTypeIgnore()); - syn java.util.regex.Pattern BuildConfig.childIgnorePattern() = java.util.regex.Pattern.compile(getChildIgnore()); - syn java.util.regex.Pattern BuildConfig.tokenIgnorePattern() = java.util.regex.Pattern.compile(getTokenIgnore()); - syn java.util.regex.Pattern BuildConfig.attributeIncludePattern() = java.util.regex.Pattern.compile(getAttributeInclude()); - syn java.util.regex.Pattern BuildConfig.ntaIncludePattern() = java.util.regex.Pattern.compile(getNonterminalAttributeInclude()); - syn java.util.regex.Pattern BuildConfig.relationIgnorePattern() = java.util.regex.Pattern.compile(getRelationIgnore()); + // TODO: add new attributes for: {token,child,relation,attribute,nta}Enabled(String parentType, String name). 1) just move implementation into this attribute. 2) add include/exclude on type-level to it. + syn boolean DumpAst.isTypeEnabled(String typeName) { + return !matches(getBuildConfig().typeIgnorePattern(), typeName); + } + syn boolean DumpAst.isTokenEnabled(String parentType, String tokenName) { + return !matches(getBuildConfig().getGlobalPatternCollection().tokenIgnorePattern(), tokenName); + } + syn boolean DumpAst.isChildEnabled(String parentType, String childName) { + return !matches(getBuildConfig().getGlobalPatternCollection().childIgnorePattern(), childName); + } + syn boolean DumpAst.isRelationEnabled(String parentType, String relationName) { + return !matches(getBuildConfig().getGlobalPatternCollection().relationIgnorePattern(), relationName); + } + syn boolean DumpAst.isAttributeEnabled(String parentType, String attributeName) { + return matches(getBuildConfig().getGlobalPatternCollection().attributeIncludePattern(), attributeName); + } + syn boolean DumpAst.isNonterminalAttributeEnabled(String parentType, String ntaName) { + return matches(getBuildConfig().getGlobalPatternCollection().ntaIncludePattern(), ntaName); + } + + syn java.util.regex.Pattern BuildConfig.typeIgnorePattern() = java.util.regex.Pattern.compile(getTypeIgnorePattern()); + syn java.util.regex.Pattern PatternCollection.childIgnorePattern() = java.util.regex.Pattern.compile(getChildPattern()); + syn java.util.regex.Pattern PatternCollection.tokenIgnorePattern() = java.util.regex.Pattern.compile(getTokenPattern()); + syn java.util.regex.Pattern PatternCollection.attributeIncludePattern() = java.util.regex.Pattern.compile(getAttributePattern()); + syn java.util.regex.Pattern PatternCollection.ntaIncludePattern() = java.util.regex.Pattern.compile(getNonterminalAttributePattern()); + syn java.util.regex.Pattern PatternCollection.relationIgnorePattern() = java.util.regex.Pattern.compile(getRelationPattern()); static boolean ASTNode.matches(java.util.regex.Pattern p, String input) { return p.matcher(input).matches(); } diff --git a/dumpAst/src/main/jastadd/GenerationFrontend.jadd b/dumpAst/src/main/jastadd/GenerationFrontend.jadd new file mode 100644 index 0000000000000000000000000000000000000000..b6815cef840deb549085fdb2ce28f94f5f2758f6 --- /dev/null +++ b/dumpAst/src/main/jastadd/GenerationFrontend.jadd @@ -0,0 +1,314 @@ +aspect GenerationFrontend { + public class Dumper { + /** + * Prepare to read in the given object. Use the <code>dump*</code> methods to actually dump its content. + * @param obj the object to dump + * @return a builder to adjust dump options + */ + public static DumpBuilder read(Object obj) { + return new DumpBuilder(obj); + } + } + public enum SkinParamBooleanSetting { + /** Print in grayscale? */ + Monochrome, + /** Use shadows? */ + Shadowing, + /** Use handwritten style? */ + Handwritten + } + public enum SkinParamStringSetting { + /** Set color of background */ + backgroundColor + } + +/** + * Building a dump. + * <p> + * + * <h3>Inclusion and Exclusion of Types</h3> + * Types can be only be disabled, see {@link #disableTypes(String[])}. + * + * <h3>Inclusion and Exclusion of Childrens, tokens and relations</h3> + * Childrens, tokens and relations are included by default. + * This can be changed using exclusions and inclusion, both in general and per-type. + * They are applied in the following order making later conditions take precedence over the first ones. + * <ol> + * <li>Include everything as default. + * <li>Exclude general. + * <li>Include per type. + * <li>Exclude per type. + * </ol> + * + * <h3>Inclusion and Exclusion of Attributes</h3> + * Attributes are excluded by default, i.e., not shown. + * This can be changed using inclusions and exclusions, both in general and per-type. + * They are applied in the following order making later conditions take precedence over the first ones. + * <ol> + * <li> Exclude everything as default. + * <li> Include general. + * <li> Exclude per type. + * <li> Include per type + * </ol> + */ +public class DumpBuilder { + private final Object target; + private String packageName; + private DumpAst result; + private final BuildConfig buildConfig; + private final PrintConfig printConfig; + + protected DumpBuilder(Object target) { + this.target = target; + buildConfig = new BuildConfig(); + buildConfig.setGlobalPatternCollection(new PatternCollection()); + printConfig = new PrintConfig(); + printConfig.setScale(1); + printConfig.setVersion(readVersion()); + } + + /** + * Add debug information in dumped content, mainly version numbers. + * @return this + */ + public DumpBuilder enableDebug() { + buildConfig.setDebug(true); + return this; + } + + /** + * Include empty strings for all tokens + * @return this + */ + public DumpBuilder includeEmptyStringsOnTokens() { + buildConfig.setIncludeEmptyString(true); + return this; + } + + /** + * Disable all objects with types matching at least one of the given regex strings. + * Disabled objects won't be included in any output. However, their children are still processed. + * <p> + * See {@link DumpBuilder} for details on inclusion and exclusion precedence. + * @param regexes patterns to match type names + * @return this + * @see java.util.regex.Pattern#compile(java.lang.String) + */ + public DumpBuilder disableTypes(String... regexes) { + updateRegexes(() -> buildConfig.getTypeIgnorePattern(), + s -> buildConfig.setTypeIgnorePattern(s), + regexes); + return this; + } + + /** + * Exclude tokens and their value if the token name matches at least one of the given regex strings. + * <p> + * See {@link DumpBuilder} for details on inclusion and exclusion precedence. + * @param regexes regex patterns to match token names + * @return this + * @see java.util.regex.Pattern#compile(java.lang.String) + */ + public DumpBuilder excludeTokens(String... regexes) { + updateRegexes(() -> buildConfig.getGlobalPatternCollection().getTokenPattern(), + s -> buildConfig.getGlobalPatternCollection().setTokenPattern(s), + regexes); + return this; + } + + /** TODO: document, implement, sort */ + public DumpBuilder excludeTokensFor(String typeRegex, String... regexes) { + return this; + } + + /** TODO: document, implement, sort */ + public DumpBuilder excludeChildrenFor(String typeRegex, String... regexes) { + return this; + } + + /** TODO: document, implement, sort */ + public DumpBuilder excludeRelationsFor(String typeRegex, String... regexes) { + return this; + } + + /** TODO: document, implement, sort */ + public DumpBuilder excludeAttributesFor(String typeRegex, String... regexes) { + return this; + } + + /** TODO: document, implement, sort */ + public DumpBuilder excludeNonterminalAttributesFor(String typeRegex, String... regexes) { + return this; + } + + /** TODO: document, implement, sort */ + public DumpBuilder includeTokensFor(String typeRegex, String... regexes) { + return this; + } + + /** TODO: document, implement, sort */ + public DumpBuilder includeChildrenFor(String typeRegex, String... regexes) { + return this; + } + + /** TODO: document, implement, sort */ + public DumpBuilder includeRelationsFor(String typeRegex, String... regexes) { + return this; + } + + /** TODO: document, implement, sort */ + public DumpBuilder includeAttributesFor(String typeRegex, String... regexes) { + return this; + } + + /** TODO: document, implement, sort */ + public DumpBuilder includeNonterminalAttributesFor(String typeRegex, String... regexes) { + return this; + } + + /** + * Include attributes (as tokens) and their value if the attribute name matches at least on of the given regex strings. + * <p> + * See {@link DumpBuilder} for details on inclusion and exclusion precedence. + * @param regexes regex patterns to match token names + * @return this + * @see java.util.regex.Pattern#compile(java.lang.String) + */ + public DumpBuilder includeAttributes(String... regexes) { + updateRegexes(() -> buildConfig.getGlobalPatternCollection().getAttributePattern(), + s -> buildConfig.getGlobalPatternCollection().setAttributePattern(s), + regexes); + return this; + } + + /** + * Includes nonterminal-attributes (as children) and their values if + * their attribute name matches at least on of the given regex strings. + * <br> + * <b>Note</b>: A leading "get" and a trailing "List" in the name will be removed prior to matching. + * Thus, it should not be contained in the regex either. + * <p> + * See {@link DumpBuilder} for details on inclusion and exclusion precedence. + * @param regexes regex patterns to match token names + * @return this + * @see java.util.regex.Pattern#compile(java.lang.String) + */ + public DumpBuilder includeNonterminalAttributes(String... regexes) { + updateRegexes(() -> buildConfig.getGlobalPatternCollection().getNonterminalAttributePattern(), + s -> buildConfig.getGlobalPatternCollection().setNonterminalAttributePattern(s), + regexes); + return this; + } + + /** + * Exclude every child whose name (i.e., context) matches at least on of the given regex strings. + * This means, that the complete object and its (transitive) children will never be included in any output. + * <p> + * See {@link DumpBuilder} for details on inclusion and exclusion precedence. + * @param regexes regex patterns to match child names + * @return this + * @see java.util.regex.Pattern#compile(java.lang.String) + */ + public DumpBuilder excludeChildren(String... regexes) { + updateRegexes(() -> buildConfig.getGlobalPatternCollection().getChildPattern(), + s -> buildConfig.getGlobalPatternCollection().setChildPattern(s), + regexes); + return this; + } + /** + * Exclude every relation whose role-name matches at least on of the given regex strings. + * This means two things: a) the relation to any potential target object(s) is never shown, and b) the target + * object(s) are not shown unless they are reachable by another relation or by containment. + * <p> + * See {@link DumpBuilder} for details on inclusion and exclusion precedence. + * @param regexes regex patterns to match child names + * @return this + * @see java.util.regex.Pattern#compile(java.lang.String) + */ + public DumpBuilder excludeRelations(String... regexes) { + updateRegexes(() -> buildConfig.getGlobalPatternCollection().getRelationPattern(), + s -> buildConfig.getGlobalPatternCollection().setRelationPattern(s), + regexes); + return this; + } + + private void updateRegexes(java.util.function.Supplier<String> getter, java.util.function.Consumer<String> setter, String... values) { + for (String value : values) { + if (getter.get().isEmpty()) { + setter.accept(value); + } else { + setter.accept(getter.get() + "|" + value); + } + } + } + + public DumpBuilder customPreamble(String option) { + printConfig.addHeader(new Header(option)); + return this; + } + + public DumpBuilder skinParam(SkinParamStringSetting setting, String value) { + customPreamble("skinparam " + setting.toString() + " " + value); + return this; + } + public DumpBuilder skinParam(SkinParamBooleanSetting setting, boolean value) { + customPreamble("skinparam " + setting.toString() + " " + value); + return this; + } + + public DumpBuilder setScale(double value) { + printConfig.setScale(value); + return this; + } + + private String readVersion() { + try { + java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("dumpAstVersion"); + return resources.getString("version"); + } catch (java.util.MissingResourceException e) { + return "version ?"; + } + } + + protected DumpAst build() { + if (result == null) { + result = new DumpAst(); + result.setPackageName(this.packageName == null ? this.target.getClass().getPackage().getName() : this.packageName); + result.setBuildConfig(this.buildConfig); + result.setPrintConfig(this.printConfig); + try { + result.transform(new TransformationTransferInformation(), this.target); + } catch (java.lang.reflect.InvocationTargetException e) { + throw new RuntimeException("Could not transform :(", e); + } catch (IllegalAccessException e) { + throw new RuntimeException("Could not transform :(", e); + } catch (NoSuchMethodException e) { + throw new RuntimeException("Could not transform :(", e); + } + } + return result; + } + + /** + * Write out content as plantuml source code. + * @param destination path of destination file + * @return this + * @throws java.io.IOException if an I/O error happend during opening or writing in that file + */ + public DumpBuilder dumpAsSource(java.nio.file.Path destination) throws java.io.IOException { + String content = build().toPlantUml(); + try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) { + writer.write(content); + } + return this; + } + + public DumpBuilder dumpAsYaml(java.nio.file.Path destination, boolean prependCreationComment) throws java.io.IOException { + String content = build().toYaml(prependCreationComment); + try (java.io.Writer writer = java.nio.file.Files.newBufferedWriter(destination)) { + writer.write(content); + } + return this; + } + } +} diff --git a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java index fcb3b16d4378d64052ea88df14d63d755c988b70..5725e0db228d7e3b237172ecf7bd94936990eaf2 100644 --- a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java +++ b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java @@ -55,7 +55,6 @@ public class Compiler extends AbstractCompiler { } public static void main(String[] args) { - System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager"); System.setProperty("mustache.debug", "true"); try { new Compiler().run(args); @@ -96,7 +95,7 @@ public class Compiler extends AbstractCompiler { new BooleanOption("help", "Print usage and exit.") .defaultValue(false)); optionVersion = addOption( - new BooleanOption("help", "Print version and exit.") + new BooleanOption("version", "Print version and exit.") .defaultValue(false)); optionVerbose = addOption( new BooleanOption("verbose", "Print more messages while compiling.")