All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.markusbernhardt.xmldoclet.Parser Maven / Gradle / Ivy

package com.github.markusbernhardt.xmldoclet;

import java.util.Map;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.markusbernhardt.xmldoclet.xjc.Annotation;
import com.github.markusbernhardt.xmldoclet.xjc.AnnotationArgument;
import com.github.markusbernhardt.xmldoclet.xjc.AnnotationElement;
import com.github.markusbernhardt.xmldoclet.xjc.AnnotationInstance;
import com.github.markusbernhardt.xmldoclet.xjc.Class;
import com.github.markusbernhardt.xmldoclet.xjc.Constructor;
import com.github.markusbernhardt.xmldoclet.xjc.Enum;
import com.github.markusbernhardt.xmldoclet.xjc.EnumConstant;
import com.github.markusbernhardt.xmldoclet.xjc.Field;
import com.github.markusbernhardt.xmldoclet.xjc.Interface;
import com.github.markusbernhardt.xmldoclet.xjc.Method;
import com.github.markusbernhardt.xmldoclet.xjc.MethodParameter;
import com.github.markusbernhardt.xmldoclet.xjc.ObjectFactory;
import com.github.markusbernhardt.xmldoclet.xjc.Package;
import com.github.markusbernhardt.xmldoclet.xjc.Root;
import com.github.markusbernhardt.xmldoclet.xjc.TagInfo;
import com.github.markusbernhardt.xmldoclet.xjc.TypeInfo;
import com.github.markusbernhardt.xmldoclet.xjc.TypeParameter;
import com.github.markusbernhardt.xmldoclet.xjc.Wildcard;
import com.sun.javadoc.AnnotationDesc;
import com.sun.javadoc.AnnotationTypeDoc;
import com.sun.javadoc.AnnotationTypeElementDoc;
import com.sun.javadoc.AnnotationValue;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.ConstructorDoc;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.Parameter;
import com.sun.javadoc.ParameterizedType;
import com.sun.javadoc.ProgramElementDoc;
import com.sun.javadoc.RootDoc;
import com.sun.javadoc.Tag;
import com.sun.javadoc.Type;
import com.sun.javadoc.TypeVariable;
import com.sun.javadoc.WildcardType;

public class Parser {

	private final static Logger log = LoggerFactory.getLogger(Parser.class);

	protected Map packages = new TreeMap();

	protected ObjectFactory objectFactory = new ObjectFactory();

	/**
	 * The entry point into parsing the javadoc.
	 * 
	 * @param rootDoc
	 *            The RootDoc intstance obtained via the doclet API
	 * @return The root node, containing everything parsed from javadoc doclet
	 */
	public Root parseRootDoc(RootDoc rootDoc) {
		Root rootNode = objectFactory.createRoot();

		for (ClassDoc classDoc : rootDoc.classes()) {
			PackageDoc packageDoc = classDoc.containingPackage();

			Package packageNode = packages.get(packageDoc.name());
			if (packageNode == null) {
				packageNode = parsePackage(packageDoc);
				packages.put(packageDoc.name(), packageNode);
				rootNode.getPackage().add(packageNode);
			}

			if (classDoc instanceof AnnotationTypeDoc) {
				packageNode.getAnnotation().add(parseAnnotationTypeDoc((AnnotationTypeDoc) classDoc));
			} else if (classDoc.isEnum()) {
				packageNode.getEnum().add(parseEnum(classDoc));
			} else if (classDoc.isInterface()) {
				packageNode.getInterface().add(parseInterface(classDoc));
			} else {
				packageNode.getClazz().add(parseClass(classDoc));
			}
		}

		return rootNode;
	}

	protected Package parsePackage(PackageDoc packageDoc) {
		Package packageNode = objectFactory.createPackage();
		packageNode.setName(packageDoc.name());
		String comment = packageDoc.commentText();
		if (comment.length() > 0) {
			packageNode.setComment(comment);
		}

		for (Tag tag : packageDoc.tags()) {
			packageNode.getTag().add(parseTag(tag));
		}

		return packageNode;
	}

