3f63969f1213671b13cef792d2376e21831d1358
[public/netxms.git] / src / java / netxms-eclipse / FileManager / src / org / netxms / ui / eclipse / filemanager / widgets / DynamicFileViewer.java
1 /**
2 * NetXMS - open source network management system
3 * Copyright (C) 2003-2016 Victor Kirhenshtein
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 package org.netxms.ui.eclipse.filemanager.widgets;
20
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.swt.events.DisposeEvent;
23 import org.eclipse.swt.events.DisposeListener;
24 import org.eclipse.swt.widgets.Composite;
25 import org.eclipse.ui.IViewPart;
26 import org.netxms.client.AgentFileData;
27 import org.netxms.client.NXCSession;
28 import org.netxms.client.ProgressListener;
29 import org.netxms.client.SessionListener;
30 import org.netxms.client.SessionNotification;
31 import org.netxms.ui.eclipse.filemanager.Activator;
32 import org.netxms.ui.eclipse.filemanager.Messages;
33 import org.netxms.ui.eclipse.jobs.ConsoleJob;
34 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
35
36 /**
37 * Dynamic file viewer - follows file changes
38 */
39 public class DynamicFileViewer extends BaseFileViewer
40 {
41 protected ConsoleJob monitoringJob = null;
42 protected ConsoleJob restartJob = null;
43 protected String fileId = null;
44 protected long nodeId = 0;
45 protected String remoteFileName;
46 protected NXCSession session = ConsoleSharedData.getSession();
47
48 /**
49 * @param parent
50 * @param style
51 * @param viewPart
52 */
53 public DynamicFileViewer(Composite parent, int style, IViewPart viewPart)
54 {
55 super(parent, style, viewPart);
56
57 final SessionListener sessionListener = new SessionListener() {
58 @Override
59 public void notificationHandler(SessionNotification n)
60 {
61 if ((n.getCode() == SessionNotification.FILE_MONITORING_FAILED) && (n.getSubCode() == nodeId))
62 {
63 getDisplay().asyncExec(new Runnable() {
64 public void run()
65 {
66 restartTracking();
67 }
68 });
69 }
70 }
71 };
72 session.addListener(sessionListener);
73
74 addDisposeListener(new DisposeListener() {
75 @Override
76 public void widgetDisposed(DisposeEvent e)
77 {
78 session.removeListener(sessionListener);
79 stopTracking();
80 }
81 });
82 }
83
84 /**
85 * Start file change tracking
86 *
87 * @param nodeId
88 * @param fileId
89 */
90 public void startTracking(final long nodeId, final String fileId, final String remoteFileName)
91 {
92 if (restartJob != null)
93 restartJob.cancel();
94
95 if (monitoringJob != null)
96 monitoringJob.cancel();
97
98 hideMessage();
99
100 this.fileId = fileId;
101 this.nodeId = nodeId;
102 this.remoteFileName = remoteFileName;
103
104 text.setTopIndex(text.getLineCount() - 1);
105 monitoringJob = new ConsoleJob(Messages.get().DynamicFileViewer_TrackFileChanges, null, Activator.PLUGIN_ID, null) {
106 private boolean tracking = true;
107
108 @Override
109 protected void canceling()
110 {
111 tracking = false;
112 }
113
114 @Override
115 protected void runInternal(IProgressMonitor monitor) throws Exception
116 {
117 while(tracking)
118 {
119 final String s = session.waitForFileTail(fileId, 3000);
120 if (s != null)
121 {
122 runInUIThread(new Runnable() {
123 @Override
124 public void run()
125 {
126 if (!text.isDisposed())
127 {
128 append(s);
129 }
130 else
131 {
132 tracking = false;
133 }
134 }
135 });
136 }
137 }
138 session.cancelFileMonitoring(nodeId, fileId);
139 }
140
141 @Override
142 protected String getErrorMessage()
143 {
144 return Messages.get().DynamicFileViewer_FileTrackingFailed;
145 }
146 };
147 monitoringJob.setUser(false);
148 monitoringJob.setSystem(true);
149 monitoringJob.start();
150 }
151
152 /**
153 * Stop tracking
154 */
155 public void stopTracking()
156 {
157 if (restartJob != null)
158 {
159 restartJob.cancel();
160 restartJob = null;
161 }
162
163 if (monitoringJob != null)
164 {
165 monitoringJob.cancel();
166 monitoringJob = null;
167 fileId = null;
168 nodeId = 0;
169 }
170 }
171
172 /**
173 * Restart tracking after failure
174 */
175 private void restartTracking()
176 {
177 if (monitoringJob != null)
178 {
179 monitoringJob.cancel();
180 monitoringJob = null;
181 }
182
183 if (restartJob != null)
184 restartJob.cancel();
185
186 text.append("\n\n" + //$NON-NLS-1$
187 "----------------------------------------------------------------------\n" + //$NON-NLS-1$
188 Messages.get().FileViewer_NotifyFollowConnectionLost +
189 "\n----------------------------------------------------------------------\n"); //$NON-NLS-1$
190 showMessage(ERROR, Messages.get().FileViewer_NotifyFollowConnectionLost);
191
192 restartJob = new ConsoleJob(Messages.get().DynamicFileViewer_RestartFileTracking, null, Activator.PLUGIN_ID, null) {
193 private boolean running = true;
194
195 @Override
196 protected void canceling()
197 {
198 running = false;
199 }
200
201 @Override
202 protected void runInternal(final IProgressMonitor monitor) throws Exception
203 {
204 // Try to reconnect in every 20 seconds
205 while(running)
206 {
207 try
208 {
209 final AgentFileData file = session.downloadFileFromAgent(nodeId, remoteFileName, 1024, true, new ProgressListener() {
210 @Override
211 public void setTotalWorkAmount(long workTotal)
212 {
213 monitor.beginTask("Track file " + remoteFileName, (int)workTotal);
214 }
215
216 @Override
217 public void markProgress(long workDone)
218 {
219 monitor.worked((int)workDone);
220 }
221 });
222
223 // When successfully connected - display notification to client.
224 runInUIThread(new Runnable() {
225 @Override
226 public void run()
227 {
228 if (text.isDisposed())
229 {
230 running = false;
231 return;
232 }
233
234 hideMessage();
235 text.append("-------------------------------------------------------------------------------\n" + //$NON-NLS-1$
236 Messages.get().FileViewer_NotifyFollowConnectionEnabed +
237 "\n-------------------------------------------------------------------------------\n\n"); //$NON-NLS-1$
238 append(loadFile(file.getFile()));
239 startTracking(nodeId, fileId, remoteFileName);
240 }
241 });
242 break;
243 }
244 catch(Exception e)
245 {
246 }
247 Thread.sleep(20000);
248 }
249
250 }
251
252 @Override
253 protected String getErrorMessage()
254 {
255 return Messages.get().DynamicFileViewer_CannotRestartFileTracking;
256 }
257 };
258 restartJob.setUser(false);
259 restartJob.setSystem(true);
260 restartJob.start();
261 }
262 }