KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > james > remotemanager > RemoteManagerHandler


1 /***********************************************************************
2  * Copyright (c) 2000-2004 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.remotemanager;
19
20 import org.apache.avalon.cornerstone.services.connection.ConnectionHandler;
21 import org.apache.avalon.excalibur.pool.Poolable;
22 import org.apache.avalon.framework.configuration.Configurable;
23 import org.apache.avalon.framework.configuration.Configuration;
24 import org.apache.avalon.framework.configuration.ConfigurationException;
25 import org.apache.avalon.framework.activity.Disposable;
26 import org.apache.avalon.framework.logger.AbstractLogEnabled;
27 import org.apache.james.Constants;
28 import org.apache.james.services.*;
29 import org.apache.james.userrepository.DefaultUser;
30 import org.apache.james.util.watchdog.Watchdog;
31 import org.apache.james.util.watchdog.WatchdogTarget;
32 import org.apache.mailet.MailAddress;
33
34 import javax.mail.internet.ParseException JavaDoc;
35 import java.io.BufferedReader JavaDoc;
36 import java.io.BufferedWriter JavaDoc;
37 import java.io.IOException JavaDoc;
38 import java.io.InputStreamReader JavaDoc;
39 import java.io.OutputStreamWriter JavaDoc;
40 import java.io.PrintWriter JavaDoc;
41 import java.net.Socket JavaDoc;
42 import java.util.HashMap JavaDoc;
43 import java.util.Iterator JavaDoc;
44 import java.util.Locale JavaDoc;
45 import java.util.StringTokenizer JavaDoc;
46
47 /**
48  * Provides a really rude network interface to administer James.
49  * Allow to add accounts.
50  * TODO: -improve protocol
51  * -much more...
52  *
53  * @version $Revision: 1.21.4.6 $
54  *
55  */

