ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/owl/trunk/tools/PymolServerOutputStream.java
Revision: 28
Committed: Fri Mar 10 10:56:22 2006 UTC (18 years, 6 months ago) by stehr
File size: 5704 byte(s)
Log Message:
prevent overlong commands from being sent to the server
Line User Rev File contents
1 stehr 10 package tools;
2    
3     import java.io.IOException;
4     import java.io.OutputStream;
5     import java.io.PrintWriter;
6     import java.net.MalformedURLException;
7     import java.util.Vector;
8     import org.apache.xmlrpc.*;
9    
10     /**
11     * Package: tools
12     * Class: PymolServerOutput
13     * Author: Henning Stehr, stehr@molgen.mpg.de
14     * Date: 2/Feb/2006
15     *
16     * This class provides an output stream to send commands to a
17     * pymol server. It wraps the XML-RPC connection to the server
18     * using the url taken by the constructor. For convenience the
19     * OutputStream should be wrapped into a PrintStream.
20     *
21     * Code example:
22     * url = "http://localhost:9123";
23     * PrintWriter serverOut = new PrintWriter(new PymolServerOutputStream(url), true);
24     * serverOut.println("load /project/StruPPi/PDBs/mainPDB/1RX4.pdb, hello");
25     *
26     * Notes:
27     * - When constructing the PrintWriter, make sure to turn on automatic flushing
28     * by giving "true" as the second parameter, otherwise flush() has to be invoked
29     * manually to send the command to the server.
30     * - Automatic flushing is only invoked when using 'println' rather than 'print'.
31     * - For some reason, this does not work with a PrintStream only with a PrintWriter.
32     * - '\n' in command strings causes problems
33     *
34     * Changelog:
35     * 06/02/02 first created by HS
36     */
37     public class PymolServerOutputStream extends OutputStream {
38    
39     static final String DEFAULTXMLRPCCOMMAND = "do";
40     static final int INITIALBUFFERCAPACITY = 255;
41     static final int BUFFERCAPACITYINCREASE = 255;
42 stehr 28 static final int PYMOLCOMMANDLENGTHLIMIT = 1060;
43 stehr 10
44     byte[] commandBuffer;
45     int commandBufferPtr, // current load
46     commandBufferCap; // capacity
47     XmlRpcClient client;
48    
49     /**
50     * Create a new output stream to the server running at the given url
51     */
52     public PymolServerOutputStream(String url) {
53    
54     // create empty command buffer
55     commandBuffer = new byte[INITIALBUFFERCAPACITY];
56     commandBufferCap = INITIALBUFFERCAPACITY;
57     commandBufferPtr = 0;
58    
59     try {
60     // initialize connection to server
61     this.client = new XmlRpcClient(url);
62     } catch(MalformedURLException e) {
63     System.err.println("Error: Malformed URL in constructor of PymolServerOutputStream");
64     e.printStackTrace();
65     }
66     }
67    
68    
69     /**
70     * Store bytes in command buffer
71     */
72     @Override
73     public void write(int arg0) throws IOException {
74     if(commandBufferPtr >= commandBufferCap) {
75     // get more space
76     byte[] newBuffer = new byte[commandBufferCap + BUFFERCAPACITYINCREASE];
77 stehr 26 for(int i = 0; i < commandBufferPtr; i++) {
78 stehr 10 newBuffer[i] = commandBuffer[i];
79     }
80     commandBuffer = newBuffer;
81 stehr 26 commandBufferCap += BUFFERCAPACITYINCREASE;
82 stehr 10 }
83     commandBuffer[commandBufferPtr++] = (byte) arg0;
84     }
85    
86    
87     /**
88     * Send command to server whenever flush is invoked
89     */
90     @Override
91     public void flush() throws IOException {
92 stehr 28 // prevent overlong commands from being sent to server
93     if(commandBufferPtr > PYMOLCOMMANDLENGTHLIMIT + 1) {
94     throw new IOException();
95     }
96 stehr 10 // prepare parameter vector
97 stehr 28 Vector<String> myvector = new Vector<String>();
98     String commandString = new String(this.commandBuffer, 0, commandBufferPtr).trim();
99     myvector.add(commandString);
100 stehr 10 // reset command buffer
101     this.commandBuffer = new byte[INITIALBUFFERCAPACITY];
102 stehr 11 this.commandBufferCap = INITIALBUFFERCAPACITY;
103     this.commandBufferPtr = 0;
104 stehr 10 // submit command
105     try {
106     this.client.execute(DEFAULTXMLRPCCOMMAND, myvector);
107    
108     } catch(XmlRpcException e) {
109     System.out.println("XMP-RPC exception occured.");
110     // send IOException instead, so use of XML-RPC is transparent
111     throw new IOException();
112     }
113     }
114    
115     // test function for current class
116     public static void main(String[] args) {
117    
118     String serverUrl = "http://gelb:9123";
119 stehr 28 String command0 = "delete hello";
120 stehr 10 String command1 = "load /project/StruPPi/PDBs/mainPDB/1RX4.pdb, hello";
121     String command2 = "show cartoon";
122     String command3 = "select hello2, resi 12";
123     String command4 = "show sticks, hello2";
124     String command5 = "zoom hello2";
125    
126     // try to connect directly
127     System.out.println("Trying to connect directly by XML-RPC...");
128     try {
129     XmlRpcClient client = new XmlRpcClient(serverUrl);
130     Vector<String> myvector = new Vector<String>();
131     myvector.add(command1);
132     try {
133     client.execute(DEFAULTXMLRPCCOMMAND,myvector);
134     System.out.println("done.");
135     }
136     catch (IOException e) {
137     e.printStackTrace();
138     }
139     catch( XmlRpcException e) {
140     e.printStackTrace();
141     }
142     }
143     catch(MalformedURLException e){
144     e.printStackTrace();
145     }
146    
147     // try using OutputStream
148     System.out.println("Trying to connect via PymolServerOutputStream...");
149     try {
150     // create new output stream
151     OutputStream serverOut = new PymolServerOutputStream(serverUrl);
152    
153     // send data to output stream
154     serverOut.write(command0.getBytes());
155     // execute command
156     serverOut.flush();
157    
158     System.out.println("done.");
159    
160     } catch(MalformedURLException e) {
161     System.out.println("Error: The server URL is wrong.");
162     e.printStackTrace();
163     System.exit(1);
164     } catch(IOException e) {
165     System.out.println("Error writing to server url.");
166     e.printStackTrace();
167     System.exit(1);
168     }
169    
170     // now try using OutputStream wrapped into PrintStream
171     System.out.println("Trying to connect via PrintWriter...");
172     PrintWriter serverOutPw = new PrintWriter(new PymolServerOutputStream(serverUrl), true);
173     serverOutPw.println(command0);
174     serverOutPw.println(command1);
175     serverOutPw.println(command2);
176     serverOutPw.println(command3);
177     serverOutPw.println(command4);
178     serverOutPw.println(command5);
179     System.out.println("done.");
180     }
181    
182     }