]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-before/ui/org/eclipse/jdt/internal/ui/jarpackager/JarManifestWizardPage.java
Some talks, mostly identical.
[ifi-stolz-refaktor.git] / case-study / jdt-before / ui / org / eclipse / jdt / internal / ui / jarpackager / JarManifestWizardPage.java
CommitLineData
1b2798f6
EK
1/*******************************************************************************
2 * Copyright (c) 2000, 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 *******************************************************************************/
11package org.eclipse.jdt.internal.ui.jarpackager;
12
13import java.lang.reflect.InvocationTargetException;
14import java.util.ArrayList;
15import java.util.Arrays;
16import java.util.HashSet;
17import java.util.Iterator;
18import java.util.List;
19import java.util.Set;
20import java.util.jar.Attributes;
21import java.util.jar.Manifest;
22
23import org.eclipse.swt.SWT;
24import org.eclipse.swt.events.KeyAdapter;
25import org.eclipse.swt.events.KeyEvent;
26import org.eclipse.swt.events.SelectionAdapter;
27import org.eclipse.swt.events.SelectionEvent;
28import org.eclipse.swt.layout.GridData;
29import org.eclipse.swt.layout.GridLayout;
30import org.eclipse.swt.widgets.Button;
31import org.eclipse.swt.widgets.Composite;
32import org.eclipse.swt.widgets.Control;
33import org.eclipse.swt.widgets.Event;
34import org.eclipse.swt.widgets.Label;
35import org.eclipse.swt.widgets.Listener;
36import org.eclipse.swt.widgets.Text;
37
38import org.eclipse.core.runtime.CoreException;
39import org.eclipse.core.runtime.IPath;
40import org.eclipse.core.runtime.IStatus;
41import org.eclipse.core.runtime.Path;
42
43import org.eclipse.core.resources.IFile;
44import org.eclipse.core.resources.IResource;
45import org.eclipse.core.resources.IWorkspace;
46
47import org.eclipse.jface.dialogs.Dialog;
48import org.eclipse.jface.dialogs.IDialogSettings;
49import org.eclipse.jface.dialogs.IMessageProvider;
50import org.eclipse.jface.resource.JFaceResources;
51import org.eclipse.jface.viewers.DecoratingLabelProvider;
52import org.eclipse.jface.window.Window;
53import org.eclipse.jface.wizard.IWizardPage;
54import org.eclipse.jface.wizard.WizardPage;
55
56import org.eclipse.ui.PlatformUI;
57import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
58import org.eclipse.ui.dialogs.ISelectionStatusValidator;
59import org.eclipse.ui.dialogs.SaveAsDialog;
60import org.eclipse.ui.dialogs.SelectionDialog;
61
62import org.eclipse.jdt.core.ICompilationUnit;
63import org.eclipse.jdt.core.IJavaElement;
64import org.eclipse.jdt.core.IPackageFragment;
65import org.eclipse.jdt.core.IPackageFragmentRoot;
66import org.eclipse.jdt.core.IType;
67import org.eclipse.jdt.core.JavaCore;
68import org.eclipse.jdt.core.JavaModelException;
69import org.eclipse.jdt.core.search.IJavaSearchScope;
70
71import org.eclipse.jdt.internal.corext.util.Messages;
72
73import org.eclipse.jdt.ui.JavaElementComparator;
74import org.eclipse.jdt.ui.JavaElementLabelProvider;
75import org.eclipse.jdt.ui.JavaElementLabels;
76import org.eclipse.jdt.ui.JavaUI;
77import org.eclipse.jdt.ui.ProblemsLabelDecorator;
78import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
79import org.eclipse.jdt.ui.jarpackager.JarPackageData;
80
81import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
82import org.eclipse.jdt.internal.ui.JavaPlugin;
83import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
84import org.eclipse.jdt.internal.ui.filters.EmptyInnerPackageFilter;
85import org.eclipse.jdt.internal.ui.search.JavaSearchScopeFactory;
86import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
87import org.eclipse.jdt.internal.ui.util.MainMethodSearchEngine;
88import org.eclipse.jdt.internal.ui.util.SWTUtil;
89import org.eclipse.jdt.internal.ui.viewsupport.LibraryFilter;
90
91/**
92 * Page 3 of the JAR Package wizard
93 */
94class JarManifestWizardPage extends WizardPage implements IJarPackageWizardPage {
95
96 // Untyped listener
97 private class UntypedListener implements Listener {
98 /*
99 * Implements method from Listener
100 */
101 public void handleEvent(Event e) {
102 if (getControl() == null)
103 return;
104 update();
105 }
106 }
107 private UntypedListener fUntypedListener= new UntypedListener();
108
109 // Model
110 private JarPackageData fJarPackage;
111
112 // Cache for main types
113 private IType[] fMainTypes;
114
115 // Widgets
116 private Composite fManifestGroup;
117 private Button fGenerateManifestRadioButton;
118 private Button fSaveManifestCheckbox;
119 private Button fReuseManifestCheckbox;
120 private Text fNewManifestFileText;
121 private Label fNewManifestFileLabel;
122 private Button fNewManifestFileBrowseButton;
123 private Button fUseManifestRadioButton;
124 private Text fManifestFileText;
125 private Label fManifestFileLabel;
126 private Button fManifestFileBrowseButton;
127
128 private Label fSealingHeaderLabel;
129 private Button fSealJarRadioButton;
130 private Label fSealJarLabel;
131 private Button fSealedPackagesDetailsButton;
132 private Button fSealPackagesRadioButton;
133 private Label fSealPackagesLabel;
134 private Button fUnSealedPackagesDetailsButton;
135
136 private Label fMainClassHeaderLabel;
137 private Label fMainClassLabel;
138 private Text fMainClassText;
139 private Button fMainClassBrowseButton;
140
141 // Dialog store id constants
142 private final static String PAGE_NAME= "JarManifestWizardPage"; //$NON-NLS-1$
143
144 // Manifest creation
145 private final static String STORE_GENERATE_MANIFEST= PAGE_NAME + ".GENERATE_MANIFEST"; //$NON-NLS-1$
146 private final static String STORE_SAVE_MANIFEST= PAGE_NAME + ".SAVE_MANIFEST"; //$NON-NLS-1$
147 private final static String STORE_REUSE_MANIFEST= PAGE_NAME + ".REUSE_MANIFEST"; //$NON-NLS-1$
148 private final static String STORE_MANIFEST_LOCATION= PAGE_NAME + ".MANIFEST_LOCATION"; //$NON-NLS-1$
149
150 // Sealing
151 private final static String STORE_SEAL_JAR= PAGE_NAME + ".SEAL_JAR"; //$NON-NLS-1$
152
153 /**
154 * Create an instance of this class
155 * @param jarPackage
156 */
157 public JarManifestWizardPage(JarPackageData jarPackage) {
158 super(PAGE_NAME);
159 setTitle(JarPackagerMessages.JarManifestWizardPage_title);
160 setDescription(JarPackagerMessages.JarManifestWizardPage_description);
161 fJarPackage= jarPackage;
162 }
163
164 // ----------- Widget creation -----------
165
166 /*
167 * Method declared on IDialogPage.
168 */
169 public void createControl(Composite parent) {
170
171 initializeDialogUnits(parent);
172
173 Composite composite= new Composite(parent, SWT.NULL);
174 composite.setLayout(new GridLayout());
175 composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
176
177 createLabel(composite, JarPackagerMessages.JarManifestWizardPage_manifestSource_label, false);
178 createManifestGroup(composite);
179
180 createSpacer(composite);
181
182 fSealingHeaderLabel= createLabel(composite, JarPackagerMessages.JarManifestWizardPage_sealingHeader_label, false);
183 createSealingGroup(composite);
184
185 createSpacer(composite);
186
187 fMainClassHeaderLabel= createLabel(composite, JarPackagerMessages.JarManifestWizardPage_mainClassHeader_label, false);
188 createMainClassGroup(composite);
189
190 setEqualButtonSizes();
191
192 restoreWidgetValues();
193
194 setControl(composite);
195 update();
196
197 Dialog.applyDialogFont(composite);
198 PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.JARMANIFEST_WIZARD_PAGE);
199
200 }
201 /**
202 * Create the export options specification widgets.
203 *
204 * @param parent org.eclipse.swt.widgets.Composite
205 */
206 protected void createManifestGroup(Composite parent) {
207 fManifestGroup= new Composite(parent, SWT.NONE);
208 GridLayout layout= new GridLayout();
209 fManifestGroup.setLayout(layout);
210 fManifestGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
211
212 fGenerateManifestRadioButton= new Button(fManifestGroup, SWT.RADIO | SWT.LEFT);
213 fGenerateManifestRadioButton.setText(JarPackagerMessages.JarManifestWizardPage_genetateManifest_text);
214 fGenerateManifestRadioButton.addListener(SWT.Selection, fUntypedListener);
215
216 Composite saveOptions= new Composite(fManifestGroup, SWT.NONE);
217 GridLayout saveOptionsLayout= new GridLayout();
218 saveOptionsLayout.marginWidth= 0;
219 saveOptions.setLayout(saveOptionsLayout);
220
221 GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
222 data.horizontalIndent=20;
223 saveOptions.setLayoutData(data);
224
225 fSaveManifestCheckbox= new Button(saveOptions, SWT.CHECK | SWT.LEFT);
226 fSaveManifestCheckbox.setText(JarPackagerMessages.JarManifestWizardPage_saveManifest_text);
227 fSaveManifestCheckbox.addListener(SWT.MouseUp, fUntypedListener);
228
229 fReuseManifestCheckbox= new Button(saveOptions, SWT.CHECK | SWT.LEFT);
230 fReuseManifestCheckbox.setText(JarPackagerMessages.JarManifestWizardPage_reuseManifest_text);
231 fReuseManifestCheckbox.addListener(SWT.MouseUp, fUntypedListener);
232
233 createNewManifestFileGroup(saveOptions);
234
235 fUseManifestRadioButton= new Button(fManifestGroup, SWT.RADIO | SWT.LEFT);
236 fUseManifestRadioButton.setText(JarPackagerMessages.JarManifestWizardPage_useManifest_text);
237
238 fUseManifestRadioButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
239 Composite existingManifestGroup= new Composite(fManifestGroup, SWT.NONE);
240 GridLayout existingManifestLayout= new GridLayout();
241 existingManifestLayout.marginWidth= 0;
242 existingManifestGroup.setLayout(existingManifestLayout);
243 data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
244 data.horizontalIndent=20;
245 existingManifestGroup.setLayoutData(data);
246 createManifestFileGroup(existingManifestGroup);
247 }
248
249 protected void createNewManifestFileGroup(Composite parent) {
250 // destination specification group
251 Composite manifestFileGroup= new Composite(parent, SWT.NONE);
252 GridLayout layout= new GridLayout();
253 layout.marginWidth= 0;
254 layout.numColumns= 3;
255 manifestFileGroup.setLayout(layout);
256 manifestFileGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
257
258 fNewManifestFileLabel= new Label(manifestFileGroup, SWT.NONE);
259 fNewManifestFileLabel.setText(JarPackagerMessages.JarManifestWizardPage_newManifestFile_text);
260
261 // entry field
262 fNewManifestFileText= new Text(manifestFileGroup, SWT.SINGLE | SWT.BORDER);
263 fNewManifestFileText.addListener(SWT.Modify, fUntypedListener);
264
265 GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
266 data.widthHint= convertWidthInCharsToPixels(40);
267 fNewManifestFileText.setLayoutData(data);
268
269 // browse button
270 fNewManifestFileBrowseButton= new Button(manifestFileGroup, SWT.PUSH);
271 fNewManifestFileBrowseButton.setText(JarPackagerMessages.JarManifestWizardPage_newManifestFileBrowseButton_text);
272 fNewManifestFileBrowseButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
273 fNewManifestFileBrowseButton.addSelectionListener(new SelectionAdapter() {
274 @Override
275 public void widgetSelected(SelectionEvent e) {
276 handleNewManifestFileBrowseButtonPressed();
277 }
278 });
279 }
280
281 protected void createManifestFileGroup(Composite parent) {
282 // destination specification group
283 Composite manifestFileGroup= new Composite(parent, SWT.NONE);
284 GridLayout layout= new GridLayout();
285 layout.numColumns= 3;
286 layout.marginWidth= 0;
287
288 manifestFileGroup.setLayout(layout);
289 manifestFileGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
290
291 fManifestFileLabel= new Label(manifestFileGroup, SWT.NONE);
292 fManifestFileLabel.setText(JarPackagerMessages.JarManifestWizardPage_manifestFile_text);
293
294 // entry field
295 fManifestFileText= new Text(manifestFileGroup, SWT.SINGLE | SWT.BORDER);
296 fManifestFileText.addListener(SWT.Modify, fUntypedListener);
297 GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
298 data.widthHint= convertWidthInCharsToPixels(40);
299 fManifestFileText.setLayoutData(data);
300
301 // browse button
302 fManifestFileBrowseButton= new Button(manifestFileGroup, SWT.PUSH);
303 fManifestFileBrowseButton.setText(JarPackagerMessages.JarManifestWizardPage_manifestFileBrowse_text);
304 fManifestFileBrowseButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
305 fManifestFileBrowseButton.addSelectionListener(new SelectionAdapter() {
306 @Override
307 public void widgetSelected(SelectionEvent e) {
308 handleManifestFileBrowseButtonPressed();
309 }
310 });
311 }
312 /**
313 * Creates the JAR sealing specification controls.
314 *
315 * @param parent the parent control
316 */
317 protected void createSealingGroup(Composite parent) {
318 // destination specification group
319 Composite sealingGroup= new Composite(parent, SWT.NONE);
320 GridLayout layout= new GridLayout();
321 layout.numColumns= 3;
322 layout.horizontalSpacing += 3;
323 sealingGroup.setLayout(layout);
324 sealingGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
325 createSealJarGroup(sealingGroup);
326 createSealPackagesGroup(sealingGroup);
327
328 }
329 /**
330 * Creates the JAR sealing specification controls to seal the whole JAR.
331 *
332 * @param sealGroup the parent control
333 */
334 protected void createSealJarGroup(Composite sealGroup) {
335 fSealJarRadioButton= new Button(sealGroup, SWT.RADIO);
336 fSealJarRadioButton.setText(JarPackagerMessages.JarManifestWizardPage_sealJar_text);
337 fSealJarRadioButton.addListener(SWT.Selection, fUntypedListener);
338
339 fSealJarLabel= new Label(sealGroup, SWT.RIGHT);
340 fSealJarLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
341 fSealJarLabel.setText(""); //$NON-NLS-1$
342
343 fUnSealedPackagesDetailsButton= new Button(sealGroup, SWT.PUSH);
344 fUnSealedPackagesDetailsButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
345 fUnSealedPackagesDetailsButton.setText(JarPackagerMessages.JarManifestWizardPage_unsealPackagesButton_text);
346 fUnSealedPackagesDetailsButton.addSelectionListener(new SelectionAdapter() {
347 @Override
348 public void widgetSelected(SelectionEvent e) {
349 handleUnSealPackagesDetailsButtonPressed();
350 }
351 });
352
353 }
354 /**
355 * Creates the JAR sealing specification controls to seal packages.
356 *
357 * @param sealGroup the parent control
358 */
359 protected void createSealPackagesGroup(Composite sealGroup) {
360 fSealPackagesRadioButton= new Button(sealGroup, SWT.RADIO);
361 fSealPackagesRadioButton.setText(JarPackagerMessages.JarManifestWizardPage_sealPackagesButton_text);
362
363 fSealPackagesLabel= new Label(sealGroup, SWT.RIGHT);
364 fSealPackagesLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
365 fSealPackagesLabel.setText(""); //$NON-NLS-1$
366
367 fSealedPackagesDetailsButton= new Button(sealGroup, SWT.PUSH);
368 fSealedPackagesDetailsButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
369 fSealedPackagesDetailsButton.setText(JarPackagerMessages.JarManifestWizardPage_sealedPackagesDetailsButton_text);
370 fSealedPackagesDetailsButton.addSelectionListener(new SelectionAdapter() {
371 @Override
372 public void widgetSelected(SelectionEvent e) {
373 handleSealPackagesDetailsButtonPressed();
374 }
375 });
376 }
377
378 protected void createMainClassGroup(Composite parent) {
379 // main type group
380 Composite mainClassGroup= new Composite(parent, SWT.NONE);
381 GridLayout layout= new GridLayout();
382 layout.numColumns= 3;
383 mainClassGroup.setLayout(layout);
384 mainClassGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
385
386 fMainClassLabel= new Label(mainClassGroup, SWT.NONE);
387 fMainClassLabel.setText(JarPackagerMessages.JarManifestWizardPage_mainClass_label);
388
389 // entry field
390 fMainClassText= new Text(mainClassGroup, SWT.SINGLE | SWT.BORDER);
391 fMainClassText.addListener(SWT.Modify, fUntypedListener);
392 GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
393 data.widthHint= convertWidthInCharsToPixels(40);
394 fMainClassText.setLayoutData(data);
395 fMainClassText.addKeyListener(new KeyAdapter() {
396 /*
397 * @see KeyListener#keyReleased(KeyEvent)
398 */
399 @Override
400 public void keyReleased(KeyEvent e) {
401 fJarPackage.setManifestMainClass(findMainMethodByName(fMainClassText.getText()));
402 update();
403 }
404 });
405
406 // browse button
407 fMainClassBrowseButton= new Button(mainClassGroup, SWT.PUSH);
408 fMainClassBrowseButton.setText(JarPackagerMessages.JarManifestWizardPage_mainClassBrowseButton_text);
409 fMainClassBrowseButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
410 fMainClassBrowseButton.addSelectionListener(new SelectionAdapter() {
411 @Override
412 public void widgetSelected(SelectionEvent e) {
413 handleMainClassBrowseButtonPressed();
414 }
415 });
416 }
417
418 // ----------- Event handlers -----------
419
420 private void update() {
421 updateModel();
422 updateEnableState();
423 updatePageCompletion();
424 }
425
426 /**
427 * Open an appropriate dialog so that the user can specify a manifest
428 * to save
429 */
430 protected void handleNewManifestFileBrowseButtonPressed() {
431 // Use Save As dialog to select a new file inside the workspace
432 SaveAsDialog dialog= new SaveAsDialog(getContainer().getShell());
433 dialog.create();
434 dialog.getShell().setText(JarPackagerMessages.JarManifestWizardPage_saveAsDialog_title);
435 dialog.setMessage(JarPackagerMessages.JarManifestWizardPage_saveAsDialog_message);
436 dialog.setOriginalFile(createFileHandle(fJarPackage.getManifestLocation()));
437 if (dialog.open() == Window.OK) {
438 fJarPackage.setManifestLocation(dialog.getResult());
439 fNewManifestFileText.setText(dialog.getResult().toString());
440 }
441 }
442
443 protected void handleManifestFileBrowseButtonPressed() {
444 ElementTreeSelectionDialog dialog= createWorkspaceFileSelectionDialog(JarPackagerMessages.JarManifestWizardPage_manifestSelectionDialog_title, JarPackagerMessages.JarManifestWizardPage_manifestSelectionDialog_message);
445 if (fJarPackage.isManifestAccessible())
446 dialog.setInitialSelections(new IResource[] {fJarPackage.getManifestFile()});
447 if (dialog.open() == Window.OK) {
448 Object[] resources= dialog.getResult();
449 if (resources.length != 1)
450 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_onlyOneManifestMustBeSelected);
451 else {
452 setErrorMessage(""); //$NON-NLS-1$
453 fJarPackage.setManifestLocation(((IResource)resources[0]).getFullPath());
454 fManifestFileText.setText(fJarPackage.getManifestLocation().toString());
455 }
456 }
457 }
458
459 private IType findMainMethodByName(String name) {
460 if (fMainTypes == null) {
461 List<IResource> resources= JarPackagerUtil.asResources(fJarPackage.getElements());
462 if (resources == null) {
463 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_noResourceSelected);
464 return null;
465 }
466 IJavaSearchScope searchScope= JavaSearchScopeFactory.getInstance().createJavaSearchScope(resources.toArray(new IResource[resources.size()]), true);
467 MainMethodSearchEngine engine= new MainMethodSearchEngine();
468 try {
469 fMainTypes= engine.searchMainMethods(getContainer(), searchScope, 0);
470 } catch (InvocationTargetException ex) {
471 // null
472 } catch (InterruptedException e) {
473 // null
474 }
475 }
476 for (int i= 0; i < fMainTypes.length; i++) {
477 if (fMainTypes[i].getFullyQualifiedName().equals(name))
478 return fMainTypes[i];
479 }
480 return null;
481 }
482
483 protected void handleMainClassBrowseButtonPressed() {
484 List<IResource> resources= JarPackagerUtil.asResources(fJarPackage.getElements());
485 if (resources == null) {
486 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_noResourceSelected);
487 return;
488 }
489 IJavaSearchScope searchScope= JavaSearchScopeFactory.getInstance().createJavaSearchScope(resources.toArray(new IResource[resources.size()]), true);
490 SelectionDialog dialog= JavaUI.createMainTypeDialog(getContainer().getShell(), getContainer(), searchScope, 0, false, ""); //$NON-NLS-1$
491 dialog.setTitle(JarPackagerMessages.JarManifestWizardPage_mainTypeSelectionDialog_title);
492 dialog.setMessage(JarPackagerMessages.JarManifestWizardPage_mainTypeSelectionDialog_message);
493 if (fJarPackage.getManifestMainClass() != null)
494 dialog.setInitialSelections(new Object[] {fJarPackage.getManifestMainClass()});
495
496 if (dialog.open() == Window.OK) {
497 fJarPackage.setManifestMainClass((IType)dialog.getResult()[0]);
498 fMainClassText.setText(JarPackagerUtil.getMainClassName(fJarPackage));
499 } else if (!fJarPackage.isMainClassValid(getContainer())) {
500 // user did not cancel: no types were found
501 fJarPackage.setManifestMainClass(null);
502 fMainClassText.setText(JarPackagerUtil.getMainClassName(fJarPackage));
503 }
504 }
505
506 protected void handleSealPackagesDetailsButtonPressed() {
507 SelectionDialog dialog= createPackageDialog(getPackagesForSelectedResources());
508 dialog.setTitle(JarPackagerMessages.JarManifestWizardPage_sealedPackagesSelectionDialog_title);
509 dialog.setMessage(JarPackagerMessages.JarManifestWizardPage_sealedPackagesSelectionDialog_message);
510 dialog.setInitialSelections(fJarPackage.getPackagesToSeal());
511 if (dialog.open() == Window.OK)
512 fJarPackage.setPackagesToSeal(getPackagesFromDialog(dialog));
513 updateSealingInfo();
514 }
515
516 protected void handleUnSealPackagesDetailsButtonPressed() {
517 SelectionDialog dialog= createPackageDialog(getPackagesForSelectedResources());
518 dialog.setTitle(JarPackagerMessages.JarManifestWizardPage_unsealedPackagesSelectionDialog_title);
519 dialog.setMessage(JarPackagerMessages.JarManifestWizardPage_unsealedPackagesSelectionDialog_message);
520 dialog.setInitialSelections(fJarPackage.getPackagesToUnseal());
521 if (dialog.open() == Window.OK)
522 fJarPackage.setPackagesToUnseal(getPackagesFromDialog(dialog));
523 updateSealingInfo();
524 }
525 /**
526 * Updates the enable state of this page's controls. Subclasses may extend.
527 */
528 protected void updateEnableState() {
529 boolean generate= fGenerateManifestRadioButton.getSelection();
530
531 boolean save= generate && fSaveManifestCheckbox.getSelection();
532 fSaveManifestCheckbox.setEnabled(generate);
533 fReuseManifestCheckbox.setEnabled(fJarPackage.isDescriptionSaved() && save);
534 fNewManifestFileText.setEnabled(save);
535 fNewManifestFileLabel.setEnabled(save);
536 fNewManifestFileBrowseButton.setEnabled(save);
537
538 fManifestFileText.setEnabled(!generate);
539 fManifestFileLabel.setEnabled(!generate);
540 fManifestFileBrowseButton.setEnabled(!generate);
541
542 fSealingHeaderLabel.setEnabled(generate);
543 boolean sealState= fSealJarRadioButton.getSelection();
544 fSealJarRadioButton.setEnabled(generate);
545 fSealJarLabel.setEnabled(generate);
546 fUnSealedPackagesDetailsButton.setEnabled(sealState && generate);
547 fSealPackagesRadioButton.setEnabled(generate);
548 fSealPackagesLabel.setEnabled(generate);
549 fSealedPackagesDetailsButton.setEnabled(!sealState && generate);
550
551 fMainClassHeaderLabel.setEnabled(generate);
552 fMainClassLabel.setEnabled(generate);
553 fMainClassText.setEnabled(generate);
554 fMainClassBrowseButton.setEnabled(generate);
555
556 updateSealingInfo();
557 }
558
559 protected void updateSealingInfo() {
560 if (fJarPackage.isJarSealed()) {
561 fSealPackagesLabel.setText(""); //$NON-NLS-1$
562 int i= fJarPackage.getPackagesToUnseal().length;
563 if (i == 0)
564 fSealJarLabel.setText(JarPackagerMessages.JarManifestWizardPage_jarSealed);
565 else if (i == 1)
566 fSealJarLabel.setText(JarPackagerMessages.JarManifestWizardPage_jarSealedExceptOne);
567 else
568 fSealJarLabel.setText(Messages.format(JarPackagerMessages.JarManifestWizardPage_jarSealedExceptSome, new Integer(i)));
569
570 }
571 else {
572 fSealJarLabel.setText(""); //$NON-NLS-1$
573 int i= fJarPackage.getPackagesToSeal().length;
574 if (i == 0)
575 fSealPackagesLabel.setText(JarPackagerMessages.JarManifestWizardPage_nothingSealed);
576 else if (i == 1)
577 fSealPackagesLabel.setText(JarPackagerMessages.JarManifestWizardPage_onePackageSealed);
578 else
579 fSealPackagesLabel.setText(Messages.format(JarPackagerMessages.JarManifestWizardPage_somePackagesSealed, new Integer(i)));
580 }
581 }
582 /*
583 * Implements method from IJarPackageWizardPage
584 */
585 @Override
586 public boolean isPageComplete() {
587 boolean isPageComplete= true;
588 setMessage(null);
589
590 if (!fJarPackage.areGeneratedFilesExported())
591 return true;
592
593 if (fJarPackage.isManifestGenerated() && fJarPackage.isManifestSaved()) {
594 if (fJarPackage.getManifestLocation().toString().length() == 0)
595 isPageComplete= false;
596 else {
597 IPath location= fJarPackage.getManifestLocation();
598 if (!location.toString().startsWith("/")) { //$NON-NLS-1$
599 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_manifestPathMustBeAbsolute);
600 return false;
601 }
602 IResource resource= findResource(location);
603 if (resource != null && resource.getType() != IResource.FILE) {
604 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_manifestMustNotBeExistingContainer);
605 return false;
606 }
607 resource= findResource(location.removeLastSegments(1));
608 if (resource == null || resource.getType() == IResource.FILE) {
609 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_manifestContainerDoesNotExist);
610 return false;
611 }
612 }
613 }
614 if (!fJarPackage.isManifestGenerated()) {
615 if (fJarPackage.isManifestAccessible()) {
616 Manifest manifest= null;
617 try {
618 manifest= fJarPackage.getManifestProvider().create(fJarPackage);
619 } catch (CoreException ex) {
620 // nothing reported in the wizard
621 }
622 if (manifest != null && manifest.getMainAttributes().getValue(Attributes.Name.MANIFEST_VERSION) == null)
623 setMessage(JarPackagerMessages.JarManifestWizardPage_warning_noManifestVersion, IMessageProvider.WARNING);
624 } else {
625 if (fJarPackage.getManifestLocation().toString().length() == 0)
626 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_noManifestFile);
627 else
628 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_invalidManifestFile);
629 return false;
630 }
631 }
632 Set<IJavaElement> selectedPackages= getPackagesForSelectedResources();
633 if (fJarPackage.isJarSealed()
634 && !selectedPackages.containsAll(Arrays.asList(fJarPackage.getPackagesToUnseal()))) {
635 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_unsealedPackagesNotInSelection);
636 return false;
637 }
638 if (!fJarPackage.isJarSealed()
639 && !selectedPackages.containsAll(Arrays.asList(fJarPackage.getPackagesToSeal()))) {
640 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_sealedPackagesNotInSelection);
641 return false;
642 }
643 if (!fJarPackage.isMainClassValid(getContainer()) || (fJarPackage.getManifestMainClass() == null && fMainClassText.getText().length() > 0)) {
644 setErrorMessage(JarPackagerMessages.JarManifestWizardPage_error_invalidMainClass);
645 return false;
646 }
647
648 setErrorMessage(null);
649 return isPageComplete;
650 }
651
652 /*
653 * Implements method from IWizardPage.
654 */
655 @Override
656 public void setPreviousPage(IWizardPage page) {
657 super.setPreviousPage(page);
658 fMainTypes= null;
659 updateEnableState();
660 if (getContainer() != null)
661 updatePageCompletion();
662 }
663
664 /*
665 * Implements method from IJarPackageWizardPage.
666 */
667 public void finish() {
668 saveWidgetValues();
669 }
670
671 // ----------- Model handling -----------
672
673 /**
674 * Persists resource specification control setting that are to be restored
675 * in the next instance of this page. Subclasses wishing to persist
676 * settings for their controls should extend the hook method
677 * <code>internalSaveWidgetValues</code>.
678 */
679 public final void saveWidgetValues() {
680 IDialogSettings settings= getDialogSettings();
681 if (settings != null) {
682 // Manifest creation
683 settings.put(STORE_GENERATE_MANIFEST, fJarPackage.isManifestGenerated());
684 settings.put(STORE_SAVE_MANIFEST, fJarPackage.isManifestSaved());
685 settings.put(STORE_REUSE_MANIFEST, fJarPackage.isManifestReused());
686 settings.put(STORE_MANIFEST_LOCATION, fJarPackage.getManifestLocation().toString());
687
688 // Sealing
689 settings.put(STORE_SEAL_JAR, fJarPackage.isJarSealed());
690 }
691
692 // Allow subclasses to save values
693 internalSaveWidgetValues();
694 }
695 /**
696 * Hook method for subclasses to persist their settings.
697 */
698 protected void internalSaveWidgetValues() {
699 }
700 /**
701 * Hook method for restoring widget values to the values that they held
702 * last time this wizard was used to completion.
703 */
704 protected void restoreWidgetValues() {
705 if (!((JarPackageWizard)getWizard()).isInitializingFromJarPackage())
706 initializeJarPackage();
707
708 // Manifest creation
709 if (fJarPackage.isManifestGenerated())
710 fGenerateManifestRadioButton.setSelection(true);
711 else
712 fUseManifestRadioButton.setSelection(true);
713 fSaveManifestCheckbox.setSelection(fJarPackage.isManifestSaved());
714 fReuseManifestCheckbox.setSelection(fJarPackage.isManifestReused());
715 fManifestFileText.setText(fJarPackage.getManifestLocation().toString());
716 fNewManifestFileText.setText(fJarPackage.getManifestLocation().toString());
717
718 // Sealing
719 if (fJarPackage.isJarSealed())
720 fSealJarRadioButton.setSelection(true);
721 else
722 fSealPackagesRadioButton.setSelection(true);
723
724 // Main-Class
725 fMainClassText.setText(JarPackagerUtil.getMainClassName(fJarPackage));
726 }
727 /**
728 * Initializes the JAR package from last used wizard page values.
729 */
730 protected void initializeJarPackage() {
731 IDialogSettings settings= getDialogSettings();
732 if (settings != null) {
733 // Manifest creation
734 fJarPackage.setGenerateManifest(settings.getBoolean(STORE_GENERATE_MANIFEST));
735 fJarPackage.setSaveManifest(settings.getBoolean(STORE_SAVE_MANIFEST));
736 fJarPackage.setReuseManifest(settings.getBoolean(STORE_REUSE_MANIFEST));
737 String pathStr= settings.get(STORE_MANIFEST_LOCATION);
738 if (pathStr == null)
739 pathStr= ""; //$NON-NLS-1$
740 fJarPackage.setManifestLocation(new Path(pathStr));
741
742 // Sealing
743 fJarPackage.setSealJar(settings.getBoolean(STORE_SEAL_JAR));
744 }
745 }
746 /**
747 * Stores the widget values in the JAR package.
748 */
749 protected void updateModel() {
750 if (getControl() == null)
751 return;
752
753 // Manifest creation
754 fJarPackage.setGenerateManifest(fGenerateManifestRadioButton.getSelection());
755 fJarPackage.setSaveManifest(fSaveManifestCheckbox.getSelection());
756 fJarPackage.setReuseManifest(fJarPackage.isManifestSaved() && fReuseManifestCheckbox.getSelection());
757 String path;
758 if (fJarPackage.isManifestGenerated())
759 path= fNewManifestFileText.getText();
760 else
761 path= fManifestFileText.getText();
762 if (path == null)
763 path= ""; //$NON-NLS-1$
764 fJarPackage.setManifestLocation(new Path(path));
765
766 // Sealing
767 fJarPackage.setSealJar(fSealJarRadioButton.getSelection());
768 }
769 /**
770 * Determine if the page is complete and update the page appropriately.
771 */
772 protected void updatePageCompletion() {
773 boolean pageComplete= isPageComplete();
774 setPageComplete(pageComplete);
775 if (pageComplete) {
776 setErrorMessage(null);
777 }
778 }
779
780 // ----------- Utility methods -----------
781
782 /**
783 * Creates a file resource handle for the file with the given workspace path.
784 * This method does not create the file resource; this is the responsibility
785 * of <code>createFile</code>.
786 *
787 * @param filePath the path of the file resource to create a handle for
788 * @return the new file resource handle
789 */
790 protected IFile createFileHandle(IPath filePath) {
791 if (filePath.isValidPath(filePath.toString()) && filePath.segmentCount() >= 2)
792 return JavaPlugin.getWorkspace().getRoot().getFile(filePath);
793 else
794 return null;
795 }
796 /**
797 * Creates a new label with a bold font.
798 *
799 * @param parent the parent control
800 * @param text the label text
801 * @param bold bold or not
802 * @return the new label control
803 */
804 protected Label createLabel(Composite parent, String text, boolean bold) {
805 Label label= new Label(parent, SWT.NONE);
806 if (bold)
807 label.setFont(JFaceResources.getBannerFont());
808 label.setText(text);
809 GridData data= new GridData();
810 data.verticalAlignment= GridData.FILL;
811 data.horizontalAlignment= GridData.FILL;
812 label.setLayoutData(data);
813 return label;
814 }
815 /**
816 * Sets the size of a control.
817 *
818 * @param control the control for which to set the size
819 * @param width the new width of the control
820 * @param height the new height of the control
821 */
822 protected void setSize(Control control, int width, int height) {
823 GridData gd= new GridData(GridData.END);
824 gd.widthHint= width ;
825 gd.heightHint= height;
826 control.setLayoutData(gd);
827 }
828 /**
829 * Makes the size of all buttons equal.
830 */
831 protected void setEqualButtonSizes() {
832 int width= SWTUtil.getButtonWidthHint(fManifestFileBrowseButton);
833 int width2= SWTUtil.getButtonWidthHint(fNewManifestFileBrowseButton);
834 width= Math.max(width, width2);
835
836 width2= SWTUtil.getButtonWidthHint(fSealedPackagesDetailsButton);
837 width= Math.max(width, width2);
838
839 width2= SWTUtil.getButtonWidthHint(fUnSealedPackagesDetailsButton);
840 width= Math.max(width, width2);
841
842 width2= SWTUtil.getButtonWidthHint(fMainClassBrowseButton);
843 width= Math.max(width, width2);
844
845 setSize(fManifestFileBrowseButton, width, SWT.DEFAULT);
846 setSize(fNewManifestFileBrowseButton, width, SWT.DEFAULT);
847 setSize(fSealedPackagesDetailsButton, width, SWT.DEFAULT);
848 setSize(fUnSealedPackagesDetailsButton, width, SWT.DEFAULT);
849 setSize(fMainClassBrowseButton, width, SWT.DEFAULT);
850 }
851
852 /**
853 * Creates a horizontal spacer line that fills the width of its container.
854 *
855 * @param parent the parent control
856 */
857 protected void createSpacer(Composite parent) {
858 Label spacer= new Label(parent, SWT.NONE);
859 GridData data= new GridData();
860 data.horizontalAlignment= GridData.FILL;
861 data.verticalAlignment= GridData.BEGINNING;
862 spacer.setLayoutData(data);
863 }
864 /**
865 * Returns the resource for the specified path.
866 *
867 * @param path the path for which the resource should be returned
868 * @return the resource specified by the path or <code>null</code>
869 */
870 protected IResource findResource(IPath path) {
871 IWorkspace workspace= JavaPlugin.getWorkspace();
872 IStatus result= workspace.validatePath(
873 path.toString(),
874 IResource.ROOT | IResource.PROJECT | IResource.FOLDER | IResource.FILE);
875 if (result.isOK() && workspace.getRoot().exists(path))
876 return workspace.getRoot().findMember(path);
877 return null;
878 }
879
880 protected IPath getPathFromString(String text) {
881 return new Path(text).makeAbsolute();
882 }
883 /**
884 * Creates a selection dialog that lists all packages under the given package
885 * fragment root.
886 * The caller is responsible for opening the dialog with <code>Window.open</code>,
887 * and subsequently extracting the selected packages (of type
888 * <code>IPackageFragment</code>) via <code>SelectionDialog.getResult</code>.
889 *
890 * @param packageFragments the package fragments
891 * @return a new selection dialog
892 */
893 protected SelectionDialog createPackageDialog(Set<IJavaElement> packageFragments) {
894 List<IPackageFragment> packages= new ArrayList<IPackageFragment>(packageFragments.size());
895 for (Iterator<IJavaElement> iter= packageFragments.iterator(); iter.hasNext();) {
896 IPackageFragment fragment= (IPackageFragment)iter.next();
897 boolean containsJavaElements= false;
898 int kind;
899 try {
900 kind= fragment.getKind();
901 containsJavaElements= fragment.getChildren().length > 0;
902 } catch (JavaModelException ex) {
903 ExceptionHandler.handle(ex, getContainer().getShell(), JarPackagerMessages.JarManifestWizardPage_error_jarPackageWizardError_title, Messages.format(JarPackagerMessages.JarManifestWizardPage_error_jarPackageWizardError_message, JavaElementLabels.getElementLabel(fragment, JavaElementLabels.ALL_DEFAULT)));
904 continue;
905 }
906 if (kind != IPackageFragmentRoot.K_BINARY && containsJavaElements)
907 packages.add(fragment);
908 }
909 StandardJavaElementContentProvider cp= new StandardJavaElementContentProvider() {
910 @Override
911 public boolean hasChildren(Object element) {
912 // prevent the + from being shown in front of packages
913 return !(element instanceof IPackageFragment) && super.hasChildren(element);
914 }
915 };
916 final DecoratingLabelProvider provider= new DecoratingLabelProvider(new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT), new ProblemsLabelDecorator(null));
917 ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(getContainer().getShell(), provider, cp);
918 dialog.setDoubleClickSelects(false);
919 dialog.setComparator(new JavaElementComparator());
920 dialog.setInput(JavaCore.create(JavaPlugin.getWorkspace().getRoot()));
921 dialog.addFilter(new EmptyInnerPackageFilter());
922 dialog.addFilter(new LibraryFilter());
923 dialog.addFilter(new SealPackagesFilter(packages));
924 dialog.setValidator(new ISelectionStatusValidator() {
925 public IStatus validate(Object[] selection) {
926 StatusInfo res= new StatusInfo();
927 for (int i= 0; i < selection.length; i++) {
928 if (!(selection[i] instanceof IPackageFragment)) {
929 res.setError(JarPackagerMessages.JarManifestWizardPage_error_mustContainPackages);
930 return res;
931 }
932 }
933 res.setOK();
934 return res;
935 }
936 });
937 return dialog;
938 }
939 /**
940 * Converts selection dialog results into an array of IPackageFragments.
941 * An empty array is returned in case of errors.
942 * @param dialog the dialog
943 * @return the selected IPackageFragments
944 * @throws ClassCastException if results are not IPackageFragments
945 */
946 protected IPackageFragment[] getPackagesFromDialog(SelectionDialog dialog) {
947 if (dialog.getReturnCode() == Window.OK && dialog.getResult().length > 0)
948 return Arrays.asList(dialog.getResult()).toArray(new IPackageFragment[dialog.getResult().length]);
949 else
950 return new IPackageFragment[0];
951 }
952 /**
953 * Creates and returns a dialog to choose an existing workspace file.
954 * @param title the title
955 * @param message the dialog message
956 * @return the dialog
957 */
958 protected ElementTreeSelectionDialog createWorkspaceFileSelectionDialog(String title, String message) {
959 int labelFlags= JavaElementLabelProvider.SHOW_BASICS
960 | JavaElementLabelProvider.SHOW_OVERLAY_ICONS
961 | JavaElementLabelProvider.SHOW_SMALL_ICONS;
962 final DecoratingLabelProvider provider= new DecoratingLabelProvider(new JavaElementLabelProvider(labelFlags), new ProblemsLabelDecorator(null));
963 ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(getShell(), provider, new StandardJavaElementContentProvider());
964 dialog.setComparator(new JavaElementComparator());
965 dialog.setAllowMultiple(false);
966 dialog.setValidator(new ISelectionStatusValidator() {
967 public IStatus validate(Object[] selection) {
968 StatusInfo res= new StatusInfo();
969 // only single selection
970 if (selection.length == 1 && (selection[0] instanceof IFile))
971 res.setOK();
972 else
973 res.setError(""); //$NON-NLS-1$
974 return res;
975 }
976 });
977 dialog.addFilter(new EmptyInnerPackageFilter());
978 dialog.addFilter(new LibraryFilter());
979 dialog.setTitle(title);
980 dialog.setMessage(message);
981 dialog.setStatusLineAboveButtons(true);
982 dialog.setInput(JavaCore.create(JavaPlugin.getWorkspace().getRoot()));
983 return dialog;
984 }
985
986 /**
987 * Returns the minimal set of packages which contain all the selected Java resources.
988 * @return the Set of IPackageFragments which contain all the selected resources
989 */
990 private Set<IJavaElement> getPackagesForSelectedResources() {
991 Set<IJavaElement> packages= new HashSet<IJavaElement>();
992 int n= fJarPackage.getElements().length;
993 for (int i= 0; i < n; i++) {
994 Object element= fJarPackage.getElements()[i];
995 if (element instanceof ICompilationUnit) {
996 packages.add(((ICompilationUnit) element).getParent());
997 }
998 }
999 return packages;
1000 }
1001}