56 public class RemoteManagerHandler
57     extends AbstractLogEnabled
58     implements ConnectionHandler, Poolable {
59
60     /**
61      * The text string for the ADDUSER command
62      */

63     private static final String JavaDoc COMMAND_ADDUSER = "ADDUSER";
64
65     /**
66      * The text string for the SETPASSWORD command
67      */

68     private static final String JavaDoc COMMAND_SETPASSWORD = "SETPASSWORD";
69
70     /**
71      * The text string for the DELUSER command
72      */

73     private static final String JavaDoc COMMAND_DELUSER = "DELUSER";
74
75     /**
76      * The text string for the LISTUSERS command
77      */

78     private static final String JavaDoc COMMAND_LISTUSERS = "LISTUSERS";
79
80     /**
81      * The text string for the COUNTUSERS command
82      */

83     private static final String JavaDoc COMMAND_COUNTUSERS = "COUNTUSERS";
84
85     /**
86      * The text string for the VERIFY command
87      */

88     private static final String JavaDoc COMMAND_VERIFY = "VERIFY";
89
90     /**
91      * The text string for the HELP command
92      */

93     private static final String JavaDoc COMMAND_HELP = "HELP";
94
95     /**
96      * The text string for the SETFORWARDING command
97      */

98     private static final String JavaDoc COMMAND_SETFORWARDING = "SETFORWARDING";
99
100     /**
101      * The text string for the SHOWFORWARDING command
102      */

103     private static final String JavaDoc COMMAND_SHOWFORWARDING = "SHOWFORWARDING";
104
105     /**
106      * The text string for the UNSETFORWARDING command
107      */

108     private static final String JavaDoc COMMAND_UNSETFORWARDING = "UNSETFORWARDING";
109
110     /**
111      * The text string for the SETALIAS command
112      */

113     private static final String JavaDoc COMMAND_SETALIAS = "SETALIAS";
114
115     /**
116      * The text string for the SHOWALIAS command
117      */

118     private static final String JavaDoc COMMAND_SHOWALIAS = "SHOWALIAS";
119
120     /**
121      * The text string for the UNSETALIAS command
122      */

123     private static final String JavaDoc COMMAND_UNSETALIAS = "UNSETALIAS";
124
125     /**
126      * The text string for the USER command
127      */

128     private static final String JavaDoc COMMAND_USER = "USER";
129
130     /**
131      * The text string for the QUIT command
132      */

133     private static final String JavaDoc COMMAND_QUIT = "QUIT";
134
135     /**
136      * The text string for the SHUTDOWN command
137      */

138     private static final String JavaDoc COMMAND_SHUTDOWN = "SHUTDOWN";
139
140     /**
141      * The per-service configuration data that applies to all handlers
142      */

143     private RemoteManagerHandlerConfigurationData theConfigData;
144
145     /**
146      * The current UsersRepository being managed/viewed/modified
147      */

148     private UsersRepository users;
149
150     /**
151      * Whether the local users repository should be used to store new
152      * users.
153      */

154     private boolean inLocalUsers = true;
155
156     /**
157      * The reader associated with incoming commands.
158      */

159     private BufferedReader JavaDoc in;
160
161     /**
162      * The writer to which outgoing messages are written.
163      */

164     private PrintWriter JavaDoc out;
165
166     /**
167      * The thread executing this handler
168      */

169     private Thread JavaDoc handlerThread;
170
171     /**
172      * The TCP/IP socket over which the RemoteManager interaction
173      * is occurring
174      */

175     private Socket JavaDoc socket;
176
177     /**
178      * The watchdog being used by this handler to deal with idle timeouts.
179      */

180     private Watchdog theWatchdog;
181
182     /**
183      * The watchdog target that idles out this handler.
184      */

185     private WatchdogTarget theWatchdogTarget = new RemoteManagerWatchdogTarget();
186
187     /**
188      * Set the configuration data for the handler.
189      *
190      * @param theData the configuration data
191      */

192     void setConfigurationData(RemoteManagerHandlerConfigurationData theData) {
193         theConfigData = theData;
194
195         // Reset the users repository to the default.
196
users = theConfigData.getUsersRepository();
197         inLocalUsers = true;
198     }
199
200     /**
201      * Set the Watchdog for use by this handler.
202      *
203      * @param theWatchdog the watchdog
204      */

205     void setWatchdog(Watchdog theWatchdog) {
206         this.theWatchdog = theWatchdog;
207     }
208
209     /**
210      * Gets the Watchdog Target that should be used by Watchdogs managing
211      * this connection.
212      *
213      * @return the WatchdogTarget
214      */

215     WatchdogTarget getWatchdogTarget() {
216         return theWatchdogTarget;
217     }
218
219     /**
220      * Idle out this connection
221      */

222     void idleClose() {
223         if (getLogger() != null) {
224             getLogger().error("Remote Manager Connection has idled out.");
225         }
226         try {
227             if (socket != null) {
228                 socket.close();
229             }
230         } catch (Exception JavaDoc e) {
231             // ignored
232
} finally {
233             socket = null;
234         }
235
236         synchronized (this) {
237             // Interrupt the thread to recover from internal hangs
238
if (handlerThread != null) {
239                 handlerThread.interrupt();
240                 handlerThread = null;
241             }
242         }
243     }
244
245     /**
246      * @see org.apache.avalon.cornerstone.services.connection.ConnectionHandler#handleConnection(Socket)
247      */

248     public void handleConnection( final Socket JavaDoc connection )
249         throws IOException JavaDoc {
250
251         socket = connection;
252         String JavaDoc remoteIP = socket.getInetAddress().getHostAddress();
253         String JavaDoc remoteHost = socket.getInetAddress().getHostName();
254
255         synchronized (this) {
256             handlerThread = Thread.currentThread();
257         }
258
259         try {
260             in = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(socket.getInputStream(), "ASCII"), 512);
261             out = new PrintWriter JavaDoc(new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(socket.getOutputStream()), 512), false);
262             if (getLogger().isInfoEnabled()) {
263                 StringBuffer JavaDoc infoBuffer =
264                     new StringBuffer JavaDoc(128)
265                             .append("Access from ")
266                             .append(remoteHost)
267                             .append("(")
268                             .append(remoteIP)
269                             .append(")");
270                 getLogger().info( infoBuffer.toString() );
271             }
272             writeLoggedResponse("JAMES Remote Administration Tool " + Constants.SOFTWARE_VERSION );
273             writeLoggedResponse("Please enter your login and password");
274             String JavaDoc login = null;
275             String JavaDoc password = null;
276             do {
277                 if (login != null) {
278                     final String JavaDoc message = "Login failed for " + login;
279                     writeLoggedFlushedResponse(message);
280                 }
281                 writeLoggedFlushedResponse("Login id:");
282                 login = in.readLine().trim();
283                 writeLoggedFlushedResponse("Password:");
284                 password = in.readLine().trim();
285             } while (!password.equals(theConfigData.getAdministrativeAccountData().get(login)) || password.length() == 0);
286
287             StringBuffer JavaDoc messageBuffer =
288                 new StringBuffer JavaDoc(64)
289                         .append("Welcome ")
290                         .append(login)
291                         .append(". HELP for a list of commands");
292             out.println( messageBuffer.toString() );
293             out.flush();
294             if (getLogger().isInfoEnabled()) {
295                 StringBuffer JavaDoc infoBuffer =
296                     new StringBuffer JavaDoc(128)
297                             .append("Login for ")
298                             .append(login)
299                             .append(" successful");
300                 getLogger().info(infoBuffer.toString());
301             }
302
303             try {
304                 theWatchdog.start();
305                 while (parseCommand(in.readLine())) {
306                     theWatchdog.reset();
307                 }
308                 theWatchdog.stop();
309             } catch (IOException JavaDoc ioe) {
310                 //We can cleanly ignore this as it's probably a socket timeout
311
} catch (Throwable JavaDoc thr) {
312                 System.out.println("Exception: " + thr.getMessage());
313                 getLogger().error("Encountered exception in handling the remote manager connection.", thr);
314             }
315             StringBuffer JavaDoc infoBuffer =
316                 new StringBuffer JavaDoc(64)
317                         .append("Logout for ")
318                         .append(login)
319                         .append(".");
320             getLogger().info(infoBuffer.toString());
321
322         } catch ( final IOException JavaDoc e ) {
323             out.println("Error. Closing connection");
324             out.flush();
325             if (getLogger().isErrorEnabled()) {
326                 StringBuffer JavaDoc exceptionBuffer =
327                     new StringBuffer JavaDoc(128)
328                             .append("Exception during connection from ")
329                             .append(remoteHost)
330                             .append(" (")
331                             .append(remoteIP)
332                             .append("): ")
333                             .append(e.getMessage());
334                 getLogger().error(exceptionBuffer.toString());
335             }
336         } finally {
337             resetHandler();
338         }
339     }
340
341     /**
342      * Resets the handler data to a basic state.
343      */