	/**
	 * Parse an annotation.
	 * 
	 * @param annotationTypeDoc
	 *            A AnnotationTypeDoc instance
	 * @return the annotation node
	 */
	protected Annotation parseAnnotationTypeDoc(AnnotationTypeDoc annotationTypeDoc) {
		Annotation annotationNode = objectFactory.createAnnotation();
		annotationNode.setName(annotationTypeDoc.name());
		annotationNode.setQualified(annotationTypeDoc.qualifiedName());
		String comment = annotationTypeDoc.commentText();
		if (comment.length() > 0) {
			annotationNode.setComment(comment);
		}
		annotationNode.setIncluded(annotationTypeDoc.isIncluded());
		annotationNode.setScope(parseScope(annotationTypeDoc));

		for (AnnotationTypeElementDoc annotationTypeElementDoc : annotationTypeDoc.elements()) {
			annotationNode.getElement().add(parseAnnotationTypeElementDoc(annotationTypeElementDoc));
		}

		for (AnnotationDesc annotationDesc : annotationTypeDoc.annotations()) {
			annotationNode.getAnnotation().add(parseAnnotationDesc(annotationDesc, annotationTypeDoc.qualifiedName()));
		}

		for (Tag tag : annotationTypeDoc.tags()) {
			annotationNode.getTag().add(parseTag(tag));
		}

		return annotationNode;
	}

	/**
	 * Parse the elements of an annotation
	 * 
	 * @param element
	 *            A AnnotationTypeElementDoc instance
	 * @return the annotation element node
	 */
	protected AnnotationElement parseAnnotationTypeElementDoc(AnnotationTypeElementDoc annotationTypeElementDoc) {
		AnnotationElement annotationElementNode = objectFactory.createAnnotationElement();
		annotationElementNode.setName(annotationTypeElementDoc.name());
		annotationElementNode.setQualified(annotationTypeElementDoc.qualifiedName());
		annotationElementNode.setType(parseTypeInfo(annotationTypeElementDoc.returnType()));

		AnnotationValue value = annotationTypeElementDoc.defaultValue();
		if (value != null) {
			annotationElementNode.setDefault(value.toString());
		}

		return annotationElementNode;
	}

	/**
	 * Parses annotation instances of an annotable program element
	 * 
	 * @param annotationDocs
	 *            Annotations decorated on some program element
	 * @return representation of annotations
	 */
	protected AnnotationInstance parseAnnotationDesc(AnnotationDesc annotationDesc, String programElement) {
		AnnotationInstance annotationInstanceNode = objectFactory.createAnnotationInstance();

		try {
			AnnotationTypeDoc annotTypeInfo = annotationDesc.annotationType();
			annotationInstanceNode.setName(annotTypeInfo.name());
			annotationInstanceNode.setQualified(annotTypeInfo.qualifiedTypeName());
		} catch (ClassCastException castException) {
			log.error("Unable to obtain type data about an annotation found on: " + programElement);
			log.error("Add to the classpath the class/jar that defines this annotation.");
		}

		for (AnnotationDesc.ElementValuePair elementValuesPair : annotationDesc.elementValues()) {
			AnnotationArgument annotationArgumentNode = objectFactory.createAnnotationArgument();
			annotationArgumentNode.setName(elementValuesPair.element().name());

			Type annotationArgumentType = elementValuesPair.element().returnType();
			annotationArgumentNode.setType(parseTypeInfo(annotationArgumentType));
			annotationArgumentNode.setPrimitive(annotationArgumentType.isPrimitive());
			annotationArgumentNode.setArray(annotationArgumentType.dimension().length() > 0);

			Object objValue = elementValuesPair.value().value();
			if (objValue instanceof AnnotationValue[]) {
				for (AnnotationValue annotationValue : (AnnotationValue[]) objValue) {
					annotationArgumentNode.getValue().add(annotationValue.value().toString());
				}
			} else if (objValue instanceof FieldDoc) {
				annotationArgumentNode.getValue().add(((FieldDoc) objValue).name());
			} else if (objValue instanceof ClassDoc) {
				annotationArgumentNode.getValue().add(((ClassDoc) objValue).qualifiedTypeName());
			} else {
				annotationArgumentNode.getValue().add(objValue.toString());
			}
			annotationInstanceNode.getArgument().add(annotationArgumentNode);
		}

		return annotationInstanceNode;
	}

