package org.testng.eclipse.ui.conversion; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.contentassist.IContextInformation; import org.eclipse.ltk.core.refactoring.DocumentChange; import org.eclipse.ltk.core.refactoring.TextChange; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.text.edits.CopyTargetEdit; import org.eclipse.text.edits.DeleteEdit; import org.eclipse.text.edits.InsertEdit; import org.eclipse.text.edits.MalformedTreeException; import org.eclipse.text.edits.MoveSourceEdit; import org.eclipse.text.edits.MoveTargetEdit; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; import org.eclipse.text.edits.TextEdit; import org.eclipse.text.edits.TextEditVisitor; import org.eclipse.text.edits.UndoEdit; import org.testng.eclipse.TestNGPlugin; import org.testng.eclipse.ui.Images; /** * This class implements the proposal to convert a JUnit class into a TestNG one. * * Created on Aug 8, 2005 * @author cbeust */ public class JUnitRewriteCorrectionProposal implements IJavaCompletionProposal { private ASTRewrite m_rewriter; private ICompilationUnit m_cu; private String m_name; public JUnitRewriteCorrectionProposal(String name, ICompilationUnit cu, ASTRewrite rewriter, int i) { m_name = name; m_rewriter = rewriter; m_cu = cu; } public void apply(IDocument document) { TextEdit edits = m_rewriter.rewriteAST(document, null); UndoEdit undo = null; try { undo = edits.apply(document); } catch(MalformedTreeException e) { e.printStackTrace(); } catch(BadLocationException e) { e.printStackTrace(); } } public Point getSelection(IDocument document) { // TODO Auto-generated method stub return null; } public String getAdditionalProposalInfo() { return getHtml(); } protected TextChange createTextChange() throws CoreException { ICompilationUnit cu = m_cu; String name = "TestNG"; TextChange change = null; // if (!cu.getResource().exists()) { // String source; // try { // source= cu.getSource(); // } catch (JavaModelException e) { // JavaPlugin.log(e); // source= new String(); // empty // } // } Document document= new Document(cu.getSource()); document.setInitialLineDelimiter(StubUtility.getLineDelimiterUsed(cu)); change= new DocumentChange(name, document); // } else { // Document doc = new Document(m_cu.getSource()); // CompilationUnitChange cuChange = new CompilationUnitChange(name, cu); // cuChange.setSaveMode(TextFileChange.LEAVE_DIRTY); // change= cuChange; // } TextEdit rootEdit= new MultiTextEdit(); change.setEdit(rootEdit); // initialize text change // IDocument document= change.getCurrentDocument(new NullProgressMonitor()); addEdits(change.getCurrentDocument(new NullProgressMonitor()), rootEdit); return change; } protected void addEdits(IDocument document, TextEdit editRoot) throws CoreException { // super.addEdits(document, editRoot); ASTRewrite rewrite = m_rewriter; if (rewrite != null) { try { TextEdit edit= rewrite.rewriteAST(); editRoot.addChild(edit); } catch (IllegalArgumentException e) { throw new CoreException(TestNGPlugin.createError(e)); } } // if (fImportRewrite != null) { // editRoot.addChild(fImportRewrite.rewriteImports(new NullProgressMonitor())); // } } private TextChange getTextChange() { try { return createTextChange(); } catch (CoreException e) { e.printStackTrace(); } return null; } /** * @return an HTML version of the change that's about to be made, with changes * highlighted in bold. */ private String getHtml() { final StringBuffer buf= new StringBuffer(); try { final TextChange change= getTextChange(); change.setKeepPreviewEdits(true); final IDocument previewContent= change.getPreviewDocument(new NullProgressMonitor()); final TextEdit rootEdit= change.getPreviewEdit(change.getEdit()); class EditAnnotator extends TextEditVisitor { private int m_writtenToPos = 0; public void unchangedUntil(int pos) { if (pos > m_writtenToPos) { appendContent(previewContent, m_writtenToPos, pos, buf, true); m_writtenToPos = pos; } } public boolean visit(MoveTargetEdit edit) { return true; //rangeAdded(edit); } public boolean visit(CopyTargetEdit edit) { return true; //return rangeAdded(edit); } public boolean visit(InsertEdit edit) { return rangeAdded(edit); } public boolean visit(ReplaceEdit edit) { if (edit.getLength() > 0) return rangeAdded(edit); return rangeRemoved(edit); } public boolean visit(MoveSourceEdit edit) { return rangeRemoved(edit); } public boolean visit(DeleteEdit edit) { return rangeRemoved(edit); } private boolean rangeRemoved(TextEdit edit) { unchangedUntil(edit.getOffset()); return false; } private boolean rangeAdded(TextEdit edit) { unchangedUntil(edit.getOffset()); buf.append("<b>"); //$NON-NLS-1$ appendContent(previewContent, edit.getOffset(), edit.getExclusiveEnd(), buf, false); buf.append("</b>"); //$NON-NLS-1$ m_writtenToPos = edit.getExclusiveEnd(); return false; } } EditAnnotator ea = new EditAnnotator(); rootEdit.accept(ea); // Final pre-existing region ea.unchangedUntil(previewContent.getLength()); } catch (CoreException e) { TestNGPlugin.log(e); } return buf.toString(); } private final int m_surroundLines= 1; private void appendContent(IDocument text, int startOffset, int endOffset, StringBuffer buf, boolean surroundLinesOnly) { try { int startLine= text.getLineOfOffset(startOffset); int endLine= text.getLineOfOffset(endOffset); boolean dotsAdded= false; if (surroundLinesOnly && startOffset == 0) { // no surround lines for the top no-change range startLine= Math.max(endLine - m_surroundLines, 0); buf.append("...<br>"); //$NON-NLS-1$ dotsAdded= true; } for (int i= startLine; i <= endLine; i++) { if (surroundLinesOnly) { if ((i - startLine > m_surroundLines) && (endLine - i > m_surroundLines)) { if (!dotsAdded) { buf.append("...<br>"); //$NON-NLS-1$ dotsAdded= true; } else if (endOffset == text.getLength()) { return; // no surround lines for the bottom no-change range } continue; } } IRegion lineInfo= text.getLineInformation(i); int start= lineInfo.getOffset(); int end= start + lineInfo.getLength(); int from= Math.max(start, startOffset); int to= Math.min(end, endOffset); String content= text.get(from, to - from); if (surroundLinesOnly && (from == start) && containsOnlyWhitespaces(content)) { continue; // ignore empty lines except when range started in the middle of a line } for (int k= 0; k < content.length(); k++) { char ch= content.charAt(k); if (ch == '<') { buf.append("<"); //$NON-NLS-1$ } else if (ch == '>') { buf.append(">"); //$NON-NLS-1$ } else { buf.append(ch); } } if (to == end && to != endOffset) { // new line when at the end of the line, and not end of range buf.append("<br>"); //$NON-NLS-1$ } } } catch (BadLocationException e) { // ignore } } private static boolean containsOnlyWhitespaces(String s) { int size= s.length(); for (int i= 0; i < size; i++) { if (!Character.isWhitespace(s.charAt(i))) return false; } return true; } public String getDisplayString() { return m_name; } public Image getImage() { return Images.getTestNGImage(); } public IContextInformation getContextInformation() { return null; } public int getRelevance() { return 0; } }