Tools: doc templates - add support for iterating tags

- Support iterating tags
- Generate (update) all docs
This commit is contained in:
ljacqu 2016-04-07 17:19:52 +02:00
parent d46ad9ab5e
commit b3a3843b60
16 changed files with 209 additions and 106 deletions

View File

@ -1,5 +1,5 @@
<!-- AUTO-GENERATED FILE! Do not edit this directly --> <!-- AUTO-GENERATED FILE! Do not edit this directly -->
<!-- File auto-generated on Sun Feb 14 19:00:30 CET 2016. See commands/commands.tpl.md --> <!-- File auto-generated on Thu Apr 07 17:17:20 CEST 2016. See commands/commands.tpl.md -->
## AuthMe Commands ## AuthMe Commands
You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >` You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >`
@ -7,74 +7,72 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
- **/authme**: The main AuthMeReloaded command. The root for all admin commands. - **/authme**: The main AuthMeReloaded command. The root for all admin commands.
- **/authme register** &lt;player> &lt;password>: Register the specified player with the specified password. - **/authme register** &lt;player> &lt;password>: Register the specified player with the specified password.
<br />Requires `authme.admin.register` <br />Requires `authme.admin.register`
- **/authme unregister** &lt;player>: Unregister the specified player. - **/authme unregister** &lt;player>: Unregister the specified player.
<br />Requires `authme.admin.unregister` <br />Requires `authme.admin.unregister`
- **/authme forcelogin** [player]: Enforce the specified player to login. - **/authme forcelogin** [player]: Enforce the specified player to login.
<br />Requires `authme.player.canbeforced` <br />Requires `authme.admin.forcelogin`
- **/authme password** &lt;player> &lt;pwd>: Change the password of a player. - **/authme password** &lt;player> &lt;pwd>: Change the password of a player.
<br />Requires `authme.admin.changepassword` <br />Requires `authme.admin.changepassword`
- **/authme lastlogin** [player]: View the date of the specified players last login. - **/authme lastlogin** [player]: View the date of the specified players last login.
<br />Requires `authme.admin.lastlogin` <br />Requires `authme.admin.lastlogin`
- **/authme accounts** [player]: Display all accounts of a player by his player name or IP. - **/authme accounts** [player]: Display all accounts of a player by his player name or IP.
<br />Requires `authme.admin.accounts` <br />Requires `authme.admin.accounts`
- **/authme email** [player]: Display the email address of the specified player if set. - **/authme email** [player]: Display the email address of the specified player if set.
<br />Requires `authme.admin.getemail` <br />Requires `authme.admin.getemail`
- **/authme setemail** &lt;player> &lt;email>: Change the email address of the specified player. - **/authme setemail** &lt;player> &lt;email>: Change the email address of the specified player.
<br />Requires `authme.admin.changemail` <br />Requires `authme.admin.changemail`
- **/authme getip** &lt;player>: Get the IP address of the specified online player. - **/authme getip** &lt;player>: Get the IP address of the specified online player.
<br />Requires `authme.admin.getip` <br />Requires `authme.admin.getip`
- **/authme spawn** &lt;player>: Teleport to the spawn. - **/authme spawn**: Teleport to the spawn.
<br />Requires `authme.admin.spawn` <br />Requires `authme.admin.spawn`
- **/authme setspawn**: Change the player's spawn to your current position. - **/authme setspawn**: Change the player's spawn to your current position.
<br />Requires `authme.admin.setspawn` <br />Requires `authme.admin.setspawn`
- **/authme firstspawn**: Teleport to the first spawn. - **/authme firstspawn**: Teleport to the first spawn.
<br />Requires `authme.admin.firstspawn` <br />Requires `authme.admin.firstspawn`
- **/authme setfirstspawn**: Change the first player's spawn to your current position. - **/authme setfirstspawn**: Change the first player's spawn to your current position.
<br />Requires `authme.admin.setfirstspawn` <br />Requires `authme.admin.setfirstspawn`
- **/authme purge** &lt;days>: Purge old AuthMeReloaded data longer than the specified amount of days ago. - **/authme purge** &lt;days>: Purge old AuthMeReloaded data longer than the specified amount of days ago.
<br />Requires `authme.admin.purge` <br />Requires `authme.admin.purge`
- **/authme resetpos** &lt;player/*>: Purge the last know position of the specified player or all of them. - **/authme resetpos** &lt;player/*>: Purge the last know position of the specified player or all of them.
<br />Requires `authme.admin.purgelastpos` <br />Requires `authme.admin.purgelastpos`
- **/authme purgebannedplayers**: Purge all AuthMeReloaded data for banned players. - **/authme purgebannedplayers**: Purge all AuthMeReloaded data for banned players.
<br />Requires `authme.admin.purgebannedplayers` <br />Requires `authme.admin.purgebannedplayers`
- **/authme switchantibot** [mode]: Switch or toggle the AntiBot mode to the specified state. - **/authme switchantibot** [mode]: Switch or toggle the AntiBot mode to the specified state.
<br />Requires `authme.admin.switchantibot` <br />Requires `authme.admin.switchantibot`
- **/authme reload**: Reload the AuthMeReloaded plugin. - **/authme reload**: Reload the AuthMeReloaded plugin.
<br />Requires `authme.admin.reload` <br />Requires `authme.admin.reload`
- **/authme version**: Show detailed information about the installed AuthMeReloaded version, the developers, contributors, and license. - **/authme version**: Show detailed information about the installed AuthMeReloaded version, the developers, contributors, and license.
- **/authme converter** &lt;job>: Converter command for AuthMeReloaded.
<br />Requires `authme.admin.converter`
- **/authme help** [query]: View detailed help for /authme commands. - **/authme help** [query]: View detailed help for /authme commands.
- **/login** &lt;password>: Command to log in using AuthMeReloaded. - **/login** &lt;password>: Command to log in using AuthMeReloaded.
<br />Requires `authme.player.login` <br />Requires `authme.player.login`
- **/login help** [query]: View detailed help for /login commands. - **/login help** [query]: View detailed help for /login commands.
- **/logout**: Command to logout using AuthMeReloaded. - **/logout**: Command to logout using AuthMeReloaded.
<br />Requires `authme.player.logout` <br />Requires `authme.player.logout`
- **/logout help** [query]: View detailed help for /logout commands. - **/logout help** [query]: View detailed help for /logout commands.
- **/register** [password] [verifyPassword]: Command to register using AuthMeReloaded. - **/register** [password] [verifyPassword]: Command to register using AuthMeReloaded.
<br />Requires `authme.player.register` <br />Requires `authme.player.register`
- **/register help** [query]: View detailed help for /register commands. - **/register help** [query]: View detailed help for /register commands.
- **/unreg** &lt;password>: Command to unregister using AuthMeReloaded. - **/unreg** &lt;password>: Command to unregister using AuthMeReloaded.
<br />Requires `authme.player.unregister` <br />Requires `authme.player.unregister`
- **/unreg help** [query]: View detailed help for /unreg commands. - **/unreg help** [query]: View detailed help for /unreg commands.
- **/changepassword** &lt;oldPassword> &lt;newPassword>: Command to change your password using AuthMeReloaded. - **/changepassword** &lt;oldPassword> &lt;newPassword>: Command to change your password using AuthMeReloaded.
<br />Requires `authme.player.changepassword` <br />Requires `authme.player.changepassword`
- **/changepassword help** [query]: View detailed help for /changepassword commands. - **/changepassword help** [query]: View detailed help for /changepassword commands.
- **/email**: The AuthMeReloaded Email command base. - **/email**: The AuthMeReloaded Email command base.
- **/email add** &lt;email> &lt;verifyEmail>: Add a new email address to your account. - **/email add** &lt;email> &lt;verifyEmail>: Add a new email address to your account.
<br />Requires `authme.player.email.add` <br />Requires `authme.player.email.add`
- **/email change** &lt;oldEmail> &lt;newEmail>: Change an email address of your account. - **/email change** &lt;oldEmail> &lt;newEmail>: Change an email address of your account.
<br />Requires `authme.player.email.change` <br />Requires `authme.player.email.change`
- **/email recover** &lt;email>: Recover your account using an Email address by sending a mail containing a new password. - **/email recover** &lt;email>: Recover your account using an Email address by sending a mail containing a new password.
<br />Requires `authme.player.email.recover` <br />Requires `authme.player.email.recover`
- **/email help** [query]: View detailed help for /email commands. - **/email help** [query]: View detailed help for /email commands.
- **/captcha** &lt;captcha>: Captcha command for AuthMeReloaded. - **/captcha** &lt;captcha>: Captcha command for AuthMeReloaded.
<br />Requires `authme.player.captcha` <br />Requires `authme.player.captcha`
- **/captcha help** [query]: View detailed help for /captcha commands. - **/captcha help** [query]: View detailed help for /captcha commands.
- **/converter** &lt;job>: Converter command for AuthMeReloaded.
<br />Requires `authme.admin.converter`
- **/converter help** [query]: View detailed help for /converter commands.
--- ---
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Sun Feb 14 19:00:30 CET 2016 This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Thu Apr 07 17:17:20 CEST 2016

