protected void process(ClassDoc clss) { writer.println(""); writer.println("## *" + clss.simpleTypeName() + "*"); writer.println(clss.commentText()); writer.println(""); if (clss.isEnum()) { for (FieldDoc field : clss.enumConstants()) { printEnumConstant(field); } writer.println(""); for (MethodDoc method : clss.methods(false)) { printMethod(method); } } else if (clss.isInterface()) { /* for (ClassDoc subClass : getDerivedClassessubclasses( clss )) { printSubClass(subClass); } */ } else { for (FieldDoc field : clss.fields(false)) { printField(field); } for (MethodDoc method : clss.methods(false)) { printMethod(method); } } }
protected void write(OutputStream o, ClassDoc clazz) throws ClassNotFoundException { String cname = mangleClassName(clazz.qualifiedName()); PrintWriter pw = wrapWriter(o); fields = clazz.fields(); methods = clazz.methods(); generateDeclsForClass(pw, clazz, cname); }
/** * Prints dependencies recovered from the methods of a class. A dependency is inferred only if * another relation between the two classes is not already in the graph. * * @param classes */ public void printInferredDependencies(ClassDoc c) { Options opt = optionProvider.getOptionsFor(c); String sourceName = c.toString(); if (hidden(c)) return; Set<Type> types = new HashSet<Type>(); // harvest method return and parameter types for (MethodDoc method : filterByVisibility(c.methods(false), opt.inferDependencyVisibility)) { types.add(method.returnType()); for (Parameter parameter : method.parameters()) { types.add(parameter.type()); } } // and the field types if (!opt.inferRelationships) { for (FieldDoc field : filterByVisibility(c.fields(false), opt.inferDependencyVisibility)) { types.add(field.type()); } } // see if there are some type parameters if (c.asParameterizedType() != null) { ParameterizedType pt = c.asParameterizedType(); types.addAll(Arrays.asList(pt.typeArguments())); } // see if type parameters extend something for (TypeVariable tv : c.typeParameters()) { if (tv.bounds().length > 0) types.addAll(Arrays.asList(tv.bounds())); } // and finally check for explicitly imported classes (this // assumes there are no unused imports...) if (opt.useImports) types.addAll(Arrays.asList(c.importedClasses())); // compute dependencies for (Type type : types) { // skip primitives and type variables, as well as dependencies // on the source class if (type.isPrimitive() || type instanceof WildcardType || type instanceof TypeVariable || c.toString().equals(type.asClassDoc().toString())) continue; // check if the destination is excluded from inference ClassDoc fc = type.asClassDoc(); if (hidden(fc)) continue; // check if source and destination are in the same package and if we are allowed // to infer dependencies between classes in the same package if (!opt.inferDepInPackage && c.containingPackage().equals(fc.containingPackage())) continue; // if source and dest are not already linked, add a dependency RelationPattern rp = getClassInfo(sourceName).getRelation(fc.toString()); if (rp == null || rp.matchesOne(new RelationPattern(RelationDirection.OUT))) { relation(opt, RelationType.DEPEND, c, fc, "", "", ""); } } }
/** * Build the serial UID information for the given class. * * @param node the XML element that specifies which components to document * @param classTree content tree to which the serial UID information will be added */ public void buildSerialUIDInfo(XMLNode node, Content classTree) { Content serialUidTree = writer.getSerialUIDInfoHeader(); FieldDoc[] fields = currentClass.fields(false); for (int i = 0; i < fields.length; i++) { if (fields[i].name().equals("serialVersionUID") && fields[i].constantValueExpression() != null) { writer.addSerialUIDInfo( SERIAL_VERSION_UID_HEADER, fields[i].constantValueExpression(), serialUidTree); break; } } classTree.addContent(serialUidTree); }
private int doTwoWordFields( FieldDefsRes res, ClassDoc clazz, int offset, String cname, boolean padWord) throws ClassNotFoundException { boolean first = true; FieldDoc[] fields = clazz.fields(); for (int i = 0; i < fields.length; i++) { FieldDoc field = fields[i]; String tc = field.type().typeName(); boolean twoWords = (tc.equals("long") || tc.equals("double")); if (twoWords && doField(res, field, cname, first && padWord)) { offset += 8; first = false; } } return offset; }
protected FieldDefsRes fieldDefs(ClassDoc clazz, String cname, boolean bottomMost) throws ClassNotFoundException { FieldDefsRes res; int offset; boolean didTwoWordFields = false; ClassDoc superclazz = clazz.superclass(); if (superclazz != null) { String supername = superclazz.qualifiedName(); res = new FieldDefsRes(clazz, fieldDefs(superclazz, cname, false), bottomMost); offset = res.parent.byteSize; } else { res = new FieldDefsRes(clazz, null, bottomMost); offset = 0; } FieldDoc[] fields = clazz.fields(); for (int i = 0; i < fields.length; i++) { FieldDoc field = fields[i]; if (doubleAlign && !didTwoWordFields && (offset % 8) == 0) { offset = doTwoWordFields(res, clazz, offset, cname, false); didTwoWordFields = true; } String tc = field.type().typeName(); boolean twoWords = (tc.equals("long") || tc.equals("double")); if (!doubleAlign || !twoWords) { if (doField(res, field, cname, false)) offset += 4; } } if (doubleAlign && !didTwoWordFields) { if ((offset % 8) != 0) offset += 4; offset = doTwoWordFields(res, clazz, offset, cname, true); } res.byteSize = offset; return res; }
/** * Build the sorted list of all the deprecated APIs in this run. Build separate lists for * deprecated packages, classes, constructors, methods and fields. * * @param configuration the current configuration of the doclet. */ private void buildDeprecatedAPIInfo(Configuration configuration) { PackageDoc[] packages = configuration.packages; PackageDoc pkg; for (int c = 0; c < packages.length; c++) { pkg = packages[c]; if (Util.isDeprecated(pkg)) { getList(PACKAGE).add(pkg); } } ClassDoc[] classes = configuration.root.classes(); for (int i = 0; i < classes.length; i++) { ClassDoc cd = classes[i]; if (Util.isDeprecated(cd)) { if (cd.isOrdinaryClass()) { getList(CLASS).add(cd); } else if (cd.isInterface()) { getList(INTERFACE).add(cd); } else if (cd.isException()) { getList(EXCEPTION).add(cd); } else if (cd.isEnum()) { getList(ENUM).add(cd); } else if (cd.isError()) { getList(ERROR).add(cd); } else if (cd.isAnnotationType()) { getList(ANNOTATION_TYPE).add(cd); } } composeDeprecatedList(getList(FIELD), cd.fields()); composeDeprecatedList(getList(METHOD), cd.methods()); composeDeprecatedList(getList(CONSTRUCTOR), cd.constructors()); if (cd.isEnum()) { composeDeprecatedList(getList(ENUM_CONSTANT), cd.enumConstants()); } if (cd.isAnnotationType()) { composeDeprecatedList(getList(ANNOTATION_TYPE_MEMBER), ((AnnotationTypeDoc) cd).elements()); } } sortDeprecatedLists(); }
/** * Prints associations recovered from the fields of a class. An association is inferred only if * another relation between the two classes is not already in the graph. * * @param classes */ public void printInferredRelations(ClassDoc c) { Options opt = optionProvider.getOptionsFor(c); // check if the source is excluded from inference if (hidden(c)) return; for (FieldDoc field : c.fields(false)) { if (hidden(field)) continue; // skip statics if (field.isStatic()) continue; // skip primitives FieldRelationInfo fri = getFieldRelationInfo(field); if (fri == null) continue; // check if the destination is excluded from inference if (hidden(fri.cd)) continue; String destAdornment = fri.multiple ? "*" : ""; relation(opt, opt.inferRelationshipType, c, fri.cd, "", "", destAdornment); } }
/** * Parses the data for a class type definition * * @param docClass * @return */ protected static Class ParseClass(ClassDoc docClass) { assert (docClass != null); Class xmlClass = new Class(); // illegal use of this class. assert (xmlClass != null); xmlClass.name = docClass.name(); xmlClass.qualifiedName = docClass.qualifiedName(); xmlClass.isSerializable = docClass.isSerializable(); xmlClass.isExternalizable = docClass.isExternalizable(); xmlClass.isAbstract = docClass.isAbstract(); xmlClass.isException = docClass.isException(); xmlClass.isError = docClass.isError(); xmlClass.comment = docClass.commentText(); xmlClass.scope = DetermineScope(docClass); xmlClass.isIncluded = docClass.isIncluded(); xmlClass.typeVariables = ParseTypeVariables(docClass.typeParameters(), docClass.typeParamTags()); Type superClassType = docClass.superclassType(); if (superClassType != null) { xmlClass.superClass = ParseType(superClassType); } Type[] interfaces = docClass.interfaceTypes(); ArrayList<TypeInfo> interfaceTypeNames = new ArrayList<TypeInfo>(); if (interfaces != null && interfaces.length > 0) { for (Type interfaceType : interfaces) { interfaceTypeNames.add(ParseType(interfaceType)); } xmlClass.interfaces = interfaceTypeNames.toArray(new TypeInfo[] {}); } ConstructorDoc[] constructors = docClass.constructors(); if (constructors != null && constructors.length > 0) { ArrayList<Constructor> constructorList = new ArrayList<Constructor>(); for (ConstructorDoc constructor : constructors) { constructorList.add(ParseConstructor(constructor)); } xmlClass.constructors = constructorList.toArray(new Constructor[] {}); } else { log.debug("No constructors in class: " + docClass.name()); } MethodDoc[] methods = docClass.methods(); if (methods != null && methods.length > 0) { ArrayList<Method> methodList = new ArrayList<Method>(); for (MethodDoc method : methods) { methodList.add(ParseMethod(method)); } xmlClass.methods = methodList.toArray(new Method[] {}); } else { log.debug("No methods in class: " + docClass.name()); } FieldDoc[] fields = docClass.fields(); if (fields != null && fields.length > 0) { ArrayList<Field> fieldList = new ArrayList<Field>(); for (FieldDoc field : fields) { fieldList.add(ParseField(field)); } xmlClass.fields = fieldList.toArray(new Field[] {}); } xmlClass.annotationInstances = ParseAnnotationInstances(docClass.annotations(), docClass.qualifiedName()); return xmlClass; }
public static boolean start(RootDoc root) { ClassDoc cd = root.classes()[0]; FieldDoc fd = cd.fields()[0]; fd.firstSentenceTags(); return true; }
private void walkFormParameter(ClassDoc formDoc) { // walk all fields for (FieldDoc field : formDoc.fields(false)) { final AnnotationDesc pathParamAnnotation = Utils.findAnnotation(field, PathParam.class); if (pathParamAnnotation != null) { String name = (String) Utils.getAnnotationValue(pathParamAnnotation); pathParameters.add( new FormFieldParameter(field, pathParamAnnotation, MethodParameterType.Path)); continue; } final AnnotationDesc matrixParamAnnotation = Utils.findAnnotation(field, MatrixParam.class); if (matrixParamAnnotation != null) { matrixParameters.add( new FormFieldParameter(field, matrixParamAnnotation, MethodParameterType.Matrix)); continue; } final AnnotationDesc queryParamAnnotation = Utils.findAnnotation(field, QueryParam.class); if (queryParamAnnotation != null) { String name = (String) Utils.getAnnotationValue(queryParamAnnotation); queryParameters.add( new FormFieldParameter(field, queryParamAnnotation, MethodParameterType.Query)); continue; } final AnnotationDesc headerParamAnnotation = Utils.findAnnotation(field, HeaderParam.class); if (headerParamAnnotation != null) { String name = (String) Utils.getAnnotationValue(headerParamAnnotation); headerParameters.add( new FormFieldParameter(field, headerParamAnnotation, MethodParameterType.Header)); continue; } final AnnotationDesc cookieParamAnnotation = Utils.findAnnotation(field, CookieParam.class); if (cookieParamAnnotation != null) { String name = (String) Utils.getAnnotationValue(cookieParamAnnotation); cookieParameters.add( new FormFieldParameter(field, cookieParamAnnotation, MethodParameterType.Cookie)); continue; } final AnnotationDesc formParamAnnotation = Utils.findAnnotation(field, FormParam.class); if (formParamAnnotation != null) { formParameters.add( new FormFieldParameter(field, formParamAnnotation, MethodParameterType.Form)); continue; } // Recurse into the embedded @Form field if (formClass != null) { final AnnotationDesc formAnnotation = Utils.findAnnotation(field, formClass); if (formAnnotation != null) { walkFormParameter(field.type().asClassDoc()); continue; } } final AnnotationDesc contextAnnotation = Utils.findAnnotation(field, Context.class); if (contextAnnotation == null) { this.inputParameter = new FormFieldParameter(field, null, MethodParameterType.Input); continue; } } // and methods for (MethodDoc method : formDoc.methods(false)) { if (!method.returnType().qualifiedTypeName().equals("void") || method.parameters().length != 1 || !method.name().startsWith("set")) continue; Parameter parameter = method.parameters()[0]; final AnnotationDesc pathParamAnnotation = Utils.findParameterAnnotation(method, parameter, 0, PathParam.class); if (pathParamAnnotation != null) { String name = (String) Utils.getAnnotationValue(pathParamAnnotation); pathParameters.add( new FormMethodParameter(method, pathParamAnnotation, MethodParameterType.Path)); continue; } final AnnotationDesc matrixParamAnnotation = Utils.findParameterAnnotation(method, parameter, 0, MatrixParam.class); if (matrixParamAnnotation != null) { String name = (String) Utils.getAnnotationValue(matrixParamAnnotation); matrixParameters.add( new FormMethodParameter(method, matrixParamAnnotation, MethodParameterType.Matrix)); continue; } final AnnotationDesc queryParamAnnotation = Utils.findParameterAnnotation(method, parameter, 0, QueryParam.class); if (queryParamAnnotation != null) { String name = (String) Utils.getAnnotationValue(queryParamAnnotation); queryParameters.add( new FormMethodParameter(method, queryParamAnnotation, MethodParameterType.Query)); continue; } final AnnotationDesc headerParamAnnotation = Utils.findParameterAnnotation(method, parameter, 0, HeaderParam.class); if (headerParamAnnotation != null) { String name = (String) Utils.getAnnotationValue(headerParamAnnotation); headerParameters.add( new FormMethodParameter(method, headerParamAnnotation, MethodParameterType.Header)); continue; } final AnnotationDesc cookieParamAnnotation = Utils.findParameterAnnotation(method, parameter, 0, CookieParam.class); if (cookieParamAnnotation != null) { String name = (String) Utils.getAnnotationValue(cookieParamAnnotation); cookieParameters.add( new FormMethodParameter(method, cookieParamAnnotation, MethodParameterType.Cookie)); continue; } final AnnotationDesc formParamAnnotation = Utils.findParameterAnnotation(method, parameter, 0, FormParam.class); if (formParamAnnotation != null) { String name = (String) Utils.getAnnotationValue(formParamAnnotation); formParameters.add( new FormMethodParameter(method, formParamAnnotation, MethodParameterType.Form)); continue; } // I'm not sure if @Form can be used on setter methods on an @Form field, but just in case... if (formClass != null) { // recurse into @Form parameters final AnnotationDesc formAnnotation = Utils.findParameterAnnotation(method, parameter, 0, formClass); if (formAnnotation != null) { walkFormParameter(parameter.type().asClassDoc()); continue; } } final AnnotationDesc contextAnnotation = Utils.findParameterAnnotation(method, parameter, 0, Context.class); if (contextAnnotation == null) { this.inputParameter = new FormMethodParameter(method, null, MethodParameterType.Input); } } }
/** * Prints the class if needed. * * <p>A class is a rootClass if it's included among the classes returned by RootDoc.classes(), * this information is used to properly compute relative links in diagrams for UMLDoc */ public String printClass(ClassDoc c, boolean rootClass) { ClassInfo ci; boolean toPrint; Options opt = optionProvider.getOptionsFor(c); String className = c.toString(); if ((ci = getClassInfo(className)) != null) toPrint = !ci.nodePrinted; else { toPrint = true; ci = newClassInfo(className, true, hidden(c)); } if (toPrint && !hidden(c) && (!c.isEnum() || opt.showEnumerations)) { // Associate classname's alias String r = className; w.println("\t// " + r); // Create label w.print("\t" + ci.name + " [label="); boolean showMembers = (opt.showAttributes && c.fields().length > 0) || (c.isEnum() && opt.showEnumConstants && c.enumConstants().length > 0) || (opt.showOperations && c.methods().length > 0) || (opt.showConstructors && c.constructors().length > 0); externalTableStart(opt, c.qualifiedName(), classToUrl(c, rootClass)); // Calculate the number of innerTable rows we will emmit int nRows = 1; if (showMembers) { if (opt.showAttributes) nRows++; else if (!c.isEnum() && (opt.showConstructors || opt.showOperations)) nRows++; if (c.isEnum() && opt.showEnumConstants) nRows++; if (!c.isEnum() && (opt.showConstructors || opt.showOperations)) nRows++; } firstInnerTableStart(opt, nRows); if (c.isInterface()) tableLine(Align.CENTER, guilWrap(opt, "interface")); if (c.isEnum()) tableLine(Align.CENTER, guilWrap(opt, "enumeration")); stereotype(opt, c, Align.CENTER); Font font = c.isAbstract() && !c.isInterface() ? Font.CLASS_ABSTRACT : Font.CLASS; String qualifiedName = qualifiedName(opt, r); int startTemplate = qualifiedName.indexOf('<'); int idx = 0; if (startTemplate < 0) idx = qualifiedName.lastIndexOf('.'); else idx = qualifiedName.lastIndexOf('.', startTemplate); if (opt.showComment) tableLine(Align.LEFT, htmlNewline(escape(c.commentText())), opt, Font.CLASS); else if (opt.postfixPackage && idx > 0 && idx < (qualifiedName.length() - 1)) { String packageName = qualifiedName.substring(0, idx); String cn = className.substring(idx + 1); tableLine(Align.CENTER, escape(cn), opt, font); tableLine(Align.CENTER, packageName, opt, Font.PACKAGE); } else { tableLine(Align.CENTER, escape(qualifiedName), opt, font); } tagvalue(opt, c); firstInnerTableEnd(opt, nRows); /* * Warning: The boolean expressions guarding innerTableStart() * in this block, should match those in the code block above * marked: "Calculate the number of innerTable rows we will emmit" */ if (showMembers) { if (opt.showAttributes) { innerTableStart(); FieldDoc[] fields = c.fields(); // if there are no fields, print an empty line to generate proper HTML if (fields.length == 0) tableLine(Align.LEFT, ""); else attributes(opt, c.fields()); innerTableEnd(); } else if (!c.isEnum() && (opt.showConstructors || opt.showOperations)) { // show an emtpy box if we don't show attributes but // we show operations innerTableStart(); tableLine(Align.LEFT, ""); innerTableEnd(); } if (c.isEnum() && opt.showEnumConstants) { innerTableStart(); FieldDoc[] ecs = c.enumConstants(); // if there are no constants, print an empty line to generate proper HTML if (ecs.length == 0) { tableLine(Align.LEFT, ""); } else { for (FieldDoc fd : c.enumConstants()) { tableLine(Align.LEFT, fd.name()); } } innerTableEnd(); } if (!c.isEnum() && (opt.showConstructors || opt.showOperations)) { innerTableStart(); boolean printedLines = false; if (opt.showConstructors) printedLines |= operations(opt, c.constructors()); if (opt.showOperations) printedLines |= operations(opt, c.methods()); if (!printedLines) // if there are no operations nor constructors, // print an empty line to generate proper HTML tableLine(Align.LEFT, ""); innerTableEnd(); } } externalTableEnd(); w.print(", URL=\"" + classToUrl(c, rootClass) + "\""); nodeProperties(opt); // If needed, add a note for this node int ni = 0; for (Tag t : c.tags("note")) { String noteName = "n" + ni + "c" + ci.name; w.print("\t// Note annotation\n"); w.print("\t" + noteName + " [label="); externalTableStart( UmlGraph.getCommentOptions(), c.qualifiedName(), classToUrl(c, rootClass)); innerTableStart(); tableLine( Align.LEFT, htmlNewline(escape(t.text())), UmlGraph.getCommentOptions(), Font.CLASS); innerTableEnd(); externalTableEnd(); nodeProperties(UmlGraph.getCommentOptions()); w.print("\t" + noteName + " -> " + relationNode(c) + "[arrowhead=none];\n"); ni++; } ci.nodePrinted = true; } return ci.name; }