7bd9be6ded5c2c233103404fe3bea197f3cb9f07
[public/netxms.git] / webui / webapp / NXSL / src / org / netxms / ui / eclipse / nxsl / views / ScriptEditorView.java
1 /**
2 * NetXMS - open source network management system
3 * Copyright (C) 2003-2015 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.nxsl.views;
20
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.jface.action.Action;
23 import org.eclipse.jface.action.IMenuManager;
24 import org.eclipse.jface.action.IToolBarManager;
25 import org.eclipse.jface.action.Separator;
26 import org.eclipse.jface.dialogs.IDialogSettings;
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.events.ModifyEvent;
29 import org.eclipse.swt.events.ModifyListener;
30 import org.eclipse.swt.layout.FillLayout;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.ui.IActionBars;
33 import org.eclipse.ui.ISaveablePart;
34 import org.eclipse.ui.IViewSite;
35 import org.eclipse.ui.PartInitException;
36 import org.eclipse.ui.commands.ActionHandler;
37 import org.eclipse.ui.contexts.IContextService;
38 import org.eclipse.ui.handlers.IHandlerService;
39 import org.eclipse.ui.part.ViewPart;
40 import org.netxms.client.NXCSession;
41 import org.netxms.client.Script;
42 import org.netxms.client.ScriptCompilationResult;
43 import org.netxms.ui.eclipse.actions.RefreshAction;
44 import org.netxms.ui.eclipse.console.resources.SharedIcons;
45 import org.netxms.ui.eclipse.jobs.ConsoleJob;
46 import org.netxms.ui.eclipse.nxsl.Activator;
47 import org.netxms.ui.eclipse.nxsl.Messages;
48 import org.netxms.ui.eclipse.nxsl.widgets.ScriptEditor;
49 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
50 import org.netxms.ui.eclipse.tools.MessageDialogHelper;
51 import org.netxms.ui.eclipse.widgets.CompositeWithMessageBar;
52
53 /**
54 * Script editor view
55 */
56 @SuppressWarnings("deprecation")
57 public class ScriptEditorView extends ViewPart implements ISaveablePart
58 {
59 public static final String ID = "org.netxms.ui.eclipse.nxsl.views.ScriptEditorView"; //$NON-NLS-1$
60
61 private NXCSession session;
62 private CompositeWithMessageBar editorMessageBar;
63 private ScriptEditor editor;
64 private long scriptId;
65 private String scriptName;
66 private Action actionRefresh;
67 private Action actionSave;
68 private Action actionCompile;
69 private boolean modified = false;
70 private boolean showLineNumbers = true;
71
72 /* (non-Javadoc)
73 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
74 */
75 @Override
76 public void init(IViewSite site) throws PartInitException
77 {
78 super.init(site);
79
80 session = ConsoleSharedData.getSession();
81 scriptId = Long.parseLong(site.getSecondaryId());
82
83 IDialogSettings settings = Activator.getDefault().getDialogSettings();
84 if (settings.get("ScriptEditor.showLineNumbers") != null)
85 showLineNumbers = settings.getBoolean("ScriptEditor.showLineNumbers");
86 }
87
88 /* (non-Javadoc)
89 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
90 */
91 @Override
92 public void createPartControl(Composite parent)
93 {
94 parent.setLayout(new FillLayout());
95
96 editorMessageBar = new CompositeWithMessageBar(parent, SWT.NONE);
97 editor = new ScriptEditor(editorMessageBar, SWT.NONE, SWT.H_SCROLL | SWT.V_SCROLL, showLineNumbers);
98 editorMessageBar.setContent(editor);
99 editor.getTextWidget().addModifyListener(new ModifyListener() {
100 @Override
101 public void modifyText(ModifyEvent e)
102 {
103 if (!modified)
104 {
105 modified = true;
106 firePropertyChange(PROP_DIRTY);
107 actionSave.setEnabled(true);
108 }
109 }
110 });
111
112 activateContext();
113 createActions();
114 contributeToActionBars();
115 //createPopupMenu();
116
117 reloadScript();
118 }
119
120 /**
121 * Activate context
122 */
123 private void activateContext()
124 {
125 IContextService contextService = (IContextService)getSite().getService(IContextService.class);
126 if (contextService != null)
127 {
128 contextService.activateContext("org.netxms.ui.eclipse.nxsl.context.ScriptEditor"); //$NON-NLS-1$
129 }
130 }
131
132 /* (non-Javadoc)
133 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
134 */
135 @Override
136 public void setFocus()
137 {
138 editor.setFocus();
139 }
140
141 /**
142 * Create actions
143 */
144 private void createActions()
145 {
146 final IHandlerService handlerService = (IHandlerService)getSite().getService(IHandlerService.class);
147
148 actionRefresh = new RefreshAction(this) {
149 @Override
150 public void run()
151 {
152 reloadScript();
153 }
154 };
155
156 actionSave = new Action(Messages.get().ScriptEditorView_Save, SharedIcons.SAVE) {
157 @Override
158 public void run()
159 {
160 saveScript();
161 }
162 };
163 actionSave.setActionDefinitionId("org.netxms.ui.eclipse.nxsl.commands.save"); //$NON-NLS-1$
164 handlerService.activateHandler(actionSave.getActionDefinitionId(), new ActionHandler(actionSave));
165
166 actionCompile = new Action("&Compile", Activator.getImageDescriptor("icons/compile.gif")) {
167 @Override
168 public void run()
169 {
170 compileScript();
171 }
172 };
173 actionCompile.setActionDefinitionId("org.netxms.ui.eclipse.nxsl.commands.compile"); //$NON-NLS-1$
174 handlerService.activateHandler(actionCompile.getActionDefinitionId(), new ActionHandler(actionCompile));
175 }
176
177 /**
178 * Contribute actions to action bar
179 */
180 private void contributeToActionBars()
181 {
182 IActionBars bars = getViewSite().getActionBars();
183 fillLocalPullDown(bars.getMenuManager());
184 fillLocalToolBar(bars.getToolBarManager());
185 }
186
187 /**
188 * Fill local pull-down menu
189 *
190 * @param manager
191 * Menu manager for pull-down menu
192 */
193 private void fillLocalPullDown(IMenuManager manager)
194 {
195 manager.add(actionCompile);
196 manager.add(actionSave);
197 manager.add(new Separator());
198 manager.add(actionRefresh);
199 }
200
201 /**
202 * Fill local tool bar
203 *
204 * @param manager
205 * Menu manager for local toolbar
206 */
207 private void fillLocalToolBar(IToolBarManager manager)
208 {
209 manager.add(actionCompile);
210 manager.add(actionSave);
211 manager.add(new Separator());
212 manager.add(actionRefresh);
213 }
214
215 /**
216 * Reload script from server
217 */
218 private void reloadScript()
219 {
220 new ConsoleJob(String.format(Messages.get().ScriptEditorView_LoadJobTitle, scriptId), this, Activator.PLUGIN_ID, null) {
221 @Override
222 protected String getErrorMessage()
223 {
224 return String.format(Messages.get().ScriptEditorView_LoadJobError, scriptId);
225 }
226
227 @Override
228 protected void runInternal(IProgressMonitor monitor) throws Exception
229 {
230 final Script script = session.getScript(scriptId);
231 runInUIThread(new Runnable() {
232 @Override
233 public void run()
234 {
235 scriptName = script.getName();
236 setPartName(String.format(Messages.get().ScriptEditorView_PartName, scriptName));
237 editor.setText(script.getSource());
238 actionSave.setEnabled(false);
239 modified = false;
240 firePropertyChange(PROP_DIRTY);
241 }
242 });
243 }
244 }.start();
245 }
246
247 /**
248 * Compile script
249 */
250 private void compileScript()
251 {
252 final String source = editor.getText();
253 editor.getTextWidget().setEditable(false);
254 new ConsoleJob("Compile script", this, Activator.PLUGIN_ID, null) {
255 @Override
256 protected String getErrorMessage()
257 {
258 return "Cannot compile script";
259 }
260
261 @Override
262 protected void runInternal(IProgressMonitor monitor) throws Exception
263 {
264 final ScriptCompilationResult result = session.compileScript(source, false);
265 runInUIThread(new Runnable() {
266 @Override
267 public void run()
268 {
269 if (result.success)
270 {
271 editorMessageBar.showMessage(CompositeWithMessageBar.INFORMATION, "Script compiled successfully");
272 }
273 else
274 {
275 editorMessageBar.showMessage(CompositeWithMessageBar.WARNING, result.errorMessage);
276 }
277 editor.getTextWidget().setEditable(true);
278 }
279 });
280 }
281 }.start();
282 }
283
284 /**
285 * Save script
286 */
287 private void saveScript()
288 {
289 final String source = editor.getText();
290 editor.getTextWidget().setEditable(false);
291 new ConsoleJob(Messages.get().ScriptEditorView_SaveJobTitle, this, Activator.PLUGIN_ID, null) {
292 @Override
293 protected String getErrorMessage()
294 {
295 return Messages.get().ScriptEditorView_SaveJobError;
296 }
297
298 @Override
299 protected void runInternal(IProgressMonitor monitor) throws Exception
300 {
301 final ScriptCompilationResult result = session.compileScript(source, false);
302 if (result.success)
303 {
304 getDisplay().syncExec(new Runnable() {
305 @Override
306 public void run()
307 {
308 editorMessageBar.hideMessage();
309 }
310 });
311 }
312 else
313 {
314 getDisplay().syncExec(new Runnable() {
315 @Override
316 public void run()
317 {
318 if (MessageDialogHelper.openQuestion(getSite().getShell(), "Compilation Errors",
319 String.format("Script compilation failed (%s)\r\nSave changes anyway?", result.errorMessage)))
320 result.success = true;
321 editorMessageBar.showMessage(CompositeWithMessageBar.WARNING, result.errorMessage);
322 }
323 });
324 }
325 if (result.success)
326 {
327 doScriptSave(source, monitor);
328 }
329 else
330 {
331 runInUIThread(new Runnable() {
332 @Override
333 public void run()
334 {
335 editor.getTextWidget().setEditable(true);
336 }
337 });
338 }
339 }
340 }.start();
341 }
342
343 /**
344 * Do actual script save
345 *
346 * @param source
347 * @param monitor
348 * @throws Exception
349 */
350 private void doScriptSave(String source, IProgressMonitor monitor) throws Exception
351 {
352 session.modifyScript(scriptId, scriptName, source);
353 editor.getDisplay().asyncExec(new Runnable() {
354 @Override
355 public void run()
356 {
357 if (editor.isDisposed())
358 return;
359
360 editor.getTextWidget().setEditable(true);
361 actionSave.setEnabled(false);
362 modified = false;
363 firePropertyChange(PROP_DIRTY);
364 }
365 });
366 }
367
368 /* (non-Javadoc)
369 * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
370 */
371 @SuppressWarnings("rawtypes")
372 @Override
373 public Object getAdapter(Class adapter)
374 {
375 Object object = super.getAdapter(adapter);
376 if (object != null)
377 {
378 return object;
379 }
380 return null;
381 }
382
383 /* (non-Javadoc)
384 * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
385 */
386 @Override
387 public void doSave(IProgressMonitor monitor)
388 {
389 final String source = editor.getText();
390 editor.getTextWidget().setEditable(false);
391 try
392 {
393 doScriptSave(source, monitor);
394 }
395 catch(Exception e)
396 {
397 MessageDialogHelper.openError(getViewSite().getShell(), Messages.get().ScriptEditorView_Error, String.format(Messages.get().ScriptEditorView_SaveErrorMessage, e.getMessage()));
398 }
399 }
400
401 /* (non-Javadoc)
402 * @see org.eclipse.ui.ISaveablePart#doSaveAs()
403 */
404 @Override
405 public void doSaveAs()
406 {
407 }
408
409 /* (non-Javadoc)
410 * @see org.eclipse.ui.ISaveablePart#isDirty()
411 */
412 @Override
413 public boolean isDirty()
414 {
415 return modified;
416 }
417
418 /* (non-Javadoc)
419 * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
420 */
421 @Override
422 public boolean isSaveAsAllowed()
423 {
424 return false;
425 }
426
427 /* (non-Javadoc)
428 * @see org.eclipse.ui.ISaveablePart#isSaveOnCloseNeeded()
429 */
430 @Override
431 public boolean isSaveOnCloseNeeded()
432 {
433 return modified;
434 }
435
436 /* (non-Javadoc)
437 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
438 */
439 @Override
440 public void dispose()
441 {
442 IDialogSettings settings = Activator.getDefault().getDialogSettings();
443 settings.put("ScriptEditor.showLineNumbers", showLineNumbers);
444 super.dispose();
445 }
446 }