	protected Enum parseEnum(ClassDoc classDoc) {
		Enum enumNode = objectFactory.createEnum();
		enumNode.setName(classDoc.name());
		enumNode.setQualified(classDoc.qualifiedName());
		String comment = classDoc.commentText();
		if (comment.length() > 0) {
			enumNode.setComment(comment);
		}
		enumNode.setIncluded(classDoc.isIncluded());
		enumNode.setScope(parseScope(classDoc));

		Type superClassType = classDoc.superclassType();
		if (superClassType != null) {
			enumNode.setClazz(parseTypeInfo(superClassType));
		}

		for (Type interfaceType : classDoc.interfaceTypes()) {
			enumNode.getInterface().add(parseTypeInfo(interfaceType));
		}

		for (FieldDoc field : classDoc.enumConstants()) {
			enumNode.getConstant().add(parseEnumConstant(field));
		}

		for (AnnotationDesc annotationDesc : classDoc.annotations()) {
			enumNode.getAnnotation().add(parseAnnotationDesc(annotationDesc, classDoc.qualifiedName()));
		}

		for (Tag tag : classDoc.tags()) {
			enumNode.getTag().add(parseTag(tag));
		}

		return enumNode;
	}

	/**
	 * Parses an enum type definition
	 * 
	 * @param fieldDoc
	 * @return
	 */
	protected EnumConstant parseEnumConstant(FieldDoc fieldDoc) {
		EnumConstant enumConstant = objectFactory.createEnumConstant();
		enumConstant.setName(fieldDoc.name());
		String comment = fieldDoc.commentText();
		if (comment.length() > 0) {
			enumConstant.setComment(comment);
		}

		for (AnnotationDesc annotationDesc : fieldDoc.annotations()) {
			enumConstant.getAnnotation().add(parseAnnotationDesc(annotationDesc, fieldDoc.qualifiedName()));
		}

		for (Tag tag : fieldDoc.tags()) {
			enumConstant.getTag().add(parseTag(tag));
		}

		return enumConstant;
	}

	protected Interface parseInterface(ClassDoc classDoc) {

		Interface interfaceNode = objectFactory.createInterface();
		interfaceNode.setName(classDoc.name());
		interfaceNode.setQualified(classDoc.qualifiedName());
		String comment = classDoc.commentText();
		if (comment.length() > 0) {
			interfaceNode.setComment(comment);
		}
		interfaceNode.setIncluded(classDoc.isIncluded());
		interfaceNode.setScope(parseScope(classDoc));

		for (TypeVariable typeVariable : classDoc.typeParameters()) {
			interfaceNode.getGeneric().add(parseTypeParameter(typeVariable));
		}

		for (Type interfaceType : classDoc.interfaceTypes()) {
			interfaceNode.getInterface().add(parseTypeInfo(interfaceType));
		}

		for (MethodDoc method : classDoc.methods()) {
			interfaceNode.getMethod().add(parseMethod(method));
		}

		for (AnnotationDesc annotationDesc : classDoc.annotations()) {
			interfaceNode.getAnnotation().add(parseAnnotationDesc(annotationDesc, classDoc.qualifiedName()));
		}

		for (Tag tag : classDoc.tags()) {
			interfaceNode.getTag().add(parseTag(tag));
		}

		return interfaceNode;
	}

	protected Class parseClass(ClassDoc classDoc) {

		Class classNode = objectFactory.createClass();
		classNode.setName(classDoc.name());
		classNode.setQualified(classDoc.qualifiedName());
		String comment = classDoc.commentText();
		if (comment.length() > 0) {
			classNode.setComment(comment);
		}
		classNode.setAbstract(classDoc.isAbstract());
		classNode.setError(classDoc.isError());
		classNode.setException(classDoc.isException());
		classNode.setExternalizable(classDoc.isExternalizable());
		classNode.setIncluded(classDoc.isIncluded());
		classNode.setSerializable(classDoc.isSerializable());
		classNode.setScope(parseScope(classDoc));

		for (TypeVariable typeVariable : classDoc.typeParameters()) {
			classNode.getGeneric().add(parseTypeParameter(typeVariable));
		}

		Type superClassType = classDoc.superclassType();
		if (superClassType != null) {
			classNode.setClazz(parseTypeInfo(superClassType));
		}

		for (Type interfaceType : classDoc.interfaceTypes()) {
			classNode.getInterface().add(parseTypeInfo(interfaceType));
		}

		for (MethodDoc method : classDoc.methods()) {
			classNode.getMethod().add(parseMethod(method));
		}

		for (AnnotationDesc annotationDesc : classDoc.annotations()) {
			classNode.getAnnotation().add(parseAnnotationDesc(annotationDesc, classDoc.qualifiedName()));
		}

		for (ConstructorDoc constructor : classDoc.constructors()) {
			classNode.getConstructor().add(parseConstructor(constructor));
		}

		for (FieldDoc field : classDoc.fields()) {
			classNode.getField().add(parseField(field));
		}

		for (Tag tag : classDoc.tags()) {
			classNode.getTag().add(parseTag(tag));
		}

		return classNode;
	}

	protected Constructor parseConstructor(ConstructorDoc constructorDoc) {
		Constructor constructorNode = objectFactory.createConstructor();

		constructorNode.setName(constructorDoc.name());
		constructorNode.setQualified(constructorDoc.qualifiedName());
		String comment = constructorDoc.commentText();
		if (comment.length() > 0) {
			constructorNode.setComment(comment);
		}
		constructorNode.setScope(parseScope(constructorDoc));
		constructorNode.setIncluded(constructorDoc.isIncluded());
		constructorNode.setFinal(constructorDoc.isFinal());
		constructorNode.setNative(constructorDoc.isNative());
		constructorNode.setStatic(constructorDoc.isStatic());
		constructorNode.setSynchronized(constructorDoc.isSynchronized());
		constructorNode.setVarArgs(constructorDoc.isVarArgs());
		constructorNode.setSignature(constructorDoc.signature());

		for (Parameter parameter : constructorDoc.parameters()) {
			constructorNode.getParameter().add(parseMethodParameter(parameter));
		}

		for (Type exceptionType : constructorDoc.thrownExceptionTypes()) {
			constructorNode.getException().add(parseTypeInfo(exceptionType));
		}

		for (AnnotationDesc annotationDesc : constructorDoc.annotations()) {
			constructorNode.getAnnotation().add(parseAnnotationDesc(annotationDesc, constructorDoc.qualifiedName()));
		}

		for (Tag tag : constructorDoc.tags()) {
			constructorNode.getTag().add(parseTag(tag));
		}

		return constructorNode;
	}

	protected Method parseMethod(MethodDoc methodDoc) {
		Method methodNode = objectFactory.createMethod();

		methodNode.setName(methodDoc.name());
		methodNode.setQualified(methodDoc.qualifiedName());
		String comment = methodDoc.commentText();
		if (comment.length() > 0) {
			methodNode.setComment(comment);
		}
		methodNode.setScope(parseScope(methodDoc));
		methodNode.setAbstract(methodDoc.isAbstract());
		methodNode.setIncluded(methodDoc.isIncluded());
		methodNode.setFinal(methodDoc.isFinal());
		methodNode.setNative(methodDoc.isNative());
		methodNode.setStatic(methodDoc.isStatic());
		methodNode.setSynchronized(methodDoc.isSynchronized());
		methodNode.setVarArgs(methodDoc.isVarArgs());
		methodNode.setSignature(methodDoc.signature());
		methodNode.setReturn(parseTypeInfo(methodDoc.returnType()));

		for (Parameter parameter : methodDoc.parameters()) {
			methodNode.getParameter().add(parseMethodParameter(parameter));
		}

		for (Type exceptionType : methodDoc.thrownExceptionTypes()) {
			methodNode.getException().add(parseTypeInfo(exceptionType));
		}

		for (AnnotationDesc annotationDesc : methodDoc.annotations()) {
			methodNode.getAnnotation().add(parseAnnotationDesc(annotationDesc, methodDoc.qualifiedName()));
		}

		for (Tag tag : methodDoc.tags()) {
			methodNode.getTag().add(parseTag(tag));
		}

		return methodNode;
	}

