001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2003 Jennifer Lhotak
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019:
020: package ca.mcgill.sable.soot.ui;
021:
022: import java.util.*;
023: import org.eclipse.jface.dialogs.*;
024: import org.eclipse.jface.viewers.*;
025: import org.eclipse.swt.custom.*;
026: import org.eclipse.swt.events.*;
027: import org.eclipse.swt.widgets.*;
028: import org.eclipse.swt.layout.*;
029: import org.eclipse.swt.*;
030: import ca.mcgill.sable.soot.launching.SavedConfigManager;
031: import ca.mcgill.sable.soot.launching.SootSavedConfiguration;
032: import ca.mcgill.sable.soot.testing.*;
033:
034: public abstract class AbstractOptionsDialog extends TitleAreaDialog
035: implements ISelectionChangedListener {
036:
037: private SashForm sashForm;
038: private TreeViewer treeViewer;
039: private Composite pageContainer;
040: private HashMap config;
041: private String configName;
042: private HashMap editMap;
043: private boolean canRun = true;
044: private HashMap radioGroups;
045: private ArrayList enableGroups;
046: private HashMap eclipseDefList;
047: private HashMap defList;
048: private CheckboxTableViewer tableViewer;
049: private Button addButton;
050: private Button removeButton;
051: private String sootMainClass;
052:
053: /**
054: * Constructor for AbstractOptionsDialog.
055: * @param parentShell
056: */
057: public AbstractOptionsDialog(Shell parentShell) {
058: super (parentShell);
059: this .setShellStyle(SWT.RESIZE);
060: }
061:
062: public void addToEclipseDefList(String key, Object val) {
063: if (getEclipseDefList() == null) {
064: setEclipseDefList(new HashMap());
065: }
066: getEclipseDefList().put(key, val);
067:
068: addToDefList(key, val);
069:
070: }
071:
072: public void addToDefList(String key, Object val) {
073: if (getDefList() == null) {
074: setDefList(new HashMap());
075: }
076: getDefList().put(key, val);
077:
078: }
079:
080: public boolean isInDefList(String key) {
081: if (getDefList().containsKey(key))
082: return true;
083: else
084: return false;
085: }
086:
087: public boolean getBoolDef(String key) {
088: Boolean temp = (Boolean) getDefList().get(key);
089: return temp.booleanValue();
090: }
091:
092: public String getStringDef(String key) {
093:
094: return (String) getDefList().get(key);
095: }
096:
097: public String getArrayDef(String key) {
098: String res = "";
099: if (getDefList().get(key) instanceof ArrayList) {
100:
101: ArrayList list = (ArrayList) getDefList().get(key);
102: Iterator it = list.iterator();
103: while (it.hasNext()) {
104: if (res.equals("")) {
105: res = res + (String) it.next();
106: } else {
107: res = res + "\r\n" + (String) it.next();
108: }
109: }
110: } else {
111: res = (String) getDefList().get(key);
112: }
113: return res;
114: }
115:
116: // This sets the title in the shell that displays the
117: // options dialog box
118: protected void configureShell(Shell shell) {
119: super .configureShell(shell);
120: shell.setText(Messages
121: .getString("AbstractOptionsDialog.Soot_Options")); //$NON-NLS-1$
122: }
123:
124: public boolean isEnableButton(String alias) {
125: if (alias.equals("enabled"))
126: return true;
127: return false;
128: }
129:
130: public void handleWidgetSelected(SelectionEvent e) {
131:
132: if (getRadioGroups() != null) {
133: Iterator it = getRadioGroups().keySet().iterator();
134: while (it.hasNext()) {
135: Integer key = (Integer) it.next();
136: if (getRadioGroups().get(key) == null)
137: break;
138: ArrayList buttons = (ArrayList) getRadioGroups().get(
139: key);
140: Iterator itButtons = buttons.iterator();
141: while (itButtons.hasNext()) {
142: if (((BooleanOptionWidget) itButtons.next())
143: .getButton().equals(e.getSource())) {
144: switchButtons(buttons, (Button) e.getSource());
145: }
146: }
147: }
148: }
149:
150: updateAllEnableGroups();
151:
152: }
153:
154: public void updateEnableGroup(Button button) {
155: if (getEnableGroups() == null)
156: return;
157: Iterator it = getEnableGroups().iterator();
158: while (it.hasNext()) {
159: EnableGroup eGroup = (EnableGroup) it.next();
160: if (eGroup.getLeader().getButton().equals(button)) {
161: // group found
162: eGroup.changeControlState(eGroup.getLeader()
163: .getButton().getSelection());
164: if (eGroup.getControls() != null) {
165: Iterator itCon = eGroup.getControls().iterator();
166: while (itCon.hasNext()) {
167: Object obj = itCon.next();
168: if (obj instanceof BooleanOptionWidget) {
169: updateEnableGroup(((BooleanOptionWidget) obj)
170: .getButton());
171: }
172: }
173: }
174: }
175: }
176: }
177:
178: public void switchButtons(ArrayList buttons, Button change) {
179: if (change.getSelection()) {
180: Iterator it = buttons.iterator();
181: while (it.hasNext()) {
182: BooleanOptionWidget nextWidget = (BooleanOptionWidget) it
183: .next();
184: if (nextWidget.getButton().equals(change)) {
185: nextWidget.getButton().setSelection(true);
186: } else {
187: nextWidget.getButton().setSelection(false);
188: }
189: }
190: } else {
191: Iterator it = buttons.iterator();
192: while (it.hasNext()) {
193: BooleanOptionWidget defWidget = (BooleanOptionWidget) it
194: .next();
195: if (defWidget.getData().isDefaultVal()) {
196: defWidget.getButton().setSelection(true);
197: } else {
198: defWidget.getButton().setSelection(false);
199: }
200: }
201: }
202: }
203:
204: protected void makeNewEnableGroup(String phaseAlias) {
205: if (getEnableGroups() == null) {
206: setEnableGroups(new ArrayList());
207: }
208:
209: EnableGroup eGroup = new EnableGroup();
210: eGroup.setPhaseAlias(phaseAlias);
211:
212: getEnableGroups().add(eGroup);
213: }
214:
215: protected void makeNewEnableGroup(String phaseAlias,
216: String subPhaseAlias) {
217: if (getEnableGroups() == null) {
218: setEnableGroups(new ArrayList());
219: }
220:
221: EnableGroup eGroup = new EnableGroup();
222: eGroup.setPhaseAlias(phaseAlias);
223: eGroup.setSubPhaseAlias(subPhaseAlias);
224:
225: getEnableGroups().add(eGroup);
226: }
227:
228: protected void addToEnableGroup(String phaseAlias,
229: ISootOptionWidget widget, String alias) {
230: EnableGroup eGroup = findEnableGroup(phaseAlias);
231: if (widget instanceof BooleanOptionWidget) {
232: // could be leader
233: if (isEnableButton(alias)) {
234: eGroup.setLeader(((BooleanOptionWidget) widget));
235: } else {
236: eGroup.addControl(widget);
237: }
238: } else {
239: eGroup.addControl(widget);
240: }
241: }
242:
243: private EnableGroup findEnableGroup(String phaseAlias) {
244: Iterator it = getEnableGroups().iterator();
245: while (it.hasNext()) {
246: EnableGroup next = (EnableGroup) it.next();
247: if (next.getPhaseAlias().equals(phaseAlias)
248: && (next.getSubPhaseAlias() == null))
249: return next;
250: }
251: return null;
252: }
253:
254: protected void addToEnableGroup(String phaseAlias,
255: String subPhaseAlias, ISootOptionWidget widget, String alias) {
256: EnableGroup eGroup = findEnableGroup(phaseAlias, subPhaseAlias);
257: if (widget instanceof BooleanOptionWidget) {
258: // could be leader
259:
260: if (isEnableButton(alias)) {
261: eGroup.setLeader(((BooleanOptionWidget) widget));
262: addToEnableGroup(phaseAlias, widget, "");
263: } else {
264: eGroup.addControl(widget);
265: }
266: } else {
267: eGroup.addControl(widget);
268: }
269: }
270:
271: private EnableGroup findEnableGroup(String phaseAlias,
272: String subPhaseAlias) {
273: Iterator it = getEnableGroups().iterator();
274: while (it.hasNext()) {
275: EnableGroup next = (EnableGroup) it.next();
276: if (next.getSubPhaseAlias() == null)
277: continue;
278: if (next.getPhaseAlias().equals(phaseAlias)
279: && next.getSubPhaseAlias().equals(subPhaseAlias))
280: return next;
281: }
282: return null;
283: }
284:
285: protected void updateAllEnableGroups() {
286: if (getEnableGroups() == null)
287: return;
288: Iterator it = getEnableGroups().iterator();
289:
290: while (it.hasNext()) {
291: EnableGroup eGroup = (EnableGroup) it.next();
292: if (eGroup.isPhaseOptType()) {
293: if (eGroup.getLeader() == null) {
294: continue;
295: }
296: if (eGroup.getLeader().getButton().getSelection()
297: && eGroup.getLeader().getButton().isEnabled()) {
298: eGroup.changeControlState(true);
299: } else {
300: eGroup.changeControlState(false);
301: }
302: }
303: }
304:
305: it = getEnableGroups().iterator();
306:
307: while (it.hasNext()) {
308: EnableGroup eGroup = (EnableGroup) it.next();
309: if (!eGroup.isPhaseOptType()) {
310: if (eGroup.getLeader() == null) {
311: continue;
312: }
313: if (eGroup.getLeader().getButton().getSelection()
314: && eGroup.getLeader().getButton().isEnabled()) {
315: eGroup.changeControlState(true);
316: } else {
317: eGroup.changeControlState(false);
318: }
319: }
320: }
321: }
322:
323: private void printEnableGroups() {
324: if (getEnableGroups() == null)
325: return;
326: Iterator it = getEnableGroups().iterator();
327: while (it.hasNext()) {
328: EnableGroup eGroup = (EnableGroup) it.next();
329: System.out.println(eGroup);
330: }
331: }
332:
333: /**
334: * creates a sash form - one side for a selection tree
335: * and the other for the options
336: */
337: protected Control createDialogArea(Composite parent) {
338: GridData gd;
339:
340: Composite dialogComp = (Composite) super
341: .createDialogArea(parent);
342: Composite topComp = new Composite(dialogComp, SWT.NONE);
343:
344: gd = new GridData(GridData.FILL_BOTH);
345: topComp.setLayoutData(gd);
346: GridLayout topLayout = new GridLayout();
347: topComp.setLayout(topLayout);
348:
349: // Set the things that TitleAreaDialog takes care of
350:
351: setTitle(Messages
352: .getString("AbstractOptionsDialog.Soot_Launching_Options")); //$NON-NLS-1$
353: setMessage(""); //$NON-NLS-1$
354:
355: // Create the SashForm that contains the selection area on the left,
356: // and the edit area on the right
357: setSashForm(new SashForm(topComp, SWT.NONE));
358: getSashForm().setOrientation(SWT.HORIZONTAL);
359:
360: gd = new GridData(GridData.FILL_BOTH);
361: getSashForm().setLayoutData(gd);
362:
363: Composite selection = createSelectionArea(getSashForm());
364:
365: setPageContainer(createEditArea(getSashForm()));
366:
367: initializePageContainer();
368:
369: // set general as first page
370: Control[] pages = getPageContainer().getChildren();
371: ((StackLayout) getPageContainer().getLayout()).topControl = pages[0];
372: getPageContainer().layout();
373:
374: try {
375: getSashForm().setWeights(new int[] { 30, 70 });
376: } catch (Exception e1) {
377: System.out.println(e1.getMessage());
378: }
379:
380: Label separator = new Label(topComp, SWT.HORIZONTAL
381: | SWT.SEPARATOR);
382: gd = new GridData(GridData.FILL_HORIZONTAL);
383: separator.setLayoutData(gd);
384:
385: dialogComp.layout(true);
386:
387: return dialogComp;
388: }
389:
390: // creates buttons Run and Close for a runnable dialog and
391: // buttons Save and Close for a savable one
392: protected void createButtonsForButtonBar(Composite parent) {
393: if (isCanRun()) {
394: createButton(parent, 1, Messages
395: .getString("AbstractOptionsDialog.Run"), true); //$NON-NLS-1$
396: createButton(parent, 2, Messages
397: .getString("AbstractOptionsDialog.Close"), false); //$NON-NLS-1$
398: } else {
399: createButton(parent, 0, Messages
400: .getString("AbstractOptionsDialog.Save"), true); //$NON-NLS-1$
401: createButton(parent, 2, Messages
402: .getString("AbstractOptionsDialog.Close"), false); //$NON-NLS-1$
403: }
404: }
405:
406: protected void buttonPressed(int i) {
407: switch (i) {
408: case 0: {
409: handleSaving();
410: break;
411: }
412: case 1: {
413: okPressed();
414: break;
415: }
416: case 2: {
417: cancelPressed();
418: break;
419: }
420: }
421:
422: }
423:
424: protected abstract HashMap savePressed();
425:
426: private void handleSaving() {
427:
428: saveConfigToMap(this .getConfigName());
429:
430: SavedConfigManager scm = new SavedConfigManager();
431: scm.setEditMap(getEditMap());
432: scm.handleEdits();
433:
434: super .okPressed();
435:
436: }
437:
438: private void saveConfigToMap(String name) {
439:
440: SootSavedConfiguration newConfig = new SootSavedConfiguration(
441: name, savePressed());
442:
443: newConfig.setEclipseDefs(getEclipseDefList());
444: if (getEditMap() == null) {
445: setEditMap(new HashMap());
446: }
447:
448: getEditMap().put(name, newConfig.toSaveArray());
449:
450: }
451:
452: protected abstract void initializePageContainer();
453:
454: protected abstract SootOption getInitialInput();
455:
456: /**
457: * initialize area containing options as a stack layout
458: */
459: private Composite createEditArea(Composite parent) {
460: Composite editArea = new Composite(parent, SWT.NONE);
461: StackLayout layout = new StackLayout();
462: editArea.setLayout(layout);
463: return editArea;
464: }
465:
466: /**
467: * creates the tree of options sections
468: */
469: private Composite createSelectionArea(Composite parent) {
470: Composite comp = new Composite(parent, SWT.NONE);
471: setSelectionArea(comp);
472:
473: GridLayout layout = new GridLayout();
474:
475: layout.numColumns = 3;
476: layout.marginHeight = 0;
477: layout.marginWidth = 5;
478:
479: comp.setLayout(layout);
480:
481: GridData gd = new GridData();
482:
483: TreeViewer tree = new TreeViewer(comp);
484: gd = new GridData(GridData.FILL_BOTH);
485: gd.horizontalSpan = 3;
486: gd.widthHint = 0;
487: tree.getControl().setLayoutData(gd);
488:
489: tree.setContentProvider(new SootOptionsContentProvider());
490: tree.setLabelProvider(new SootOptionsLabelProvider());
491: tree.setInput(getInitialInput());
492:
493: setTreeViewer(tree);
494:
495: tree.addSelectionChangedListener(this );
496:
497: tree.getControl().addKeyListener(new KeyAdapter() {
498: public void keyPressed(KeyEvent e) {
499: handleKeyPressed(e);
500: }
501: });
502:
503: return comp;
504: }
505:
506: /*
507: * (non-Javadoc)
508: * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
509: */
510: public void selectionChanged(SelectionChangedEvent event) {
511: IStructuredSelection selection = (IStructuredSelection) event
512: .getSelection();
513: if (!selection.isEmpty()) {
514: Object elem = selection.getFirstElement();
515: if (elem instanceof SootOption) {
516: SootOption sel = (SootOption) elem;
517: Control[] children = getPageContainer().getChildren();
518: String childTitle = null;
519: for (int i = 0; i < children.length; i++) {
520:
521: if (children[i] instanceof Composite) {
522: if (children[i] instanceof Group) {
523: childTitle = (String) ((Group) children[i])
524: .getData("id");
525:
526: }
527: if (childTitle.compareTo(sel.getAlias()) == 0) {
528: ((StackLayout) getPageContainer()
529: .getLayout()).topControl = children[i];
530: getPageContainer().layout();
531:
532: } else {
533: children[i].setVisible(false);
534: }
535: }
536: }
537: }
538: }
539: }
540:
541: public void addOtherBranches(SootOption root) {
542: SootOption sootMainClassBranch = new SootOption(
543: "Soot Main Class", "sootMainClass");
544: root.addChild(sootMainClassBranch);
545: }
546:
547: public void addOtherPages(Composite parent) {
548: Composite mainClassChild = sootMainClassCreate(parent);
549: }
550:
551: private Composite sootMainClassCreate(Composite parent) {
552:
553: Group editGroupSootMainClass = new Group(parent, SWT.NONE);
554: GridLayout layout = new GridLayout();
555: editGroupSootMainClass.setLayout(layout);
556:
557: editGroupSootMainClass.setText("Soot Main Class Manager");
558:
559: editGroupSootMainClass.setData("id", "sootMainClass");
560:
561: String desc = "Specify main class to run.";
562: if (desc.length() > 0) {
563: Label descLabel = new Label(editGroupSootMainClass,
564: SWT.WRAP);
565: descLabel.setText(desc);
566: }
567:
568: String defKey = "sootMainClass";
569: String defaultString;
570:
571: if (isInDefList(defKey)) {
572: defaultString = getStringDef(defKey);
573: } else {
574: defaultString = "";
575: }
576: setSootMainClassWidget(new StringOptionWidget(
577: editGroupSootMainClass, SWT.NONE, new OptionData(
578: "Soot Main Class", "", "", "sootMainClass",
579: "\nUses specified main class to run Soot.",
580: defaultString)));
581:
582: return editGroupSootMainClass;
583: }
584:
585: private StringOptionWidget sootMainClassWidget;
586:
587: private void setPageContainer(Composite comp) {
588: pageContainer = comp;
589: }
590:
591: protected Composite getPageContainer() {
592: return pageContainer;
593: }
594:
595: /**
596: * Returns the sashForm.
597: * @return SashForm
598: */
599: private SashForm getSashForm() {
600: return sashForm;
601: }
602:
603: /**
604: * Sets the sashForm.
605: * @param sashForm The sashForm to set
606: */
607: private void setSashForm(SashForm sashForm) {
608: this .sashForm = sashForm;
609: }
610:
611: protected void handleKeyPressed(KeyEvent event) {
612: }
613:
614: private Composite selectionArea;
615:
616: private void setSelectionArea(Composite comp) {
617: selectionArea = comp;
618: }
619:
620: private Composite getSelectionArea() {
621: return selectionArea;
622: }
623:
624: private void setTreeViewer(TreeViewer tree) {
625: treeViewer = tree;
626: }
627:
628: private TreeViewer getTreeViewer() {
629: return treeViewer;
630: }
631:
632: /**
633: * Returns the defList.
634: * @return HashMap
635: */
636: public HashMap getDefList() {
637: return defList;
638: }
639:
640: /**
641: * Sets the defList.
642: * @param defList The defList to set
643: */
644: public void setDefList(HashMap defList) {
645: this .defList = defList;
646: }
647:
648: /**
649: * Returns the config.
650: * @return HashMap
651: */
652: public HashMap getConfig() {
653: return config;
654: }
655:
656: /**
657: * Sets the config.
658: * @param config The config to set
659: */
660: public void setConfig(HashMap config) {
661: this .config = config;
662: }
663:
664: /**
665: * Returns the configName.
666: * @return String
667: */
668: public String getConfigName() {
669: return configName;
670: }
671:
672: /**
673: * Sets the configName.
674: * @param configName The configName to set
675: */
676: public void setConfigName(String configName) {
677: this .configName = configName;
678: }
679:
680: /**
681: * Returns the eclipseDefList.
682: * @return HashMap
683: */
684: public HashMap getEclipseDefList() {
685: return eclipseDefList;
686: }
687:
688: /**
689: * Sets the eclipseDefList.
690: * @param eclipseDefList The eclipseDefList to set
691: */
692: public void setEclipseDefList(HashMap eclipseDefList) {
693: this .eclipseDefList = eclipseDefList;
694: }
695:
696: /**
697: * Returns the editMap.
698: * @return HashMap
699: */
700: public HashMap getEditMap() {
701: return editMap;
702: }
703:
704: /**
705: * Sets the editMap.
706: * @param editMap The editMap to set
707: */
708: public void setEditMap(HashMap editMap) {
709: this .editMap = editMap;
710: }
711:
712: /**
713: * Returns the canRun.
714: * @return boolean
715: */
716: public boolean isCanRun() {
717: return canRun;
718: }
719:
720: /**
721: * Sets the canRun.
722: * @param canRun The canRun to set
723: */
724: public void setCanRun(boolean canRun) {
725: this .canRun = canRun;
726: }
727:
728: /**
729: * @return
730: */
731: public HashMap getRadioGroups() {
732: return radioGroups;
733: }
734:
735: /**
736: * @param map
737: */
738: public void setRadioGroups(HashMap map) {
739: radioGroups = map;
740: }
741:
742: /**
743: * @return
744: */
745: public ArrayList getEnableGroups() {
746: return enableGroups;
747: }
748:
749: /**
750: * @param map
751: */
752: public void setEnableGroups(ArrayList list) {
753: enableGroups = list;
754: }
755:
756: /**
757: * @return
758: */
759: public Button getAddButton() {
760: return addButton;
761: }
762:
763: /**
764: * @return
765: */
766: public Button getRemoveButton() {
767: return removeButton;
768: }
769:
770: /**
771: * @param button
772: */
773: public void setAddButton(Button button) {
774: addButton = button;
775: }
776:
777: /**
778: * @param button
779: */
780: public void setRemoveButton(Button button) {
781: removeButton = button;
782: }
783:
784: /**
785: * @return
786: */
787: public CheckboxTableViewer getTableViewer() {
788: return tableViewer;
789: }
790:
791: /**
792: * @param viewer
793: */
794: public void setTableViewer(CheckboxTableViewer viewer) {
795: tableViewer = viewer;
796: }
797:
798: /**
799: * @return
800: */
801: public StringOptionWidget getSootMainClassWidget() {
802: return sootMainClassWidget;
803: }
804:
805: /**
806: * @param widget
807: */
808: public void setSootMainClassWidget(StringOptionWidget widget) {
809: sootMainClassWidget = widget;
810: }
811:
812: /**
813: * @return
814: */
815: public String getSootMainClass() {
816: return sootMainClass;
817: }
818:
819: /**
820: * @param string
821: */
822: public void setSootMainClass(String string) {
823: sootMainClass = string;
824: }
825:
826: }
|