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.remotemanager;
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.service.ServiceException;
028: import org.apache.avalon.framework.service.ServiceManager;
029: import org.apache.avalon.framework.configuration.Configuration;
030: import org.apache.avalon.framework.configuration.ConfigurationException;
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.services.UsersStore;
037: import org.apache.james.util.watchdog.Watchdog;
038: import org.apache.james.util.watchdog.WatchdogFactory;
039:
040: import java.util.HashMap;
041:
042: /**
043: * Provides a really rude network interface to administer James.
044: * Allow to add accounts.
045: * TODO: -improve protocol
046: * -add remove user
047: * -much more...
048: * @version 1.0.0, 24/04/1999
049: */
050: public class RemoteManager extends AbstractJamesService implements
051: RemoteManagerMBean {
052:
053: /**
054: * A HashMap of (user id, passwords) for James administrators
055: */
056: private HashMap adminAccounts = new HashMap();
057:
058: /**
059: * The UsersStore that contains all UsersRepositories managed by this RemoteManager
060: */
061: private UsersStore usersStore;
062:
063: /**
064: * The current UsersRepository being managed/viewed/modified
065: */
066: private UsersRepository users;
067:
068: /**
069: * The service prompt to be displayed when waiting for input.
070: */
071: private String prompt = "";
072:
073: /**
074: * The reference to the internal MailServer service
075: */
076: private MailServer mailServer;
077:
078: /**
079: * The pool used to provide RemoteManager Handler objects
080: */
081: private Pool theHandlerPool = null;
082:
083: /**
084: * The pool used to provide RemoteManager Handler objects
085: */
086: private ObjectFactory theHandlerFactory = new RemoteManagerHandlerFactory();
087:
088: /**
089: * The factory used to generate Watchdog objects
090: */
091: private WatchdogFactory theWatchdogFactory;
092:
093: /**
094: * The configuration data to be passed to the handler
095: */
096: private RemoteManagerHandlerConfigurationData theConfigData = new RemoteManagerHandlerConfigurationDataImpl();
097:
098: /**
099: * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
100: */
101: public void service(final ServiceManager componentManager)
102: throws ServiceException {
103: super .service(componentManager);
104: mailServer = (MailServer) componentManager
105: .lookup(MailServer.ROLE);
106: usersStore = (UsersStore) componentManager
107: .lookup(UsersStore.ROLE);
108: users = (UsersRepository) componentManager
109: .lookup(UsersRepository.ROLE);
110: if (users == null) {
111: throw new ServiceException("",
112: "The user repository could not be found.");
113: }
114: }
115:
116: /**
117: * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
118: */
119: public void configure(final Configuration configuration)
120: throws ConfigurationException {
121:
122: super .configure(configuration);
123: if (isEnabled()) {
124: Configuration handlerConfiguration = configuration
125: .getChild("handler");
126: Configuration admin = handlerConfiguration
127: .getChild("administrator_accounts");
128: Configuration[] accounts = admin.getChildren("account");
129: for (int i = 0; i < accounts.length; i++) {
130: adminAccounts.put(accounts[i].getAttribute("login"),
131: accounts[i].getAttribute("password"));
132: }
133: Configuration promtConfiguration = handlerConfiguration
134: .getChild("prompt", false);
135: if (promtConfiguration != null)
136: prompt = promtConfiguration.getValue();
137: if (prompt == null)
138: prompt = "";
139: else if (!prompt.equals("") && !prompt.endsWith(" "))
140: prompt += " ";
141: }
142: }
143:
144: /**
145: * @see org.apache.avalon.framework.activity.Initializable#initialize()
146: */
147: public void initialize() throws Exception {
148: super .initialize();
149: if (!isEnabled()) {
150: return;
151: }
152:
153: if (connectionLimit != null) {
154: theHandlerPool = new HardResourceLimitingPool(
155: theHandlerFactory, 5, connectionLimit.intValue());
156: getLogger().debug(
157: "Using a bounded pool for RemoteManager handlers with upper limit "
158: + connectionLimit.intValue());
159: } else {
160: // NOTE: The maximum here is not a real maximum. The handler pool will continue to
161: // provide handlers beyond this value.
162: theHandlerPool = new DefaultPool(theHandlerFactory, null,
163: 5, 30);
164: getLogger()
165: .debug(
166: "Using an unbounded pool for RemoteManager handlers.");
167: }
168: if (theHandlerPool instanceof LogEnabled) {
169: ((LogEnabled) theHandlerPool).enableLogging(getLogger());
170: }
171: if (theHandlerPool instanceof Initializable) {
172: ((Initializable) theHandlerPool).initialize();
173: }
174:
175: theWatchdogFactory = getWatchdogFactory();
176: }
177:
178: /**
179: * @see org.apache.james.core.AbstractJamesService#getDefaultPort()
180: */
181: protected int getDefaultPort() {
182: return 4555;
183: }
184:
185: /**
186: * @see org.apache.james.core.AbstractJamesService#getServiceType()
187: */
188: public String getServiceType() {
189: return "Remote Manager Service";
190: }
191:
192: /**
193: * @see org.apache.avalon.cornerstone.services.connection.AbstractHandlerFactory#newHandler()
194: */
195: protected ConnectionHandler newHandler() throws Exception {
196: RemoteManagerHandler theHandler = (RemoteManagerHandler) theHandlerPool
197: .get();
198: theHandler.enableLogging(getLogger());
199:
200: Watchdog theWatchdog = theWatchdogFactory
201: .getWatchdog(theHandler.getWatchdogTarget());
202:
203: theHandler.setConfigurationData(theConfigData);
204: theHandler.setWatchdog(theWatchdog);
205: return theHandler;
206: }
207:
208: /**
209: * @see org.apache.avalon.cornerstone.services.connection.ConnectionHandlerFactory#releaseConnectionHandler(ConnectionHandler)
210: */
211: public void releaseConnectionHandler(
212: ConnectionHandler connectionHandler) {
213: if (!(connectionHandler instanceof RemoteManagerHandler)) {
214: throw new IllegalArgumentException(
215: "Attempted to return non-RemoteManagerHandler to pool.");
216: }
217: theHandlerPool.put((Poolable) connectionHandler);
218: }
219:
220: /**
221: * The factory for producing handlers.
222: */
223: private static class RemoteManagerHandlerFactory implements
224: ObjectFactory {
225:
226: /**
227: * @see org.apache.avalon.excalibur.pool.ObjectFactory#newInstance()
228: */
229: public Object newInstance() throws Exception {
230: return new RemoteManagerHandler();
231: }
232:
233: /**
234: * @see org.apache.avalon.excalibur.pool.ObjectFactory#getCreatedClass()
235: */
236: public Class getCreatedClass() {
237: return RemoteManagerHandler.class;
238: }
239:
240: /**
241: * @see org.apache.avalon.excalibur.pool.ObjectFactory#decommision(Object)
242: */
243: public void decommission(Object object) throws Exception {
244: return;
245: }
246: }
247:
248: /**
249: * A class to provide RemoteManager handler configuration to the handlers
250: */
251: private class RemoteManagerHandlerConfigurationDataImpl implements
252: RemoteManagerHandlerConfigurationData {
253:
254: /**
255: * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getHelloName()
256: */
257: public String getHelloName() {
258: return RemoteManager.this .helloName;
259: }
260:
261: /**
262: * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getMailServer()
263: */
264: public MailServer getMailServer() {
265: return RemoteManager.this .mailServer;
266: }
267:
268: /**
269: * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getUsersRepository()
270: */
271: public UsersRepository getUsersRepository() {
272: return RemoteManager.this .users;
273: }
274:
275: /**
276: * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getUsersStore()
277: */
278: public UsersStore getUserStore() {
279: return RemoteManager.this .usersStore;
280: }
281:
282: /**
283: * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getAdministrativeAccountData()
284: */
285: public HashMap getAdministrativeAccountData() {
286: return RemoteManager.this .adminAccounts;
287: }
288:
289: /**
290: * @see org.apache.james.remotemanager.RemoteManagerHandlerConfigurationData#getPrompt()
291: */
292: public String getPrompt() {
293: return RemoteManager.this.prompt;
294: }
295:
296: }
297: }
|