Package net.sf.logsaw.ui.dialogs

Source Code of net.sf.logsaw.ui.dialogs.FilterSettingsDialog

/*******************************************************************************
* Copyright (c) 2010, 2011 LogSaw project and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    LogSaw project committers - initial API and implementation
*******************************************************************************/
package net.sf.logsaw.ui.dialogs;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import net.sf.logsaw.core.CorePlugin;
import net.sf.logsaw.core.config.model.StringConfigOption;
import net.sf.logsaw.core.field.ALogEntryField;
import net.sf.logsaw.core.field.ILogEntryFieldVisitor;
import net.sf.logsaw.core.field.Level;
import net.sf.logsaw.core.field.model.DateLogEntryField;
import net.sf.logsaw.core.field.model.LevelLogEntryField;
import net.sf.logsaw.core.field.model.StringLogEntryField;
import net.sf.logsaw.core.logresource.ILogResource;
import net.sf.logsaw.core.query.IRestrictionFactory;
import net.sf.logsaw.core.query.IRestrictionVisitor;
import net.sf.logsaw.core.query.Operator;
import net.sf.logsaw.core.query.Operators;
import net.sf.logsaw.core.query.model.DateRestriction;
import net.sf.logsaw.core.query.model.LevelRestriction;
import net.sf.logsaw.core.query.model.StringRestriction;
import net.sf.logsaw.core.query.support.ARestriction;
import net.sf.logsaw.ui.IHelpContexts;
import net.sf.logsaw.ui.Messages;
import net.sf.logsaw.ui.UIPlugin;
import net.sf.logsaw.ui.model.NamedFilter;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;

/**
* @author Philipp Nanz
*/
public class FilterSettingsDialog extends TitleAreaDialog {

  private static final String ELEM_ROOT = "namedFilters"; //$NON-NLS-1$
  private static final String ELEM_FILTER = "filter"; //$NON-NLS-1$
  private static final String ATTRIB_NAME = "name"; //$NON-NLS-1$
  private static final String ELEM_CLAUSE = "clause"; //$NON-NLS-1$
  private static final String ATTRIB_FIELD = "field"; //$NON-NLS-1$
  private static final String ATTRIB_OPERATOR = "operator"; //$NON-NLS-1$
  private static final StringConfigOption OPTION_NAMED_FILTERS =
    new StringConfigOption("namedFilters", "Named Filters", false); //$NON-NLS-1$ //$NON-NLS-2$

  private boolean focusLast;
  private List<FilterClauseComposite> clauses = new ArrayList<FilterClauseComposite>();
  private List<ARestriction<?>> restrictions;
  private Set<NamedFilter> namedFilters;
  private ILogResource log;
  private ComboViewer namedFiltersViewer;
  private Button saveButton;
  private Button deleteButton;
  private Button clearButton;
  private ScrolledComposite scrolledComposite;
  private Composite buttonComposite;
  private Composite rootComposite;

  /**
   * Constructor.
   *
   * @param parentShell the parent shell
   * @param log the log resource
   * @param restrictions the restrictions to restore
   * @param focusLast whether to focus the last entry
   */
  public FilterSettingsDialog(Shell parentShell, ILogResource log,
      List<ARestriction<?>> restrictions, boolean focusLast) {
    super(parentShell);
    Assert.isNotNull(log, "log"); //$NON-NLS-1$
    Assert.isNotNull(restrictions, "restrictions"); //$NON-NLS-1$
    this.focusLast = focusLast;
    this.log = log;
    this.restrictions = restrictions;
    try {
      init();
    } catch (CoreException e) {
      // Log and show error
      UIPlugin.logAndShowError(e, true);
    }
  }

