diff options
| author | Martin Ritchie <ritchiem@apache.org> | 2009-07-24 11:32:40 +0000 |
|---|---|---|
| committer | Martin Ritchie <ritchiem@apache.org> | 2009-07-24 11:32:40 +0000 |
| commit | e28e61ac208c9a873c52a5fc2ce2505f50c22377 (patch) | |
| tree | 429db4efb0af0f807354a47acf4a143e8e400c71 /qpid/java/broker/src/velocity | |
| parent | d48bc3489bde46736c3773d8062b6637df450628 (diff) | |
| download | qpid-python-e28e61ac208c9a873c52a5fc2ce2505f50c22377.tar.gz | |
QPID-2001 : Update to provide control of options in messages.
Update to improve formatting of generated code
Inclusion of more documentation
Defaulted generation to use US locale
Removed duplicate messages in MST that were added to while the option solution was being discussed.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@797421 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker/src/velocity')
2 files changed, 268 insertions, 71 deletions
diff --git a/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java b/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java index cc0565031f..ea0946f6d6 100644 --- a/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java +++ b/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java @@ -30,6 +30,7 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Properties; import java.util.ResourceBundle; @@ -210,15 +211,20 @@ public class GenerateLogMessages * type checking during compilation whilst allowing the log message to * maintain formatting controls. * + * OPTIONS + * * The returned hashMap contains the following structured data: * * - name - ClassName ('Broker') - * list - methodName ('BRK_1001') - * - name ('BRK-1001') - * - format ('Startup : Version: {0} Build: {1}') - * - parameters (list) - * - type ('String'|'Number') - * - name ('param1') + * - list[logEntryData] - methodName ('BRK_1001') + * - name ('BRK-1001') + * - format ('Startup : Version: {0} Build: {1}') + * - parameters (list) + * - type ('String'|'Number') + * - name ('param1') + * - options (list) + * - name ('opt1') + * - value ('AutoDelete') * * @param messsageName the name to give the Class e.g. 'Broker' * @param messageKey the 3-digit key to extract the messages e.g. 'BRK' @@ -228,7 +234,7 @@ public class GenerateLogMessages private HashMap<String, Object> prepareType(String messsageName, String messageKey) throws InvalidTypeException { // Load the LogMessages Resource Bundle - ResourceBundle _messages = ResourceBundle.getBundle("org.apache.qpid.server.logging.messages.LogMessages"); + ResourceBundle _messages = ResourceBundle.getBundle("org.apache.qpid.server.logging.messages.LogMessages", Locale.US); Enumeration<String> messageKeys = _messages.getKeys(); @@ -265,79 +271,187 @@ public class GenerateLogMessages // Javadoc of the method. logEntryData.put("format", logMessage); - // Split the string on the start brace '{' this will give us the - // details for each parameter that this message contains. - String[] parametersString = logMessage.split("\\{"); - // Taking an example of 'Text {n[,type]} text {m} more text {p}' - // This would give us: - // 0 - Text - // 1 - n[,type]} text - // 2 - m} more text - // 3 - p} - - // Create the parameter list for this item - List<HashMap<String, String>> parameters = new LinkedList<HashMap<String, String>>(); + // Add the parameters for this message + logEntryData.put("parameters", extractParameters(logMessage)); - // Add the parameter list to this log entry data - logEntryData.put("parameters", parameters); + //Add the options for this messagse + logEntryData.put("options", extractOptions(logMessage)); - // Add the data to the list of messages + //Add this entry to the list for this class logMessageList.add(logEntryData); + } + } - // Check that we have some parameters to process - // Skip 0 as that will not be the first entry - // Text {n[,type]} text {m} more text {p} - if (parametersString.length > 1) - { - for (int index = 1; index < parametersString.length; index++) - { - // Use a HashMap to store the type,name of the parameter - // for easy retrieval in the macro template - HashMap<String, String> parameter = new HashMap<String, String>(); + return messageTypeData; + } - // Check for any properties of the parameter : - // e.g. {0} vs {0,number} vs {0,number,xxxx} - int typeIndex = parametersString[index].indexOf(","); + /** + * This method is responsible for extracting the options form the given log + * message and providing a HashMap with the expected data: + * - options (list) + * - name ('opt1') + * - value ('AutoDelete') + * + * The options list that this method provides must contain HashMaps that + * have two entries. A 'name' and a 'value' these strings are important as + * they are used in LogMessage.vm to extract the stored String during + * processing of the template. + * + * The 'name' is a unique string that is used to name the boolean parameter + * and refer to it later in the method body. + * + * The 'value' is used to provide documentation in the generated class to + * aid readability. + * + * @param logMessage the message from the properties file + * @return list of option data + */ + private List<HashMap<String, String>> extractOptions(String logMessage) + { + // Split the string on the start brace '{' this will give us the + // details for each parameter that this message contains. + // NOTE: Simply splitting on '[' prevents the use of nested options. + // Currently there is no demand for nested options + String[] optionString = logMessage.split("\\["); + // Taking an example of: + // 'Text {n,type,format} [option] text {m} [option with param{p}] more' + // This would give us: + // 0 - Text {n,type,format} + // 1 - option] text {m} + // 2 - option with param{p}] more + + // Create the parameter list for this item + List<HashMap<String, String>> options = new LinkedList<HashMap<String, String>>(); + + // Check that we have some parameters to process + // Skip 0 as that will not be the first entry + // Text {n,type,format} [option] text {m} [option with param{p}] more + if (optionString.length > 1) + { + for (int index = 1; index < optionString.length; index++) + { + // Use a HashMap to store the type,name of the parameter + // for easy retrieval in the macro template + HashMap<String, String> option = new HashMap<String, String>(); - // The parameter type - String type; + // Locate the end of the Option + // NOTE: it is this simple matching on the first ']' that + // prevents the nesting of options. + // Currently there is no demand for nested options + int end = optionString[index].indexOf("]"); - //Be default all types are Strings - if (typeIndex == -1) - { - type = "String"; - } - else - { - //Check string ',....}' for existence of number - // to identify this parameter as an integer - // This allows for a style value to be present - // Only check the text inside the braces '{}' - int typeIndexEnd = parametersString[index].indexOf("}", typeIndex); - String typeString = parametersString[index].substring(typeIndex, typeIndexEnd); - if (typeString.contains("number")) - { - type = "Number"; - } - else - { - throw new InvalidTypeException("Invalid type(" + typeString + ") index (" + parameter.size() + ") in message:" + logMessage); - } + // The parameter type + String value = optionString[index].substring(0, end); - } + // Simply name the parameters by index. + option.put("name", "opt" + index); + + //Store the value e.g. AutoDelete + // We trim as we don't need to include any whitespace that is + // used for formating. This is only used to aid readability of + // of the generated code. + option.put("value", value.trim()); - //Store the data - parameter.put("type", type); - // Simply name the parameters by index. - parameter.put("name", "param" + index); + options.add(option); + } + } - parameters.add(parameter); + return options; + } + + /** + * This method is responsible for extract the parameters that are requried + * for this log message. The data is returned in a HashMap that has the + * following structure: + * - parameters (list) + * - type ('String'|'Number') + * - name ('param1') + * + * The parameters list that is provided must contain HashMaps that have the + * two named entries. A 'type' and a 'name' these strings are importans as + * they are used in LogMessage.vm to extract and the stored String during + * processing of the template + * + * The 'type' and 'name' values are used to populate the method signature. + * This is what gives us the compile time validation of log messages. + * + * The 'name' must be unique as there may be many parameters. The value is + * also used in the method body to pass the values through to the + * MessageFormat class for formating the log message. + * + * @param logMessage the message from the properties file + * @return list of option data + * @throws InvalidTypeException if the FormatType is specified and is not 'number' + */ + private List<HashMap<String, String>> extractParameters(String logMessage) + throws InvalidTypeException + { + // Split the string on the start brace '{' this will give us the + // details for each parameter that this message contains. + String[] parametersString = logMessage.split("\\{"); + // Taking an example of 'Text {n[,type]} text {m} more text {p}' + // This would give us: + // 0 - Text + // 1 - n[,type]} text + // 2 - m} more text + // 3 - p} + + // Create the parameter list for this item + List<HashMap<String, String>> parameters = new LinkedList<HashMap<String, String>>(); + + // Check that we have some parameters to process + // Skip 0 as that will not be the first entry + // Text {n[,type]} text {m} more text {p} + if (parametersString.length > 1) + { + for (int index = 1; index < parametersString.length; index++) + { + // Use a HashMap to store the type,name of the parameter + // for easy retrieval in the macro template + HashMap<String, String> parameter = new HashMap<String, String>(); + + // Check for any properties of the parameter : + // e.g. {0} vs {0,number} vs {0,number,xxxx} + int typeIndex = parametersString[index].indexOf(","); + + + // The parameter type + String type; + + //Be default all types are Strings + if (typeIndex == -1) + { + type = "String"; + } + else + { + //Check string ',....}' for existence of number + // to identify this parameter as an integer + // This allows for a style value to be present + // Only check the text inside the braces '{}' + int typeIndexEnd = parametersString[index].indexOf("}", typeIndex); + String typeString = parametersString[index].substring(typeIndex, typeIndexEnd); + if (typeString.contains("number")) + { + type = "Number"; } + else + { + throw new InvalidTypeException("Invalid type(" + typeString + ") index (" + parameter.size() + ") in message:" + logMessage); + } + } + + //Store the data + parameter.put("type", type); + // Simply name the parameters by index. + parameter.put("name", "param" + index); + + parameters.add(parameter); } } - return messageTypeData; + return parameters; } /** diff --git a/qpid/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm b/qpid/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm index 6656763ab9..917901a18b 100644 --- a/qpid/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm +++ b/qpid/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm @@ -33,7 +33,10 @@ import java.util.ResourceBundle; * This file is based on the content of LogMessages.properties * * It is generated so that we can provide compile time validation of the - * message parameters + * message parameters. + * + * DO NOT EDIT DIRECTLY THIS FILE IS GENERATED. + * */ public class ${type.name}Messages { @@ -51,25 +54,105 @@ public class ${type.name}Messages _formatter.setLocale(currentLocale); } +## +## The list stored under key 'list' in the 'type' HashMap contains all the +## log messages that this class should contain. So for each entry in the list +## this template will create a new log method. +## #foreach( $message in ${type.list} ) /** * Log a ${type.name} message of the Format: - * <pre>${message.format}</pre> + * <pre>${message.format}</pre> + * Optional values are contained in [square brackets] and are numbered + * sequentially in the method call. + * */ +## There is a lot in the method header here. To make it more readable/understandable +## This is the same text laid out to be easier to read: +## public static LogMessage ${message.methodName} ( +## #foreach($parameter in ${message.parameters}) +## ${parameter.type} ${parameter.name} +## #if (${velocityCount} != ${message.parameters.size()} ) +## , +## #end +## #end +## #if(${message.parameters.size()} > 0 && ${message.options.size()} > 0) +## , +## #end +## #foreach($option in ${message.options}) +## boolean ${option.name} +## #if (${velocityCount} != ${message.options.size()} ) +## , +## #end +## #end +## ) +## +## What is going on is that we set the method name based on the HashMap lookup +## for 'methodName' Then for each entry(another HashMap) in the list stored +## in the HashMap under 'parameters' build the argument list of from the 'type' +## and 'name' values. Ensuring that we add a ', ' between each entry. +## +## However, check that we are not at the last entry of the list as we don't +## want to add ', ' at then end. +## +## Before we go on to the options we perform a check to see if we had any +## parameters. If we did and we have options to add then we add ', ' to keep +## the syntax correct. +## +## We then go on to the options that are again retrieved from the top HashMap +## with key 'options'. For each option a boolean argument is created and the +## name is retrieved from the option HashMap with key 'name' +## public static LogMessage ${message.methodName}(#foreach($parameter in ${message.parameters})${parameter.type} ${parameter.name}#if (${velocityCount} != ${message.parameters.size()} ), #end -#end) +#end#if(${message.parameters.size()} > 0 && ${message.options.size()} > 0), #end#foreach($option in ${message.options})boolean ${option.name}#if (${velocityCount} != ${message.options.size()} ), #end#end) { final Object[] messageArguments = {#foreach($parameter in ${message.parameters})${parameter.name}#if (${velocityCount} != ${message.parameters.size()} ), #end#end}; - _formatter.applyPattern(_messages.getString("${message.name}")); + + ## If we have some options then we need to build the message based + ## on those values so only provide that logic if we need it. +#if(${message.options.size()} > 0) + String rawMessage = _formatter.format(messageArguments); + + StringBuffer msg =new StringBuffer("${message.name} : "); + + // Split the formatted message up on the option values so we can + // rebuild the message based on the configured options. + String[] parts = rawMessage.split("\\["); + msg.append(parts[0]); + + int end; + if (parts.length > 1) + { + ## For Each Optional value check if it has been enabled and then + ## append it to the log. +#foreach($option in ${message.options}) + + // Add Option : ${option.value} + end = parts[${velocityCount}].indexOf(']'); + if (${option.name}) + { + msg.append(parts[${velocityCount}].substring(0, end)); + } + + // Use 'end + 1' to remove the ']' from the output + msg.append(parts[${velocityCount}].substring(end + 1)); +#end + } + + final String message = msg.toString(); +#else + ## If we have no options then we can just format and set the log + final String message = "${message.name} : " + _formatter.format(messageArguments); +#end + return new LogMessage() { public String toString() { - return "${message.name} : " + _formatter.format(messageArguments); + return message; } }; - } #end |
