View Javadoc

1   /************************************************************************
2    * Copyright (c) 2000-2006 The Apache Software Foundation.             *
3    * All rights reserved.                                                *
4    * ------------------------------------------------------------------- *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you *
6    * may not use this file except in compliance with the License. You    *
7    * may obtain a copy of the License at:                                *
8    *                                                                     *
9    *     http://www.apache.org/licenses/LICENSE-2.0                      *
10   *                                                                     *
11   * Unless required by applicable law or agreed to in writing, software *
12   * distributed under the License is distributed on an "AS IS" BASIS,   *
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or     *
14   * implied.  See the License for the specific language governing       *
15   * permissions and limitations under the License.                      *
16   ***********************************************************************/
17  
18  package org.apache.james.nntpserver;
19  
20  import org.apache.avalon.cornerstone.services.connection.ConnectionHandler;
21  import org.apache.avalon.excalibur.pool.DefaultPool;
22  import org.apache.avalon.excalibur.pool.HardResourceLimitingPool;
23  import org.apache.avalon.excalibur.pool.ObjectFactory;
24  import org.apache.avalon.excalibur.pool.Pool;
25  import org.apache.avalon.excalibur.pool.Poolable;
26  import org.apache.avalon.framework.activity.Initializable;
27  import org.apache.avalon.framework.configuration.Configuration;
28  import org.apache.avalon.framework.configuration.ConfigurationException;
29  import org.apache.avalon.framework.logger.LogEnabled;
30  import org.apache.avalon.framework.service.ServiceException;
31  import org.apache.avalon.framework.service.ServiceManager;
32  
33  import org.apache.james.core.AbstractJamesService;
34  import org.apache.james.nntpserver.repository.NNTPRepository;
35  import org.apache.james.services.UsersRepository;
36  import org.apache.james.util.watchdog.Watchdog;
37  import org.apache.james.util.watchdog.WatchdogFactory;
38  
39  /***
40   * NNTP Server
41   *
42   */
43  public class NNTPServer extends AbstractJamesService implements NNTPServerMBean {
44  
45      /***
46       * Whether authentication is required to access this NNTP server
47       */
48      private boolean authRequired = false;
49  
50      /***
51       * The repository that stores the news articles for this NNTP server.
52       */
53      private NNTPRepository repo;
54  
55      /***
56       * The repository that stores the local users.  Used for authentication.
57       */
58      private UsersRepository userRepository = null;
59  
60      /***
61       * The pool used to provide NNTP Handler objects
62       */
63      private Pool theHandlerPool = null;
64  
65      /***
66       * The pool used to provide NNTP Handler objects
67       */
68      private ObjectFactory theHandlerFactory = new NNTPHandlerFactory();
69  
70      /***
71       * The factory used to generate Watchdog objects
72       */
73      private WatchdogFactory theWatchdogFactory;
74  
75      /***
76       * The configuration data to be passed to the handler
77       */
78      private NNTPHandlerConfigurationData theConfigData
79          = new NNTPHandlerConfigurationDataImpl();
80  
81      /***
82       * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
83       */
84      public void service( final ServiceManager componentManager )
85          throws ServiceException {
86          super.service(componentManager);
87          userRepository = (UsersRepository)componentManager.lookup(UsersRepository.ROLE);
88  
89          repo = (NNTPRepository)componentManager
90              .lookup("org.apache.james.nntpserver.repository.NNTPRepository");
91  
92      }
93  
94      /***
95       * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
96       */
97      public void configure(final Configuration configuration) throws ConfigurationException {
98          super.configure(configuration);
99          if (isEnabled()) {
100             Configuration handlerConfiguration = configuration.getChild("handler");
101             authRequired =
102                 handlerConfiguration.getChild("authRequired").getValueAsBoolean(false);
103             if (getLogger().isDebugEnabled()) {
104                 if (authRequired) {
105                     getLogger().debug("NNTP Server requires authentication.");
106                 } else {
107                     getLogger().debug("NNTP Server doesn't require authentication.");
108                 }
109             }
110         }
111     }
112 
113     /***
114      * @see org.apache.avalon.framework.activity.Initializable#initialize()
115      */
116     public void initialize() throws Exception {
117         super.initialize();
118         if (!isEnabled()) {
119             return;
120         }
121 
122         if (connectionLimit != null) {
123             theHandlerPool = new HardResourceLimitingPool(theHandlerFactory, 5, connectionLimit.intValue());
124             getLogger().debug("Using a bounded pool for NNTP handlers with upper limit " + connectionLimit.intValue());
125         } else {
126             // NOTE: The maximum here is not a real maximum.  The handler pool will continue to
127             //       provide handlers beyond this value.
128             theHandlerPool = new DefaultPool(theHandlerFactory, null, 5, 30);
129             getLogger().debug("Using an unbounded pool for NNTP handlers.");
130         }
131         if (theHandlerPool instanceof LogEnabled) {
132             ((LogEnabled)theHandlerPool).enableLogging(getLogger());
133         }
134         if (theHandlerPool instanceof Initializable) {
135             ((Initializable)theHandlerPool).initialize();
136         }
137 
138         theWatchdogFactory = getWatchdogFactory();
139     }
140 
141     /***
142      * @see org.apache.james.core.AbstractJamesService#getDefaultPort()
143      */
144      protected int getDefaultPort() {
145         return 119;
146      }
147 
148     /***
149      * @see org.apache.james.core.AbstractJamesService#getServiceType()
150      */
151     public String getServiceType() {
152         return "NNTP Service";
153     }
154 
155     /***
156      * @see org.apache.avalon.cornerstone.services.connection.AbstractHandlerFactory#newHandler()
157      */
158     protected ConnectionHandler newHandler()
159             throws Exception {
160         NNTPHandler theHandler = (NNTPHandler)theHandlerPool.get();
161 
162         Watchdog theWatchdog = theWatchdogFactory.getWatchdog(theHandler.getWatchdogTarget());
163 
164         theHandler.setConfigurationData(theConfigData);
165         theHandler.setWatchdog(theWatchdog);
166         return theHandler;
167     }
168 
169     /***
170      * @see org.apache.avalon.cornerstone.services.connection.ConnectionHandlerFactory#releaseConnectionHandler(ConnectionHandler)
171      */
172     public void releaseConnectionHandler( ConnectionHandler connectionHandler ) {
173         if (!(connectionHandler instanceof NNTPHandler)) {
174             throw new IllegalArgumentException("Attempted to return non-NNTPHandler to pool.");
175         }
176         theHandlerPool.put((Poolable)connectionHandler);
177     }
178 
179     /***
180      * The factory for producing handlers.
181      */
182     private static class NNTPHandlerFactory
183         implements ObjectFactory {
184 
185         /***
186          * @see org.apache.avalon.excalibur.pool.ObjectFactory#newInstance()
187          */
188         public Object newInstance() throws Exception {
189             return new NNTPHandler();
190         }
191 
192         /***
193          * @see org.apache.avalon.excalibur.pool.ObjectFactory#getCreatedClass()
194          */
195         public Class getCreatedClass() {
196             return NNTPHandler.class;
197         }
198 
199         /***
200          * @see org.apache.avalon.excalibur.pool.ObjectFactory#decommision(Object)
201          */
202         public void decommission( Object object ) throws Exception {
203             return;
204         }
205     }
206 
207     /***
208      * A class to provide NNTP handler configuration to the handlers
209      */
210     private class NNTPHandlerConfigurationDataImpl
211         implements NNTPHandlerConfigurationData {
212 
213         /***
214          * @see org.apache.james.smtpserver.NNTPHandlerConfigurationData#getHelloName()
215          */
216         public String getHelloName() {
217             return NNTPServer.this.helloName;
218         }
219 
220         /***
221          * @see org.apache.james.smtpserver.NNTPHandlerConfigurationData#isAuthRequired()
222          */
223         public boolean isAuthRequired() {
224             return NNTPServer.this.authRequired;
225         }
226 
227         /***
228          * @see org.apache.james.smtpserver.NNTPHandlerConfigurationData#getUsersRepository()
229          */
230         public UsersRepository getUsersRepository() {
231             return NNTPServer.this.userRepository;
232         }
233 
234         /***
235          * @see org.apache.james.smtpserver.NNTPHandlerConfigurationData#getNNTPRepository()
236          */
237         public NNTPRepository getNNTPRepository() {
238             return NNTPServer.this.repo;
239         }
240 
241     }
242 }