Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/jabberwookie/Component2Server.java


1   /*
2    * Component2Server.java
3    *
4    * Created on May 16, 2003, 4:18 PM
5    * Copyright (c) 2003, Sean M. Meiners, sean@jabberwookie.com
6    * All rights reserved.
7    * 
8    * Redistribution and use in source and binary forms, with or without
9    * modification, are permitted provided that the following conditions are met:
10   * 
11   *     * Redistributions of source code must retain the above copyright notice,
12   *       this list of conditions and the following disclaimer.
13   *     * Redistributions in binary form must reproduce the above copyright notice,
14   *       this list of conditions and the following disclaimer in the documentation
15   *       and/or other materials provided with the distribution.
16   *     * Neither the name of JabberWookie nor the names of its contributors may be used
17   *       to endorse or promote products derived from this software without specific
18   *       prior written permission.
19   * 
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   */
31  
32  package com.jabberwookie;
33  
34  import java.util.Hashtable;
35  
36  import java.io.IOException;
37  import java.io.InputStream;
38  import java.io.OutputStream;
39  
40  import com.jabberwookie.ns.jabber.Chunk;
41  
42  import com.jabberwookie.UnrecognizedChunkListener;
43  
44  import com.ssttr.crypto.SHA1;
45  
46  import com.ssttr.util.processor.Processor;
47  
48  /**
49   * Implements the required methods to establish a connection to a
50   * Jabber server as a component.  This allows you to create new
51   * services for the server. 
52   * @author  smeiners
53   */
54  public class Component2Server
55  extends Stream
56  implements UnrecognizedChunkListener
57  {
58      
59      private static final String     STREAM_OPENER   =
60      "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' " +
61      "xmlns='jabber:component:accept' to='";
62      
63      private static final String     STREAM_CLOSER   =
64      "</stream:stream>";
65      
66      private String secret = "";
67      
68      private boolean authenticated = false;
69      
70      /** Creates a new instance of Component2Server.  Since this class
71       * doesn't understand what a Socket is you'll have to open
72       * one youself and then pass in the input and output stream.
73       * @param secret The secret used to authenticate yourself to
74       * the Jabber server. */
75      public Component2Server (InputStream in, OutputStream out, String secret) {
76          super(in,out);
77          _init(secret);
78      }
79      
80      /** Creates a new instance of Component2Server.  Since this class
81       * doesn't understand what a Socket is you'll have to open
82       * one youself and then pass in the input and output stream.
83       * Please see the documentation for
84       * {@link Stream#Stream(InputStream,OutputStream,Processor)}
85       * and {@link Stream#setProcessor} for more information about
86       * the Processor.
87       * @param secret The secret used to authenticate yourself to
88       * the Jabber server.
89       */
90      public Component2Server (InputStream in, OutputStream out,
91                               String secret, Processor processor) {
92          super(in,out,processor);
93          _init(secret);
94      }
95      
96      private void _init(String secret)
97      {
98          unListener = this;
99          this.secret = secret;
100     }
101     
102     /**
103      * Since Jabber components are set to receive data from specific
104      * namespaces only this overrides the default
105      * {@link Stream#setUnrecogizedChunkListener} to do nothing.
106      */
107     public void setUnrecogizedChunkListener(UnrecognizedChunkListener listener)
108     {
109     }
110     
111     /**
112      * Opens the stream and attempts to authenticate itself.
113      */
114     public boolean open(String serverName, int timeoutSecs)
115     throws IOException
116     {
117         if( DEBUG )
118             System.out.println("SEND: " + (STREAM_OPENER + serverName + "'>"));
119 
120         if( ns == null )
121             ns = new Namespaces();
122         
123         out.write( (STREAM_OPENER + serverName + "'>").getBytes() );
124         out.flush();
125         
126         long stopTime = System.currentTimeMillis() + timeoutSecs * 1000;
127         while( ! connected && ! authenticated && System.currentTimeMillis() < stopTime )
128         {
129             try
130             { Thread.sleep(5); }
131             catch( InterruptedException x )
132             { }
133         }
134         
135         return connected && authenticated;
136     }
137     
138     /**
139      * Closes the stream.
140      */
141     public synchronized void close()
142     {
143         try
144         {
145             if( DEBUG )
146                 System.out.println("SEND: " + (STREAM_CLOSER));
147                 
148             if( out != null )
149             {
150                 out.write ( STREAM_CLOSER.getBytes () );
151                 out.flush();
152             }
153         }
154         catch( IOException x )
155         { }
156         
157         if( in != null )
158             try
159             { in.close(); }
160             catch( IOException x )
161             { }
162 
163         if( out != null )        
164             try
165             { out.close(); }
166             catch( IOException x )
167             { }
168         
169         connected = false;
170         authenticated = false;
171         in = null;
172         out = null;
173     }
174     
175     public void docStart (String tag, Hashtable attrs)
176     {
177         super.docStart(tag,attrs);
178         
179         // authenticate ourselves
180         SHA1 md = new SHA1();
181         String resp = getConnectionId() + secret;
182         if( DEBUG )
183             System.out.println("Making hash from: '"+resp+"'");
184         md.computeDigest( resp.getBytes() );
185         String hash = md.getDigestHex();
186         
187         Chunk hs = new Chunk("handshake");
188         hs.setValue(hash);
189 
190         try
191         { send(hs); }
192         catch( IOException x )
193         { x.printStackTrace(); }
194     }
195     
196     /** From UnrecognizedChunkListener, needed for authentication. */
197     public void incomingChunk(Chunk chunk)
198     {
199         if( chunk.getName().equals("handshake") )
200             authenticated = true;
201     }
202     
203 }