344     private void resetHandler() {
345
346         // Clear the Watchdog
347
if (theWatchdog != null) {
348             if (theWatchdog instanceof Disposable) {
349                 ((Disposable)theWatchdog).dispose();
350             }
351             theWatchdog = null;
352         }
353
354         in = null;
355         out = null;
356         try {
357             if (socket != null) {
358                 socket.close();
359             }
360         } catch (IOException JavaDoc e) {
361             if (getLogger().isErrorEnabled()) {
362                 getLogger().error("Exception closing socket: "
363                                   + e.getMessage());
364             }
365         } finally {
366             socket = null;
367         }
368
369         synchronized (this) {
370             handlerThread = null;
371         }
372
373         // Reset user repository
374
users = theConfigData.getUsersRepository();
375         inLocalUsers = true;
376
377         // Clear config data
378
theConfigData = null;
379     }
380
381     /**
382      * <p>This method parses and processes RemoteManager commands read off the
383      * wire in handleConnection. It returns true if expecting additional
384      * commands, false otherwise.</p>
385      *
386      * @param command the raw command string passed in over the socket
387      *
388      * @return whether additional commands are expected.
389      */

390     private boolean parseCommand( String JavaDoc rawCommand ) {
391         if (rawCommand == null) {
392             return false;
393         }
394         String JavaDoc command = rawCommand.trim();
395         String JavaDoc argument = null;
396         int breakIndex = command.indexOf(" ");
397         if (breakIndex > 0) {
398             argument = command.substring(breakIndex + 1);
399             command = command.substring(0, breakIndex);
400         }
401         command = command.toUpperCase(Locale.US);
402         String JavaDoc argument1 = null;
403         if (command.equals(COMMAND_ADDUSER)) {
404             doADDUSER(argument);
405         } else if (command.equals(COMMAND_SETPASSWORD)) {
406             return doSETPASSWORD(argument);
407         } else if (command.equals(COMMAND_DELUSER)) {
408             return doDELUSER(argument);
409         } else if (command.equals(COMMAND_LISTUSERS)) {
410             return doLISTUSERS(argument);
411         } else if (command.equals(COMMAND_COUNTUSERS)) {
412             return doCOUNTUSERS(argument);
413         } else if (command.equals(COMMAND_VERIFY)) {
414             return doVERIFY(argument);
415         } else if (command.equals(COMMAND_HELP)) {
416             return doHELP(argument);
417         } else if (command.equals(COMMAND_SETALIAS)) {
418             return doSETALIAS(argument);
419         } else if (command.equals(COMMAND_SETFORWARDING)) {
420             return doSETFORWARDING(argument);
421         } else if (command.equals(COMMAND_SHOWALIAS)) {
422             return doSHOWALIAS(argument);
423         } else if (command.equals(COMMAND_SHOWFORWARDING)) {
424             return doSHOWFORWARDING(argument);
425         } else if (command.equals(COMMAND_UNSETALIAS)) {
426             return doUNSETALIAS(argument);
427         } else if (command.equals(COMMAND_UNSETFORWARDING)) {
428             return doUNSETFORWARDING(argument);
429         } else if (command.equals(COMMAND_USER)) {
430             return doUSER(argument);
431         } else if (command.equals(COMMAND_QUIT)) {
432             return doQUIT(argument);
433         } else if (command.equals(COMMAND_SHUTDOWN)) {
434             return doSHUTDOWN(argument);
435         } else {
436             return doUnknownCommand(rawCommand);
437         }
438         return true;
439     }
440
441     /**
442      * Handler method called upon receipt of an ADDUSER command.
443      * Returns whether further commands should be read off the wire.
444      *
445      * @param argument the argument passed in with the command
446      */

