From 37999b6e9788eef674e845e6a8f7e8f8be2c3865 Mon Sep 17 00:00:00 2001 From: Martin Ritchie Date: Thu, 23 Jul 2009 12:56:08 +0000 Subject: QPID-2001 : Correct code style of generated files QPID-2001 : Added documentation and replaced Integer with Number. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@797048 13f79535-47bb-0310-9956-ffa450edef68 --- .../qpid/server/logging/GenerateLogMessages.java | 167 +++++++++++++++++---- .../qpid/server/logging/messages/LogMessages.vm | 4 +- 2 files changed, 139 insertions(+), 32 deletions(-) (limited to 'java/broker/src') diff --git a/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java b/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java index c62c51bb3f..cc0565031f 100644 --- a/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java +++ b/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java @@ -1,4 +1,4 @@ -package org.apache.qpid.server.logging;/* +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,6 +19,8 @@ package org.apache.qpid.server.logging;/* * */ +package org.apache.qpid.server.logging; + import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; @@ -45,10 +47,12 @@ public class GenerateLogMessages } catch (IllegalAccessException iae) { + // This occurs when args does not contain Template and output dirs. System.exit(-1); } catch (Exception e) { + //This is thrown by the Velocity Engine initialisation e.printStackTrace(); System.exit(-1); } @@ -59,6 +63,8 @@ public class GenerateLogMessages } catch (InvalidTypeException e) { + // This occurs when a type other than 'number' appears in the + // paramater config {0, number...} System.err.println(e.getMessage()); System.exit(-1); } @@ -73,17 +79,16 @@ public class GenerateLogMessages { processArgs(args); - if (_tmplDir == null||_outputDir == null) + // We need the template and output dirs set to run. + if (_tmplDir == null || _outputDir == null) { showUsage(); throw new IllegalAccessException(); } - - /* first, we init the runtime engine. Defaults are fine. */ + // Initialise the Velocity Engine, Telling it where our macro lives Properties props = new Properties(); props.setProperty("file.resource.loader.path", _tmplDir); - Velocity.init(props); } @@ -111,9 +116,11 @@ public class GenerateLogMessages } /** - * Process the args for a -t value for the template location + * Process the args for: + * -t|T value for the template location + * -o|O value for the output directory * - * @param args + * @param args the commandline arguments */ private void processArgs(String[] args) { @@ -144,99 +151,199 @@ public class GenerateLogMessages } } + /** + * This is the main method that generates the _Messages.java file. + * The class is generated by extracting the list of messges from the + * available LogMessages Resource. + * + * The extraction is done based on typeIdentifier which is a 3-digit prefix + * on the messages e.g. BRK for Broker. + * + * @param className The name for the file '_className_Messages.java' + * @param typeIdentifier The 3 digit identifier + * @throws InvalidTypeException when an unknown parameter type is used in the properties file + * @throws Exception thrown by velocity if there is an error + */ private void createMessageClass(String className, String typeIdentifier) throws InvalidTypeException, Exception { VelocityContext context = new VelocityContext(); + // Get the Data for this class and typeIdentifier HashMap typeData = prepareType(className, typeIdentifier); + // Store this data in the context for the macro to access context.put("type", typeData); - /* lets render a template */ + // Create the file writer to put the finished file in FileWriter output = new FileWriter(_outputDir + File.separator + className + "Messages.java"); - Velocity.mergeTemplate("LogMessages.vm", context, output); + // Run Velocity to create the output file. + // Fix the default file encoding to 'ISO-8859-1' rather than let + // Velocity fix it. This is the encoding format for the macro. + Velocity.mergeTemplate("LogMessages.vm", "ISO-8859-1", context, output); + //Close our file. output.flush(); output.close(); } + /** + * This method does the processing and preparation of the data to be added + * to the Velocity context so that the macro can access and process the data + * + * The given messageKey (e.g. 'BRK') uses a 3-digit code used to match + * the property key from the loaded 'LogMessages' ResourceBundle. + * + * This gives a list of messages which are to be associated with the given + * messageName (e.g. 'Broker') + * + * Each of the messages in the list are then processed to identify how many + * parameters the MessageFormat call is expecting. These parameters are + * identified by braces ('{}') so a quick count of these can then be used + * to create a defined parameter list. + * + * Rather than defaulting all parameters to String a check is performed to + * see if a 'number' value has been requested. e.g. {0. number} + * {@see MessageFormat}. If a parameter has a 'number' type then the + * parameter will be defined as an Number value. This allows for better + * type checking during compilation whilst allowing the log message to + * maintain formatting controls. + * + * 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') + * + * @param messsageName the name to give the Class e.g. 'Broker' + * @param messageKey the 3-digit key to extract the messages e.g. 'BRK' + * @return A HashMap with data for the macro + * @throws InvalidTypeException when an unknown parameter type is used in the properties file + */ private HashMap prepareType(String messsageName, String messageKey) throws InvalidTypeException { + // Load the LogMessages Resource Bundle ResourceBundle _messages = ResourceBundle.getBundle("org.apache.qpid.server.logging.messages.LogMessages"); Enumeration messageKeys = _messages.getKeys(); - HashMap typeData = new HashMap(); - typeData.put("name", messsageName); + //Create the return map + HashMap messageTypeData = new HashMap(); + // Store the name to give to this Class Messages.java + messageTypeData.put("name", messsageName); - List messageList = new LinkedList(); - typeData.put("list", messageList); + // Prepare the list of log messages + List logMessageList = new LinkedList(); + messageTypeData.put("list", logMessageList); + //Process each of the properties while (messageKeys.hasMoreElements()) { - HashMap item = new HashMap(); + HashMap logEntryData = new HashMap(); //Add MessageName to amp String message = messageKeys.nextElement(); + // Process the log message if it matches the specified key e.g.'BRK' if (message.startsWith(messageKey)) { - item.put("methodName", message.replace('-','_')); - item.put("name", message); - - item.put("format", _messages.getString(message)); + // Method names can't have a '-' in them so lets make it '_' + // e.g. BRK_1001 + logEntryData.put("methodName", message.replace('-', '_')); + // Store the real name so we can use that in the actual log. + logEntryData.put("name", message); + + //Retrieve the actual log message string. + String logMessage = _messages.getString(message); + + // Store the value of the property so we can add it to the + // 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> parameters = new LinkedList>(); - String[] parametersString = _messages.getString(message).split("\\{"); + // Add the parameter list to this log entry data + logEntryData.put("parameters", parameters); - // Add P - List> parameters = new LinkedList>(); + // Add the data to the list of messages + 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 {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 parameter = new HashMap(); + // 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 + 1, typeIndexEnd); - if (typeString.equalsIgnoreCase("number")) + String typeString = parametersString[index].substring(typeIndex, typeIndexEnd); + if (typeString.contains("number")) { - type = "Integer"; + type = "Number"; } else { - throw new InvalidTypeException("Invalid type(" + typeString + ") index (" + parameter.size() + ") in message:" + _messages.getString(message)); + 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); } } - - item.put("parameters", parameters); - messageList.add(item); } } - return typeData; + return messageTypeData; } + /** + * Just a inner exception to be able to identify when a type that is not + * 'number' occurs in the message parameter text. + */ private class InvalidTypeException extends Throwable { public InvalidTypeException(String message) diff --git a/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm b/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm index 7360b8c403..6656763ab9 100644 --- a/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm +++ b/java/broker/src/velocity/templates/org/apache/qpid/server/logging/messages/LogMessages.vm @@ -56,10 +56,10 @@ public class ${type.name}Messages * Log a ${type.name} message of the Format: *
${message.format}
*/ - public static LogMessage ${message.methodName}(#foreach($parameter in ${message.parameters})${parameter.type} ${parameter.name}#if (${velocityCount} != ${message.parameters.size()} ),#end + public static LogMessage ${message.methodName}(#foreach($parameter in ${message.parameters})${parameter.type} ${parameter.name}#if (${velocityCount} != ${message.parameters.size()} ), #end #end) { - final Object[] messageArguments = {#foreach($parameter in ${message.parameters})${parameter.name}#if (${velocityCount} != ${message.parameters.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}")); return new LogMessage() -- cgit v1.2.1