Project Report: fawkez

Packagesummary org.jcoderz.phoenix.jabber

org.jcoderz.phoenix.jabber.Jabber

LineHitsNoteSource
1  /*
2   * $Id: Jabber.java 1011 2008-06-16 17:57:36Z amandel $
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   */
33  package org.jcoderz.phoenix.jabber;
34  
35  import java.net.InetAddress;
36  import java.util.logging.Level;
37  import java.util.logging.Logger;
38  
39  import org.jivesoftware.smack.GroupChat;
40  import org.jivesoftware.smack.XMPPConnection;
41  import 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   */
57  public final class Jabber
58  {
59     private static final int JABBER_DEFAULT_PORT = 5222;
6075    private static final String CLASSNAME = Jabber.class.getName();
61100    private static final Logger logger = Logger.getLogger(CLASSNAME);
62  
63     private Jabber ()
640    {
65        // main class - no instances allowed.
660    }
67  
68     /**
69      * Shortcut to send message directly from the command line.
70 (1)    * TODO: Allow different chat server.
71      * @param args the message to send.
72      */
73     public static void main (String[] args)
74     {
750       JabberConnection.getInstance().say(args[0]);
760    }
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     {
850       JabberConnection.getInstance().say(msg);
860    }
87  
88     private static class JabberConnection
89     {
90100       private static final JabberConnection INSTANCE = new JabberConnection();
91        private static final int GRACEFUL_PERIOD = 1000;
92        
93        private final String mHostname;
94100       private String mJabberUserName = "cc";
95100       private String mJabberUserPassword = "cc42";
96100       private String mJabberServerName = "jabber.org";
97100       private String mJabberHostAddress = "jabber.org";
98100       private int mJabberHostPort = JABBER_DEFAULT_PORT;
99100       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 ()
107100       {
108           String localhost;
109           try
110           {
111100             localhost = InetAddress.getLocalHost().getHostName();
112           }
1130          catch (Exception ex)
114           {
1150             localhost = "localhost";
116100          }
117100          mHostname = localhost;
118100          mJabberMucAlias
119                 = System.getProperty("user.name", "cruise.control")
120                    + "@" + mHostname;
121100       }
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        {
129100          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        {
1530          clear();
1540          mJabberHostAddress = jabberHostName;
1550          mJabberHostPort = jabberHostPort;
1560          mJabberServerName = jabberServerName;
1570          mJabberUserName = jabberUserName;
1580          mJabberUserPassword = jabberUserPassword;
1590          mJabberMucName = jabberMucName;
1600          checkConnection();
1610       }
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           {
1720             checkConnection();
1730             mGroupChat.sendMessage(message);
174           }
1750          catch (Exception ex)
176           {
1770             logger.log(Level.WARNING, "Exception sending message."
178                    + " Will retry", ex);
1790             clear();
180              try
181              {
1820                checkConnection();
1830                mGroupChat.sendMessage(message);
184              }
185100             catch (Exception e)
186              {
187100                clear();
188100(2)               throw new RuntimeException("Jabber send message failed fatal!",
189                       e);
1900             }
1910          }
1920       }
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           {
2030             checkConnectionRaw();
204           }
205100          catch (Exception ex)
206           {
207100             logger.log(Level.WARNING, "Exception while reconnecting (1).", ex);
208100             mGroupChat = null;
2090          }
210  
211           try
212           {
2130             checkConnectionRaw();
214           }
215100          catch (Exception ex)
216           {
217100             logger.log(Level.WARNING, "Exception while reconnecting (2).",
218                    ex);
219100             mConnection = null;
220100             mGroupChat = null;
2210          }
222           try
223           {
2240             checkConnectionRaw();
225           }
226100          catch (Exception ex)
227           {
228100             mConnection = null;
229100             mGroupChat = null;
230100             throw new RuntimeException("Jabber connect failed fatal!", ex);
2310          }
2320       }
233  
234        protected void finalize ()
235            throws Throwable
236        {
2370           clear();
2380           super.finalize();
2390       }
240  
241        private void checkConnectionRaw ()
242 (3)          throws XMPPException, InterruptedException
243        {
244100          if (mConnection == null || !mConnection.isConnected())
245           {
246100             clear();
247100(4)            mConnection = new XMPPConnection (// CHECKME: new SSLXMPPConnection(
248                    mJabberHostAddress, mJabberHostPort, mJabberServerName);
249100             mGroupChat = null;
250100             logger.fine("New connection to jabber server. TLS: "
251                    + mConnection.isUsingTLS() + " secure: "
252                    + mConnection.isSecureConnection());
253100             if (!mConnection.isConnected())
254              {
2550                Thread.sleep(GRACEFUL_PERIOD);
256              }
257           }
258  
259100          if (!mConnection.isAuthenticated())
260           {
261100             mConnection.login(mJabberUserName, mJabberUserPassword, mHostname);
262100             mGroupChat = null;
263100             logger.fine("Login to jabber server. ("
264                    + mConnection.isAuthenticated() + ").");
265           }
266  
267100          if (mGroupChat == null)
268           {
269100             mGroupChat = mConnection.createGroupChat(mJabberMucName);
270100             logger.fine("New group chat generated.");
271           }
272  
273100          if (!mGroupChat.isJoined())
274           {
2750             mGroupChat.join(mJabberMucAlias);
2760             if (!mGroupChat.isJoined())
277              {
2780                Thread.sleep(GRACEFUL_PERIOD);
279              }
2800             logger.fine("Joined to group chat. (" + mGroupChat.isJoined()
281                  + ").");
282           }
2830       }
284  
285        private void clear ()
286        {
287           try
288           {
289100             if (mGroupChat != null)
290              {
2910                mGroupChat.leave();
292              }
293           }
2940          catch (Exception ex)
295           {
2960             logger.log(Level.FINEST, "Exception while leaving groupchat.", ex);
297100          }
298100          mGroupChat = null;
299           try
300           {
301100             if (mConnection != null)
302              {
3030                mConnection.close();
304              }
305           }
3060          catch (Exception ex)
307           {
3080              logger.log(Level.FINEST,
309                   "Exception while closing jabber connection.", ex);
310100          }
311100          mConnection = null;
312100       }
313  
314     }
315  
316  
317  }

Findings in this File

i (1) 70 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
i (2) 188 : 0 method org.jcoderz.phoenix.jabber.Jabber$JabberConnection.say(String) throws exception with static message string
c (3) 242 : 18 Unable to get class information for XMPPException.
i (4) 247 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.