/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2011-2012 ForgeRock AS */ package org.opends.build.tools; import org.apache.tools.ant.Task; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import static org.opends.build.tools.Utilities.*; import org.opends.messages.Category; import org.opends.messages.Severity; import org.opends.messages.MessageDescriptor; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.DataOutputStream; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Properties; import java.util.List; import java.util.ArrayList; import java.util.TreeSet; import java.util.UnknownFormatConversionException; import java.util.Calendar; import java.util.Arrays; import java.util.Locale; import java.util.Map; import java.util.TreeMap; import java.util.HashSet; import java.util.Set; import java.util.EnumSet; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Generates a Java class containing representations of messages * found in a properties file. */ public class GenerateMessageFile extends Task { private File source; private File dest; private boolean overwrite; private boolean writeLogRef; static private final String MESSAGES_FILE_STUB = "resource/Messages.java.stub"; /* * The registry filename is the result of the concatenation of the * location of where the source are generated, the package name and the * DESCRIPTORS_REG value. */ static private String REGISTRY_FILE_NAME; static private final String DESCRIPTORS_REG = "descriptors.reg"; /** * Used to set a category for all messages in the property file. * If set, the category for each message need not be encoded in * the message's property file key. */ static private final String GLOBAL_CATEGORY = "global.category"; /** * Used to set a severity for all messages in the property file. * If set, the severity for each message need not be encoded in * the message's property file key. */ static private final String GLOBAL_SEVERITY = "global.severity"; /** * Used to set a category mask for all messages in the property * file. If set, the category will automatically be assigned * USER_DEFINED and the value of GLOBAL_CATEGORY * will be ignored. */ static private final String GLOBAL_CATEGORY_MASK = "global.mask"; /** * When true generates messages that have no ordinals. */ static private final String GLOBAL_ORDINAL = "global.ordinal"; /** * When true and if the Java Web Start property is set use the class loader of * the jar where the MessageDescriptor is contained to retrieve the * ResourceBundle. */ static private final String GLOBAL_USE_MESSAGE_JAR_IF_WEBSTART = "global.use.message.jar.if.webstart"; static private final Set DIRECTIVE_PROPERTIES = new HashSet(); static { DIRECTIVE_PROPERTIES.add(GLOBAL_CATEGORY); DIRECTIVE_PROPERTIES.add(GLOBAL_CATEGORY_MASK); DIRECTIVE_PROPERTIES.add(GLOBAL_SEVERITY); DIRECTIVE_PROPERTIES.add(GLOBAL_ORDINAL); DIRECTIVE_PROPERTIES.add(GLOBAL_USE_MESSAGE_JAR_IF_WEBSTART); } static private final String SPECIFIER_REGEX = "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])"; private final Pattern SPECIFIER_PATTERN = Pattern.compile(SPECIFIER_REGEX); /** * Message giving formatting rules for string keys. */ static public String KEY_FORM_MSG; static { KEY_FORM_MSG = new StringBuilder() .append(".\n\nOpenDJ message property keys must be of the form\n\n") .append("\t\'[CATEGORY]_[SEVERITY]_[DESCRIPTION]_[ORDINAL]\'\n\n") .append("where\n\n") .append("CATEGORY is one of ") .append(EnumSet.allOf(Category.class)) .append("\n\nSEVERITY is one of ") .append(Severity.getPropertyKeyFormSet().toString()) .append("\n\nDESCRIPTION is a descriptive string composed ") .append("of uppercase character, digits and underscores ") .append("describing the purpose of the message ") .append("\n\nORDINAL is an integer between 0 and 65535 that is ") .append("unique to other messages defined in this file.\n\n") .append("You can relax the mandate for including the CATEGORY, ") .append("SEVERITY, and/or ORDINAL by including one or more ") .append("of the following respective property directives in your ") .append("properties file: ") .append(GLOBAL_CATEGORY) .append(", ") .append(GLOBAL_SEVERITY) .append(", ") .append(GLOBAL_ORDINAL) .append("and setting their value appropriately.") .toString(); } /* * ISO_LANGUAGES contains all official supported languages for i18n */ private static final List ISO_LANGUAGES = Arrays.asList(Locale.getISOLanguages()); /* * ISO_COUNTRIES contains all official supported countries for i18n */ private static final List ISO_COUNTRIES = Arrays.asList(Locale.getISOCountries()); /* * A Pattern instance that matches "