1   package com.stateofflow.eclipse.metrics.properties.exclusions;
2   
3   import java.io.IOException;
4   import java.util.Iterator;
5   
6   import org.apache.oro.text.regex.MalformedPatternException;
7   import org.eclipse.core.resources.IFile;
8   import org.eclipse.core.resources.IProject;
9   import org.eclipse.core.runtime.CoreException;
10  import org.eclipse.core.runtime.IStatus;
11  import org.eclipse.core.runtime.Status;
12  import org.eclipse.jface.dialogs.ErrorDialog;
13  import org.eclipse.jface.dialogs.IInputValidator;
14  import org.eclipse.jface.dialogs.InputDialog;
15  import org.eclipse.jface.viewers.ISelectionChangedListener;
16  import org.eclipse.jface.viewers.IStructuredSelection;
17  import org.eclipse.jface.viewers.SelectionChangedEvent;
18  import org.eclipse.jface.viewers.TableViewer;
19  import org.eclipse.jface.window.Window;
20  import org.eclipse.swt.SWT;
21  import org.eclipse.swt.layout.GridData;
22  import org.eclipse.swt.layout.GridLayout;
23  import org.eclipse.swt.widgets.Composite;
24  import org.eclipse.ui.dialogs.ResourceSelectionDialog;
25  
26  import com.stateofflow.eclipse.metrics.MetricsPlugin;
27  import com.stateofflow.eclipse.metrics.properties.exclusions.table.TableViewerBuilder;
28  
29  public final class View extends Composite {
30      private final ExcludedResources excludedResources;
31      private final TableViewer tableViewer;
32  
33      public View(final Composite parent, final IProject project) throws IOException {
34          super(parent, SWT.NULL);
35          excludedResources = new ExcludedResources(project);
36  
37          setLayout(new GridLayout());
38          setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));
39  
40          tableViewer = new TableViewerBuilder().create(this, excludedResources);
41          final ButtonPanel buttons = new ButtonPanel(this);
42          addSelectionChangedListenerToTable(buttons);
43      }
44  
45      void addExcludedFile() {
46          final ResourceSelectionDialog dialog = new ResourceSelectionDialog(getShell(), excludedResources.getProject(), "Select resources to exclude");
47          dialog.setInitialSelections(excludedResources.getFiles());
48          dialog.open();
49          final Object[] resources = dialog.getResult();
50          if (resources != null) {
51              addFilesToExcludedResources(resources);
52          }
53      }
54  
55      private void addFilesToExcludedResources(final Object[] resources) {
56          excludedResources.clearFiles();
57          for (final Object resource : resources) {
58              if (resource instanceof IFile) {
59                  excludedResources.addFile((IFile) resource);
60              }
61          }
62  
63          tableViewer.refresh();
64      }
65  
66      void addRegex() {
67          final InputDialog dialog = openRegexDialog("");
68          if (dialog.getReturnCode() == Window.OK) {
69              addRegex(dialog.getValue());
70          }
71      }
72  
73      private void addRegex(final String regex) {
74          final String trimmedRegex = regex.trim();
75          if (trimmedRegex.length() == 0) {
76              return;
77          }
78  
79          addTrimmedRegex(trimmedRegex);
80  
81          tableViewer.refresh();
82      }
83  
84      private void addSelectionChangedListenerToTable(final ButtonPanel buttons) {
85          tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
86              public void selectionChanged(final SelectionChangedEvent event) {
87                  final boolean empty = event.getSelection().isEmpty();
88                  buttons.selectionChanged(empty);
89              }
90          });
91      }
92  
93      private void addTrimmedRegex(final String trimmedRegex) {
94          try {
95              excludedResources.addRegex(trimmedRegex);
96          } catch (final MalformedPatternException mpex) {
97              ErrorDialog.openError(getShell(), "Invalid regex", null, new Status(IStatus.ERROR, MetricsPlugin.PLUGIN_ID, IStatus.OK, "The string '" + trimmedRegex + "' is not a valid regex.", null));
98          }
99      }
100 
101     private void editRegex(final String original) {
102         final InputDialog dialog = openRegexDialog(original);
103         if (dialog.getReturnCode() == Window.OK) {
104             excludedResources.removeRegex(original);
105             addRegex(dialog.getValue());
106         }
107     }
108 
109     private void editResource(final Object firstSelectedItem) {
110         if (firstSelectedItem instanceof String) {
111             editRegex((String) firstSelectedItem);
112         } else {
113             addExcludedFile();
114         }
115     }
116 
117     void editSelectedResource() {
118         final IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
119         if (selection.isEmpty()) {
120             return;
121         }
122 
123         editResource(selection.getFirstElement());
124     }
125 
126     public boolean isModified() {
127         return excludedResources.isModified();
128     }
129 
130     private InputDialog openRegexDialog(final String initialValue) {
131         final InputDialog dialog = new InputDialog(getShell(), "Regex Entry", "Enter a regex", initialValue, new IInputValidator() {
132             public String isValid(final String regex) {
133                 return excludedResources.isValidRegex(regex.trim()) ? null : (String) "Not a valid regex";
134             }
135         });
136         dialog.setBlockOnOpen(true);
137         dialog.open();
138         return dialog;
139     }
140 
141     void removeSelectedExclusions() {
142         final IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
143         if (selection.isEmpty()) {
144             return;
145         }
146 
147         removeSelectedExclusions(selection);
148         tableViewer.refresh();
149     }
150 
151     private void removeSelectedExclusions(final IStructuredSelection selection) {
152         @SuppressWarnings("unchecked")
153         final Iterator<Object> iter = selection.iterator();
154         while (iter.hasNext()) {
155             final Object toRemove = iter.next();
156             if (toRemove instanceof String) {
157                 excludedResources.removeRegex((String) toRemove);
158             } else {
159                 excludedResources.removeFile((IFile) toRemove);
160             }
161         }
162     }
163 
164     public void store() throws CoreException {
165         excludedResources.store();
166     }
167 }
168