
org.hamcrest.generator.QDoxFactoryReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hamcrest-generator Show documentation
Show all versions of hamcrest-generator Show documentation
A tool to allow many Matcher implementations to be combined into a single class so users don't have to remember many classes/packages to import. Generates code.
The newest version!
package org.hamcrest.generator;
import com.thoughtworks.qdox.model.DocletTag;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.JavaParameter;
import com.thoughtworks.qdox.model.Type;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
/**
* Wraps an existing sequence of FactoryMethods, and attempts to pull in
* parameter names and JavaDoc (which aren't available using reflection) using
* QDox.
*
* @see QDox
* @author Joe Walnes
*/
public class QDoxFactoryReader implements Iterable {
private final Iterable wrapped;
private final JavaClass classSource;
private static final Pattern GENERIC_REGEX = Pattern.compile("<.*>");
private static final Pattern VARARGS_REGEX = Pattern.compile("...", Pattern.LITERAL);
public QDoxFactoryReader(Iterable wrapped, QDox qdox, String className) {
this.wrapped = wrapped;
this.classSource = qdox.getClassByName(className);
}
@Override
public Iterator iterator() {
final Iterator iterator = wrapped.iterator();
return new Iterator() {
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public FactoryMethod next() {
return enhance(iterator.next());
}
@Override
public void remove() {
iterator.remove();
}
};
}
private FactoryMethod enhance(FactoryMethod factoryMethod) {
JavaMethod methodSource = findMethodInSource(factoryMethod);
if (methodSource != null) {
factoryMethod.setJavaDoc(createJavaDocComment(methodSource));
JavaParameter[] parametersFromSource
= methodSource.getParameters();
List parametersFromReflection
= factoryMethod.getParameters();
if (parametersFromReflection.size() == parametersFromSource.length) {
for (int i = 0; i < parametersFromSource.length; i++) {
parametersFromReflection.get(i).setName(
parametersFromSource[i].getName());
}
}
}
return factoryMethod;
}
/**
* Attempts to locate the source code for a specific method, by cross-referencing
* the signature returned by reflection with the list of methods parsed by QDox.
*/
private JavaMethod findMethodInSource(FactoryMethod factoryMethod) {
// Note, this doesn't always work - it struggles with some kinds of generics.
// This seems to cover most cases though.
List params = factoryMethod.getParameters();
Type[] types = new Type[params.size()];
boolean varArgs = false;
for (int i = 0; i < types.length; i++) {
String type = params.get(i).getType();
varArgs = VARARGS_REGEX.matcher(type).find();
// QDox ignores varargs and generics, so we strip them out to help QDox.
type = GENERIC_REGEX.matcher(type).replaceAll("");
type = VARARGS_REGEX.matcher(type).replaceAll("");
types[i] = new Type(type);
}
JavaMethod[] methods = classSource.getMethodsBySignature(factoryMethod.getName(), types, false, varArgs);
return methods.length == 1 ? methods[0] : null;
}
/**
* Reconstructs the JavaDoc as a string for a particular method.
*/
private static String createJavaDocComment(JavaMethod methodSource) {
String comment = methodSource.getComment();
DocletTag[] tags = methodSource.getTags();
if ((comment == null || comment.trim().length() == 0) && tags.length == 0) {
return null;
}
StringBuilder result = new StringBuilder();
result.append(comment);
result.append("\n\n");
for (DocletTag tag : tags) {
result.append('@').append(tag.getName())
.append(' ').append(tag.getValue())
.append('\n');
}
return result.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy