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

Quick Search    Search Deep

Source code: org/apache/axis/monitor/SOAPMonitorService.java


1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.axis.monitor;
18  
19  import javax.servlet.ServletConfig;
20  import javax.servlet.ServletException;
21  import javax.servlet.http.HttpServlet;
22  import javax.servlet.http.HttpServletRequest;
23  import javax.servlet.http.HttpServletResponse;
24  import java.io.IOException;
25  import java.io.ObjectInputStream;
26  import java.io.ObjectOutputStream;
27  import java.net.ServerSocket;
28  import java.net.Socket;
29  import java.util.Enumeration;
30  import java.util.Vector;
31  
32  /**
33   * This is a SOAP Monitor Service class. 
34   *
35   * During the HTTP server startup, the servlet init method 
36   * is invoked.  This allows the code to open a server 
37   * socket that will be used to communicate with running 
38   * applets.
39   *
40   * When an HTTP GET request is received, the servlet 
41   * dynamically produces an HTML document to load the SOAP 
42   * monitor applet and supply the port number being used by
43   * the server socket (so the applet will know how to 
44   * connect back to the server).
45   *
46   * Each time a socket connection is established, a new 
47   * thread is created to handle communications from the 
48   * applet.
49   *
50   * The publishMethod routine is invoked by the SOAP monitor
51   * handler when a SOAP message request or response is 
52   * detected.  The information about the SOAP message is 
53   * then forwared to all current socket connections for 
54   * display by the applet.
55   *
56   * @author Brian Price (pricebe@us.ibm.com)
57   * xdoclet tags are not active yet; keep web.xml in sync
58   * @web.servlet name="SOAPMonitorService"  display-name="SOAPMonitorService"  load-on-startup="100"
59   * @web.servlet-mapping url-pattern="/SOAPMonitor"
60   * @web.servlet-init-param name="SOAPMonitorPort" value="5001"
61   */
62  
63  public class SOAPMonitorService extends HttpServlet {
64  
65    /**
66     * Private data 
67     */
68    private static ServerSocket server_socket = null;
69    private static Vector       connections = null;
70  
71    /**
72     * Constructor
73     */
74    public SOAPMonitorService() {
75    }
76  
77  
78    /**
79     * Publish a SOAP message to listeners
80     */
81    public static void publishMessage(Long id, 
82                                      Integer type, 
83                                      String target,
84                                      String soap) {
85      if (connections != null) {
86        Enumeration e = connections.elements();
87        while (e.hasMoreElements()) {
88          ConnectionThread ct = (ConnectionThread) e.nextElement();
89          ct.publishMessage(id,type,target,soap);
90        }
91      }
92    }
93  
94    /**
95     * Servlet initialiation
96     */
97    public void init() throws ServletException {
98      if (connections == null) {
99        // Create vector to hold connection information
100       connections = new Vector();
101     }
102     if (server_socket == null) {
103       // Get the server socket port from the init params
104       ServletConfig config = super.getServletConfig();
105       String port = config.getInitParameter(SOAPMonitorConstants.SOAP_MONITOR_PORT);
106       if (port == null) {
107         // No port defined, so let the system assign a port
108         port = "0";
109       } 
110       try {
111         // Try to open the server socket
112         server_socket = new ServerSocket(Integer.parseInt(port));
113       } catch (Exception e) {
114         // Let someone know we could not open the socket
115         // System. out.println("Unable to open server socket using port "+port+".");
116         server_socket = null;
117       }
118       if (server_socket != null) {
119         // Start the server socket thread
120         new Thread(new ServerSocketThread()).start();
121       }
122     }
123   }
124 
125   /**
126    * Servlet termination
127    */
128   public void destroy() {
129     // End all connection threads
130     Enumeration e = connections.elements();
131     while (e.hasMoreElements()) {
132       ConnectionThread ct = (ConnectionThread) e.nextElement();
133       ct.close();
134     }
135     // End main server socket thread
136     if (server_socket != null) {
137       try {
138         server_socket.close();
139       } catch (Exception x) {}
140       server_socket = null;
141     }
142   }
143 
144   /**
145    * HTTP GET request
146    */
147   public void doGet(HttpServletRequest request, HttpServletResponse response)
148               throws IOException, ServletException
149   {
150    // Create HTML to load the SOAP monitor applet
151    int port = 0;
152    if (server_socket != null) {
153      port = server_socket.getLocalPort();
154    }
155    response.setContentType("text/html");
156    response.getWriter().println("<html>");
157    response.getWriter().println("<head>");
158    response.getWriter().println("<title>SOAP Monitor</title>");
159    response.getWriter().println("</head>");
160    response.getWriter().println("<body>");
161    response.getWriter().println("<object classid=\"clsid:8AD9C840-044E-11D1-B3E9-00805F499D93\" width=100% height=100% codebase=\"http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0\">");
162    response.getWriter().println("<param name=code value=SOAPMonitorApplet.class>");
163    response.getWriter().println("<param name=\"type\" value=\"application/x-java-applet;version=1.3\">");
164    response.getWriter().println("<param name=\"scriptable\" value=\"false\">");
165    response.getWriter().println("<param name=\"port\" value=\""+port+"\">");
166    response.getWriter().println("<comment>");
167    response.getWriter().println("<embed type=\"application/x-java-applet;version=1.3\" code=SOAPMonitorApplet.class width=100% height=100% port=\""+port+"\" scriptable=false pluginspage=\"http://java.sun.com/products/plugin/1.3/plugin-install.html\">"); 
168    response.getWriter().println("<noembed>"); 
169    response.getWriter().println("</comment>"); 
170    response.getWriter().println("</noembed>"); 
171    response.getWriter().println("</embed>"); 
172    response.getWriter().println("</object>");
173    response.getWriter().println("</body>");
174    response.getWriter().println("</html>");
175   }
176 
177   /**
178    * Thread class for handling the server socket
179    */
180   class ServerSocketThread implements Runnable {
181 
182     /**
183      * Thread for handling the server socket
184      */
185     public void run() {
186       // Wait for socket connections
187       while (server_socket != null) {
188         try {
189           Socket socket = server_socket.accept();
190           new Thread(new ConnectionThread(socket)).start();
191         } catch (IOException ioe) {}
192       }
193     }
194   }
195 
196   /**
197    * Thread class for handling socket connections
198    */
199   class ConnectionThread implements Runnable {
200 
201     private Socket             socket = null;
202     private ObjectInputStream  in = null;
203     private ObjectOutputStream out = null;
204     private boolean            closed = false;
205 
206     /**
207      * Constructor
208      */
209     public ConnectionThread(Socket s) {
210       socket = s;
211       try {
212         // Use object streams for input and output
213         //
214         // NOTE: We need to be sure to create and flush the 
215         // output stream first because the ObjectOutputStream
216         // constructor writes a header to the stream that is
217         // needed by the ObjectInputStream on the other end
218         out = new ObjectOutputStream(socket.getOutputStream());
219         out.flush();
220         in = new ObjectInputStream(socket.getInputStream());
221       } catch (Exception e) {}
222       // Add the connection to our list
223       synchronized (connections) {
224         connections.addElement(this);
225       }
226     }
227 
228     /**
229      * Close the socket connection
230      */
231     public void close() {
232       closed = true;
233       try {
234         socket.close();
235       } catch (IOException ioe) {}
236     }
237 
238     /**
239      * Thread to handle the socket connection
240      */
241     public void run() {
242       try {
243         while (!closed) {
244           Object o = in.readObject();
245         }
246       } catch (Exception e) {}
247       // Cleanup connection list
248       synchronized (connections) {
249         connections.removeElement(this);
250       }
251       // Cleanup I/O streams 
252       if (out != null) {
253         try {
254           out.close();
255         } catch (IOException ioe) {}
256         out = null;
257       }
258       if (in != null) {
259         try {
260           in.close();
261         } catch (IOException ioe) {}
262         in = null;
263       }
264       // Be sure the socket is closed
265       close();
266     }
267 
268     /**
269      * Publish SOAP message information
270      */
271     public synchronized void publishMessage(Long id, 
272                                Integer message_type, 
273                                String target, 
274                                String soap) {
275       // If we have a valid output stream, then
276       // send the data to the applet
277       if (out != null) {
278         try {
279           switch (message_type.intValue()) {
280             case SOAPMonitorConstants.SOAP_MONITOR_REQUEST:
281               out.writeObject(message_type);
282               out.writeObject(id);
283               out.writeObject(target);
284               out.writeObject(soap);
285               out.flush();
286               break;
287             case SOAPMonitorConstants.SOAP_MONITOR_RESPONSE:
288               out.writeObject(message_type);
289               out.writeObject(id);
290               out.writeObject(soap);
291               out.flush();
292               break;
293           }
294         } catch (Exception e) {}
295       }
296     }
297   }
298 }
299