fix #774 infinite loop in net.sourceforge.phpeclipse.builder.IdentifierIndexManager...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / obfuscator / export / WizardObfuscatorResourceExportPage1.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpeclipse.obfuscator.export;
12
13 import java.io.File;
14 import java.lang.reflect.InvocationTargetException;
15 import java.util.List;
16
17 import org.eclipse.core.resources.IProject;
18 import org.eclipse.core.resources.IWorkspaceRoot;
19 import org.eclipse.core.resources.ResourcesPlugin;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.Path;
23 import org.eclipse.jface.dialogs.ErrorDialog;
24 import org.eclipse.jface.dialogs.IDialogSettings;
25 import org.eclipse.jface.dialogs.MessageDialog;
26 import org.eclipse.jface.viewers.IStructuredSelection;
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.graphics.Font;
29 import org.eclipse.swt.layout.GridData;
30 import org.eclipse.swt.layout.GridLayout;
31 import org.eclipse.swt.widgets.Button;
32 import org.eclipse.swt.widgets.Combo;
33 import org.eclipse.swt.widgets.Composite;
34 import org.eclipse.swt.widgets.DirectoryDialog;
35 import org.eclipse.swt.widgets.Event;
36 import org.eclipse.swt.widgets.Group;
37 import org.eclipse.swt.widgets.Label;
38 import org.eclipse.swt.widgets.Listener;
39 import org.eclipse.swt.widgets.Widget;
40 import org.eclipse.ui.dialogs.WizardExportResourcesPage;
41
42 /**
43  * Page 1 of the base resource export-to-file-system Wizard
44  */
45 /* package */
46 class WizardObfuscatorResourceExportPage1 extends WizardExportResourcesPage
47                 implements Listener {
48
49         // widgets
50         private Combo destinationNameField;
51
52         private Button destinationBrowseButton;
53
54         protected Button overwriteExistingFilesCheckbox;
55
56         // protected Button createDirectoryStructureButton;
57         // protected Button createSelectionOnlyButton;
58
59         // constants
60         private static final int SIZING_TEXT_FIELD_WIDTH = 250;
61
62         // dialog store id constants
63         private static final String STORE_DESTINATION_NAMES_ID = "WizardObfuscatorResourceExportPage1.STORE_DESTINATION_NAMES_ID"; //$NON-NLS-1$
64
65         private static final String STORE_OVERWRITE_EXISTING_FILES_ID = "WizardObfuscatorResourceExportPage1.STORE_OVERWRITE_EXISTING_FILES_ID"; //$NON-NLS-1$
66         // private static final String STORE_CREATE_STRUCTURE_ID =
67         // "WizardObfuscatorResourceExportPage1.STORE_CREATE_STRUCTURE_ID";
68         // //$NON-NLS-1$
69
70         // messages
71         private static final String SELECT_DESTINATION_MESSAGE = ObfuscatorExportMessages
72                         .getString("FileExport.selectDestinationMessage"); //$NON-NLS-1$
73
74         private static final String SELECT_DESTINATION_TITLE = ObfuscatorExportMessages
75                         .getString("FileExport.selectDestinationTitle"); //$NON-NLS-1$
76
77         /**
78          * Create an instance of this class
79          */
80         protected WizardObfuscatorResourceExportPage1(String name,
81                         IStructuredSelection selection) {
82                 super(name, selection);
83         }
84
85         /**
86          * Create an instance of this class
87          */
88         public WizardObfuscatorResourceExportPage1(IStructuredSelection selection) {
89                 this("fileSystemExportPage1", selection); //$NON-NLS-1$
90                 setTitle(ObfuscatorExportMessages
91                                 .getString("ObfuscatorTransfer.fileSystemTitle")); //$NON-NLS-1$
92                 setDescription(ObfuscatorExportMessages
93                                 .getString("FileExport.exportLocalFileSystem")); //$NON-NLS-1$
94         }
95
96         /**
97          * Add the passed value to self's destination widget's history
98          * 
99          * @param value
100          *            java.lang.String
101          */
102         protected void addDestinationItem(String value) {
103                 destinationNameField.add(value);
104         }
105
106         /**
107          * (non-Javadoc) Method declared on IDialogPage.
108          */
109         public void createControl(Composite parent) {
110                 super.createControl(parent);
111                 giveFocusToDestination();
112                 // WorkbenchHelp.setHelp(
113                 // getControl(),
114                 // IDataTransferHelpContextIds.FILE_SYSTEM_EXPORT_WIZARD_PAGE);
115         }
116
117         /**
118          * Create the export destination specification widgets
119          * 
120          * @param parent
121          *            org.eclipse.swt.widgets.Composite
122          */
123         protected void createDestinationGroup(Composite parent) {
124
125                 Font font = parent.getFont();
126                 // destination specification group
127                 Composite destinationSelectionGroup = new Composite(parent, SWT.NONE);
128                 GridLayout layout = new GridLayout();
129                 layout.numColumns = 3;
130                 destinationSelectionGroup.setLayout(layout);
131                 destinationSelectionGroup.setLayoutData(new GridData(
132                                 GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
133                 destinationSelectionGroup.setFont(font);
134
135                 Label destinationLabel = new Label(destinationSelectionGroup, SWT.NONE);
136                 destinationLabel.setText(getDestinationLabel());
137                 destinationLabel.setFont(font);
138
139                 // destination name entry field
140                 destinationNameField = new Combo(destinationSelectionGroup, SWT.SINGLE
141                                 | SWT.BORDER);
142                 destinationNameField.addListener(SWT.Modify, this);
143                 destinationNameField.addListener(SWT.Selection, this);
144                 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
145                                 | GridData.GRAB_HORIZONTAL);
146                 data.widthHint = SIZING_TEXT_FIELD_WIDTH;
147                 destinationNameField.setLayoutData(data);
148                 destinationNameField.setFont(font);
149
150                 // destination browse button
151                 destinationBrowseButton = new Button(destinationSelectionGroup,
152                                 SWT.PUSH);
153                 destinationBrowseButton.setText(ObfuscatorExportMessages
154                                 .getString("ObfuscatorTransfer.browse")); //$NON-NLS-1$
155                 destinationBrowseButton.addListener(SWT.Selection, this);
156                 destinationBrowseButton.setFont(font);
157                 setButtonLayoutData(destinationBrowseButton);
158
159                 new Label(parent, SWT.NONE); // vertical spacer
160         }
161
162         /**
163          * Create the buttons in the options group.
164          */
165
166         protected void createOptionsGroupButtons(Group optionsGroup) {
167
168                 Font font = optionsGroup.getFont();
169                 createOverwriteExisting(optionsGroup, font);
170
171                 // createDirectoryStructureOptions(optionsGroup, font);
172         }
173
174         /**
175          * Create the buttons for the group that determine if the entire or selected
176          * directory structure should be created.
177          * 
178          * @param optionsGroup
179          * @param font
180          */
181         // protected void createDirectoryStructureOptions(
182         // Group optionsGroup,
183         // Font font) {
184         // // create directory structure radios
185         // createDirectoryStructureButton =
186         // new Button(optionsGroup, SWT.RADIO | SWT.LEFT);
187         // createDirectoryStructureButton.setText(ObfuscatorExportMessages.getString("FileExport.createDirectoryStructure"));
188         // //$NON-NLS-1$
189         // createDirectoryStructureButton.setSelection(false);
190         // createDirectoryStructureButton.setFont(font);
191         //
192         // // create directory structure radios
193         // createSelectionOnlyButton =
194         // new Button(optionsGroup, SWT.RADIO | SWT.LEFT);
195         // createSelectionOnlyButton.setText(
196         // ObfuscatorExportMessages.getString(
197         // "FileExport.createSelectedDirectories"));//$NON-NLS-1$
198         // createSelectionOnlyButton.setSelection(true);
199         // createSelectionOnlyButton.setFont(font);
200         // }
201         /**
202          * Create the button for checking if we should ask if we are going to
203          * overwrite existing files.
204          * 
205          * @param optionsGroup
206          * @param font
207          */
208         protected void createOverwriteExisting(Group optionsGroup, Font font) {
209                 // overwrite... checkbox
210                 overwriteExistingFilesCheckbox = new Button(optionsGroup, SWT.CHECK
211                                 | SWT.LEFT);
212                 overwriteExistingFilesCheckbox.setText(ObfuscatorExportMessages
213                                 .getString("ExportFile.overwriteExisting")); //$NON-NLS-1$
214                 overwriteExistingFilesCheckbox.setFont(font);
215         }
216
217         /**
218          * Attempts to ensure that the specified directory exists on the local file
219          * system. Answers a boolean indicating success.
220          * 
221          * @return boolean
222          * @param directory
223          *            java.io.File
224          */
225         protected boolean ensureDirectoryExists(File directory) {
226                 if (!directory.exists()) {
227                         if (!queryYesNoQuestion(ObfuscatorExportMessages
228                                         .getString("ObfuscatorTransfer.createTargetDirectory"))) //$NON-NLS-1$
229                                 return false;
230
231                         if (!directory.mkdirs()) {
232                                 displayErrorDialog(ObfuscatorExportMessages
233                                                 .getString("ObfuscatorTransfer.directoryCreationError")); //$NON-NLS-1$
234                                 giveFocusToDestination();
235                                 return false;
236                         }
237                 }
238
239                 return true;
240         }
241
242         /**
243          * If the target for export does not exist then attempt to create it. Answer
244          * a boolean indicating whether the target exists (ie.- if it either
245          * pre-existed or this method was able to create it)
246          * 
247          * @return boolean
248          */
249         protected boolean ensureTargetIsValid(File targetDirectory) {
250                 if (targetDirectory.exists() && !targetDirectory.isDirectory()) {
251                         displayErrorDialog(ObfuscatorExportMessages
252                                         .getString("FileExport.directoryExists")); //$NON-NLS-1$
253                         giveFocusToDestination();
254                         return false;
255                 }
256
257                 return ensureDirectoryExists(targetDirectory);
258         }
259
260         /**
261          * Set up and execute the passed Operation. Answer a boolean indicating
262          * success.
263          * 
264          * @return boolean
265          */
266         protected boolean executeExportOperation(ObfuscatorExportOperation op) {
267                 // op.setCreateLeadupStructure(
268                 // createDirectoryStructureButton.getSelection());
269                 op.setOverwriteFiles(overwriteExistingFilesCheckbox.getSelection());
270
271                 try {
272                         getContainer().run(true, true, op);
273                 } catch (InterruptedException e) {
274                         return false;
275                 } catch (InvocationTargetException e) {
276                         displayErrorDialog(e.getTargetException());
277                         return false;
278                 }
279
280                 IStatus status = op.getStatus();
281                 if (!status.isOK()) {
282                         ErrorDialog.openError(getContainer().getShell(),
283                                         ObfuscatorExportMessages
284                                                         .getString("ObfuscatorTransfer.exportProblems"), //$NON-NLS-1$
285                                         null, // no special message
286                                         status);
287                         return false;
288                 }
289
290                 return true;
291         }
292
293         /**
294          * The Finish button was pressed. Try to do the required work now and answer
295          * a boolean indicating success. If false is returned then the wizard will
296          * not close.
297          * 
298          * @return boolean
299          */
300         public boolean finish() {
301                 if (!ensureTargetIsValid(new File(getDestinationValue())))
302                         return false;
303
304                 List resourcesToExport = getWhiteCheckedResources();
305
306                 // Save dirty editors if possible but do not stop if not all are saved
307                 saveDirtyEditors();
308                 // about to invoke the operation so save our state
309                 saveWidgetValues();
310
311                 if (resourcesToExport.size() > 0)
312                         return executeExportOperation(new ObfuscatorExportOperation(null,
313                                         resourcesToExport, getDestinationValue(), this));
314
315                 MessageDialog.openInformation(getContainer().getShell(),
316                                 ObfuscatorExportMessages
317                                                 .getString("ObfuscatorTransfer.information"), //$NON-NLS-1$
318                                 ObfuscatorExportMessages.getString("FileExport.noneSelected")); //$NON-NLS-1$
319
320                 return false;
321         }
322
323         /**
324          * Answer the string to display in self as the destination type
325          * 
326          * @return java.lang.String
327          */
328         protected String getDestinationLabel() {
329                 return ObfuscatorExportMessages.getString("FileExport.toDirectory"); //$NON-NLS-1$
330         }
331
332         /**
333          * Answer the contents of self's destination specification widget
334          * 
335          * @return java.lang.String
336          */
337         protected String getDestinationValue() {
338                 return destinationNameField.getText().trim();
339         }
340
341         /**
342          * Set the current input focus to self's destination entry field
343          */
344         protected void giveFocusToDestination() {
345                 destinationNameField.setFocus();
346         }
347
348         /**
349          * Open an appropriate destination browser so that the user can specify a
350          * source to import from
351          */
352         protected void handleDestinationBrowseButtonPressed() {
353                 DirectoryDialog dialog = new DirectoryDialog(getContainer().getShell(),
354                                 SWT.SAVE);
355                 dialog.setMessage(SELECT_DESTINATION_MESSAGE);
356                 dialog.setText(SELECT_DESTINATION_TITLE);
357                 dialog.setFilterPath(getDestinationValue());
358                 String selectedDirectoryName = dialog.open();
359
360                 if (selectedDirectoryName != null) {
361                         setErrorMessage(null);
362                         setDestinationValue(selectedDirectoryName);
363                 }
364         }
365
366         /**
367          * Handle all events and enablements for widgets in this page
368          * 
369          * @param e
370          *            Event
371          */
372         public void handleEvent(Event e) {
373                 Widget source = e.widget;
374
375                 if (source == destinationBrowseButton)
376                         handleDestinationBrowseButtonPressed();
377
378                 updatePageCompletion();
379         }
380
381         /**
382          * Hook method for saving widget values for restoration by the next instance
383          * of this class.
384          */
385         protected void internalSaveWidgetValues() {
386                 // update directory names history
387                 IDialogSettings settings = getDialogSettings();
388                 if (settings != null) {
389                         String[] directoryNames = settings
390                                         .getArray(STORE_DESTINATION_NAMES_ID);
391                         if (directoryNames == null)
392                                 directoryNames = new String[0];
393
394                         directoryNames = addToHistory(directoryNames, getDestinationValue());
395                         settings.put(STORE_DESTINATION_NAMES_ID, directoryNames);
396
397                         // options
398                         settings.put(STORE_OVERWRITE_EXISTING_FILES_ID,
399                                         overwriteExistingFilesCheckbox.getSelection());
400
401                         // settings.put(
402                         // STORE_CREATE_STRUCTURE_ID,
403                         // createDirectoryStructureButton.getSelection());
404
405                 }
406         }
407
408         /**
409          * Hook method for restoring widget values to the values that they held last
410          * time this wizard was used to completion.
411          */
412         protected void restoreWidgetValues() {
413                 IDialogSettings settings = getDialogSettings();
414                 if (settings != null) {
415                         String[] directoryNames = settings
416                                         .getArray(STORE_DESTINATION_NAMES_ID);
417                         if (directoryNames == null)
418                                 return; // ie.- no settings stored
419
420                         // destination
421                         setDestinationValue(directoryNames[0]);
422                         for (int i = 0; i < directoryNames.length; i++)
423                                 addDestinationItem(directoryNames[i]);
424
425                         // options
426                         overwriteExistingFilesCheckbox.setSelection(settings
427                                         .getBoolean(STORE_OVERWRITE_EXISTING_FILES_ID));
428
429                         // boolean createDirectories =
430                         // settings.getBoolean(STORE_CREATE_STRUCTURE_ID);
431                         // createDirectoryStructureButton.setSelection(createDirectories);
432                         // createSelectionOnlyButton.setSelection(!createDirectories);
433                 }
434         }
435
436         /**
437          * Set the contents of the receivers destination specification widget to the
438          * passed value
439          * 
440          */
441         protected void setDestinationValue(String value) {
442                 destinationNameField.setText(value);
443         }
444
445         /**
446          * Answer a boolean indicating whether the receivers destination
447          * specification widgets currently all contain valid values.
448          */
449         protected boolean validateDestinationGroup() {
450                 String destinationValue = getDestinationValue();
451                 if (destinationValue.length() == 0) {
452                         setMessage(destinationEmptyMessage());
453                         return false;
454                 }
455
456                 String conflictingContainer = getConflictingContainerNameFor(destinationValue);
457                 if (conflictingContainer == null)
458                         setErrorMessage(""); //$NON-NLS-1$
459                 else {
460                         setErrorMessage(ObfuscatorExportMessages.format(
461                                         "FileExport.conflictingContainer", //$NON-NLS-1$
462                                         new Object[] { conflictingContainer }));
463                         giveFocusToDestination();
464                         return false;
465                 }
466
467                 return true;
468         }
469
470         /**
471          * Get the message used to denote an empty destination.
472          */
473         protected String destinationEmptyMessage() {
474                 return ObfuscatorExportMessages
475                                 .getString("FileExport.destinationEmpty"); //$NON-NLS-1$
476         }
477
478         /**
479          * Returns the name of a container with a location that encompasses
480          * targetDirectory. Returns null if there is no conflict.
481          * 
482          * @param targetDirectory
483          *            the path of the directory to check.
484          * @return the conflicting container name or <code>null</code>
485          */
486         protected String getConflictingContainerNameFor(String targetDirectory) {
487
488                 IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
489                 IPath testPath = new Path(targetDirectory);
490
491                 if (root.getFullPath().isPrefixOf(testPath))
492                         return ObfuscatorExportMessages.getString("FileExport.rootName"); //$NON-NLS-1$
493
494                 IProject[] projects = root.getProjects();
495
496                 for (int i = 0; i < projects.length; i++) {
497                         if (projects[i].getFullPath().isPrefixOf(testPath))
498                                 return projects[i].getName();
499                 }
500
501                 return null;
502
503         }
504
505 }