KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > apt > ui > internal > preferences > FactoryPathConfigurationBlock


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 BEA Systems, Inc.
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  * wharley@bea.com - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jdt.apt.ui.internal.preferences;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.LinkedHashMap JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18
19 import org.eclipse.core.resources.IFile;
20 import org.eclipse.core.resources.IProject;
21 import org.eclipse.core.resources.IResource;
22 import org.eclipse.core.resources.IWorkspaceRoot;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.core.runtime.IPath;
25 import org.eclipse.core.runtime.Path;
26 import org.eclipse.core.runtime.preferences.IScopeContext;
27 import org.eclipse.jdt.apt.core.internal.util.FactoryContainer;
28 import org.eclipse.jdt.apt.core.internal.util.FactoryPath;
29 import org.eclipse.jdt.apt.core.internal.util.FactoryPathUtil;
30 import org.eclipse.jdt.apt.core.internal.util.FactoryPath.Attributes;
31 import org.eclipse.jdt.apt.core.util.AptConfig;
32 import org.eclipse.jdt.apt.core.util.IFactoryPath;
33 import org.eclipse.jdt.apt.ui.internal.util.ExceptionHandler;
34 import org.eclipse.jdt.core.IJavaProject;
35 import org.eclipse.jdt.core.JavaCore;
36 import org.eclipse.jdt.internal.ui.util.PixelConverter;
37 import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
38 import org.eclipse.jdt.internal.ui.wizards.dialogfields.CheckedListDialogField;
39 import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
40 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
41 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter;
42 import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
43 import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField;
44 import org.eclipse.jdt.ui.wizards.BuildPathDialogAccess;
45 import org.eclipse.jface.dialogs.Dialog;
46 import org.eclipse.jface.viewers.ITableLabelProvider;
47 import org.eclipse.jface.viewers.LabelProvider;
48 import org.eclipse.jface.window.Window;
49 import org.eclipse.swt.SWT;
50 import org.eclipse.swt.graphics.Image;
51 import org.eclipse.swt.widgets.Composite;
52 import org.eclipse.swt.widgets.Control;
53 import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
54
55 /**
56  * Data and controls for the Java Annotation Factory Path preference page.
57  */

58 public class FactoryPathConfigurationBlock extends BaseConfigurationBlock {
59
60     private static final int IDX_UP= 0;
61     private static final int IDX_DOWN= 1;
62     // 2
63
private static final int IDX_ADDJAR= 3;
64     private static final int IDX_ADDEXTJAR= 4;
65     private static final int IDX_ADDVAR= 5;
66     // 6
67
private static final int IDX_EDIT= 7;
68     private static final int IDX_ADVANCED= 8;
69     private static final int IDX_REMOVE= 9;
70     // 10
71
private static final int IDX_ENABLEALL= 11;
72     private static final int IDX_DISABLEALL= 12;
73
74     private final static String JavaDoc[] buttonLabels = {
75         Messages.FactoryPathConfigurationBlock_up,
76         Messages.FactoryPathConfigurationBlock_down,
77         null, // 2
78
Messages.FactoryPathConfigurationBlock_addJars,
79         Messages.FactoryPathConfigurationBlock_addExternalJars,
80         Messages.FactoryPathConfigurationBlock_addVariable,
81         null, // 6
82
Messages.FactoryPathConfigurationBlock_edit,
83         Messages.FactoryPathConfigurationBlock_advanced,
84         Messages.FactoryPathConfigurationBlock_remove,
85         null, // 10
86
Messages.FactoryPathConfigurationBlock_enableAll,
87         Messages.FactoryPathConfigurationBlock_disableAll
88     };
89
90     /**
91      * Event handler for factory path list control
92      */

93     private class FactoryPathAdapter implements IListAdapter, IDialogFieldListener {
94         public void customButtonPressed(ListDialogField field, int index) {
95             FactoryPathConfigurationBlock.this.customButtonPressed(index);
96         }
97
98         public void selectionChanged(ListDialogField field) {
99             boolean enableRemove = canRemove();
100             field.enableButton(IDX_REMOVE, enableRemove);
101             boolean enableEdit = canEdit();
102             field.enableButton(IDX_EDIT, enableEdit);
103             boolean enableAdvanced = canAdvanced();
104             field.enableButton(IDX_ADVANCED, enableAdvanced);
105         }
106
107         /**
108          * This method gets called when, among other things, a checkbox is
109          * clicked. However, it doesn't get any information about which
110          * item it was whose checkbox was clicked. We could hook into the
111          * list control's CheckboxTableViewer event listener for changes to
112          * individual checkboxes; but that does not get called for enableAll
113          * and disableAll events.
114          */

115         public void dialogFieldChanged(DialogField field) {
116             if (!fSettingListContents) {
117                 updateFactoryPathEntries();
118             }
119         }
120
121         public void doubleClicked(ListDialogField field) {
122             if (canEdit()) {
123                 editSelectedItem();
124             }
125         }
126     }
127     
128     private class FactoryPathLabelProvider extends LabelProvider implements ITableLabelProvider {
129
130         public Image getColumnImage(Object JavaDoc element, int columnIndex) {
131             return null;
132         }
133
134         public String JavaDoc getColumnText(Object JavaDoc element, int columnIndex) {
135             if (!(element instanceof FactoryPathEntry)) {
136                 return ""; //$NON-NLS-1$
137
}
138             FactoryPathEntry fpe = (FactoryPathEntry)element;
139             if (columnIndex == 0) {
140                 return fpe._fc.toString();
141             }
142             else {
143                 return ""; //$NON-NLS-1$
144
}
145         }
146     }
147     
148     /**
149      * The factory path is a list of containers, plus some information about
150      * each container. That makes it a list of FactoryPathEntry.
151      */

152     private static class FactoryPathEntry {
153         /* shallow copies - beware! */
154         public final FactoryContainer _fc;
155         public FactoryPath.Attributes _attr;
156         
157         // CONSTRUCTORS
158
public FactoryPathEntry(FactoryContainer fc, FactoryPath.Attributes attr) {
159             _fc = fc;
160             _attr = attr;
161         }
162
163         // CONVERSION TO/FROM INDIVIDUAL ELEMENTS
164
public static Map JavaDoc<FactoryContainer, Attributes> pathMapFromList(List JavaDoc<FactoryPathEntry> list) {
165             Map JavaDoc<FactoryContainer, FactoryPath.Attributes> map =
166                 new LinkedHashMap JavaDoc<FactoryContainer, FactoryPath.Attributes>(list.size());
167             for (FactoryPathEntry fpe : list) {
168                 map.put(fpe._fc, fpe._attr);
169             }
170             return map;
171         }
172         public static List JavaDoc<FactoryPathEntry> pathListFromMap(Map JavaDoc<FactoryContainer, Attributes> map) {
173             List JavaDoc<FactoryPathEntry> list = new ArrayList JavaDoc<FactoryPathEntry>(map.size());
174             for (Map.Entry JavaDoc<FactoryContainer, Attributes> entry : map.entrySet()) {
175                 FactoryPathEntry fpe = new FactoryPathEntry(entry.getKey(), entry.getValue());
176                 list.add(fpe);
177             }
178             return list;
179         }
180
181         // SUPPORT FOR COMPARISON
182
public boolean equals(Object JavaDoc obj) {
183             if (!(obj instanceof FactoryPathEntry))
184                 return false;
185             FactoryPathEntry fpe = (FactoryPathEntry)obj;
186             return _fc.equals(fpe._fc) && _attr.equals(fpe._attr);
187         }
188         public int hashCode() {
189             return _fc.hashCode() ^ _attr.hashCode();
190         }
191         
192     }
193     
194     private PixelConverter fPixelConverter;
195     private Composite fBlockControl; // the control representing the entire configuration block
196

197     /**
198      * The factory path at the time this pref pane was launched.
199      * Use this to see if anything changed at save time.
200      */

201     private List JavaDoc<FactoryPathEntry> fOriginalPath;
202     
203     private final IJavaProject fJProj;
204
205     /**
206      * The GUI control representing the factory path. Its data items
207      * are of type FactoryPathEntry.
208      */

209     private CheckedListDialogField fFactoryPathList;
210     
211     /**
212      * True while inside setListContents(). Used in order to efficiently
213      * and correctly add new elements to the factory list: short-circuits
214      * the factory list field listener code.
215      */

216     private boolean fSettingListContents = false;
217
218     public FactoryPathConfigurationBlock(IStatusChangeListener context,
219             IProject project, IWorkbenchPreferenceContainer container) {
220         super(context, project, new Key[] {}, container);
221         
222         fJProj = JavaCore.create(project);
223         
224         FactoryPathAdapter adapter= new FactoryPathAdapter();
225         FactoryPathLabelProvider labelProvider = new FactoryPathLabelProvider();
226         
227         fFactoryPathList= new CheckedListDialogField(adapter, buttonLabels, labelProvider);
228         fFactoryPathList.setDialogFieldListener(adapter);
229         fFactoryPathList.setLabelText(Messages.FactoryPathConfigurationBlock_pluginsAndJars);
230         fFactoryPathList.setUpButtonIndex(IDX_UP);
231         fFactoryPathList.setDownButtonIndex(IDX_DOWN);
232         fFactoryPathList.setRemoveButtonIndex(IDX_REMOVE);
233         fFactoryPathList.setCheckAllButtonIndex(IDX_ENABLEALL);
234         fFactoryPathList.setUncheckAllButtonIndex(IDX_DISABLEALL);
235     }
236
237     /**
238      * Respond to the user checking the "enabled" checkbox of an entry
239      * in the factory path control, by replacing the FactoryPathEntry
240      * with a new one with the correct "enabled" value.
241      * We don't have information about which entry was changed, so we
242      * have to look at all of them. This is inefficient - somewhere
243      * around O(n log n) depending on how the list is implemented - but
244      * hopefully the list is not so huge that it's a problem.
245      */

246     private void updateFactoryPathEntries() {
247         for (FactoryPathEntry fpe : getListContents()) {
248             boolean checked = fFactoryPathList.isChecked(fpe);
249             if (checked != fpe._attr.isEnabled()) {
250                 fpe._attr.setEnabled(checked);
251             }
252         }
253     }
254
255     /**
256      * Respond to a button in the button bar.
257      * Most buttons are handled by code in CheckedListDialogField;
258      * this method is for the rest, e.g., Add External Jar.
259      * @param index
260      */

261     public void customButtonPressed(int index) {
262         FactoryPathEntry[] newEntries = null;
263         switch (index) {
264         case IDX_ADDJAR: // add jars in project
265
newEntries= openJarFileDialog(null);
266             addEntries(newEntries);
267             break;
268             
269         case IDX_ADDEXTJAR: // add external jars
270
newEntries= openExtJarFileDialog(null);
271             addEntries(newEntries);
272             break;
273             
274         case IDX_ADDVAR: // add jar from classpath variable
275
newEntries= openVariableSelectionDialog(null);
276             addEntries(newEntries);
277             break;
278             
279         case IDX_EDIT: // edit selected item
280
if (canEdit()) {
281                 editSelectedItem();
282             }
283             break;
284             
285         case IDX_ADVANCED: // advanced options
286
advancedOptionsDialog();
287             break;
288         }
289         
290     }
291     
292     /**
293      * Can't remove a selection that contains a plugin.
294      */

295     private boolean canRemove() {
296         List JavaDoc<FactoryPathEntry> selected= getSelectedListContents();
297         boolean containsPlugin= false;
298         for (FactoryPathEntry fpe : selected) {
299             if (fpe._fc.getType() == FactoryContainer.FactoryType.PLUGIN) {
300                 containsPlugin = true;
301                 break;
302             }
303         }
304         return !containsPlugin;
305     }
306     
307     /**
308      * Can only edit a single item at a time. Can't edit plugins.
309      */

310     private boolean canEdit() {
311         List JavaDoc<FactoryPathEntry> selected= getSelectedListContents();
312         if (selected.size() != 1) {
313             return false;
314         }
315         FactoryContainer fc = selected.get(0)._fc;
316         return (fc.getType() != FactoryContainer.FactoryType.PLUGIN);
317     }
318
319     /**
320      * Can only launch the 'advanced' dialog on a single item at a time.
321      */

322     private boolean canAdvanced() {
323         List JavaDoc<FactoryPathEntry> selected= getSelectedListContents();
324         return (selected.size() == 1);
325     }
326
327     /**
328      * Edit the item selected.
329      * Precondition: exactly one item is selected in the list,
330      * and it is an editable item (not a plugin).
331      * @param field a listbox of FactoryContainers.
332      */

333     private void editSelectedItem() {
334         List JavaDoc<FactoryPathEntry> selected= getSelectedListContents();
335         if (selected.size() != 1) {
336             return;
337         }
338         FactoryPathEntry original = selected.get(0);
339         FactoryPathEntry[] edited = null;
340         switch (original._fc.getType()) {
341         case PLUGIN:
342             return;
343         case EXTJAR:
344             edited= openExtJarFileDialog(original);
345             break;
346         case VARJAR:
347             edited= openVariableSelectionDialog(original);
348             break;
349         case WKSPJAR:
350             edited= openJarFileDialog(original);
351             break;
352         }
353         if (edited != null && edited.length > 0) {
354             fFactoryPathList.replaceElement(original, edited[0]);
355         }
356     }
357
358     /* (non-Javadoc)
359      * @see org.eclipse.jdt.apt.ui.internal.preferences.BaseConfigurationBlock#createContents(org.eclipse.swt.widgets.Composite)
360      */

361     protected Control createContents(Composite parent) {
362         setShell(parent.getShell());
363         
364         fPixelConverter= new PixelConverter(parent);
365         
366         fBlockControl= new Composite(parent, SWT.NONE);
367         fBlockControl.setFont(parent.getFont());
368
369         Dialog.applyDialogFont(fBlockControl);
370         
371         LayoutUtil.doDefaultLayout(fBlockControl, new DialogField[] { fFactoryPathList }, true, SWT.DEFAULT, SWT.DEFAULT);
372         LayoutUtil.setHorizontalGrabbing(fFactoryPathList.getListControl(null));
373
374         fFactoryPathList.enableButton(IDX_ADDJAR, (fJProj != null));
375         // bugzilla 139101: only enable Advanced and Edit buttons if there is a selection
376
fFactoryPathList.enableButton(IDX_ADVANCED, false);
377         fFactoryPathList.enableButton(IDX_EDIT, false);
378         int buttonBarWidth= fPixelConverter.convertWidthInCharsToPixels(24);
379         fFactoryPathList.setButtonsMinWidth(buttonBarWidth);
380         
381         return fBlockControl;
382     }
383     
384     @Override JavaDoc
385     public boolean hasProjectSpecificOptionsNoCache(IProject project) {
386         return (project == null) ? false : AptConfig.hasProjectSpecificFactoryPath(JavaCore.create(project));
387     }
388
389     /**
390      * Initialize the user interface based on the cached original settings.
391      */

392     @Override JavaDoc
393     protected void initContents() {
394         setListContents(fOriginalPath);
395     }
396
397     /**
398      * Save reference copies of the settings, so we can see if anything changed.
399      * This must stay in sync with the actual saved values for the rebuild logic
400      * to work; so be sure to call this any time you save (eg in performApply()).
401      */

402     @Override JavaDoc
403     protected void cacheOriginalValues() {
404         IFactoryPath ifp = AptConfig.getFactoryPath(fJProj);
405         // we'll risk this downcast because we're such good buddies with apt.core.
406
FactoryPath fp = (FactoryPath)ifp;
407         Map JavaDoc<FactoryContainer, FactoryPath.Attributes> path = fp.getAllContainers();
408         fOriginalPath = FactoryPathEntry.pathListFromMap(path);
409         super.cacheOriginalValues();
410     }
411     
412     /*
413      * Helper method to get rid of unchecked conversion warning
414      */

415     @SuppressWarnings JavaDoc("unchecked")
416     private List JavaDoc<FactoryPathEntry> getListContents() {
417         List JavaDoc<FactoryPathEntry> contents= fFactoryPathList.getElements();
418         return contents;
419     }
420     
421     /*
422      * Helper method to get rid of unchecked conversion warning
423      */

424     @SuppressWarnings JavaDoc("unchecked")
425     private List JavaDoc<FactoryPathEntry> getSelectedListContents() {
426         List JavaDoc<FactoryPathEntry> contents= fFactoryPathList.getSelectedElements();
427         return contents;
428     }
429     
430     /**
431      * Add new entries to the list control. Differs from setListContents()
432      * in that the list is not cleared first, and the entries are not copied
433      * before being added to the list.
434      * @param entries can be null.
435      */

436     private void addEntries(FactoryPathEntry[] entries) {
437         if (null == entries) {
438             return;
439         }
440         int insertAt;
441         List JavaDoc<FactoryPathEntry> selectedElements= getSelectedListContents();
442         if (selectedElements.size() == 1) {
443             insertAt= fFactoryPathList.getIndexOfElement(selectedElements.get(0)) + 1;
444         } else {
445             insertAt= fFactoryPathList.getSize();
446         }
447         try {
448             fSettingListContents = true;
449             for (int i = 0; i < entries.length; ++i) {
450                 fFactoryPathList.addElement(entries[i], insertAt + i);
451                 fFactoryPathList.setChecked(entries[i], entries[i]._attr.isEnabled());
452             }
453         }
454         finally {
455             fSettingListContents = false;
456         }
457     }
458     
459     /**
460      * Set the contents of the list control. The FPEs in the input list
461      * will be copied; the originals are left untouched, so that if the
462      * list control's contents are modified they can be compared with the
463      * original.
464      * @param fpeList can be null.
465      */

466     private void setListContents(List JavaDoc<FactoryPathEntry> fpeList) {
467         try {
468             fSettingListContents = true;
469             fFactoryPathList.removeAllElements();
470             if (fpeList == null) {
471                 return;
472             }
473             for (FactoryPathEntry originalFpe : fpeList) {
474                 // clone, because we may later want to compare with the original.
475
FactoryPathEntry fpe = new FactoryPathEntry(originalFpe._fc, new Attributes(originalFpe._attr));
476                 fFactoryPathList.addElement(fpe);
477                 fFactoryPathList.setChecked(fpe, fpe._attr.isEnabled());
478             }
479         }
480         finally {
481             fSettingListContents = false;
482         }
483     }
484
485     /**
486      * Get all the containers of a certain type currently on the list.
487      * The format of the returned paths will depend on the container type:
488      * for EXTJAR it will be an absolute path; for WKSPJAR it will be a
489      * path relative to the workspace root; for VARJAR it will be a path
490      * whose first segment is the name of a classpath variable.
491      * @param type may not be PLUGIN
492      * @param ignore null, or an item to not put on the list (used when
493      * editing an existing item).
494      * @return an array, possibly empty (but never null)
495      */

496     private IPath[] getExistingPaths(FactoryContainer.FactoryType type, FactoryContainer ignore) {
497         if (type == FactoryContainer.FactoryType.PLUGIN) {
498             throw new IllegalArgumentException JavaDoc();
499         }
500         List JavaDoc<FactoryPathEntry> all = getListContents();
501         // find out how many entries there are of this type
502
int countType = 0;
503         for (FactoryPathEntry fpe : all) {
504             FactoryContainer fc = fpe._fc;
505             if (fc.getType() == type && fc != ignore) {
506                 ++countType;
507             }
508         }
509         // create an array of paths, one per entry of this type
510
IPath[] some = new IPath[countType];
511         int i = 0;
512         for (FactoryPathEntry fpe : all) {
513             FactoryContainer fc = fpe._fc;
514             if (fc.getType() == type && fc != ignore) {
515                 some[i++] = new Path(fc.getId());
516             }
517         }
518         return some;
519     }
520     
521     /**
522      * Launch the "advanced options" dialog, which displays the factory classes
523      * contained by the selected container and allows the user to specify
524      * options that are needed only in certain special cases.
525      *
526      * We treat advanced options as an attribute of the factory path, not of the
527      * container; the same container may have different advanced options in different
528      * projects. We treat advanced options the same way as the "enabled" flag.
529      */

530     private void advancedOptionsDialog() {
531         List JavaDoc<FactoryPathEntry> selected= getSelectedListContents();
532         if (selected.size() != 1) {
533             return;
534         }
535         FactoryPathEntry original= selected.get(0);
536         AdvancedFactoryPathOptionsDialog dialog=
537             new AdvancedFactoryPathOptionsDialog(getShell(), original._fc, original._attr);
538         if (dialog.open() == Window.OK) {
539             original._attr = dialog.getResult();
540             // If the dialog could change the enabled attribute, we would also
541
// need to update the checkbox in the GUI here. But it doesn't.
542
}
543     }
544
545     /**
546      * Add or edit a project-relative jar file. Only possible when editing
547      * project properties; this method is disabled in workspace prefs.
548      * @param original null, or an existing list entry to be edited
549      * @return a list of additional factory path entries to be added
550      */

551     private FactoryPathEntry[] openJarFileDialog(FactoryPathEntry original) {
552         if (fJProj == null) {
553             return null;
554         }
555         IWorkspaceRoot root= fJProj.getProject().getWorkspace().getRoot();
556         
557         if (original == null) {
558             IPath[] results= BuildPathDialogAccess.chooseJAREntries(getShell(), fJProj.getPath(), new IPath[0]);
559             if (results == null) {
560                 return null;
561             }
562             ArrayList JavaDoc<FactoryPathEntry> res= new ArrayList JavaDoc<FactoryPathEntry>();
563             for (int i= 0; i < results.length; i++) {
564                 IResource resource= root.findMember(results[i]);
565                 if (resource instanceof IFile) {
566                     FactoryContainer fc = FactoryPathUtil.newWkspJarFactoryContainer(results[i]);
567                     // assume defaults of enabled=true, runInAptMode=false
568
FactoryPath.Attributes attr = new FactoryPath.Attributes(true, false);
569                     FactoryPathEntry fpe = new FactoryPathEntry(fc, attr);
570                     res.add(fpe);
571                 }
572                 //TODO: handle missing jars
573
}
574             return res.toArray(new FactoryPathEntry[res.size()]);
575         }
576         else {
577             IPath[] existingPaths = getExistingPaths(FactoryContainer.FactoryType.WKSPJAR, original._fc);
578             IPath result= BuildPathDialogAccess.configureJAREntry(getShell(), new Path(original._fc.getId()), existingPaths);
579             if (result == null) {
580                 return null;
581             }
582             IResource resource= root.findMember(result);
583             if (resource instanceof IFile) {
584                 FactoryPathEntry[] edited = new FactoryPathEntry[1];
585                 FactoryContainer fc= FactoryPathUtil.newWkspJarFactoryContainer(result);
586                 // Use prior value for isEnabled. Assume default of runInAptMode=false
587
FactoryPath.Attributes attr = new FactoryPath.Attributes(original._attr.isEnabled(), false);
588                 edited[0]= new FactoryPathEntry(fc, attr);
589                 return edited;
590             }
591             //TODO: handle missing jars
592
return null;
593         }
594     }
595
596     /**
597      * Add or edit an external (not project-relative) jar file.
598      * @param original null, or an existing list entry to be edited
599      * @return a list of additional factory path entries to be added
600      */

601     private FactoryPathEntry[] openExtJarFileDialog(FactoryPathEntry original) {
602         if (original == null) {
603             IPath[] selected= BuildPathDialogAccess.chooseExternalJAREntries(getShell());
604             if (selected == null) {
605                 return null;
606             }
607             ArrayList JavaDoc<FactoryPathEntry> res= new ArrayList JavaDoc<FactoryPathEntry>();
608             for (int i= 0; i < selected.length; i++) {
609                 FactoryContainer fc = FactoryPathUtil.newExtJarFactoryContainer(selected[i].toFile());
610                 // assume defaults of enabled=true, runInAptMode=false
611
FactoryPath.Attributes attr = new FactoryPath.Attributes(true, false);
612                 FactoryPathEntry fpe = new FactoryPathEntry(fc, attr);
613                 res.add(fpe);
614             }
615             return res.toArray(new FactoryPathEntry[res.size()]);
616         }
617         else {
618             IPath result= BuildPathDialogAccess.configureExternalJAREntry(getShell(), new Path(original._fc.getId()));
619             if (result == null) {
620                 return null;
621             }
622             FactoryPathEntry[] edited= new FactoryPathEntry[1];
623             FactoryContainer fc= FactoryPathUtil.newExtJarFactoryContainer(result.toFile());
624             // Use prior value for isEnabled. Assume default of runInAptMode=false
625
FactoryPath.Attributes attr = new FactoryPath.Attributes(original._attr.isEnabled(), false);
626             edited[0]= new FactoryPathEntry(fc, attr);
627             return edited;
628         }
629     }
630     
631     /**
632      * Add or edit an external (not project-relative) jar file whose
633      * location includes a classpath variable name.
634      * @param original null, or an existing list entry to be edited
635      * @return a list of additional factory path entries to be added
636      */

637     private FactoryPathEntry[] openVariableSelectionDialog(FactoryPathEntry original) {
638         if (original == null) {
639             IPath[] selected= BuildPathDialogAccess.chooseVariableEntries(getShell(), new IPath[0]);
640             if (selected == null) {
641                 return null;
642             }
643             ArrayList JavaDoc<FactoryPathEntry> res= new ArrayList JavaDoc<FactoryPathEntry>();
644             for (int i= 0; i < selected.length; i++) {
645                 FactoryContainer fc= FactoryPathUtil.newVarJarFactoryContainer(selected[i]);
646                 // assume defaults of enabled=true, runInAptMode=false
647
FactoryPath.Attributes attr = new FactoryPath.Attributes(true, false);
648                 FactoryPathEntry fpe = new FactoryPathEntry(fc, attr);
649                 res.add(fpe);
650             }
651             return res.toArray(new FactoryPathEntry[res.size()]);
652         }
653         else {
654             IPath[] existingPaths = getExistingPaths(FactoryContainer.FactoryType.VARJAR, original._fc);
655             IPath result= BuildPathDialogAccess.configureVariableEntry(getShell(), new Path(original._fc.getId()), existingPaths);
656             if (result == null) {
657                 return null;
658             }
659             FactoryPathEntry[] edited= new FactoryPathEntry[1];
660             FactoryContainer fc= FactoryPathUtil.newVarJarFactoryContainer(result);
661             // Use prior value for isEnabled. Assume default of runInAptMode=false
662
FactoryPath.Attributes attr = new FactoryPath.Attributes(original._attr.isEnabled(), false);
663             edited[0]= new FactoryPathEntry(fc, attr);
664             return edited;
665         }
666     }
667     
668     /* (non-Javadoc)
669      * @see org.eclipse.jdt.apt.ui.internal.preferences.BaseConfigurationBlock#updateModel(org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField)
670      */

671     protected void updateModel(DialogField field) {
672         // We don't use IEclipsePreferences for this pane, so no need to do anything.
673
}
674
675     /* (non-Javadoc)
676      * @see org.eclipse.jdt.apt.ui.internal.preferences.BaseConfigurationBlock#validateSettings(org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock.Key, java.lang.String, java.lang.String)
677      */

678     protected void validateSettings(Key changedKey, String JavaDoc oldValue, String JavaDoc newValue) {
679         // TODO: validate that all the specified factory containers exist?
680
}
681     
682     protected void saveSettings() {
683         FactoryPath fp;
684         if ((fJProj != null) && !fBlockControl.isEnabled()) {
685             // We're in a project properties pane but the entire configuration
686
// block control is disabled. That means the per-project settings checkbox
687
// is unchecked. To save that state, we'll delete the settings file.
688
fp = null;
689         }
690         else {
691             List JavaDoc<FactoryPathEntry> containers;
692             Map JavaDoc<FactoryContainer, FactoryPath.Attributes> map;
693             containers = getListContents();
694             map = FactoryPathEntry.pathMapFromList(containers);
695             fp = new FactoryPath();
696             fp.setContainers(map);
697         }
698         
699         try {
700             AptConfig.setFactoryPath(fJProj, fp);
701         }
702         catch (CoreException e) {
703             final String JavaDoc title = Messages.FactoryPathConfigurationBlock_unableToSaveFactorypath_title;
704             final String JavaDoc message = Messages.FactoryPathConfigurationBlock_unableToSaveFactorypath_message;
705             ExceptionHandler.handle(e, fBlockControl.getShell(), title, message);
706         }
707         
708         super.saveSettings();
709     }
710     
711     /**
712      * If per-project, restore list contents to current workspace settings;
713      * the per-project settings checkbox will be cleared for us automatically.
714      * If workspace, restore list contents to factory-default settings.
715      */

716     public void performDefaults() {
717         IFactoryPath ifp = AptConfig.getDefaultFactoryPath(fJProj);
718         // we'll risk this downcast because we're such good buddies with apt.core.
719
FactoryPath fp = (FactoryPath)ifp;
720         Map JavaDoc<FactoryContainer, FactoryPath.Attributes> map = fp.getAllContainers();
721         List JavaDoc<FactoryPathEntry> defaults = FactoryPathEntry.pathListFromMap(map);
722         setListContents(defaults);
723         super.performDefaults();
724     }
725     
726     /**
727      * @return true if settings or project-specificness changed since
728      * the pane was launched - that is, if there is anything to save.
729      */

730     @Override JavaDoc
731     protected boolean settingsChanged(IScopeContext currContext) {
732         if (fOriginalPath == null) {
733             // shouldn't happen, but just in case it does, consider it a change.
734
return true;
735         }
736         // Is the new path the same size, containing the same items
737
// in the same order? We rely on FactoryPathEntry.equals() here.
738
List JavaDoc<FactoryPathEntry> newPath = getListContents();
739         return !fOriginalPath.equals(newPath);
740     }
741     
742 }
743
Popular Tags