1 11 package org.eclipse.search.internal.ui.text; 12 13 import java.lang.reflect.InvocationTargetException ; 14 import java.util.ArrayList ; 15 import java.util.HashSet ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.NoSuchElementException ; 19 import java.util.Set ; 20 21 import org.eclipse.search.internal.ui.SearchMessages; 22 import org.eclipse.search.internal.ui.SearchPlugin; 23 import org.eclipse.search.internal.ui.util.ExceptionHandler; 24 import org.eclipse.search.ui.NewSearchUI; 25 import org.eclipse.search.ui.text.AbstractTextSearchResult; 26 import org.eclipse.search.ui.text.Match; 27 28 import org.eclipse.core.filebuffers.FileBuffers; 29 import org.eclipse.core.filebuffers.ITextFileBuffer; 30 import org.eclipse.core.filebuffers.ITextFileBufferManager; 31 import org.eclipse.core.filebuffers.LocationKind; 32 33 import org.eclipse.core.resources.IFile; 34 import org.eclipse.core.resources.IResource; 35 import org.eclipse.core.resources.IResourceProxy; 36 import org.eclipse.core.resources.IResourceProxyVisitor; 37 import org.eclipse.core.resources.IWorkspace; 38 import org.eclipse.core.resources.ResourcesPlugin; 39 40 import org.eclipse.core.runtime.Assert; 41 import org.eclipse.core.runtime.CoreException; 42 import org.eclipse.core.runtime.IProgressMonitor; 43 import org.eclipse.core.runtime.IStatus; 44 import org.eclipse.core.runtime.MultiStatus; 45 import org.eclipse.core.runtime.OperationCanceledException; 46 import org.eclipse.core.runtime.Platform; 47 import org.eclipse.core.runtime.jobs.ISchedulingRule; 48 49 import org.eclipse.swt.widgets.Item; 50 51 import org.eclipse.jface.action.Action; 52 import org.eclipse.jface.dialogs.ErrorDialog; 53 import org.eclipse.jface.dialogs.IDialogConstants; 54 import org.eclipse.jface.dialogs.ProgressMonitorDialog; 55 import org.eclipse.jface.viewers.ILabelProvider; 56 import org.eclipse.jface.viewers.IStructuredSelection; 57 import org.eclipse.jface.viewers.StructuredViewer; 58 import org.eclipse.jface.viewers.TableViewer; 59 import org.eclipse.jface.viewers.TreeViewer; 60 61 import org.eclipse.ui.IWorkbenchSite; 62 import org.eclipse.ui.actions.WorkspaceModifyOperation; 63 64 class ReplaceAction2 extends Action { 65 66 private IWorkbenchSite fSite; 67 private IFile[] fElements; 68 private FileSearchPage fPage; 69 70 private static class ItemIterator implements Iterator { 71 private Item[] fArray; 72 private int fNextPosition; 73 ItemIterator(Item[] array) { 74 fArray= array; 75 fNextPosition= 0; 76 } 77 78 public boolean hasNext() { 79 return fNextPosition < fArray.length; 80 } 81 82 public Object next() { 83 if (!hasNext()) 84 throw new NoSuchElementException (); 85 return fArray[fNextPosition++].getData(); 86 } 87 88 public void remove() { 89 throw new UnsupportedOperationException (); 90 } 91 } 92 93 public ReplaceAction2(FileSearchPage page, IFile[] elements) { 94 Assert.isNotNull(page); 95 fSite= page.getSite(); 96 if (elements != null) 97 fElements= elements; 98 else 99 fElements= new IFile[0]; 100 fPage= page; 101 102 setText(SearchMessages.ReplaceAction_label_all); 103 setEnabled(!(fElements.length == 0)); 104 } 105 106 public ReplaceAction2(FileSearchPage page) { 107 Assert.isNotNull(page); 108 fSite= page.getSite(); 109 fPage= page; 110 111 Item[] items= null; 112 StructuredViewer viewer= fPage.getViewer(); 113 if (viewer instanceof TreeViewer) { 114 items= ((TreeViewer)viewer).getTree().getItems(); 115 } else if (viewer instanceof TableViewer) { 116 items= ((TableViewer)viewer).getTable().getItems(); 117 } 118 fElements= collectFiles(new ItemIterator(items)); 119 120 setText(SearchMessages.ReplaceAction_label_all); 121 setEnabled(!(fElements.length == 0)); 122 } 123 124 125 public ReplaceAction2(FileSearchPage page, IStructuredSelection selection) { 126 fSite= page.getSite(); 127 fPage= page; 128 setText(SearchMessages.ReplaceAction_label_selected); 129 fElements= collectFiles(selection.iterator()); 130 setEnabled(!(fElements.length == 0)); 131 } 132 133 private IFile[] collectFiles(Iterator resources) { 134 final Set files= new HashSet (); 135 final AbstractTextSearchResult result= fPage.getInput(); 136 if (result == null) 137 return new IFile[0]; 138 while (resources.hasNext()) { 139 IResource resource= (IResource) resources.next(); 140 try { 141 resource.accept(new IResourceProxyVisitor() { 142 public boolean visit(IResourceProxy proxy) throws CoreException { 143 if (proxy.getType() == IResource.FILE) { 144 IResource file= proxy.requestResource(); 145 if (result.getMatchCount(file) > 0) { 146 files.add(file); 147 } 148 return false; 149 } 150 return true; 151 } 152 }, IResource.NONE); 153 } catch (CoreException e) { 154 SearchPlugin.getDefault().getLog().log(e.getStatus()); 157 } 158 } 159 return (IFile[]) files.toArray(new IFile[files.size()]); 160 } 161 162 163 public void run() { 164 IWorkspace workspace= ResourcesPlugin.getWorkspace(); 165 ISchedulingRule rule= workspace.getRuleFactory().modifyRule(workspace.getRoot()); 166 try { 167 Platform.getJobManager().beginRule(rule, null); 168 if (validateResources((FileSearchQuery) fPage.getInput().getQuery())) { 169 ReplaceDialog2 dialog= new ReplaceDialog2(fSite.getShell(), fElements, fPage); 170 dialog.open(); 171 } 172 } catch (OperationCanceledException e) { 173 } finally { 174 Platform.getJobManager().endRule(rule); 175 } 176 } 177 178 private boolean validateResources(final FileSearchQuery operation) { 179 IFile[] readOnlyFiles= getReadOnlyFiles(); 180 IStatus status= ResourcesPlugin.getWorkspace().validateEdit(readOnlyFiles, fSite.getShell()); 181 if (!status.isOK()) { 182 if (status.getSeverity() != IStatus.CANCEL) { 183 ErrorDialog.openError(fSite.getShell(), SearchMessages.ReplaceAction2_error_validate_title, SearchMessages.ReplaceAction2_error_validate_message, status); 184 } 185 return false; 186 } 187 188 final List outOfDateEntries= new ArrayList (); 189 for (int j= 0; j < fElements.length; j++) { 190 IFile entry = fElements[j]; 191 Match[] markers= fPage.getDisplayedMatches(entry); 192 for (int i= 0; i < markers.length; i++) { 193 if (isOutOfDate((FileMatch)markers[i])) { 194 outOfDateEntries.add(entry); 195 break; 196 } 197 } 198 } 199 200 final List outOfSyncEntries= new ArrayList (); 201 for (int i= 0; i < fElements.length; i++) { 202 IFile entry = fElements[i]; 203 if (isOutOfSync(entry)) { 204 outOfSyncEntries.add(entry); 205 } 206 } 207 208 if (outOfDateEntries.size() > 0 || outOfSyncEntries.size() > 0) { 209 if (askForResearch(outOfDateEntries, outOfSyncEntries)) { 210 ProgressMonitorDialog pmd= new ProgressMonitorDialog(fSite.getShell()); 211 try { 212 pmd.run(true, true, new WorkspaceModifyOperation(null) { 213 protected void execute(IProgressMonitor monitor) throws CoreException { 214 research(monitor, outOfDateEntries, operation); 215 } 216 }); 217 return true; 218 } catch (InvocationTargetException e) { 219 ExceptionHandler.handle(e, fSite.getShell(), SearchMessages.ReplaceAction_label, SearchMessages.ReplaceAction_research_error); 220 } catch (InterruptedException e) { 221 } 223 } 224 return false; 225 } 226 return true; 227 } 228 229 private IFile[] getReadOnlyFiles() { 230 Set readOnly= new HashSet (); 231 for (int i = 0; i < fElements.length; i++) { 232 if (fElements[i].isReadOnly()) 233 readOnly.add(fElements[i]); 234 } 235 IFile[] readOnlyArray= new IFile[readOnly.size()]; 236 return (IFile[]) readOnly.toArray(readOnlyArray); 237 } 238 239 private void research(IProgressMonitor monitor, List outOfDateEntries, FileSearchQuery operation) throws CoreException { 240 String message= SearchMessages.ReplaceAction2_statusMessage; 241 MultiStatus multiStatus= new MultiStatus(NewSearchUI.PLUGIN_ID, IStatus.OK, message, null); 242 for (Iterator elements = outOfDateEntries.iterator(); elements.hasNext();) { 243 IFile entry = (IFile) elements.next(); 244 IStatus status = research(operation, monitor, entry); 245 if (status != null && !status.isOK()) { 246 multiStatus.add(status); 247 } 248 } 249 if (!multiStatus.isOK()) { 250 throw new CoreException(multiStatus); 251 } 252 } 253 254 private boolean askForResearch(List outOfDateEntries, List outOfSyncEntries) { 255 SearchAgainConfirmationDialog dialog= new SearchAgainConfirmationDialog(fSite.getShell(), (ILabelProvider) fPage.getViewer().getLabelProvider(), outOfSyncEntries, outOfDateEntries); 256 return dialog.open() == IDialogConstants.OK_ID; 257 } 258 259 private boolean isOutOfDate(FileMatch match) { 260 261 if (match.getCreationTimeStamp() != match.getFile().getModificationStamp()) 262 return true; 263 ITextFileBufferManager bm= FileBuffers.getTextFileBufferManager(); 264 ITextFileBuffer fb= bm.getTextFileBuffer(match.getFile().getFullPath(), LocationKind.IFILE); 265 if (fb != null && fb.isDirty()) 266 return true; 267 return false; 268 } 269 270 private boolean isOutOfSync(IFile entry) { 271 return !entry.isSynchronized(IResource.DEPTH_ZERO); 272 } 273 274 private IStatus research(FileSearchQuery operation, final IProgressMonitor monitor, IFile entry) { 275 Match[] matches= fPage.getDisplayedMatches(entry); 276 IStatus status= operation.searchInFile(getResult(), monitor, entry); 277 278 for (int i= 0; i < matches.length; i++) { 280 getResult().removeMatch(matches[i]); 281 } 282 return status; 283 } 284 285 private AbstractTextSearchResult getResult() { 286 return fPage.getInput(); 287 } 288 289 } 290 | Popular Tags |