View Javadoc

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