185efb15529d45e32fea8de03c38a968c157c8262chrismair/* 285efb15529d45e32fea8de03c38a968c157c8262chrismair * Copyright 2007 the original author or authors. 385efb15529d45e32fea8de03c38a968c157c8262chrismair * 485efb15529d45e32fea8de03c38a968c157c8262chrismair * Licensed under the Apache License, Version 2.0 (the "License"); 585efb15529d45e32fea8de03c38a968c157c8262chrismair * you may not use this file except in compliance with the License. 685efb15529d45e32fea8de03c38a968c157c8262chrismair * You may obtain a copy of the License at 785efb15529d45e32fea8de03c38a968c157c8262chrismair * 885efb15529d45e32fea8de03c38a968c157c8262chrismair * http://www.apache.org/licenses/LICENSE-2.0 985efb15529d45e32fea8de03c38a968c157c8262chrismair * 1085efb15529d45e32fea8de03c38a968c157c8262chrismair * Unless required by applicable law or agreed to in writing, software 1185efb15529d45e32fea8de03c38a968c157c8262chrismair * distributed under the License is distributed on an "AS IS" BASIS, 1285efb15529d45e32fea8de03c38a968c157c8262chrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1385efb15529d45e32fea8de03c38a968c157c8262chrismair * See the License for the specific language governing permissions and 1485efb15529d45e32fea8de03c38a968c157c8262chrismair * limitations under the License. 1585efb15529d45e32fea8de03c38a968c157c8262chrismair */ 1685efb15529d45e32fea8de03c38a968c157c8262chrismairpackage org.mockftpserver.core.command; 1785efb15529d45e32fea8de03c38a968c157c8262chrismair 1885efb15529d45e32fea8de03c38a968c157c8262chrismairimport java.text.MessageFormat; 1985efb15529d45e32fea8de03c38a968c157c8262chrismairimport java.util.ArrayList; 2085efb15529d45e32fea8de03c38a968c157c8262chrismairimport java.util.List; 2185efb15529d45e32fea8de03c38a968c157c8262chrismairimport java.util.MissingResourceException; 2285efb15529d45e32fea8de03c38a968c157c8262chrismairimport java.util.ResourceBundle; 2385efb15529d45e32fea8de03c38a968c157c8262chrismair 2485efb15529d45e32fea8de03c38a968c157c8262chrismairimport org.apache.log4j.Logger; 2585efb15529d45e32fea8de03c38a968c157c8262chrismairimport org.mockftpserver.core.session.Session; 2685efb15529d45e32fea8de03c38a968c157c8262chrismairimport org.mockftpserver.core.util.Assert; 2785efb15529d45e32fea8de03c38a968c157c8262chrismairimport org.mockftpserver.core.util.AssertFailedException; 2885efb15529d45e32fea8de03c38a968c157c8262chrismair 2985efb15529d45e32fea8de03c38a968c157c8262chrismair/** 3085efb15529d45e32fea8de03c38a968c157c8262chrismair * The abstract superclass for CommandHandler classes. This class manages the List of 3185efb15529d45e32fea8de03c38a968c157c8262chrismair * InvocationRecord objects corresponding to each invocation of the command handler, 3285efb15529d45e32fea8de03c38a968c157c8262chrismair * and provides helper methods for subclasses. 3385efb15529d45e32fea8de03c38a968c157c8262chrismair * 3485efb15529d45e32fea8de03c38a968c157c8262chrismair * @version $Revision$ - $Date$ 3585efb15529d45e32fea8de03c38a968c157c8262chrismair * 3685efb15529d45e32fea8de03c38a968c157c8262chrismair * @author Chris Mair 3785efb15529d45e32fea8de03c38a968c157c8262chrismair */ 3885efb15529d45e32fea8de03c38a968c157c8262chrismairpublic abstract class AbstractCommandHandler implements CommandHandler, ReplyTextBundleAware, InvocationHistory { 3985efb15529d45e32fea8de03c38a968c157c8262chrismair 4085efb15529d45e32fea8de03c38a968c157c8262chrismair private static final Logger LOG = Logger.getLogger(AbstractCommandHandler.class); 4185efb15529d45e32fea8de03c38a968c157c8262chrismair 4285efb15529d45e32fea8de03c38a968c157c8262chrismair private ResourceBundle replyTextBundle; 4385efb15529d45e32fea8de03c38a968c157c8262chrismair private List invocations = new ArrayList(); 4485efb15529d45e32fea8de03c38a968c157c8262chrismair 4585efb15529d45e32fea8de03c38a968c157c8262chrismair // ------------------------------------------------------------------------- 4685efb15529d45e32fea8de03c38a968c157c8262chrismair // Template Method 4785efb15529d45e32fea8de03c38a968c157c8262chrismair // ------------------------------------------------------------------------- 4885efb15529d45e32fea8de03c38a968c157c8262chrismair 4985efb15529d45e32fea8de03c38a968c157c8262chrismair /** 5085efb15529d45e32fea8de03c38a968c157c8262chrismair * Handle the specified command for the session. This method is declared to throw Exception, 5185efb15529d45e32fea8de03c38a968c157c8262chrismair * allowing CommandHandler implementations to avoid unnecessary exception-handling. All checked 5285efb15529d45e32fea8de03c38a968c157c8262chrismair * exceptions are expected to be wrapped and handled by the caller. 5385efb15529d45e32fea8de03c38a968c157c8262chrismair * 5485efb15529d45e32fea8de03c38a968c157c8262chrismair * @param command - the Command to be handled 5585efb15529d45e32fea8de03c38a968c157c8262chrismair * @param session - the session on which the Command was submitted 5685efb15529d45e32fea8de03c38a968c157c8262chrismair * 5785efb15529d45e32fea8de03c38a968c157c8262chrismair * @throws Exception 5885efb15529d45e32fea8de03c38a968c157c8262chrismair * @throws AssertFailedException - if the command or session is null 5985efb15529d45e32fea8de03c38a968c157c8262chrismair * 6085efb15529d45e32fea8de03c38a968c157c8262chrismair * @see org.mockftpserver.core.command.CommandHandler#handleCommand(org.mockftpserver.core.command.Command, 6185efb15529d45e32fea8de03c38a968c157c8262chrismair * org.mockftpserver.core.session.Session) 6285efb15529d45e32fea8de03c38a968c157c8262chrismair */ 6385efb15529d45e32fea8de03c38a968c157c8262chrismair public final void handleCommand(Command command, Session session) throws Exception { 6485efb15529d45e32fea8de03c38a968c157c8262chrismair Assert.notNull(command, "command"); 6585efb15529d45e32fea8de03c38a968c157c8262chrismair Assert.notNull(session, "session"); 6685efb15529d45e32fea8de03c38a968c157c8262chrismair InvocationRecord invocationRecord = new InvocationRecord(command, session.getClientHost()); 6785efb15529d45e32fea8de03c38a968c157c8262chrismair invocations.add(invocationRecord); 6885efb15529d45e32fea8de03c38a968c157c8262chrismair handleCommand(command, session, invocationRecord); 6985efb15529d45e32fea8de03c38a968c157c8262chrismair invocationRecord.lock(); 7085efb15529d45e32fea8de03c38a968c157c8262chrismair } 7185efb15529d45e32fea8de03c38a968c157c8262chrismair 7285efb15529d45e32fea8de03c38a968c157c8262chrismair /** 7385efb15529d45e32fea8de03c38a968c157c8262chrismair * Handle the specified command for the session. This method is declared to throw Exception, 7485efb15529d45e32fea8de03c38a968c157c8262chrismair * allowing CommandHandler implementations to avoid unnecessary exception-handling. All checked 7585efb15529d45e32fea8de03c38a968c157c8262chrismair * exceptions are expected to be wrapped and handled by the caller. 7685efb15529d45e32fea8de03c38a968c157c8262chrismair * 7785efb15529d45e32fea8de03c38a968c157c8262chrismair * @param command - the Command to be handled 7885efb15529d45e32fea8de03c38a968c157c8262chrismair * @param session - the session on which the Command was submitted 7985efb15529d45e32fea8de03c38a968c157c8262chrismair * @param invocationRecord - the InvocationRecord; CommandHandlers are expected to add 8085efb15529d45e32fea8de03c38a968c157c8262chrismair * handler-specific data to the InvocationRecord, as appropriate 8185efb15529d45e32fea8de03c38a968c157c8262chrismair * @throws Exception 8285efb15529d45e32fea8de03c38a968c157c8262chrismair */ 8385efb15529d45e32fea8de03c38a968c157c8262chrismair protected abstract void handleCommand(Command command, Session session, InvocationRecord invocationRecord) 8485efb15529d45e32fea8de03c38a968c157c8262chrismair throws Exception; 8585efb15529d45e32fea8de03c38a968c157c8262chrismair 8685efb15529d45e32fea8de03c38a968c157c8262chrismair //------------------------------------------------------------------------- 8785efb15529d45e32fea8de03c38a968c157c8262chrismair // Support for reply text ResourceBundle 8885efb15529d45e32fea8de03c38a968c157c8262chrismair //------------------------------------------------------------------------- 8985efb15529d45e32fea8de03c38a968c157c8262chrismair 9085efb15529d45e32fea8de03c38a968c157c8262chrismair /** 9185efb15529d45e32fea8de03c38a968c157c8262chrismair * Return the ResourceBundle containing the reply text messages 9285efb15529d45e32fea8de03c38a968c157c8262chrismair * @return the replyTextBundle 9385efb15529d45e32fea8de03c38a968c157c8262chrismair * 9485efb15529d45e32fea8de03c38a968c157c8262chrismair * @see org.mockftpserver.core.command.ReplyTextBundleAware#getReplyTextBundle() 9585efb15529d45e32fea8de03c38a968c157c8262chrismair */ 9685efb15529d45e32fea8de03c38a968c157c8262chrismair public ResourceBundle getReplyTextBundle() { 9785efb15529d45e32fea8de03c38a968c157c8262chrismair return replyTextBundle; 9885efb15529d45e32fea8de03c38a968c157c8262chrismair } 9985efb15529d45e32fea8de03c38a968c157c8262chrismair 10085efb15529d45e32fea8de03c38a968c157c8262chrismair /** 10185efb15529d45e32fea8de03c38a968c157c8262chrismair * Set the ResourceBundle containing the reply text messages 10285efb15529d45e32fea8de03c38a968c157c8262chrismair * @param replyTextBundle - the replyTextBundle to set 10385efb15529d45e32fea8de03c38a968c157c8262chrismair * 10485efb15529d45e32fea8de03c38a968c157c8262chrismair * @see org.mockftpserver.core.command.ReplyTextBundleAware#setReplyTextBundle(java.util.ResourceBundle) 10585efb15529d45e32fea8de03c38a968c157c8262chrismair */ 10685efb15529d45e32fea8de03c38a968c157c8262chrismair public void setReplyTextBundle(ResourceBundle replyTextBundle) { 10785efb15529d45e32fea8de03c38a968c157c8262chrismair this.replyTextBundle = replyTextBundle; 10885efb15529d45e32fea8de03c38a968c157c8262chrismair } 10985efb15529d45e32fea8de03c38a968c157c8262chrismair 11085efb15529d45e32fea8de03c38a968c157c8262chrismair // ------------------------------------------------------------------------- 11185efb15529d45e32fea8de03c38a968c157c8262chrismair // Utility methods for subclasses 11285efb15529d45e32fea8de03c38a968c157c8262chrismair // ------------------------------------------------------------------------- 11385efb15529d45e32fea8de03c38a968c157c8262chrismair 11485efb15529d45e32fea8de03c38a968c157c8262chrismair /** 11585efb15529d45e32fea8de03c38a968c157c8262chrismair * Send a reply for this command on the control connection. 11685efb15529d45e32fea8de03c38a968c157c8262chrismair * 11785efb15529d45e32fea8de03c38a968c157c8262chrismair * The reply code is designated by the <code>replyCode</code> property, and the reply text 11885efb15529d45e32fea8de03c38a968c157c8262chrismair * is determined by the following rules: 11985efb15529d45e32fea8de03c38a968c157c8262chrismair * <ol> 12085efb15529d45e32fea8de03c38a968c157c8262chrismair * <li>If the <code>replyText</code> property is non-null, then use that.</li> 12185efb15529d45e32fea8de03c38a968c157c8262chrismair * <li>Otherwise, if <code>replyMessageKey</code> is non-null, the use that to retrieve a 12285efb15529d45e32fea8de03c38a968c157c8262chrismair * localized message from the <code>replyText</code> ResourceBundle.</li> 12385efb15529d45e32fea8de03c38a968c157c8262chrismair * <li>Otherwise, retrieve the reply text from the <code>replyText</code> ResourceBundle, 12485efb15529d45e32fea8de03c38a968c157c8262chrismair * using the reply code as the key.</li> 12585efb15529d45e32fea8de03c38a968c157c8262chrismair * </ol> 12685efb15529d45e32fea8de03c38a968c157c8262chrismair * If the arguments Object[] is not null, then these arguments are substituted within the 12785efb15529d45e32fea8de03c38a968c157c8262chrismair * reply text using the {@link MessageFormat} class. 12885efb15529d45e32fea8de03c38a968c157c8262chrismair * 12985efb15529d45e32fea8de03c38a968c157c8262chrismair * @param session - the Session 13085efb15529d45e32fea8de03c38a968c157c8262chrismair * @param replyCode - the reply code 13185efb15529d45e32fea8de03c38a968c157c8262chrismair * @param replyMessageKey - if not null (and replyText is null), this is used as the ResourceBundle 13285efb15529d45e32fea8de03c38a968c157c8262chrismair * message key instead of the reply code. 13385efb15529d45e32fea8de03c38a968c157c8262chrismair * @param replyText - if non-null, this is used as the reply text 13485efb15529d45e32fea8de03c38a968c157c8262chrismair * @param arguments - the array of arguments to be formatted and substituted within the reply 13585efb15529d45e32fea8de03c38a968c157c8262chrismair * text; may be null 13685efb15529d45e32fea8de03c38a968c157c8262chrismair * 13785efb15529d45e32fea8de03c38a968c157c8262chrismair * @throws AssertFailedException - if session is null 13885efb15529d45e32fea8de03c38a968c157c8262chrismair * 13985efb15529d45e32fea8de03c38a968c157c8262chrismair * @see MessageFormat 14085efb15529d45e32fea8de03c38a968c157c8262chrismair */ 14185efb15529d45e32fea8de03c38a968c157c8262chrismair protected void sendReply(Session session, int replyCode, String replyMessageKey, String replyText, 14285efb15529d45e32fea8de03c38a968c157c8262chrismair Object[] arguments) { 14385efb15529d45e32fea8de03c38a968c157c8262chrismair 14485efb15529d45e32fea8de03c38a968c157c8262chrismair Assert.notNull(session, "session"); 14585efb15529d45e32fea8de03c38a968c157c8262chrismair assertValidReplyCode(replyCode); 14685efb15529d45e32fea8de03c38a968c157c8262chrismair 14785efb15529d45e32fea8de03c38a968c157c8262chrismair final Logger HANDLER_LOG = Logger.getLogger(getClass()); 14885efb15529d45e32fea8de03c38a968c157c8262chrismair String key = (replyMessageKey != null) ? replyMessageKey : Integer.toString(replyCode); 14985efb15529d45e32fea8de03c38a968c157c8262chrismair String text = getTextForReplyCode(replyCode, key, replyText, arguments); 15085efb15529d45e32fea8de03c38a968c157c8262chrismair String replyTextToLog = (text == null) ? "" : " " + text; 15185efb15529d45e32fea8de03c38a968c157c8262chrismair HANDLER_LOG.debug("Sending reply [" + replyCode + replyTextToLog + "]"); 15285efb15529d45e32fea8de03c38a968c157c8262chrismair session.sendReply(replyCode, text); 15385efb15529d45e32fea8de03c38a968c157c8262chrismair } 15485efb15529d45e32fea8de03c38a968c157c8262chrismair 15585efb15529d45e32fea8de03c38a968c157c8262chrismair /** 15685efb15529d45e32fea8de03c38a968c157c8262chrismair * Return the specified text surrounded with double quotes 15785efb15529d45e32fea8de03c38a968c157c8262chrismair * 15885efb15529d45e32fea8de03c38a968c157c8262chrismair * @param text - the text to surround with quotes 15985efb15529d45e32fea8de03c38a968c157c8262chrismair * @return the text with leading and trailing double quotes 16085efb15529d45e32fea8de03c38a968c157c8262chrismair * 16185efb15529d45e32fea8de03c38a968c157c8262chrismair * @throws AssertFailedException - if text is null 16285efb15529d45e32fea8de03c38a968c157c8262chrismair */ 16385efb15529d45e32fea8de03c38a968c157c8262chrismair protected static String quotes(String text) { 16485efb15529d45e32fea8de03c38a968c157c8262chrismair Assert.notNull(text, "text"); 16585efb15529d45e32fea8de03c38a968c157c8262chrismair final String QUOTES = "\""; 16685efb15529d45e32fea8de03c38a968c157c8262chrismair return QUOTES + text + QUOTES; 16785efb15529d45e32fea8de03c38a968c157c8262chrismair } 16885efb15529d45e32fea8de03c38a968c157c8262chrismair 16985efb15529d45e32fea8de03c38a968c157c8262chrismair /** 17085efb15529d45e32fea8de03c38a968c157c8262chrismair * Assert that the specified number is a valid reply code 17185efb15529d45e32fea8de03c38a968c157c8262chrismair * @param replyCode - the reply code to check 17285efb15529d45e32fea8de03c38a968c157c8262chrismair * 17385efb15529d45e32fea8de03c38a968c157c8262chrismair * @throws AssertFailedException - if the replyCode is invalid 17485efb15529d45e32fea8de03c38a968c157c8262chrismair */ 17585efb15529d45e32fea8de03c38a968c157c8262chrismair protected void assertValidReplyCode(int replyCode) { 17685efb15529d45e32fea8de03c38a968c157c8262chrismair Assert.isTrue(replyCode > 0, "The number [" + replyCode + "] is not a valid reply code"); 17785efb15529d45e32fea8de03c38a968c157c8262chrismair } 17885efb15529d45e32fea8de03c38a968c157c8262chrismair 17985efb15529d45e32fea8de03c38a968c157c8262chrismair // ------------------------------------------------------------------------- 18085efb15529d45e32fea8de03c38a968c157c8262chrismair // InvocationHistory - Support for command history 18185efb15529d45e32fea8de03c38a968c157c8262chrismair // ------------------------------------------------------------------------- 18285efb15529d45e32fea8de03c38a968c157c8262chrismair 18385efb15529d45e32fea8de03c38a968c157c8262chrismair /** 18485efb15529d45e32fea8de03c38a968c157c8262chrismair * @return the number of invocation records stored for this command handler instance 18585efb15529d45e32fea8de03c38a968c157c8262chrismair * 18685efb15529d45e32fea8de03c38a968c157c8262chrismair * @see org.mockftpserver.core.command.InvocationHistory#numberOfInvocations() 18785efb15529d45e32fea8de03c38a968c157c8262chrismair */ 18885efb15529d45e32fea8de03c38a968c157c8262chrismair public int numberOfInvocations() { 18985efb15529d45e32fea8de03c38a968c157c8262chrismair return invocations.size(); 19085efb15529d45e32fea8de03c38a968c157c8262chrismair } 19185efb15529d45e32fea8de03c38a968c157c8262chrismair 19285efb15529d45e32fea8de03c38a968c157c8262chrismair /** 19385efb15529d45e32fea8de03c38a968c157c8262chrismair * Return the InvocationRecord representing the command invoction data for the nth invocation 19485efb15529d45e32fea8de03c38a968c157c8262chrismair * for this command handler instance. One InvocationRecord should be stored for each invocation 19585efb15529d45e32fea8de03c38a968c157c8262chrismair * of the CommandHandler. 19685efb15529d45e32fea8de03c38a968c157c8262chrismair * 19785efb15529d45e32fea8de03c38a968c157c8262chrismair * @param index - the index of the invocation record to return. The first record is at index zero. 19885efb15529d45e32fea8de03c38a968c157c8262chrismair * @return the InvocationRecord for the specified index 19985efb15529d45e32fea8de03c38a968c157c8262chrismair * 20085efb15529d45e32fea8de03c38a968c157c8262chrismair * @throws AssertFailedException - if there is no invocation record corresponding to the specified index 20185efb15529d45e32fea8de03c38a968c157c8262chrismair * 20285efb15529d45e32fea8de03c38a968c157c8262chrismair * @see org.mockftpserver.core.command.InvocationHistory#getInvocation(int) 20385efb15529d45e32fea8de03c38a968c157c8262chrismair */ 20485efb15529d45e32fea8de03c38a968c157c8262chrismair public InvocationRecord getInvocation(int index) { 20585efb15529d45e32fea8de03c38a968c157c8262chrismair return (InvocationRecord) invocations.get(index); 20685efb15529d45e32fea8de03c38a968c157c8262chrismair } 20785efb15529d45e32fea8de03c38a968c157c8262chrismair 20885efb15529d45e32fea8de03c38a968c157c8262chrismair /** 20985efb15529d45e32fea8de03c38a968c157c8262chrismair * Clear out the invocation history for this CommandHandler. After invoking this method, the 21085efb15529d45e32fea8de03c38a968c157c8262chrismair * <code>numberOfInvocations()</code> method will return zero. 21185efb15529d45e32fea8de03c38a968c157c8262chrismair * 21285efb15529d45e32fea8de03c38a968c157c8262chrismair * @see org.mockftpserver.core.command.InvocationHistory#clearInvocations() 21385efb15529d45e32fea8de03c38a968c157c8262chrismair */ 21485efb15529d45e32fea8de03c38a968c157c8262chrismair public void clearInvocations() { 21585efb15529d45e32fea8de03c38a968c157c8262chrismair invocations.clear(); 21685efb15529d45e32fea8de03c38a968c157c8262chrismair } 21785efb15529d45e32fea8de03c38a968c157c8262chrismair 21885efb15529d45e32fea8de03c38a968c157c8262chrismair // ------------------------------------------------------------------------- 21985efb15529d45e32fea8de03c38a968c157c8262chrismair // Internal Helper Methods 22085efb15529d45e32fea8de03c38a968c157c8262chrismair // ------------------------------------------------------------------------- 22185efb15529d45e32fea8de03c38a968c157c8262chrismair 22285efb15529d45e32fea8de03c38a968c157c8262chrismair /** 22385efb15529d45e32fea8de03c38a968c157c8262chrismair * Return the text for the specified reply code, formatted using the message arguments, if 22485efb15529d45e32fea8de03c38a968c157c8262chrismair * supplied. If overrideText is not null, then return that. Otherwise, return the text mapped to 22585efb15529d45e32fea8de03c38a968c157c8262chrismair * the code from the replyText ResourceBundle. If the ResourceBundle contains no mapping, then 22685efb15529d45e32fea8de03c38a968c157c8262chrismair * return null. 22785efb15529d45e32fea8de03c38a968c157c8262chrismair * <p> 22885efb15529d45e32fea8de03c38a968c157c8262chrismair * If arguments is not null, then the returned reply text if formatted using the 22985efb15529d45e32fea8de03c38a968c157c8262chrismair * {@link MessageFormat} class. 23085efb15529d45e32fea8de03c38a968c157c8262chrismair * 23185efb15529d45e32fea8de03c38a968c157c8262chrismair * @param code - the reply code 23285efb15529d45e32fea8de03c38a968c157c8262chrismair * @param messageKey - the key used to retrieve the reply text from the replyTextBundle 23385efb15529d45e32fea8de03c38a968c157c8262chrismair * @param overrideText - if not null, this is used instead of the text from the replyTextBundle. 23485efb15529d45e32fea8de03c38a968c157c8262chrismair * @param arguments - the array of arguments to be formatted and substituted within the reply 23585efb15529d45e32fea8de03c38a968c157c8262chrismair * text; may be null 23685efb15529d45e32fea8de03c38a968c157c8262chrismair * @return the text for the reply code; may be null 23785efb15529d45e32fea8de03c38a968c157c8262chrismair */ 23885efb15529d45e32fea8de03c38a968c157c8262chrismair private String getTextForReplyCode(int code, String messageKey, String overrideText, Object[] arguments) { 23985efb15529d45e32fea8de03c38a968c157c8262chrismair try { 24085efb15529d45e32fea8de03c38a968c157c8262chrismair String t = (overrideText == null) ? replyTextBundle.getString(messageKey) : overrideText; 24185efb15529d45e32fea8de03c38a968c157c8262chrismair String formattedMessage = MessageFormat.format(t, arguments); 24285efb15529d45e32fea8de03c38a968c157c8262chrismair return (formattedMessage == null) ? null : formattedMessage.trim(); 24385efb15529d45e32fea8de03c38a968c157c8262chrismair } 24485efb15529d45e32fea8de03c38a968c157c8262chrismair catch (MissingResourceException e) { 24585efb15529d45e32fea8de03c38a968c157c8262chrismair // No reply text is mapped for the specified key 24685efb15529d45e32fea8de03c38a968c157c8262chrismair LOG.warn("No reply text defined for reply code [" + code + "]"); 24785efb15529d45e32fea8de03c38a968c157c8262chrismair return null; 24885efb15529d45e32fea8de03c38a968c157c8262chrismair } 24985efb15529d45e32fea8de03c38a968c157c8262chrismair } 25085efb15529d45e32fea8de03c38a968c157c8262chrismair 25185efb15529d45e32fea8de03c38a968c157c8262chrismair} 252