View File

@ -1,5 +1,5 @@
<!-- AUTO-GENERATED FILE! Do not edit this directly --> <!-- AUTO-GENERATED FILE! Do not edit this directly -->
<!-- File auto-generated on Sun Feb 14 19:00:32 CET 2016. See hashmethods/hash_algorithms.tpl.md --> <!-- File auto-generated on Thu Apr 07 17:17:22 CEST 2016. See hashmethods/hash_algorithms.tpl.md -->
## Hash Algorithms ## Hash Algorithms
AuthMe supports the following hash algorithms for storing your passwords safely. AuthMe supports the following hash algorithms for storing your passwords safely.
@ -17,7 +17,7 @@ JOOMLA | Recommended | 65 | | | Text | 32 |
MD5 | Do not use | 32 | | | None | | MD5 | Do not use | 32 | | | None | |
MD5VB | Acceptable | 56 | | | Text | 16 | MD5VB | Acceptable | 56 | | | Text | 16 |
MYBB | Acceptable | 32 | | | Text | 8 | Y MYBB | Acceptable | 32 | | | Text | 8 | Y
PBKDF2 | Does not work | 330 | | | Text | 12 | PBKDF2 | Does not work | 328 | | | Text | 12 |
PBKDF2DJANGO | Acceptable | 77 | Y | | Text | 12 | PBKDF2DJANGO | Acceptable | 77 | Y | | Text | 12 |
PHPBB | Acceptable | 34 | | | Text | 16 | PHPBB | Acceptable | 34 | | | Text | 16 |
PHPFUSION | Do not use | 64 | Y | | | | Y PHPFUSION | Do not use | 64 | Y | | | | Y
@ -82,4 +82,4 @@ or bad.
--- ---
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Sun Feb 14 19:00:32 CET 2016 This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Thu Apr 07 17:17:22 CEST 2016