	protected MethodParameter parseMethodParameter(Parameter parameter) {
		MethodParameter parameterMethodNode = objectFactory.createMethodParameter();
		parameterMethodNode.setName(parameter.name());
		parameterMethodNode.setType(parseTypeInfo(parameter.type()));

		for (AnnotationDesc annotationDesc : parameter.annotations()) {
			parameterMethodNode.getAnnotation().add(parseAnnotationDesc(annotationDesc, parameter.typeName()));
		}

		return parameterMethodNode;
	}

	protected Field parseField(FieldDoc fieldDoc) {
		Field fieldNode = objectFactory.createField();
		fieldNode.setType(parseTypeInfo(fieldDoc.type()));
		fieldNode.setName(fieldDoc.name());
		fieldNode.setQualified(fieldDoc.qualifiedName());
		String comment = fieldDoc.commentText();
		if (comment.length() > 0) {
			fieldNode.setComment(comment);
		}
		fieldNode.setScope(parseScope(fieldDoc));
		fieldNode.setFinal(fieldDoc.isFinal());
		fieldNode.setStatic(fieldDoc.isStatic());
		fieldNode.setVolatile(fieldDoc.isVolatile());
		fieldNode.setTransient(fieldDoc.isTransient());
		fieldNode.setConstant(fieldDoc.constantValueExpression());

		for (AnnotationDesc annotationDesc : fieldDoc.annotations()) {
			fieldNode.getAnnotation().add(parseAnnotationDesc(annotationDesc, fieldDoc.qualifiedName()));
		}

		for (Tag tag : fieldDoc.tags()) {
			fieldNode.getTag().add(parseTag(tag));
		}

		return fieldNode;
	}

	protected TypeInfo parseTypeInfo(Type type) {
		TypeInfo typeInfoNode = objectFactory.createTypeInfo();
		typeInfoNode.setQualified(type.qualifiedTypeName());
		String dimension = type.dimension();
		if (dimension.length() > 0) {
			typeInfoNode.setDimension(dimension);
		}

		WildcardType wildcard = type.asWildcardType();
		if (wildcard != null) {
			typeInfoNode.setWildcard(parseWildcard(wildcard));
		}

		ParameterizedType parameterized = type.asParameterizedType();
		if (parameterized != null) {
			for (Type typeArgument : parameterized.typeArguments()) {
				typeInfoNode.getGeneric().add(parseTypeInfo(typeArgument));
			}
		}

		return typeInfoNode;
	}

	protected Wildcard parseWildcard(WildcardType wildcard) {
		Wildcard wildcardNode = objectFactory.createWildcard();

		for (Type extendType : wildcard.extendsBounds()) {
			wildcardNode.getExtendsBound().add(parseTypeInfo(extendType));
		}

		for (Type superType : wildcard.superBounds()) {
			wildcardNode.getSuperBound().add(parseTypeInfo(superType));
		}

		return wildcardNode;
	}

	/**
	 * Parse type variables for generics
	 * 
	 * @param typeVariable
	 * @return
	 */
	protected TypeParameter parseTypeParameter(TypeVariable typeVariable) {
		TypeParameter typeParameter = objectFactory.createTypeParameter();
		typeParameter.setName(typeVariable.typeName());

		for (Type bound : typeVariable.bounds()) {
			typeParameter.getBound().add(bound.qualifiedTypeName());
		}

		return typeParameter;
	}

	protected TagInfo parseTag(Tag tagDoc) {
		TagInfo tagNode = objectFactory.createTagInfo();
		tagNode.setName(tagDoc.kind());
		tagNode.setText(tagDoc.text());
		return tagNode;
	}

	/**
	 * Returns string representation of scope
	 * 
	 * @param doc
	 * @return
	 */
	protected String parseScope(ProgramElementDoc doc) {
		if (doc.isPrivate()) {
			return "private";
		} else if (doc.isProtected()) {
			return "protected";
		} else if (doc.isPublic()) {
			return "public";
		}
		return "";
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy