1ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair/* 2ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Copyright 2007 the original author or authors. 3ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 4ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Licensed under the Apache License, Version 2.0 (the "License"); 5ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * you may not use this file except in compliance with the License. 6ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * You may obtain a copy of the License at 7ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 8ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * http://www.apache.org/licenses/LICENSE-2.0 9ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 10ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Unless required by applicable law or agreed to in writing, software 11ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * distributed under the License is distributed on an "AS IS" BASIS, 12ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * See the License for the specific language governing permissions and 14ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * limitations under the License. 15ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 16ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairpackage org.mockftpserver.stub.command; 17ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 18ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.apache.log4j.Logger; 19ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.easymock.MockControl; 20ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.AbstractCommandHandler; 21ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.Command; 22ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.InvocationHistory; 23ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.InvocationRecord; 24ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.ReplyCodes; 25ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.session.Session; 26ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.test.AbstractTest; 27ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 28ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport java.text.MessageFormat; 29ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport java.util.ListResourceBundle; 30ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport java.util.ResourceBundle; 31ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 32ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair/** 33ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Abstract superclass for CommandHandler tests 34ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 35ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @author Chris Mair 36ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @version $Revision$ - $Date$ 37ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 38ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairpublic abstract class AbstractCommandHandlerTest extends AbstractTest { 39ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 40ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair private static final Logger LOG = Logger.getLogger(AbstractCommandHandlerTest.class); 41ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 42ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair // Some common test constants 43ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected static final String DIR1 = "dir1"; 44ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected static final String DIR2 = "dir2"; 45ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected static final String FILENAME1 = "sample1.txt"; 46ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected static final String FILENAME2 = "sample2.txt"; 47ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 48ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected Session session; 49ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected ResourceBundle replyTextBundle; 50ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 51ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 52ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Test the handleCommand() method, when one or more parameter is missing or invalid 53ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 54ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param commandHandler - the CommandHandler to test 55ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param commandName - the name for the Command 56ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param parameters - the Command parameters 57ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 58ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void testHandleCommand_InvalidParameters(AbstractCommandHandler commandHandler, 59ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair String commandName, String[] parameters) throws Exception { 60ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair Command command = new Command(commandName, parameters); 61ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair session.sendReply(ReplyCodes.COMMAND_SYNTAX_ERROR, replyTextFor(ReplyCodes.COMMAND_SYNTAX_ERROR)); 62ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair replay(session); 63ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 64ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair commandHandler.handleCommand(command, session); 65ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair verify(session); 66ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 67ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair verifyNumberOfInvocations(commandHandler, 1); 68ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair verifyNoDataElements(commandHandler.getInvocation(0)); 69ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 70ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 71ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 72ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Verify that the CommandHandler contains the specified number of invocation records 73ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 74ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param commandHandler - the CommandHandler 75ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param expected - the expected number of invocations 76ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 77ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void verifyNumberOfInvocations(InvocationHistory commandHandler, int expected) { 78ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertEquals("number of invocations", expected, commandHandler.numberOfInvocations()); 79ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 80ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 81ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 82ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Verify that the InvocationRecord contains no data elements 83ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 84ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param invocationRecord - the InvocationRecord 85ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 86ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void verifyNoDataElements(InvocationRecord invocationRecord) { 87ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair LOG.info("Verifying: " + invocationRecord); 88ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertEquals("number of data elements", 0, invocationRecord.keySet().size()); 89ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 90ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 91ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 92ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Verify that the InvocationRecord contains exactly one data element, with the specified key 93ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * and value. 94ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 95ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param invocationRecord - the InvocationRecord 96ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param key - the expected key 97ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param value - the expected value 98ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 99ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void verifyOneDataElement(InvocationRecord invocationRecord, String key, Object value) { 100ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair LOG.info("Verifying: " + invocationRecord); 101ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertEquals("number of data elements", 1, invocationRecord.keySet().size()); 102ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertEqualsAllTypes("value:" + value, value, invocationRecord.getObject(key)); 103ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 104ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 105ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 106ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Verify that the InvocationRecord contains exactly two data element, with the specified keys 107ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * and values. 108ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 109ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param invocationRecord - the InvocationRecord 110ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param key1 - the expected key1 111ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param value1 - the expected value1 112ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param key2 - the expected key2 113ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param value2- the expected value2 114ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 115ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void verifyTwoDataElements(InvocationRecord invocationRecord, String key1, Object value1, 116ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair String key2, Object value2) { 117ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 118ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair LOG.info("Verifying: " + invocationRecord); 119ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertEquals("number of data elements", 2, invocationRecord.keySet().size()); 120ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertEqualsAllTypes("value1:" + value1, value1, invocationRecord.getObject(key1)); 121ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertEqualsAllTypes("value2:" + value2, value2, invocationRecord.getObject(key2)); 122ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 123ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 124ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 125ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Assert that the actual is equal to the expected, using arrays equality comparison if 126ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * necessary 127ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 128ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param message - the message, used if the comparison fails 129ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param expected - the expected value 130ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param actual - the actual value 131ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 132ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair private void assertEqualsAllTypes(String message, Object expected, Object actual) { 133ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 134ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair if (expected instanceof byte[] || actual instanceof byte[]) { 135ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertEquals(message, (byte[]) expected, (byte[]) actual); 136ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } else if (expected instanceof Object[] || actual instanceof Object[]) { 137ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertEquals(message, (Object[]) expected, (Object[]) actual); 138ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } else { 139ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair assertEquals(message, expected, actual); 140ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 141ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 142ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 143ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 144ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Perform setup before each test 145ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 146ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @see org.mockftpserver.test.AbstractTest#setUp() 147ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 148ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void setUp() throws Exception { 149ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair super.setUp(); 150ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 151ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair session = (Session) createMock(Session.class); 152ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair control(session).setDefaultMatcher(MockControl.ARRAY_MATCHER); 153ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair control(session).expectAndDefaultReturn(session.getClientHost(), DEFAULT_HOST); 154ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 155ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair replyTextBundle = new ListResourceBundle() { 156ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected Object[][] getContents() { 157ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return new Object[][]{ 158ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"150", replyTextFor(150)}, 159ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"200", replyTextFor(200)}, 160ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"211", replyTextWithParameterFor(211)}, 161ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"213", replyTextWithParameterFor(213)}, 162ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"214", replyTextWithParameterFor(214)}, 163ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"215", replyTextWithParameterFor(215)}, 164ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"220", replyTextFor(220)}, 165ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"221", replyTextFor(221)}, 166ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"226", replyTextFor(226)}, 167ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"226.WithFilename", replyTextWithParameterFor("226.WithFilename")}, 168ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"227", replyTextWithParameterFor(227)}, 169ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"230", replyTextFor(230)}, 170ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"250", replyTextFor(250)}, 171ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"257", replyTextWithParameterFor(257)}, 172ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"331", replyTextFor(331)}, 173ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"350", replyTextFor(350)}, 174ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair {"501", replyTextFor(501)}, 175ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair }; 176ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 177ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair }; 178ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 179ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 180ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 181ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Return the test-specific reply text for the specified reply code 182ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 183ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param replyCode - the reply code 184ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @return the reply text for the specified reply code 185ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 186ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected String replyTextFor(int replyCode) { 187ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return "Reply for " + replyCode; 188ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 189ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 190ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 191ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Return the test-specific parameterized reply text for the specified reply code 192ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 193ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param replyCode - the reply code 194ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @return the reply text for the specified reply code 195ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 196ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected String replyTextWithParameterFor(int replyCode) { 197ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return "Reply for " + replyCode + ":{0}"; 198ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 199ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 200ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 201ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Return the test-specific parameterized reply text for the specified messageKey 202ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 203ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param messageKey - the messageKey 204ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @return the reply text for the specified messageKey 205ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 206ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected String replyTextWithParameterFor(String messageKey) { 207ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return "Reply for " + messageKey + ":{0}"; 208ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 209ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 210ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 211ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Return the test-specific reply text for the specified reply code and message parameter 212ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 213ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param replyCode - the reply code 214ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param parameter - the message parameter value 215ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @return the reply text for the specified reply code 216ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 217ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected String formattedReplyTextFor(int replyCode, Object parameter) { 218ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return MessageFormat.format(replyTextWithParameterFor(replyCode), objArray(parameter)); 219ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 220ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 221ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 222ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Return the test-specific reply text for the specified message key and message parameter 223ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 224ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param messageKey - the messageKey 225ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param parameter - the message parameter value 226ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @return the reply text for the specified message key and parameter 227ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 228ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected String formattedReplyTextFor(String messageKey, Object parameter) { 229ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return MessageFormat.format(replyTextWithParameterFor(messageKey), objArray(parameter)); 230ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 231ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 232ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair} 233