Index: default.properties =================================================================== --- default.properties (revision 360174) +++ default.properties (working copy) @@ -50,6 +50,9 @@ build.lib = ${build.dir}/lib build.src = ${build.dir}/src build.classes = ${build.dir}/classes +build.test = ${build.dir}/test +build.test.classes = ${build.test}/classes +build.test.reports = ${build.test}/reports build.javadocs = ${build.docs}/javadocs build.docs = ${build.dir}/docs build.mailetdocs = ${build.dir}/mailetdocs @@ -62,6 +65,7 @@ src.dir=${james.dir}/src java.dir=${src.dir}/java +junitjava.dir=${src.dir}/test conf.dir=${src.dir}/conf xdocs.dir=${src.dir}/xdocs docs.src=${xdocs.dir} @@ -83,3 +87,7 @@ www.dir = ${james.dir}/www +# +# +# + Index: tools/lib/junit.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: tools/lib/junit.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: tools/lib/ristretto-1.0-all.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: tools/lib/ristretto-1.0-all.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: tools/lib/LICENSE.ristretto.txt =================================================================== --- tools/lib/LICENSE.ristretto.txt (revision 0) +++ tools/lib/LICENSE.ristretto.txt (revision 0) @@ -0,0 +1,35 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ristretto Mail API. + * + * The Initial Developers of the Original Code are + * Timo Stich and Frederik Dietz. + * Portions created by the Initial Developers are Copyright (C) 2004 + * All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ \ No newline at end of file Index: src/test/org/apache/james/JamesTest.java =================================================================== --- src/test/org/apache/james/JamesTest.java (revision 0) +++ src/test/org/apache/james/JamesTest.java (revision 0) @@ -0,0 +1,73 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james; + +import org.apache.james.services.MailServerTestAllImplementations; +import org.apache.james.services.MailServer; +import org.apache.james.test.mock.avalon.MockServiceManager; +import org.apache.james.test.mock.avalon.MockLogger; +import org.apache.james.test.mock.avalon.MockStore; +import org.apache.james.test.mock.avalon.MockContext; +import org.apache.james.test.mock.james.MockUsersRepository; +import org.apache.james.test.mock.james.MockUsersStore; + +import java.io.File; + +public class JamesTest extends MailServerTestAllImplementations { + + public MailServer createMailServer() { + James james = new James(); + james.service(setUpServiceManager()); + MockLogger mockLogger = new MockLogger(); + mockLogger.disableDebug(); + james.enableLogging(mockLogger); + try { + JamesTestConfiguration conf = new JamesTestConfiguration(); + conf.init(); + james.configure(conf); + james.contextualize(new MockContext(File.createTempFile("james_test", "tmp"))); + james.initialize(); + } catch (Exception e) { + e.printStackTrace(); + fail("James.initialize() failed"); + } + return james; + } + + private MockServiceManager setUpServiceManager() { + MockServiceManager serviceManager = new MockServiceManager(); + MockUsersRepository mockUsersRepository = new MockUsersRepository(); + serviceManager.put("org.apache.james.services.UsersRepository", mockUsersRepository); + serviceManager.put("org.apache.james.services.UsersStore", new MockUsersStore(mockUsersRepository)); + serviceManager.put("org.apache.avalon.cornerstone.services.store.Store", new MockStore()); + return serviceManager; + } + + public boolean allowsPasswordlessUser() { + return false; + } + + public boolean canTestUserExists() { + return true; + } + + public boolean isUserExisting(MailServer mailServerImpl, String username) { + return ((James)mailServerImpl).isLocalUser(username); + } +} Index: src/test/org/apache/james/test/mock/james/MockMailServer.java =================================================================== --- src/test/org/apache/james/test/mock/james/MockMailServer.java (revision 0) +++ src/test/org/apache/james/test/mock/james/MockMailServer.java (revision 0) @@ -0,0 +1,111 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ +package org.apache.james.test.mock.james; + +import org.apache.james.services.MailRepository; +import org.apache.james.services.MailServer; +import org.apache.james.smtpserver.MessageSizeException; +import org.apache.mailet.Mail; +import org.apache.mailet.MailAddress; + +import javax.mail.Address; +import javax.mail.MessagingException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import java.io.InputStream; +import java.util.*; + +public class MockMailServer implements MailServer { + + private final HashMap m_users = new HashMap(); + + private int m_counter = 0; + private int m_maxMessageSizeBytes = 0; + + private final ArrayList mails = new ArrayList(); + + public void sendMail(MailAddress sender, Collection recipients, MimeMessage msg) throws MessagingException { + Object[] mailObjects = new Object[]{sender, recipients, msg}; + mails.add(mailObjects); + } + + public void sendMail(MailAddress sender, Collection recipients, InputStream msg) throws MessagingException { + Object[] mailObjects = new Object[]{sender, recipients, msg}; + mails.add(mailObjects); + } + + public void sendMail(Mail mail) throws MessagingException { + int bodySize = mail.getMessage().getSize(); + try { + if (m_maxMessageSizeBytes != 0 && m_maxMessageSizeBytes < bodySize) throw new MessageSizeException(); + } catch (MessageSizeException e) { + throw new MessagingException("message size exception is nested", e); + } + sendMail(mail.getSender(), mail.getRecipients(), mail.getMessage()); + } + + public void sendMail(MimeMessage message) throws MessagingException { + // taken from class org.apache.james.James + MailAddress sender = new MailAddress((InternetAddress)message.getFrom()[0]); + Collection recipients = new HashSet(); + Address addresses[] = message.getAllRecipients(); + if (addresses != null) { + for (int i = 0; i < addresses.length; i++) { + // Javamail treats the "newsgroups:" header field as a + // recipient, so we want to filter those out. + if ( addresses[i] instanceof InternetAddress ) { + recipients.add(new MailAddress((InternetAddress)addresses[i])); + } + } + } + sendMail(sender, recipients, message); + } + + public MailRepository getUserInbox(String userName) { + return null; // trivial implementation + } + + public Map getRepositoryCounters() { + return null; // trivial implementation + } + + public synchronized String getId() { + m_counter++; + return "MockMailServer-ID-" + m_counter; + } + + public boolean addUser(String userName, String password) { + m_users.put(userName, password); + return true; + } + + public boolean isLocalServer(String serverName) { + return "localhost".equals(serverName); + } + + public Object[] getLastMail() + { + if (mails.size() == 0) return null; + return (Object[])mails.get(mails.size()-1); + } + + public void setMaxMessageSizeBytes(int maxMessageSizeBytes) { + m_maxMessageSizeBytes = maxMessageSizeBytes; + } +} + + Index: src/test/org/apache/james/test/mock/james/MockUsersStore.java =================================================================== --- src/test/org/apache/james/test/mock/james/MockUsersStore.java (revision 0) +++ src/test/org/apache/james/test/mock/james/MockUsersStore.java (revision 0) @@ -0,0 +1,43 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james.test.mock.james; + +import org.apache.james.services.UsersStore; +import org.apache.james.services.UsersRepository; + +import java.util.Iterator; +import java.util.ArrayList; + +public class MockUsersStore implements UsersStore { + private UsersRepository m_usersRepository; + + public MockUsersStore(UsersRepository usersRepository) { + m_usersRepository = usersRepository; + } + + public UsersRepository getRepository(String name) { + return m_usersRepository; + } + + public Iterator getRepositoryNames() { + ArrayList repositoryList = new ArrayList(); + repositoryList.add(m_usersRepository); + return repositoryList.iterator(); + } +} Index: src/test/org/apache/james/test/mock/james/MockUsersRepository.java =================================================================== --- src/test/org/apache/james/test/mock/james/MockUsersRepository.java (revision 0) +++ src/test/org/apache/james/test/mock/james/MockUsersRepository.java (revision 0) @@ -0,0 +1,95 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ +package org.apache.james.test.mock.james; + +import org.apache.james.security.DigestUtil; +import org.apache.james.services.User; +import org.apache.james.services.UsersRepository; +import org.apache.james.userrepository.DefaultUser; + +import java.util.HashMap; +import java.util.Iterator; + +public class MockUsersRepository implements UsersRepository { + + private final HashMap m_users = new HashMap(); + + public boolean addUser(User user) { + String key = user.getUserName(); + if (m_users.containsKey(key)) return false; + m_users.put(key, user); + return true; + } + + public void addUser(String name, Object attributes) { + try { + addUser(new DefaultUser(name, DigestUtil.digestString(((String)attributes), "SHA"), "SHA")); + } catch (Exception e) { + e.printStackTrace(); // encoding failed + } + } + + public Object getAttributes(String name) { + return null; // trivial implementation + } + + public User getUserByName(String name) { + return (User) m_users.get(name); + } + + public User getUserByNameCaseInsensitive(String name) { + return null; // trivial implementation + } + + public String getRealName(String name) { + return ((User) m_users.get(name)).getUserName(); + } + + public boolean updateUser(User user) { + return false; // trivial implementation + } + + public void removeUser(String name) { + // trivial implementation + } + + public boolean contains(String name) { + return m_users.containsKey(name); + } + + public boolean containsCaseInsensitive(String name) { + return false; // trivial implementation + } + + public boolean test(String name, Object attributes) { + return false; // trivial implementation + } + + public boolean test(String name, String password) { + User user = getUserByName(name); + if (user == null) return false; + return user.verifyPassword(password); + } + + public int countUsers() { + return m_users.size(); + } + + public Iterator list() { + return m_users.values().iterator(); + } +} Index: src/test/org/apache/james/test/mock/james/MockMailRepository.java =================================================================== --- src/test/org/apache/james/test/mock/james/MockMailRepository.java (revision 0) +++ src/test/org/apache/james/test/mock/james/MockMailRepository.java (revision 0) @@ -0,0 +1,61 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james.test.mock.james; + +import org.apache.james.services.MailRepository; +import org.apache.mailet.Mail; + +import javax.mail.MessagingException; +import java.util.Iterator; +import java.util.Collection; + +public class MockMailRepository implements MailRepository { + + public void store(Mail mc) throws MessagingException { + // trivial implementation + } + + public Iterator list() throws MessagingException { + return null; // trivial implementation + } + + public Mail retrieve(String key) throws MessagingException { + return null; // trivial implementation + } + + public void remove(Mail mail) throws MessagingException { + // trivial implementation + } + + public void remove(Collection mails) throws MessagingException { + // trivial implementation + } + + public void remove(String key) throws MessagingException { + // trivial implementation + } + + public boolean lock(String key) throws MessagingException { + return false; // trivial implementation + } + + public boolean unlock(String key) throws MessagingException { + return false; // trivial implementation + } +} Index: src/test/org/apache/james/test/mock/avalon/MockServiceManager.java =================================================================== --- src/test/org/apache/james/test/mock/avalon/MockServiceManager.java (revision 0) +++ src/test/org/apache/james/test/mock/avalon/MockServiceManager.java (revision 0) @@ -0,0 +1,42 @@ +/*********************************************************************** + * Copyright (c) 1999-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ +package org.apache.james.test.mock.avalon; + +import org.apache.avalon.framework.service.ServiceException; + +import java.util.HashMap; + +public class MockServiceManager implements org.apache.avalon.framework.service.ServiceManager { + + private HashMap m_serviceMap = new HashMap(); + + public Object lookup(String serviceName) throws ServiceException { + return m_serviceMap.get(serviceName); + } + + public boolean hasService(String serviceName) { + return m_serviceMap.get(serviceName) != null; + } + + public void put(String name, Object service) { + m_serviceMap.put(name, service); + } + + public void release(Object object) { + // trivial implementation + } +} Index: src/test/org/apache/james/test/mock/avalon/MockStore.java =================================================================== --- src/test/org/apache/james/test/mock/avalon/MockStore.java (revision 0) +++ src/test/org/apache/james/test/mock/avalon/MockStore.java (revision 0) @@ -0,0 +1,57 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james.test.mock.avalon; + +import org.apache.avalon.cornerstone.services.store.Store; +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.ConfigurationException; +import org.apache.avalon.framework.service.ServiceException; + +import java.util.HashMap; +import java.util.Map; + +public class MockStore implements Store { + + Map m_storedObjectMap = new HashMap(); + + public void add(Object key, Object obj) { + m_storedObjectMap.put(key, obj); + } + + public Object select(Object object) throws ServiceException { + if (object instanceof Configuration) { + Configuration repConf = (Configuration) object; + try { + object = repConf.getAttribute("destinationURL"); + } catch (ConfigurationException e) { + throw new RuntimeException("test failed"); + } + } + Object result = m_storedObjectMap.get(object); + return result; + } + + public boolean isSelectable(Object object) { + return m_storedObjectMap.get(object) != null; + } + + public void release(Object object) { + //trivial implementation + } +} Index: src/test/org/apache/james/test/mock/avalon/MockLogger.java =================================================================== --- src/test/org/apache/james/test/mock/avalon/MockLogger.java (revision 0) +++ src/test/org/apache/james/test/mock/avalon/MockLogger.java (revision 0) @@ -0,0 +1,92 @@ +/*********************************************************************** + * Copyright (c) 1999-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ +package org.apache.james.test.mock.avalon; + +import org.apache.avalon.framework.logger.Logger; + +public class MockLogger implements Logger { + private boolean m_debugEnabled = true; + + public void debug(java.lang.String string) { + System.out.println(string); + } + + public void debug(java.lang.String string, java.lang.Throwable throwable) { + System.out.println(string + throwable.toString()); + } + + public boolean isDebugEnabled() { + return m_debugEnabled; + } + + public void disableDebug() { + m_debugEnabled = false; + } + + public void info(java.lang.String string) { + System.out.println(string); + } + + public void info(java.lang.String string, java.lang.Throwable throwable) { + System.out.println(string + throwable.toString()); + } + + public boolean isInfoEnabled() { + return true; + } + + public void warn(java.lang.String string) { + System.out.println(string); + } + + public void warn(java.lang.String string, java.lang.Throwable throwable) { + System.out.println(string + throwable.toString()); + } + + public boolean isWarnEnabled() { + return true; + } + + public void error(java.lang.String string) { + System.out.println(string); + } + + public void error(java.lang.String string, java.lang.Throwable throwable) { + System.out.println(string + throwable.toString()); + } + + public boolean isErrorEnabled() { + return true; + } + + public void fatalError(java.lang.String string) { + System.out.println(string); + } + + public void fatalError(java.lang.String string, java.lang.Throwable throwable) { + System.out.println(string + throwable.toString()); + } + + public boolean isFatalErrorEnabled() { + return true; + } + + public org.apache.avalon.framework.logger.Logger getChildLogger(java.lang.String string) { + return this; + } + +} Index: src/test/org/apache/james/test/mock/avalon/MockThreadManager.java =================================================================== --- src/test/org/apache/james/test/mock/avalon/MockThreadManager.java (revision 0) +++ src/test/org/apache/james/test/mock/avalon/MockThreadManager.java (revision 0) @@ -0,0 +1,38 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ +package org.apache.james.test.mock.avalon; + +import org.apache.avalon.cornerstone.services.threads.ThreadManager; +import org.apache.avalon.excalibur.thread.impl.DefaultThreadPool; +import org.apache.excalibur.thread.ThreadPool; + +public class MockThreadManager implements ThreadManager { + public ThreadPool getThreadPool(String string) throws IllegalArgumentException { + return getDefaultThreadPool(); + } + + public ThreadPool getDefaultThreadPool() { + try { + DefaultThreadPool defaultThreadPool = new DefaultThreadPool(1); + defaultThreadPool.enableLogging(new MockLogger()); + return defaultThreadPool; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} Index: src/test/org/apache/james/test/mock/avalon/MockSocketManager.java =================================================================== --- src/test/org/apache/james/test/mock/avalon/MockSocketManager.java (revision 0) +++ src/test/org/apache/james/test/mock/avalon/MockSocketManager.java (revision 0) @@ -0,0 +1,40 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ +package org.apache.james.test.mock.avalon; + +import org.apache.avalon.cornerstone.services.sockets.SocketManager; +import org.apache.avalon.cornerstone.services.sockets.ServerSocketFactory; +import org.apache.avalon.cornerstone.services.sockets.SocketFactory; +import org.apache.avalon.cornerstone.blocks.sockets.DefaultServerSocketFactory; +import org.apache.avalon.cornerstone.blocks.sockets.DefaultSocketFactory; + +public class MockSocketManager implements SocketManager { + private int m_port; + + public MockSocketManager(int port) + { + m_port = port; + } + + public ServerSocketFactory getServerSocketFactory(String string) throws Exception { + return new DefaultServerSocketFactory(); + } + + public SocketFactory getSocketFactory(String string) throws Exception { + return new DefaultSocketFactory(); + } +} Index: src/test/org/apache/james/test/mock/avalon/MockContext.java =================================================================== --- src/test/org/apache/james/test/mock/avalon/MockContext.java (revision 0) +++ src/test/org/apache/james/test/mock/avalon/MockContext.java (revision 0) @@ -0,0 +1,39 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james.test.mock.avalon; + +import org.apache.avalon.framework.context.Context; +import org.apache.avalon.framework.context.ContextException; + +public class MockContext implements Context { + + private Object m_retObj; + + public MockContext() { + ; // will always return NULL + } + + public MockContext(Object retObj) { + m_retObj = retObj; + } + + public Object get(Object object) throws ContextException { + return m_retObj; + } +} Index: src/test/org/apache/james/test/mock/mailet/MockMailContext.java =================================================================== --- src/test/org/apache/james/test/mock/mailet/MockMailContext.java (revision 0) +++ src/test/org/apache/james/test/mock/mailet/MockMailContext.java (revision 0) @@ -0,0 +1,113 @@ +/*********************************************************************** + * Copyright (c) 1999-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ +package org.apache.james.test.mock.mailet; + +import org.apache.mailet.MailetContext; +import org.apache.mailet.Mail; +import org.apache.mailet.MailAddress; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.util.Collection; +import java.util.Iterator; + +public class MockMailContext implements MailetContext { + + public void bounce(Mail mail, String message) throws MessagingException { + // trivial implementation + } + + public void bounce(Mail mail, String message, MailAddress bouncer) throws MessagingException { + // trivial implementation + } + + public Collection getMailServers(String host) { + return null; // trivial implementation + } + + public MailAddress getPostmaster() { + return null; // trivial implementation + } + + public Object getAttribute(String name) { + return null; // trivial implementation + } + + public Iterator getAttributeNames() { + return null; // trivial implementation + } + + public int getMajorVersion() { + return 0; // trivial implementation + } + + public int getMinorVersion() { + return 0; // trivial implementation + } + + public String getServerInfo() { + return null; // trivial implementation + } + + public boolean isLocalServer(String serverName) { + return false; // trivial implementation + } + + public boolean isLocalUser(String userAccount) { + return false; // trivial implementation + } + + public void log(String message) { + // trivial implementation + } + + public void log(String message, Throwable t) { + // trivial implementation + } + + public void removeAttribute(String name) { + // trivial implementation + } + + public void sendMail(MimeMessage msg) throws MessagingException { + // trivial implementation + } + + public void sendMail(MailAddress sender, Collection recipients, MimeMessage msg) throws MessagingException { + // trivial implementation + } + + public void sendMail(MailAddress sender, Collection recipients, MimeMessage msg, String state) throws MessagingException { + // trivial implementation + } + + public void sendMail(Mail mail) throws MessagingException { + // trivial implementation + } + + public void setAttribute(String name, Object object) { + // trivial implementation + } + + public void storeMail(MailAddress sender, MailAddress recipient, MimeMessage msg) throws MessagingException { + // trivial implementation + } + + public Iterator getSMTPHostAddresses(String domainName) { + return null; // trivial implementation + } +} Index: src/test/org/apache/james/test/mock/javaxmail/MockMimeMessage.java =================================================================== --- src/test/org/apache/james/test/mock/javaxmail/MockMimeMessage.java (revision 0) +++ src/test/org/apache/james/test/mock/javaxmail/MockMimeMessage.java (revision 0) @@ -0,0 +1,468 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james.test.mock.javaxmail; + +import javax.mail.internet.MimeMessage; +import javax.mail.internet.InternetHeaders; +import javax.mail.internet.InternetAddress; +import javax.mail.*; +import javax.mail.search.SearchTerm; +import javax.activation.DataHandler; +import java.util.*; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +public class MockMimeMessage extends MimeMessage { + + private final List m_fromAddresses = new ArrayList(); + private Address m_senderAddress; + private final List m_toRecepients = new ArrayList(); + private final List m_ccRecepients = new ArrayList(); + private final List m_bccRecepients = new ArrayList(); + private final List m_replyToAddresses = new ArrayList(); + private String m_subject; + private int m_iMessageNumber; + private boolean m_bIsExpunged; + private Object m_content; + private Date m_sentDate; + private String[] m_contentLanguage; + private String m_fileName; + private DataHandler m_dataHandler; + private HashMap m_contentHeaders = new HashMap(); + private Flags m_setFlags = new Flags(); + private boolean m_doMatch; + + public MockMimeMessage() throws MessagingException { + super((Session)null); + } + + public MockMimeMessage(MimeMessage mimeMessage) throws MessagingException { + super(mimeMessage); // trivial implementation + } + + public Address[] getFrom() throws MessagingException { + return (Address[])m_fromAddresses.toArray(); + } + + public void setFrom(Address address) throws MessagingException { + m_fromAddresses.clear(); + m_fromAddresses.add(address); + } + + public void setFrom() throws MessagingException { + m_fromAddresses.clear(); + m_fromAddresses.add(InternetAddress.getLocalAddress(null)); + } + + public void addFrom(Address[] addresses) throws MessagingException { + m_fromAddresses.add(addresses); + } + + public Address getSender() throws MessagingException { + return m_senderAddress; + } + + public void setSender(Address address) throws MessagingException { + m_senderAddress = address; + } + + public Address[] getRecipients(Message.RecipientType recipientType) throws MessagingException { + return (Address[]) getRecipientsList(recipientType).toArray(); + } + + private List getRecipientsList(Message.RecipientType recipientType) { + if (Message.RecipientType.TO.equals(recipientType)) return m_toRecepients; + if (Message.RecipientType.CC.equals(recipientType)) return m_ccRecepients; + if (Message.RecipientType.BCC.equals(recipientType)) return m_bccRecepients; + return null; + } + + public Address[] getAllRecipients() throws MessagingException { + List allRecipients = new ArrayList(); + allRecipients.addAll(m_toRecepients); + allRecipients.addAll(m_ccRecepients); + allRecipients.addAll(m_bccRecepients); + return (Address[]) allRecipients.toArray(); + } + + public void setRecipients(Message.RecipientType recipientType, Address[] addresses) throws MessagingException { + getRecipientsList(recipientType).addAll(Arrays.asList(addresses)); + } + + public void setRecipients(Message.RecipientType recipientType, String recipient) throws MessagingException { + getRecipientsList(recipientType).add(recipient); + } + + public void addRecipients(Message.RecipientType recipientType, Address[] addresses) throws MessagingException { + getRecipientsList(recipientType).addAll(Arrays.asList(addresses)); + } + + public void addRecipients(Message.RecipientType recipientType, String recipient) throws MessagingException { + getRecipientsList(recipientType).add(recipient); + } + + public Address[] getReplyTo() throws MessagingException { + return (Address[]) m_replyToAddresses.toArray(); + } + + public void setReplyTo(Address[] addresses) throws MessagingException { + m_replyToAddresses.addAll(Arrays.asList(addresses)); + } + + public String getSubject() throws MessagingException { + return m_subject; + } + + public void setSubject(String subject) throws MessagingException { + m_subject = subject; + } + + public void setSubject(String subject, String charset) throws MessagingException { + if (subject == null) + { + m_subject = null; + return; + } + try { + m_subject = new String(subject.getBytes(charset)); + } catch (UnsupportedEncodingException e) { + throw new MessagingException("setting subject failed", e); + } + } + + public Date getSentDate() throws MessagingException { + return m_sentDate; + } + + public void setSentDate(Date date) throws MessagingException { + m_sentDate = date; + } + + public Date getReceivedDate() throws MessagingException { + return null; // trivial implementation + } + + public int getSize() throws MessagingException { + return -1; // trivial implementation + } + + public int getLineCount() throws MessagingException { + return -1; // trivial implementation + } + + public String getContentType() throws MessagingException { + return getHeader("Content-Type", null); + } + + public boolean isMimeType(String mimeType) throws MessagingException { + return mimeType.startsWith(getContentType()); + } + + public String getDisposition() throws MessagingException { + return getHeader("Content-Disposition", null); + } + + public void setDisposition(String disposition) throws MessagingException { + setHeader("Content-Disposition", disposition); + } + + public String getEncoding() throws MessagingException { + return getHeader("Content-Transfer-Encoding", null); + } + + public String getContentID() throws MessagingException { + return getHeader("Content-ID", null); + } + + public void setContentID(String contentID) throws MessagingException { + setHeader("Content-ID", contentID); + } + + public String getContentMD5() throws MessagingException { + return getHeader("Content-MD5", null); + } + + public void setContentMD5(String value) throws MessagingException { + setHeader("Content-MD5", value); + } + + public String getDescription() throws MessagingException { + return getHeader("Content-Description", null); + } + + public void setDescription(String description) throws MessagingException { + setHeader("Content-Description", description); + } + + public void setDescription(String description, String charset) throws MessagingException { + try { + setDescription(new String(description.getBytes(charset))); + } catch (UnsupportedEncodingException e) { + throw new MessagingException("setting description failed", e); + } + } + + public String[] getContentLanguage() throws MessagingException { + return m_contentLanguage; + } + + public void setContentLanguage(String[] contentLanguage) throws MessagingException { + m_contentLanguage = contentLanguage; + } + + public String getMessageID() throws MessagingException { + return "ID-" + m_iMessageNumber; // trivial implementation + } + + public String getFileName() throws MessagingException { + return m_fileName; + } + + public void setFileName(String fileName) throws MessagingException { + m_fileName = fileName; + } + + public InputStream getInputStream() throws IOException, MessagingException { + return null; // trivial implementation + } + + protected InputStream getContentStream() throws MessagingException { + return null; // trivial implementation + } + + public InputStream getRawInputStream() throws MessagingException { + return null; // trivial implementation + } + + public synchronized DataHandler getDataHandler() throws MessagingException { + return m_dataHandler; + } + + public synchronized void setDataHandler(DataHandler dataHandler) throws MessagingException { + m_dataHandler = dataHandler; + } + + public Object getContent() throws IOException, MessagingException { + return m_content; + } + + public void setContent(Object object, String mimeType) throws MessagingException { + m_content = object; // trivial implementation + } + + public void setText(String string) throws MessagingException { + setContent(string, "text/plain"); + } + + public void setText(String string, String charset) throws MessagingException { + try { + setContent(new String(string.getBytes(charset)) , "text/plain"); + } catch (UnsupportedEncodingException e) { + throw new MessagingException("setting text content failed", e); + } + } + + public void setContent(Multipart multipart) throws MessagingException { + m_content = multipart; + } + + public Message reply(boolean b) throws MessagingException { + return new MockMimeMessage(this); // trivial implementation + } + + public void writeTo(OutputStream outputStream) throws IOException, MessagingException { + ; // trivial implementation + } + + public void writeTo(OutputStream outputStream, String[] strings) throws IOException, MessagingException { + ; // trivial implementation + } + + public String[] getHeader(String name) throws MessagingException { + String value = (String) m_contentHeaders.get(name); + if (value == null) return null; + return new String[] {value}; + } + + public String getHeader(String name, String delimiter) throws MessagingException { + String[] header = getHeader(name); + if (header.length == 0) return null; + return header[0]; + } + + public void setHeader(String name, String value) throws MessagingException { + addHeader(name, value); + } + + public void addHeader(String name, String value) throws MessagingException { + m_contentHeaders.put(name, value); + } + + public void removeHeader(String name) throws MessagingException { + m_contentHeaders.remove(name); + } + + public Enumeration getAllHeaders() throws MessagingException { + return Collections.enumeration(m_contentHeaders.values()); + } + + public Enumeration getMatchingHeaders(String[] names) throws MessagingException { + ArrayList matchingHeaders = new ArrayList(); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + String value = getHeader(name, null); + if (value == null) continue; + matchingHeaders.add(value); + } + return Collections.enumeration(matchingHeaders); + } + + public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException { + List existingHeaders = Arrays.asList(names); + + ArrayList nonMatchingHeaders = new ArrayList(); + + Iterator iterator = m_contentHeaders.keySet().iterator(); + while (iterator.hasNext()) { + String name = (String) iterator.next(); + if (existingHeaders.contains(name)) continue; + String value = getHeader(name, null); + if (value == null) continue; + nonMatchingHeaders.add(value); + } + return Collections.enumeration(nonMatchingHeaders); + } + + public void addHeaderLine(String headerLine) throws MessagingException { + int separatorIndex = headerLine.indexOf(":"); + if (separatorIndex < 0) throw new MessagingException("header line does not conform to standard"); + + addHeader(headerLine.substring(0,separatorIndex), headerLine.substring(separatorIndex,headerLine.length())); + } + + public Enumeration getAllHeaderLines() throws MessagingException { + return Collections.enumeration(getHeadersAsStrings(m_contentHeaders)); + } + + private ArrayList getHeadersAsStrings(HashMap contentHeaders) { + ArrayList headerLines = new ArrayList(); + Iterator iterator = contentHeaders.keySet().iterator(); + while (iterator.hasNext()) { + String key = (String) iterator.next(); + String value = (String) contentHeaders.get(key); + headerLines.add(key + ":" + value); + } + return headerLines; + } + + public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException { + ArrayList matchingHeaders = new ArrayList(); + for (int i = 0; i < names.length; i++) { + String name = names[i]; + String value = getHeader(name, null); + if (value == null) continue; + matchingHeaders.add(name + ":" + value); + } + return Collections.enumeration(matchingHeaders); + } + + public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException { + List existingHeaders = Arrays.asList(names); + + ArrayList nonMatchingHeaders = new ArrayList(); + + Iterator iterator = m_contentHeaders.keySet().iterator(); + while (iterator.hasNext()) { + String name = (String) iterator.next(); + if (existingHeaders.contains(name)) continue; + String value = getHeader(name, null); + if (value == null) continue; + nonMatchingHeaders.add(name + ":" + value); + } + return Collections.enumeration(nonMatchingHeaders); + } + + public synchronized Flags getFlags() throws MessagingException { + return new Flags(m_setFlags); + } + + public synchronized boolean isSet(Flags.Flag flag) throws MessagingException { + return m_setFlags.contains(flag); + } + + public synchronized void setFlags(Flags flags, boolean set) throws MessagingException { + if (set) m_setFlags.add(flags); + else m_setFlags.remove(flags); + } + + public void saveChanges() throws MessagingException { + ; // trivial implementation + } + + protected void updateHeaders() throws MessagingException { + ; // trivial implementation + } + + protected InternetHeaders createInternetHeaders(InputStream inputStream) throws MessagingException { + return new InternetHeaders(); + } + + public void setRecipient(Message.RecipientType recipientType, Address address) throws MessagingException { + setRecipients(recipientType, new Address[]{address}); + } + + public void addRecipient(Message.RecipientType recipientType, Address address) throws MessagingException { + setRecipients(recipientType, new Address[]{address}); + } + + public void setFlag(Flags.Flag flag, boolean set) throws MessagingException { + if (set) m_setFlags.add(flag); + else m_setFlags.remove(flag); + } + + public int getMessageNumber() { + return m_iMessageNumber; + } + + protected void setMessageNumber(int i) { + m_iMessageNumber = i; + } + + public Folder getFolder() { + return null; + } + + public boolean isExpunged() { + return m_bIsExpunged; + } + + protected void setExpunged(boolean b) { + m_bIsExpunged = b; + } + + public void setShouldMatch(boolean doMatch) { + m_doMatch = doMatch; + } + + public boolean match(SearchTerm searchTerm) throws MessagingException { + return m_doMatch; + } +} Index: src/test/org/apache/james/test/util/Util.java =================================================================== --- src/test/org/apache/james/test/util/Util.java (revision 0) +++ src/test/org/apache/james/test/util/Util.java (revision 0) @@ -0,0 +1,33 @@ +/*********************************************************************** + * Copyright (c) 1999-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ +package org.apache.james.test.util; + +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.DefaultConfiguration; + +public class Util { + + public static int getRandomNonPrivilegedPort() { + return ((int)( Math.random() * 1000) + 3000); + } + + public static Configuration getValuedConfiguration(String name, String value) { + DefaultConfiguration defaultConfiguration = new DefaultConfiguration(name); + defaultConfiguration.setValue(value); + return defaultConfiguration; + } +} Index: src/test/org/apache/james/services/MailServerTestAllImplementations.java =================================================================== --- src/test/org/apache/james/services/MailServerTestAllImplementations.java (revision 0) +++ src/test/org/apache/james/services/MailServerTestAllImplementations.java (revision 0) @@ -0,0 +1,145 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james.services; + +import junit.framework.TestCase; + +/** + * tests all implementations for interface MailServer + */ +abstract public class MailServerTestAllImplementations extends TestCase { + + abstract public MailServer createMailServer(); + abstract public boolean allowsPasswordlessUser(); + + /** + * while addUser() is part of MailServer interface, a user cannot be tested for afterwards + * at the same time, James allows to do exactly this via isLocalUser(), other implementations + * might vary. + */ + abstract public boolean canTestUserExists(); + abstract public boolean isUserExisting(MailServer mailServerImpl, String username); + + public void testId() { + MailServer mailServer = createMailServer(); + + String id = mailServer.getId(); + assertNotNull("mail id not null", id); + assertFalse("mail id not empty", "".equals(id)); + } + + public void testIdIncrement() { + MailServer mailServer = createMailServer(); + + String id1 = mailServer.getId(); + String id2 = mailServer.getId(); + assertFalse("next id is different", id1.equals(id2)); + } + + public void testAddUser() { + + // addUser acts on field localUsers for class org.apache.james.James + // thus, it is unrelated to getUserInbox() for the only known implementation of MailServer + // TODO clarify this + + MailServer mailServer = createMailServer(); + + String userName = "testUserName"; + MailRepository userInbox = null; + + if (canTestUserExists()) + { + assertFalse("this is a fresh user", isUserExisting(mailServer, userName)); + } + + boolean allowsPasswordlessUser = allowsPasswordlessUser(); + try { + boolean success = mailServer.addUser(userName, null); + if (!allowsPasswordlessUser) fail("null pwd was accepted unexpectedly"); + if (!success) fail("null pwd was not accepted unexpectedly"); + } catch (Exception e) { + if (allowsPasswordlessUser) fail("null pwd not accepted unexpectedly (with exception)"); + } + + userName = userName + "_next"; + String password = "password"; + + boolean success = mailServer.addUser(userName, password); + if (!success) fail("user has not been added"); + + if (canTestUserExists()) + { + assertTrue("user is present now", isUserExisting(mailServer, userName)); + } + + boolean successAgain = mailServer.addUser(userName, password); + if (successAgain) fail("user has been added two times"); + + } + + public void testGetNonexisitingUserInbox() { + + // + // TODO fix test (or James) -- test WILL FAIL + // + + MailServer mailServer = createMailServer(); + + String userName = "testNonexisitingUserName"; + MailRepository userInbox = null; + + try { + userInbox = mailServer.getUserInbox(userName); + assertEquals("test user does not exist", null, userInbox); + fail("found inbox which should be unexistent"); + } catch (NullPointerException e) { + // this is what org.apache.james.James returns + // is this behavior compatible with other implementations? + // shouldn't James behave more gracefully? + } + } + + public void testGetExisitingUserInbox() { + + // + // TODO fix test (or James) -- test WILL FAIL + // + + MailServer mailServer = createMailServer(); + + String userName = "testUserName"; + MailRepository userInbox = null; + + // getUserInbox acts on field mailboxes for class org.apache.james.James + // thus, it is unrelated to addUser() for the only known implementation of MailServer + // TODO clarify this + mailServer.addUser(userName, "password"); // !! is not retrievable via getUserInbox !! + + + try { + userInbox = mailServer.getUserInbox(userName); + assertEquals("test user does not exist", null, userInbox); + fail("found inbox which should be unexistent"); + } catch (NullPointerException e) { + // this is what org.apache.james.James returns + // is this behavior compatible with other implementations? + // shouldn't James behave more gracefully? + } + } +} Index: src/test/org/apache/james/JamesTestConfiguration.java =================================================================== --- src/test/org/apache/james/JamesTestConfiguration.java (revision 0) +++ src/test/org/apache/james/JamesTestConfiguration.java (revision 0) @@ -0,0 +1,49 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james; + +import org.apache.avalon.framework.configuration.DefaultConfiguration; +import org.apache.james.test.util.Util; + +public class JamesTestConfiguration extends DefaultConfiguration { + + public JamesTestConfiguration() { + super("James"); + } + + public void init() { + + //setAttribute("enabled", true); + + DefaultConfiguration serverNamesConfig = new DefaultConfiguration("servernames"); + serverNamesConfig.setAttribute("autodetect", false); + serverNamesConfig.addChild(Util.getValuedConfiguration("servername", "localhost")); + addChild(serverNamesConfig); + + DefaultConfiguration inboxRepositoryConfig = new DefaultConfiguration("inboxRepository"); + + DefaultConfiguration repositoryConfig = new DefaultConfiguration("repository"); + repositoryConfig.setAttribute("destinationURL", "db://maildb/inbox/"); + repositoryConfig.setAttribute("type", "MAIL"); + inboxRepositoryConfig.addChild(repositoryConfig); + + addChild(inboxRepositoryConfig); + } + +} Index: src/test/org/apache/james/core/MailImplTest.java =================================================================== --- src/test/org/apache/james/core/MailImplTest.java (revision 0) +++ src/test/org/apache/james/core/MailImplTest.java (revision 0) @@ -0,0 +1,96 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james.core; + +import org.apache.james.test.mock.james.MockMailServer; +import org.apache.james.test.mock.javaxmail.MockMimeMessage; +import org.apache.mailet.MailAddress; +import org.apache.mailet.Mail; + +import javax.mail.MessagingException; +import java.util.ArrayList; + +public class MailImplTest extends MailTestAllImplementations { + + protected Mail createMailImplementation() { + return new MailImpl(); + } + + public void testConstr1() throws MessagingException { + MailImpl mail = new MailImpl(); + + helperTestInitialState(mail); + helperTestMessageSize(mail, 0); // MimeMessageWrapper default is 0 + assertNull("no initial message", mail.getMessage()); + assertNull("no initial sender", mail.getSender()); + assertNull("no initial name", mail.getName()); + } + + public void testConstr2() throws MessagingException { + ArrayList recepients = new ArrayList(); + String name = new MockMailServer().getId(); + String sender = "sender@localhost"; + MailAddress senderMailAddress = new MailAddress(sender); + MailImpl mail = new MailImpl(name, senderMailAddress, recepients); + + helperTestInitialState(mail); // MimeMessageWrapper default is 0 + helperTestMessageSize(mail, 0); // MimeMessageWrapper default is 0 + assertNull("no initial message", mail.getMessage()); + assertEquals("sender", sender, mail.getSender().toString()); + assertEquals("name", name, mail.getName()); + + mail.setMessage(new MockMimeMessage()); + assertNotNull("message", mail.getMessage()); + } + + public void testConstr3() throws MessagingException { + ArrayList recepients = new ArrayList(); + String name = new MockMailServer().getId(); + String sender = "sender@localhost"; + MailAddress senderMailAddress = new MailAddress(sender); + MockMimeMessage mimeMessage = new MockMimeMessage(); + MailImpl mail = new MailImpl(name, senderMailAddress, recepients, mimeMessage); + + helperTestInitialState(mail); + helperTestMessageSize(mail, mimeMessage.getSize()); // MockMimeMessage default is -1 (accord. to javax.mail javadoc) + assertEquals("initial message", mimeMessage, mail.getMessage()); + assertEquals("sender", sender, mail.getSender().toString()); + assertEquals("name", name, mail.getName()); + } + + public void testDuplicate() throws MessagingException { + MailImpl mail = new MailImpl(); + MailImpl duplicate = (MailImpl) mail.duplicate(); + assertNotSame("is real duplicate", mail, duplicate); + helperTestInitialState(duplicate); + helperTestMessageSize(duplicate, 0); + } + + public void testDuplicateNewName() throws MessagingException { + String newName = "aNewName"; + + MailImpl mail = new MailImpl(); + assertFalse("before + after names differ", newName.equals(mail.getName())); + + MailImpl duplicate = (MailImpl) mail.duplicate(newName); + assertEquals("new name set", newName, duplicate.getName()); + helperTestInitialState(duplicate); + helperTestMessageSize(duplicate, 0); + } +} Index: src/test/org/apache/james/core/MailTestAllImplementations.java =================================================================== --- src/test/org/apache/james/core/MailTestAllImplementations.java (revision 0) +++ src/test/org/apache/james/core/MailTestAllImplementations.java (revision 0) @@ -0,0 +1,69 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james.core; + +import junit.framework.TestCase; + +import javax.mail.MessagingException; + +import org.apache.mailet.Mail; + +/** + * testing common behavior of Mail implementors. subclasses automatically get their Mail-behavior tested. + */ +public abstract class MailTestAllImplementations extends TestCase { + + /** provide the concrete implementation to test */ + protected abstract Mail createMailImplementation(); + + protected void helperTestInitialState(Mail mail) throws MessagingException { + assertFalse("no initial attributes", mail.hasAttributes()); + assertNull("no initial error", mail.getErrorMessage()); + assertNotNull("initial last update set", mail.getLastUpdated()); + try { + assertTrue("no initial recipient", mail.getRecipients().isEmpty()); + } catch (NullPointerException e) { + // current behavior. *BUT*, shouldn't this method better return with an empty list?! + } + assertEquals("initial remote address is localhost ip", "127.0.0.1", mail.getRemoteAddr()); + assertEquals("initial remote host is localhost", "localhost", mail.getRemoteHost()); + assertEquals("default initial state", Mail.DEFAULT, mail.getState()); + } + + protected void helperTestMessageSize(Mail mail, int expectedMsgSize) throws MessagingException { + try { + assertEquals("initial message size == " + expectedMsgSize, expectedMsgSize, mail.getMessageSize()); + } catch (NullPointerException e) { + // current behavior. *BUT*, shouldn't this method return more gracefully?! + } + } + + public void testAttributes() { + Mail mail = createMailImplementation(); + assertFalse("no initial attributes", mail.hasAttributes()); + assertFalse("attributes initially empty", mail.getAttributeNames().hasNext()); + assertNull("not found on emtpy list", mail.getAttribute("test")); + assertNull("no previous item with key", mail.setAttribute("testKey", "testValue")); + assertEquals("item found", "testValue", mail.getAttribute("testKey")); + assertTrue("has attribute", mail.hasAttributes()); + assertEquals("item removed", "testValue", mail.removeAttribute("testKey")); + assertNull("item no longer found", mail.getAttribute("testKey")); + } + +} Index: src/test/org/apache/james/smtpserver/SMTPServerTest.java =================================================================== --- src/test/org/apache/james/smtpserver/SMTPServerTest.java (revision 0) +++ src/test/org/apache/james/smtpserver/SMTPServerTest.java (revision 0) @@ -0,0 +1,335 @@ +/*********************************************************************** + * Copyright (c) 1999-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ +package org.apache.james.smtpserver; + +import junit.framework.TestCase; +import org.apache.avalon.cornerstone.services.sockets.SocketManager; +import org.apache.avalon.cornerstone.services.threads.ThreadManager; +import org.apache.james.services.JamesConnectionManager; +import org.apache.james.test.mock.avalon.MockLogger; +import org.apache.james.test.mock.avalon.MockServiceManager; +import org.apache.james.test.mock.avalon.MockSocketManager; +import org.apache.james.test.mock.avalon.MockThreadManager; +import org.apache.james.test.mock.james.MockMailServer; +import org.apache.james.test.mock.james.MockUsersRepository; +import org.apache.james.test.mock.mailet.MockMailContext; +import org.apache.james.test.util.Util; +import org.apache.james.util.Base64; +import org.apache.james.util.connection.SimpleConnectionManager; +import org.columba.ristretto.composer.MimeTreeRenderer; +import org.columba.ristretto.io.CharSequenceSource; +import org.columba.ristretto.message.*; +import org.columba.ristretto.smtp.SMTPException; +import org.columba.ristretto.smtp.SMTPProtocol; +import org.columba.ristretto.smtp.SMTPResponse; + +import java.io.IOException; +import java.net.InetAddress; +import java.util.Arrays; +import java.util.List; + +/** + * Tests the org.apache.james.smtpserver.SMTPServer unit + */ +public class SMTPServerTest extends TestCase { + private int m_smtpListenerPort = Util.getRandomNonPrivilegedPort(); + private MockMailServer m_mailServer; + private SMTPTestConfiguration m_testConfiguration; + private SMTPServer m_smtpServer; + private MockUsersRepository m_usersRepository = new MockUsersRepository(); + + public SMTPServerTest() { + super("SMTPServerTest"); + } + + protected void setUp() throws Exception { + m_smtpServer = new SMTPServer(); + m_smtpServer.enableLogging(new MockLogger()); + + m_smtpServer.service(setUpServiceManager()); + m_testConfiguration = new SMTPTestConfiguration(m_smtpListenerPort); + } + + private void finishSetUp(SMTPTestConfiguration testConfiguration) throws Exception { + testConfiguration.init(); + m_smtpServer.configure(testConfiguration); + m_smtpServer.initialize(); + m_mailServer.setMaxMessageSizeBytes(m_testConfiguration.getMaxMessageSize()); + } + + private MockServiceManager setUpServiceManager() { + MockServiceManager serviceManager = new MockServiceManager(); + SimpleConnectionManager connectionManager = new SimpleConnectionManager(); + connectionManager.enableLogging(new MockLogger()); + serviceManager.put(JamesConnectionManager.ROLE, connectionManager); + serviceManager.put("org.apache.mailet.MailetContext", new MockMailContext()); + m_mailServer = new MockMailServer(); + serviceManager.put("org.apache.james.services.MailServer", m_mailServer); + serviceManager.put("org.apache.james.services.UsersRepository", m_usersRepository); + serviceManager.put(SocketManager.ROLE, new MockSocketManager(m_smtpListenerPort)); + serviceManager.put(ThreadManager.ROLE, new MockThreadManager()); + return serviceManager; + } + + public void testSimpleMailSendWithEHLO() throws Exception, SMTPException { + finishSetUp(m_testConfiguration); + + SMTPProtocol smtpProtocol = new SMTPProtocol("127.0.0.1", m_smtpListenerPort); + smtpProtocol.openPort(); + + // no message there, yet + assertNull("no mail received by mail server", m_mailServer.getLastMail()); + + String[] capabilityStrings = smtpProtocol.ehlo(InetAddress.getLocalHost()); + assertEquals("capabilities", 3, capabilityStrings.length); + List capabilitieslist = Arrays.asList(capabilityStrings); + assertTrue("capabilities present PIPELINING", capabilitieslist.contains("PIPELINING")); + assertTrue("capabilities present ENHANCEDSTATUSCODES", capabilitieslist.contains("ENHANCEDSTATUSCODES")); + assertTrue("capabilities present 8BITMIME", capabilitieslist.contains("8BITMIME")); + + smtpProtocol.mail(new Address("mail@localhost")); + smtpProtocol.rcpt(new Address("mail@localhost")); + + smtpProtocol.data(MimeTreeRenderer.getInstance().renderMimePart(createMail())); + + smtpProtocol.quit(); + + // mail was propagated by SMTPServer + assertNotNull("mail received by mail server", m_mailServer.getLastMail()); + } + + public void testSimpleMailSendWithHELO() throws Exception, SMTPException { + finishSetUp(m_testConfiguration); + + SMTPProtocol smtpProtocol = new SMTPProtocol("127.0.0.1", m_smtpListenerPort); + smtpProtocol.openPort(); + + // no message there, yet + assertNull("no mail received by mail server", m_mailServer.getLastMail()); + + smtpProtocol.helo(InetAddress.getLocalHost()); + + smtpProtocol.mail(new Address("mail@localhost")); + smtpProtocol.rcpt(new Address("mail@localhost")); + + smtpProtocol.data(MimeTreeRenderer.getInstance().renderMimePart(createMail())); + + smtpProtocol.quit(); + + // mail was propagated by SMTPServer + assertNotNull("mail received by mail server", m_mailServer.getLastMail()); + } + + private LocalMimePart createMail() { + MimeHeader mimeHeader = new MimeHeader(new Header()); + mimeHeader.set("Mime-Version", "1.0"); + LocalMimePart mail = new LocalMimePart(mimeHeader); + MimeHeader header = mail.getHeader(); + header.setMimeType(new MimeType("text", "plain")); + + mail.setBody(new CharSequenceSource("James Unit Test Body")); + return mail; + } + + public void testAuth() throws Exception, SMTPException { + m_testConfiguration.setAuthorizedAddresses("128.0.0.1/8"); + m_testConfiguration.setAuthorizingAnnounce(); + finishSetUp(m_testConfiguration); + + MySMTPProtocol smtpProtocol = new MySMTPProtocol("127.0.0.1", m_smtpListenerPort); + smtpProtocol.openPort(); + + String[] capabilityStrings = smtpProtocol.ehlo(InetAddress.getLocalHost()); + List capabilitieslist = Arrays.asList(capabilityStrings); + assertTrue("anouncing auth required", capabilitieslist.contains("AUTH LOGIN PLAIN")); + // is this required or just for compatibility? assertTrue("anouncing auth required", capabilitieslist.contains("AUTH=LOGIN PLAIN")); + + String userName = "test_user_smtp"; + String noexistUserName = "noexist_test_user_smtp"; + + smtpProtocol.sendCommand("AUTH FOO", null); + SMTPResponse response = smtpProtocol.getResponse(); + assertEquals("expected error: unrecognized authentication type", 504, response.getCode()); + + smtpProtocol.mail(new Address(userName)); + + try { + smtpProtocol.rcpt(new Address("mail@sample.com")); + fail("no auth required"); + } catch (SMTPException e) { + assertEquals("expected 530 error", 530, e.getCode()); + } + + assertFalse("user not existing", m_usersRepository.contains(noexistUserName)); + try { + smtpProtocol.auth("PLAIN", noexistUserName, "pwd".toCharArray()); + fail("auth succeeded for non-existing user"); + } catch (SMTPException e) { + assertEquals("expected error", 535, e.getCode()); + } + + m_usersRepository.addUser(userName, "pwd"); + try { + smtpProtocol.auth("PLAIN", userName, "wrongpwd".toCharArray()); + fail("auth succeeded with wrong password"); + } catch (SMTPException e) { + assertEquals("expected error", 535, e.getCode()); + } + + try { + smtpProtocol.auth("PLAIN", userName, "pwd".toCharArray()); + } catch (SMTPException e) { + e.printStackTrace(); + fail("authentication failed"); + } + + smtpProtocol.sendCommand("AUTH PLAIN ", new String[]{Base64.encodeAsString("\0" + userName + "\0pwd")}); + response = smtpProtocol.getResponse(); + assertEquals("expected error: User has previously authenticated.", 503, response.getCode()); + + smtpProtocol.rcpt(new Address("mail@sample.com")); + smtpProtocol.data(MimeTreeRenderer.getInstance().renderMimePart(createMail())); + + smtpProtocol.quit(); + + // mail was propagated by SMTPServer + assertNotNull("mail received by mail server", m_mailServer.getLastMail()); + } + + public void testNoRecepientSpecified() throws Exception, SMTPException { + finishSetUp(m_testConfiguration); + + MySMTPProtocol smtpProtocol = new MySMTPProtocol("127.0.0.1", m_smtpListenerPort); + smtpProtocol.openPort(); + + smtpProtocol.ehlo(InetAddress.getLocalHost()); + + smtpProtocol.mail(new Address("mail@sample.com")); + + // left out for test smtpProtocol.rcpt(new Address("mail@localhost")); + + try { + smtpProtocol.data(MimeTreeRenderer.getInstance().renderMimePart(createMail())); + fail("sending succeeded without recepient"); + } catch (Exception e) { + // test succeeded + } + + smtpProtocol.quit(); + + // mail was propagated by SMTPServer + assertNull("no mail received by mail server", m_mailServer.getLastMail()); + } + + public void testRelayingDenied() throws Exception, SMTPException { + m_testConfiguration.setAuthorizedAddresses("128.0.0.1/8"); + finishSetUp(m_testConfiguration); + + SMTPProtocol smtpProtocol = new SMTPProtocol("127.0.0.1", m_smtpListenerPort); + smtpProtocol.openPort(); + + smtpProtocol.ehlo(InetAddress.getLocalHost()); + + smtpProtocol.mail(new Address("mail@sample.com")); + try { + smtpProtocol.rcpt(new Address("maila@sample.com")); + fail("relaying allowed"); + } catch (SMTPException e) { + assertEquals("expected 550 error", 550, e.getCode()); + } + } + + public void testHandleAnnouncedMessageSizeLimitExceeded() throws Exception, SMTPException { + m_testConfiguration.setMaxMessageSize(1); // set message limit to 1kb + finishSetUp(m_testConfiguration); + + MySMTPProtocol smtpProtocol = new MySMTPProtocol("127.0.0.1", m_smtpListenerPort); + smtpProtocol.openPort(); + + smtpProtocol.ehlo(InetAddress.getLocalHost()); + + smtpProtocol.sendCommand("MAIL FROM: SIZE=1025", null); + SMTPResponse response = smtpProtocol.getResponse(); + assertEquals("expected error: max msg size exceeded", 552, response.getCode()); + + smtpProtocol.rcpt(new Address("mail@localhost")); + } + + public void testHandleMessageSizeLimitExceeded() throws Exception, SMTPException { + m_testConfiguration.setMaxMessageSize(1); // set message limit to 1kb + finishSetUp(m_testConfiguration); + + MySMTPProtocol smtpProtocol = new MySMTPProtocol("127.0.0.1", m_smtpListenerPort); + smtpProtocol.openPort(); + + smtpProtocol.ehlo(InetAddress.getLocalHost()); + + smtpProtocol.mail(new Address("mail@localhost")); + smtpProtocol.rcpt(new Address("mail@localhost")); + + MimeHeader mimeHeader = new MimeHeader(new Header()); + mimeHeader.set("Mime-Version", "1.0"); + LocalMimePart mail = new LocalMimePart(mimeHeader); + MimeHeader header = mail.getHeader(); + header.setMimeType(new MimeType("text", "plain")); + + // create Body with more than 1kb + StringBuffer body = new StringBuffer(); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345678301234567840123456785012345678601234567870123456788012345678901234567100"); + body.append("1234567810123456782012345"); // 1025 chars + + mail.setBody(new CharSequenceSource(body.toString())); + + try { + smtpProtocol.data(MimeTreeRenderer.getInstance().renderMimePart(mail)); + fail("message size exceeded not recognized"); + } catch (SMTPException e) { + assertEquals("expected 552 error", 552, e.getCode()); + } + + } +} + +class MySMTPProtocol extends SMTPProtocol +{ + + public MySMTPProtocol(String s, int i) { + super(s, i); + } + + public MySMTPProtocol(String s) { + super(s); + } + + public void sendCommand(String string, String[] strings) throws IOException { + super.sendCommand(string, strings); + } + + public SMTPResponse getResponse() throws IOException, SMTPException { + return super.readSingleLineResponse(); + } +} Index: src/test/org/apache/james/smtpserver/SMTPTestConfiguration.java =================================================================== --- src/test/org/apache/james/smtpserver/SMTPTestConfiguration.java (revision 0) +++ src/test/org/apache/james/smtpserver/SMTPTestConfiguration.java (revision 0) @@ -0,0 +1,109 @@ +/*********************************************************************** + * Copyright (c) 2000-2005 The Apache Software Foundation. * + * All rights reserved. * + * ------------------------------------------------------------------- * + * Licensed under the Apache License, Version 2.0 (the "License"); you * + * may not use this file except in compliance with the License. You * + * may obtain a copy of the License at: * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * + * implied. See the License for the specific language governing * + * permissions and limitations under the License. * + ***********************************************************************/ + + +package org.apache.james.smtpserver; + +import org.apache.avalon.framework.configuration.DefaultConfiguration; +import org.apache.james.test.util.Util; + +public class SMTPTestConfiguration extends DefaultConfiguration { + + private int m_smtpListenerPort; + private int m_maxMessageSize = 0; + private String m_authorizedAddresses = "127.0.0.0/8"; + private String m_authorizingMode = "false"; + private boolean m_verifyIdentity = false; + + public SMTPTestConfiguration(int smtpListenerPort) { + super("smptserver"); + + m_smtpListenerPort = smtpListenerPort; + } + + public void setMaxMessageSize(int kilobytes) + { + m_maxMessageSize = kilobytes; + } + + public int getMaxMessageSize() { + return m_maxMessageSize; + } + + public String getAuthorizedAddresses() { + return m_authorizedAddresses; + } + + public void setAuthorizedAddresses(String authorizedAddresses) { + m_authorizedAddresses = authorizedAddresses; + } + + public void setAuthorizingNotRequired() { + m_authorizingMode = "false"; + m_verifyIdentity = false; + } + + public void setAuthorizingRequired() { + m_authorizingMode = "true"; + m_verifyIdentity = true; + } + + public void setAuthorizingAnnounce() { + m_authorizingMode = "announce"; + m_verifyIdentity = true; + } + + public void init() { + + setAttribute("enabled", true); + + addChild(Util.getValuedConfiguration("port", "" + m_smtpListenerPort)); + + DefaultConfiguration handlerConfig = new DefaultConfiguration("handler"); + handlerConfig.addChild(Util.getValuedConfiguration("helloName", "myMailServer")); + handlerConfig.addChild(Util.getValuedConfiguration("connectiontimeout", "360000")); + handlerConfig.addChild(Util.getValuedConfiguration("authorizedAddresses", m_authorizedAddresses)); + handlerConfig.addChild(Util.getValuedConfiguration("maxmessagesize", "" + m_maxMessageSize)); + handlerConfig.addChild(Util.getValuedConfiguration("authRequired", m_authorizingMode)); + if (m_verifyIdentity) handlerConfig.addChild(Util.getValuedConfiguration("verifyIdentity", "" + m_verifyIdentity)); + + DefaultConfiguration handlerChainConfig = new DefaultConfiguration("handlerchain"); + handlerChainConfig.addChild(createCommandHandlerConfiguration("HELO", HeloCmdHandler.class)); + handlerChainConfig.addChild(createCommandHandlerConfiguration("EHLO", EhloCmdHandler.class)); + handlerChainConfig.addChild(createCommandHandlerConfiguration("AUTH", AuthCmdHandler.class)); + handlerChainConfig.addChild(createCommandHandlerConfiguration("VRFY", VrfyCmdHandler.class)); + handlerChainConfig.addChild(createCommandHandlerConfiguration("EXPN", ExpnCmdHandler.class)); + handlerChainConfig.addChild(createCommandHandlerConfiguration("MAIL", MailCmdHandler.class)); + handlerChainConfig.addChild(createCommandHandlerConfiguration("RCPT", RcptCmdHandler.class)); + handlerChainConfig.addChild(createCommandHandlerConfiguration("DATA", DataCmdHandler.class)); + handlerChainConfig.addChild(createCommandHandlerConfiguration("RSET", RsetCmdHandler.class)); + handlerChainConfig.addChild(createCommandHandlerConfiguration("HELP", HelpCmdHandler.class)); + handlerChainConfig.addChild(createCommandHandlerConfiguration("QUIT", QuitCmdHandler.class)); + + handlerConfig.addChild(handlerChainConfig); + addChild(handlerConfig); + } + + private DefaultConfiguration createCommandHandlerConfiguration(String command, Class commandClass) { + DefaultConfiguration cmdHandlerConfig = new DefaultConfiguration("handler"); + cmdHandlerConfig.setAttribute("command", command); + String classname = commandClass.getName(); + cmdHandlerConfig.setAttribute("class", classname); + return cmdHandlerConfig; + } + +} Index: build.xml =================================================================== --- build.xml (revision 360174) +++ build.xml (working copy) @@ -739,6 +739,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +