001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.jarimport;
011:
012: import java.io.File;
013: import java.io.IOException;
014: import java.io.InputStream;
015: import java.net.URI;
016: import java.util.HashSet;
017: import java.util.Set;
018: import java.util.zip.ZipEntry;
019: import java.util.zip.ZipFile;
020:
021: import org.eclipse.core.filesystem.URIUtil;
022:
023: import org.eclipse.core.runtime.Assert;
024: import org.eclipse.core.runtime.CoreException;
025:
026: import org.eclipse.core.resources.ResourcesPlugin;
027:
028: import org.eclipse.swt.SWT;
029: import org.eclipse.swt.events.ModifyEvent;
030: import org.eclipse.swt.events.ModifyListener;
031: import org.eclipse.swt.events.SelectionAdapter;
032: import org.eclipse.swt.events.SelectionEvent;
033: import org.eclipse.swt.layout.GridData;
034: import org.eclipse.swt.layout.GridLayout;
035: import org.eclipse.swt.widgets.Button;
036: import org.eclipse.swt.widgets.Composite;
037: import org.eclipse.swt.widgets.FileDialog;
038: import org.eclipse.swt.widgets.Label;
039:
040: import org.eclipse.jface.dialogs.Dialog;
041: import org.eclipse.jface.dialogs.IDialogConstants;
042: import org.eclipse.jface.viewers.DecoratingLabelProvider;
043: import org.eclipse.jface.viewers.ISelectionChangedListener;
044: import org.eclipse.jface.viewers.IStructuredSelection;
045: import org.eclipse.jface.viewers.SelectionChangedEvent;
046: import org.eclipse.jface.viewers.StructuredSelection;
047: import org.eclipse.jface.viewers.TreeViewer;
048: import org.eclipse.jface.wizard.WizardPage;
049:
050: import org.eclipse.ui.PlatformUI;
051:
052: import org.eclipse.ltk.core.refactoring.RefactoringCore;
053:
054: import org.eclipse.jdt.core.IJavaElement;
055: import org.eclipse.jdt.core.IJavaModel;
056: import org.eclipse.jdt.core.IJavaProject;
057: import org.eclipse.jdt.core.IPackageFragment;
058: import org.eclipse.jdt.core.IPackageFragmentRoot;
059: import org.eclipse.jdt.core.JavaCore;
060: import org.eclipse.jdt.core.JavaModelException;
061: import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
062:
063: import org.eclipse.jdt.ui.JavaElementComparator;
064: import org.eclipse.jdt.ui.JavaElementLabelProvider;
065: import org.eclipse.jdt.ui.ProblemsLabelDecorator;
066: import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
067:
068: import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
069: import org.eclipse.jdt.internal.ui.JavaPlugin;
070: import org.eclipse.jdt.internal.ui.filters.EmptyPackageFilter;
071: import org.eclipse.jdt.internal.ui.jarpackager.JarPackagerUtil;
072: import org.eclipse.jdt.internal.ui.refactoring.binary.BinaryRefactoringHistoryWizard;
073: import org.eclipse.jdt.internal.ui.util.SWTUtil;
074:
075: /**
076: * Jar import wizard page.
077: *
078: * @since 3.2
079: */
080: public final class JarImportWizardPage extends WizardPage {
081:
082: /** The jar import wizard page name */
083: private static final String PAGE_NAME = "JarImportWizardPage"; //$NON-NLS-1$
084:
085: /** The history dialog setting */
086: protected static final String SETTING_HISTORY = "org.eclipse.jdt.ui.refactoring.jarHistory"; //$NON-NLS-1$
087:
088: /** Is the wizard page displayed for the first time? */
089: private boolean fFirstTime = true;
090:
091: /** Is the wizard part of an import wizard? */
092: private final boolean fImportWizard;
093:
094: /** The location control */
095: private RefactoringLocationControl fLocationControl = null;
096:
097: /** The java model viewer */
098: private TreeViewer fTreeViewer = null;
099:
100: /** The import wizard */
101: private final JarImportWizard fWizard;
102:
103: /**
104: * Creates a new jar import wizard page.
105: *
106: * @param wizard
107: * the jar import wizard
108: * @param importWizard
109: * <code>true</code> if the wizard is part of an import wizard,
110: * <code>false</code> otherwise
111: */
112: public JarImportWizardPage(final JarImportWizard wizard,
113: final boolean importWizard) {
114: super (PAGE_NAME);
115: Assert.isNotNull(wizard);
116: fWizard = wizard;
117: fImportWizard = importWizard;
118: if (fImportWizard) {
119: setTitle(JarImportMessages.JarImportWizardPage_page_title);
120: setDescription(JarImportMessages.JarImportWizardPage_page_description);
121: } else {
122: setTitle(JarImportMessages.JarImportWizardPage_page_replace_title);
123: setDescription(JarImportMessages.JarImportWizardPage_page_replace_description);
124: }
125: }
126:
127: /**
128: * {@inheritDoc}
129: */
130: public void createControl(final Composite parent) {
131: initializeDialogUnits(parent);
132: final Composite composite = new Composite(parent, SWT.NONE);
133: composite.setLayout(new GridLayout());
134: composite.setLayoutData(new GridData(
135: GridData.VERTICAL_ALIGN_FILL
136: | GridData.HORIZONTAL_ALIGN_FILL));
137: createLocationGroup(composite);
138: if (fImportWizard)
139: createInputGroup(composite);
140: createRenameGroup(composite);
141: setPageComplete(false);
142: if (fImportWizard && !fTreeViewer.getControl().isEnabled())
143: setMessage(
144: JarImportMessages.JarImportWizardPage_no_jar_files,
145: INFORMATION);
146: setControl(composite);
147: Dialog.applyDialogFont(composite);
148: PlatformUI.getWorkbench().getHelpSystem().setHelp(composite,
149: IJavaHelpContextIds.JARIMPORT_WIZARD_PAGE);
150: }
151:
152: /**
153: * Creates a new grid data.
154: *
155: * @param flag
156: * the flags to use
157: * @param hspan
158: * the horizontal span
159: * @param indent
160: * the indent
161: * @return the grid data
162: */
163: protected GridData createGridData(final int flag, final int hspan,
164: final int indent) {
165: final GridData data = new GridData(flag);
166: data.horizontalIndent = indent;
167: data.horizontalSpan = hspan;
168: return data;
169: }
170:
171: /**
172: * Creates the input group.
173: *
174: * @param parent
175: * the parent control
176: */
177: protected void createInputGroup(final Composite parent) {
178: Assert.isNotNull(parent);
179: new Label(parent, SWT.NONE);
180: final Label label = new Label(parent, SWT.NONE);
181: label
182: .setText(JarImportMessages.JarImportWizardPage_import_message);
183: final StandardJavaElementContentProvider contentProvider = new StandardJavaElementContentProvider() {
184:
185: public Object[] getChildren(Object element) {
186: if ((element instanceof IJavaProject)
187: || (element instanceof IJavaModel))
188: return super .getChildren(element);
189: return new Object[0];
190: }
191:
192: protected Object[] getJavaProjects(final IJavaModel model)
193: throws JavaModelException {
194: final Set set = new HashSet();
195: final IJavaProject[] projects = model.getJavaProjects();
196: for (int index = 0; index < projects.length; index++) {
197: if (JarImportWizard
198: .isValidJavaProject(projects[index])) {
199: final Object[] roots = getPackageFragmentRoots(projects[index]);
200: if (roots.length > 0)
201: set.add(projects[index]);
202: }
203: }
204: return set.toArray();
205: }
206:
207: protected Object[] getPackageFragmentRoots(
208: final IJavaProject project)
209: throws JavaModelException {
210: final Set set = new HashSet();
211: final IPackageFragmentRoot[] roots = project
212: .getPackageFragmentRoots();
213: for (int offset = 0; offset < roots.length; offset++) {
214: if (JarImportWizard
215: .isValidClassPathEntry(roots[offset]
216: .getRawClasspathEntry()))
217: set.add(roots[offset]);
218: }
219: return set.toArray();
220: }
221:
222: public boolean hasChildren(final Object element) {
223: return (element instanceof IJavaProject)
224: || (element instanceof IJavaModel);
225: }
226: };
227:
228: final DecoratingLabelProvider labelProvider = new DecoratingLabelProvider(
229: new JavaElementLabelProvider(
230: JavaElementLabelProvider.SHOW_BASICS
231: | JavaElementLabelProvider.SHOW_OVERLAY_ICONS
232: | JavaElementLabelProvider.SHOW_SMALL_ICONS),
233: new ProblemsLabelDecorator(null));
234: fTreeViewer = new TreeViewer(parent, SWT.SINGLE | SWT.BORDER);
235: fTreeViewer.getTree().setLayoutData(
236: createGridData(GridData.FILL_BOTH, 6, 0));
237: fTreeViewer.setLabelProvider(labelProvider);
238: fTreeViewer.setContentProvider(contentProvider);
239: fTreeViewer.addFilter(new EmptyPackageFilter());
240: fTreeViewer.setComparator(new JavaElementComparator());
241: fTreeViewer.setAutoExpandLevel(2);
242: fTreeViewer.setInput(JavaCore.create(ResourcesPlugin
243: .getWorkspace().getRoot()));
244: final IPackageFragmentRoot root = fWizard
245: .getPackageFragmentRoot();
246: if (root != null) {
247: fTreeViewer.setSelection(new StructuredSelection(
248: new Object[] { root }), true);
249: fTreeViewer.expandToLevel(root, 1);
250: }
251: fTreeViewer
252: .addSelectionChangedListener(new ISelectionChangedListener() {
253:
254: public void selectionChanged(
255: final SelectionChangedEvent event) {
256: handleInputChanged();
257: }
258: });
259: if (contentProvider.getChildren(JavaCore.create(ResourcesPlugin
260: .getWorkspace().getRoot())).length == 0) {
261: fTreeViewer.getControl().setEnabled(false);
262: label.setEnabled(false);
263: }
264: }
265:
266: /**
267: * Creates the location group.
268: *
269: * @param parent
270: * the parent control
271: */
272: protected void createLocationGroup(final Composite parent) {
273: Assert.isNotNull(parent);
274: new Label(parent, SWT.NONE)
275: .setText(JarImportMessages.JarImportWizardPage_import_label);
276: final Composite composite = new Composite(parent, SWT.NONE);
277: composite.setLayoutData(createGridData(
278: GridData.FILL_HORIZONTAL, 6, 0));
279: composite.setLayout(new GridLayout(3, false));
280: final Label label = new Label(composite, SWT.NONE);
281: label
282: .setText(JarImportMessages.JarImportWizardPage_location_label);
283: label.setLayoutData(createGridData(
284: GridData.HORIZONTAL_ALIGN_BEGINNING, 1, 0));
285: fLocationControl = new RefactoringLocationControl(fWizard,
286: composite, SETTING_HISTORY);
287: fLocationControl.setLayoutData(createGridData(
288: GridData.FILL_HORIZONTAL, 1, 0));
289: fLocationControl.loadHistory();
290: fLocationControl.getControl().addModifyListener(
291: new ModifyListener() {
292:
293: public final void modifyText(final ModifyEvent event) {
294: handleInputChanged();
295: }
296: });
297: fLocationControl.getControl().addSelectionListener(
298: new SelectionAdapter() {
299:
300: public final void widgetSelected(
301: final SelectionEvent event) {
302: handleInputChanged();
303: }
304: });
305: fLocationControl.setFocus();
306: final Button button = new Button(composite, SWT.PUSH);
307: button
308: .setText(JarImportMessages.JarImportWizardPage_browse_button_label);
309: button.setLayoutData(createGridData(
310: GridData.HORIZONTAL_ALIGN_FILL, 1, 0));
311: SWTUtil.setButtonDimensionHint(button);
312: button.addSelectionListener(new SelectionAdapter() {
313:
314: public final void widgetSelected(final SelectionEvent event) {
315: handleBrowseButtonSelected();
316: }
317: });
318: }
319:
320: /**
321: * Creates the rename group.
322: *
323: * @param parent
324: * the parent control
325: */
326: protected void createRenameGroup(final Composite parent) {
327: Assert.isNotNull(parent);
328: final JarImportData data = fWizard.getImportData();
329: final Button button = new Button(parent, SWT.CHECK);
330: button
331: .setText(JarImportMessages.JarImportWizardPage_replace_jar_file);
332: button.setSelection(!data.isRenameJarFile());
333: button.addSelectionListener(new SelectionAdapter() {
334:
335: public void widgetSelected(final SelectionEvent event) {
336: data.setRenameJarFile(!button.getSelection());
337: }
338: });
339: if (fImportWizard && !fTreeViewer.getControl().isEnabled())
340: button.setEnabled(false);
341: if (!fImportWizard) {
342: final GridData gd = new GridData();
343: gd.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN;
344: button.setLayoutData(gd);
345: }
346: }
347:
348: /**
349: * Handles the browse button selected event.
350: */
351: protected void handleBrowseButtonSelected() {
352: final FileDialog file = new FileDialog(getShell(), SWT.OPEN);
353: file
354: .setText(JarImportMessages.JarImportWizardPage_browse_caption);
355: file.setFilterNames(new String[] { "*.jar", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$
356: file.setFilterExtensions(new String[] { "*.jar", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$
357: final String path = file.open();
358: if (path != null) {
359: fLocationControl.setText(path);
360: handleInputChanged();
361: }
362: }
363:
364: /**
365: * Handles the input changed event.
366: */
367: protected void handleInputChanged() {
368: final JarImportData data = fWizard.getImportData();
369: data.setRefactoringHistory(null);
370: data.setRefactoringFileLocation(null);
371: setErrorMessage(null);
372: setMessage(null, NONE);
373: setPageComplete(true);
374: handleJarFileChanged();
375: if (isPageComplete())
376: handlePackageFragmentRootChanged();
377: if (fImportWizard && !fTreeViewer.getControl().isEnabled())
378: setErrorMessage(JarImportMessages.JarImportWizardPage_no_jar_files);
379: fFirstTime = false;
380: getContainer().updateButtons();
381: }
382:
383: /**
384: * Handles the jar file changed event.
385: */
386: protected void handleJarFileChanged() {
387: if (fLocationControl != null) {
388: final String path = fLocationControl.getText();
389: if ("".equals(path)) { //$NON-NLS-1$
390: setErrorMessage(JarImportMessages.JarImportWizardPage_empty_location);
391: setPageComplete(false);
392: return;
393: } else {
394: final File file = new File(path);
395: if (!file.exists()) {
396: setErrorMessage(JarImportMessages.JarImportWizardPage_invalid_location);
397: setPageComplete(false);
398: return;
399: }
400: ZipFile zip = null;
401: try {
402: try {
403: zip = new ZipFile(file, ZipFile.OPEN_READ);
404: } catch (IOException exception) {
405: setErrorMessage(JarImportMessages.JarImportWizardPage_invalid_location);
406: setPageComplete(false);
407: return;
408: }
409: final JarImportData data = fWizard.getImportData();
410: data
411: .setRefactoringFileLocation(URIUtil
412: .toURI(path));
413: ZipEntry entry = zip.getEntry(JarPackagerUtil
414: .getRefactoringsEntry());
415: if (entry == null) {
416: setMessage(
417: JarImportMessages.JarImportWizardPage_no_refactorings,
418: INFORMATION);
419: setPageComplete(true);
420: return;
421: }
422: handleTimeStampChanged();
423: if (data.getExistingTimeStamp() > entry.getTime()) {
424: setMessage(
425: JarImportMessages.JarImportWizardPage_version_warning,
426: WARNING);
427: setPageComplete(true);
428: return;
429: }
430: InputStream stream = null;
431: try {
432: stream = zip.getInputStream(entry);
433: data
434: .setRefactoringHistory(RefactoringCore
435: .getHistoryService()
436: .readRefactoringHistory(
437: stream,
438: JavaRefactoringDescriptor.JAR_MIGRATION
439: | JavaRefactoringDescriptor.JAR_REFACTORING));
440: } catch (IOException exception) {
441: setErrorMessage(JarImportMessages.JarImportWizardPage_no_refactorings);
442: setPageComplete(false);
443: return;
444: } catch (CoreException exception) {
445: JavaPlugin.log(exception);
446: setErrorMessage(JarImportMessages.JarImportWizardPage_no_refactorings);
447: setPageComplete(false);
448: return;
449: } finally {
450: if (stream != null) {
451: try {
452: stream.close();
453: } catch (IOException exception) {
454: // Do nothing
455: }
456: }
457: }
458: } finally {
459: if (zip != null) {
460: try {
461: zip.close();
462: } catch (IOException e) {
463: }
464: }
465: }
466: }
467: }
468: }
469:
470: /**
471: * Handles the package fragment root changed event.
472: */
473: protected void handlePackageFragmentRootChanged() {
474: if (fTreeViewer != null) {
475: final IStructuredSelection selection = (IStructuredSelection) fTreeViewer
476: .getSelection();
477: final Object[] elements = selection.toArray();
478: if (elements.length != 1) {
479: setErrorMessage(JarImportMessages.JarImportWizardPage_select_single_jar);
480: setPageComplete(false);
481: return;
482: } else {
483: final JarImportData data = fWizard.getImportData();
484: final Object element = elements[0];
485: if (element instanceof IPackageFragmentRoot)
486: data
487: .setPackageFragmentRoot((IPackageFragmentRoot) element);
488: else if (element instanceof IPackageFragment) {
489: data
490: .setPackageFragmentRoot((IPackageFragmentRoot) ((IJavaElement) element)
491: .getParent());
492: } else {
493: setErrorMessage(JarImportMessages.JarImportWizardPage_select_single_jar);
494: setPageComplete(false);
495: }
496: }
497: }
498: }
499:
500: /**
501: * Handles the time stamp changed event.
502: */
503: protected void handleTimeStampChanged() {
504: final IPackageFragmentRoot root = fWizard
505: .getPackageFragmentRoot();
506: if (root != null) {
507: try {
508: final URI uri = BinaryRefactoringHistoryWizard
509: .getLocationURI(root.getRawClasspathEntry());
510: if (uri != null) {
511: final File file = new File(uri);
512: if (file.exists()) {
513: ZipFile zip = null;
514: try {
515: zip = new ZipFile(file, ZipFile.OPEN_READ);
516: ZipEntry entry = zip
517: .getEntry(JarPackagerUtil
518: .getRefactoringsEntry());
519: if (entry != null) {
520: fWizard.getImportData()
521: .setExistingTimeStamp(
522: entry.getTime());
523: }
524: } catch (IOException exception) {
525: // Just leave it
526: } finally {
527: if (zip != null) {
528: try {
529: zip.close();
530: } catch (IOException e) {
531: }
532: }
533: }
534: }
535: }
536: } catch (CoreException exception) {
537: JavaPlugin.log(exception);
538: }
539: }
540: }
541:
542: /**
543: * Gets called if the wizard is finished.
544: */
545: public void performFinish() {
546: fLocationControl.saveHistory();
547: }
548:
549: /**
550: * {@inheritDoc}
551: */
552: public void setErrorMessage(final String message) {
553: if (!fFirstTime)
554: super .setErrorMessage(message);
555: else
556: setMessage(message, NONE);
557: }
558:
559: /**
560: * {@inheritDoc}
561: */
562: public void setVisible(final boolean visible) {
563: super.setVisible(visible);
564: if (visible)
565: handleInputChanged();
566: }
567: }
|