package jqian.slicer.view; import java.util.*; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.*; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.IDocument; import org.eclipse.swt.SWT; import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.*; //import org.eclipse.swt.widgets.FileDialog; //import org.eclipse.core.resources.*; //import org.eclipse.ui.part.*; //import org.eclipse.ui.*; import org.eclipse.ui.dialogs.SelectionDialog; import org.eclipse.ui.texteditor.*; import org.eclipse.jdt.ui.*; import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.search.*; import jqian.slicer.util.*; import jqian.util.eclipse.JDTUtils; import jqian.util.eclipse.MethodSelectionDialog; public class CriteriaSelector extends Dialog { protected IJavaProject _project; protected ITextEditor _editor; protected ITextSelection _selection; protected String _entry; protected String _scenarioPath; protected String _slicedMethod; protected Collection<String> _vars = new LinkedList<String>(); protected int _line; protected boolean _sliceInGlobal; protected boolean _slicingOnAssignedOne; //--------------------- UI elements--------------------------// private Text _prjEntryText; private Text _criterionMethodText; private Text _lineText; private Text _lineContextText; private Text _variablesText; private String _defaultPrjEntry; private Button assignedButton; private boolean _prjEntryEditable; /** * Create the dialog * @param parentShell */ public CriteriaSelector(Shell parentShell,IJavaProject project,ITextEditor editor, ITextSelection selection, String defaultPrjEntry,boolean prjEntryEditable) { super(parentShell); this._project = project; this._editor = editor; this._selection = selection; this._defaultPrjEntry = defaultPrjEntry; this._prjEntryEditable = prjEntryEditable; } public int getLine(){ return _line; } public String getSlicingStartMethod(){ return _slicedMethod; } public String getScenarioPath(){ return _scenarioPath; } public boolean isSlicingInGlobal(){ return _sliceInGlobal; } public Collection<String> getSlicedVars(){ return _vars; } public boolean slicingOnAssignedVar(){ return _slicingOnAssignedOne; } //public String get /** * Create contents of the dialog * @param parent */ @Override protected Control createDialogArea(Composite parent) { Composite container = (Composite) super.createDialogArea(parent); container.setLayout(null); final Label projectEntryLabel = new Label(container, SWT.NONE); projectEntryLabel.setText("Project entry"); projectEntryLabel.setBounds(15, 17, 73, 17); _prjEntryText = new Text(container, SWT.BORDER); _prjEntryText.setBounds(94, 14, 303, 23); _prjEntryText.setText(_defaultPrjEntry); final Button entrySelectButton = new Button(container, SWT.NONE); entrySelectButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { onSelectProjectEntry(e); } }); entrySelectButton.setText("Select"); entrySelectButton.setBounds(403, 12, 46, 27); if(!_prjEntryEditable){ _prjEntryText.setEditable(false); entrySelectButton.setEnabled(false); } final Group slicingCriteriaGroup = new Group(container, SWT.NONE); slicingCriteriaGroup.setText("Slicing criterion"); slicingCriteriaGroup.setBounds(10, 52, 439, 252); final Label methodLabel = new Label(slicingCriteriaGroup, SWT.NONE); methodLabel.setText("method"); methodLabel.setBounds(10, 35, 53, 15); _criterionMethodText = new Text(slicingCriteriaGroup, SWT.BORDER); _criterionMethodText.setBounds(82, 32, 294, 23); //method not editable //_criterionMethodText.setEditable(false); final Label lineLabel = new Label(slicingCriteriaGroup, SWT.NONE); lineLabel.setText("line"); lineLabel.setBounds(22, 66, 20, 15); _lineText = new Text(slicingCriteriaGroup, SWT.BORDER); _lineText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { onChangeLine(e); } }); _lineText.setBounds(82, 61, 347, 23); int line = getSlicingCriteriionLine()+1; _lineText.setText(""+line); //line not editable //_lineText.setEditable(false); _lineContextText = new Text(slicingCriteriaGroup, SWT.V_SCROLL | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER); _lineContextText.setBounds(82, 90, 347, 61); updateLineText(getSlicingCriteriionLine()); final Label variableLabel = new Label(slicingCriteriaGroup, SWT.NONE); variableLabel.setText("variables"); variableLabel.setBounds(10, 160, 53, 15); _variablesText = new Text(slicingCriteriaGroup, SWT.BORDER); _variablesText.setBounds(82, 157, 347, 23); //variable not editable //_variablesText.setEditable(false); final Button selectButton = new Button(slicingCriteriaGroup, SWT.NONE); selectButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { onSelectCriterionMethod(e); } }); selectButton.setText("Select"); selectButton.setBounds(382, 30, 47, 27); assignedButton = new Button(slicingCriteriaGroup, SWT.CHECK); assignedButton.setText("Focus on variable on the left of assignment"); assignedButton.setBounds(70, 186, 335, 20); final Button isGlobalButton = new Button(slicingCriteriaGroup, SWT.CHECK); isGlobalButton.setBounds(229, 212, 200, 30); isGlobalButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { onSelectGlobalMode(e); } }); isGlobalButton.setText("Slicing in the global?"); if(isSelectionOnTheLeftOfAssignment()){ assignedButton.setSelection(true); } showSelectedVariables(); return container; } /** * Create contents of the button bar * @param parent */ @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); } /** * Return the initial size of the dialog */ @Override protected Point getInitialSize() { return new Point(467, 389); } protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText("Select criterion for slicing"); } //----------------------- Event handles ----------------------------// private void onSelectProjectEntry(SelectionEvent e){ String entry = selectProjectEntry(); if(entry!=null){ _prjEntryText.setText(entry); } } private void onSelectGlobalMode(SelectionEvent e){ _sliceInGlobal = !_sliceInGlobal; } private void onSelectCriterionMethod(SelectionEvent e){ String method = selectMethod("Select the method where a slicing criterion lies in"); _criterionMethodText.setText(method); } private void showSelectedVariables(){ //find selected java element ICompilationUnit icompilationUnit = JDTUtils.getCompliationUnit(_editor); IJavaElement[] elements = null; try{ elements = JDTUtils.codeResolve(icompilationUnit,_selection); }catch(Exception e){} // String all = ""; Object[] selected = getSelectedVariables(elements); for(int i=0;i<selected.length;i++){ String s = selected[i].toString(); all += s; if(i<selected.length-1) all +=", "; } _variablesText.setText(all); //The method label will be update with the line //get the selected method //if(selected.length>0){ //ILocalVariable local = (ILocalVariable)selected[0]; //IMethod method = JDTUtils.getMethod(local); //int line = getSlicingCriteriionLine(); //updateMethodSignature(line); //} } private void updateMethodSignature(int line){ try{ IMethod method = JDTUtils.getEnclosingMethod(_editor,line); String sig = JDTUtils.getMethodSootSignature(method); _criterionMethodText.setText(sig); } catch(Exception e){} } private Object[] getSelectedVariables(IJavaElement[] elements){ if(elements==null){ return new Object[0]; } try{ LinkedList<String> vars = new LinkedList<String>(); for(int i=0;i<elements.length;i++){ IJavaElement elmt = elements[i]; if(elmt instanceof ILocalVariable){ String valName = elmt.getElementName(); vars.add(valName); } else if(elmt instanceof IField){ IField field = (IField)elmt; int flags = field.getFlags(); //static field if(Flags.isStatic(flags) || Flags.isEnum(flags)){ String fieldSig = JDTUtils.getFieldSignature(field); vars.add(fieldSig); } else{ String selText = JDTUtils.getSelectedText(_editor, _selection); int index = selText.lastIndexOf('.'); String prefix = selText.substring(0,index+1); if(prefix.length()==0){ prefix = "this."; } String fieldSig = JDTUtils.getFieldSignature(field); String name = prefix + fieldSig; vars.add(name); } } } return vars.toArray(); }catch(Exception e){ ErrorPrinter.printError(e); } return null; } private boolean isSelectionOnTheLeftOfAssignment(){ try{ int offset = _selection.getOffset() + _selection.getLength(); IDocument doc = _editor.getDocumentProvider().getDocument(_editor.getEditorInput()); int length = doc.getLength(); char ch = ' '; while(offset<length){ ch = doc.getChar(offset); if(Character.isJavaIdentifierPart(ch) || Character.isJavaIdentifierStart(ch)){ break; } else if(Character.isWhitespace(ch)){ offset++; } else{ break; } } if(ch=='='){ return true; } } catch(Exception e){ } return false; } protected String selectMethod(String title){ try { Shell shell = this.getParentShell(); /*IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[]{_project}, false); SelectionDialog dialog = JavaUI.createTypeDialog(shell, new ProgressMonitorDialog(shell), scope, IJavaElementSearchConstants.CONSIDER_ALL_TYPES, false);*/ MethodSelectionDialog dlg = new MethodSelectionDialog(shell,title,_project); if (dlg.open() != IDialogConstants.OK_ID) return null; return dlg.getSelection(); } catch (Exception e) { return null; } } protected String selectProjectEntry(){ Shell shell = this.getParentShell(); int style = 0;//IJavaElementSearchConstants.CONSIDER_BINARIES; IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[]{_project}, false); SelectionDialog dlg = JavaUI.createMainTypeDialog(shell, new ProgressMonitorDialog(shell), scope,style,false); dlg.setTitle("Select a project entry"); dlg.setMessage("Ench analysis require a entry method, please select a method for slicing"); if (dlg.open() != IDialogConstants.OK_ID) return null; Object[] results = dlg.getResult(); if (results != null && results.length > 0) { IType type= (IType)results[0]; String name = type.getTypeQualifiedName(); String pkg = type.getPackageFragment().getElementName(); String signature = "<"+pkg+"."+name+": void main(java.lang.String[])>"; //OpenTypeHierarchyUtil.open(new IType[] { type }, fWindow); return signature; } return null; } private void onChangeLine(ModifyEvent e){ //update line String lineStr = _lineText.getText(); int line = Integer.parseInt(lineStr); //update method signature updateMethodSignature(line-1); //update line context updateLineText(line-1); } private int getSlicingCriteriionLine(){ return _selection.getEndLine(); } private void updateLineText(int line){ try{ IDocumentProvider provider = _editor.getDocumentProvider(); IDocument doc = provider.getDocument(_editor.getEditorInput()); int startLine = line-2; startLine = startLine>=0? startLine:0; int endLine = line+2; while(endLine>doc.getNumberOfLines()){ endLine--; } String text = ""; for(int i=startLine;i<=endLine;i++){ text += getLineText(i,doc); if(line<endLine) text += "\n"; } if(_lineContextText!=null) _lineContextText.setText(text); }catch(Exception e){ if(_lineContextText!=null) _lineContextText.setText(""); } } private String getLineText(int line,IDocument doc) throws Exception{ IRegion region = doc.getLineInformation(line); int offset = region.getOffset(); int length = region.getLength(); return doc.get(offset,length); } /** Check the validence of a selected slicing criteria. */ protected boolean checkValidence(){ return true; } protected void buttonPressed(int buttonId) { if (buttonId == IDialogConstants.OK_ID) { //return only if the inputted slicing criterion is validate if(!checkValidence()) return; //get sliced variables String varText = _variablesText.getText(); String[] strs = varText.split(","); _vars = Arrays.asList(strs); _line = Integer.parseInt(_lineText.getText()); _slicedMethod = _criterionMethodText.getText(); _slicingOnAssignedOne = assignedButton.getSelection(); } super.buttonPressed(buttonId); } }