/**
   * 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;
  }
Example #6
0
 /** 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());
   }
 }
Example #8
0
 /**
  * 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;
  }
Example #10
0
  /**
   * 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;
 }
Example #12
0
 /**
  * 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();
   }
 }
Example #13
0
 public String getAPIFunctionName() {
   return declaringClass.name() + "." + declaringMethod.name();
 }
Example #14
0
 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);
  }
Example #18
0
 /** 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;
 }