447     private boolean doADDUSER(String JavaDoc argument) {
448         int breakIndex = -1;
449         if ((argument == null) ||
450             (argument.equals("")) ||
451             ((breakIndex = argument.indexOf(" ")) < 0)) {
452             writeLoggedFlushedResponse("Usage: adduser [username] [password]");
453             return true;
454         }
455         String JavaDoc username = argument.substring(0,breakIndex);
456         String JavaDoc passwd = argument.substring(breakIndex + 1);
457         if (username.equals("") || passwd.equals("")) {
458             writeLoggedFlushedResponse("Usage: adduser [username] [password]");
459             return true;
460         }
461
462         boolean success = false;
463         if (users.contains(username)) {
464             StringBuffer JavaDoc responseBuffer =
465                 new StringBuffer JavaDoc(64)
466                         .append("User ")
467                         .append(username)
468                         .append(" already exists");
469             String JavaDoc response = responseBuffer.toString();
470             writeLoggedResponse(response);
471         } else if ( inLocalUsers ) {
472             // TODO: Why does the LocalUsers repository get treated differently?
473
// What exactly is the LocalUsers repository?
474
success = theConfigData.getMailServer().addUser(username, passwd);
475         } else {
476             DefaultUser user = new DefaultUser(username, "SHA");
477             user.setPassword(passwd);
478             success = users.addUser(user);
479         }
480         if ( success ) {
481             StringBuffer JavaDoc responseBuffer =
482                 new StringBuffer JavaDoc(64)
483                         .append("User ")
484                         .append(username)
485                         .append(" added");
486             String JavaDoc response = responseBuffer.toString();
487             out.println(response);
488             getLogger().info(response);
489         } else {
490             out.println("Error adding user " + username);
491             getLogger().error("Error adding user " + username);
492         }
493         out.flush();
494         return true;
495     }
496
497     /**
498      * Handler method called upon receipt of an SETPASSWORD command.
499      * Returns whether further commands should be read off the wire.
500      *
501      * @param argument the argument passed in with the command
502      */

503     private boolean doSETPASSWORD(String JavaDoc argument) {
504
505         int breakIndex = -1;
506         if ((argument == null) ||
507             (argument.equals("")) ||
508             ((breakIndex = argument.indexOf(" ")) < 0)) {
509             writeLoggedFlushedResponse("Usage: setpassword [username] [password]");
510             return true;
511         }
512         String JavaDoc username = argument.substring(0,breakIndex);
513         String JavaDoc passwd = argument.substring(breakIndex + 1);
514
515         if (username.equals("") || passwd.equals("")) {
516             writeLoggedFlushedResponse("Usage: adduser [username] [password]");
517             return true;
518         }
519         User user = users.getUserByName(username);
520         if (user == null) {
521             writeLoggedFlushedResponse("No such user " + username);
522             return true;
523         }
524         boolean success = user.setPassword(passwd);
525         if (success) {
526             users.updateUser(user);
527             StringBuffer JavaDoc responseBuffer =
528                 new StringBuffer JavaDoc(64)
529                         .append("Password for ")
530                         .append(username)
531                         .append(" reset");
532             String JavaDoc response = responseBuffer.toString();
533             out.println(response);
534             getLogger().info(response);
535         } else {
536             out.println("Error resetting password");
537             getLogger().error("Error resetting password");
538         }
539         out.flush();
540         return true;
541     }
542
543     /**
544      * Handler method called upon receipt of an DELUSER command.
545      * Returns whether further commands should be read off the wire.
546      *
547      * @param argument the argument passed in with the command
548      */