View File

@ -1,5 +1,5 @@
<!-- AUTO-GENERATED FILE! Do not edit this directly --> <!-- AUTO-GENERATED FILE! Do not edit this directly -->
<!-- File auto-generated on Sun Feb 14 19:00:34 CET 2016. See permissions/permission_nodes.tpl.md --> <!-- File auto-generated on Thu Apr 07 17:17:24 CEST 2016. See permissions/permission_nodes.tpl.md -->
## AuthMe Permission Nodes ## AuthMe Permission Nodes
The following are the permission nodes that are currently supported by the latest dev builds. The following are the permission nodes that are currently supported by the latest dev builds.
@ -42,7 +42,6 @@ The following are the permission nodes that are currently supported by the lates
- **authme.player.unregister** Command permission to unregister. - **authme.player.unregister** Command permission to unregister.
- **authme.vip** Permission node to identify VIP users. - **authme.vip** Permission node to identify VIP users.
--- ---
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Sun Feb 14 19:00:34 CET 2016 This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Thu Apr 07 17:17:24 CEST 2016

View File

@ -1,6 +1,5 @@
package commands; package commands;
import com.google.common.collect.ImmutableMap;
import fr.xephi.authme.command.CommandArgumentDescription; import fr.xephi.authme.command.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandInitializer; import fr.xephi.authme.command.CommandInitializer;
@ -8,12 +7,12 @@ import fr.xephi.authme.command.CommandPermissions;
import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
import utils.FileUtils; import utils.FileUtils;
import utils.TagReplacer; import utils.TagValue.NestedTagValue;
import utils.TagValueHolder;
import utils.ToolTask; import utils.ToolTask;
import utils.ToolsConstants; import utils.ToolsConstants;
import java.util.Collection; import java.util.Collection;
import java.util.Map;
import java.util.Scanner; import java.util.Scanner;
import java.util.Set; import java.util.Set;
@ -29,31 +28,27 @@ public class CommandPageCreater implements ToolTask {
@Override @Override
public void execute(Scanner scanner) { public void execute(Scanner scanner) {
final Set<CommandDescription> baseCommands = CommandInitializer.buildCommands(); final Set<CommandDescription> baseCommands = CommandInitializer.buildCommands();
final String template = FileUtils.readFromFile(ToolsConstants.TOOLS_SOURCE_ROOT NestedTagValue commandTags = new NestedTagValue();
+ "commands/command_entry.tpl.md"); addCommandsInfo(commandTags, baseCommands);
StringBuilder commandsResult = new StringBuilder();
addCommandsInfo(commandsResult, baseCommands, template);
FileUtils.generateFileFromTemplate( FileUtils.generateFileFromTemplate(
ToolsConstants.TOOLS_SOURCE_ROOT + "commands/commands.tpl.md", ToolsConstants.TOOLS_SOURCE_ROOT + "commands/commands.tpl.md",
OUTPUT_FILE, OUTPUT_FILE,
ImmutableMap.of("commands", commandsResult.toString())); TagValueHolder.create().put("commands", commandTags));
System.out.println("Wrote to '" + OUTPUT_FILE + "' with " + baseCommands.size() + " base commands."); System.out.println("Wrote to '" + OUTPUT_FILE + "' with " + baseCommands.size() + " base commands.");
} }
private static void addCommandsInfo(StringBuilder sb, Collection<CommandDescription> commands, private static void addCommandsInfo(NestedTagValue commandTags, Collection<CommandDescription> commands) {
final String template) {
for (CommandDescription command : commands) { for (CommandDescription command : commands) {
Map<String, String> tags = ImmutableMap.of( TagValueHolder tags = TagValueHolder.create()
"command", CommandUtils.constructCommandPath(command), .put("command", CommandUtils.constructCommandPath(command))
"description", command.getDetailedDescription(), .put("description", command.getDetailedDescription())
"arguments", formatArguments(command.getArguments()), .put("arguments", formatArguments(command.getArguments()))
"permissions", formatPermissions(command.getCommandPermissions())); .put("permissions", formatPermissions(command.getCommandPermissions()));
sb.append(TagReplacer.applyReplacements(template, tags)); commandTags.add(tags);
if (!command.getChildren().isEmpty()) { if (!command.getChildren().isEmpty()) {
addCommandsInfo(sb, command.getChildren(), template); addCommandsInfo(commandTags, command.getChildren());
} }
} }
} }

View File

@ -1,2 +0,0 @@
- **{command}**{arguments}: {description}[permissions]
<br />Requires `{permissions}`[/permissions]

View File

@ -5,6 +5,9 @@
You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >` You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >`
brackets; optional arguments are enclosed in square brackets (`[ ]`). brackets; optional arguments are enclosed in square brackets (`[ ]`).
{commands} [#commands]
- **{command}**{arguments}: {description}[permissions]
<br />Requires `{permissions}`[/permissions]
[/#commands]
{gen_footer} {gen_footer}

View File

@ -1,11 +1,11 @@
package hashmethods; package hashmethods;
import com.google.common.collect.ImmutableMap;
import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.WrapperMock; import fr.xephi.authme.util.WrapperMock;
import utils.FileUtils; import utils.FileUtils;
import utils.TagReplacer; import utils.TagValue.NestedTagValue;
import utils.TagValueHolder;
import utils.ToolTask; import utils.ToolTask;
import utils.ToolsConstants; import utils.ToolsConstants;
@ -33,30 +33,28 @@ public class HashAlgorithmsDescriptionTask implements ToolTask {
// Gather info and construct a row for each method // Gather info and construct a row for each method
EncryptionMethodInfoGatherer infoGatherer = new EncryptionMethodInfoGatherer(); EncryptionMethodInfoGatherer infoGatherer = new EncryptionMethodInfoGatherer();
Map<HashAlgorithm, MethodDescription> descriptions = infoGatherer.getDescriptions(); Map<HashAlgorithm, MethodDescription> descriptions = infoGatherer.getDescriptions();
final String methodRows = constructMethodRows(descriptions); final NestedTagValue methodRows = constructMethodRows(descriptions);
// Write to the docs file // Write to the docs file
Map<String, String> tags = ImmutableMap.of("method_rows", methodRows); TagValueHolder tags = TagValueHolder.create().put("algorithms", methodRows);
FileUtils.generateFileFromTemplate(CUR_FOLDER + "hash_algorithms.tpl.md", OUTPUT_FILE, tags); FileUtils.generateFileFromTemplate(CUR_FOLDER + "hash_algorithms.tpl.md", OUTPUT_FILE, tags);
} }
private static String constructMethodRows(Map<HashAlgorithm, MethodDescription> descriptions) { private static NestedTagValue constructMethodRows(Map<HashAlgorithm, MethodDescription> descriptions) {
final String rowTemplate = FileUtils.readFromFile(CUR_FOLDER + "hash_algorithms_row.tpl.md"); NestedTagValue methodTags = new NestedTagValue();
StringBuilder result = new StringBuilder();
for (Map.Entry<HashAlgorithm, MethodDescription> entry : descriptions.entrySet()) { for (Map.Entry<HashAlgorithm, MethodDescription> entry : descriptions.entrySet()) {
MethodDescription description = entry.getValue(); MethodDescription description = entry.getValue();
Map<String, String> tags = ImmutableMap.<String, String>builder() TagValueHolder tags = TagValueHolder.create()
.put("name", asString(entry.getKey())) .put("name", asString(entry.getKey()))
.put("recommendation", asString(description.getUsage())) .put("recommendation", asString(description.getUsage()))
.put("hash_length", asString(description.getHashLength())) .put("hash_length", asString(description.getHashLength()))
.put("ascii_restricted", asString(description.isAsciiRestricted())) .put("ascii_restricted", asString(description.isAsciiRestricted()))
.put("salt_type", asString(description.getSaltType())) .put("salt_type", asString(description.getSaltType()))
.put("salt_length", asString(description.getSaltLength())) .put("salt_length", asString(description.getSaltLength()))
.put("separate_salt", asString(description.hasSeparateSalt())) .put("separate_salt", asString(description.hasSeparateSalt()));
.build(); methodTags.add(tags);
result.append(TagReplacer.applyReplacements(rowTemplate, tags));
} }
return result.toString(); return methodTags;
} }
@Override @Override

View File

@ -7,7 +7,10 @@ AuthMe supports the following hash algorithms for storing your passwords safely.
Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate? Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate?
--------- | -------------- | ----------- | ----- | --- | --------- | ------ | --------- --------- | -------------- | ----------- | ----- | --- | --------- | ------ | ---------
{method_rows}CUSTOM | | | | | | | | [#algorithms]
{name} | {recommendation} | {hash_length} | {ascii_restricted} | | {salt_type} | {salt_length} | {separate_salt}
[/#algorithms]
CUSTOM | | | | | | | |
<!-- {gen_warning} --> <!-- {gen_warning} -->

View File

@ -1 +0,0 @@
{name} | {recommendation} | {hash_length} | {ascii_restricted} | | {salt_type} | {salt_length} | {separate_salt}

View File

@ -1,8 +1,8 @@
package permissions; package permissions;
import com.google.common.collect.ImmutableMap;
import utils.FileUtils; import utils.FileUtils;
import utils.TagReplacer; import utils.TagValue.NestedTagValue;
import utils.TagValueHolder;
import utils.ToolTask; import utils.ToolTask;
import utils.ToolsConstants; import utils.ToolsConstants;
@ -45,29 +45,25 @@ public class PermissionsListWriter implements ToolTask {
} }
private static void generateAndWriteFile() { private static void generateAndWriteFile() {
final String permissionsTagValue = generatePermissionsList(); final NestedTagValue permissionsTagValue = generatePermissionsList();
Map<String, String> tags = ImmutableMap.of("permissions", permissionsTagValue); TagValueHolder tags = TagValueHolder.create().put("nodes", permissionsTagValue);
FileUtils.generateFileFromTemplate( FileUtils.generateFileFromTemplate(
ToolsConstants.TOOLS_SOURCE_ROOT + "permissions/permission_nodes.tpl.md", PERMISSIONS_OUTPUT_FILE, tags); ToolsConstants.TOOLS_SOURCE_ROOT + "permissions/permission_nodes.tpl.md", PERMISSIONS_OUTPUT_FILE, tags);
System.out.println("Wrote to '" + PERMISSIONS_OUTPUT_FILE + "'"); System.out.println("Wrote to '" + PERMISSIONS_OUTPUT_FILE + "'");
System.out.println("Before committing, please verify the output!"); System.out.println("Before committing, please verify the output!");
} }
private static String generatePermissionsList() { private static NestedTagValue generatePermissionsList() {
PermissionNodesGatherer gatherer = new PermissionNodesGatherer(); PermissionNodesGatherer gatherer = new PermissionNodesGatherer();
Map<String, String> permissions = gatherer.gatherNodesWithJavaDoc(); Map<String, String> permissions = gatherer.gatherNodesWithJavaDoc();
NestedTagValue permissionTags = new NestedTagValue();
final String template = FileUtils.readFromToolsFile("permissions/permission_node_entry.tpl.md");
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : permissions.entrySet()) { for (Map.Entry<String, String> entry : permissions.entrySet()) {
Map<String, String> tags = ImmutableMap.of( permissionTags.add(TagValueHolder.create()
"node", entry.getKey(), .put("node", entry.getKey())
"description", entry.getValue()); .put("description", entry.getValue()));
sb.append(TagReplacer.applyReplacements(template, tags));
} }
return sb.toString(); return permissionTags;
} }
private static void outputSimpleList() { private static void outputSimpleList() {

View File

@ -1 +0,0 @@
- **{node}** {description}

View File

@ -4,6 +4,8 @@
## AuthMe Permission Nodes ## AuthMe Permission Nodes
The following are the permission nodes that are currently supported by the latest dev builds. The following are the permission nodes that are currently supported by the latest dev builds.
{permissions} [#nodes]
- **{node}** {description}
[/#nodes]
{gen_footer} {gen_footer}

View File

@ -6,7 +6,6 @@ import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Utility class for reading from and writing to files. * Utility class for reading from and writing to files.
@ -18,7 +17,7 @@ public final class FileUtils {
private FileUtils() { private FileUtils() {
} }
public static void generateFileFromTemplate(String templateFile, String destinationFile, Map<String, String> tags) { public static void generateFileFromTemplate(String templateFile, String destinationFile, TagValueHolder tags) {
String template = readFromFile(templateFile); String template = readFromFile(templateFile);
String result = TagReplacer.applyReplacements(template, tags); String result = TagReplacer.applyReplacements(template, tags);
writeToFile(destinationFile, result); writeToFile(destinationFile, result);
@ -56,8 +55,4 @@ public final class FileUtils {
} }
} }
public static String readFromToolsFile(String file) {
return readFromFile(ToolsConstants.TOOLS_SOURCE_ROOT + file);
}
} }

View File

@ -1,6 +1,7 @@
package utils; package utils;
import fr.xephi.authme.util.StringUtils; import utils.TagValue.NestedTagValue;
import utils.TagValue.TextTagValue;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
@ -26,18 +27,25 @@ public class TagReplacer {
* Replace a template with default tags and custom ones supplied by a map. * Replace a template with default tags and custom ones supplied by a map.
* *
* @param template The template to process * @param template The template to process
* @param tags Map with additional tags, e.g. a map entry with key "foo" and value "bar" will replace * @param tagValues Map with additional tags, e.g. a map entry with key "foo" and value "bar" will replace
* any occurrences of "{foo}" to "bar". * any occurrences of "{foo}" to "bar".
* @return The filled template * @return The filled template
*/ */
public static String applyReplacements(String template, Map<String, String> tags) { public static String applyReplacements(String template, TagValueHolder tagValues) {
String result = template; String result = template;
for (Map.Entry<String, String> tagRule : tags.entrySet()) { for (Map.Entry<String, TagValue<?>> tagRule : tagValues.getValues().entrySet()) {
final String name = tagRule.getKey(); final String name = tagRule.getKey();
final String value = tagRule.getValue();
result = replaceOptionalTag(result, name, value) if (tagRule.getValue() instanceof TextTagValue) {
.replace("{" + name + "}", value); final TextTagValue value = (TextTagValue) tagRule.getValue();
result = replaceOptionalTag(result, name, value)
.replace("{" + name + "}", value.getValue());
} else if (tagRule.getValue() instanceof NestedTagValue) {
final NestedTagValue value = (NestedTagValue) tagRule.getValue();
result = replaceIterateTag(replaceOptionalTag(result, name, value), name, value);
} else {
throw new IllegalStateException("Unknown tag value type");
}
} }
return applyReplacements(result); return applyReplacements(result);
} }
@ -58,14 +66,14 @@ public class TagReplacer {
+ " on " + curDate); + " on " + curDate);
} }
private static String replaceOptionalTag(String text, String tagName, String tagValue) { private static String replaceOptionalTag(String text, String tagName, TagValue<?> tagValue) {
Pattern regex = Pattern.compile("\\[" + tagName + "](.*?)\\[/" + tagName + "]", Pattern.DOTALL); Pattern regex = Pattern.compile("\\[" + tagName + "](.*?)\\[/" + tagName + "]", Pattern.DOTALL);
Matcher matcher = regex.matcher(text); Matcher matcher = regex.matcher(text);
if (!matcher.find()) { if (!matcher.find()) {
// Couldn't find results, so just return text as it is // Couldn't find results, so just return text as it is
return text; return text;
} else if (StringUtils.isEmpty(tagValue)) { } else if (tagValue.isEmpty()) {
// Tag is empty, replace [tagName]some_text[/tagName] to nothing // Tag is empty, replace [tagName]some_text[/tagName] to nothing
return matcher.replaceAll(""); return matcher.replaceAll("");
} else { } else {
@ -74,5 +82,30 @@ public class TagReplacer {
} }
} }
/**
* Replace iterating tags with the value. Tags of the type [#tag]...[/#tag] specify to iterate over the
* entries in {@link NestedTagValue} and to apply any replacements in there.
*
* @param text The file text
* @param tagName The tag name to handle
* @param tagValue The associated value
* @return The text with the applied replacement
*/
private static String replaceIterateTag(String text, String tagName, NestedTagValue tagValue) {
Pattern regex = Pattern.compile("\\[#" + tagName + "](.*?)\\[/#" + tagName + "]\\s?", Pattern.DOTALL);
Matcher matcher = regex.matcher(text);
if (!matcher.find()) {
return text;
} else if (tagValue.isEmpty()) {
return matcher.replaceAll("");
}
final String innerTemplate = matcher.group(1).trim() + "\n";
String result = "";
for (TagValueHolder entry : tagValue.getValue()) {
result += applyReplacements(innerTemplate, entry);
}
return matcher.replaceAll(result);
}
} }

View File

@ -0,0 +1,51 @@
package utils;
import java.util.ArrayList;
import java.util.List;
public abstract class TagValue<T> {
private final T value;
public TagValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public abstract boolean isEmpty();
public static final class TextTagValue extends TagValue<String> {
public TextTagValue(String value) {
super(value);
}
@Override
public boolean isEmpty() {
return getValue().isEmpty();
}
@Override
public int hashCode() {
return super.hashCode();
}
}
public static final class NestedTagValue extends TagValue<List<TagValueHolder>> {
public NestedTagValue() {
super(new ArrayList<TagValueHolder>());
}
@Override
public boolean isEmpty() {
return getValue().isEmpty();
}
public void add(TagValueHolder entry) {
getValue().add(entry);
}
}
}

View File

@ -0,0 +1,34 @@
package utils;
import utils.TagValue.TextTagValue;
import java.util.HashMap;
import java.util.Map;
public class TagValueHolder {
private Map<String, TagValue<?>> values;
private TagValueHolder() {
this.values = new HashMap<>();
}
public static TagValueHolder create() {
return new TagValueHolder();
}
public TagValueHolder put(String key, TagValue<?> value) {
values.put(key, value);
return this;
}
public TagValueHolder put(String key, String value) {
values.put(key, new TextTagValue(value));
return this;
}
public Map<String, TagValue<?>> getValues() {
return values;
}
}