KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > filesys > smb > mailslot > HostAnnouncer


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.filesys.smb.mailslot;
18
19 import java.io.IOException JavaDoc;
20
21 import org.alfresco.filesys.netbios.NetBIOSName;
22 import org.alfresco.filesys.netbios.win32.WinsockNetBIOSException;
23 import org.alfresco.filesys.smb.ServerType;
24 import org.alfresco.filesys.smb.TransactionNames;
25 import org.alfresco.filesys.util.StringList;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 /**
30  * <p>
31  * The host announcer class periodically broadcasts a host announcement datagram to inform other
32  * Windows networking hosts of the local hosts existence and capabilities.
33  */

34 public abstract class HostAnnouncer extends Thread JavaDoc
35 {
36
37     // Debug logging
38

39     protected static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.mailslot");
40
41     // Shutdown announcement interval and message count
42

43     public static final int SHUTDOWN_WAIT = 2000; // 2 seconds
44
public static final int SHUTDOWN_COUNT = 3;
45
46     // Starting announcement interval, doubles until it reaches the configured interval
47

48     public static final long STARTING_INTERVAL = 5000; // 5 seconds
49

50     // Local host name(s) to announce
51

52     private StringList m_names;
53
54     // Domain to announce to
55

56     private String JavaDoc m_domain;
57
58     // Server comment string
59

60     private String JavaDoc m_comment;
61
62     // Announcement interval in minutes
63

64     private int m_interval;
65
66     // Server type flags, see org.alfresco.filesys.smb.SMBServerInfo
67

68     private int m_srvtype = ServerType.WorkStation + ServerType.Server;
69
70     // SMB mailslot packet
71

72     private SMBMailslotPacket m_smbPkt;
73
74     // Update count for the host announcement packet
75

76     private byte m_updateCount;
77
78     // Shutdown flag, host announcer should remove the announced name as it shuts down
79

80     private boolean m_shutdown = false;
81
82     // Debug output enable
83

84     private boolean m_debug;
85
86     /**
87      * HostAnnouncer constructor.
88      */

89     public HostAnnouncer()
90     {
91
92         // Common constructor
93

94         commonConstructor();
95     }
96
97     /**
98      * Create a host announcer.
99      *
100      * @param name Host name to announce
101      * @param domain Domain name to announce to
102      * @param intval Announcement interval, in minutes
103      */

104     public HostAnnouncer(String JavaDoc name, String JavaDoc domain, int intval)
105     {
106
107         // Common constructor
108

109         commonConstructor();
110
111         // Add the host to the list of names to announce
112

113         addHostName(name);
114         setDomain(domain);
115         setInterval(intval);
116     }
117
118     /**
119      * Common constructor code
120      */

121     private final void commonConstructor()
122     {
123
124         // Allocate the host name list
125

126         m_names = new StringList();
127     }
128
129     /**
130      * Return the server comment string.
131      *
132      * @return java.lang.String
133      */

134     public final String JavaDoc getComment()
135     {
136         return m_comment;
137     }
138
139     /**
140      * Return the domain name that the host announcement is directed to.
141      *
142      * @return java.lang.String
143      */

144     public final String JavaDoc getDomain()
145     {
146         return m_domain;
147     }
148
149     /**
150      * Return the number of names being announced
151      *
152      * @return int
153      */

154     public final int numberOfNames()
155     {
156         return m_names.numberOfStrings();
157     }
158
159     /**
160      * Return the specified host name being announced.
161      *
162      * @param idx int
163      * @return java.lang.String
164      */

165     public final String JavaDoc getHostName(int idx)
166     {
167         if (idx < 0 || idx > m_names.numberOfStrings())
168             return null;
169         return m_names.getStringAt(idx);
170     }
171
172     /**
173      * Return the announcement interval, in minutes.
174      *
175      * @return int
176      */

177     public final int getInterval()
178     {
179         return m_interval;
180     }
181
182     /**
183      * Return the server type flags.
184      *
185      * @return int
186      */

187     public final int getServerType()
188     {
189         return m_srvtype;
190     }
191
192     /**
193      * Determine if debug output is enabled
194      *
195      * @return boolean
196      */

197     public final boolean hasDebug()
198     {
199         return m_debug;
200     }
201
202     /**
203      * Enable/disable debug output
204      *
205      * @param dbg true or false
206      */

207     public final void setDebug(boolean dbg)
208     {
209         m_debug = dbg;
210     }
211
212     /**
213      * Initialize the host announcement SMB.
214      *
215      * @param name String
216      */

217     protected final void initHostAnnounceSMB(String JavaDoc name)
218     {
219
220         // Allocate the transact SMB
221

222         if (m_smbPkt == null)
223             m_smbPkt = new SMBMailslotPacket();
224
225         // Create the host announcement structure
226

227         byte[] data = new byte[256];
228         int pos = MailSlot.createHostAnnouncement(data, 0, name, m_comment, m_srvtype, m_interval, m_updateCount++);
229
230         // Create the mailslot SMB
231

232         m_smbPkt.initializeMailslotSMB(TransactionNames.MailslotBrowse, data, pos);
233     }
234
235     /**
236      * Start the host announcer thread.
237      */

238     public void run()
239     {
240
241         // Initialize the host announcer
242

243         try
244         {
245
246             // Initialize the host announcer datagram socket
247

248             initialize();
249         }
250         catch (Exception JavaDoc ex)
251         {
252
253             // Debug
254

255             logger.error("HostAnnouncer initialization error", ex);
256             return;
257         }
258
259         // Clear the shutdown flag
260

261         m_shutdown = false;
262
263         // Send the host announcement datagram
264

265         long sleepTime = STARTING_INTERVAL;
266         long sleepNormal = getInterval() * 60 * 1000;
267
268         while (m_shutdown == false)
269         {
270
271             try
272             {
273
274                 // Check if the network connection is valid
275

276                 if (isNetworkEnabled())
277                 {
278
279                     // Loop through the host names to be announced
280

281                     for (int i = 0; i < m_names.numberOfStrings(); i++)
282                     {
283
284                         // Create a host announcement transact SMB
285

286                         String JavaDoc hostName = getHostName(i);
287                         initHostAnnounceSMB(hostName);
288
289                         // Send the host announce datagram
290

291                         sendAnnouncement(hostName, m_smbPkt.getBuffer(), 0, m_smbPkt.getLength());
292
293                         // DEBUG
294

295                         if (logger.isDebugEnabled() && hasDebug())
296                             logger.debug("HostAnnouncer: Announced host " + hostName);
297                     }
298                 }
299                 else
300                 {
301
302                     // Reset the sleep interval to the starting interval as the network connection
303
// is not
304
// available
305

306                     sleepTime = STARTING_INTERVAL;
307                 }
308
309                 // Sleep for a while
310

311                 sleep(sleepTime);
312
313                 // Update the sleep interval, if the network connection is enabled
314

315                 if (isNetworkEnabled() && sleepTime < sleepNormal)
316                 {
317
318                     // Double the sleep interval until it exceeds the configured announcement
319
// interval.
320
// This is to send out more broadcasts when the server first starts.
321

322                     sleepTime *= 2;
323                     if (sleepTime > sleepNormal)
324                         sleepTime = sleepNormal;
325                 }
326             }
327             catch (WinsockNetBIOSException ex)
328             {
329                 // Debug
330

331                 if (m_shutdown == false)
332                     logger.error("HostAnnouncer error", ex);
333                 m_shutdown = true;
334             }
335             catch ( IOException JavaDoc ex)
336             {
337                 // Debug
338

339                 if (m_shutdown == false)
340                 {
341                     logger.error("HostAnnouncer error", ex);
342                     logger.error(" Check <broadcast> setting in file-servers.xml");
343                 }
344                 m_shutdown = true;
345             }
346             catch (Exception JavaDoc ex)
347             {
348                 // Debug
349

350                 if (m_shutdown == false)
351                     logger.error("HostAnnouncer error", ex);
352                 m_shutdown = true;
353             }
354         }
355
356         // Set the announcement interval to zero to indicate that the host is leaving Network
357
// Neighborhood
358

359         setInterval(0);
360
361         // Clear the server flag in the announced host type
362

363         if ((m_srvtype & ServerType.Server) != 0)
364             m_srvtype -= ServerType.Server;
365
366         // Send out a number of host announcement to remove the host name(s) from Network
367
// Neighborhood
368

369         for (int j = 0; j < SHUTDOWN_COUNT; j++)
370         {
371
372             // Loop through the host names to be announced
373

374             for (int i = 0; i < m_names.numberOfStrings(); i++)
375             {
376
377                 // Create a host announcement transact SMB
378

379                 String JavaDoc hostName = getHostName(i);
380                 initHostAnnounceSMB(hostName);
381
382                 // Send the host announce datagram
383

384                 try
385                 {
386
387                     // Send the host announcement
388

389                     sendAnnouncement(hostName, m_smbPkt.getBuffer(), 0, m_smbPkt.getLength());
390                 }
391                 catch (Exception JavaDoc ex)
392                 {
393                 }
394             }
395
396             // Sleep for a while
397

398             try
399             {
400                 sleep(SHUTDOWN_WAIT);
401             }
402             catch (InterruptedException JavaDoc ex)
403             {
404             }
405         }
406     }
407
408     /**
409      * Initialize the host announcer.
410      *
411      * @exception Exception
412      */

413     protected void initialize() throws Exception JavaDoc
414     {
415     }
416
417     /**
418      * Determine if the network connection used for the host announcement is valid
419      *
420      * @return boolean
421      */

422     public abstract boolean isNetworkEnabled();
423
424     /**
425      * Send an announcement broadcast.
426      *
427      * @param hostName Host name being announced
428      * @param buf Buffer containing the host announcement mailslot message.
429      * @param offset Offset to the start of the host announcement message.
430      * @param len Host announcement message length.
431      */

432     protected abstract void sendAnnouncement(String JavaDoc hostName, byte[] buf, int offset, int len) throws Exception JavaDoc;
433
434     /**
435      * Set the server comment string.
436      *
437      * @param comment java.lang.String
438      */

439     public final void setComment(String JavaDoc comment)
440     {
441         m_comment = comment;
442         if (m_comment != null && m_comment.length() > 80)
443             m_comment = m_comment.substring(0, 80);
444     }
445
446     /**
447      * Set the domain name that the host announcement are directed to.
448      *
449      * @param name java.lang.String
450      */

451     public final void setDomain(String JavaDoc name)
452     {
453         m_domain = name.toUpperCase();
454     }
455
456     /**
457      * Add a host name to the list of names to announce
458      *
459      * @param name java.lang.String
460      */

461     public final void addHostName(String JavaDoc name)
462     {
463         m_names.addString(NetBIOSName.toUpperCaseName(name));
464     }
465
466     /**
467      * Add a list of names to the announcement list
468      *
469      * @param names StringList
470      */

471     public final void addHostNames(StringList names)
472     {
473         m_names.addStrings(names);
474     }
475
476     /**
477      * Set the announcement interval, in minutes.
478      *
479      * @param intval int
480      */

481     public final void setInterval(int intval)
482     {
483         m_interval = intval;
484     }
485
486     /**
487      * Set the server type flags.
488      *
489      * @param typ int
490      */

491     public final void setServerType(int typ)
492     {
493         m_srvtype = typ;
494     }
495
496     /**
497      * Shutdown the host announcer and remove the announced name from Network Neighborhood.
498      */

499     public final synchronized void shutdownAnnouncer()
500     {
501
502         // Set the shutdown flag and wakeup the main host announcer thread
503

504         m_shutdown = true;
505         interrupt();
506
507         try
508         {
509             join(2000);
510         }
511         catch (InterruptedException JavaDoc ex)
512         {
513         }
514     }
515 }
Popular Tags