/** * Parses an annotation type definition * * @param docClass * @return */ protected static Annotation ParseAnnotation(ClassDoc docClass) { AnnotationTypeDoc docAnnotation = (AnnotationTypeDoc) docClass; assert (docAnnotation != null); Annotation xmlAnnotation = new Annotation(); xmlAnnotation.name = docClass.name(); xmlAnnotation.qualifiedName = docClass.qualifiedName(); xmlAnnotation.comment = docClass.commentText(); xmlAnnotation.isIncluded = docClass.isIncluded(); xmlAnnotation.scope = DetermineScope(docClass); AnnotationTypeElementDoc[] elements = docAnnotation.elements(); if (elements != null && elements.length > 0) { ArrayList<AnnotationElement> elementList = new ArrayList<AnnotationElement>(); for (AnnotationTypeElementDoc element : elements) { elementList.add(ParseAnnotationElement(element)); } xmlAnnotation.elements = elementList.toArray(new AnnotationElement[] {}); } else { log.debug("No elements in annotation: " + docClass.name()); } xmlAnnotation.annotationInstances = ParseAnnotationInstances(docClass.annotations(), docClass.qualifiedName()); return xmlAnnotation; }
/** * Return the qualified name of the <code>ClassDoc</code> if it's qualifier is not excluded. * Otherwise, return the unqualified <code>ClassDoc</code> name. * * @param cd the <code>ClassDoc</code> to check. */ public String getClassName(ClassDoc cd) { PackageDoc pd = cd.containingPackage(); if (pd != null && shouldExcludeQualifier(cd.containingPackage().name())) { return cd.name(); } else { return cd.qualifiedName(); } }
/** * Add a row for the class that uses the given package. * * @param usedClass the class that uses the given package * @param packageName the name of the package to which the class belongs * @param contentTree the content tree to which the row will be added */ protected void addClassRow(ClassDoc usedClass, String packageName, Content contentTree) { DocPath dp = pathString(usedClass, DocPaths.CLASS_USE.resolve(DocPath.forName(usedClass))); Content td = HtmlTree.TD( HtmlStyle.colOne, getHyperLink(dp.fragment(packageName), new StringContent(usedClass.name()))); addIndexComment(usedClass, td); contentTree.addContent(td); }
/** * Add use information to the documentation tree. * * @param mems list of program elements for which the use information will be added * @param heading the section heading * @param tableSummary the summary for the use table * @param contentTree the content tree to which the use information will be added */ protected void addUseInfo( List<? extends ProgramElementDoc> mems, Content heading, String tableSummary, Content contentTree) { if (mems == null) { return; } List<? extends ProgramElementDoc> members = mems; boolean printedUseTableHeader = false; if (members.size() > 0) { Content caption = writer.getTableCaption(heading); Content table = (configuration.isOutputHtml5()) ? HtmlTree.TABLE(HtmlStyle.useSummary, caption) : HtmlTree.TABLE(HtmlStyle.useSummary, tableSummary, caption); Content tbody = new HtmlTree(HtmlTag.TBODY); Iterator<? extends ProgramElementDoc> it = members.iterator(); for (int i = 0; it.hasNext(); i++) { ProgramElementDoc pgmdoc = it.next(); ClassDoc cd = pgmdoc.containingClass(); if (!printedUseTableHeader) { table.addContent(writer.getSummaryTableHeader(this.getSummaryTableHeader(pgmdoc), "col")); printedUseTableHeader = true; } HtmlTree tr = new HtmlTree(HtmlTag.TR); if (i % 2 == 0) { tr.addStyle(HtmlStyle.altColor); } else { tr.addStyle(HtmlStyle.rowColor); } HtmlTree tdFirst = new HtmlTree(HtmlTag.TD); tdFirst.addStyle(HtmlStyle.colFirst); writer.addSummaryType(this, pgmdoc, tdFirst); tr.addContent(tdFirst); HtmlTree tdLast = new HtmlTree(HtmlTag.TD); tdLast.addStyle(HtmlStyle.colLast); if (cd != null && !(pgmdoc instanceof ConstructorDoc) && !(pgmdoc instanceof ClassDoc)) { HtmlTree name = new HtmlTree(HtmlTag.SPAN); name.addStyle(HtmlStyle.typeNameLabel); name.addContent(cd.name() + "."); tdLast.addContent(name); } addSummaryLink( pgmdoc instanceof ClassDoc ? LinkInfoImpl.Kind.CLASS_USE : LinkInfoImpl.Kind.MEMBER, cd, pgmdoc, tdLast); writer.addSummaryLinkComment(this, pgmdoc, tdLast); tr.addContent(tdLast); tbody.addContent(tr); } table.addContent(tbody); contentTree.addContent(table); } }
/** * Parses an interface type definition * * @param docClass * @return */ protected static Interface ParseInterface(ClassDoc docClass) { assert (docClass != null); Interface xmlInterface = new Interface(); xmlInterface.name = docClass.name(); xmlInterface.qualifiedName = docClass.qualifiedName(); xmlInterface.comment = docClass.commentText(); xmlInterface.isIncluded = docClass.isIncluded(); xmlInterface.scope = DetermineScope(docClass); xmlInterface.typeVariables = ParseTypeVariables(docClass.typeParameters(), docClass.typeParamTags()); Type[] interfaces = docClass.interfaceTypes(); ArrayList<String> interfaceTypeNames = new ArrayList<String>(); if (interfaces != null && interfaces.length > 0) { for (Type interfaceType : interfaces) { interfaceTypeNames.add(interfaceType.qualifiedTypeName()); } xmlInterface.interfaces = interfaceTypeNames.toArray(new String[] {}); } MethodDoc[] methods = docClass.methods(); if (methods != null && methods.length > 0) { ArrayList<Method> methodList = new ArrayList<Method>(); for (MethodDoc method : methods) { methodList.add(ParseMethod(method)); } xmlInterface.methods = methodList.toArray(new Method[] {}); } else { log.debug("No methods in interface: " + docClass.name()); } xmlInterface.annotationInstances = ParseAnnotationInstances(docClass.annotations(), docClass.qualifiedName()); return xmlInterface; }
/** The documentation for values() and valueOf() in Enums are set by the doclet. */ public static void setEnumDocumentation(Configuration configuration, ClassDoc classDoc) { MethodDoc[] methods = classDoc.methods(); for (int j = 0; j < methods.length; j++) { MethodDoc currentMethod = methods[j]; if (currentMethod.name().equals("values") && currentMethod.parameters().length == 0) { currentMethod.setRawCommentText( configuration.getText("doclet.enum_values_doc", classDoc.name())); } else if (currentMethod.name().equals("valueOf") && currentMethod.parameters().length == 1) { Type paramType = currentMethod.parameters()[0].type(); if (paramType != null && paramType.qualifiedTypeName().equals(String.class.getName())) { currentMethod.setRawCommentText(configuration.getText("doclet.enum_valueof_doc")); } } } }
/** Convert the class name into a corresponding URL */ public String classToUrl(ClassDoc cd, boolean rootClass) { // building relative path for context and package diagrams if (contextDoc != null && rootClass) { // determine the context path, relative to the root String packageName = null; if (contextDoc instanceof ClassDoc) { packageName = ((ClassDoc) contextDoc).containingPackage().name(); } else if (contextDoc instanceof PackageDoc) { packageName = ((PackageDoc) contextDoc).name(); } else { return classToUrl(cd.qualifiedName()); } return buildRelativePath(packageName, cd.containingPackage().name()) + cd.name() + ".html"; } else { return classToUrl(cd.qualifiedName()); } }
/** * Handles the {@literal <ClassDoc>} tag. * * @param node the XML element that specifies which components to document * @param contentTree the content tree to which the documentation will be added */ public void buildClassDoc(XMLNode node, Content contentTree) throws Exception { String key; if (isInterface) { key = "doclet.Interface"; } else if (isEnum) { key = "doclet.Enum"; } else { key = "doclet.Class"; } contentTree = writer.getHeader(configuration.getText(key) + " " + classDoc.name()); Content classContentTree = writer.getClassContentHeader(); buildChildren(node, classContentTree); contentTree.addContent(classContentTree); writer.addFooter(contentTree); writer.printDocument(contentTree); writer.close(); copyDocFiles(); }
/** * Parses the enum type definition * * @param docClass * @return */ protected static Enum ParseEnum(ClassDoc docClass) { assert (docClass != null); Enum xmlEnum = new Enum(); xmlEnum.name = docClass.name(); xmlEnum.qualifiedName = docClass.qualifiedName(); xmlEnum.comment = docClass.commentText(); xmlEnum.isIncluded = docClass.isIncluded(); xmlEnum.scope = DetermineScope(docClass); Type superClassType = docClass.superclassType(); if (superClassType != null) { xmlEnum.superClass = superClassType.qualifiedTypeName(); } Type[] interfaces = docClass.interfaceTypes(); ArrayList<String> interfaceTypeNames = new ArrayList<String>(); if (interfaces != null && interfaces.length > 0) { for (Type interfaceType : interfaces) { interfaceTypeNames.add(interfaceType.qualifiedTypeName()); } } xmlEnum.extendedFrom = interfaceTypeNames.toArray(new String[] {}); FieldDoc[] fields = docClass.enumConstants(); if (fields != null && fields.length > 0) { ArrayList<EnumField> fieldList = new ArrayList<EnumField>(); for (FieldDoc field : fields) { fieldList.add(ParseEnumField(field)); } xmlEnum.fields = fieldList.toArray(new EnumField[] {}); } xmlEnum.annotationInstances = ParseAnnotationInstances(docClass.annotations(), docClass.qualifiedName()); return xmlEnum; }
/** * Process the methods in the class. * * @param md An array of MethodDoc objects */ public void processMethods(ClassDoc cd, MethodDoc[] md) { if (trace) System.out.println("PROCESSING " + cd.name() + " METHODS, number = " + md.length); for (int i = 0; i < md.length; i++) { String methodName = md[i].name(); if (trace) System.out.println("PROCESSING METHOD: " + methodName); // Skip <init> and <clinit> if (methodName.startsWith("<")) continue; // Only save the shown elements if (!shownElement(md[i], memberVisibilityLevel)) continue; outputFile.print(" <method name=\"" + methodName + "\""); com.sun.javadoc.Type retType = md[i].returnType(); if (retType.qualifiedTypeName().compareTo("void") == 0) { // Don't add a return attribute if the return type is void outputFile.println(); } else { outputFile.print(" return=\""); emitType(retType); outputFile.println("\""); } outputFile.print(" abstract=\"" + md[i].isAbstract() + "\""); outputFile.print(" native=\"" + md[i].isNative() + "\""); outputFile.println(" synchronized=\"" + md[i].isSynchronized() + "\""); addCommonModifiers(md[i], 6); outputFile.println(">"); // Generate the parameter elements, if any Parameter[] params = md[i].parameters(); for (int j = 0; j < params.length; j++) { outputFile.print(" <param name=\"" + params[j].name() + "\""); outputFile.print(" type=\""); emitType(params[j].type()); outputFile.println("\"/>"); } // Generate the exception elements if any exceptions are thrown processExceptions(md[i].thrownExceptions()); addDocumentation(md[i], 6); outputFile.println(" </method>"); } // for } // processMethods()
/** * Translate from a a controller class to a Controller model. * * @param classDoc * @return */ public static ControllerModel translateToModel(ClassDoc classDoc) { ControllerModel model = new ControllerModel(); // Setup the basic data model.setName(classDoc.name()); model.setClassDescription(classDoc.getRawCommentText()); model.setFullClassName(classDoc.qualifiedName()); // Map the annotations of the class Map<String, Object> annotationMap = mapAnnotation(classDoc.annotations()); // Get the display name and path if they exist model.setDisplayName((String) annotationMap.get(CONTROLLER_INFO_DISPLAY_NAME)); model.setPath((String) annotationMap.get(CONTROLLER_INFO_PATH)); Iterator<MethodDoc> methodIt = FilterUtils.requestMappingIterator(classDoc.methods()); List<MethodModel> methods = new LinkedList<MethodModel>(); model.setMethods(methods); while (methodIt.hasNext()) { MethodDoc methodDoc = methodIt.next(); MethodModel methodModel = translateMethod(methodDoc); methods.add(methodModel); } return model; }
/** * Generate a class page. * * @param prev the previous class to generated, or null if no previous. * @param classdoc the class to generate. * @param next the next class to be generated, or null if no next. */ public static void generate( ConfigurationStandard configurationStandard, ClassDoc classdoc, ClassDoc prev, ClassDoc next, ClassTree classtree, boolean nopackage) { RcsClassWriter clsgen; String path = DirectoryManager.getDirectoryPath(classdoc.containingPackage()); String filename = classdoc.name() + ".html"; try { clsgen = new RcsClassWriter( configurationStandard, path, filename, classdoc, prev, next, classtree, nopackage); clsgen.generateClassFile(); clsgen.close(); } catch (IOException exc) { configurationStandard.standardmessage.error( "doclet.exception_encountered", exc.toString(), filename); throw new DocletAbortException(); } }
public String getAPIFunctionName() { return declaringClass.name() + "." + declaringMethod.name(); }
public static String urlToClass(ClassDoc from, ClassDoc to) { return classToRoot(from) + classToPath(to) + "/" + to.name() + ".html"; }
public boolean run() { try { // setup additional classes needed for processing, generally these are java ones such as // java.lang.String // adding them here allows them to be used in @outputType Collection<ClassDoc> typeClasses = new ArrayList<ClassDoc>(); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.lang.String.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.lang.Integer.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.lang.Boolean.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.lang.Float.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.lang.Double.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.lang.Character.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.lang.Long.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.lang.Byte.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.util.Date.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.util.Calendar.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.util.Map.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.util.Collection.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.util.Set.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.util.List.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.math.BigInteger.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.math.BigDecimal.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.util.UUID.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.DayOfWeek.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.Duration.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.Instant.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.LocalDate.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.LocalDateTime.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.Month.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.MonthDay.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.OffsetDateTime.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.OffsetTime.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.Period.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.Year.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.YearMonth.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.ZoneId.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.ZoneOffset.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.time.ZonedDateTime.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.net.URI.class.getName())); addIfNotNull(typeClasses, this.rootDoc.classNamed(java.net.URL.class.getName())); // filter the classes to process Collection<ClassDoc> docletClasses = new ArrayList<ClassDoc>(); for (ClassDoc classDoc : this.rootDoc.classes()) { // see if excluded via its FQN boolean excludeResource = false; if (this.options.getExcludeResourcePrefixes() != null && !this.options.getExcludeResourcePrefixes().isEmpty()) { for (String prefix : this.options.getExcludeResourcePrefixes()) { String className = classDoc.qualifiedName(); if (className.startsWith(prefix)) { excludeResource = true; break; } } } // see if the inclusion filter is set and if so this resource must match this if (!excludeResource && this.options.getIncludeResourcePrefixes() != null && !this.options.getIncludeResourcePrefixes().isEmpty()) { boolean matched = false; for (String prefix : this.options.getIncludeResourcePrefixes()) { String className = classDoc.qualifiedName(); if (className.startsWith(prefix)) { matched = true; break; } } excludeResource = !matched; } if (excludeResource) { continue; } // see if deprecated if (this.options.isExcludeDeprecatedResourceClasses() && ParserHelper.isDeprecated(classDoc, this.options)) { continue; } // see if excluded via a tag if (ParserHelper.hasTag(classDoc, this.options.getExcludeClassTags())) { continue; } docletClasses.add(classDoc); } ClassDocCache classCache = new ClassDocCache(docletClasses); List<ApiDeclaration> declarations = null; // build up set of subresources // do simple parsing to find sub resource classes // these are ones referenced in the return types of methods // which have a path but no http method Map<Type, ClassDoc> subResourceClasses = new HashMap<Type, ClassDoc>(); for (ClassDoc classDoc : docletClasses) { ClassDoc currentClassDoc = classDoc; while (currentClassDoc != null) { for (MethodDoc method : currentClassDoc.methods()) { // if the method has @Path but no Http method then its an entry point to a sub resource if (!ParserHelper.resolveMethodPath(method, this.options).isEmpty() && HttpMethod.fromMethod(method) == null) { ClassDoc subResourceClassDoc = classCache.findByType(method.returnType()); if (subResourceClassDoc != null) { if (this.options.isLogDebug()) { System.out.println( "Adding return type as sub resource class : " + subResourceClassDoc.name() + " for method " + method.name() + " of referencing class " + currentClassDoc.name()); } subResourceClasses.put(method.returnType(), subResourceClassDoc); } } } currentClassDoc = currentClassDoc.superclass(); // ignore parent object class if (!ParserHelper.hasAncestor(currentClassDoc)) { break; } } } // parse with the v2 parser that supports endpoints of the same resource being spread across // resource files Map<String, ApiDeclaration> resourceToDeclaration = new HashMap<String, ApiDeclaration>(); for (ClassDoc classDoc : docletClasses) { CrossClassApiParser classParser = new CrossClassApiParser( this.options, classDoc, docletClasses, subResourceClasses, typeClasses, SWAGGER_VERSION, this.options.getApiVersion(), this.options.getApiBasePath()); classParser.parse(resourceToDeclaration); } Collection<ApiDeclaration> declarationColl = resourceToDeclaration.values(); if (this.options.isLogDebug()) { System.out.println("After parse phase api declarations are: "); for (ApiDeclaration apiDec : declarationColl) { System.out.println( "Api Dec: base path " + apiDec.getBasePath() + ", res path: " + apiDec.getResourcePath()); for (Api api : apiDec.getApis()) { System.out.println("Api path:" + api.getPath()); for (Operation op : api.getOperations()) { System.out.println("Api nick name:" + op.getNickname() + " method " + op.getMethod()); } } } } // add any extra declarations if (this.options.getExtraApiDeclarations() != null && !this.options.getExtraApiDeclarations().isEmpty()) { declarationColl = new ArrayList<ApiDeclaration>(declarationColl); declarationColl.addAll(this.options.getExtraApiDeclarations()); } // set root path on any empty resources for (ApiDeclaration api : declarationColl) { if (api.getResourcePath() == null || api.getResourcePath().isEmpty() || api.getResourcePath().equals("/")) { api.setResourcePath(this.options.getResourceRootPath()); } } // merge the api declarations declarationColl = new ApiDeclarationMerger( SWAGGER_VERSION, this.options.getApiVersion(), this.options.getApiBasePath()) .merge(declarationColl); // clear any empty models for (ApiDeclaration api : declarationColl) { if (api.getModels() != null && api.getModels().isEmpty()) { api.setModels(null); } } declarations = new ArrayList<ApiDeclaration>(declarationColl); // sort the api declarations if needed if (this.options.isSortResourcesByPriority()) { Collections.sort( declarations, new Comparator<ApiDeclaration>() { public int compare(ApiDeclaration dec1, ApiDeclaration dec2) { return Integer.compare(dec1.getPriority(), dec2.getPriority()); } }); } else if (this.options.isSortResourcesByPath()) { Collections.sort( declarations, new Comparator<ApiDeclaration>() { public int compare(ApiDeclaration dec1, ApiDeclaration dec2) { if (dec1 == null || dec1.getResourcePath() == null) { return 1; } if (dec2 == null || dec2.getResourcePath() == null) { return -1; } return dec1.getResourcePath().compareTo(dec2.getResourcePath()); } }); } // sort apis of each declaration if (this.options.isSortApisByPath()) { for (ApiDeclaration dec : declarations) { if (dec.getApis() != null) { Collections.sort( dec.getApis(), new Comparator<Api>() { public int compare(Api o1, Api o2) { if (o1 == null || o1.getPath() == null) { return -1; } return o1.getPath().compareTo(o2.getPath()); } }); } } } writeApis(declarations); // Copy swagger-ui into the output directory. if (this.options.isIncludeSwaggerUi()) { copyUi(); } return true; } catch (IOException e) { System.err.println("Failed to write api docs, err msg: " + e.getMessage()); e.printStackTrace(); return false; } }
/** * 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; }
/** Print a class's relations */ public void printRelations(ClassDoc c) { Options opt = optionProvider.getOptionsFor(c); if (hidden(c) || c.name() .equals("")) // avoid phantom classes, they may pop up when the source uses annotations return; String className = c.toString(); // Print generalization (through the Java superclass) Type s = c.superclassType(); if (s != null && !s.toString().equals("java.lang.Object") && !c.isEnum() && !hidden(s.asClassDoc())) { ClassDoc sc = s.asClassDoc(); w.println( "\t//" + c + " extends " + s + "\n" + "\t" + relationNode(sc) + " -> " + relationNode(c) + " [dir=back,arrowtail=empty];"); getClassInfo(className) .addRelation(sc.toString(), RelationType.EXTENDS, RelationDirection.OUT); getClassInfo(sc.toString()) .addRelation(className, RelationType.EXTENDS, RelationDirection.IN); } // Print generalizations (through @extends tags) for (Tag tag : c.tags("extends")) if (!hidden(tag.text())) { ClassDoc from = c.findClass(tag.text()); w.println( "\t//" + c + " extends " + tag.text() + "\n" + "\t" + relationNode(from, tag.text()) + " -> " + relationNode(c) + " [dir=back,arrowtail=empty];"); getClassInfo(className) .addRelation(tag.text(), RelationType.EXTENDS, RelationDirection.OUT); getClassInfo(tag.text()).addRelation(className, RelationType.EXTENDS, RelationDirection.IN); } // Print realizations (Java interfaces) for (Type iface : c.interfaceTypes()) { ClassDoc ic = iface.asClassDoc(); if (!hidden(ic)) { w.println( "\t//" + c + " implements " + ic + "\n\t" + relationNode(ic) + " -> " + relationNode(c) + " [dir=back,arrowtail=empty,style=dashed];"); getClassInfo(className) .addRelation(ic.toString(), RelationType.IMPLEMENTS, RelationDirection.OUT); getClassInfo(ic.toString()) .addRelation(className, RelationType.IMPLEMENTS, RelationDirection.IN); } } // Print other associations allRelation(opt, RelationType.ASSOC, c); allRelation(opt, RelationType.NAVASSOC, c); allRelation(opt, RelationType.HAS, c); allRelation(opt, RelationType.NAVHAS, c); allRelation(opt, RelationType.COMPOSED, c); allRelation(opt, RelationType.NAVCOMPOSED, c); allRelation(opt, RelationType.DEPEND, c); }
/** Return the ClassDoc for the specified class; null if not found. */ private static ClassDoc findClass(RootDoc root, String name) { ClassDoc[] classes = root.classes(); for (ClassDoc cd : classes) if (cd.name().equals(name)) return cd; return null; }