package junit.extensions.eclipse.quick.javadoc; import java.util.regex.Matcher; import java.util.regex.Pattern; import junit.extensions.eclipse.quick.javadoc.internal.JavaDocActivator; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.TagElement; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.core.search.SearchParticipant; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.core.search.SearchRequestor; public class SearchJavaClassFromDocTagVisitor extends ASTVisitor { private static final String METHOD_PREFIX = "#"; private SearchRequestor requestor; private TypeDeclaration type = null; private IType targetType; private IProgressMonitor monitor = new NullProgressMonitor(); public SearchJavaClassFromDocTagVisitor(IType targetType, SearchRequestor requestor) { super(true); this.targetType = targetType; this.requestor = requestor; } public SearchJavaClassFromDocTagVisitor(IType targetType, SearchRequestor requestor,IProgressMonitor monitor) { this(targetType,requestor); this.monitor = monitor; } @Override public boolean visit(TypeDeclaration node) { if(node.getName().getIdentifier().equals("MISSING")) return true; this.type = node; return super.visit(node); } @Override public boolean visit(Javadoc node) { if(type != null && node.getParent() != type) return false; return super.visit(node); } public boolean visit(TagElement node) { if(QuickJUnitDocTagConstants.TestContext.toAnnotation().equals(node.getTagName())){ for(Object obj:node.fragments()){ String patternString = obj.toString(); if(patternString.trim().equals("")) continue; if(patternString.contains(METHOD_PREFIX)){ if(patternString.startsWith(METHOD_PREFIX)){ acceptMethodInCurrentType(patternString); continue; } acceptMethodPattern(patternString); }else{ acceptClassPattern(patternString); } } } return true; } private void acceptClassPattern(String patternString) { SearchPattern pattern = SearchPattern.createPattern(patternString, IJavaSearchConstants.TYPE, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EQUIVALENT_MATCH); search(pattern); } private void acceptMethodPattern(String patternString) { SearchPattern pattern = createMethodPattern(patternString); search(pattern); } private void search(SearchPattern pattern) { try { SearchEngine engine = new SearchEngine(); IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); SearchParticipant[] participants = new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}; engine.search(pattern, participants, scope, requestor, monitor); } catch (CoreException e) { JavaDocActivator.getDefault().handleSystemError(e, this); } } private SearchPattern createMethodPattern(String patternString) { SearchPattern pattern; patternString = patternString.replace(METHOD_PREFIX, "."); pattern= SearchPattern.createPattern(patternString, IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_ERASURE_MATCH); return pattern; } private void acceptMethodInCurrentType(String patternString) { Pattern methodPattern = Pattern.compile("#(.*)\\((.*)\\)"); Matcher matcher = methodPattern.matcher(patternString); if( matcher.matches() == false) return; String name = matcher.group(1); String paramString = matcher.group(2); String[] params = paramString == null || paramString.equals("") ? null : paramString.split(","); int index = 0; if(params != null && params.length != 0){ for(String param : params){ params[index++] = transParamToSignatureStyle(param); } } IMethod element = targetType.getMethod(name, params); match(element); } private String transParamToSignatureStyle(String param) { String sigStyle = Signature.createTypeSignature(param, true); return sigStyle; } private void match(IJavaElement elem) { if(!(elem instanceof IMethod)) return; try { IMethod element = (IMethod) elem; if(element.exists() == false) return; ISourceRange range = element.getSourceRange(); SearchMatch match = new SearchMatch(element, SearchMatch.A_ACCURATE, range.getOffset(), range.getLength(), null, null); requestor.acceptSearchMatch(match); } catch (CoreException e) { JavaDocActivator.getDefault().handleSystemError(e, this); } } }