]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/jarimport/JarImportWizard.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / ui / org / eclipse / jdt / internal / ui / jarimport / JarImportWizard.java
1 /*******************************************************************************
2  * Copyright (c) 2005, 2011 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.jdt.internal.ui.jarimport;
12
13 import java.io.File;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.net.URI;
17 import java.util.zip.ZipEntry;
18 import java.util.zip.ZipFile;
19
20 import org.eclipse.core.filesystem.EFS;
21 import org.eclipse.core.filesystem.IFileStore;
22 import org.eclipse.core.filesystem.URIUtil;
23
24 import org.eclipse.core.runtime.Assert;
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IPath;
27 import org.eclipse.core.runtime.IProgressMonitor;
28 import org.eclipse.core.runtime.IStatus;
29 import org.eclipse.core.runtime.Status;
30 import org.eclipse.core.runtime.SubProgressMonitor;
31
32 import org.eclipse.core.resources.IResource;
33 import org.eclipse.core.resources.ResourcesPlugin;
34
35 import org.eclipse.jface.dialogs.IDialogSettings;
36 import org.eclipse.jface.viewers.ISelection;
37 import org.eclipse.jface.viewers.IStructuredSelection;
38 import org.eclipse.jface.wizard.IWizardPage;
39 import org.eclipse.jface.wizard.WizardDialog;
40
41 import org.eclipse.ui.IImportWizard;
42 import org.eclipse.ui.IWorkbench;
43 import org.eclipse.ui.PlatformUI;
44
45 import org.eclipse.ltk.core.refactoring.RefactoringCore;
46 import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy;
47 import org.eclipse.ltk.core.refactoring.history.RefactoringHistory;
48 import org.eclipse.ltk.ui.refactoring.history.RefactoringHistoryControlConfiguration;
49
50 import org.eclipse.jdt.core.IClasspathEntry;
51 import org.eclipse.jdt.core.IJavaProject;
52 import org.eclipse.jdt.core.IPackageFragmentRoot;
53 import org.eclipse.jdt.core.JavaCore;
54 import org.eclipse.jdt.core.JavaModelException;
55 import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
56
57 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
58 import org.eclipse.jdt.internal.ui.JavaPlugin;
59 import org.eclipse.jdt.internal.ui.JavaPluginImages;
60 import org.eclipse.jdt.internal.ui.jarpackager.JarPackagerUtil;
61 import org.eclipse.jdt.internal.ui.refactoring.actions.MigrateJarFileAction;
62 import org.eclipse.jdt.internal.ui.refactoring.binary.BinaryRefactoringHistoryWizard;
63
64 /**
65  * Import wizard to import a refactoring-aware Java Archive (JAR) file.
66  * <p>
67  * This class may be instantiated and used without further configuration; this
68  * class is not intended to be subclassed.
69  * </p>
70  * <p>
71  * Example:
72  *
73  * <pre>
74  * IWizard wizard= new JarImportWizard();
75  * wizard.init(workbench, selection);
76  * WizardDialog dialog= new WizardDialog(shell, wizard);
77  * dialog.open();
78  * </pre>
79  *
80  * During the call to <code>open</code>, the wizard dialog is presented to
81  * the user. When the user hits Finish, the user-selected JAR file is inspected
82  * for associated refactorings, the wizard executes eventual refactorings,
83  * copies the JAR file over its old version, the dialog closes, and the call to
84  * <code>open</code> returns.
85  * </p>
86  *
87  * @since 3.2
88  */
89 public final class JarImportWizard extends BinaryRefactoringHistoryWizard implements IImportWizard {
90
91         /** Proxy which requests the refactoring history from the import data */
92         private final class RefactoringHistoryProxy extends RefactoringHistory {
93
94                 /** The cached refactoring history delta */
95                 private RefactoringDescriptorProxy[] fHistoryDelta= null;
96
97                 /**
98                  * {@inheritDoc}
99                  */
100                 @Override
101                 public RefactoringDescriptorProxy[] getDescriptors() {
102                         if (fHistoryDelta != null)
103                                 return fHistoryDelta;
104                         final RefactoringHistory incoming= fImportData.getRefactoringHistory();
105                         if (incoming != null) {
106                                 fHistoryDelta= incoming.getDescriptors();
107                                 final IPackageFragmentRoot root= fImportData.getPackageFragmentRoot();
108                                 if (root != null) {
109                                         try {
110                                                 final URI uri= getLocationURI(root.getRawClasspathEntry());
111                                                 if (uri != null) {
112                                                         final File file= new File(uri);
113                                                         if (file.exists()) {
114                                                                 ZipFile zip= null;
115                                                                 try {
116                                                                         zip= new ZipFile(file, ZipFile.OPEN_READ);
117                                                                         ZipEntry entry= zip.getEntry(JarPackagerUtil.getRefactoringsEntry());
118                                                                         if (entry != null) {
119                                                                                 InputStream stream= null;
120                                                                                 try {
121                                                                                         stream= zip.getInputStream(entry);
122                                                                                         final RefactoringHistory existing= RefactoringCore.getHistoryService().readRefactoringHistory(stream, JavaRefactoringDescriptor.JAR_MIGRATION | JavaRefactoringDescriptor.JAR_REFACTORING);
123                                                                                         if (existing != null)
124                                                                                                 fHistoryDelta= incoming.removeAll(existing).getDescriptors();
125                                                                                 } finally {
126                                                                                         if (stream != null) {
127                                                                                                 try {
128                                                                                                         stream.close();
129                                                                                                 } catch (IOException exception) {
130                                                                                                         // Do nothing
131                                                                                                 }
132                                                                                         }
133                                                                                 }
134                                                                         }
135                                                                 } catch (IOException exception) {
136                                                                         try {
137                                                                                 zip.close();
138                                                                         } catch(IOException e){
139                                                                         }
140                                                                 }
141                                                         }
142                                                 }
143                                         } catch (CoreException exception) {
144                                                 JavaPlugin.log(exception);
145                                         }
146                                 }
147                                 return fHistoryDelta;
148                         }
149                         return new RefactoringDescriptorProxy[0];
150                 }
151
152                 /**
153                  * {@inheritDoc}
154                  */
155                 @Override
156                 public boolean isEmpty() {
157                         final RefactoringDescriptorProxy[] proxies= getDescriptors();
158                         if (proxies != null)
159                                 return proxies.length == 0;
160                         return true;
161                 }
162
163                 /**
164                  * {@inheritDoc}
165                  */
166                 @Override
167                 public RefactoringHistory removeAll(final RefactoringHistory history) {
168                         throw new UnsupportedOperationException();
169                 }
170         }
171
172         /** The dialog settings key */
173         private static String DIALOG_SETTINGS_KEY= "JarImportWizard"; //$NON-NLS-1$
174
175         /**
176          * Is the specified class path entry pointing to a valid location for
177          * import?
178          *
179          * @param entry
180          *            the class path entry
181          * @return <code>true</code> if it is a valid package fragment root,
182          *         <code>false</code> otherwise
183          */
184         public static boolean isValidClassPathEntry(final IClasspathEntry entry) {
185                 Assert.isNotNull(entry);
186                 final int kind= entry.getEntryKind();
187                 if (kind == IClasspathEntry.CPE_LIBRARY)
188                         return entry.getContentKind() == IPackageFragmentRoot.K_BINARY;
189                 else if (kind == IClasspathEntry.CPE_VARIABLE)
190                         return true; // be optimistic
191                 return false;
192         }
193
194         /**
195          * Is the specified java project a valid project for import?
196          *
197          * @param project
198          *            the java project
199          * @return
200          *                 returns <code>true</code> if the project is valid
201          * @throws JavaModelException
202          *             if an error occurs
203          */
204         public static boolean isValidJavaProject(final IJavaProject project) throws JavaModelException {
205                 Assert.isNotNull(project);
206                 return project.getProject().isAccessible();
207         }
208
209         /** The refactoring history proxy */
210         private final RefactoringHistoryProxy fHistoryProxy;
211
212         /** The jar import data */
213         final JarImportData fImportData= new JarImportData();
214
215         /** The jar import page, or <code>null</code> */
216         private JarImportWizardPage fImportPage= null;
217
218         /** Is the wizard part of an import wizard? */
219         private boolean fImportWizard= true;
220
221         /** Has the wizard new dialog settings? */
222         private boolean fNewSettings;
223
224         /**
225          * Creates a new jar import wizard.
226          */
227         public JarImportWizard() {
228                 super(JarImportMessages.JarImportWizard_window_title, JarImportMessages.RefactoringImportPreviewPage_title, JarImportMessages.RefactoringImportPreviewPage_description);
229                 fImportData.generated_5455369633822607821();
230                 fHistoryProxy= new RefactoringHistoryProxy();
231                 setInput(fHistoryProxy);
232                 final IDialogSettings section= JavaPlugin.getDefault().getDialogSettings().getSection(DIALOG_SETTINGS_KEY);
233                 if (section == null)
234                         fNewSettings= true;
235                 else {
236                         fNewSettings= false;
237                         setDialogSettings(section);
238                 }
239                 setConfiguration(new RefactoringHistoryControlConfiguration(null, false, false) {
240
241                         @Override
242                         public String getProjectPattern() {
243                                 return JarImportMessages.JarImportWizard_project_pattern;
244                         }
245
246                         @Override
247                         public String getWorkspaceCaption() {
248                                 return JarImportMessages.JarImportWizard_workspace_caption;
249                         }
250                 });
251                 setDefaultPageImageDescriptor(JavaPluginImages.DESC_WIZBAN_REPLACE_JAR);
252         }
253
254         /**
255          * Creates a new jar import wizard.
256          *
257          * @param wizard
258          *            <code>true</code> if the wizard is part of an import wizard,
259          *            <code>false</code> otherwise
260          */
261         public JarImportWizard(final boolean wizard) {
262                 this();
263                 fImportWizard= wizard;
264                 setWindowTitle(JarImportMessages.JarImportWizard_replace_title);
265         }
266
267         /**
268          * {@inheritDoc}
269          */
270         @Override
271         protected void addUserDefinedPages() {
272                 fImportPage= new JarImportWizardPage(this, fImportWizard);
273                 addPage(fImportPage);
274         }
275
276         /**
277          * {@inheritDoc}
278          */
279         @Override
280         public boolean canFinish() {
281                 return super.canFinish() && fImportData.getPackageFragmentRoot() != null && fImportData.getRefactoringFileLocation() != null;
282         }
283
284         /**
285          * {@inheritDoc}
286          */
287         @Override
288         protected boolean deconfigureClasspath(final IClasspathEntry[] entries, final IProgressMonitor monitor) throws CoreException {
289                 final boolean rename= fImportData.isRenameJarFile();
290                 if (rename && !fCancelled) {
291                         final IPackageFragmentRoot root= getPackageFragmentRoot();
292                         if (root != null) {
293                                 final IClasspathEntry entry= root.getRawClasspathEntry();
294                                 for (int index= 0; index < entries.length; index++) {
295                                         if (entries[index].equals(entry)) {
296                                                 final IPath path= getTargetPath(entries[index]);
297                                                 if (path != null)
298                                                         entries[index]= JavaCore.newLibraryEntry(path, entries[index].getSourceAttachmentPath(), entries[index].getSourceAttachmentRootPath(), entries[index].getAccessRules(), entries[index].getExtraAttributes(), entries[index].isExported());
299                                         }
300                                 }
301                         }
302                 }
303                 if (!fCancelled)
304                         replaceJarFile(new SubProgressMonitor(monitor, 100, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
305                 return rename;
306         }
307
308         /**
309          * Returns the jar import data.
310          *
311          * @return the jar import data
312          */
313         public JarImportData getImportData() {
314                 return fImportData;
315         }
316
317         /**
318          * {@inheritDoc}
319          */
320         @Override
321         public IWizardPage getNextPage(final IWizardPage page) {
322                 if (page == fImportPage && fImportData.getRefactoringHistory() == null)
323                         return null;
324                 return super.getNextPage(page);
325         }
326
327         /**
328          * {@inheritDoc}
329          */
330         @Override
331         protected IPackageFragmentRoot getPackageFragmentRoot() {
332                 return fImportData.getPackageFragmentRoot();
333         }
334
335         /**
336          * {@inheritDoc}
337          */
338         @Override
339         protected RefactoringHistory getRefactoringHistory() {
340                 return fHistoryProxy;
341         }
342
343         /**
344          * Returns the target path to be used for the updated classpath entry.
345          *
346          * @param entry
347          *            the classpath entry
348          * @return the target path, or <code>null</code>
349          * @throws CoreException
350          *             if an error occurs
351          */
352         private IPath getTargetPath(final IClasspathEntry entry) throws CoreException {
353                 final URI location= getLocationURI(entry);
354                 if (location != null) {
355                         final URI target= getTargetURI(location);
356                         if (target != null) {
357                                 IPath path= URIUtil.toPath(target);
358                                 if (path != null) {
359                                         final IPath workspace= ResourcesPlugin.getWorkspace().getRoot().getLocation();
360                                         if (workspace.isPrefixOf(path)) {
361                                                 path= path.removeFirstSegments(workspace.segmentCount());
362                                                 path= path.setDevice(null);
363                                                 path= path.makeAbsolute();
364                                         }
365                                 }
366                                 return path;
367                         }
368                 }
369                 return null;
370         }
371
372         /**
373          * Returns the target uri taking any renaming of the jar file into account.
374          *
375          * @param uri
376          *            the location uri
377          * @return the target uri
378          * @throws CoreException
379          *             if an error occurs
380          */
381         private URI getTargetURI(final URI uri) throws CoreException {
382                 final IFileStore parent= EFS.getStore(uri).getParent();
383                 if (parent != null) {
384                         final URI location= fImportData.getRefactoringFileLocation();
385                         if (location != null)
386                                 return parent.getChild(EFS.getStore(location).getName()).toURI();
387                 }
388                 return uri;
389         }
390
391         /**
392          * {@inheritDoc}
393          */
394         public void init(final IWorkbench workbench, final IStructuredSelection selection) {
395                 if (selection != null && selection.size() == 1) {
396                         final Object element= selection.getFirstElement();
397                         if (element instanceof IPackageFragmentRoot) {
398                                 final IPackageFragmentRoot root= (IPackageFragmentRoot) element;
399                                 try {
400                                         final IClasspathEntry entry= root.getRawClasspathEntry();
401                                         if (isValidClassPathEntry(entry)
402                                                         && root.getResolvedClasspathEntry().getReferencingEntry() == null)
403                                                 fImportData.setPackageFragmentRoot(root);
404                                 } catch (JavaModelException exception) {
405                                         JavaPlugin.log(exception);
406                                 }
407                         }
408                 }
409         }
410
411         /**
412          * {@inheritDoc}
413          */
414         @Override
415         public boolean performFinish() {
416                 if (fNewSettings) {
417                         final IDialogSettings settings= JavaPlugin.getDefault().getDialogSettings();
418                         IDialogSettings section= settings.getSection(DIALOG_SETTINGS_KEY);
419                         section= settings.addNewSection(DIALOG_SETTINGS_KEY);
420                         setDialogSettings(section);
421                 }
422                 fImportPage.performFinish();
423                 return super.performFinish();
424         }
425
426         /**
427          * Replaces the old jar file with the new one.
428          *
429          * @param monitor
430          *            the progress monitor to use
431          * @throws CoreException
432          *             if an error occurs
433          */
434         private void replaceJarFile(final IProgressMonitor monitor) throws CoreException {
435                 try {
436                         monitor.beginTask(JarImportMessages.JarImportWizard_cleanup_import, 250);
437                         final URI location= fImportData.getRefactoringFileLocation();
438                         if (location != null) {
439                                 final IPackageFragmentRoot root= fImportData.getPackageFragmentRoot();
440                                 if (root != null) {
441                                         final URI uri= getLocationURI(root.getRawClasspathEntry());
442                                         if (uri != null) {
443                                                 final IFileStore store= EFS.getStore(location);
444                                                 if (fImportData.isRenameJarFile()) {
445                                                         final URI target= getTargetURI(uri);
446                                                         store.copy(EFS.getStore(target), EFS.OVERWRITE, new SubProgressMonitor(monitor, 50, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
447                                                         if (!uri.equals(target))
448                                                                 EFS.getStore(uri).delete(EFS.NONE, new SubProgressMonitor(monitor, 50, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
449                                                 } else
450                                                         store.copy(EFS.getStore(uri), EFS.OVERWRITE, new SubProgressMonitor(monitor, 100, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
451                                                 if (fJavaProject != null)
452                                                         fJavaProject.getResource().refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 50, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
453                                                 return;
454                                         }
455                                 }
456                         }
457                         throw new CoreException(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), 0, JarImportMessages.JarImportWizard_error_copying_jar, null));
458                 } finally {
459                         monitor.done();
460                 }
461         }
462
463         public WizardDialog generated_7221379870203952480(MigrateJarFileAction migratejarfileaction) {
464                 final ISelection selection= migratejarfileaction.fWindow.getSelectionService().getSelection();
465                 if (selection instanceof IStructuredSelection)
466                         init(migratejarfileaction.fWindow.getWorkbench(), (IStructuredSelection) selection);
467                 final WizardDialog dialog= new WizardDialog(migratejarfileaction.fWindow.getShell(), this);
468                 dialog.create();
469                 dialog.getShell().setSize(Math.max(MigrateJarFileAction.SIZING_WIZARD_WIDTH, dialog.getShell().getSize().x), MigrateJarFileAction.SIZING_WIZARD_HEIGHT);
470                 PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), IJavaHelpContextIds.JARIMPORT_WIZARD_PAGE);
471                 return dialog;
472         }
473 }