1   package net.sf.jhylafax;
2   
3   import static net.sf.jhylafax.JHylaFAX.i18n;
4   import gnu.hylafax.HylaFAXClient;
5   import gnu.inet.ftp.ServerResponseException;
6   import java.io.BufferedOutputStream;
7   import java.io.File;
8   import java.io.FileNotFoundException;
9   import java.io.FileOutputStream;
10  import java.io.IOException;
11  import java.io.OutputStream;
12  import java.util.ArrayList;
13  import java.util.Iterator;
14  import java.util.List;
15  import java.util.StringTokenizer;
16  import net.sf.jhylafax.fax.Document;
17  import net.sf.jhylafax.fax.FaxJob;
18  import net.sf.jhylafax.fax.HylaFAXClientHelper;
19  import net.sf.jhylafax.fax.ReceivedFax;
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  import org.xnap.commons.io.Job;
23  import org.xnap.commons.io.ProgressMonitor;
24  import org.xnap.commons.io.UserAbortException;
25  
26  public class JobHelper {
27  	
28  	private final static Log logger = LogFactory.getLog(JobHelper.class);
29  	
30  	static void retryJob(final int jobID) {
31  		Job<?> ioJob = new Job() {
32  			public Object run(ProgressMonitor monitor) throws Exception
33  			{
34  				monitor.setTotalSteps(3);
35  				
36  				HylaFAXClient client = JHylaFAX.getInstance().getConnection(monitor);
37  				monitor.work(1);
38  
39  				monitor.setText(i18n.tr("Retrying job"));
40  				gnu.hylafax.Job editJob = client.getJob(jobID);
41  				client.suspend(editJob);
42  				editJob.setProperty("SENDTIME", "NOW");
43  				monitor.work(1);
44  				
45  				client.submit(editJob);
46  				monitor.work(1);
47  
48  				return null;
49  			}
50  		};
51  		
52  		try {
53  			JHylaFAX.getInstance().runJob(ioJob);
54  			JHylaFAX.getInstance().updateTables();
55  		} 
56  		catch (UserAbortException e) {
57  		} 
58  		catch (Exception e) {
59  			logger.debug("Error retrying job", e);
60  			JHylaFAX.getInstance().showError(i18n.tr("Could not retry job"), e);
61  		}
62  	}
63  
64  	static void resumeJob(final int jobID) {
65  		Job<?> ioJob = new Job() {
66  			public Object run(ProgressMonitor monitor) throws Exception
67  			{
68  				monitor.setTotalSteps(2);
69  				
70  				HylaFAXClient client = JHylaFAX.getInstance().getConnection(monitor);
71  				monitor.work(1);
72  
73  				monitor.setText(i18n.tr("Resuming job"));
74  				gnu.hylafax.Job editJob = client.getJob(jobID);
75  				client.submit(editJob);
76  				monitor.work(1);
77  
78  				return null;
79  			}
80  		};
81  		
82  		try {
83  			JHylaFAX.getInstance().runJob(ioJob);
84  			JHylaFAX.getInstance().updateTables();
85  		} 
86  		catch (UserAbortException e) {
87  		} 
88  		catch (Exception e) {
89  			logger.debug("Error resuming job", e);
90  			JHylaFAX.getInstance().showError(i18n.tr("Could not resume job"), e); 
91  		}
92  	}
93  
94  	static FileStat[] retrieveJobFilenames(final int jobID) {
95  		Job<FileStat[]> ioJob = new Job<FileStat[]>() {
96  			public FileStat[] run(ProgressMonitor monitor) throws Exception
97  			{
98  				monitor.setTotalSteps(2);
99  				
100 				HylaFAXClient client = JHylaFAX.getInstance().getConnection(monitor);
101 				monitor.work(1);
102 
103 				monitor.setText(i18n.tr("Getting document filenames"));
104 				gnu.hylafax.Job editJob = client.getJob(jobID);
105 				String[] filenames = editJob.getDocumentName().split("\n");
106 				
107 				List<FileStat> results = new ArrayList<FileStat>(filenames.length);
108 				for (int i = 0; i < filenames.length; i++) {
109 					StringTokenizer t = new StringTokenizer(filenames[i]);
110 					String filetype = t.nextToken();
111 					if (t.hasMoreTokens() && 
112 							("PS".equalsIgnoreCase(filetype) || "PDF".equalsIgnoreCase(filetype))) {
113 						String filename = t.nextToken();
114 						try {
115 							long filesize = client.size(filename);
116 							results.add(new FileStat(filename, filesize));
117 						}
118 						catch (FileNotFoundException e) {
119 						}
120 					}
121 				}
122 				monitor.work(1);
123 
124 				return results.toArray(new FileStat[0]);
125 			}
126 		};
127 		
128 		try {
129 			return JHylaFAX.getInstance().runJob(ioJob);
130 		} 
131 		catch (UserAbortException e) {
132 		} 
133 		catch (Exception e) {
134 			logger.debug("Error getting job documents", e);
135 			JHylaFAX.getInstance().showError(i18n.tr("Could not get filenames"), e); 
136 		}
137 		return null;
138 	}
139 
140 	static boolean delete(final String filename) {
141 		Job<?> ioJob = new Job() {
142 			public Object run(ProgressMonitor monitor) throws Exception
143 			{
144 				monitor.setTotalSteps(2);
145 				monitor.setText(i18n.tr("Deleting file"));
146 				HylaFAXClient client = JHylaFAX.getInstance().getConnection(monitor);
147 				monitor.work(1);
148 				client.dele(filename);
149 				monitor.work(1);
150 				return null;
151 			}
152 		};
153 		
154 		try {
155 			JHylaFAX.getInstance().runJob(ioJob);
156 			JHylaFAX.getInstance().updateTables();
157 		} 
158 		catch (UserAbortException e) {
159 			return false;
160 		}
161 		catch (Exception e) {
162 			logger.debug("Error deleting file " + filename, e);
163 			JHylaFAX.getInstance().showError(i18n.tr("Could not delete file"), e); 
164 			return false;
165 		}
166 		return true;
167 	}
168 
169 	static boolean save(final File file, final String filename, final long size) {
170 		Job<?> ioJob = new Job() {
171 			public Object run(ProgressMonitor monitor) throws Exception
172 			{
173 				monitor.setTotalSteps(12);
174 				
175 				HylaFAXClient client = JHylaFAX.getInstance().getConnection(monitor);
176 				monitor.work(1);
177 				
178 				monitor.setText(i18n.tr("Setting mode"));
179 				client.mode(HylaFAXClient.MODE_STREAM);
180 				client.type(HylaFAXClient.TYPE_IMAGE);
181 				monitor.work(1);
182 
183 				monitor.setText(i18n.tr("Downloading file"));
184 				TransferMonitor transferMonitor = new TransferMonitor(monitor, 10, size);
185 				OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
186 				try {
187 					client.addTransferListener(transferMonitor);
188 					client.get(filename, out);
189 				}
190 				finally {
191 					transferMonitor.transferCompleted();
192 					client.removeTransferListener(transferMonitor);
193 					out.close();
194 				}
195 				// check if monitor was cancelled
196 				monitor.work(0);
197 				return null;
198 			}
199 		};
200 		
201 		try {
202 			JHylaFAX.getInstance().runJob(ioJob);
203 		} 
204 		catch (UserAbortException e) {
205 			return false;
206 		}
207 		catch (Exception e) {
208 			logger.debug("Error getting file " + filename, e);
209 			JHylaFAX.getInstance().showError(i18n.tr("Could not download file"), e); 
210 			return false;
211 		}
212 		return true;
213 	}
214 
215 	static void removeJob(final int jobID) {
216 		Job<?> ioJob = new Job() {
217 			public Object run(ProgressMonitor monitor) throws Exception
218 			{
219 				monitor.setTotalSteps(2);
220 				
221 				HylaFAXClient client = JHylaFAX.getInstance().getConnection(monitor);
222 				monitor.work(1);
223 
224 				monitor.setText(i18n.tr("Removing job"));
225 				gnu.hylafax.Job editJob = client.getJob(jobID);
226 				client.kill(editJob);
227 				monitor.work(1);
228 
229 				return null;
230 			}
231 		};
232 		
233 		try {
234 			JHylaFAX.getInstance().runJob(ioJob);
235 			JHylaFAX.getInstance().updateTables();
236 		} 
237 		catch (UserAbortException e) {
238 		} 
239 		catch (Exception e) {
240 			logger.debug("Error killing job", e);
241 			JHylaFAX.getInstance().showError(i18n.tr("Could not remove job"), e); 
242 		}
243 	}
244 
245 	static void suspendJob(final int jobID) {
246 		Job<?> ioJob = new Job() {
247 			public Object run(ProgressMonitor monitor) throws Exception
248 			{
249 				monitor.setTotalSteps(2);
250 				
251 				HylaFAXClient client = JHylaFAX.getInstance().getConnection(monitor);
252 				monitor.work(1);
253 
254 				monitor.setText(i18n.tr("Suspending job"));
255 				gnu.hylafax.Job editJob = client.getJob(jobID);
256 				client.suspend(editJob);
257 				monitor.work(1);
258 
259 				return null;
260 			}
261 		};
262 		
263 		try {
264 			JHylaFAX.getInstance().runJob(ioJob);
265 			JHylaFAX.getInstance().updateTables();
266 		} 
267 		catch (UserAbortException e) {
268 		} 
269 		catch (Exception e) {
270 			logger.debug("Error suspending job", e);
271 			JHylaFAX.getInstance().showError(i18n.tr("Could not suspend job"), e); 
272 		}
273 	}
274 
275 	public static class FileStat {
276 
277 		public String filename;
278 		public long filesize;
279 
280 		public FileStat(String filename, long filesize)
281 		{
282 			this.filename = filename;
283 			this.filesize = filesize;
284 		}
285 		
286 	}
287 
288 	public static StatusResponse updateStatus()
289 	{
290 		Job<StatusResponse> ioJob = new StatusUpdateJob(); 
291 		try {
292 			return JHylaFAX.getInstance().runJob(ioJob);
293 		} 
294 		catch (UserAbortException e) {
295 		} 
296 		catch (Exception e) {
297 			logger.debug("Error updating status", e);
298 			JHylaFAX.getInstance().showError(i18n.tr("Could not get status"), e); 
299 		}
300 		return null;
301 	}
302 
303 	public static class StatusResponse {
304 		String status;
305 		String verboseStatus;
306 		List<ReceivedFax> recvq;
307 		List<FaxJob> sendq;
308 		List<FaxJob> pollq;
309 		List<FaxJob> doneq;
310 		List<Document> docq;
311 	}
312 
313 	public static class StatusUpdateJob implements Job<StatusResponse> {
314 		@SuppressWarnings("unchecked")
315 		public StatusResponse run(ProgressMonitor monitor) throws Exception {				
316 			monitor.setTotalSteps(1 + 1 + 5 /* connection + status + queues*/);
317 			
318 			HylaFAXClient client = JHylaFAX.getInstance().getConnection(monitor);
319 			monitor.work(1);
320 			
321 			StatusResponse response = new StatusResponse();
322 			
323 			monitor.setText(i18n.tr("Getting Status"));
324 			List<String> lines = client.getList("status");
325 			StringBuffer sb = new StringBuffer();
326 			for (Iterator<String> it = lines.iterator(); it.hasNext();) {
327 				String line = it.next();
328 				if (response.status == null) {
329 					response.status = line;
330 				}
331 				sb.append(line + "\n"); 
332 			}
333 			response.verboseStatus = sb.toString();
334 			monitor.work(1);
335 			
336 			client.jobfmt(HylaFAXClientHelper.JOBFMT);
337 			client.rcvfmt(HylaFAXClientHelper.RCVFMT);
338 			client.filefmt(HylaFAXClientHelper.FILEFMT);
339 			
340 			response.recvq = getQueue(monitor, client, "recvq", ReceivedFax.class);
341 			response.sendq = getQueue(monitor, client, "sendq", FaxJob.class);
342 			response.pollq = getQueue(monitor, client, "pollq", FaxJob.class);
343 			response.doneq = getQueue(monitor, client, "doneq", FaxJob.class);
344 			response.docq = getQueue(monitor, client, "docq", Document.class);
345 			
346 			return response;
347 		}				
348 		
349 		@SuppressWarnings("unchecked")
350 		private <T> List<T> getQueue(ProgressMonitor monitor, HylaFAXClient client, String name, Class<T> clazz) 
351 		throws IOException, ServerResponseException {
352 			monitor.setText(i18n.tr("Getting {0}", name));
353 			List<T> result = new ArrayList<T>();
354 			List<String> lines = client.getList(name);
355 			for (String line : lines) {
356 				Object o = HylaFAXClientHelper.parseFmt(line);
357 				if (o != null && clazz.isAssignableFrom(o.getClass())) {
358 					result.add((T)o);
359 				}
360 			}
361 			monitor.work(1);				
362 			return result;
363 		}
364 		
365 	}
366 	
367 }