883d53645a73e894d6de97eb5721f017e74b5359
[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.StructureManager;
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     // TODO do we need a maximum wait time before aborting?
71                 while (!replyLog.containsKey(command)) {
72                         try {
73                                 Thread.currentThread().sleep(100);
74                         } catch (InterruptedException e) {
75                         }
76                 }
77
78                 synchronized (replyLog) {
79                         reply = replyLog.get(command);
80                         // System.out.println("getResponse ("+command+") = "+reply);
81                         replyLog.remove(command);
82                 }
83                 return reply;
84         }
85
86         public void clearResponse(String command) {
87                 try {
88                         Thread.currentThread().sleep(100);
89                 } catch (InterruptedException e) {
90                 }
91                 if (replyLog.containsKey(command))
92     {
93       replyLog.remove(command);
94     }
95                 return;
96         }
97
98         /**
99          * Read input from Chimera
100          * 
101          * @return a List containing the replies from Chimera
102          */
103         private void chimeraRead() throws IOException {
104                 if (chimera == null)
105     {
106       return;
107     }
108
109                 String line = null;
110                 while ((line = lineReader.readLine()) != null) {
111                         // System.out.println("From Chimera-->" + line);
112                         if (line.startsWith("CMD")) {
113                                 chimeraCommandRead(line.substring(4));
114                         } else if (line.startsWith("ModelChanged: ")) {
115                                 (new ModelUpdater()).start();
116                         } else if (line.startsWith("SelectionChanged: ")) {
117                                 (new SelectionUpdater()).start();
118                         } else if (line.startsWith("Trajectory residue network info:")) {
119                                 (new NetworkUpdater(line)).start();
120                         }
121                 }
122                 return;
123         }
124
125         private void chimeraCommandRead(String command) throws IOException {
126                 // Generally -- looking for:
127                 // CMD command
128                 // ........
129                 // END
130                 // We return the text in between
131                 List<String> reply = new ArrayList<String>();
132                 boolean updateModels = false;
133                 boolean updateSelection = false;
134                 boolean importNetwork = false;
135                 String line = null;
136
137                 synchronized (replyLog) {
138                         while ((line = lineReader.readLine()) != null) {
139                                 // System.out.println("From Chimera (" + command + ") -->" + line);
140                                 if (line.startsWith("CMD")) {
141                                         logger.warn("Got unexpected command from Chimera: " + line);
142
143                                 } else if (line.startsWith("END")) {
144                                         break;
145                                 }
146                                 if (line.startsWith("ModelChanged: ")) {
147                                         updateModels = true;
148                                 } else if (line.startsWith("SelectionChanged: ")) {
149                                         updateSelection = true;
150                                 } else if (line.length() == 0) {
151                                         continue;
152                                 } else if (!line.startsWith("CMD")) {
153                                         reply.add(line);
154                                 } else if (line.startsWith("Trajectory residue network info:")) {
155                                         importNetwork = true;
156                                 }
157                         }
158                         replyLog.put(command, reply);
159                 }
160                 if (updateModels)
161     {
162       (new ModelUpdater()).start();
163     }
164                 if (updateSelection)
165     {
166       (new SelectionUpdater()).start();
167     }
168                 if (importNetwork) {
169                         (new NetworkUpdater(line)).start();
170                 }
171                 return;
172         }
173
174         /**
175          * Model updater thread
176          */
177         class ModelUpdater extends Thread {
178
179                 public ModelUpdater() {
180                 }
181
182                 public void run() {
183                         structureManager.updateModels();
184                         structureManager.modelChanged();
185                 }
186         }
187
188         /**
189          * Selection updater thread
190          */
191         class SelectionUpdater extends Thread {
192
193                 public SelectionUpdater() {
194                 }
195
196                 public void run() {
197                         try {
198                           logger.info("Responding to chimera selection");
199                           structureManager.chimeraSelectionChanged();
200                         } catch (Exception e) {
201                                 logger.warn("Could not update selection", e);
202                         }
203                 }
204         }
205
206         /**
207          * Selection updater thread
208          */
209         class NetworkUpdater extends Thread {
210
211                 private String line;
212
213                 public NetworkUpdater(String line) {
214                         this.line = line;
215                 }
216
217                 public void run() {
218                         try {
219 //                              ((TaskManager<?, ?>) structureManager.getService(TaskManager.class))
220 //                                              .execute(new ImportTrajectoryRINTaskFactory(structureManager, line)
221 //                                                              .createTaskIterator());
222                         } catch (Exception e) {
223                                 logger.warn("Could not import trajectory network", e);
224                         }
225                 }
226         }
227 }