a69c18785cf51e3e9f498c4e989e4d8013108e8b
[public/netxms.git] / webui / webapp / 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 text.setScrollOnAppend(!scrollLock);
58
59 final SessionListener sessionListener = new SessionListener() {
60 @Override
61 public void notificationHandler(SessionNotification n)
62 {
63 if ((n.getCode() == SessionNotification.FILE_MONITORING_FAILED) && (n.getSubCode() == nodeId))
64 {
65 getDisplay().asyncExec(new Runnable() {
66 public void run()
67 {
68 restartTracking();
69 }
70 });
71 }
72 }
73 };
74 session.addListener(sessionListener);
75
76 addDisposeListener(new DisposeListener() {
77 @Override
78 public void widgetDisposed(DisposeEvent e)
79 {
80 session.removeListener(sessionListener);
81 stopTracking();
82 }
83 });
84 }
85
86 /**
87 * Start file change tracking
88 *
89 * @param nodeId
90 * @param fileId
91 */
92 public void startTracking(final long nodeId, final String fileId, final String remoteFileName)
93 {
94 if (restartJob != null)
95 restartJob.cancel();
96
97 if (monitoringJob != null)
98 monitoringJob.cancel();
99
100 hideMessage();
101
102 this.fileId = fileId;
103 this.nodeId = nodeId;
104 this.remoteFileName = remoteFileName;
105
106 //text.setTopIndex(text.getLineCount() - 1);
107 monitoringJob = new ConsoleJob(Messages.get().DynamicFileViewer_TrackFileChanges, null, Activator.PLUGIN_ID, null) {
108 private boolean tracking = true;
109
110 @Override
111 protected void canceling()
112 {
113 tracking = false;
114 }
115
116 @Override
117 protected void runInternal(IProgressMonitor monitor) throws Exception
118 {
119 while(tracking)
120 {
121 final String s = session.waitForFileTail(fileId, 3000);
122 if (s != null)
123 {
124 runInUIThread(new Runnable() {
125 @Override
126 public void run()
127 {
128 if (!text.isDisposed())
129 {
130 append(s);
131 }
132 else
133 {
134 tracking = false;
135 }
136 }
137 });
138 }
139 }
140 session.cancelFileMonitoring(nodeId, fileId);
141 }
142
143 @Override
144 protected String getErrorMessage()
145 {
146 return Messages.get().DynamicFileViewer_FileTrackingFailed;
147 }
148 };
149 monitoringJob.setUser(false);
150 monitoringJob.setSystem(true);
151 monitoringJob.start();
152 }
153
154 /**
155 * Stop tracking
156 */
157 public void stopTracking()
158 {
159 if (restartJob != null)
160 {
161 restartJob.cancel();
162 restartJob = null;
163 }
164
165 if (monitoringJob != null)
166 {
167 monitoringJob.cancel();
168 monitoringJob = null;
169 fileId = null;
170 nodeId = 0;
171 }
172 }
173
174 /**
175 * Restart tracking after failure
176 */
177 private void restartTracking()
178 {
179 if (monitoringJob != null)
180 {
181 monitoringJob.cancel();
182 monitoringJob = null;
183 }
184
185 if (restartJob != null)
186 restartJob.cancel();
187
188 text.append("\n\n" + //$NON-NLS-1$
189 "----------------------------------------------------------------------\n" + //$NON-NLS-1$
190 Messages.get().FileViewer_NotifyFollowConnectionLost +
191 "\n----------------------------------------------------------------------\n"); //$NON-NLS-1$
192 showMessage(ERROR, Messages.get().FileViewer_NotifyFollowConnectionLost);
193
194 restartJob = new ConsoleJob(Messages.get().DynamicFileViewer_RestartFileTracking, null, Activator.PLUGIN_ID, null) {
195 private boolean running = true;
196
197 @Override
198 protected void canceling()
199 {
200 running = false;
201 }
202
203 @Override
204 protected void runInternal(final IProgressMonitor monitor) throws Exception
205 {
206 // Try to reconnect in every 20 seconds
207 while(running)
208 {
209 try
210 {
211 final AgentFileData file = session.downloadFileFromAgent(nodeId, remoteFileName, 1024, true, new ProgressListener() {
212 @Override
213 public void setTotalWorkAmount(long workTotal)
214 {
215 monitor.beginTask("Download file " + remoteFileName, (int)workTotal);
216 }
217
218 @Override
219 public void markProgress(long workDone)
220 {
221 monitor.worked((int)workDone);
222 }
223 });
224
225 // When successfully connected - display notification to client.
226 runInUIThread(new Runnable() {
227 @Override
228 public void run()
229 {
230 if (text.isDisposed())
231 {
232 running = false;
233 return;
234 }
235
236 hideMessage();
237 text.append("-------------------------------------------------------------------------------\n" + //$NON-NLS-1$
238 Messages.get().FileViewer_NotifyFollowConnectionEnabed +
239 "\n-------------------------------------------------------------------------------\n\n"); //$NON-NLS-1$
240 append(loadFile(file.getFile()));
241 startTracking(nodeId, fileId, remoteFileName);
242 }
243 });
244 break;
245 }
246 catch(Exception e)
247 {
248 }
249 Thread.sleep(20000);
250 }
251
252 }
253
254 @Override
255 protected String getErrorMessage()
256 {
257 return Messages.get().DynamicFileViewer_CannotRestartFileTracking;
258 }
259 };
260 restartJob.setUser(false);
261 restartJob.setSystem(true);
262 restartJob.start();
263 }
264 }