549     private boolean doDELUSER(String JavaDoc argument) {
550         String JavaDoc user = argument;
551         if ((user == null) || (user.equals(""))) {
552             writeLoggedFlushedResponse("Usage: deluser [username]");
553             return true;
554         }
555         if (users.contains(user)) {
556             try {
557                 users.removeUser(user);
558                 StringBuffer JavaDoc responseBuffer =
559                                              new StringBuffer JavaDoc(64)
560                                              .append("User ")
561                                              .append(user)
562                                              .append(" deleted");
563                 String JavaDoc response = responseBuffer.toString();
564                 out.println(response);
565                 getLogger().info(response);
566             } catch (Exception JavaDoc e) {
567                 StringBuffer JavaDoc exceptionBuffer =
568                                               new StringBuffer JavaDoc(128)
569                                               .append("Error deleting user ")
570                                               .append(user)
571                                               .append(" : ")
572                                               .append(e.getMessage());
573                 String JavaDoc exception = exceptionBuffer.toString();
574                 out.println(exception);
575                 getLogger().error(exception);
576             }
577         } else {
578             StringBuffer JavaDoc responseBuffer =
579                                          new StringBuffer JavaDoc(64)
580                                          .append("User ")
581                                          .append(user)
582                                          .append(" doesn't exist");
583             String JavaDoc response = responseBuffer.toString();
584             out.println(response);
585         }
586         out.flush();
587         return true;
588     }
589
590     /**
591      * Handler method called upon receipt of an LISTUSERS command.
592      * Returns whether further commands should be read off the wire.
593      *
594      * @param argument the argument passed in with the command
595      */

596     private boolean doLISTUSERS(String JavaDoc argument) {
597         writeLoggedResponse("Existing accounts " + users.countUsers());
598         for (Iterator JavaDoc it = users.list(); it.hasNext();) {
599            writeLoggedResponse("user: " + (String JavaDoc) it.next());
600         }
601         out.flush();
602         return true;
603     }
604
605     /**
606      * Handler method called upon receipt of an COUNTUSERS command.
607      * Returns whether further commands should be read off the wire.
608      *
609      * @param argument the argument passed in with the command
610      */

611     private boolean doCOUNTUSERS(String JavaDoc argument) {
612         writeLoggedFlushedResponse("Existing accounts " + users.countUsers());
613         return true;
614     }
615
616     /**
617      * Handler method called upon receipt of an VERIFY command.
618      * Returns whether further commands should be read off the wire.
619      *
620      * @param argument the argument passed in with the command
621      */

622     private boolean doVERIFY(String JavaDoc argument) {
623         String JavaDoc user = argument;
624         if (user == null || user.equals("")) {
625             writeLoggedFlushedResponse("Usage: verify [username]");
626             return true;
627         }
628         if (users.contains(user)) {
629             StringBuffer JavaDoc responseBuffer =
630                 new StringBuffer JavaDoc(64)
631                         .append("User ")
632                         .append(user)
633                         .append(" exists");
634             String JavaDoc response = responseBuffer.toString();
635             writeLoggedResponse(response);
636         } else {
637             StringBuffer JavaDoc responseBuffer =
638                 new StringBuffer JavaDoc(64)
639                         .append("User ")
640                         .append(user)
641                         .append(" does not exist");
642             String JavaDoc response = responseBuffer.toString();
643             writeLoggedResponse(response);
644         }
645         out.flush();
646         return true;
647     }
648
649     /**
650      * Handler method called upon receipt of an HELP command.
651      * Returns whether further commands should be read off the wire.
652      *
653      * @param argument the argument passed in with the command
654      */

