/* * 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-2015 ForgeRock AS */ package org.opends.build.tools; import static org.opends.build.tools.Utilities.*; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.UnknownFormatConversionException; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.forgerock.i18n.LocalizableMessageDescriptor; import org.opends.messages.Category; import org.opends.messages.Severity; /** * 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; private static 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. */ private static String REGISTRY_FILE_NAME; private static 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. */ private static 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. */ private static 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. */ private static final String GLOBAL_CATEGORY_MASK = "global.mask"; /** * When true generates messages that have no ordinals. */ private static 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. */ private static final String GLOBAL_USE_MESSAGE_JAR_IF_WEBSTART = "global.use.message.jar.if.webstart"; private static final Set DIRECTIVE_PROPERTIES = new HashSet(Arrays.asList( GLOBAL_CATEGORY, GLOBAL_CATEGORY_MASK, GLOBAL_SEVERITY, GLOBAL_ORDINAL, GLOBAL_USE_MESSAGE_JAR_IF_WEBSTART)); private static final String SPECIFIER_REGEX = "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])"; private static final Pattern SPECIFIER_PATTERN = Pattern.compile(SPECIFIER_REGEX); /** * Message giving formatting rules for string keys. */ public static String KEY_FORM_MSG = ".\n\nOpenDJ message property keys must be of the form\n\n" + "\t\'[CATEGORY]_[SEVERITY]_[DESCRIPTION]_[ORDINAL]\'\n\n" // + "where\n\n" // + "CATEGORY is one of ..." // + EnumSet.allOf(Category.class) // + "\n\nSEVERITY is one of " // + Severity.getPropertyKeyFormSet() + "\n\nDESCRIPTION is a descriptive string composed " + "of uppercase character, digits and underscores " + "describing the purpose of the message " + "\n\nORDINAL is an integer between 0 and 65535 that is " + "unique to other messages defined in this file.\n\n" + "You can relax the mandate for including the CATEGORY, " + "SEVERITY, and/or ORDINAL by including one or more " + "of the following respective property directives in your properties file: " + GLOBAL_CATEGORY + ", " + GLOBAL_SEVERITY + ", " + GLOBAL_ORDINAL + "and setting their value appropriately."; /** 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 "