/**
   * Parses an enum type definition
   *
   * @param docField
   * @return
   */
  protected static EnumField ParseEnumField(FieldDoc docField) {
    assert (docField != null);

    EnumField xmlEnumField = new EnumField();

    xmlEnumField.name = docField.name();
    xmlEnumField.comment = docField.commentText();

    return xmlEnumField;
  }
 /**
  * Build the field sub header.
  *
  * @param node the XML element that specifies which components to document
  * @param fieldsContentTree content tree to which the documentation will be added
  */
 public void buildFieldSubHeader(XMLNode node, Content fieldsContentTree) {
   if (!currentClass.definesSerializableFields()) {
     FieldDoc field = (FieldDoc) currentMember;
     fieldWriter.addMemberHeader(
         field.type().asClassDoc(),
         field.type().typeName(),
         field.type().dimension(),
         field.name(),
         fieldsContentTree);
   }
 }
 /**
  * Build the serial field tags information.
  *
  * @param serializableFieldsTree content tree to which the documentation will be added
  */
 public void buildSerialFieldTagsInfo(Content serializableFieldsTree) {
   if (configuration.nocomment) {
     return;
   }
   FieldDoc field = (FieldDoc) currentMember;
   // Process Serializable Fields specified as array of
   // ObjectStreamFields. Print a member for each serialField tag.
   // (There should be one serialField tag per ObjectStreamField
   // element.)
   SerialFieldTag[] tags = field.serialFieldTags();
   Arrays.sort(tags);
   int tagsLength = tags.length;
   for (int i = 0; i < tagsLength; i++) {
     if (tags[i].fieldName() == null
         || tags[i].fieldType() == null) // ignore malformed @serialField tags
     continue;
     Content fieldsContentTree = fieldWriter.getFieldsContentHeader((i == tagsLength - 1));
     fieldWriter.addMemberHeader(
         tags[i].fieldTypeDoc(), tags[i].fieldType(), "", tags[i].fieldName(), fieldsContentTree);
     fieldWriter.addMemberDescription(tags[i], fieldsContentTree);
     serializableFieldsTree.addContent(fieldsContentTree);
   }
 }
 /**
  * Build the field information.
  *
  * @param node the XML element that specifies which components to document
  * @param fieldsContentTree content tree to which the documentation will be added
  */
 public void buildFieldInfo(XMLNode node, Content fieldsContentTree) {
   if (configuration.nocomment) {
     return;
   }
   FieldDoc field = (FieldDoc) currentMember;
   ClassDoc cd = field.containingClass();
   // Process default Serializable field.
   if ((field.tags("serial").length == 0) && !field.isSynthetic() && configuration.serialwarn) {
     configuration.message.warning(
         field.position(), "doclet.MissingSerialTag", cd.qualifiedName(), field.name());
   }
   fieldWriter.addMemberDescription(field, fieldsContentTree);
   fieldWriter.addMemberTags(field, fieldsContentTree);
 }
  /**
   * Parses a field type definition
   *
   * @param docField
   * @return
   */
  protected static Field ParseField(FieldDoc docField) {
    assert (docField != null);

    Field xmlField = new Field();

    xmlField.name = docField.name();
    xmlField.comment = docField.commentText();
    xmlField.type = ParseType(docField.type());
    xmlField.isFinal = docField.isFinal();
    if (xmlField.isFinal) {
      xmlField.finalExpression = docField.constantValueExpression();
    } else if (docField.constantValueExpression() != null) {
      // how would a non-final field have a constant value expression?
      // my understanding is that this field is only != null when is not final
      assert (false);
    }
    xmlField.isStatic = docField.isStatic();
    xmlField.isVolatile = docField.isVolatile();
    xmlField.isTransient = docField.isTransient();
    xmlField.scope = DetermineScope(docField);

    // parse annotations from the field
    xmlField.annotationInstances =
        ParseAnnotationInstances(docField.annotations(), docField.qualifiedName());

    return xmlField;
  }
  /**
   * Parses annotation instances from the javadoc annotation instance type
   *
   * @param annotationDocs Annotations decorated on some type
   * @return Serializable representation of annotations
   */
  protected static AnnotationInstance[] ParseAnnotationInstances(
      AnnotationDesc[] annotationDocs, String origin) {
    AnnotationInstance[] annotations = null;

    if (annotationDocs != null && annotationDocs.length > 0) {
      ArrayList<AnnotationInstance> list = new ArrayList<AnnotationInstance>();

      for (AnnotationDesc annot : annotationDocs) {
        AnnotationInstance instance = new AnnotationInstance();

        AnnotationTypeDoc annotTypeInfo = null;
        try {
          annotTypeInfo = annot.annotationType();
          instance.name = annot.annotationType().name();
          instance.qualifiedName = annot.annotationType().qualifiedTypeName();

        } catch (ClassCastException castException) {
          log.error("Unable to obtain type data about an annotation found on: " + origin);
          log.error("Add to the -cp parameter the class/jar that defines this annotation.");
          instance.name = null;
          instance.qualifiedName = null;
        }

        AnnotationDesc.ElementValuePair[] arguments = annot.elementValues();
        if (arguments != null && arguments.length > 0) {
          ArrayList<AnnotationArgument> argumentList = new ArrayList<AnnotationArgument>();

          for (AnnotationDesc.ElementValuePair pair : arguments) {
            AnnotationArgument annotationArgument = new AnnotationArgument();
            annotationArgument.name = pair.element().name();

            Type annotationArgumentType = pair.element().returnType();
            annotationArgument.type = annotationArgumentType.qualifiedTypeName();
            annotationArgument.isPrimitive = annotationArgumentType.isPrimitive();
            annotationArgument.isArray = annotationArgumentType.dimension().length() > 0;

            Object objValue = pair.value().value();
            if (objValue instanceof AnnotationValue[]) {
              AnnotationValue[] realValues = (AnnotationValue[]) objValue;
              String[] values = new String[realValues.length];

              for (int i = 0; i < realValues.length; i++) {
                values[i] = realValues[i].value().toString();
              }
              annotationArgument.value = values;
            } else if (objValue instanceof Number) {
              Number number = (Number) objValue;
              annotationArgument.value = new String[] {number.toString()};
            } else if (objValue instanceof Character) {
              Character character = (Character) objValue;
              annotationArgument.value = new String[] {character.toString()};
            } else if (objValue instanceof Boolean) {
              Boolean booleanValue = (Boolean) objValue;
              annotationArgument.value = new String[] {booleanValue.toString()};
            } else if (objValue instanceof String) {
              String stringValue = (String) objValue;
              annotationArgument.value = new String[] {stringValue};
            } else if (objValue instanceof FieldDoc) {
              FieldDoc field = (FieldDoc) objValue;
              annotationArgument.value = new String[] {field.name()};
            } else if (objValue instanceof ClassDoc) {
              ClassDoc classDoc = (ClassDoc) objValue;
              annotationArgument.value = new String[] {classDoc.qualifiedTypeName()};
            }
            argumentList.add(annotationArgument);
          }

          instance.arguments = argumentList.toArray(new AnnotationArgument[] {});
        }

        list.add(instance);
      }

      annotations = list.toArray(new AnnotationInstance[] {});
    }

    return annotations;
  }