655     private boolean doHELP(String JavaDoc argument) {
656         out.println("Currently implemented commands:");
657         out.println("help display this help");
658         out.println("listusers display existing accounts");
659         out.println("countusers display the number of existing accounts");
660         out.println("adduser [username] [password] add a new user");
661         out.println("verify [username] verify if specified user exist");
662         out.println("deluser [username] delete existing user");
663         out.println("setpassword [username] [password] sets a user's password");
664         out.println("setalias [user] [alias] locally forwards all email for 'user' to 'alias'");
665         out.println("showalias [username] shows a user's current email alias");
666         out.println("unsetalias [user] unsets an alias for 'user'");
667         out.println("setforwarding [username] [emailaddress] forwards a user's email to another email address");
668         out.println("showforwarding [username] shows a user's current email forwarding");
669         out.println("unsetforwarding [username] removes a forward");
670         out.println("user [repositoryname] change to another user repository");
671         out.println("shutdown kills the current JVM (convenient when James is run as a daemon)");
672         out.println("quit close connection");
673         out.flush();
674         return true;
675     }
676
677     /**
678      * Handler method called upon receipt of an SETALIAS command.
679      * Returns whether further commands should be read off the wire.
680      *
681      * @param argument the argument passed in with the command
682      */

683     private boolean doSETALIAS(String JavaDoc argument) {
684         int breakIndex = -1;
685         if ((argument == null) ||
686             (argument.equals("")) ||
687             ((breakIndex = argument.indexOf(" ")) < 0)) {
688             writeLoggedFlushedResponse("Usage: setalias [username] [emailaddress]");
689             return true;
690         }
691         String JavaDoc username = argument.substring(0,breakIndex);
692         String JavaDoc alias = argument.substring(breakIndex + 1);
693         if (username.equals("") || alias.equals("")) {
694             writeLoggedFlushedResponse("Usage: setalias [username] [alias]");
695             return true;
696         }
697         JamesUser user = (JamesUser) users.getUserByName(username);
698         if (user == null) {
699             writeLoggedFlushedResponse("No such user " + username);
700             return true;
701         }
702         JamesUser aliasUser = (JamesUser) users.getUserByName(alias);
703         if (aliasUser == null) {
704             writeLoggedFlushedResponse("Alias unknown to server - create that user first.");
705             return true;
706         }
707
708         boolean success = user.setAlias(alias);
709         if (success) {
710             user.setAliasing(true);
711             users.updateUser(user);
712             StringBuffer JavaDoc responseBuffer =
713                 new StringBuffer JavaDoc(64)
714                         .append("Alias for ")
715                         .append(username)
716                         .append(" set to:")
717                         .append(alias);
718             String JavaDoc response = responseBuffer.toString();
719             out.println(response);
720             getLogger().info(response);
721         } else {
722             out.println("Error setting alias");
723             getLogger().error("Error setting alias");
724         }
725         out.flush();
726         return true;
727     }
728
729     /**
730      * Handler method called upon receipt of an SETFORWARDING command.
731      * Returns whether further commands should be read off the wire.
732      *
733      * @param argument the argument passed in with the command
734      */

735     private boolean doSETFORWARDING(String JavaDoc argument) {
736         int breakIndex = -1;
737         if ((argument == null) ||
738             (argument.equals("")) ||
739             ((breakIndex = argument.indexOf(" ")) < 0)) {
740             writeLoggedFlushedResponse("Usage: setforwarding [username] [emailaddress]");
741             return true;
742         }
743         String JavaDoc username = argument.substring(0,breakIndex);
744         String JavaDoc forward = argument.substring(breakIndex + 1);
745         if (username.equals("") || forward.equals("")) {
746            writeLoggedFlushedResponse("Usage: setforwarding [username] [emailaddress]");
747            return true;
748         }
749         // Verify user exists
750
User baseuser = users.getUserByName(username);
751         if (baseuser == null) {
752             writeLoggedFlushedResponse("No such user " + username);
753             return true;
754         } else if (! (baseuser instanceof JamesUser ) ) {
755             writeLoggedFlushedResponse("Can't set forwarding for this user type.");
756             return true;
757         }
758         JamesUser user = (JamesUser)baseuser;
759         // Verify acceptable email address
760
MailAddress forwardAddr;
761         try {
762              forwardAddr = new MailAddress(forward);
763         } catch(ParseException JavaDoc pe) {
764             writeLoggedResponse("Parse exception with that email address: " + pe.getMessage());
765             writeLoggedFlushedResponse("Forwarding address not added for " + username);
766             return true;
767         }
768
769         boolean success = user.setForwardingDestination(forwardAddr);
770         if (success) {
771             user.setForwarding(true);
772             users.updateUser(user);
773             StringBuffer JavaDoc responseBuffer =
774                 new StringBuffer JavaDoc(64)
775                         .append("Forwarding destination for ")
776                         .append(username)
777                         .append(" set to:")
778                         .append(forwardAddr.toString());
779             String JavaDoc response = responseBuffer.toString();
780             out.println(response);
781             getLogger().info(response);
782         } else {
783             out.println("Error setting forwarding");
784             getLogger().error("Error setting forwarding");
785         }
786         out.flush();
787         return true;
788     }
789
790     /**
791      * Handler method called upon receipt of an SHOWALIAS command.
792      * Returns whether further commands should be read off the wire.
793      *
794      * @param argument the user name
795      */

