package com.technophobia.substeps.document.content.view.hover.model.javadoc; import java.util.ArrayList; import java.util.List; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.SingleMemberAnnotation; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.TagElement; import org.eclipse.jdt.core.dom.TextElement; import com.technophobia.substeps.glossary.StepDescriptor; import com.technophobia.substeps.supplier.Transformer; public class JavaDocVisitor extends ASTVisitor { private final StringBuilder description; private final StringBuilder example; private final StringBuilder expression; private final List<String> parameterNames; private final Transformer<StepDescriptor, String> stepDescriptorToStringTransformer; private final String methodName; public JavaDocVisitor(final String methodName, final Transformer<StepDescriptor, String> stepDescriptorToStringTransformer) { this.methodName = methodName; this.stepDescriptorToStringTransformer = stepDescriptorToStringTransformer; this.description = new StringBuilder(); this.example = new StringBuilder(); this.expression = new StringBuilder(); this.parameterNames = new ArrayList<String>(); } @Override public void endVisit(final Javadoc node) { super.endVisit(node); if (isCorrectMethod(node.getParent())) { for (final Object tag : node.tags()) { final TagElement tagElement = (TagElement) tag; if (tagElement.getTagName() == null) { appendFragmentsTo(tagElement, description); } else if (tagElement.getTagName().trim().startsWith("@example")) { appendFragmentsTo(tagElement, example); } } } } @Override public void endVisit(final SingleMemberAnnotation node) { super.endVisit(node); if (isCorrectMethod(node.getParent())) { if ("Step".equals(node.getTypeName().toString())) { expression.append(node.getValue()); } } } @SuppressWarnings("unchecked") @Override public void endVisit(final MethodDeclaration node) { // TODO Auto-generated method stub super.endVisit(node); if (isCorrectMethod(node)) { final List<Object> parameterProperties = ((List<Object>) node .getStructuralProperty(MethodDeclaration.PARAMETERS_PROPERTY)); for (final Object prop : parameterProperties) { if (prop instanceof SingleVariableDeclaration) { this.parameterNames.add(((SingleVariableDeclaration) prop).getName().toString()); } } } } public String parsedJavaDoc() { if (isStepDescriptorDefined()) { final StepDescriptor descriptor = new StepDescriptor(); descriptor.setDescription(description.toString()); descriptor.setExample(example.toString()); descriptor.setExpression(buildExpression()); return stepDescriptorToStringTransformer.from(descriptor); } return description.toString(); } private boolean isStepDescriptorDefined() { return description.length() > 0 && expression.length() > 0; } private void appendFragmentsTo(final TagElement tagElement, final StringBuilder sb) { for (final Object fragment : tagElement.fragments()) { if (fragment instanceof TextElement) { sb.append(((TextElement) fragment).getText()); sb.append("\n"); } } } private String buildExpression() { String expr = expression.toString(); for (final String parameter : parameterNames) { expr = expr.replaceFirst("\\([^\\)]*\\)", "<" + parameter + ">"); } expr = expr.replaceAll("\\?", ""); expr = expr.replaceAll("\\\\", ""); if (expr.startsWith("\"")) { expr = expr.substring(1, expr.length() - 1); } return expr; } private boolean isCorrectMethod(final ASTNode node) { if (node instanceof MethodDeclaration) { final MethodDeclaration method = (MethodDeclaration) node; return methodName.equals(method.getName().toString()); } return false; } }