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.nntpserver;
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.logger.LogEnabled;
030: import org.apache.avalon.framework.service.ServiceException;
031: import org.apache.avalon.framework.service.ServiceManager;
032:
033: import org.apache.james.core.AbstractJamesService;
034: import org.apache.james.nntpserver.repository.NNTPRepository;
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: * NNTP Server
041: *
042: */
043: public class NNTPServer extends AbstractJamesService implements
044: NNTPServerMBean {
045:
046: /**
047: * Whether authentication is required to access this NNTP server
048: */
049: private boolean authRequired = false;
050:
051: /**
052: * The repository that stores the news articles for this NNTP server.
053: */
054: private NNTPRepository repo;
055:
056: /**
057: * The repository that stores the local users. Used for authentication.
058: */
059: private UsersRepository userRepository = null;
060:
061: /**
062: * The pool used to provide NNTP Handler objects
063: */
064: private Pool theHandlerPool = null;
065:
066: /**
067: * The pool used to provide NNTP Handler objects
068: */
069: private ObjectFactory theHandlerFactory = new NNTPHandlerFactory();
070:
071: /**
072: * The factory used to generate Watchdog objects
073: */
074: private WatchdogFactory theWatchdogFactory;
075:
076: /**
077: * The configuration data to be passed to the handler
078: */
079: private NNTPHandlerConfigurationData theConfigData = new NNTPHandlerConfigurationDataImpl();
080:
081: /**
082: * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
083: */
084: public void service(final ServiceManager componentManager)
085: throws ServiceException {
086: super .service(componentManager);
087: userRepository = (UsersRepository) componentManager
088: .lookup(UsersRepository.ROLE);
089:
090: repo = (NNTPRepository) componentManager
091: .lookup("org.apache.james.nntpserver.repository.NNTPRepository");
092:
093: }
094:
095: /**
096: * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
097: */
098: public void configure(final Configuration configuration)
099: throws ConfigurationException {
100: super .configure(configuration);
101: if (isEnabled()) {
102: Configuration handlerConfiguration = configuration
103: .getChild("handler");
104: authRequired = handlerConfiguration
105: .getChild("authRequired").getValueAsBoolean(false);
106: if (getLogger().isDebugEnabled()) {
107: if (authRequired) {
108: getLogger().debug(
109: "NNTP Server requires authentication.");
110: } else {
111: getLogger()
112: .debug(
113: "NNTP Server doesn't require authentication.");
114: }
115: }
116: }
117: }
118:
119: /**
120: * @see org.apache.avalon.framework.activity.Initializable#initialize()
121: */
122: public void initialize() throws Exception {
123: super .initialize();
124: if (!isEnabled()) {
125: return;
126: }
127:
128: if (connectionLimit != null) {
129: theHandlerPool = new HardResourceLimitingPool(
130: theHandlerFactory, 5, connectionLimit.intValue());
131: getLogger().debug(
132: "Using a bounded pool for NNTP handlers with upper limit "
133: + connectionLimit.intValue());
134: } else {
135: // NOTE: The maximum here is not a real maximum. The handler pool will continue to
136: // provide handlers beyond this value.
137: theHandlerPool = new DefaultPool(theHandlerFactory, null,
138: 5, 30);
139: getLogger().debug(
140: "Using an unbounded pool for NNTP handlers.");
141: }
142: if (theHandlerPool instanceof LogEnabled) {
143: ((LogEnabled) theHandlerPool).enableLogging(getLogger());
144: }
145: if (theHandlerPool instanceof Initializable) {
146: ((Initializable) theHandlerPool).initialize();
147: }
148:
149: theWatchdogFactory = getWatchdogFactory();
150: }
151:
152: /**
153: * @see org.apache.james.core.AbstractJamesService#getDefaultPort()
154: */
155: protected int getDefaultPort() {
156: return 119;
157: }
158:
159: /**
160: * @see org.apache.james.core.AbstractJamesService#getServiceType()
161: */
162: public String getServiceType() {
163: return "NNTP Service";
164: }
165:
166: /**
167: * @see org.apache.avalon.cornerstone.services.connection.AbstractHandlerFactory#newHandler()
168: */
169: protected ConnectionHandler newHandler() throws Exception {
170: NNTPHandler theHandler = (NNTPHandler) theHandlerPool.get();
171:
172: Watchdog theWatchdog = theWatchdogFactory
173: .getWatchdog(theHandler.getWatchdogTarget());
174:
175: theHandler.setConfigurationData(theConfigData);
176: theHandler.setWatchdog(theWatchdog);
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 NNTPHandler)) {
186: throw new IllegalArgumentException(
187: "Attempted to return non-NNTPHandler to pool.");
188: }
189: theHandlerPool.put((Poolable) connectionHandler);
190: }
191:
192: /**
193: * The factory for producing handlers.
194: */
195: private static class NNTPHandlerFactory implements ObjectFactory {
196:
197: /**
198: * @see org.apache.avalon.excalibur.pool.ObjectFactory#newInstance()
199: */
200: public Object newInstance() throws Exception {
201: return new NNTPHandler();
202: }
203:
204: /**
205: * @see org.apache.avalon.excalibur.pool.ObjectFactory#getCreatedClass()
206: */
207: public Class getCreatedClass() {
208: return NNTPHandler.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 NNTP handler configuration to the handlers
221: */
222: private class NNTPHandlerConfigurationDataImpl implements
223: NNTPHandlerConfigurationData {
224:
225: /**
226: * @see org.apache.james.smtpserver.NNTPHandlerConfigurationData#getHelloName()
227: */
228: public String getHelloName() {
229: return NNTPServer.this .helloName;
230: }
231:
232: /**
233: * @see org.apache.james.smtpserver.NNTPHandlerConfigurationData#isAuthRequired()
234: */
235: public boolean isAuthRequired() {
236: return NNTPServer.this .authRequired;
237: }
238:
239: /**
240: * @see org.apache.james.smtpserver.NNTPHandlerConfigurationData#getUsersRepository()
241: */
242: public UsersRepository getUsersRepository() {
243: return NNTPServer.this .userRepository;
244: }
245:
246: /**
247: * @see org.apache.james.smtpserver.NNTPHandlerConfigurationData#getNNTPRepository()
248: */
249: public NNTPRepository getNNTPRepository() {
250: return NNTPServer.this.repo;
251: }
252:
253: }
254: }
|