JAL-1333 Chimera specific code extracted from the StructureViz library for opening...
[jalview.git] / src / ext / edu / ucsf / rbvi / strucviz2 / port / ListenerThreads.java
1 package ext.edu.ucsf.rbvi.strucviz2.port;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.InputStreamReader;
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.List;
10 import java.util.Map;
11
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15 import ext.edu.ucsf.rbvi.strucviz2.*;
16
17 /***************************************************
18  *                 Thread Classes                  *
19  **************************************************/
20
21 /**
22  * Reply listener thread
23  */
24 public class ListenerThreads extends Thread {
25         private InputStream readChan = null;
26         private BufferedReader lineReader = null;
27         private Process chimera = null;
28         private Map<String, List<String>> replyLog = null;
29         private Logger logger;
30         private StructureManager structureManager = null;
31
32         /**
33          * Create a new listener thread to read the responses from Chimera
34          * 
35          * @param chimera
36          *            a handle to the Chimera Process
37          * @param log
38          *            a handle to a List to post the responses to
39          * @param chimeraObject
40          *            a handle to the Chimera Object
41          */
42         public ListenerThreads(Process chimera, StructureManager structureManager) {
43                 this.chimera = chimera;
44                 this.structureManager = structureManager;
45                 replyLog = new HashMap<String, List<String>>();
46                 // Get a line-oriented reader
47                 readChan = chimera.getInputStream();
48                 lineReader = new BufferedReader(new InputStreamReader(readChan));
49                 logger = LoggerFactory.getLogger(ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads.class);
50         }
51
52         /**
53          * Start the thread running
54          */
55         public void run() {
56                 // System.out.println("ReplyLogListener running");
57                 while (true) {
58                         try {
59                                 chimeraRead();
60                         } catch (IOException e) {
61                                 logger.warn("UCSF Chimera has exited: " + e.getMessage());
62                                 return;
63                         }
64                 }
65         }
66
67         public List<String> getResponse(String command) {
68                 List<String> reply;
69                 // System.out.println("getResponse: "+command);
70                 while (!replyLog.containsKey(command)) {
71                         try {
72                                 Thread.currentThread().sleep(100);
73                         } catch (InterruptedException e) {
74                         }
75                 }
76
77                 synchronized (replyLog) {
78                         reply = replyLog.get(command);
79                         // System.out.println("getResponse ("+command+") = "+reply);
80                         replyLog.remove(command);
81                 }
82                 return reply;
83         }
84
85         public void clearResponse(String command) {
86                 try {
87                         Thread.currentThread().sleep(100);
88                 } catch (InterruptedException e) {
89                 }
90                 if (replyLog.containsKey(command))
91                         replyLog.remove(command);
92                 return;
93         }
94
95         /**
96          * Read input from Chimera
97          * 
98          * @return a List containing the replies from Chimera
99          */
100         private void chimeraRead() throws IOException {
101                 if (chimera == null)
102                         return;
103
104                 String line = null;
105                 while ((line = lineReader.readLine()) != null) {
106                         // System.out.println("From Chimera-->" + line);
107                         if (line.startsWith("CMD")) {
108                                 chimeraCommandRead(line.substring(4));
109                         } else if (line.startsWith("ModelChanged: ")) {
110                                 (new ModelUpdater()).start();
111                         } else if (line.startsWith("SelectionChanged: ")) {
112                                 (new SelectionUpdater()).start();
113                         } else if (line.startsWith("Trajectory residue network info:")) {
114                                 (new NetworkUpdater(line)).start();
115                         }
116                 }
117                 return;
118         }
119
120         private void chimeraCommandRead(String command) throws IOException {
121                 // Generally -- looking for:
122                 // CMD command
123                 // ........
124                 // END
125                 // We return the text in between
126                 List<String> reply = new ArrayList<String>();
127                 boolean updateModels = false;
128                 boolean updateSelection = false;
129                 boolean importNetwork = false;
130                 String line = null;
131
132                 synchronized (replyLog) {
133                         while ((line = lineReader.readLine()) != null) {
134                                 // System.out.println("From Chimera (" + command + ") -->" + line);
135                                 if (line.startsWith("CMD")) {
136                                         logger.warn("Got unexpected command from Chimera: " + line);
137
138                                 } else if (line.startsWith("END")) {
139                                         break;
140                                 }
141                                 if (line.startsWith("ModelChanged: ")) {
142                                         updateModels = true;
143                                 } else if (line.startsWith("SelectionChanged: ")) {
144                                         updateSelection = true;
145                                 } else if (line.length() == 0) {
146                                         continue;
147                                 } else if (!line.startsWith("CMD")) {
148                                         reply.add(line);
149                                 } else if (line.startsWith("Trajectory residue network info:")) {
150                                         importNetwork = true;
151                                 }
152                         }
153                         replyLog.put(command, reply);
154                 }
155                 if (updateModels)
156                         (new ModelUpdater()).start();
157                 if (updateSelection)
158                         (new SelectionUpdater()).start();
159                 if (importNetwork) {
160                         (new NetworkUpdater(line)).start();
161                 }
162                 return;
163         }
164
165         /**
166          * Model updater thread
167          */
168         class ModelUpdater extends Thread {
169
170                 public ModelUpdater() {
171                 }
172
173                 public void run() {
174                         structureManager.updateModels();
175                         structureManager.modelChanged();
176                 }
177         }
178
179         /**
180          * Selection updater thread
181          */
182         class SelectionUpdater extends Thread {
183
184                 public SelectionUpdater() {
185                 }
186
187                 public void run() {
188                         try {
189 //                              structureManager.chimeraSelectionChanged();
190                         } catch (Exception e) {
191                                 logger.warn("Could not update selection", e);
192                         }
193                 }
194         }
195
196         /**
197          * Selection updater thread
198          */
199         class NetworkUpdater extends Thread {
200
201                 private String line;
202
203                 public NetworkUpdater(String line) {
204                         this.line = line;
205                 }
206
207                 public void run() {
208                         try {
209 //                              ((TaskManager<?, ?>) structureManager.getService(TaskManager.class))
210 //                                              .execute(new ImportTrajectoryRINTaskFactory(structureManager, line)
211 //                                                              .createTaskIterator());
212                         } catch (Exception e) {
213                                 logger.warn("Could not import trajectory network", e);
214                         }
215                 }
216         }
217 }