001: package net.sourceforge.tracelog.ui;
002:
003: import java.io.File;
004: import java.util.LinkedList;
005: import java.util.List;
006:
007: import net.sourceforge.tracelog.config.ConfigFile;
008: import net.sourceforge.tracelog.config.ConfigFileFactory;
009: import net.sourceforge.tracelog.config.LogFile;
010: import net.sourceforge.tracelog.config.LogGroup;
011: import net.sourceforge.tracelog.config.UserConfig;
012: import net.sourceforge.tracelog.listeners.GenericListener;
013: import net.sourceforge.tracelog.utils.Util;
014:
015: import org.apache.log4j.Logger;
016: import org.eclipse.swt.SWT;
017: import org.eclipse.swt.events.MouseEvent;
018: import org.eclipse.swt.events.SelectionAdapter;
019: import org.eclipse.swt.events.SelectionEvent;
020: import org.eclipse.swt.graphics.Cursor;
021: import org.eclipse.swt.layout.GridData;
022: import org.eclipse.swt.layout.GridLayout;
023: import org.eclipse.swt.widgets.Button;
024: import org.eclipse.swt.widgets.Combo;
025: import org.eclipse.swt.widgets.Composite;
026: import org.eclipse.swt.widgets.Event;
027: import org.eclipse.swt.widgets.FileDialog;
028: import org.eclipse.swt.widgets.Label;
029: import org.eclipse.swt.widgets.MessageBox;
030: import org.eclipse.swt.widgets.Table;
031: import org.eclipse.swt.widgets.TableColumn;
032: import org.eclipse.swt.widgets.TableItem;
033: import org.eclipse.swt.widgets.Text;
034:
035: public class ShellOptionLogFile extends AbstractWidget {
036: public static final int MAX_LOG_NAME_LENGTH = 15;
037:
038: public static final int MAX_TABLE_ROW = 10;
039: private static final int COLUMN_LOG_FILE_PATH = 2;
040:
041: private static final int COLUMN_LOG_NAME = 1;
042: private static final int COLUMN_NUMBER = 0;
043: private static final int DEFAULT_BACKGROUND_COLOR = SWT.COLOR_WHITE;
044:
045: private static final int DEFAULT_FOREGROUND_COLOR = SWT.COLOR_BLACK;
046: private static final String DEFAULT_VALUE = "[available slot]";
047: private static Logger log = Logger
048: .getLogger(ShellOptionLogFile.class);
049:
050: private static final String[] TABLE_COLUMN_NAMES = { "#",
051: "Log Name", "Log File Path" };
052:
053: private static final int[] TABLE_COLUMN_WIDTHS = { 30, 100, 450 };
054:
055: private Label backgroundColorText;
056: private Button cancelBtn;
057: private Label colorSelection;
058: private ConfigFile configFile;
059: private Button deleteBtn;
060: private Composite entryFieldsComposite;
061: private Label foregroundColorText;
062: private Composite logConfigComposite;
063: private Text logFilePathText;
064: private List<LogFile> logFiles;
065: private Combo logGroupCombo;
066: private Text logNameText;
067: private Button saveBtn;
068:
069: private int selectedLogFileIndex;
070: private Table table;
071: private UserConfig userConfig;
072:
073: /**
074: * Package-access constructor.
075: */
076: ShellOptionLogFile() {
077: super ();
078: this .logFiles = new LinkedList<LogFile>();
079: this .configFile = ConfigFileFactory.getInstance()
080: .getConfigFile();
081: }
082:
083: /**
084: * Returns the color selection.
085: *
086: * @return Color selection.
087: */
088: public Label getColorSelection() {
089: return colorSelection;
090: }
091:
092: /**
093: * Returns log bean list.
094: *
095: * @return Log bean list.
096: */
097: public List<LogFile> getLogFiles() {
098: return logFiles;
099: }
100:
101: /**
102: * Controller to display the log config dialog.
103: */
104: public void run() {
105: this .userConfig = configFile.getUserConfig();
106:
107: logConfigComposite = new Composite(parentComposite, SWT.NONE);
108: logConfigComposite.setLayout(UIUtil.getDefaultGridLayout());
109: logConfigComposite.setLayoutData(UIUtil
110: .getGridDataFillHorizontal());
111:
112: widgetFactory.createLogConfigShellColorChooser(parentShell,
113: logConfigComposite, mediator);
114:
115: UIUtil.createTitle(logConfigComposite, "Log Files");
116:
117: setupInstruction();
118: setupLogGroupDropDownList();
119: setupTable();
120: setupEntryFields();
121: setupButtons();
122:
123: logGroupCombo.notifyListeners(SWT.Selection, null);
124:
125: parentComposite.layout();
126: }
127:
128: private void changeLogGroup() {
129: setupCurrentLogFiles();
130: hideEntryFields();
131: displayTableContent();
132: }
133:
134: private void setupCurrentLogFiles() {
135: logFiles = getSelectedLogGroup().getLogFiles();
136: }
137:
138: /**
139: * Deletes an entry field and updates the table content and the server log
140: * configuration.
141: */
142: private void deleteEntryField() {
143: // trying to delete an available entry
144: if (selectedLogFileIndex < logFiles.size()) {
145: logFiles.remove(selectedLogFileIndex);
146: notifyContentChange();
147: } else {
148: hideEntryFields();
149: }
150:
151: }
152:
153: /**
154: * Prefills the entry field values, and then displays them and the buttons.
155: *
156: * @param foregroundColor
157: * Foreground color.
158: * @param backgroundColor
159: * Background color.
160: * @param logName
161: * Log name.
162: * @param logFilePath
163: * Log file path.
164: */
165: private void displayEntryFields(int foregroundColor,
166: int backgroundColor, String logName, String logFilePath) {
167: foregroundColorText.setBackground(display
168: .getSystemColor(foregroundColor));
169: backgroundColorText.setBackground(display
170: .getSystemColor(backgroundColor));
171:
172: foregroundColorText.setData(foregroundColor);
173: backgroundColorText.setData(backgroundColor);
174: logNameText.setText(logName);
175: logFilePathText.setText(logFilePath);
176:
177: entryFieldsComposite.setVisible(true);
178: saveBtn.setVisible(true);
179: cancelBtn.setVisible(true);
180: deleteBtn.setVisible(true);
181: }
182:
183: /**
184: * Displays the table content.
185: */
186: private void displayTableContent() {
187:
188: for (int i = 0; i < MAX_TABLE_ROW; ++i) {
189: int backgroundColor = DEFAULT_BACKGROUND_COLOR;
190: int foregroundColor = DEFAULT_FOREGROUND_COLOR;
191: String logName = DEFAULT_VALUE;
192: String logFilePath = DEFAULT_VALUE;
193:
194: if (i < logFiles.size()) {
195: LogFile logFile = (LogFile) logFiles.get(i);
196: backgroundColor = logFile.getBackgroundColor();
197: foregroundColor = logFile.getForegroundColor();
198: logName = logFile.getLogName();
199: logFilePath = logFile.getLogPath();
200: }
201:
202: setTableItem(i, foregroundColor, backgroundColor, logName,
203: logFilePath);
204: }
205: }
206:
207: private LogGroup getSelectedLogGroup() {
208: String groupName = logGroupCombo.getItem(logGroupCombo
209: .getSelectionIndex());
210:
211: for (LogGroup logGroup : userConfig.getLogGroups()) {
212: if (logGroup.getGroupName().equals(groupName)) {
213: return logGroup;
214: }
215: }
216:
217: log
218: .error("Should not reached here. Somehow, the selected log group cannot be found.");
219: return null;
220: }
221:
222: /**
223: * Hides the entry fields and the buttons.
224: */
225: private void hideEntryFields() {
226: entryFieldsComposite.setVisible(false);
227:
228: if (saveBtn != null && !saveBtn.isDisposed()) {
229: saveBtn.setVisible(false);
230: }
231:
232: if (cancelBtn != null && !cancelBtn.isDisposed()) {
233: cancelBtn.setVisible(false);
234: }
235:
236: if (deleteBtn != null && !deleteBtn.isDisposed()) {
237: deleteBtn.setVisible(false);
238: }
239: }
240:
241: private void notifyContentChange() {
242: configFile.saveUserConfig(userConfig);
243: mediator.handleEvent(ActionMediator.EVENT_REDRAW_LOG_VIEWERS);
244: table.clearAll();
245: displayTableContent();
246: hideEntryFields();
247: }
248:
249: /**
250: * Performs validation on the entry fields before saving the configuration
251: * permanently.
252: */
253: private void saveConfig() {
254: String msg = "";
255:
256: List<String> existingLogNames = new LinkedList<String>();
257:
258: // get all the existing log names excluding the selected entry
259: for (int i = 0; i < logFiles.size(); ++i) {
260: if (i != selectedLogFileIndex) {
261: existingLogNames.add(logFiles.get(i).getLogName());
262: }
263: }
264:
265: // int rowNum = selectedLogFileIndex + 1;
266: int foregroundColor = (Integer) foregroundColorText.getData();
267: int backgroundColor = (Integer) backgroundColorText.getData();
268: String logName = logNameText.getText();
269: String logFilePath = logFilePathText.getText();
270:
271: // one (or more) field is empty
272: if (Util.isEmpty(logName) || Util.isEmpty(logFilePath)) {
273: msg += Util.LINE_BREAK
274: + "- Log name and log file path must all exist.";
275: }
276: // log name has invalid characters
277: else if (!logName.matches("[A-Za-z0-9_ ]*")) {
278: msg += Util.LINE_BREAK
279: + "- Log name has invalid character(s). Please use only alphanumeric, underscore and space.";
280: }
281: // log name already exists
282: else if (existingLogNames.contains(logName)) {
283: msg += Util.LINE_BREAK
284: + "- Log name already exists. Make sure all log names are unique.";
285: }
286: // file does not exist
287: else if (!new File(logFilePath).exists()) {
288: msg += Util.LINE_BREAK
289: + "- This log file path either does not exist or you do not have sufficient privilege to access it.";
290: }
291: // not a file
292: else if (!new File(logFilePath).isFile()) {
293: msg += Util.LINE_BREAK
294: + "- This log file path does not represent a file.";
295: }
296: // no errors
297: else {
298: LogFile logFile = null;
299: int newTableItemIndex = 0;
300:
301: if (selectedLogFileIndex < logFiles.size()) {
302: newTableItemIndex = selectedLogFileIndex;
303: logFile = logFiles.get(selectedLogFileIndex);
304: logFile.setBackgroundColor(backgroundColor);
305: logFile.setForegroundColor(foregroundColor);
306: logFile.setLogName(logName);
307: logFile.setLogPath(logFilePath);
308: } else {
309: newTableItemIndex = logFiles.size();
310: logFile = new LogFile(newTableItemIndex + 1, logName,
311: logFilePath, foregroundColor, backgroundColor);
312: logFiles.add(logFile);
313: }
314:
315: notifyContentChange();
316:
317: return;
318: }
319:
320: // will reach here if there is error
321: MessageBox mb = new MessageBox(parentShell, SWT.OK
322: | SWT.ICON_ERROR);
323: mb.setText("Log Files Dialog");
324: mb.setMessage("Please fix the following error(s):"
325: + Util.LINE_BREAK + msg);
326: mb.open();
327: }
328:
329: /**
330: * Sets up a table item.
331: *
332: * @param tableItemIndex
333: * Position of the table item.
334: * @param foregroundColor
335: * Foreground color.
336: * @param backgroundColor
337: * Background color.
338: * @param logName
339: * Log name.
340: * @param logFilePath
341: * Log file path.
342: */
343: private void setTableItem(int tableItemIndex, int foregroundColor,
344: int backgroundColor, String logName, String logFilePath) {
345: TableItem tableItem = null;
346:
347: if (tableItemIndex < table.getItemCount()) {
348: tableItem = table.getItem(tableItemIndex);
349: } else {
350: tableItem = new TableItem(table, SWT.NONE);
351: }
352:
353: tableItem.setText(COLUMN_NUMBER, String
354: .valueOf(tableItemIndex + 1)
355: + ".");
356: tableItem.setText(COLUMN_LOG_NAME, logName);
357: tableItem.setText(COLUMN_LOG_FILE_PATH, logFilePath);
358: tableItem
359: .setForeground(display.getSystemColor(foregroundColor));
360: tableItem
361: .setBackground(display.getSystemColor(backgroundColor));
362:
363: LogFile logFile = new LogFile(tableItemIndex, logName,
364: logFilePath, foregroundColor, backgroundColor);
365: tableItem.setData(logFile);
366: }
367:
368: /**
369: * Sets up action buttons: save, cancel, delete and close.
370: */
371: private void setupButtons() {
372: Composite c = new Composite(logConfigComposite, SWT.NONE);
373: c.setLayout(new GridLayout(5, true));
374: c.setLayoutData(UIUtil.getGridDataFillHorizontal());
375:
376: Label label = new Label(c, SWT.NONE);
377: label.setLayoutData(UIUtil.getGridDataFillHorizontalSpan(2));
378:
379: saveBtn = new Button(c, SWT.PUSH);
380: saveBtn.setText("Save");
381: saveBtn.setVisible(false);
382: saveBtn.setLayoutData(UIUtil.getGridDataFillHorizontal());
383:
384: saveBtn.addMouseListener(new GenericListener() {
385: public void mouseUp(MouseEvent e) {
386: saveConfig();
387: }
388: });
389:
390: cancelBtn = new Button(c, SWT.PUSH);
391: cancelBtn.setText("Cancel");
392: cancelBtn.setVisible(false);
393: cancelBtn.setLayoutData(UIUtil.getGridDataFillHorizontal());
394:
395: cancelBtn.addMouseListener(new GenericListener() {
396: public void mouseUp(MouseEvent e) {
397: hideEntryFields();
398: }
399: });
400:
401: deleteBtn = new Button(c, SWT.PUSH);
402: deleteBtn.setText("Delete");
403: deleteBtn.setVisible(false);
404: deleteBtn.setLayoutData(UIUtil.getGridDataFillHorizontal());
405:
406: deleteBtn.addMouseListener(new GenericListener() {
407: public void mouseUp(MouseEvent e) {
408: deleteEntryField();
409: }
410: });
411: }
412:
413: /**
414: * Sets up the entry fields for configuring the logs. These entry fields are
415: * by default hidden until a log is selected from the table.
416: */
417: private void setupEntryFields() {
418: entryFieldsComposite = new Composite(logConfigComposite,
419: SWT.NONE);
420: GridLayout gridLayout = new GridLayout(5, true);
421: entryFieldsComposite.setLayout(gridLayout);
422: entryFieldsComposite.setLayoutData(UIUtil
423: .getGridDataFillHorizontal());
424:
425: GridData span3Cells = UIUtil.getGridDataFillHorizontalSpan(3);
426:
427: // foreground color
428: setupLeftEntryField(entryFieldsComposite, "Foreground Color");
429:
430: foregroundColorText = new Label(entryFieldsComposite,
431: SWT.BORDER | SWT.READ_ONLY);
432: foregroundColorText.setCursor(UIUtil.getCursorHand());
433: foregroundColorText.setLayoutData(new GridData(
434: GridData.FILL_HORIZONTAL));
435:
436: foregroundColorText.addMouseListener(new GenericListener() {
437: public void mouseUp(MouseEvent e) {
438: colorSelection = foregroundColorText;
439: mediator
440: .handleEvent(ActionMediator.EVENT_DISPLAY_COLOR_CHOOSER);
441: }
442: });
443:
444: Label pad = new Label(entryFieldsComposite, SWT.NONE);
445: pad.setLayoutData(span3Cells);
446:
447: // background color
448: setupLeftEntryField(entryFieldsComposite, "Background Color");
449:
450: backgroundColorText = new Label(entryFieldsComposite,
451: SWT.BORDER | SWT.READ_ONLY);
452: backgroundColorText.setCursor(UIUtil.getCursorHand());
453: backgroundColorText.setLayoutData(UIUtil
454: .getGridDataFillHorizontal());
455:
456: backgroundColorText.addMouseListener(new GenericListener() {
457: public void mouseUp(MouseEvent e) {
458: colorSelection = backgroundColorText;
459: mediator
460: .handleEvent(ActionMediator.EVENT_DISPLAY_COLOR_CHOOSER);
461: }
462: });
463:
464: pad = new Label(entryFieldsComposite, SWT.NONE);
465: pad.setLayoutData(span3Cells);
466:
467: // log name
468: setupLeftEntryField(entryFieldsComposite, "Log Name");
469:
470: logNameText = new Text(entryFieldsComposite, SWT.BORDER);
471: logNameText.setBackground(display
472: .getSystemColor(SWT.COLOR_WHITE));
473: logNameText.setLayoutData(UIUtil.getGridDataFillHorizontal());
474: logNameText.setTextLimit(MAX_LOG_NAME_LENGTH);
475:
476: pad = new Label(entryFieldsComposite, SWT.NONE);
477: pad.setLayoutData(span3Cells);
478:
479: // log file path
480: setupLeftEntryField(entryFieldsComposite, "Log File Path");
481:
482: logFilePathText = new Text(entryFieldsComposite, SWT.BORDER);
483: logFilePathText.setBackground(display
484: .getSystemColor(SWT.COLOR_WHITE));
485: logFilePathText.setLayoutData(span3Cells);
486:
487: Button logFilePathButton = new Button(entryFieldsComposite,
488: SWT.PUSH);
489: logFilePathButton.setText("Browse...");
490: logFilePathButton.setCursor(UIUtil.getCursorHand());
491: logFilePathButton.setLayoutData(UIUtil
492: .getGridDataFillHorizontal());
493:
494: logFilePathButton.addMouseListener(new GenericListener() {
495: public void mouseUp(MouseEvent e) {
496: FileDialog fileDialog = new FileDialog(parentShell,
497: SWT.OPEN);
498: String fileName = fileDialog.open();
499: if (fileName == null) {
500: fileName = "";
501: }
502:
503: logFilePathText.setText(fileName);
504: }
505: });
506:
507: hideEntryFields();
508: }
509:
510: /**
511: * Displays the instruction label.
512: */
513: private void setupInstruction() {
514: Label label = new Label(logConfigComposite, SWT.WRAP);
515: label.setLayoutData(UIUtil.getGridDataFillHorizontal());
516:
517: String msg = "The log file represents the file you wish monitor at real-time. Every log file must be associated with a log group. "
518: + "You can attach up to "
519: + MAX_TABLE_ROW
520: + " log files to each log group. "
521: + "Please ensure you have sufficient privilege to access these log files."
522: + Util.LINE_BREAK + Util.LINE_BREAK;
523:
524: label.setText(msg);
525: }
526:
527: /**
528: * Displays a right aligned label.
529: *
530: * @param composite
531: * Composite parent.
532: * @param value
533: * Label value.
534: */
535: private void setupLeftEntryField(Composite composite, String value) {
536: Label label = new Label(composite, SWT.NONE);
537: label.setLayoutData(UIUtil.getGridDataFillHorizontal());
538: label.setAlignment(SWT.RIGHT);
539: label.setText(value + " : ");
540: }
541:
542: private void setupLogGroupDropDownList() {
543: Composite c = new Composite(logConfigComposite, SWT.NONE);
544: c.setLayout(new GridLayout(5, true));
545: c.setLayoutData(UIUtil.getGridDataFillHorizontal());
546:
547: // foreground color
548: setupLeftEntryField(c, "Log Group");
549:
550: logGroupCombo = new Combo(c, SWT.READ_ONLY);
551:
552: List<LogGroup> logGroups = userConfig.getLogGroups();
553: String[] groupNames = new String[logGroups.size()];
554: for (int i = 0; i < logGroups.size(); ++i) {
555: groupNames[i] = logGroups.get(i).getGroupName();
556: }
557:
558: logGroupCombo.setItems(groupNames);
559: logGroupCombo.select(0);
560: logGroupCombo.setLayoutData(UIUtil.getGridDataFillHorizontal());
561: logGroupCombo.addSelectionListener(new SelectionAdapter() {
562: public void widgetSelected(SelectionEvent e) {
563: changeLogGroup();
564: }
565: });
566:
567: }
568:
569: /**
570: * Sets up the contents in the table.
571: */
572: private void setupTable() {
573:
574: table = new Table(logConfigComposite, SWT.BORDER
575: | SWT.FULL_SELECTION);
576: table.setLayoutData(UIUtil.getGridDataFillHorizontal());
577: table.setLinesVisible(true);
578: table.setHeaderVisible(true);
579: table.setCursor(new Cursor(display, SWT.CURSOR_HAND));
580: table.addListener(SWT.Selection, new GenericListener() {
581: public void handleEvent(Event event) {
582: TableItem tableItem = (TableItem) event.item;
583: LogFile logFile = (LogFile) tableItem.getData();
584:
585: selectedLogFileIndex = logFile.getLogOrder();
586: int foregroundColor = logFile.getForegroundColor();
587: int backgroundColor = logFile.getBackgroundColor();
588: String logName = logFile.getLogName();
589: String logFilePath = logFile.getLogPath();
590:
591: displayEntryFields(foregroundColor, backgroundColor,
592: logName, logFilePath);
593:
594: }
595: });
596:
597: for (int i = 0; i < TABLE_COLUMN_NAMES.length; ++i) {
598: final TableColumn column = new TableColumn(table, SWT.LEFT);
599: column.setText(TABLE_COLUMN_NAMES[i]);
600: column.setWidth(TABLE_COLUMN_WIDTHS[i]);
601: }
602:
603: displayTableContent();
604: }
605: }
|