14bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair/*
24bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * Copyright 2007 the original author or authors.
34bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair *
44bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * Licensed under the Apache License, Version 2.0 (the "License");
54bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * you may not use this file except in compliance with the License.
64bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * You may obtain a copy of the License at
74bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair *
84bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair *      http://www.apache.org/licenses/LICENSE-2.0
94bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair *
104bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * Unless required by applicable law or agreed to in writing, software
114bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * distributed under the License is distributed on an "AS IS" BASIS,
124bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * See the License for the specific language governing permissions and
144bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * limitations under the License.
154bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair */
164bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairpackage org.mockftpserver.core.command;
174bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
184bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairimport java.text.MessageFormat;
194bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairimport java.util.ArrayList;
204bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairimport java.util.List;
214bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairimport java.util.MissingResourceException;
224bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairimport java.util.ResourceBundle;
234bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
244bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairimport org.apache.log4j.Logger;
254bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairimport org.mockftpserver.core.session.Session;
264bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairimport org.mockftpserver.core.util.Assert;
274bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairimport org.mockftpserver.core.util.AssertFailedException;
284bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
294bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair/**
304bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * The abstract superclass for CommandHandler classes. This class manages the List of
314bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * InvocationRecord objects corresponding to each invocation of the command handler,
324bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * and provides helper methods for subclasses.
334bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair *
344bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * @version $Revision$ - $Date$
354bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair *
364bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair * @author Chris Mair
374bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair */
384bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismairpublic abstract class AbstractCommandHandler implements CommandHandler, ReplyTextBundleAware, InvocationHistory {
394bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
404bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    private static final Logger LOG = Logger.getLogger(AbstractCommandHandler.class);
414bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
424bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    private ResourceBundle replyTextBundle;
434bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    private List invocations = new ArrayList();
444bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
454bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // -------------------------------------------------------------------------
464bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // Template Method
474bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // -------------------------------------------------------------------------
484bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
494bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
504bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * Handle the specified command for the session. This method is declared to throw Exception,
514bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * allowing CommandHandler implementations to avoid unnecessary exception-handling. All checked
524bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * exceptions are expected to be wrapped and handled by the caller.
534bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
544bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param command - the Command to be handled
554bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param session - the session on which the Command was submitted
564bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
574bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @throws Exception
584bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @throws AssertFailedException - if the command or session is null
594bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
604bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @see org.mockftpserver.core.command.CommandHandler#handleCommand(org.mockftpserver.core.command.Command,
614bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *      org.mockftpserver.core.session.Session)
624bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
634bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    public final void handleCommand(Command command, Session session) throws Exception {
644bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        Assert.notNull(command, "command");
654bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        Assert.notNull(session, "session");
664bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        InvocationRecord invocationRecord = new InvocationRecord(command, session.getClientHost());
674bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        invocations.add(invocationRecord);
684bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        handleCommand(command, session, invocationRecord);
694bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        invocationRecord.lock();
704bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    }
714bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
724bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
734bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * Handle the specified command for the session. This method is declared to throw Exception,
744bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * allowing CommandHandler implementations to avoid unnecessary exception-handling. All checked
754bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * exceptions are expected to be wrapped and handled by the caller.
764bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
774bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param command - the Command to be handled
784bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param session - the session on which the Command was submitted
794bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param invocationRecord - the InvocationRecord; CommandHandlers are expected to add
804bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *        handler-specific data to the InvocationRecord, as appropriate
814bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @throws Exception
824bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
834bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    protected abstract void handleCommand(Command command, Session session, InvocationRecord invocationRecord)
844bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair            throws Exception;
854bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
864bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    //-------------------------------------------------------------------------
874bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // Support for reply text ResourceBundle
884bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    //-------------------------------------------------------------------------
894bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
904bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
914bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * Return the ResourceBundle containing the reply text messages
924bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @return the replyTextBundle
934bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
944bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @see org.mockftpserver.core.command.ReplyTextBundleAware#getReplyTextBundle()
954bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
964bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    public ResourceBundle getReplyTextBundle() {
974bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        return replyTextBundle;
984bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    }
994bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
1004bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
1014bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * Set the ResourceBundle containing the reply text messages
1024bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param replyTextBundle - the replyTextBundle to set
1034bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
1044bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @see org.mockftpserver.core.command.ReplyTextBundleAware#setReplyTextBundle(java.util.ResourceBundle)
1054bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
1064bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    public void setReplyTextBundle(ResourceBundle replyTextBundle) {
1074bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        this.replyTextBundle = replyTextBundle;
1084bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    }
1094bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
1104bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // -------------------------------------------------------------------------
1114bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // Utility methods for subclasses
1124bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // -------------------------------------------------------------------------
1134bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
1144bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
1154bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * Send a reply for this command on the control connection.
1164bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
1174bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * The reply code is designated by the <code>replyCode</code> property, and the reply text
1184bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * is determined by the following rules:
1194bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * <ol>
1204bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *   <li>If the <code>replyText</code> property is non-null, then use that.</li>
1214bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *   <li>Otherwise, if <code>replyMessageKey</code> is non-null, the use that to retrieve a
1224bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *      localized message from the <code>replyText</code> ResourceBundle.</li>
1234bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *   <li>Otherwise, retrieve the reply text from the <code>replyText</code> ResourceBundle,
1244bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *      using the reply code as the key.</li>
1254bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * </ol>
1264bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * If the arguments Object[] is not null, then these arguments are substituted within the
1274bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * reply text using the {@link MessageFormat} class.
1284bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
1294bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param session - the Session
1304bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param replyCode - the reply code
1314bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param replyMessageKey - if not null (and replyText is null), this is used as the ResourceBundle
1324bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *      message key instead of the reply code.
1334bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param replyText - if non-null, this is used as the reply text
1344bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param arguments - the array of arguments to be formatted and substituted within the reply
1354bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *        text; may be null
1364bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
1374bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @throws AssertFailedException - if session is null
1384bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
1394bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @see MessageFormat
1404bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
1414bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    protected void sendReply(Session session, int replyCode, String replyMessageKey, String replyText,
1424bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair            Object[] arguments) {
1434bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
1444bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        Assert.notNull(session, "session");
1454bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        assertValidReplyCode(replyCode);
1464bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
1474bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        final Logger HANDLER_LOG = Logger.getLogger(getClass());
1484bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        String key = (replyMessageKey != null) ? replyMessageKey : Integer.toString(replyCode);
1494bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        String text = getTextForReplyCode(replyCode, key, replyText, arguments);
1504bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        String replyTextToLog = (text == null) ? "" : " " + text;
1514bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        HANDLER_LOG.debug("Sending reply [" + replyCode + replyTextToLog + "]");
1524bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        session.sendReply(replyCode, text);
1534bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    }
1544bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
1554bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
1564bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * Return the specified text surrounded with double quotes
1574bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
1584bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param text - the text to surround with quotes
1594bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @return the text with leading and trailing double quotes
1604bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
1614bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @throws AssertFailedException - if text is null
1624bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
1634bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    protected static String quotes(String text) {
1644bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        Assert.notNull(text, "text");
1654bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        final String QUOTES = "\"";
1664bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        return QUOTES + text + QUOTES;
1674bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    }
1684bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
1694bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
1704bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * Assert that the specified number is a valid reply code
1714bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param replyCode - the reply code to check
1724bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
1734bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @throws AssertFailedException - if the replyCode is invalid
1744bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
1754bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    protected void assertValidReplyCode(int replyCode) {
1764bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        Assert.isTrue(replyCode > 0, "The number [" + replyCode + "] is not a valid reply code");
1774bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    }
1784bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
1794bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // -------------------------------------------------------------------------
1804bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // InvocationHistory - Support for command history
1814bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // -------------------------------------------------------------------------
1824bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
1834bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
1844bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @return the number of invocation records stored for this command handler instance
1854bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
1864bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @see org.mockftpserver.core.command.InvocationHistory#numberOfInvocations()
1874bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
1884bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    public int numberOfInvocations() {
1894bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        return invocations.size();
1904bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    }
1914bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
1924bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
1934bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * Return the InvocationRecord representing the command invoction data for the nth invocation
1944bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * for this command handler instance. One InvocationRecord should be stored for each invocation
1954bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * of the CommandHandler.
1964bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
1974bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param index - the index of the invocation record to return. The first record is at index zero.
1984bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @return the InvocationRecord for the specified index
1994bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
2004bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @throws AssertFailedException - if there is no invocation record corresponding to the specified index
2014bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
2024bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @see org.mockftpserver.core.command.InvocationHistory#getInvocation(int)
2034bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
2044bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    public InvocationRecord getInvocation(int index) {
2054bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        return (InvocationRecord) invocations.get(index);
2064bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    }
2074bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
2084bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
2094bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * Clear out the invocation history for this CommandHandler. After invoking this method, the
2104bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * <code>numberOfInvocations()</code> method will return zero.
2114bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
2124bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @see org.mockftpserver.core.command.InvocationHistory#clearInvocations()
2134bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
2144bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    public void clearInvocations() {
2154bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        invocations.clear();
2164bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    }
2174bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
2184bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // -------------------------------------------------------------------------
2194bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // Internal Helper Methods
2204bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    // -------------------------------------------------------------------------
2214bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
2224bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    /**
2234bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * Return the text for the specified reply code, formatted using the message arguments, if
2244bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * supplied. If overrideText is not null, then return that. Otherwise, return the text mapped to
2254bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * the code from the replyText ResourceBundle. If the ResourceBundle contains no mapping, then
2264bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * return null.
2274bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * <p>
2284bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * If arguments is not null, then the returned reply text if formatted using the
2294bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * {@link MessageFormat} class.
2304bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *
2314bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param code - the reply code
2324bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param messageKey - the key used to retrieve the reply text from the replyTextBundle
2334bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param overrideText - if not null, this is used instead of the text from the replyTextBundle.
2344bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @param arguments - the array of arguments to be formatted and substituted within the reply
2354bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     *        text; may be null
2364bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     * @return the text for the reply code; may be null
2374bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair     */
2384bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    private String getTextForReplyCode(int code, String messageKey, String overrideText, Object[] arguments) {
2394bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        try {
2404bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair            String t = (overrideText == null) ? replyTextBundle.getString(messageKey) : overrideText;
2414bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair            String formattedMessage = MessageFormat.format(t, arguments);
2424bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair            return (formattedMessage == null) ? null : formattedMessage.trim();
2434bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        }
2444bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        catch (MissingResourceException e) {
2454bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair            // No reply text is mapped for the specified key
2464bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair            LOG.warn("No reply text defined for reply code [" + code + "]");
2474bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair            return null;
2484bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair        }
2494bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair    }
2504bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair
2514bc314fb002f3e5369cd724b91e83e0c71aeeccbchrismair}
252