|
|
@@ -39,6 +39,9 @@ import com.thoughtworks.qdox.model.JavaMethod; |
|
|
|
import com.thoughtworks.qdox.model.JavaParameter; |
|
|
|
import com.thoughtworks.qdox.model.Type; |
|
|
|
|
|
|
|
/** |
|
|
|
* Finds EventProducer interfaces and builds the event model for them. |
|
|
|
*/ |
|
|
|
public class EventProducerCollector { |
|
|
|
|
|
|
|
private static final String CLASSNAME_EVENT_PRODUCER = EventProducer.class.getName(); |
|
|
@@ -76,7 +79,7 @@ public class EventProducerCollector { |
|
|
|
for (int i = 0, c = classes.length; i < c; i++) { |
|
|
|
JavaClass clazz = classes[i]; |
|
|
|
if (clazz.isInterface() && implementsInterface(clazz, CLASSNAME_EVENT_PRODUCER)) { |
|
|
|
processJavaClass(clazz, filename); |
|
|
|
processEventProducerInterface(clazz, filename); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@@ -92,68 +95,81 @@ public class EventProducerCollector { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
protected void processJavaClass(JavaClass clazz, String javaFilename) |
|
|
|
/** |
|
|
|
* Processes an EventProducer interface and creates an EventProducerModel from it. |
|
|
|
* @param clazz the EventProducer interface |
|
|
|
* @param javaFilename the filename of the Java source of the interface |
|
|
|
* @throws EventConventionException if the event producer conventions are violated |
|
|
|
* @throws ClassNotFoundException if a required class cannot be found |
|
|
|
*/ |
|
|
|
protected void processEventProducerInterface(JavaClass clazz, String javaFilename) |
|
|
|
throws EventConventionException, ClassNotFoundException { |
|
|
|
EventProducerModel prodMeta = new EventProducerModel(clazz.getFullyQualifiedName()); |
|
|
|
JavaMethod[] methods = clazz.getMethods(); |
|
|
|
JavaMethod[] methods = clazz.getMethods(true); |
|
|
|
for (int i = 0, c = methods.length; i < c; i++) { |
|
|
|
JavaMethod method = methods[i]; |
|
|
|
|
|
|
|
//Check EventProducer conventions |
|
|
|
if (!method.getReturns().isVoid()) { |
|
|
|
throw new EventConventionException("All methods of interface " |
|
|
|
+ clazz.getFullyQualifiedName() + " must have return type 'void'!"); |
|
|
|
} |
|
|
|
String methodSig = clazz.getFullyQualifiedName() + "." + method.getCallSignature(); |
|
|
|
JavaParameter[] params = method.getParameters(); |
|
|
|
if (params.length < 1) { |
|
|
|
throw new EventConventionException("The method " + methodSig |
|
|
|
+ " must have at least one parameter: 'Object source'!"); |
|
|
|
} |
|
|
|
Type firstType = params[0].getType(); |
|
|
|
if (firstType.isPrimitive() || !"source".equals(params[0].getName())) { |
|
|
|
throw new EventConventionException("The first parameter of the method " + methodSig |
|
|
|
+ " must be: 'Object source'!"); |
|
|
|
} |
|
|
|
|
|
|
|
//build method model |
|
|
|
DocletTag tag = method.getTagByName("event.severity"); |
|
|
|
EventSeverity severity; |
|
|
|
if (tag != null) { |
|
|
|
severity = EventSeverity.valueOf(tag.getValue()); |
|
|
|
} else { |
|
|
|
severity = EventSeverity.INFO; |
|
|
|
} |
|
|
|
EventMethodModel methodMeta = new EventMethodModel( |
|
|
|
method.getName(), severity); |
|
|
|
if (params.length > 1) { |
|
|
|
for (int j = 1, cj = params.length; j < cj; j++) { |
|
|
|
JavaParameter p = params[j]; |
|
|
|
Class type; |
|
|
|
JavaClass pClass = p.getType().getJavaClass(); |
|
|
|
if (p.getType().isPrimitive()) { |
|
|
|
type = (Class)PRIMITIVE_MAP.get(pClass.getName()); |
|
|
|
if (type == null) { |
|
|
|
throw new UnsupportedOperationException( |
|
|
|
"Primitive datatype not supported: " + pClass.getName()); |
|
|
|
} |
|
|
|
} else { |
|
|
|
String className = pClass.getFullyQualifiedName(); |
|
|
|
type = Class.forName(className); |
|
|
|
EventMethodModel methodMeta = createMethodModel(method); |
|
|
|
prodMeta.addMethod(methodMeta); |
|
|
|
} |
|
|
|
this.model.addProducer(prodMeta); |
|
|
|
} |
|
|
|
|
|
|
|
private EventMethodModel createMethodModel(JavaMethod method) |
|
|
|
throws EventConventionException, ClassNotFoundException { |
|
|
|
JavaClass clazz = method.getParentClass(); |
|
|
|
//Check EventProducer conventions |
|
|
|
if (!method.getReturns().isVoid()) { |
|
|
|
throw new EventConventionException("All methods of interface " |
|
|
|
+ clazz.getFullyQualifiedName() + " must have return type 'void'!"); |
|
|
|
} |
|
|
|
String methodSig = clazz.getFullyQualifiedName() + "." + method.getCallSignature(); |
|
|
|
JavaParameter[] params = method.getParameters(); |
|
|
|
if (params.length < 1) { |
|
|
|
throw new EventConventionException("The method " + methodSig |
|
|
|
+ " must have at least one parameter: 'Object source'!"); |
|
|
|
} |
|
|
|
Type firstType = params[0].getType(); |
|
|
|
if (firstType.isPrimitive() || !"source".equals(params[0].getName())) { |
|
|
|
throw new EventConventionException("The first parameter of the method " + methodSig |
|
|
|
+ " must be: 'Object source'!"); |
|
|
|
} |
|
|
|
|
|
|
|
//build method model |
|
|
|
DocletTag tag = method.getTagByName("event.severity"); |
|
|
|
EventSeverity severity; |
|
|
|
if (tag != null) { |
|
|
|
severity = EventSeverity.valueOf(tag.getValue()); |
|
|
|
} else { |
|
|
|
severity = EventSeverity.INFO; |
|
|
|
} |
|
|
|
EventMethodModel methodMeta = new EventMethodModel( |
|
|
|
method.getName(), severity); |
|
|
|
if (params.length > 1) { |
|
|
|
for (int j = 1, cj = params.length; j < cj; j++) { |
|
|
|
JavaParameter p = params[j]; |
|
|
|
Class type; |
|
|
|
JavaClass pClass = p.getType().getJavaClass(); |
|
|
|
if (p.getType().isPrimitive()) { |
|
|
|
type = (Class)PRIMITIVE_MAP.get(pClass.getName()); |
|
|
|
if (type == null) { |
|
|
|
throw new UnsupportedOperationException( |
|
|
|
"Primitive datatype not supported: " + pClass.getName()); |
|
|
|
} |
|
|
|
methodMeta.addParameter(type, p.getName()); |
|
|
|
} else { |
|
|
|
String className = pClass.getFullyQualifiedName(); |
|
|
|
type = Class.forName(className); |
|
|
|
} |
|
|
|
methodMeta.addParameter(type, p.getName()); |
|
|
|
} |
|
|
|
Type[] exceptions = method.getExceptions(); |
|
|
|
if (exceptions != null && exceptions.length > 0) { |
|
|
|
//We only use the first declared exception because that is always thrown |
|
|
|
JavaClass cl = exceptions[0].getJavaClass(); |
|
|
|
methodMeta.setExceptionClass(cl.getFullyQualifiedName()); |
|
|
|
methodMeta.setSeverity(EventSeverity.FATAL); //In case it's not set in the comments |
|
|
|
} |
|
|
|
prodMeta.addMethod(methodMeta); |
|
|
|
} |
|
|
|
this.model.addProducer(prodMeta); |
|
|
|
Type[] exceptions = method.getExceptions(); |
|
|
|
if (exceptions != null && exceptions.length > 0) { |
|
|
|
//We only use the first declared exception because that is always thrown |
|
|
|
JavaClass cl = exceptions[0].getJavaClass(); |
|
|
|
methodMeta.setExceptionClass(cl.getFullyQualifiedName()); |
|
|
|
methodMeta.setSeverity(EventSeverity.FATAL); //In case it's not set in the comments |
|
|
|
} |
|
|
|
return methodMeta; |
|
|
|
} |
|
|
|
|
|
|
|
public EventModel getModel() { |