View Javadoc

1   /* ***** BEGIN LICENSE BLOCK *****
2    * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3    *
4    * The contents of this file are subject to the Mozilla Public License Version
5    * 1.1 (the "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    * http://www.mozilla.org/MPL/
8    *
9    * Software distributed under the License is distributed on an "AS IS" basis,
10   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11   * for the specific language governing rights and limitations under the
12   * License.
13   *
14   * The Original Code is "SMS Library for the Java platform".
15   *
16   * The Initial Developer of the Original Code is Markus Eriksson.
17   * Portions created by the Initial Developer are Copyright (C) 2002
18   * the Initial Developer. All Rights Reserved.
19   *
20   * Contributor(s):
21   *
22   * Alternatively, the contents of this file may be used under the terms of
23   * either the GNU General Public License Version 2 or later (the "GPL"), or
24   * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
25   * in which case the provisions of the GPL or the LGPL are applicable instead
26   * of those above. If you wish to allow use of your version of this file only
27   * under the terms of either the GPL or the LGPL, and not to allow others to
28   * use your version of this file under the terms of the MPL, indicate your
29   * decision by deleting the provisions above and replace them with the notice
30   * and other provisions required by the GPL or the LGPL. If you do not delete
31   * the provisions above, a recipient may use your version of this file under
32   * the terms of any one of the MPL, the GPL or the LGPL.
33   *
34   * ***** END LICENSE BLOCK ***** */
35  package org.marre;
36  
37  import java.io.FileInputStream;
38  import java.io.IOException;
39  import java.util.Properties;
40  
41  import org.marre.sms.SmsAddress;
42  import org.marre.sms.SmsConstants;
43  import org.marre.sms.SmsDcs;
44  import org.marre.sms.SmsException;
45  import org.marre.sms.SmsMessage;
46  import org.marre.sms.SmsMsgWaitingMessage;
47  import org.marre.sms.SmsTextMessage;
48  import org.marre.sms.transport.SmsTransport;
49  import org.marre.sms.transport.SmsTransportManager;
50  import org.marre.wap.nokia.NokiaOtaBrowserSettings;
51  import org.marre.wap.push.SmsMmsNotificationMessage;
52  import org.marre.wap.push.SmsWapPushMessage;
53  import org.marre.wap.push.WapSIPush;
54  import org.marre.wap.push.WapSLPush;
55  
56  /***
57   * High level API to the smsj library.
58   * 
59   * If you only need to send some basic SMS messages than you only have to use
60   * this API. Ex:
61   * 
62   * <pre>
63   * try
64   * {
65   *     // Send SMS with clickatell
66   *     SmsSender smsSender = SmsSender.getClickatellSender(&quot;username&quot;, &quot;password&quot;, &quot;apiid&quot;);
67   *     String msg = &quot;A sample SMS.&quot;;
68   *     // International number to reciever without leading &quot;+&quot;
69   *     String reciever = &quot;464545425463&quot;;
70   *     // Number of sender (not supported on all transports)
71   *     String sender = &quot;46534534535&quot;;
72   *     // Connect
73   *     smsSender.connect();
74   *     // Send message
75   *     smsSender.send(&quot;A sample SMS.&quot;, reciever, sender);
76   *     // Disconnect
77   *     smsSender.disconnect();
78   * }
79   * catch (IOException ex)
80   * {
81   *     ex.printStackTrace();
82   * }
83   * catch (SmsException ex)
84   * {
85   *     ex.printStackTrace();
86   * }
87   * </pre>
88   * 
89   * @author Markus Eriksson
90   * @version $Id: SmsSender.java,v 1.11 2005/11/26 17:06:45 c95men Exp $
91   */
92  public class SmsSender
93  {
94      /***
95       * The sms transport that is used to send the messages.
96       */
97      protected SmsTransport transport_;
98  
99      /***
100      * Creates a SmsSender object by using the given transport and properties.
101      * <p>
102      * You can also use getClickatellSender(...) to create a SmsSender object
103      * 
104      * @param transport
105      *            Classname of the SmsTransport class
106      * @param props
107      *            Properties to initialize the transport with
108      * @throws SmsException
109      */
110     public SmsSender(String transport, Properties props) throws SmsException
111     {
112         transport_ = SmsTransportManager.getTransport(transport, props);
113     }
114 
115     /***
116      * Convenience method to create a SmsSender object that knows how to send
117      * messages with the Clickatell service.
118      * 
119      * @param username
120      *            Clickatell username
121      * @param password
122      *            Clickatell password
123      * @param apiid
124      *            Clickatell api-id
125      *            
126      * @return A SmsSender object that uses the ClickatellTransport to send
127      *         messages
128      *         
129      * @throws SmsException
130      */
131     public static SmsSender getClickatellSender(String username, String password, String apiid)
132             throws SmsException
133     {
134         Properties props = new Properties();
135 
136         props.setProperty("smsj.clickatell.username", username);
137         props.setProperty("smsj.clickatell.password", password);
138         props.setProperty("smsj.clickatell.apiid", apiid);
139         props.setProperty("smsj.clickatell.protocol", "https");
140 
141         return new SmsSender("org.marre.sms.transport.clickatell.ClickatellTransport", props);
142     }
143 
144     /***
145      * Convenience method to create a SmsSender object that knows how to send
146      * messages with the Clickatell service.
147      * 
148      * @param propsFilename
149      *            Filename of a properties file containing properties for the
150      *            clickatell transport.
151      *            
152      * @return A SmsSender object that uses the ClickatellTransport to send
153      *         messages
154      *         
155      * @throws SmsException
156      * @throws IOException 
157      */
158     public static SmsSender getClickatellSender(String propsFilename) throws SmsException, IOException
159     {
160         Properties props = new Properties();
161         props.load(new FileInputStream(propsFilename));
162         return new SmsSender("org.marre.sms.transport.clickatell.ClickatellTransport", props);
163     }
164 
165     /***
166      * Convenience method to create a SmsSender object that knows how to send
167      * messages with a GSM phone attached to the serial port on your computer.
168      * 
169      * @param portName
170      *            Serial port where your phone is located. Ex "COM1:"
171      *            
172      * @return A SmsSender object that uses the GsmTranport to send messages
173      * 
174      * @throws SmsException
175      */
176     public static SmsSender getGsmSender(String portName) throws SmsException
177     {
178         Properties props = new Properties();
179         props.setProperty("sms.gsm.serialport", portName);
180         return new SmsSender("org.marre.sms.transport.gsm.GsmTransport", props);
181     }
182 
183     /***
184      * Convenience method to create a SmsSender object that knows how to send
185      * messages with a UCP SMSC.
186      * 
187      * @param address
188      *            A string with the ip address or host name of the SMSC
189      * @param port
190      *            An integer with the ip port on which the SMSC listens
191      * @return A SmsSender object that uses the UcpTranport to send messages
192      * @throws SmsException
193      */
194     public static SmsSender getUcpSender(String address, int port) throws SmsException
195     {
196         //Liquidterm: strict input checking is done in the UcpTransport class
197         Properties props = new Properties();
198         props.setProperty("smsj.ucp.ip.host", address);
199         props.setProperty("smsj.ucp.ip.port", Integer.toString(port));
200         return new SmsSender("org.marre.sms.transport.ucp.UcpTransport", props);
201     }
202 
203     /***
204      * Convenience method to create a SmsSender object that knows how to send
205      * messages with a UCP SMSC.
206      * 
207      * @param address
208      *            A string with the ip address or host name of the SMSC
209      * @param port
210      *            An integer with the ip port on which the SMSC listens
211      * @param ucp60Uid
212      *            A string containing the UCP60 userid
213      * @param ucp60Pwd
214      *            A string containing the UCP60 password
215      *            
216      * @return A SmsSender object that uses the UcpTranport to send messages
217      * 
218      * @throws SmsException
219      */
220     public static SmsSender getUcpSender(String address, int port, String ucp60Uid, String ucp60Pwd)
221             throws SmsException
222     {
223         //Liquidterm: strict input checking is done in the UcpTransport class
224         Properties props = new Properties();
225         props.setProperty("smsj.ucp.ip.host", address);
226         props.setProperty("smsj.ucp.ip.port", Integer.toString(port));
227         props.setProperty("smsj.ucp.ucp60.uid", ucp60Uid);
228         props.setProperty("smsj.ucp.ucp60.password", ucp60Pwd);
229         return new SmsSender("org.marre.sms.transport.ucp.UcpTransport", props);
230     }
231 
232     /***
233      * Convenience method to create a SmsSender object that knows how to send
234      * messages with a UCP SMSC.
235      * 
236      * @param propsFilename
237      *            A string containt a filename with the serialized Properties
238      *            object for the transport
239      *            
240      * @return A SmsSender object that uses the UcpTranport to send messages
241      * 
242      * @throws SmsException
243      * @throws IOException 
244      */
245     public static SmsSender getUcpSender(String propsFilename) throws SmsException, IOException
246     {
247         Properties props = new Properties();
248         props.load(new FileInputStream(propsFilename));
249         return new SmsSender("org.marre.sms.transport.ucp.UcpTransport", props);
250     }
251 
252     /***
253      * Convenience method to create a SmsSender object that knows how to send
254      * messages via PSWinComm
255      * 
256      * @param username
257      *            PsWinComm username
258      * @param password
259      *            PsWinComm password
260      * @return A SmsSender object that uses the PsWinXmlTransport to send
261      *         messages
262      * @throws SmsException
263      */
264     public static SmsSender getPsWinCommXmlSender(String username, String password) throws SmsException
265     {
266         Properties props = new Properties();
267 
268         props.setProperty("smsj.pswincom.username", username);
269         props.setProperty("smsj.pswincom.password", password);
270 
271         return new SmsSender("org.marre.sms.transport.pswincom.PsWinXmlTransport", props);
272     }
273 
274     /***
275      * Convenience method to create a SmsSender object that knows how to send
276      * messages via PSWinComm
277      * 
278      * @param propsFilename
279      *            Filename of a properties file containing properties for the
280      *            pswincomm transport.
281      *            
282      * @return A SmsSender object that uses the PsWinXmlTransport to send
283      *         messages
284      *         
285      * @throws SmsException
286      * @throws IOException 
287      */
288     public static SmsSender getPsWinCommXmlSender(String propsFilename) throws SmsException, IOException
289     {
290         Properties props = new Properties();
291         props.load(new FileInputStream(propsFilename));
292         return new SmsSender("org.marre.sms.transport.pswincom.PsWinXmlTransport", props);
293     }
294 
295     /***
296      * Sends an ordinary SMS to the given recipient.
297      * 
298      * There is no limit on the number of concatenated SMS that this message will
299      * use. It will send the message with the GSM charset (Max 160 chars/SMS).
300      * 
301      * @param text Message to send
302      * @param dest Destination number (international format without leading +).
303      * @param sender Sender number (international format without leading +). Can also be an alphanumerical string like
304      *               "SMSJ". This is property is not supported by all transports.
305      *            
306      * @return Returns a local message id for the sent message. It is possible that the message id is null.
307      * 
308      * @throws SmsException
309      * @throws IOException 
310      */
311     public String sendTextSms(String text, String dest, String sender) throws SmsException, IOException
312     {
313         SmsTextMessage textMessage = new SmsTextMessage(text, SmsDcs.ALPHABET_GSM, SmsDcs.MSG_CLASS_UNKNOWN);        
314         return sendSms(textMessage, dest, sender);
315     }
316 
317     /***
318      * Sends an ordinary SMS to the given recipient.
319      * 
320      * There is no limit on the number of concatenated SMS that this message will
321      * use. It will send the message with the GSM charset (Max 160 chars/SMS).
322      * 
323      * @param text Message to send
324      * @param dest Destination number (international format without leading +).
325      *            
326      * @return Returns a local message id for the sent message. It is possible that the message id is null.
327      * 
328      * @throws SmsException
329      * @throws IOException 
330      */
331     public String sendTextSms(String text, String dest) throws SmsException, IOException
332     {
333         SmsTextMessage textMessage = new SmsTextMessage(text, SmsDcs.ALPHABET_GSM, SmsDcs.MSG_CLASS_UNKNOWN);        
334         return sendSms(textMessage, dest, null);
335     }
336     
337     /***
338      * Sends an ordinary SMS to the given recipient.
339      * 
340      * No limit on the number of concatenated SMS that this message will
341      * use. Will send the message with the UCS2 charset (MAX 70 chars/SMS).
342      * 
343      * @param text Message to send
344      * @param dest Destination number (international format without leading +).
345      * @param sender Sender number (international format without leading +). Can also be an alphanumerical string like
346      *               "SMSJ". This is property is not supported by all transports.
347      *            
348      * @return Returns a local message id for the sent message. It is possible that the message id is null.
349      * 
350      * @throws SmsException
351      * @throws IOException 
352      */
353     public String sendUnicodeTextSms(String text, String dest, String sender) throws SmsException, IOException
354     {
355         SmsTextMessage textMessage = new SmsTextMessage(text, SmsDcs.ALPHABET_UCS2, SmsDcs.MSG_CLASS_UNKNOWN);        
356         return sendSms(textMessage, dest, sender);
357     }
358 
359     /***
360      * Sends an ordinary SMS to the given recipient.
361      * 
362      * No limit on the number of concatenated SMS that this message will
363      * use. Will send the message with the UCS2 charset (MAX 70 chars/SMS).
364      * 
365      * @param text Message to send
366      * @param dest Destination number (international format without leading +).
367      * 
368      * @return Returns a local message id for the sent message. It is possible that the message id is null.
369      * 
370      * @throws SmsException
371      * @throws IOException 
372      */
373     public String sendUnicodeTextSms(String text, String dest) throws SmsException, IOException
374     {
375         SmsTextMessage textMessage = new SmsTextMessage(text, SmsDcs.ALPHABET_UCS2, SmsDcs.MSG_CLASS_UNKNOWN);        
376         return sendSms(textMessage, dest, null);
377     }
378     
379     /***
380      * 
381      * Sends an OTA Bookmark (Nokia specification) to the given recipient
382      * 
383      * @param title String with the title of the bookmark
384      * @param url String with the url referenced by the bookmark
385      * @param dest Destination number (international format without leading +).
386      * 
387      * @return Returns a local message id for the sent message. It is possible that the message id is null.
388      *
389      * @throws SmsException
390      * @throws IOException 
391      */
392     public String sendNokiaBookmark(String title, String url, String dest) throws SmsException, IOException
393     {
394         NokiaOtaBrowserSettings browserSettings = new NokiaOtaBrowserSettings();
395         browserSettings.addBookmark(title, url);
396            
397         SmsWapPushMessage wapPushMessage = new SmsWapPushMessage(browserSettings, "application/x-wap-prov.browser-bookmarks");
398         wapPushMessage.setPorts(49154, SmsConstants.PORT_OTA_SETTINGS_BROWSER);
399  
400         return sendSms(wapPushMessage, dest, null);
401     }
402     
403     /***
404      * Sends a Wap Push SI containing to the given recipient.
405      *
406      * @param text String with the description of the service
407      * @param url String with the url referenced by the SI
408      * @param dest Destination number (international format without leading +).
409      *            
410      * @return Returns a local message id for the sent message. It is possible that the message id is null.
411      *
412      * @throws SmsException
413      * @throws IOException 
414      */
415     public String sendWapSiPushMsg(String url, String text, String dest) throws SmsException, IOException
416     {
417         WapSIPush siPush = new WapSIPush(url, text);
418         
419         SmsWapPushMessage wapPushMessage = new SmsWapPushMessage(siPush);
420 //      wapPushMessage.setXWapApplicationId("x-wap-application:*");
421         
422         return sendSms(wapPushMessage, dest, null);
423     }
424 
425     /***
426      * Sends a Wap Push SL containing to the given recipient.
427      *
428      * @param url String with the url referenced by the SL
429      * @param dest Destination number in international format
430      *            
431      * @return Returns a local message id for the sent message. It is possible that the message id is null.
432      *
433      * @throws SmsException
434      * @throws IOException 
435      */
436     public String sendWapSlPushMsg(String url, String dest) throws SmsException, IOException
437     {
438         WapSLPush slPush = new WapSLPush(url);
439         
440         SmsWapPushMessage wapPushMessage = new SmsWapPushMessage(slPush);
441 //      wapPushMessage.setXWapApplicationId("x-wap-application:*");
442         
443         return sendSms(wapPushMessage, dest, null);
444     }
445     
446   
447     /***
448      * Sends a simple MMS Notification.
449      * 
450      * @param contentLocation Where the mms pdu can be downloaded from.
451      * @param size The size of the message.
452      * @param subject The subject of the message.
453      * @param dest Destination number (international format without leading +).
454      *            
455      * @return Returns a local message id for the sent message. It is possible that the message id is null.
456      *
457      * @throws SmsException
458      * @throws IOException 
459      */
460     public String sendMmsNotification(String contentLocation, long size, String subject, String dest) throws SmsException, IOException
461     {
462         SmsMmsNotificationMessage mmsNotification = new SmsMmsNotificationMessage(contentLocation, size);
463         mmsNotification.setSubject(subject);
464         
465         return sendSms(mmsNotification, dest, null);
466     }
467  
468     /***
469      * Sends a voice message waiting message indication.
470      * 
471      * @param count Number of messages waiting. Set to 0 to clear the message waiting flag in the phone.
472      * @param dest Destination number (international format without leading +).
473      *            
474      * @return Returns a local message id for the sent message. It is possible that the message id is null.
475      * 
476      * @throws SmsException
477      * @throws IOException
478      */
479     public String sendMsgWaitingVoice(int count, String dest) throws SmsException, IOException
480     {
481         return sendMsgWaiting(SmsMsgWaitingMessage.TYPE_VOICE, count, dest);
482     }
483     
484     /***
485      * Sends a fax message waiting message indication.
486      * 
487      * @param count Number of messages waiting. Set to 0 to clear the message waiting flag in the phone.
488      * @param dest Destination number (international format without leading +).
489      *            
490      * @return Returns a local message id for the sent message. It is possible that the message id is null.
491      * 
492      * @throws SmsException
493      * @throws IOException
494      */
495     public String sendMsgWaitingFax(int count, String dest) throws SmsException, IOException
496     {
497         return sendMsgWaiting(SmsMsgWaitingMessage.TYPE_FAX, count, dest);
498     }
499     
500     /***
501      * Sends a email message waiting message indication.
502      * 
503      * @param count Number of messages waiting. Set to 0 to clear the message waiting flag in the phone.
504      * @param dest Destination number (international format without leading +).
505      *            
506      * @return Returns a local message id for the sent message. It is possible that the message id is null.
507      * 
508      * @throws SmsException
509      * @throws IOException
510      */
511     public String sendMsgWaitingEmail(int count, String dest) throws SmsException, IOException
512     {
513         return sendMsgWaiting(SmsMsgWaitingMessage.TYPE_EMAIL, count, dest);
514     }
515     
516     private String sendMsgWaiting(int type, int count, String dest) throws SmsException, IOException
517     {
518         SmsMsgWaitingMessage msgWaiting = new SmsMsgWaitingMessage();
519         msgWaiting.addMsgWaiting(type, count);
520         
521         return sendSms(msgWaiting, dest, null);
522     }
523     
524     /***
525      * Sends a SmsMessage.
526      * 
527      * @param msg The message to send.
528      * @param dest
529      *            Destination number (international format without leading +)
530      *            Ex. 44546754235
531      * @param sender
532      *            Destination number (international format without leading +).
533      *            Can also be an alphanumerical string. Ex "SMSJ". (not
534      *            supported by all transports).
535      *            
536      * @return Returns a local message id for the sent message. It is possible that the message id is null.
537      * 
538      * @throws SmsException
539      * @throws IOException
540      */
541     public String sendSms(SmsMessage msg, String dest, String sender) throws SmsException, IOException
542     {
543         SmsAddress destAddress = new SmsAddress(dest);
544         SmsAddress senderAddress = null;
545 
546         if (sender != null)
547         {
548             senderAddress = new SmsAddress(sender);
549         }
550         
551         return transport_.send(msg, destAddress, senderAddress);
552     }
553     
554     /***
555      * Connect to the server.
556      * 
557      * Must be called before any send method.
558      * 
559      * @throws SmsException
560      * @throws IOException
561      */
562     public void connect() throws SmsException, IOException
563     {
564         transport_.connect();
565     }
566     
567     /***
568      * Call this when you are done with the SmsSender object.
569      * 
570      * It will free any resources that we have used.
571      * 
572      * @throws SmsException
573      * @throws IOException 
574      */
575     public void disconnect() throws SmsException, IOException
576     {
577         if (transport_ != null)
578         {
579             transport_.disconnect();
580             transport_ = null;
581         }
582     }
583 
584     /***
585      * Probably never called, but good to have if the caller forget to disconnect().
586      * @see java.lang.Object#finalize()
587      */
588     protected void finalize() throws Throwable
589     {
590         // Disconnect transport if the caller forget to close us
591         try
592         {
593             disconnect();
594         }
595         catch (Exception ex)
596         {
597             // Nothing to do here. The object is gone...
598         }
599         
600         super.finalize();
601     }
602 }