796     private boolean doSHOWALIAS(String JavaDoc username) {
797         if ( username == null || username.equals("") ) {
798             writeLoggedFlushedResponse("Usage: showalias [username]");
799             return true;
800         }
801
802         JamesUser user = (JamesUser)users.getUserByName(username);
803         if ( user == null ) {
804             writeLoggedFlushedResponse("No such user " + username);
805             return true;
806         }
807
808         if ( !user.getAliasing() ) {
809             writeLoggedFlushedResponse("User " + username + " does not currently have an alias");
810             return true;
811         }
812
813         String JavaDoc alias = user.getAlias();
814
815         if ( alias == null || alias.equals("") ) { // defensive programming -- neither should occur
816
String JavaDoc errmsg = "For user " + username + ", the system indicates that aliasing is set but no alias was found";
817             out.println(errmsg);
818             getLogger().error(errmsg);
819             return true;
820         }
821
822         writeLoggedFlushedResponse("Current alias for " + username + " is: " + alias);
823         return true;
824     }
825
826     /**
827      * Handler method called upon receipt of an SHOWFORWARDING command.
828      * Returns whether further commands should be read off the wire.
829      *
830      * @param argument the user name
831      */

832     private boolean doSHOWFORWARDING(String JavaDoc username) {
833         if ( username == null || username.equals("") ) {
834             writeLoggedFlushedResponse("Usage: showforwarding [username]");
835             return true;
836         }
837
838         JamesUser user = (JamesUser)users.getUserByName(username);
839         if ( user == null ) {
840             writeLoggedFlushedResponse("No such user " + username);
841             return true;
842         }
843
844         if ( !user.getForwarding() ) {
845             writeLoggedFlushedResponse("User " + username + " is not currently being forwarded");
846             return true;
847         }
848
849         MailAddress fwdAddr = user.getForwardingDestination();
850
851         if ( fwdAddr == null ) { // defensive programming -- should not occur
852
String JavaDoc errmsg = "For user " + username + ", the system indicates that forwarding is set but no forwarding destination was found";
853             out.println(errmsg);
854             getLogger().error(errmsg);
855             return true;
856         }
857
858         writeLoggedFlushedResponse("Current forwarding destination for " + username + " is: " + fwdAddr);
859         return true;
860     }
861
862     /**
863      * Handler method called upon receipt of an UNSETALIAS command.
864      * Returns whether further commands should be read off the wire.
865      *
866      * @param argument the argument passed in with the command
867      */

868     private boolean doUNSETALIAS(String JavaDoc argument) {
869         if ((argument == null) || (argument.equals(""))) {
870             writeLoggedFlushedResponse("Usage: unsetalias [username]");
871             return true;
872         }
873         String JavaDoc username = argument;
874         JamesUser user = (JamesUser) users.getUserByName(username);
875         if (user == null) {
876             writeLoggedResponse("No such user " + username);
877         } else if (user.getAliasing()){
878             user.setAliasing(false);
879             users.updateUser(user);
880             StringBuffer JavaDoc responseBuffer =
881                 new StringBuffer JavaDoc(64)
882                         .append("Alias for ")
883                         .append(username)
884                         .append(" unset");
885             String JavaDoc response = responseBuffer.toString();
886             out.println(response);
887             getLogger().info(response);
888         } else {
889             writeLoggedResponse("Aliasing not active for" + username);
890         }
891         out.flush();
892         return true;
893     }
894
895     /**
896      * Handler method called upon receipt of an UNSETFORWARDING command.
897      * Returns whether further commands should be read off the wire.
898      *
899      * @param argument the argument passed in with the command
900      */

