root/trunk/src/java/org/jcoderz/phoenix/jabber/Jabber.java

Revision 1011, 10.0 kB (checked in by amandel, 4 years ago)

Aligned svn keyword settings.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 *
4 * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *    * Redistributions of source code must retain the above copyright
11 *      notice, this list of conditions and the following disclaimer.
12 *    * Redistributions in binary form must reproduce the above
13 *      copyright notice, this list of conditions and the following
14 *      disclaimer in the documentation and/or other materials
15 *      provided with the distribution.
16 *    * Neither the name of the jCoderZ.org Project nor the names of
17 *      its contributors may be used to endorse or promote products
18 *      derived from this software without specific prior written
19 *      permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33package org.jcoderz.phoenix.jabber;
34
35import java.net.InetAddress;
36import java.util.logging.Level;
37import java.util.logging.Logger;
38
39import org.jivesoftware.smack.GroupChat;
40import org.jivesoftware.smack.XMPPConnection;
41import org.jivesoftware.smack.XMPPException;
42
43/**
44 * Simply sends a jabber message in a jabber group.
45 *
46 * <p>To setup different than the default connection call
47 * <code>JabberConnection.getInstance().setup(...)</code> prior the
48 * first call to say().</p>
49 *
50 * <p>This implementation tries to establish a static connection to a
51 * group chat and re-use this connection for further messages.</p>
52 *
53 * <p>By design there is only one connection per VM/classloader possible.</p>
54 *
55 * @author Andreas Mandel
56 */
57public final class Jabber
58{
59   private static final int JABBER_DEFAULT_PORT = 5222;
60   private static final String CLASSNAME = Jabber.class.getName();
61   private static final Logger logger = Logger.getLogger(CLASSNAME);
62
63   private Jabber ()
64   {
65      // main class - no instances allowed.
66   }
67
68   /**
69    * Shortcut to send message directly from the command line.
70    * TODO: Allow different chat server.
71    * @param args the message to send.
72    */
73   public static void main (String[] args)
74   {
75      JabberConnection.getInstance().say(args[0]);
76   }
77
78   /**
79    * Sends the given text message to the GroupChat.
80    * @param msg the message to send.
81    * @throws RuntimeException if sending fails (even after retry).
82    */
83   public static void say (String msg)
84   {
85      JabberConnection.getInstance().say(msg);
86   }
87
88   private static class JabberConnection
89   {
90      private static final JabberConnection INSTANCE = new JabberConnection();
91      private static final int GRACEFUL_PERIOD = 1000;
92     
93      private final String mHostname;
94      private String mJabberUserName = "cc";
95      private String mJabberUserPassword = "cc42";
96      private String mJabberServerName = "jabber.org";
97      private String mJabberHostAddress = "jabber.org";
98      private int mJabberHostPort = JABBER_DEFAULT_PORT;
99      private String mJabberMucName = "jcoderz@conference.jabber.org";
100
101      private final String mJabberMucAlias;
102
103      private XMPPConnection mConnection;
104      private GroupChat mGroupChat;
105
106      JabberConnection ()
107      {
108         String localhost;
109         try
110         {
111            localhost = InetAddress.getLocalHost().getHostName();
112         }
113         catch (Exception ex)
114         {
115            localhost = "localhost";
116         }
117         mHostname = localhost;
118         mJabberMucAlias
119               = System.getProperty("user.name", "cruise.control")
120                  + "@" + mHostname;
121      }
122
123      /**
124       * Returns the one and only instance of the jabber connection.
125       * @return the one and only instance of the jabber connection.
126       */
127      public static JabberConnection getInstance ()
128      {
129         return INSTANCE;
130      }
131
132      /**
133       * Setup the connection parameters to be used.
134       * If there was already a connection to a group chat, this
135       * connection is closed.
136       * The connection is established after setting the bew parameters.
137       * Be prepared to catch a runtime exception if the connection fails.
138       * @param jabberHostName The host name of the JabberServer to connect to
139       *        might also be it's numeric ip address.
140       * @param jabberHostPort The port to connect to (most likely 5222)
141       * @param jabberServerName The "virtual" server name of the jabber
142       *        server (the part after the @ in the JIDs)
143       * @param jabberUserName The user name to connect as. This is
144       *        the part before the @ in the JID.
145       * @param jabberUserPassword The password to use.
146       * @param jabberMucName The full qualified name of the MUC.
147       *        (eg. talk@conf.jabber.org)
148       */
149      public synchronized void setup (String jabberHostName,
150            int jabberHostPort, String jabberServerName, String jabberUserName,
151            String jabberUserPassword, String jabberMucName)
152      {
153         clear();
154         mJabberHostAddress = jabberHostName;
155         mJabberHostPort = jabberHostPort;
156         mJabberServerName = jabberServerName;
157         mJabberUserName = jabberUserName;
158         mJabberUserPassword = jabberUserPassword;
159         mJabberMucName = jabberMucName;
160         checkConnection();
161      }
162
163      /**
164       * Sends the given text message to the GroupChat
165       * @param message the message to send.
166       * @throws RuntimeException if sending fails (even after retry).
167       */
168      public synchronized void say (String message)
169      {
170         try
171         {
172            checkConnection();
173            mGroupChat.sendMessage(message);
174         }
175         catch (Exception ex)
176         {
177            logger.log(Level.WARNING, "Exception sending message."
178                  + " Will retry", ex);
179            clear();
180            try
181            {
182               checkConnection();
183               mGroupChat.sendMessage(message);
184            }
185            catch (Exception e)
186            {
187               clear();
188               throw new RuntimeException("Jabber send message failed fatal!",
189                     e);
190            }
191         }
192      }
193
194      /**
195       * Checks and ensures that a connection is established.
196       * @throws RuntimeException if connecting fails (even after retry).
197       */
198      public synchronized void checkConnection ()
199            throws RuntimeException
200      {
201         try
202         {
203            checkConnectionRaw();
204         }
205         catch (Exception ex)
206         {
207            logger.log(Level.WARNING, "Exception while reconnecting (1).", ex);
208            mGroupChat = null;
209         }
210
211         try
212         {
213            checkConnectionRaw();
214         }
215         catch (Exception ex)
216         {
217            logger.log(Level.WARNING, "Exception while reconnecting (2).",
218                  ex);
219            mConnection = null;
220            mGroupChat = null;
221         }
222         try
223         {
224            checkConnectionRaw();
225         }
226         catch (Exception ex)
227         {
228            mConnection = null;
229            mGroupChat = null;
230            throw new RuntimeException("Jabber connect failed fatal!", ex);
231         }
232      }
233
234      protected void finalize ()
235          throws Throwable
236      {
237          clear();
238          super.finalize();
239      }
240
241      private void checkConnectionRaw () 
242          throws XMPPException, InterruptedException
243      {
244         if (mConnection == null || !mConnection.isConnected())
245         {
246            clear();
247            mConnection = new XMPPConnection (// CHECKME: new SSLXMPPConnection(
248                  mJabberHostAddress, mJabberHostPort, mJabberServerName);
249            mGroupChat = null;
250            logger.fine("New connection to jabber server. TLS: "
251                  + mConnection.isUsingTLS() + " secure: "
252                  + mConnection.isSecureConnection());
253            if (!mConnection.isConnected())
254            {
255               Thread.sleep(GRACEFUL_PERIOD);
256            }
257         }
258
259         if (!mConnection.isAuthenticated())
260         {
261            mConnection.login(mJabberUserName, mJabberUserPassword, mHostname);
262            mGroupChat = null;
263            logger.fine("Login to jabber server. ("
264                  + mConnection.isAuthenticated() + ").");
265         }
266
267         if (mGroupChat == null)
268         {
269            mGroupChat = mConnection.createGroupChat(mJabberMucName);
270            logger.fine("New group chat generated.");
271         }
272
273         if (!mGroupChat.isJoined())
274         {
275            mGroupChat.join(mJabberMucAlias);
276            if (!mGroupChat.isJoined())
277            {
278               Thread.sleep(GRACEFUL_PERIOD);
279            }
280            logger.fine("Joined to group chat. (" + mGroupChat.isJoined() 
281                + ").");
282         }
283      }
284
285      private void clear ()
286      {
287         try
288         {
289            if (mGroupChat != null)
290            {
291               mGroupChat.leave();
292            }
293         }
294         catch (Exception ex)
295         {
296            logger.log(Level.FINEST, "Exception while leaving groupchat.", ex);
297         }
298         mGroupChat = null;
299         try
300         {
301            if (mConnection != null)
302            {
303               mConnection.close();
304            }
305         }
306         catch (Exception ex)
307         {
308             logger.log(Level.FINEST, 
309                 "Exception while closing jabber connection.", ex);
310         }
311         mConnection = null;
312      }
313
314   }
315
316
317}
Note: See TracBrowser for help on using the browser.