001: /****************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one *
003: * or more contributor license agreements. See the NOTICE file *
004: * distributed with this work for additional information *
005: * regarding copyright ownership. The ASF licenses this file *
006: * to you under the Apache License, Version 2.0 (the *
007: * "License"); you may not use this file except in compliance *
008: * with the License. You may obtain a copy of the License at *
009: * *
010: * http://www.apache.org/licenses/LICENSE-2.0 *
011: * *
012: * Unless required by applicable law or agreed to in writing, *
013: * software distributed under the License is distributed on an *
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015: * KIND, either express or implied. See the License for the *
016: * specific language governing permissions and limitations *
017: * under the License. *
018: ****************************************************************/package org.apache.james.pop3server;
019:
020: import org.apache.avalon.cornerstone.services.connection.ConnectionHandler;
021: import org.apache.avalon.excalibur.pool.DefaultPool;
022: import org.apache.avalon.excalibur.pool.HardResourceLimitingPool;
023: import org.apache.avalon.excalibur.pool.ObjectFactory;
024: import org.apache.avalon.excalibur.pool.Pool;
025: import org.apache.avalon.excalibur.pool.Poolable;
026: import org.apache.avalon.framework.activity.Initializable;
027: import org.apache.avalon.framework.configuration.Configuration;
028: import org.apache.avalon.framework.configuration.ConfigurationException;
029: import org.apache.avalon.framework.service.ServiceException;
030: import org.apache.avalon.framework.service.ServiceManager;
031: import org.apache.avalon.framework.logger.LogEnabled;
032:
033: import org.apache.james.core.AbstractJamesService;
034: import org.apache.james.services.MailServer;
035: import org.apache.james.services.UsersRepository;
036: import org.apache.james.util.watchdog.Watchdog;
037: import org.apache.james.util.watchdog.WatchdogFactory;
038:
039: /**
040: * <p>Accepts POP3 connections on a server socket and dispatches them to POP3Handlers.</p>
041: *
042: * <p>Also responsible for loading and parsing POP3 specific configuration.</p>
043: *
044: * @version 1.0.0, 24/04/1999
045: */
046: public class POP3Server extends AbstractJamesService implements
047: POP3ServerMBean {
048:
049: /**
050: * The internal mail server service
051: */
052: private MailServer mailServer;
053:
054: /**
055: * The user repository for this server - used to authenticate users.
056: */
057: private UsersRepository users;
058:
059: /**
060: * The number of bytes to read before resetting
061: * the connection timeout timer. Defaults to
062: * 20 KB.
063: */
064: private int lengthReset = 20 * 1024;
065:
066: /**
067: * The pool used to provide POP3 Handler objects
068: */
069: private Pool theHandlerPool = null;
070:
071: /**
072: * The factory used to provide POP3 Handler objects
073: */
074: private ObjectFactory theHandlerFactory = new POP3HandlerFactory();
075:
076: /**
077: * The factory used to generate Watchdog objects
078: */
079: private WatchdogFactory theWatchdogFactory;
080:
081: /**
082: * The configuration data to be passed to the handler
083: */
084: private POP3HandlerConfigurationData theConfigData = new POP3HandlerConfigurationDataImpl();
085:
086: /**
087: * @see org.apache.avalon.framework.service.Serviceable#compose(ServiceManager)
088: */
089: public void service(final ServiceManager componentManager)
090: throws ServiceException {
091: super .service(componentManager);
092: mailServer = (MailServer) componentManager
093: .lookup(MailServer.ROLE);
094: users = (UsersRepository) componentManager
095: .lookup(UsersRepository.ROLE);
096: }
097:
098: /**
099: * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
100: */
101: public void configure(final Configuration configuration)
102: throws ConfigurationException {
103: super .configure(configuration);
104: if (isEnabled()) {
105: Configuration handlerConfiguration = configuration
106: .getChild("handler");
107: lengthReset = handlerConfiguration.getChild("lengthReset")
108: .getValueAsInteger(lengthReset);
109: if (getLogger().isInfoEnabled()) {
110: getLogger().info(
111: "The idle timeout will be reset every "
112: + lengthReset + " bytes.");
113: }
114: }
115: }
116:
117: /**
118: * @see org.apache.avalon.framework.activity.Initializable#initialize()
119: */
120: public void initialize() throws Exception {
121: super .initialize();
122: if (!isEnabled()) {
123: return;
124: }
125:
126: if (connectionLimit != null) {
127: theHandlerPool = new HardResourceLimitingPool(
128: theHandlerFactory, 5, connectionLimit.intValue());
129: getLogger().debug(
130: "Using a bounded pool for POP3 handlers with upper limit "
131: + connectionLimit.intValue());
132: } else {
133: // NOTE: The maximum here is not a real maximum. The handler pool will continue to
134: // provide handlers beyond this value.
135: theHandlerPool = new DefaultPool(theHandlerFactory, null,
136: 5, 30);
137: getLogger().debug(
138: "Using an unbounded pool for POP3 handlers.");
139: }
140: if (theHandlerPool instanceof LogEnabled) {
141: ((LogEnabled) theHandlerPool).enableLogging(getLogger());
142: }
143: if (theHandlerPool instanceof Initializable) {
144: ((Initializable) theHandlerPool).initialize();
145: }
146:
147: theWatchdogFactory = getWatchdogFactory();
148: }
149:
150: /**
151: * @see org.apache.james.core.AbstractJamesService#getDefaultPort()
152: */
153: protected int getDefaultPort() {
154: return 110;
155: }
156:
157: /**
158: * @see org.apache.james.core.AbstractJamesService#getServiceType()
159: */
160: public String getServiceType() {
161: return "POP3 Service";
162: }
163:
164: /**
165: * @see org.apache.avalon.cornerstone.services.connection.AbstractHandlerFactory#newHandler()
166: */
167: protected ConnectionHandler newHandler() throws Exception {
168: POP3Handler theHandler = (POP3Handler) theHandlerPool.get();
169:
170: Watchdog theWatchdog = theWatchdogFactory
171: .getWatchdog(theHandler.getWatchdogTarget());
172:
173: theHandler.setConfigurationData(theConfigData);
174:
175: theHandler.setWatchdog(theWatchdog);
176:
177: return theHandler;
178: }
179:
180: /**
181: * @see org.apache.avalon.cornerstone.services.connection.ConnectionHandlerFactory#releaseConnectionHandler(ConnectionHandler)
182: */
183: public void releaseConnectionHandler(
184: ConnectionHandler connectionHandler) {
185: if (!(connectionHandler instanceof POP3Handler)) {
186: throw new IllegalArgumentException(
187: "Attempted to return non-POP3Handler to pool.");
188: }
189: theHandlerPool.put((Poolable) connectionHandler);
190: }
191:
192: /**
193: * The factory for producing handlers.
194: */
195: private static class POP3HandlerFactory implements ObjectFactory {
196:
197: /**
198: * @see org.apache.avalon.excalibur.pool.ObjectFactory#newInstance()
199: */
200: public Object newInstance() throws Exception {
201: return new POP3Handler();
202: }
203:
204: /**
205: * @see org.apache.avalon.excalibur.pool.ObjectFactory#getCreatedClass()
206: */
207: public Class getCreatedClass() {
208: return POP3Handler.class;
209: }
210:
211: /**
212: * @see org.apache.avalon.excalibur.pool.ObjectFactory#decommision(Object)
213: */
214: public void decommission(Object object) throws Exception {
215: return;
216: }
217: }
218:
219: /**
220: * A class to provide POP3 handler configuration to the handlers
221: */
222: private class POP3HandlerConfigurationDataImpl implements
223: POP3HandlerConfigurationData {
224:
225: /**
226: * @see org.apache.james.pop3server.POP3HandlerConfigurationData#getHelloName()
227: */
228: public String getHelloName() {
229: return POP3Server.this .helloName;
230: }
231:
232: /**
233: * @see org.apache.james.pop3server.POP3HandlerConfigurationData#getResetLength()
234: */
235: public int getResetLength() {
236: return POP3Server.this .lengthReset;
237: }
238:
239: /**
240: * @see org.apache.james.pop3server.POP3HandlerConfigurationData#getMailServer()
241: */
242: public MailServer getMailServer() {
243: return POP3Server.this .mailServer;
244: }
245:
246: /**
247: * @see org.apache.james.pop3server.POP3HandlerConfigurationData#getUsersRepository()
248: */
249: public UsersRepository getUsersRepository() {
250: return POP3Server.this.users;
251: }
252: }
253: }
|