/** * 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; }
protected void generateDeclsForClass(PrintWriter pw, ClassDoc clazz, String cname) throws ClassNotFoundException { doneHandleTypes = new Hashtable(); /* The following handle types are predefined in "typedefs.h". Suppress inclusion in the output by generating them "into the blue" here. */ genHandleType(null, "java.lang.Class"); genHandleType(null, "java.lang.ClassLoader"); genHandleType(null, "java.lang.Object"); genHandleType(null, "java.lang.String"); genHandleType(null, "java.lang.Thread"); genHandleType(null, "java.lang.ThreadGroup"); genHandleType(null, "java.lang.Throwable"); pw.println("/* LLNI Header for class " + clazz.qualifiedName() + " */" + lineSep); pw.println("#ifndef _Included_" + cname); pw.println("#define _Included_" + cname); pw.println("#include \"typedefs.h\""); pw.println("#include \"llni.h\""); pw.println("#include \"jni.h\"" + lineSep); forwardDecls(pw, clazz); structSectionForClass(pw, clazz, cname); methodSectionForClass(pw, clazz, cname); pw.println("#endif"); }
/** * Constructor. * * @param filename the file to be generated. * @throws IOException * @throws DocletAbortException */ public PackageUseWriter( ConfigurationImpl configuration, ClassUseMapper mapper, DocPath filename, PackageDoc pkgdoc) throws IOException { super(configuration, DocPath.forPackage(pkgdoc).resolve(filename)); this.pkgdoc = pkgdoc; // by examining all classes in this package, find what packages // use these classes - produce a map between using package and // used classes. ClassDoc[] content = pkgdoc.allClasses(); for (int i = 0; i < content.length; ++i) { ClassDoc usedClass = content[i]; Set<ClassDoc> usingClasses = mapper.classToClass.get(usedClass.qualifiedName()); if (usingClasses != null) { for (Iterator<ClassDoc> it = usingClasses.iterator(); it.hasNext(); ) { ClassDoc usingClass = it.next(); PackageDoc usingPackage = usingClass.containingPackage(); Set<ClassDoc> usedClasses = usingPackageToUsedClasses.get(usingPackage.name()); if (usedClasses == null) { usedClasses = new TreeSet<ClassDoc>(); usingPackageToUsedClasses.put(Util.getPackageName(usingPackage), usedClasses); } usedClasses.add(usedClass); } } } }
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); }
FieldDefsRes(ClassDoc clazz, FieldDefsRes parent, boolean bottomMost) { this.className = clazz.qualifiedName(); this.parent = parent; this.bottomMost = bottomMost; int byteSize = 0; if (parent == null) this.s = ""; else this.s = parent.s; }
/** * 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; }
/** * 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; }
protected void forwardDecls(PrintWriter pw, ClassDoc clazz) throws ClassNotFoundException { ClassDoc clazzfield = null; if (clazz.qualifiedName().equals("java.lang.Object")) return; genHandleType(pw, clazz.qualifiedName()); ClassDoc superClass = clazz.superclass(); if (superClass != null) { String superClassName = superClass.qualifiedName(); forwardDecls(pw, superClass); } for (int i = 0; i < fields.length; i++) { FieldDoc field = (FieldDoc) fields[i]; if (!field.isStatic()) { Type t = field.type(); String tname = t.qualifiedTypeName(); TypeSignature newTypeSig = new TypeSignature(root); String sig = newTypeSig.getTypeSignature(tname); if (sig.charAt(0) != '[') forwardDeclsFromSig(pw, sig); } } for (int i = 0; i < methods.length; i++) { MethodDoc method = (MethodDoc) methods[i]; if (method.isNative()) { Type retType = method.returnType(); String typesig = method.signature(); TypeSignature newTypeSig = new TypeSignature(root); String sig = newTypeSig.getTypeSignature(typesig, retType); if (sig.charAt(0) != '[') forwardDeclsFromSig(pw, sig); } } }
/** Generate the class use list. */ protected void generateClassUseFile() throws IOException { Content body = getClassUseHeader(); HtmlTree div = new HtmlTree(HtmlTag.DIV); div.addStyle(HtmlStyle.classUseContainer); if (pkgSet.size() > 0) { addClassUse(div); } else { div.addContent(getResource("doclet.ClassUse_No.usage.of.0", classdoc.qualifiedName())); } body.addContent(div); addNavLinks(false, body); addBottom(body); printHtmlDocument(null, true, body); }
/** * 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); }
/** * Given an array of <code>Tag</code>s representing this custom tag, return its string * representation. * * @param throwTags the array of <code>ThrowsTag</code>s to convert. * @param writer the TagletWriter that will write this tag. * @param alreadyDocumented the set of exceptions that have already been documented. * @param allowDups True if we allow duplicate throws tags to be documented. * @return the TagletOutput representation of this <code>Tag</code>. */ protected TagletOutput throwsTagsOutput( ThrowsTag[] throwTags, TagletWriter writer, Set<String> alreadyDocumented, boolean allowDups) { TagletOutput result = writer.getOutputInstance(); if (throwTags.length > 0) { for (int i = 0; i < throwTags.length; ++i) { ThrowsTag tt = throwTags[i]; ClassDoc cd = tt.exception(); if ((!allowDups) && (alreadyDocumented.contains(tt.exceptionName()) || (cd != null && alreadyDocumented.contains(cd.qualifiedName())))) { continue; } if (alreadyDocumented.size() == 0) { result.appendOutput(writer.getThrowsHeader()); } result.appendOutput(writer.throwsTagOutput(tt)); alreadyDocumented.add(cd != null ? cd.qualifiedName() : tt.exceptionName()); } } return result; }
/** * Given a class, return the closest visible super class. * * @param classDoc the class we are searching the parent for. * @param configuration the current configuration of the doclet. * @return the closest visible super class. Return null if it cannot be found (i.e. classDoc is * java.lang.Object). */ public static Type getFirstVisibleSuperClass(ClassDoc classDoc, Configuration configuration) { if (classDoc == null) { return null; } Type sup = classDoc.superclassType(); ClassDoc supClassDoc = classDoc.superclass(); while (sup != null && (!(supClassDoc.isPublic() || isLinkable(supClassDoc, configuration)))) { if (supClassDoc.superclass().qualifiedName().equals(supClassDoc.qualifiedName())) break; sup = supClassDoc.superclassType(); supClassDoc = supClassDoc.superclass(); } if (classDoc.equals(supClassDoc)) { return null; } return sup; }
public ThrowsTagImpl(String text, ClassDocImpl contextClass, MemberDocImpl contextMember) { super(text); char[] textarr = text.toCharArray(); int i = 0; for (; i < textarr.length; ++i) { if (!Parser.isWhitespace(textarr[i])) break; } for (; i < textarr.length; ++i) { if (Parser.isWhitespace(textarr[i])) { this.exceptionName = new String(textarr, 0, i).trim(); this.exceptionComment = new String(textarr, i, textarr.length - i).trim(); break; } } if (null != exceptionName) { if (contextClass == null) { this.exception = Main.getRootDoc().classNamed(exceptionName); } else { this.exception = contextClass.findClass(exceptionName); } if (exception != null) this.exceptionName = exception.qualifiedName(); else { if (text.trim().startsWith("<")) { Main.getRootDoc() .printWarning( "Expected exception name but got '" + text + "' in class " + contextClass.getClassName()); } } } else { Main.getRootDoc() .printWarning( "@throws tag in comment for " + contextClass.qualifiedName() + "." + contextMember.name() + " doesn't specify an exception."); } if (this.exceptionComment != null) { setBody(this.exceptionComment, contextClass, contextMember); } }
/** * Get the header for the class use Listing. * * @return a content tree representing the class use header */ protected Content getClassUseHeader() { String cltype = configuration.getText(classdoc.isInterface() ? "doclet.Interface" : "doclet.Class"); String clname = classdoc.qualifiedName(); String title = configuration.getText("doclet.Window_ClassUse_Header", cltype, clname); Content bodyTree = getBody(true, getWindowTitle(title)); addTop(bodyTree); addNavLinks(true, bodyTree); ContentBuilder headContent = new ContentBuilder(); headContent.addContent(getResource("doclet.ClassUse_Title", cltype)); headContent.addContent(new HtmlTree(HtmlTag.BR)); headContent.addContent(clname); Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true, HtmlStyle.title, headContent); Content div = HtmlTree.DIV(HtmlStyle.header, heading); bodyTree.addContent(div); return bodyTree; }
private Map<String, List<ProgramElementDoc>> pkgDivide( Map<String, ? extends List<? extends ProgramElementDoc>> classMap) { Map<String, List<ProgramElementDoc>> map = new HashMap<>(); List<? extends ProgramElementDoc> list = classMap.get(classdoc.qualifiedName()); if (list != null) { Collections.sort(list); for (ProgramElementDoc doc : list) { PackageDoc pkg = doc.containingPackage(); pkgSet.add(pkg); List<ProgramElementDoc> inPkg = map.get(pkg.name()); if (inPkg == null) { inPkg = new ArrayList<>(); map.put(pkg.name(), inPkg); } inPkg.add(doc); } } return map; }
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; }
protected void structSectionForClass(PrintWriter pw, ClassDoc jclazz, String cname) throws ClassNotFoundException { String jname = jclazz.qualifiedName(); if (cname.equals("java_lang_Object")) { pw.println("/* struct java_lang_Object is defined in typedefs.h. */"); pw.println(); return; } pw.println("#if !defined(__i386)"); pw.println("#pragma pack(4)"); pw.println("#endif"); pw.println(); pw.println("struct " + cname + " {"); pw.println(" ObjHeader h;"); pw.print(fieldDefs(jclazz, cname)); if (jname.equals("java.lang.Class")) pw.println(" Class *LLNI_mask(cClass);" + " /* Fake field; don't access (see oobj.h) */"); pw.println("};" + lineSep + lineSep + "#pragma pack()"); pw.println(); return; }
/** * The entry point into the Parser class. * * @param root A RootDoc intstance obtained via the doclet API * @return A XML (XStream) serializable element, containing everything parsed from javadoc doclet */ public static Root ParseRoot(RootDoc root) { processingStorage = new HashMap<PackageDoc, ParserMediary>(); try { md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { log.error("unable to acquire MD5 algorithm", e); return null; } rootXml = new Root(); ClassDoc[] allClasses = root.classes(); for (ClassDoc classDoc : allClasses) { PackageDoc doc = classDoc.containingPackage(); ParserMediary mediary = null; // the age old 'if I have it pull out existing, if I don't make a new one' if (processingStorage.containsKey(doc)) { mediary = processingStorage.get(doc); } else { mediary = new ParserMediary( doc.name(), doc.commentText(), ParseAnnotationInstances(doc.annotations(), doc.name())); processingStorage.put(doc, mediary); } if (classDoc.isIncluded()) { // dev comment--why do enums show up as ordinary class? if (classDoc.isOrdinaryClass() || classDoc.isException() || classDoc.isError()) { mediary.addClass(ParseClass(classDoc)); } else if (classDoc.isEnum()) { mediary.addEnum(ParseEnum(classDoc)); } else if (isAnnotation(classDoc)) { mediary.addAnnotation(ParseAnnotation(classDoc)); } else if (classDoc.isInterface()) { mediary.addInterface(ParseInterface(classDoc)); } } else { log.debug("Skipping not-included class " + classDoc.qualifiedName()); } } if (processingStorage.size() > 0) { List list = new ArrayList<Package>(); for (ParserMediary mediary : processingStorage.values()) { list.add(mediary.wrapup()); } rootXml.packages = (Package[]) list.toArray(new Package[] {}); } else { log.warn("No packages found!"); } return rootXml; }
/** * Constructor. * * @param filename the file to be generated. * @throws IOException * @throws DocletAbortException */ public ClassUseWriter( ConfigurationImpl configuration, ClassUseMapper mapper, DocPath filename, ClassDoc classdoc) throws IOException { super(configuration, filename); this.classdoc = classdoc; if (mapper.classToPackageAnnotations.containsKey(classdoc.qualifiedName())) pkgToPackageAnnotations = new TreeSet<>(mapper.classToPackageAnnotations.get(classdoc.qualifiedName())); configuration.currentcd = classdoc; this.pkgSet = new TreeSet<>(); this.pkgToClassTypeParameter = pkgDivide(mapper.classToClassTypeParam); this.pkgToClassAnnotations = pkgDivide(mapper.classToClassAnnotations); this.pkgToMethodTypeParameter = pkgDivide(mapper.classToExecMemberDocTypeParam); this.pkgToMethodArgTypeParameter = pkgDivide(mapper.classToExecMemberDocArgTypeParam); this.pkgToFieldTypeParameter = pkgDivide(mapper.classToFieldDocTypeParam); this.pkgToFieldAnnotations = pkgDivide(mapper.annotationToFieldDoc); this.pkgToMethodReturnTypeParameter = pkgDivide(mapper.classToExecMemberDocReturnTypeParam); this.pkgToMethodAnnotations = pkgDivide(mapper.classToExecMemberDocAnnotations); this.pkgToMethodParameterAnnotations = pkgDivide(mapper.classToExecMemberDocParamAnnotation); this.pkgToSubclass = pkgDivide(mapper.classToSubclass); this.pkgToSubinterface = pkgDivide(mapper.classToSubinterface); this.pkgToImplementingClass = pkgDivide(mapper.classToImplementingClass); this.pkgToField = pkgDivide(mapper.classToField); this.pkgToMethodReturn = pkgDivide(mapper.classToMethodReturn); this.pkgToMethodArgs = pkgDivide(mapper.classToMethodArgs); this.pkgToMethodThrows = pkgDivide(mapper.classToMethodThrows); this.pkgToConstructorAnnotations = pkgDivide(mapper.classToConstructorAnnotations); this.pkgToConstructorParameterAnnotations = pkgDivide(mapper.classToConstructorParamAnnotation); this.pkgToConstructorArgs = pkgDivide(mapper.classToConstructorArgs); this.pkgToConstructorArgTypeParameter = pkgDivide(mapper.classToConstructorDocArgTypeParam); this.pkgToConstructorThrows = pkgDivide(mapper.classToConstructorThrows); // tmp test if (pkgSet.size() > 0 && mapper.classToPackage.containsKey(classdoc.qualifiedName()) && !pkgSet.equals(mapper.classToPackage.get(classdoc.qualifiedName()))) { configuration.root.printWarning( "Internal error: package sets don't match: " + pkgSet + " with: " + mapper.classToPackage.get(classdoc.qualifiedName())); } methodSubWriter = new MethodWriterImpl(this); constrSubWriter = new ConstructorWriterImpl(this); fieldSubWriter = new FieldWriterImpl(this); classSubWriter = new NestedClassWriterImpl(this); classUseTableSummary = configuration.getText("doclet.Use_Table_Summary", configuration.getText("doclet.classes")); subclassUseTableSummary = configuration.getText( "doclet.Use_Table_Summary", configuration.getText("doclet.subclasses")); subinterfaceUseTableSummary = configuration.getText( "doclet.Use_Table_Summary", configuration.getText("doclet.subinterfaces")); fieldUseTableSummary = configuration.getText("doclet.Use_Table_Summary", configuration.getText("doclet.fields")); methodUseTableSummary = configuration.getText("doclet.Use_Table_Summary", configuration.getText("doclet.methods")); constructorUseTableSummary = configuration.getText( "doclet.Use_Table_Summary", configuration.getText("doclet.constructors")); }
/** * 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; }