1 /**
2 * AUTOHIT 2003
3 * Copyright Erich P Gatejen (c) 1989,1997,2003,2004
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Additional license information can be found in the documentation.
19 * @author Erich P Gatejen
20 */
21 package autohit.call.modules;
22
23 import java.io.BufferedReader;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.io.OutputStream;
28 import java.io.Writer;
29
30 import org.apache.commons.net.io.Util;
31 import org.apache.commons.net.smtp.RelayPath;
32 import org.apache.commons.net.smtp.SMTPClient;
33 import org.apache.commons.net.smtp.SMTPConnectionClosedException;
34
35 import autohit.call.CallException;
36 import autohit.common.Constants;
37 import autohit.universe.UniverseException;
38 import autohit.universe.UniverseUtils;
39 import autohit.vm.process.StringProcessors;
40
41 /**
42 * Simple SMTP module. There is a client/per module at this time. <code>
43 * start(address,optional{port}) start an SMTP session<br>
44 * login(optional{hostname}) login to peer<br>
45 * sender(address) set the sender with address<br>
46 * addsenderrelay(address) add to the sender relay path<br>
47 * senderrelay() set the sender with sender relay path. clear the accumulated relay path.<br>
48 * recipient(address) add a recipient with address<br>
49 * addrecipientrelay(address) add to the recipient relay path<br>
50 * newrecipientrelay(address) start a new recipient relay path<br>
51 * recipientrelay() add a recipient with recipient relay path. clear the accumulated relay path.<br>
52 * send(text) send message from text.<br>
53 * senduni(uniobj) send message from universe object.<br>
54 * senduniscrub(uniobj) send message from universe object. scrub it first with variable replacements<br>
55 * reset() reset the smtp state.<br>
56 * done() complete a session. It will logout and close.<br>
57 * mailit(from,to,text,host,optional{port}) convenience method for sending small message.
58 * mailituni(from,to,uniobj,host,optional{port}) convenience method for sending small message.
59 * </code>
60 *
61 * @author Erich P. Gatejen
62 * @version 1.0 <i>Version History</i><code>EPG - Initial - 11Aug03</code>
63 */
64 public class SimpleSmtpModule extends Module {
65
66 private final static String myNAME = "SimpleSmtp";
67 private final static String TEMPFILE = "temp/smtpscrub";
68
69 private final static String ERROR_STRING_FOR_FAILURE = "451";
70 private final static int SMTP_ERROR_THRESHOLD = 300;
71 // An SMTP error code
72
73 /**
74 * METHODS */
75 private final static String method_START = "start";
76 private final static String method_START_1_ADDRESS = "address";
77 private final static String method_START_2_PORT = "port";
78 private final static String method_LOGIN = "login";
79 private final static String method_LOGIN_1_HOSTNAME = "hostname";
80 private final static String method_SENDER = "sender";
81 private final static String method_SENDER_1_ADDRESS = "address";
82 private final static String method_ADDSENDERRELAY = "addsenderrelay";
83 private final static String method_ADDSENDERRELAY_1_ADDRESS = "address";
84 private final static String method_SENDERRELAY = "senderrelay";
85 private final static String method_RECIPIENT = "recipient";
86 private final static String method_RECIPIENT_1_ADDRESS = "address";
87 private final static String method_ADDRECIPIENTRELAY = "addrecipientrelay";
88 private final static String method_NEWRECIPIENTRELAY = "newrecipientrelay";
89 private final static String method_ADDRECIPIENTRELAY_1_ADDRESS = "address";
90 private final static String method_RECIPIENTRELAY = "recipientrelay";
91 private final static String method_SEND = "send";
92 private final static String method_SEND_1_TEXT = "text";
93 private final static String method_SENDUNI = "senduni";
94 private final static String method_SENDUNI_1_TEXT = "uniobj";
95 private final static String method_SENDUNISCRUB = "senduniscrub";
96 private final static String method_SENDUNISCRUB_1_TEXT = "uniobj";
97 private final static String method_RESET = "reset";
98 private final static String method_DONE = "done";
99 private final static String method_MAILIT = "mailit";
100 private final static String method_MAILIT_1_TO = "to";
101 private final static String method_MAILIT_2_FROM = "from";
102 private final static String method_MAILIT_3_TEXT = "text";
103 private final static String method_MAILIT_4_HOSTNAME = "host";
104 private final static String method_MAILIT_5_PORT = "port";
105 private final static String method_MAILITUNI = "mailituni";
106 private final static String method_MAILITUNI_1_TO = "to";
107 private final static String method_MAILITUNI_2_FROM = "from";
108 private final static String method_MAILITUNI_3_UNIOBJ = "uniobj";
109 private final static String method_MAILITUNI_4_HOSTNAME = "host";
110 private final static String method_MAILITUNI_5_PORT = "port";
111
112 SMTPClient client;
113 RelayPath senderrelay;
114 RelayPath recipientrelay;
115
116 /**
117 * Constructor */
118 public SimpleSmtpModule() {
119
120 }
121
122 // IMPLEMENTORS
123
124 /**
125 * Execute a named method. You must implement this method. You can call any
126 * of the helpers for data and services. The returned object better be a
127 * string (for now).
128 *
129 * @param name
130 * name of the method
131 * @see autohit.common.NOPair
132 * @throws CallException
133 */
134 public Object execute_chain(String name) throws CallException {
135
136 Object response = Constants.EMPTY_LEFT;
137 Object thingie;
138
139 if (name.equals(method_START)) {
140 String param1 = this.required(method_START_1_ADDRESS, name);
141 String param2 = this.optional(method_START_2_PORT);
142 this.start(param1, param2);
143
144 } else if (name.equals(method_LOGIN)) {
145 String param1 = this.optional(method_LOGIN_1_HOSTNAME);
146 this.login(param1);
147
148 } else if (name.equals(method_SENDER)) {
149 String param1 = this.required(method_SENDER_1_ADDRESS, name);
150 this.sender(param1);
151
152 } else if (name.equals(method_ADDSENDERRELAY)) {
153 String param1 = this.required(method_ADDSENDERRELAY_1_ADDRESS, name);
154 this.addsenderrelay(param1);
155
156 } else if (name.equals(method_SENDERRELAY)) {
157 this.senderrelay();
158
159 } else if (name.equals(method_RECIPIENT)) {
160 String param1 = this.required(method_RECIPIENT_1_ADDRESS, name);
161 this.recipient(param1);
162
163 } else if (name.equals(method_ADDRECIPIENTRELAY)) {
164 String param1 = this.required(method_ADDRECIPIENTRELAY_1_ADDRESS, name);
165 this.addrecipientrelay(param1);
166
167 } else if (name.equals(method_NEWRECIPIENTRELAY)) {
168 this.newrecipientrelay();
169
170 } else if (name.equals(method_RECIPIENTRELAY)) {
171 this.recipientrelay();
172
173 } else if (name.equals(method_SEND)) {
174 String param1 = this.required(method_SEND_1_TEXT, name);
175 response = this.send(param1);
176
177 } else if (name.equals(method_SENDUNI)) {
178 String param1 = this.required(method_SENDUNI_1_TEXT, name);
179 response = this.senduni(param1);
180
181 } else if (name.equals(method_SENDUNISCRUB)) {
182 String param1 = this.required(method_SENDUNISCRUB_1_TEXT, name);
183 response = this.senduniscrub(param1);
184
185 } else if (name.equals(method_RESET)) {
186 this.reset();
187
188 } else if (name.equals(method_DONE)) {
189 this.done();
190
191 } else if (name.equals(method_MAILIT)) {
192 String param1 = this.required(method_MAILIT_1_TO, name);
193 String param2 = this.required(method_MAILIT_2_FROM, name);
194 String param3 = this.required(method_MAILIT_3_TEXT, name);
195 String param4 = this.required(method_MAILIT_4_HOSTNAME, name);
196 String param5 = this.optional(method_MAILIT_5_PORT);
197 response = this.mailit(param1, param2, param3, param4, param5);
198
199 } else if (name.equals(method_MAILITUNI)) {
200 String param1 = this.required(method_MAILITUNI_1_TO, name);
201 String param2 = this.required(method_MAILITUNI_2_FROM, name);
202 String param3 = this.required(method_MAILITUNI_3_UNIOBJ, name);
203 String param4 = this.required(method_MAILITUNI_4_HOSTNAME, name);
204 String param5 = this.optional(method_MAILITUNI_5_PORT);
205 response = this.mailituni(param1, param2, param3, param4, param5);
206
207 } else {
208 error("Not a provided method. method=" + name);
209 }
210 return response;
211 }
212
213 /**
214 * Allow the subclass a chance to initialize. At a minium, an implementor
215 * should create an empty method.
216 *
217 * @throws CallException
218 * @return the name
219 */
220 protected String instantiation_chain() throws CallException {
221 client = null;
222 return myNAME;
223 }
224
225 /**
226 * Allow the subclass a chance to cleanup on free. At a minium, an
227 * implementor should create an empty method.
228 *
229 * @throws CallException
230 */
231 protected void free_chain() throws CallException {
232 try {
233 this.done();
234 } catch (Exception e) {
235 // don't care
236 }
237 }
238
239 // PRIVATE IMPLEMENTATIONS
240
241 /**
242 * Start method. It will open a connection to an SMTP server/relay. If a
243 * session is already started, it will report an error. If it cannot make
244 * the connection, it will cause a fault.
245 *
246 * @param addr
247 * the domain name address. Do not include protocol or port.
248 * @param post
249 * this should be a parsable integer. If it is null, the default
250 * will be used.
251 * @throws CallException
252 */
253 private void start(String addr, String port) throws CallException {
254
255 SMTPClient candidate = null;
256
257 // Already started?
258 if (client != null) {
259 this.error("Session already started. Ignoring new start().");
260 return;
261 }
262 // Passed a port number?
263 int portNum = 0;
264 if (port != null) {
265 try {
266 portNum = Integer.parseInt(port);
267 } catch (Exception e) {
268 this.fault("Malformed 'port' number. It must be a parsable integer. text=" + port);
269 }
270 }
271 // Try and construct it
272 try {
273 candidate = new SMTPClient();
274 if (port == null) {
275 candidate.connect(addr);
276 } else {
277 candidate.connect(addr, portNum);
278 }
279
280 } catch (Exception ex) {
281 if(client.isConnected()) {
282 try {
283 client.disconnect();
284 } catch(IOException f) {
285 // do nothing
286 }
287 }
288 this.fault("Could not connect to host. message=" + ex.getMessage());
289 }
290
291 // NO CODE AFTER THIS!
292 this.log("Connection started.");
293 client = candidate;
294 }
295
296 /**
297 * Done method. Dispose of state and everything. */
298 private void done() {
299
300 // Brute force close. Don't care about errors
301 if (client != null) {
302 try {
303 client.logout();
304 } catch (Exception exx) {
305 }
306 try {
307 client.disconnect();
308 } catch (Exception exx) {
309 }
310 }
311 senderrelay = null;
312 client = null;
313 this.log("Connection closed.");
314 // NO NEW CODE BEFORE THIS LINE!
315 }
316
317 /**
318 * Login method. It will fault if a session has not been started or has
319 * expired. The hostname is optional; pass null if not used.
320 *
321 * @param hostname
322 * hostname to use instead of localhost.
323 * @throws CallException
324 */
325 private void login(String hostname) throws CallException {
326
327 // Is it started?
328 if (client == null) {
329 this.fault("Session not start()'ed.");
330 }
331
332 try {
333 if (hostname == null) {
334 client.login();
335 } else {
336 client.login(hostname);
337 }
338
339 // what happened?
340 int code = client.getReplyCode();
341 if (code >= SMTP_ERROR_THRESHOLD) {
342 this.error("Login failed with code=" + code + " reply=" + client.getReplyString());
343 } else if (this.isDebugging()) {
344 this.debug("Login complete. code=" + code);
345 }
346
347 } catch (SMTPConnectionClosedException ex) {
348 this.done();
349 this.fault("Cannot login. Connection expired and closed itself.");
350 } catch (Exception ex) {
351 this.done();
352 this.fault("Cannot login due to exception. message=" + ex.getMessage());
353 }
354 }
355
356 /**
357 * Sender method. It will fault if a session has not been started or has
358 * expired. It will set the sender. Subsequent calls will overwrite the
359 * value. The address should be a valid email address.
360 *
361 * @param hostname
362 * hostname to use instead of localhost.
363 * @throws CallException
364 */
365 private void sender(String s) throws CallException {
366
367 // Is it started?
368 if (client == null) {
369 this.fault("Session not start()'ed.");
370 }
371
372 try {
373 client.setSender(s);
374
375 // what happened?
376 int code = client.getReplyCode();
377 if (code >= SMTP_ERROR_THRESHOLD) {
378 this.error("Sender failed with code=" + code + " reply=" + client.getReplyString());
379 } else if (this.isDebugging()) {
380 this.debug("Sender complete. code=" + code);
381 }
382
383 } catch (SMTPConnectionClosedException ex) {
384 this.done();
385 this.fault("Cannot set sender. Connection expired and closed itself.");
386 } catch (Exception ex) {
387 this.done();
388 this.fault("Cannot set sender due to exception. message=" + ex.getMessage());
389 }
390 }
391
392 /**
393 * Add sender relay leg method. It will fault if a session has not been
394 * started or has expired. It will start accumulating a sender relay path.
395 * You must call this at least once, if you are going to use senderrelay().
396 * The first call should contain a complete email address at the root of
397 * the relay chain. The accumulation will be reset after done() or other
398 * connection ending event.
399 *
400 * @param leg
401 * relay leg.
402 * @throws CallException
403 */
404 private void addsenderrelay(String leg) throws CallException {
405
406 // Is it started?
407 if (client == null) {
408 this.fault("Session not start()'ed.");
409 }
410
411 try {
412 if (senderrelay == null) {
413 senderrelay = new RelayPath(leg);
414 } else {
415 senderrelay.addRelay(leg);
416 }
417
418 } catch (Exception ex) {
419 this.done();
420 this.fault("Cannot add sender relay due to exception. message=" + ex.getMessage());
421 }
422 }
423
424 /**
425 * Sender relay method. It will fault if a session has not been started or
426 * has expired. It will set the sender as the accumulated relay. You must
427 * have called addsenderrelay() at least once or you will get an error.
428 * Subsequent calls will overwrite the value.
429 *
430 * @param hostname
431 * hostname to use instead of localhost.
432 * @throws CallException
433 */
434 private void senderrelay() throws CallException {
435
436 // Is it started?
437 if (client == null) {
438 this.fault("Session not start()'ed.");
439 }
440
441 // Is there a relay?
442 if (senderrelay == null) {
443 this.error("Sender relay not ready. You need to call addsenderrelay() at least once before this method.");
444 return;
445 }
446
447 try {
448 client.setSender(senderrelay);
449
450 // what happened?
451 int code = client.getReplyCode();
452 if (code >= SMTP_ERROR_THRESHOLD) {
453 this.error("Set sender relay failed with code=" + code + " reply=" + client.getReplyString());
454 } else if (this.isDebugging()) {
455 this.debug("Set sender relay complete. code=" + code);
456 }
457
458 } catch (SMTPConnectionClosedException ex) {
459 this.done();
460 this.fault("Cannot set sender. Connection expired and closed itself.");
461 } catch (Exception ex) {
462 this.done();
463 this.fault("Cannot set sender due to exception. message=" + ex.getMessage());
464 }
465 }
466
467 /**
468 * Recipient method. It will fault if a session has not been started or has
469 * expired. It will add a recipient. Subsequent calls will add to the list
470 * of recipients. The address should be a valid email address. The only way
471 * to clear the list is to call reset() and start over.
472 *
473 * @param hostname
474 * hostname to use instead of localhost.
475 * @throws CallException
476 */
477 private void recipient(String s) throws CallException {
478
479 // Is it started?
480 if (client == null) {
481 this.fault("Session not start()'ed.");
482 }
483
484 try {
485 client.addRecipient(s);
486
487 // what happened?
488 int code = client.getReplyCode();
489 if (code >= SMTP_ERROR_THRESHOLD) {
490 this.error("Add recipient failed with code=" + code + " reply=" + client.getReplyString());
491 } else if (this.isDebugging()) {
492 this.debug("Add recipient complete. code=" + code);
493 }
494
495 } catch (SMTPConnectionClosedException ex) {
496 this.done();
497 this.fault("Cannot add recipient. Connection expired and closed itself.");
498 } catch (Exception ex) {
499 this.done();
500 this.fault("Cannot add recipient due to exception. message=" + ex.getMessage());
501 }
502 }
503
504 /**
505 * Add recipeint relay leg method. It will fault if a session has not been
506 * started or has expired. It will start accumulating a recipeint relay
507 * path. You must call this at least once, if you are going to use
508 * recipient relay(). The first call should contain a complete email
509 * address at the root of the relay chain. The accumulation will be reset
510 * after done(), a call to new recipientrelay(), or some other connection
511 * ending event.
512 *
513 * @param leg
514 * relay leg.
515 * @throws CallException
516 */
517 private void addrecipientrelay(String leg) throws CallException {
518
519 // Is it started?
520 if (client == null) {
521 this.fault("Session not start()'ed.");
522 }
523
524 try {
525 if (recipientrelay == null) {
526 recipientrelay = new RelayPath(leg);
527 } else {
528 recipientrelay.addRelay(leg);
529 }
530 } catch (Exception ex) {
531 this.done();
532 this.fault("Cannot add recipient relay due to exception. message=" + ex.getMessage());
533 }
534 }
535
536 /**
537 * Recipient relay method. It will fault if a session has not been started
538 * or has expired. It will set the sender as the accumulated relay. You
539 * must have called addrecipientrelay() at least once or you will get an
540 * error. Subsequent calls will overwrite the value.
541 *
542 * @param hostname
543 * hostname to use instead of localhost.
544 * @throws CallException
545 */
546 private void recipientrelay() throws CallException {
547
548 // Is it started?
549 if (client == null) {
550 this.fault("Session not start()'ed.");
551 }
552
553 // Is there a relay?
554 if (recipientrelay == null) {
555 this.error(
556 "Recipient relay not ready. You need to call addrecipientrelay() at least once before this method.");
557 return;
558 }
559
560 try {
561 client.addRecipient(recipientrelay);
562
563 // what happened?
564 int code = client.getReplyCode();
565 if (code >= SMTP_ERROR_THRESHOLD) {
566 this.error("Add recipient relay failed with code=" + code + " reply=" + client.getReplyString());
567 } else if (this.isDebugging()) {
568 this.debug("Add recipient relay complete. code=" + code);
569 }
570
571 } catch (SMTPConnectionClosedException ex) {
572 this.done();
573 this.fault("Cannot add recipient. Connection expired and closed itself.");
574 } catch (Exception ex) {
575 this.done();
576 this.fault("Cannot add recipient due to exception. message=" + ex.getMessage());
577 } finally {
578 this.done();
579 }
580 }
581
582 /**
583 * Clear the recipeint relay accumulation. Do this if you want to start on
584 * a new recipeint relay. This will never report any kind of error.
585 *
586 * @param leg
587 * relay leg.
588 * @throws CallException
589 */
590 private void newrecipientrelay() {
591 recipientrelay = null;
592 }
593
594 /**
595 * Send the message in the text. Returns the SMTP reply code.
596 *
597 * @param hostname
598 * hostname to use instead of localhost.
599 * @throws CallException
600 */
601 private String send(String text) throws CallException {
602
603 String result = ERROR_STRING_FOR_FAILURE;
604
605 // Is it started?
606 if (client == null) {
607 this.fault("Session not start()'ed.");
608 }
609
610 // Is there something to send? PARANOID
611 if (text == null) {
612 this.error("Nothing to send.");
613 return result;
614 }
615
616 try {
617 client.sendShortMessageData(text);
618 //client.completePendingCommand(); // don't care if it was ok.
619 result = Integer.toString(client.getReplyCode());
620
621 // what happened?
622 int code = client.getReplyCode();
623 if (code >= SMTP_ERROR_THRESHOLD) {
624 this.error("Message send FAILED. code=" + code + " reply=" + client.getReplyString());
625 } else if (this.isDebugging()) {
626 this.debug("Message send complete. code=" + code + " reply=" + client.getReplyString());
627 }
628
629 } catch (SMTPConnectionClosedException ex) {
630 this.done();
631 this.fault("Send failed. Connection expired and closed itself.");
632 } catch (Exception ex) {
633 this.done();
634 this.fault("Send failed due to exception. message=" + ex.getMessage());
635 } finally {
636 this.done();
637 }
638 return result;
639 }
640
641 /**
642 * Send the message in a Universe Object. Returns the SMTP reply code.
643 *
644 * @param hostname
645 * hostname to use instead of localhost.
646 * @throws CallException
647 */
648 private String senduni(String uniobject) throws CallException {
649
650 String result = ERROR_STRING_FOR_FAILURE;
651
652 // Is it started?
653 if (client == null) {
654 this.fault("Session not start()'ed.");
655 }
656
657 try {
658 // get the hoses
659 InputStream unio = visUniverse.getStream(uniobject);
660 BufferedReader bin = new BufferedReader(new InputStreamReader(unio));
661 Writer mwriter = client.sendMessageData();
662
663 // and pipe them together
664 if (mwriter != null) {
665 Util.copyReader(bin, mwriter);
666 mwriter.close();
667 unio.close();
668 client.completePendingCommand(); // don't care if it was ok.
669
670 // what happened?
671 int code = client.getReplyCode();
672 if (code >= SMTP_ERROR_THRESHOLD) {
673 this.error(
674 "Message send FAILED (from Universe). code=" + code + " reply=" + client.getReplyString());
675 } else if (this.isDebugging()) {
676 this.debug("Message send complete (from Universe). code=");
677 }
678 result = Integer.toString(code);
679
680 } else {
681 this.log(
682 "Message send FAILED (from Universe) because SMTP connection was completely ready. reply="
683 + client.getReplyString());
684 }
685
686 } catch (UniverseException uex) {
687 this.fault(
688 "Could not send universe object due to Universe problem. code="
689 + uex.numeric
690 + " message="
691 + uex.getMessage(),
692 uex);
693 } catch (SMTPConnectionClosedException ex) {
694 this.done();
695 this.fault("Send failed (from Universe). Connection expired and closed itself.");
696 } catch (Exception ex) {
697 this.done();
698 this.fault("Send failed (from Universe) due to exception. message=" + ex.getMessage());
699 }
700 return result;
701 }
702
703 /**
704 * Send the message in a Universe Object. Returns the SMTP reply code. It
705 * will run a variable replace on it before sending it.
706 *
707 * @param hostname
708 * hostname to use instead of localhost.
709 * @throws CallException
710 */
711 private String senduniscrub(String uniobject) throws CallException {
712
713 String result = ERROR_STRING_FOR_FAILURE;
714 String tempObj = null;
715
716 // Is it started?
717 if (client == null) {
718 this.fault("Session not start()'ed.");
719 }
720
721 try {
722
723 // Process it
724 try {
725 tempObj = visUniverse.reserveUnique(TEMPFILE);
726 String thing = UniverseUtils.load2String(visUniverse.getStream(uniobject));
727 String thang = StringProcessors.evalString2Core(thing, visCore);
728 OutputStream os = visUniverse.putStream(tempObj);
729 UniverseUtils.saveString(os, thang);
730
731 } catch (UniverseException ue) {
732 throw ue;
733 } catch (Exception e) {
734 this.fault("Send failed (from Universe). Could not create scrubbed intermediary tempfile. message=" + e.getMessage());
735 }
736
737 // get the hoses
738 InputStream unio = visUniverse.getStream(tempObj);
739 BufferedReader bin = new BufferedReader(new InputStreamReader(unio));
740 Writer mwriter = client.sendMessageData();
741
742 // and pipe them together
743 if (mwriter != null) {
744 Util.copyReader(bin, mwriter);
745 mwriter.close();
746 unio.close();
747 client.completePendingCommand(); // don't care if it was ok.
748
749 // what happened?
750 int code = client.getReplyCode();
751 if (code >= SMTP_ERROR_THRESHOLD) {
752 this.error(
753 "Message send FAILED (from Universe). code=" + code + " reply=" + client.getReplyString());
754 } else if (this.isDebugging()) {
755 this.debug("Message send complete (from Universe). code=");
756 }
757 result = Integer.toString(code);
758
759 } else {
760 this.log(
761 "Message send FAILED (from Universe) because SMTP connection was completely ready. reply="
762 + client.getReplyString());
763 }
764
765 } catch (CallException cex) {
766 throw cex;
767 } catch (UniverseException uex) {
768 this.fault(
769 "Could not send universe object due to Universe problem. code="
770 + uex.numeric
771 + " message="
772 + uex.getMessage(),
773 uex);
774 } catch (SMTPConnectionClosedException ex) {
775 this.done();
776 this.fault("Send failed (from Universe). Connection expired and closed itself.");
777 } catch (Exception ex) {
778 this.done();
779 this.fault("Send failed (from Universe) due to exception. message=" + ex.getMessage());
780 } finally {
781 if ((!this.isDebugging())&&(tempObj != null)) {
782 try {
783 visUniverse.remove(tempObj);
784 } catch (Exception ee) {
785 // Don't care
786 }
787 }
788 }
789 return result;
790 }
791
792 /**
793 * Reset method. It will never give an error, even if not start()'ed.
794 *
795 * @throws CallException
796 */
797 private void reset() throws CallException {
798 try {
799 if (client != null)
800 client.reset();
801
802 // what happened?
803 int code = client.getReplyCode();
804 if (code >= SMTP_ERROR_THRESHOLD) {
805 this.error("Reset FAILED with code=" + code + " reply=" + client.getReplyString());
806 this.done();
807 } else if (this.isDebugging()) {
808 this.debug("Reset complete. code=" + code);
809 }
810
811 } catch (Exception ex) {
812 }
813 }
814
815 /**
816 * Mailit method. A complete transaction wrapped into a convenient method.
817 * No session should be started.
818 *
819 * @param to
820 * TO address.
821 * @param from
822 * FROM address.
823 * @param text
824 * to send as the message
825 * @param host
826 * address of smpt server or relay
827 * @param port
828 * optional port
829 * @throws CallException
830 */
831 private String mailit(String to, String from, String text, String host, String port) throws CallException {
832
833 String response = null;
834
835 // Is it started?
836 if (client != null) {
837 this.fault("Session already start()'ed. You can't use this method on an open session.");
838 }
839
840 try {
841 this.start(host, port);
842 this.login(null);
843 this.sender(from);
844 this.recipient(to);
845 response = this.send(text);
846
847 } catch (CallException ce) {
848 throw ce;
849 } finally {
850 this.done();
851 }
852 return response;
853 }
854
855 /**
856 * Mailituni method. A complete transaction wrapped into a convenient
857 * method. No session should be started.
858 *
859 * @param to
860 * TO address.
861 * @param from
862 * FROM address.
863 * @param uniobj
864 * to send as the message from universe
865 * @param host
866 * address of smpt server or relay
867 * @param port
868 * optional port
869 * @throws CallException
870 */
871 private String mailituni(String to, String from, String uniobj, String host, String port) throws CallException {
872
873 String response = null;
874
875 // Is it started?
876 if (client != null) {
877 this.fault("Session already start()'ed. You can't use this method on an open session.");
878 }
879
880 try {
881 this.start(host, port);
882 this.login(null);
883 this.sender(from);
884 this.recipient(to);
885 response = this.senduni(uniobj);
886
887 } catch (CallException ce) {
888 throw ce;
889 } finally {
890 this.done();
891 }
892 return response;
893 }
894 }
|