ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/owl/trunk/tools/PymolServerOutputStream.java
Revision: 26
Committed: Thu Mar 9 15:55:56 2006 UTC (18 years, 6 months ago) by stehr
File size: 5571 byte(s)
Log Message:
fixed bug for very long command strings (> 255 characters)
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    
43     byte[] commandBuffer;
44     int commandBufferPtr, // current load
45     commandBufferCap; // capacity
46     XmlRpcClient client;
47    
48     /**
49     * Create a new output stream to the server running at the given url
50     */
51     public PymolServerOutputStream(String url) {
52    
53     // create empty command buffer
54     commandBuffer = new byte[INITIALBUFFERCAPACITY];
55     commandBufferCap = INITIALBUFFERCAPACITY;
56     commandBufferPtr = 0;
57    
58     try {
59    
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     // prepare parameter vector
93     Vector<String> myvector = new Vector<String>();
94     myvector.add(new String(this.commandBuffer, 0, commandBufferPtr).trim());
95     // reset command buffer
96     this.commandBuffer = new byte[INITIALBUFFERCAPACITY];
97 stehr 11 this.commandBufferCap = INITIALBUFFERCAPACITY;
98     this.commandBufferPtr = 0;
99 stehr 10 // DEBUG: view command to be sent
100     // System.out.println("Flush, current buffer=" + myvector);
101     // submit command
102     try {
103     this.client.execute(DEFAULTXMLRPCCOMMAND, myvector);
104    
105     } catch(XmlRpcException e) {
106     System.out.println("XMP-RPC exception occured.");
107     // send IOException instead, so use of XML-RPC is transparent
108     throw new IOException();
109     }
110     }
111    
112     // test function for current class
113     public static void main(String[] args) {
114    
115     String serverUrl = "http://gelb:9123";
116     String command0 = "delete hello";
117     String command1 = "load /project/StruPPi/PDBs/mainPDB/1RX4.pdb, hello";
118     String command2 = "show cartoon";
119     String command3 = "select hello2, resi 12";
120     String command4 = "show sticks, hello2";
121     String command5 = "zoom hello2";
122    
123     // try to connect directly
124     System.out.println("Trying to connect directly by XML-RPC...");
125     try {
126     XmlRpcClient client = new XmlRpcClient(serverUrl);
127     Vector<String> myvector = new Vector<String>();
128     myvector.add(command1);
129     try {
130     client.execute(DEFAULTXMLRPCCOMMAND,myvector);
131     System.out.println("done.");
132     }
133     catch (IOException e) {
134     e.printStackTrace();
135     }
136     catch( XmlRpcException e) {
137     e.printStackTrace();
138     }
139     }
140     catch(MalformedURLException e){
141     e.printStackTrace();
142     }
143    
144     // try using OutputStream
145     System.out.println("Trying to connect via PymolServerOutputStream...");
146     try {
147     // create new output stream
148     OutputStream serverOut = new PymolServerOutputStream(serverUrl);
149    
150     // send data to output stream
151     serverOut.write(command0.getBytes());
152     // execute command
153     serverOut.flush();
154    
155     System.out.println("done.");
156    
157     } catch(MalformedURLException e) {
158     System.out.println("Error: The server URL is wrong.");
159     e.printStackTrace();
160     System.exit(1);
161     } catch(IOException e) {
162     System.out.println("Error writing to server url.");
163     e.printStackTrace();
164     System.exit(1);
165     }
166    
167     // now try using OutputStream wrapped into PrintStream
168     System.out.println("Trying to connect via PrintWriter...");
169     PrintWriter serverOutPw = new PrintWriter(new PymolServerOutputStream(serverUrl), true);
170     serverOutPw.println(command0);
171     serverOutPw.println(command1);
172     serverOutPw.println(command2);
173     serverOutPw.println(command3);
174     serverOutPw.println(command4);
175     serverOutPw.println(command5);
176     System.out.println("done.");
177     }
178    
179     }