001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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: * Red Hat, Inc - Extracted several methods to ArchiveFileManipulations
011: *******************************************************************************/package org.eclipse.ui.internal.wizards.datatransfer;
012:
013: import java.io.File;
014: import java.io.IOException;
015: import java.util.List;
016: import java.util.zip.ZipException;
017: import java.util.zip.ZipFile;
018:
019: import org.eclipse.jface.dialogs.IDialogSettings;
020: import org.eclipse.jface.viewers.IStructuredSelection;
021: import org.eclipse.jface.viewers.ITreeContentProvider;
022: import org.eclipse.osgi.util.NLS;
023: import org.eclipse.swt.SWT;
024: import org.eclipse.swt.widgets.Button;
025: import org.eclipse.swt.widgets.Composite;
026: import org.eclipse.swt.widgets.FileDialog;
027: import org.eclipse.swt.widgets.Listener;
028: import org.eclipse.ui.IWorkbench;
029: import org.eclipse.ui.PlatformUI;
030: import org.eclipse.ui.model.AdaptableList;
031: import org.eclipse.ui.model.WorkbenchContentProvider;
032: import org.eclipse.ui.wizards.datatransfer.ImportOperation;
033:
034: /**
035: * Page 1 of the base resource import-from-archive Wizard.
036: *
037: * Note that importing from .jar is identical to importing from .zip, so
038: * all references to .zip in this class are equally applicable to .jar
039: * references.
040: *
041: * @since 3.1
042: */
043: public class WizardArchiveFileResourceImportPage1 extends
044: WizardFileSystemResourceImportPage1 implements Listener {
045:
046: ZipLeveledStructureProvider zipCurrentProvider;
047: TarLeveledStructureProvider tarCurrentProvider;
048:
049: // constants
050: private static final String[] FILE_IMPORT_MASK = {
051: "*.jar;*.zip;*.tar;*.tar.gz;*.tgz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$
052:
053: // dialog store id constants
054: private final static String STORE_SOURCE_NAMES_ID = "WizardZipFileResourceImportPage1.STORE_SOURCE_NAMES_ID"; //$NON-NLS-1$
055:
056: private final static String STORE_OVERWRITE_EXISTING_RESOURCES_ID = "WizardZipFileResourceImportPage1.STORE_OVERWRITE_EXISTING_RESOURCES_ID"; //$NON-NLS-1$
057:
058: private final static String STORE_SELECTED_TYPES_ID = "WizardZipFileResourceImportPage1.STORE_SELECTED_TYPES_ID"; //$NON-NLS-1$
059:
060: /**
061: * Creates an instance of this class
062: * @param aWorkbench IWorkbench
063: * @param selection IStructuredSelection
064: */
065: public WizardArchiveFileResourceImportPage1(IWorkbench aWorkbench,
066: IStructuredSelection selection) {
067: super ("zipFileImportPage1", aWorkbench, selection); //$NON-NLS-1$
068: setTitle(DataTransferMessages.ArchiveExport_exportTitle);
069: setDescription(DataTransferMessages.ArchiveImport_description);
070: }
071:
072: /**
073: * Called when the user presses the Cancel button. Return a boolean
074: * indicating permission to close the wizard.
075: *
076: * @return boolean
077: */
078: public boolean cancel() {
079: clearProviderCache();
080: return true;
081: }
082:
083: /**
084: * Clears the cached structure provider after first finalizing
085: * it properly.
086: */
087: protected void clearProviderCache() {
088: ArchiveFileManipulations.clearProviderCache(getContainer()
089: .getShell());
090: }
091:
092: /**
093: * Attempts to close the passed zip file, and answers a boolean indicating success.
094: */
095: protected boolean closeZipFile(ZipFile file) {
096: try {
097: file.close();
098: } catch (IOException e) {
099: displayErrorDialog(NLS.bind(
100: DataTransferMessages.ZipImport_couldNotClose, file
101: .getName()));
102: return false;
103: }
104:
105: return true;
106: }
107:
108: /** (non-Javadoc)
109: * Method declared on IDialogPage.
110: */
111: public void createControl(Composite parent) {
112: super .createControl(parent);
113: PlatformUI
114: .getWorkbench()
115: .getHelpSystem()
116: .setHelp(
117: getControl(),
118: IDataTransferHelpContextIds.ZIP_FILE_IMPORT_WIZARD_PAGE);
119: }
120:
121: /**
122: * Create the options specification widgets. There is only one
123: * in this case so create no group.
124: *
125: * @param parent org.eclipse.swt.widgets.Composite
126: */
127: protected void createOptionsGroup(Composite parent) {
128:
129: // overwrite... checkbox
130: overwriteExistingResourcesCheckbox = new Button(parent,
131: SWT.CHECK);
132: overwriteExistingResourcesCheckbox
133: .setText(DataTransferMessages.FileImport_overwriteExisting);
134: overwriteExistingResourcesCheckbox.setFont(parent.getFont());
135: }
136:
137: private boolean validateSourceFile(String fileName) {
138: if (ArchiveFileManipulations.isTarFile(fileName)) {
139: TarFile tarFile = getSpecifiedTarSourceFile(fileName);
140: return (tarFile != null);
141: }
142: ZipFile zipFile = getSpecifiedZipSourceFile(fileName);
143: if (zipFile != null) {
144: ArchiveFileManipulations.closeZipFile(zipFile,
145: getContainer().getShell());
146: return true;
147: }
148: return false;
149: }
150:
151: /**
152: * Answer a boolean indicating whether the specified source currently exists
153: * and is valid (ie.- proper format)
154: */
155: private boolean ensureZipSourceIsValid() {
156: ZipFile specifiedFile = getSpecifiedZipSourceFile();
157: if (specifiedFile == null) {
158: return false;
159: }
160: return ArchiveFileManipulations.closeZipFile(specifiedFile,
161: getContainer().getShell());
162: }
163:
164: private boolean ensureTarSourceIsValid() {
165: TarFile specifiedFile = getSpecifiedTarSourceFile();
166: if (specifiedFile == null) {
167: return false;
168: }
169: return true;
170: }
171:
172: /**
173: * Answer a boolean indicating whether the specified source currently exists
174: * and is valid (ie.- proper format)
175: */
176: protected boolean ensureSourceIsValid() {
177: if (ArchiveFileManipulations.isTarFile(sourceNameField
178: .getText())) {
179: return ensureTarSourceIsValid();
180: }
181: return ensureZipSourceIsValid();
182: }
183:
184: /**
185: * The Finish button was pressed. Try to do the required work now and answer
186: * a boolean indicating success. If <code>false</code> is returned then the
187: * wizard will not close.
188: *
189: * @return boolean
190: */
191: public boolean finish() {
192: if (!super .finish()) {
193: return false;
194: }
195:
196: ArchiveFileManipulations.clearProviderCache(getContainer()
197: .getShell());
198: return true;
199: }
200:
201: /**
202: * Returns a content provider for <code>FileSystemElement</code>s that returns
203: * only files as children.
204: */
205: protected ITreeContentProvider getFileProvider() {
206: return new WorkbenchContentProvider() {
207: public Object[] getChildren(Object o) {
208: if (o instanceof MinimizedFileSystemElement) {
209: MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
210: AdaptableList l;
211: if (zipCurrentProvider != null) {
212: l = element.getFiles(zipCurrentProvider);
213: } else {
214: l = element.getFiles(tarCurrentProvider);
215: }
216: return l.getChildren(element);
217: }
218: return new Object[0];
219: }
220: };
221: }
222:
223: /**
224: * Answer the root FileSystemElement that represents the contents of the
225: * currently-specified .zip file. If this FileSystemElement is not
226: * currently defined then create and return it.
227: */
228: protected MinimizedFileSystemElement getFileSystemTree() {
229: if (ArchiveFileManipulations.isTarFile(sourceNameField
230: .getText())) {
231: TarFile sourceTarFile = getSpecifiedTarSourceFile();
232: if (sourceTarFile == null) {
233: //Clear out the provider as well
234: this .zipCurrentProvider = null;
235: this .tarCurrentProvider = null;
236: return null;
237: }
238:
239: TarLeveledStructureProvider provider = ArchiveFileManipulations
240: .getTarStructureProvider(sourceTarFile,
241: getContainer().getShell());
242: this .tarCurrentProvider = provider;
243: this .zipCurrentProvider = null;
244: return selectFiles(provider.getRoot(), provider);
245: }
246:
247: ZipFile sourceFile = getSpecifiedZipSourceFile();
248: if (sourceFile == null) {
249: //Clear out the provider as well
250: this .zipCurrentProvider = null;
251: this .tarCurrentProvider = null;
252: return null;
253: }
254:
255: ZipLeveledStructureProvider provider = ArchiveFileManipulations
256: .getZipStructureProvider(sourceFile, getContainer()
257: .getShell());
258: this .zipCurrentProvider = provider;
259: this .tarCurrentProvider = null;
260: return selectFiles(provider.getRoot(), provider);
261: }
262:
263: /**
264: * Returns a content provider for <code>FileSystemElement</code>s that returns
265: * only folders as children.
266: */
267: protected ITreeContentProvider getFolderProvider() {
268: return new WorkbenchContentProvider() {
269: public Object[] getChildren(Object o) {
270: if (o instanceof MinimizedFileSystemElement) {
271: MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
272: AdaptableList l;
273: if (zipCurrentProvider != null) {
274: l = element.getFolders(zipCurrentProvider);
275: } else {
276: l = element.getFolders(tarCurrentProvider);
277: }
278: return l.getChildren(element);
279: }
280: return new Object[0];
281: }
282:
283: public boolean hasChildren(Object o) {
284: if (o instanceof MinimizedFileSystemElement) {
285: MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
286: if (element.isPopulated()) {
287: return getChildren(element).length > 0;
288: }
289:
290: //If we have not populated then wait until asked
291: return true;
292: }
293: return false;
294: }
295: };
296: }
297:
298: /**
299: * Answer the string to display as the label for the source specification field
300: */
301: protected String getSourceLabel() {
302: return DataTransferMessages.ArchiveImport_fromFile;
303: }
304:
305: /**
306: * Answer a handle to the zip file currently specified as being the source.
307: * Return null if this file does not exist or is not of valid format.
308: */
309: protected ZipFile getSpecifiedZipSourceFile() {
310: return getSpecifiedZipSourceFile(sourceNameField.getText());
311: }
312:
313: /**
314: * Answer a handle to the zip file currently specified as being the source.
315: * Return null if this file does not exist or is not of valid format.
316: */
317: private ZipFile getSpecifiedZipSourceFile(String fileName) {
318: if (fileName.length() == 0) {
319: return null;
320: }
321:
322: try {
323: return new ZipFile(fileName);
324: } catch (ZipException e) {
325: displayErrorDialog(DataTransferMessages.ZipImport_badFormat);
326: } catch (IOException e) {
327: displayErrorDialog(DataTransferMessages.ZipImport_couldNotRead);
328: }
329:
330: sourceNameField.setFocus();
331: return null;
332: }
333:
334: /**
335: * Answer a handle to the zip file currently specified as being the source.
336: * Return null if this file does not exist or is not of valid format.
337: */
338: protected TarFile getSpecifiedTarSourceFile() {
339: return getSpecifiedTarSourceFile(sourceNameField.getText());
340: }
341:
342: /**
343: * Answer a handle to the zip file currently specified as being the source.
344: * Return null if this file does not exist or is not of valid format.
345: */
346: private TarFile getSpecifiedTarSourceFile(String fileName) {
347: if (fileName.length() == 0) {
348: return null;
349: }
350:
351: try {
352: return new TarFile(fileName);
353: } catch (TarException e) {
354: displayErrorDialog(DataTransferMessages.TarImport_badFormat);
355: } catch (IOException e) {
356: displayErrorDialog(DataTransferMessages.ZipImport_couldNotRead);
357: }
358:
359: sourceNameField.setFocus();
360: return null;
361: }
362:
363: /**
364: * Open a FileDialog so that the user can specify the source
365: * file to import from
366: */
367: protected void handleSourceBrowseButtonPressed() {
368: String selectedFile = queryZipFileToImport();
369:
370: if (selectedFile != null) {
371: //Be sure it is valid before we go setting any names
372: if (!selectedFile.equals(sourceNameField.getText())
373: && validateSourceFile(selectedFile)) {
374: setSourceName(selectedFile);
375: selectionGroup.setFocus();
376: }
377: }
378: }
379:
380: /**
381: * Import the resources with extensions as specified by the user
382: */
383: protected boolean importResources(List fileSystemObjects) {
384: boolean result = false;
385:
386: if (ArchiveFileManipulations.isTarFile(sourceNameField
387: .getText())) {
388: if (ensureTarSourceIsValid()) {
389: TarFile tarFile = getSpecifiedTarSourceFile();
390: TarLeveledStructureProvider structureProvider = ArchiveFileManipulations
391: .getTarStructureProvider(tarFile,
392: getContainer().getShell());
393: ImportOperation operation = new ImportOperation(
394: getContainerFullPath(), structureProvider
395: .getRoot(), structureProvider, this ,
396: fileSystemObjects);
397:
398: operation.setContext(getShell());
399: return executeImportOperation(operation);
400: }
401: }
402:
403: if (ensureZipSourceIsValid()) {
404: ZipFile zipFile = getSpecifiedZipSourceFile();
405: ZipLeveledStructureProvider structureProvider = ArchiveFileManipulations
406: .getZipStructureProvider(zipFile, getContainer()
407: .getShell());
408: ImportOperation operation = new ImportOperation(
409: getContainerFullPath(),
410: structureProvider.getRoot(), structureProvider,
411: this , fileSystemObjects);
412:
413: operation.setContext(getShell());
414: result = executeImportOperation(operation);
415:
416: closeZipFile(zipFile);
417: }
418: return result;
419: }
420:
421: /**
422: * Initializes the specified operation appropriately.
423: */
424: protected void initializeOperation(ImportOperation op) {
425: op.setOverwriteResources(overwriteExistingResourcesCheckbox
426: .getSelection());
427: }
428:
429: /**
430: * Opens a file selection dialog and returns a string representing the
431: * selected file, or <code>null</code> if the dialog was canceled.
432: */
433: protected String queryZipFileToImport() {
434: FileDialog dialog = new FileDialog(sourceNameField.getShell(),
435: SWT.OPEN);
436: dialog.setFilterExtensions(FILE_IMPORT_MASK);
437: dialog.setText(DataTransferMessages.ArchiveImportSource_title);
438:
439: String currentSourceString = sourceNameField.getText();
440: int lastSeparatorIndex = currentSourceString
441: .lastIndexOf(File.separator);
442: if (lastSeparatorIndex != -1) {
443: dialog.setFilterPath(currentSourceString.substring(0,
444: lastSeparatorIndex));
445: }
446:
447: return dialog.open();
448: }
449:
450: /**
451: * Repopulate the view based on the currently entered directory.
452: */
453: protected void resetSelection() {
454:
455: super .resetSelection();
456: setAllSelections(true);
457: }
458:
459: /**
460: * Use the dialog store to restore widget values to the values that they held
461: * last time this wizard was used to completion
462: */
463: protected void restoreWidgetValues() {
464: IDialogSettings settings = getDialogSettings();
465: if (settings != null) {
466: String[] sourceNames = settings
467: .getArray(STORE_SOURCE_NAMES_ID);
468: if (sourceNames == null) {
469: return; // ie.- no settings stored
470: }
471:
472: // set filenames history
473: for (int i = 0; i < sourceNames.length; i++) {
474: sourceNameField.add(sourceNames[i]);
475: }
476:
477: // radio buttons and checkboxes
478: overwriteExistingResourcesCheckbox.setSelection(settings
479: .getBoolean(STORE_OVERWRITE_EXISTING_RESOURCES_ID));
480: }
481: }
482:
483: /**
484: * Since Finish was pressed, write widget values to the dialog store so that they
485: * will persist into the next invocation of this wizard page.
486: *
487: * Note that this method is identical to the one that appears in the superclass.
488: * This is necessary because proper overriding of instance variables is not occurring.
489: */
490: protected void saveWidgetValues() {
491: IDialogSettings settings = getDialogSettings();
492: if (settings != null) {
493: // update source names history
494: String[] sourceNames = settings
495: .getArray(STORE_SOURCE_NAMES_ID);
496: if (sourceNames == null) {
497: sourceNames = new String[0];
498: }
499:
500: sourceNames = addToHistory(sourceNames, sourceNameField
501: .getText());
502: settings.put(STORE_SOURCE_NAMES_ID, sourceNames);
503:
504: // update specific types to import history
505: String[] selectedTypesNames = settings
506: .getArray(STORE_SELECTED_TYPES_ID);
507: if (selectedTypesNames == null) {
508: selectedTypesNames = new String[0];
509: }
510:
511: settings.put(STORE_OVERWRITE_EXISTING_RESOURCES_ID,
512: overwriteExistingResourcesCheckbox.getSelection());
513: }
514: }
515:
516: /**
517: * Answer a boolean indicating whether self's source specification
518: * widgets currently all contain valid values.
519: */
520: protected boolean validateSourceGroup() {
521:
522: //If there is nothing being provided to the input then there is a problem
523: if (this .zipCurrentProvider == null
524: && this .tarCurrentProvider == null) {
525: setMessage(SOURCE_EMPTY_MESSAGE);
526: enableButtonGroup(false);
527: return false;
528: }
529:
530: List resourcesToExport = selectionGroup
531: .getAllWhiteCheckedItems();
532: if (resourcesToExport.size() == 0) {
533: setErrorMessage(DataTransferMessages.FileImport_noneSelected);
534: return false;
535: }
536:
537: enableButtonGroup(true);
538: setErrorMessage(null);
539: return true;
540: }
541: }
|