tmf: Bug 494689: fix failing name conflict handling in trace import
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / project / wizards / importtrace / ImportConflictHandler.java
1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson.
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Bernd Hufmann - Initial API and implementation
11 *******************************************************************************/
12 package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.importtrace;
13
14 import java.util.List;
15
16 import org.eclipse.core.resources.IContainer;
17 import org.eclipse.core.resources.IResource;
18 import org.eclipse.core.resources.ResourcesPlugin;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.jface.dialogs.MessageDialog;
23 import org.eclipse.osgi.util.NLS;
24 import org.eclipse.swt.SWT;
25 import org.eclipse.swt.widgets.Shell;
26 import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
27 import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
28
29 /**
30 * Handler to check for name clashes during import operations. It will allow
31 * users to select renaming, overwriting or skipping of a given trace as well
32 * as upcoming traces by keeping track of the user selection. In case of
33 * overwriting the original trace will be deleted.
34 *
35 * See {@link ImportConfirmation} for users selection choices.
36 *
37 * @author Bernd Hufmann
38 */
39 public class ImportConflictHandler {
40
41 // ------------------------------------------------------------------------
42 // Attributes
43 // ------------------------------------------------------------------------
44 private Shell fShell;
45 private TmfTraceFolder fTraceFolderElement;
46 private ImportConfirmation fConfirmationMode;
47
48 // ------------------------------------------------------------------------
49 // Constructor(s)
50 // ------------------------------------------------------------------------
51 /**
52 * @param shell
53 * shell to display confirmation dialog
54 * @param folder
55 * Target folder for the traces
56 * @param initialMode
57 * Initial confirmation mode
58 */
59 public ImportConflictHandler(Shell shell, TmfTraceFolder folder, ImportConfirmation initialMode) {
60 fShell = shell;
61 fTraceFolderElement = folder;
62 fConfirmationMode = initialMode;
63 }
64
65 // ------------------------------------------------------------------------
66 // Operation(s)
67 // ------------------------------------------------------------------------
68 /**
69 * It checks for name clashes. In case of a name clash it will open a
70 * confirmation dialog where the use can rename, overwrite or skip
71 * the trace. The user has also the choice to rename, overwrite or
72 * skip all traces of subsequent calls to this method. This class will
73 * keep track about the {@link ImportConfirmation} mode selected by the
74 * user.
75 *
76 * In case of {@link ImportConfirmation#RENAME} or
77 * {@link ImportConfirmation#RENAME_ALL} a new name will be return by
78 * adding sequence number surrounded by (), e.g. (1) or (2).
79 *
80 * In case of {@link ImportConfirmation#OVERWRITE} or
81 * {@link ImportConfirmation#OVERWRITE_ALL} the original trace will be
82 * deleted and the original name will be returned.
83 *
84 * In case the dialog {@link ImportConfirmation#SKIP} or
85 * {@link ImportConfirmation#SKIP_ALL} it will return null to indicate
86 * the skipping.
87 *
88 * @param tracePath
89 * The trace to check
90 * @param monitor
91 * The progress monitor
92 * @return the trace name to use or null
93 * @throws InterruptedException
94 * If the dialog box was cancelled
95 * @throws CoreException
96 * If an error during deletion occurred
97 */
98 public String checkAndHandleNameClash(IPath tracePath, IProgressMonitor monitor) throws InterruptedException, CoreException {
99 ImportConfirmation mode = checkForNameClash(tracePath);
100 switch (mode) {
101 case RENAME:
102 case RENAME_ALL:
103 return rename(tracePath);
104 case OVERWRITE:
105 case OVERWRITE_ALL:
106 delete(tracePath, monitor);
107 //$FALL-THROUGH$
108 case CONTINUE:
109 return tracePath.lastSegment();
110 case SKIP:
111 case SKIP_ALL:
112 default:
113 return null;
114 }
115 }
116
117 // ------------------------------------------------------------------------
118 // Helper methods
119 // ------------------------------------------------------------------------
120 private ImportConfirmation checkForNameClash(IPath tracePath) throws InterruptedException {
121 // handle rename
122 if (getExistingResource(tracePath) != null) {
123 if ((fConfirmationMode == ImportConfirmation.RENAME_ALL) ||
124 (fConfirmationMode == ImportConfirmation.OVERWRITE_ALL) ||
125 (fConfirmationMode == ImportConfirmation.SKIP_ALL)) {
126 return fConfirmationMode;
127 }
128
129 int returnCode = promptForOverwrite(tracePath);
130 if (returnCode < 0) {
131 // Cancel
132 throw new InterruptedException();
133 }
134 fConfirmationMode = ImportConfirmation.values()[returnCode];
135 return fConfirmationMode;
136 }
137 return ImportConfirmation.CONTINUE;
138 }
139
140 private int promptForOverwrite(IPath tracePath) {
141 final MessageDialog dialog = new MessageDialog(fShell,
142 Messages.ImportTraceWizard_MessageTitle, null, NLS.bind(Messages.ImportTraceWizard_TraceAlreadyExists, tracePath.makeRelativeTo(fTraceFolderElement.getProject().getPath())),
143 MessageDialog.QUESTION, new String[] {
144 ImportConfirmation.RENAME.getInName(),
145 ImportConfirmation.RENAME_ALL.getInName(),
146 ImportConfirmation.OVERWRITE.getInName(),
147 ImportConfirmation.OVERWRITE_ALL.getInName(),
148 ImportConfirmation.SKIP.getInName(),
149 ImportConfirmation.SKIP_ALL.getInName(),
150 }, 4) {
151 @Override
152 protected int getShellStyle() {
153 return super.getShellStyle() | SWT.SHEET;
154 }
155 };
156
157 final int[] returnValue = new int[1];
158 fShell.getDisplay().syncExec(new Runnable() {
159
160 @Override
161 public void run() {
162 returnValue[0] = dialog.open();
163 }
164 });
165 return returnValue[0];
166 }
167
168 private static String rename(IPath tracePath) {
169 IResource existingResource = getExistingResource(tracePath);
170 if (existingResource == null) {
171 return tracePath.lastSegment();
172 }
173
174 // Not using IFolder on purpose to leave the door open to import
175 // directly into an IProject
176 IContainer folder = existingResource.getParent();
177
178 int i = 2;
179 while (true) {
180 String name = existingResource.getName() + '(' + Integer.toString(i++) + ')';
181 IResource resource = folder.findMember(name);
182 if (resource == null) {
183 return name;
184 }
185 }
186 }
187
188 private void delete(IPath tracePath, IProgressMonitor monitor) throws CoreException {
189 IResource existingResource = getExistingResource(tracePath);
190 if (existingResource == null) {
191 return;
192 }
193 TmfTraceElement existingTraceElement = getExistingTrace(tracePath);
194 if (existingTraceElement != null) {
195 // Delete existing TmfTraceElement
196 existingTraceElement.delete(monitor);
197 return;
198 }
199
200 // Delete resource existing in workspace
201 existingResource.delete(true, monitor);
202 }
203
204 private TmfTraceElement getExistingTrace(IPath tracePath) {
205 List<TmfTraceElement> traces = fTraceFolderElement.getTraces();
206 for (TmfTraceElement t : traces) {
207 if (t.getPath().equals(tracePath)) {
208 return t;
209 }
210 }
211 return null;
212 }
213
214 private static IResource getExistingResource(IPath tracePath) {
215 // Look for existing resource
216 return ResourcesPlugin.getWorkspace().getRoot().findMember(tracePath);
217 }
218 }
219
This page took 0.042498 seconds and 5 git commands to generate.