  /* (non-Javadoc)
   * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
   */
  @Override
  protected Control createDialogArea(Composite parent) {
    Composite parentComposite = (Composite) super.createDialogArea(parent);
   
    Composite namedFilterComposite = new Composite(parentComposite, SWT.NONE);
    namedFilterComposite.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
    namedFilterComposite.setLayout(new GridLayout());
    Group group = new Group(namedFilterComposite, SWT.NONE);
    group.setText(Messages.FilterSettingsDialog_label_saveLoad);
    group.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
    group.setLayout(new GridLayout(4, false));
    Label label = new Label(group, SWT.NONE);
    label.setText(Messages.FilterSettingsDialog_label_filterName);
    namedFiltersViewer = new ComboViewer(group, SWT.BORDER);
    namedFiltersViewer.getCombo().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    namedFiltersViewer.setContentProvider(new ArrayContentProvider());
    namedFiltersViewer.setLabelProvider(new LabelProvider() {
      /* (non-Javadoc)
       * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
       */
      @Override
      public String getText(Object element) {
        NamedFilter flt = (NamedFilter) element;
        return flt.getName();
      }
    });
    namedFiltersViewer.setInput(namedFilters.toArray());
    namedFiltersViewer.setComparator(new ViewerComparator());
    namedFiltersViewer.addSelectionChangedListener(new ISelectionChangedListener() {
      /* (non-Javadoc)
       * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
       */
      @Override
      public void selectionChanged(SelectionChangedEvent e) {
        IStructuredSelection sel = (IStructuredSelection) e.getSelection();
        NamedFilter flt = (NamedFilter) sel.getFirstElement();
        if (flt != null) {
          // Delete button is only enabled when a fresh filter is selected
          deleteButton.setEnabled(true);
          clearContents();
          // Set restrictions to load
          restrictions = new ArrayList<ARestriction<?>>(flt.getRestrictions());
          updateContents(false);
        }
      }
    });
    namedFiltersViewer.getCombo().addModifyListener(new ModifyListener() {
      /* (non-Javadoc)
       * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
       */
      @Override
      public void modifyText(ModifyEvent e) {
        updateSaveButton();
        // Delete button is being disabled as soon as the text is modified
        deleteButton.setEnabled(false);
        try {
          save();
        } catch (CoreException ce) {
          // Log and show error
          UIPlugin.logAndShowError(ce, true);
        }
      }
    });
    saveButton = new Button(group, SWT.NONE);
    saveButton.setText(Messages.FilterSettingsDialog_label_save);
    saveButton.addSelectionListener(new SelectionAdapter() {
      /* (non-Javadoc)
       * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
       */
      @Override
      public void widgetSelected(SelectionEvent e) {
        NamedFilter flt = doFindNamedFilter();
        if (flt != null) {
          if (MessageDialog.openQuestion(getShell(),
              Messages.FilterSettingsDialog_confirm_title,
              Messages.FilterSettingsDialog_confirm_question)) {
            // Remove old
            namedFilters.remove(flt);
          } else {
            // Abort saving
            return;
          }
        }
        flt = new NamedFilter();
        flt.setName(namedFiltersViewer.getCombo().getText().trim());
        flt.setRestrictions(doGetRestrictions());
        namedFilters.add(flt);
        namedFiltersViewer.setInput(namedFilters.toArray());
        try {
          save();
        } catch (CoreException ce) {
          // Log and show error
          UIPlugin.logAndShowError(ce, true);
        }
      }
    });
    deleteButton = new Button(group, SWT.NONE);
    deleteButton.setText(Messages.FilterSettingsDialog_label_delete);
    deleteButton.addSelectionListener(new SelectionAdapter() {
      /* (non-Javadoc)
       * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
       */
      @Override
      public void widgetSelected(SelectionEvent e) {
        NamedFilter flt = doFindNamedFilter();
        namedFilters.remove(flt);
        namedFiltersViewer.setInput(namedFilters.toArray());
      }
    });
    deleteButton.setEnabled(false);
   
    label = new Label(parentComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
    label.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
   
    scrolledComposite = new ScrolledComposite(parentComposite, SWT.V_SCROLL);
    GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
    gridData.heightHint = 250;
    gridData.widthHint = 600;
    scrolledComposite.setLayoutData(gridData);
    scrolledComposite.setExpandHorizontal(true);
    rootComposite = new Composite(scrolledComposite, SWT.NONE);
    rootComposite.setLayout(new GridLayout());
   
    label = new Label(parentComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
    label.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
   
    setTitle(Messages.FilterSettingsDialog_title);
    setMessage(Messages.FilterSettingsDialog_message);
   
    updateContents(true);
   
    // Enable help button
    setHelpAvailable(true);
    PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(),
        IHelpContexts.FILTER_SETTINGS_DIALOG);
   
    return rootComposite;
  }

  private <T> String getInputValue(ARestriction<T> restriction) {
    return restriction.getField().toInputValue(restriction.getValue(), log);
  }

  /* (non-Javadoc)
   * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
   */
  @Override
  protected void createButtonsForButtonBar(Composite parent) {
    super.createButtonsForButtonBar(parent);
    // Trigger re-evaluation
    updateOKButton();
  }

  /* (non-Javadoc)
   * @see org.eclipse.jface.dialogs.Dialog#okPressed()
   */
  @Override
  protected void okPressed() {
    restrictions = doGetRestrictions();
    super.okPressed();
  }

  /**
   * @return the restrictions
   */
  public List<ARestriction<?>> getRestrictions() {
    return restrictions;
  }

  private NamedFilter doFindNamedFilter() {
    String name = namedFiltersViewer.getCombo().getText().trim();
    Iterator<NamedFilter> it = namedFilters.iterator();
    while (it.hasNext()) {
      NamedFilter flt = it.next();
      if (name.equals(flt.getName())) {
        return flt;
      }
    }
    return null;
  }

  private List<ARestriction<?>> doGetRestrictions() {
    List<ARestriction<?>> ret = new ArrayList<ARestriction<?>>();
    for (FilterClauseComposite clause : clauses) {
      ret.add(clause.getRestriction());
    }
    return ret;
  }

  private void refreshScrolledComposite() {
    // Necessary for scrolled composite to work
    scrolledComposite.setContent(rootComposite);
    rootComposite.setSize(rootComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
  }

  private FilterClauseComposite createFilterClauseRow() {
    final FilterClauseComposite newClause =
      new FilterClauseComposite(rootComposite, SWT.NONE, log);
    newClause.addFilterClauseListener(new IFilterClauseListener() {
     
      @Override
      public void removeButtonPressed(FilterClauseEvent e) {
        clauses.remove(newClause);
        newClause.dispose();
        refreshScrolledComposite();
        updateSaveButton();
        updateClearButton();
        updateOKButton();
        setDefaultButton();
      }
     
      @Override
      public void inputChanged(FilterClauseEvent e) {
        updateSaveButton();
        updateOKButton();
      }
    });
    clauses.add(newClause);
    return newClause;
  }

  private void updateClearButton() {
    clearButton.setEnabled(!clauses.isEmpty());
  }

  private void updateSaveButton() {
    boolean allValid = true;
    for (FilterClauseComposite clause : clauses) {
      if (!clause.isValid()) {
        allValid = false;
        break;
      }
    }
    saveButton.setEnabled(allValid && !doGetRestrictions().isEmpty() &&
        (namedFiltersViewer.getCombo().getText().trim().length() > 0));
  }

  private void updateOKButton() {
    boolean allValid = true;
    for (FilterClauseComposite clause : clauses) {
      if (!clause.isValid()) {
        allValid = false;
        break;
      }
    }
    if (getButton(OK) != null) {
      getButton(OK).setEnabled(allValid);
    }
  }

  private void setDefaultButton() {
    getShell().setDefaultButton(getButton(OK));
  }

  private void createAddClearButtonRow() {
    buttonComposite = new Composite(rootComposite, SWT.NONE);
    buttonComposite.setLayout(new GridLayout(2, false));
   
    final Button addButton = new Button(buttonComposite, SWT.NONE);
    addButton.setText(Messages.FilterSettingsDialog_label_add);
    addButton.addSelectionListener(new SelectionAdapter() {
      /* (non-Javadoc)
       * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
       */
      @Override
      public void widgetSelected(SelectionEvent e) {
        // Dispose button row
        buttonComposite.dispose();
        // Create new filter row, then new button row
        createFilterClauseRow();
        createAddClearButtonRow();
        refreshScrolledComposite();
        updateSaveButton();
        updateClearButton();
        updateOKButton();
        setDefaultButton();
      }
    });
   
    clearButton = new Button(buttonComposite, SWT.NONE);
    clearButton.setText(Messages.FilterSettingsDialog_label_clear);
    clearButton.addSelectionListener(new SelectionAdapter() {
      /* (non-Javadoc)
       * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
       */
      @Override
      public void widgetSelected(SelectionEvent e) {
        clearContents();
        updateContents(false);
      }
    });
  }

  private void clearContents() {
    buttonComposite.dispose();
    for (FilterClauseComposite clause : clauses) {
      clause.dispose();
    }
    clauses.clear();
    restrictions.clear();
  }

  private void updateContents(boolean addRowIfEmpty) {
    if (restrictions.isEmpty()) {
      if (addRowIfEmpty) {
        // Create initial row if requested
        createFilterClauseRow();
      }
      createAddClearButtonRow();
      refreshScrolledComposite();
    } else {
      // Create empty filter clauses
      for (int i = 0; i < restrictions.size(); i++) {
        createFilterClauseRow();
      }
      createAddClearButtonRow();
      refreshScrolledComposite();
      // Initialize values
      int i = 0;
      for (ARestriction<?> restriction : restrictions) {
        clauses.get(i).setField(restriction.getField());
        clauses.get(i).setOperator(restriction.getOperator());
        clauses.get(i).setValue(getInputValue(restriction));
        i++;
      }
      if (focusLast) {
        // This was added using Quick Filter
        clauses.get(i - 1).setFocus();
        scrolledComposite.getVerticalBar().setSelection(
            scrolledComposite.getVerticalBar().getMaximum());
        focusLast = false;
      }
    }
    updateSaveButton();
    updateClearButton();
    updateOKButton();
    setDefaultButton();
  }

  private void save() throws CoreException {
    XMLMemento rootElem = XMLMemento.createWriteRoot(ELEM_ROOT);
    for (NamedFilter flt : namedFilters) {
      final IMemento filterElem = rootElem.createChild(ELEM_FILTER);
      filterElem.putString(ATTRIB_NAME, flt.getName());
      for (ARestriction<?> rest : flt.getRestrictions()) {
        final IMemento clauseElem = filterElem.createChild(ELEM_CLAUSE);
        clauseElem.putString(ATTRIB_FIELD, rest.getField().getKey());
        clauseElem.putInteger(ATTRIB_OPERATOR, rest.getOperator().getId());
        rest.visit(new IRestrictionVisitor() {
          /* (non-Javadoc)
           * @see net.sf.logsaw.core.query.IRestrictionVisitor#visit(net.sf.logsaw.core.query.LevelRestriction)
           */
          @Override
          public void visit(LevelRestriction restriction) {
            clauseElem.putTextData(restriction.getField().toInputValue(restriction.getValue(), log));
          }

          /* (non-Javadoc)
           * @see net.sf.logsaw.core.query.IRestrictionVisitor#visit(net.sf.logsaw.core.query.StringRestriction)
           */
          @Override
          public void visit(StringRestriction restriction) {
            clauseElem.putTextData(restriction.getField().toInputValue(restriction.getValue(), log));
          }

          /* (non-Javadoc)
           * @see net.sf.logsaw.core.query.IRestrictionVisitor#visit(net.sf.logsaw.core.query.DateRestriction)
           */
          @Override
          public void visit(DateRestriction restriction) {
            clauseElem.putTextData(restriction.getField().toInputValue(restriction.getValue(), log));
          }
        });
     
    }
    try {
      StringWriter w = new StringWriter();
      // Save to byte buffer first
      rootElem.save(w);
      // Update log resource
      log.configure(OPTION_NAMED_FILTERS, w.toString());
    } catch (IOException e) {
      // Unexpected exception; wrap with CoreException
      throw new CoreException(new Status(IStatus.ERROR, UIPlugin.PLUGIN_ID,
          NLS.bind(Messages.LogViewEditorColumnConfiguration_error_failedToSave,
              new Object[] {e.getLocalizedMessage()}), e));
    }
  }

  private void init() throws CoreException {
    String str = log.getConfigValue(OPTION_NAMED_FILTERS);
    namedFilters = new HashSet<NamedFilter>();
    if (str != null) {
      // Read memento
      IMemento rootElem = XMLMemento.createReadRoot(new StringReader(str));
      IMemento[] filters = rootElem.getChildren(ELEM_FILTER);
      for (final IMemento filterElem : filters) {
        String name = filterElem.getString(ATTRIB_NAME);
        final List<ARestriction<?>> restrictions = new ArrayList<ARestriction<?>>();
        IMemento[] clauses = filterElem.getChildren(ELEM_CLAUSE);
        for (final IMemento clauseElem : clauses) {
          ALogEntryField<?, ?> fld = log.getDialect().getFieldProvider().findField(
              clauseElem.getString(ATTRIB_FIELD));
          final Operator op = Operators.getOperator(clauseElem.getInteger(ATTRIB_OPERATOR));
          final IRestrictionFactory rf = CorePlugin.getDefault().getRestrictionFactory();
          fld.visit(new ILogEntryFieldVisitor() {
            /* (non-Javadoc)
             * @see net.sf.logsaw.core.model.ILogEntryFieldVisitor#visit(net.sf.logsaw.core.model.StringLogEntryField)
             */
            @Override
            public void visit(StringLogEntryField fld) {
              String val = fld.fromInputValue(clauseElem.getTextData(), log);
              restrictions.add(rf.newRestriction(fld, op, val));
            }

            /* (non-Javadoc)
             * @see net.sf.logsaw.core.model.ILogEntryFieldVisitor#visit(net.sf.logsaw.core.model.LevelLogEntryField)
             */
            @Override
            public void visit(LevelLogEntryField fld) {
              Level val = fld.fromInputValue(clauseElem.getTextData(), log);
              restrictions.add(rf.newRestriction(fld, op, val));
            }

            /* (non-Javadoc)
             * @see net.sf.logsaw.core.model.ILogEntryFieldVisitor#visit(net.sf.logsaw.core.model.DateLogEntryField)
             */
            @Override
            public void visit(DateLogEntryField fld) {
              Date val = fld.fromInputValue(clauseElem.getTextData(), log);
              restrictions.add(rf.newRestriction(fld, op, val));
            }
          });
        }
        NamedFilter flt = new NamedFilter();
        flt.setName(name);
        flt.setRestrictions(restrictions);
        namedFilters.add(flt);
      }
    }
  }

  /* (non-Javadoc)
   * @see org.eclipse.jface.window.Window#getShellStyle()
   */
  @Override
  protected int getShellStyle() {
    return super.getShellStyle() | SWT.RESIZE;
  }

  /* (non-Javadoc)
   * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
   */
  @Override
  protected void configureShell(Shell newShell) {
    super.configureShell(newShell);
    newShell.setText(Messages.FilterSettingsDialog_title);
  }
}
TOP

Related Classes of net.sf.logsaw.ui.dialogs.FilterSettingsDialog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.