901     private boolean doUNSETFORWARDING(String JavaDoc argument) {
902         if ((argument == null) || (argument.equals(""))) {
903             writeLoggedFlushedResponse("Usage: unsetforwarding [username]");
904             return true;
905         }
906         String JavaDoc username = argument;
907         JamesUser user = (JamesUser) users.getUserByName(username);
908         if (user == null) {
909             writeLoggedFlushedResponse("No such user " + username);
910         } else if (user.getForwarding()){
911             user.setForwarding(false);
912             users.updateUser(user);
913             StringBuffer JavaDoc responseBuffer =
914                 new StringBuffer JavaDoc(64)
915                         .append("Forward for ")
916                         .append(username)
917                         .append(" unset");
918             String JavaDoc response = responseBuffer.toString();
919             out.println(response);
920             out.flush();
921             getLogger().info(response);
922         } else {
923             writeLoggedFlushedResponse("Forwarding not active for" + username);
924         }
925         return true;
926     }
927
928     /**
929      * Handler method called upon receipt of a USER command.
930      * Returns whether further commands should be read off the wire.
931      *
932      * @param argument the argument passed in with the command
933      */

934     private boolean doUSER(String JavaDoc argument) {
935         if (argument == null || argument.equals("")) {
936             writeLoggedFlushedResponse("Usage: user [repositoryName]");
937             return true;
938         }
939         String JavaDoc repositoryName = argument.toLowerCase(Locale.US);
940         UsersRepository repos = theConfigData.getUserStore().getRepository(repositoryName);
941         if ( repos == null ) {
942             writeLoggedFlushedResponse("No such repository: " + repositoryName);
943         } else {
944             users = repos;
945             StringBuffer JavaDoc responseBuffer =
946                 new StringBuffer JavaDoc(64)
947                         .append("Changed to repository '")
948                         .append(repositoryName)
949                         .append("'.");
950             writeLoggedFlushedResponse(responseBuffer.toString());
951             if ( repositoryName.equals("localusers") ) {
952                 inLocalUsers = true;
953             } else {
954                 inLocalUsers = false;
955             }
956         }
957         return true;
958     }
959
960     /**
961      * Handler method called upon receipt of a QUIT command.
962      * Returns whether further commands should be read off the wire.
963      *
964      * @param argument the argument passed in with the command
965      */

966     private boolean doQUIT(String JavaDoc argument) {
967         writeLoggedFlushedResponse("Bye");
968         return false;
969     }
970
971     /**
972      * Handler method called upon receipt of a SHUTDOWN command.
973      * Returns whether further commands should be read off the wire.
974      *
975      * @param argument the argument passed in with the command
976      */

977     private boolean doSHUTDOWN(String JavaDoc argument) {
978         writeLoggedFlushedResponse("Shutting down, bye bye");
979         System.exit(0);
980         return false;
981     }
982
983     /**
984      * Handler method called upon receipt of an unrecognized command.
985      * Returns whether further commands should be read off the wire.
986      *
987      * @param argument the unknown command
988      */

989     private boolean doUnknownCommand(String JavaDoc argument) {
990         writeLoggedFlushedResponse("Unknown command " + argument);
991         return true;
992     }
993
994     /**
995      * This method logs at a "DEBUG" level the response string that
996      * was sent to the RemoteManager client. The method is provided largely
997      * as syntactic sugar to neaten up the code base. It is declared
998      * private and final to encourage compiler inlining.
999      *
1000     * @param responseString the response string sent to the client
1001     */

1002    private final void logResponseString(String JavaDoc responseString) {
1003        if (getLogger().isDebugEnabled()) {
1004            getLogger().debug("Sent: " + responseString);
1005        }
1006    }
1007
1008    /**
1009     * Write and flush a response string. The response is also logged.
1010     * Should be used for the last line of a multi-line response or
1011     * for a single line response.
1012     *
1013     * @param responseString the response string sent to the client
1014     */

1015    final void writeLoggedFlushedResponse(String JavaDoc responseString) {
1016        out.println(responseString);
1017        out.flush();
1018        logResponseString(responseString);
1019    }
1020
1021    /**
1022     * Write a response string. The response is also logged.
1023     * Used for multi-line responses.
1024     *
1025     * @param responseString the response string sent to the client
1026     */

1027    final void writeLoggedResponse(String JavaDoc responseString) {
1028        out.println(responseString);
1029        logResponseString(responseString);
1030    }
1031
1032    /**
1033     * A private inner class which serves as an adaptor
1034     * between the WatchdogTarget interface and this
1035     * handler class.
1036     */

1037    private class RemoteManagerWatchdogTarget
1038        implements WatchdogTarget {
1039
1040        /**
1041         * @see org.apache.james.util.watchdog.WatchdogTarget#execute()
1042         */

1043        public void execute() {
1044            RemoteManagerHandler.this.idleClose();
1045        }
1046    }
1047}
1048
Popular Tags