KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > search > internal > ui > text > ReplaceAction2


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.search.internal.ui.text;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.NoSuchElementException JavaDoc;
19 import java.util.Set JavaDoc;
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 /* package */ 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 JavaDoc {
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 JavaDoc next() {
83             if (!hasNext())
84                 throw new NoSuchElementException JavaDoc();
85             return fArray[fNextPosition++].getData();
86         }
87         
88         public void remove() {
89             throw new UnsupportedOperationException JavaDoc();
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 JavaDoc resources) {
134         final Set JavaDoc files= new HashSet JavaDoc();
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                 // TODO Don't know yet how to handle this. This is called when we open the context
155
// menu. A bad time to show a dialog.
156
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 JavaDoc outOfDateEntries= new ArrayList JavaDoc();
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 JavaDoc outOfSyncEntries= new ArrayList JavaDoc();
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 JavaDoc e) {
219                     ExceptionHandler.handle(e, fSite.getShell(), SearchMessages.ReplaceAction_label, SearchMessages.ReplaceAction_research_error);
220                 } catch (InterruptedException JavaDoc e) {
221                     // canceled
222
}
223             }
224             return false;
225         }
226         return true;
227     }
228
229     private IFile[] getReadOnlyFiles() {
230         Set JavaDoc readOnly= new HashSet JavaDoc();
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 JavaDoc outOfDateEntries, FileSearchQuery operation) throws CoreException {
240         String JavaDoc message= SearchMessages.ReplaceAction2_statusMessage;
241         MultiStatus multiStatus= new MultiStatus(NewSearchUI.PLUGIN_ID, IStatus.OK, message, null);
242         for (Iterator JavaDoc 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 JavaDoc outOfDateEntries, List JavaDoc 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         // always remove old matches
279
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