/** * Given a string, return an array of tokens. The separator can be escaped with the '\' character. * The '\' character may also be escaped by the '\' character. * * @param s the string to tokenize. * @param separator the separator char. * @param maxTokens the maxmimum number of tokens returned. If the max is reached, the remaining * part of s is appended to the end of the last token. * @return an array of tokens. */ public static String[] tokenize(String s, char separator, int maxTokens) { List tokens = new ArrayList(); StringBuilder token = new StringBuilder(); boolean prevIsEscapeChar = false; for (int i = 0; i < s.length(); i += Character.charCount(i)) { int currentChar = s.codePointAt(i); if (prevIsEscapeChar) { // Case 1: escaped character token.appendCodePoint(currentChar); prevIsEscapeChar = false; } else if (currentChar == separator && tokens.size() < maxTokens - 1) { // Case 2: separator tokens.add(token.toString()); token = new StringBuilder(); } else if (currentChar == '\\') { // Case 3: escape character prevIsEscapeChar = true; } else { // Case 4: regular character token.appendCodePoint(currentChar); } } if (token.length() > 0) { tokens.add(token.toString()); } return (String[]) tokens.toArray(new String[] {}); }
/** Return the list of ProgramElementDoc objects as Array. */ public static ProgramElementDoc[] toProgramElementDocArray(List list) { ProgramElementDoc[] pgmarr = new ProgramElementDoc[list.size()]; for (int i = 0; i < list.size(); i++) { pgmarr[i] = (ProgramElementDoc) (list.get(i)); } return pgmarr; }
public static List asList(ProgramElementDoc[] members) { List list = new ArrayList(); for (int i = 0; i < members.length; i++) { list.add(members[i]); } return list; }
/** * Add deprecated information to the documentation tree * * @param deprmembers list of deprecated members * @param headingKey the caption for the deprecated members table * @param tableSummary the summary for the deprecated members table * @param tableHeader table headers for the deprecated members table * @param contentTree the content tree to which the deprecated members table will be added */ protected void addDeprecatedAPI( List<Doc> deprmembers, String headingKey, String tableSummary, String[] tableHeader, Content contentTree) { if (deprmembers.size() > 0) { Content caption = writer.getTableCaption(configuration.getResource(headingKey)); Content table = (configuration.isOutputHtml5()) ? HtmlTree.TABLE(HtmlStyle.deprecatedSummary, caption) : HtmlTree.TABLE(HtmlStyle.deprecatedSummary, tableSummary, caption); table.addContent(writer.getSummaryTableHeader(tableHeader, "col")); Content tbody = new HtmlTree(HtmlTag.TBODY); for (int i = 0; i < deprmembers.size(); i++) { ProgramElementDoc member = (ProgramElementDoc) deprmembers.get(i); HtmlTree td = HtmlTree.TD(HtmlStyle.colOne, getDeprecatedLink(member)); if (member.tags("deprecated").length > 0) writer.addInlineDeprecatedComment(member, member.tags("deprecated")[0], td); HtmlTree tr = HtmlTree.TR(td); if (i % 2 == 0) tr.addStyle(HtmlStyle.altColor); else tr.addStyle(HtmlStyle.rowColor); tbody.addContent(tr); } table.addContent(tbody); Content li = HtmlTree.LI(HtmlStyle.blockList, table); Content ul = HtmlTree.UL(HtmlStyle.blockList, li); contentTree.addContent(ul); } }
private static void addAllInterfaceTypes( Map<ClassDoc, Type> results, Type type, Type[] interfaceTypes, boolean raw, Configuration configuration) { for (int i = 0; i < interfaceTypes.length; i++) { Type interfaceType = interfaceTypes[i]; ClassDoc interfaceClassDoc = interfaceType.asClassDoc(); if (!(interfaceClassDoc.isPublic() || (configuration != null && isLinkable(interfaceClassDoc, configuration)))) { continue; } if (raw) interfaceType = interfaceType.asClassDoc(); results.put(interfaceClassDoc, interfaceType); List<Type> superInterfaces = getAllInterfaces(interfaceType, configuration); for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) { Type superInterface = iter.next(); results.put(superInterface.asClassDoc(), superInterface); } } if (type instanceof ParameterizedType) findAllInterfaceTypes(results, (ParameterizedType) type, configuration); else if (((ClassDoc) type).typeParameters().length == 0) findAllInterfaceTypes(results, (ClassDoc) type, raw, configuration); else findAllInterfaceTypes(results, (ClassDoc) type, true, configuration); }
/** * 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); } }
/** * Return array of class members whose documentation is to be generated. If the member is * deprecated do not include such a member in the returned array. * * @param members Array of members to choose from. * @return List List of eligible members for whom documentation is getting generated. */ public static List excludeDeprecatedMembersAsList(ProgramElementDoc[] members) { List list = new ArrayList(); for (int i = 0; i < members.length; i++) { if (members[i].tags("deprecated").length == 0) { list.add(members[i]); } } Collections.sort(list); return list; }
/** * Adjust the Class Tree. Add the class interface in to it's super-class' or super-interface's * sub-interface list. * * @param map the entire map. * @param superclass java.lang.Object or the super-interface. * @param cd sub-interface to be mapped. * @returns boolean true if class added, false if class already processed. */ private boolean add(Map map, ClassDoc superclass, ClassDoc cd) { List list = (List) map.get(superclass); if (list == null) { list = new ArrayList(); map.put(superclass, list); } if (list.contains(cd)) { return false; } else { list.add(cd); } return true; }
/** * Build the field documentation. * * @param elements the XML elements that specify how to construct this documentation. */ public void buildFieldDoc(List<?> elements) { if (writer == null) { return; } for (currentFieldIndex = 0; currentFieldIndex < fields.size(); currentFieldIndex++) { build(elements); } }
/** * Add the navigation summary link. * * @param members members to be linked * @param visibleMemberMap the visible inherited members map * @param liNav the content tree to which the navigation summary link will be added */ protected void addNavSummaryLink( List<?> members, VisibleMemberMap visibleMemberMap, Content liNav) { if (members.size() > 0) { liNav.addContent(getNavSummaryLink(null, true)); return; } ClassDoc icd = classdoc.superclass(); while (icd != null) { List<?> inhmembers = visibleMemberMap.getMembersFor(icd); if (inhmembers.size() > 0) { liNav.addContent(getNavSummaryLink(icd, true)); return; } icd = icd.superclass(); } liNav.addContent(getNavSummaryLink(null, false)); }
/** * For the class return all implemented interfaces including the superinterfaces of the * implementing interfaces, also iterate over for all the superclasses. For interface return all * the extended interfaces as well as superinterfaces for those extended interfaces. * * @param type type whose implemented or super interfaces are sought. * @param configuration the current configuration of the doclet. * @param sort if true, return list of interfaces sorted alphabetically. * @return List of all the required interfaces. */ public static List<Type> getAllInterfaces(Type type, Configuration configuration, boolean sort) { Map<ClassDoc, Type> results = sort ? new TreeMap<ClassDoc, Type>() : new LinkedHashMap<ClassDoc, Type>(); Type[] interfaceTypes = null; Type superType = null; if (type instanceof ParameterizedType) { interfaceTypes = ((ParameterizedType) type).interfaceTypes(); superType = ((ParameterizedType) type).superclassType(); } else if (type instanceof ClassDoc) { interfaceTypes = ((ClassDoc) type).interfaceTypes(); superType = ((ClassDoc) type).superclassType(); } else { interfaceTypes = type.asClassDoc().interfaceTypes(); superType = type.asClassDoc().superclassType(); } for (int i = 0; i < interfaceTypes.length; i++) { Type interfaceType = interfaceTypes[i]; ClassDoc interfaceClassDoc = interfaceType.asClassDoc(); if (!(interfaceClassDoc.isPublic() || (configuration == null || isLinkable(interfaceClassDoc, configuration)))) { continue; } results.put(interfaceClassDoc, interfaceType); List<Type> superInterfaces = getAllInterfaces(interfaceType, configuration, sort); for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) { Type t = iter.next(); results.put(t.asClassDoc(), t); } } if (superType == null) return new ArrayList<Type>(results.values()); // Try walking the tree. addAllInterfaceTypes( results, superType, superType instanceof ClassDoc ? ((ClassDoc) superType).interfaceTypes() : ((ParameterizedType) superType).interfaceTypes(), false, configuration); List<Type> resultsList = new ArrayList<Type>(results.values()); if (sort) { Collections.sort(resultsList, new TypeComparator()); } return resultsList; }
/** * Build the field documentation. * * @param node the XML element that specifies which components to document * @param memberDetailsTree the content tree to which the documentation will be added */ public void buildFieldDoc(XMLNode node, Content memberDetailsTree) { if (writer == null) { return; } int size = fields.size(); if (size > 0) { Content fieldDetailsTree = writer.getFieldDetailsTreeHeader(classDoc, memberDetailsTree); for (currentFieldIndex = 0; currentFieldIndex < size; currentFieldIndex++) { Content fieldDocTree = writer.getFieldDocTreeHeader( (FieldDoc) fields.get(currentFieldIndex), fieldDetailsTree); buildChildren(node, fieldDocTree); fieldDetailsTree.addContent( writer.getFieldDoc(fieldDocTree, (currentFieldIndex == size - 1))); } memberDetailsTree.addContent(writer.getFieldDetails(fieldDetailsTree)); } }
/** * Build the method documentation. * * @param node the XML element that specifies which components to document * @param memberDetailsTree the content tree to which the documentation will be added */ public void buildMethodDoc(XMLNode node, Content memberDetailsTree) { if (writer == null) { return; } int size = methods.size(); if (size > 0) { Content methodDetailsTree = writer.getMethodDetailsTreeHeader(classDoc, memberDetailsTree); for (currentMethodIndex = 0; currentMethodIndex < size; currentMethodIndex++) { Content methodDocTree = writer.getMethodDocTreeHeader( (MethodDoc) methods.get(currentMethodIndex), methodDetailsTree); buildChildren(node, methodDocTree); methodDetailsTree.addContent( writer.getMethodDoc(methodDocTree, (currentMethodIndex == size - 1))); } memberDetailsTree.addContent(writer.getMethodDetails(methodDetailsTree)); } }
/** * For the interface passed get the interfaces which it extends, and then put this interface in * the sub-interface list of those interfaces. Do it recursively. If a interface doesn't have * super-interface just attach that interface in the list of all the baseinterfaces. * * @param cd Interface under consideration. */ private void processInterface(ClassDoc cd) { ClassDoc[] intfacs = cd.interfaces(); if (intfacs.length > 0) { for (int i = 0; i < intfacs.length; i++) { if (!add(subinterfaces, intfacs[i], cd)) { return; } else { processInterface(intfacs[i]); // Recurse } } } else { // we need to add all the interfaces who do not have // super-interfaces to baseinterfaces list to traverse them if (!baseinterfaces.contains(cd)) { baseinterfaces.add(cd); } } }
/** * For the class passed map it to it's own sub-class listing. For the Class passed, get the super * class, if superclass is non null, (it is not "java.lang.Object") get the "value" from the * hashmap for this key Class if entry not found create one and get that. add this Class as a sub * class in the list Recurse till hits java.lang.Object Null SuperClass. * * @param cd class for which sub-class mapping to be generated. * @param configuration the current configurtation of the doclet. */ private void processType(ClassDoc cd, Configuration configuration, List bases, Map subs) { ClassDoc superclass = Util.getFirstVisibleSuperClassCD(cd, configuration); if (superclass != null) { if (!add(subs, superclass, cd)) { return; } else { processType(superclass, configuration, bases, subs); } } else { // cd is java.lang.Object, add it once to the list if (!bases.contains(cd)) { bases.add(cd); } } List intfacs = Util.getAllInterfaces(cd, configuration); for (Iterator iter = intfacs.iterator(); iter.hasNext(); ) { add(implementingclasses, ((Type) iter.next()).asClassDoc(), cd); } }
/** * Build the enum constant documentation. * * @param elements the XML elements that specify how to construct this documentation. */ public void buildEnumConstant(List<?> elements) { if (writer == null) { return; } for (currentEnumConstantsIndex = 0; currentEnumConstantsIndex < enumConstants.size(); currentEnumConstantsIndex++) { build(elements); } }
/** * Return the list of classes which implement the interface passed. * * @param cd interface whose implementing-classes list is required. */ public List implementingclasses(ClassDoc cd) { List result = get(implementingclasses, cd); List subinterfaces = allSubs(cd, false); // If class x implements a subinterface of cd, then it follows // that class x implements cd. Iterator implementingClassesIter, subInterfacesIter = subinterfaces.listIterator(); ClassDoc c; while (subInterfacesIter.hasNext()) { implementingClassesIter = implementingclasses((ClassDoc) subInterfacesIter.next()).listIterator(); while (implementingClassesIter.hasNext()) { c = (ClassDoc) implementingClassesIter.next(); if (!result.contains(c)) { result.add(c); } } } Collections.sort(result); return result; }
/** * Return a list of all direct or indirect, sub-classes and subinterfaces of the ClassDoc * argument. * * @param cd ClassDoc whose sub-classes or sub-interfaces are requested. * @param isEnum true if the subclasses should be forced to come from the enum tree. */ public List allSubs(ClassDoc cd, boolean isEnum) { List list = subs(cd, isEnum); for (int i = 0; i < list.size(); i++) { cd = (ClassDoc) list.get(i); List tlist = subs(cd, isEnum); for (int j = 0; j < tlist.size(); j++) { ClassDoc tcd = (ClassDoc) tlist.get(j); if (!list.contains(tcd)) { list.add(tcd); } } } Collections.sort(list); return list; }
/** * Build the comments for the method. Do nothing if {@link Configuration#nocomment} is set to * true. * * @param node the XML element that specifies which components to document * @param methodDocTree the content tree to which the documentation will be added */ public void buildMethodComments(XMLNode node, Content methodDocTree) { if (!configuration.nocomment) { MethodDoc method = (MethodDoc) methods.get(currentMethodIndex); if (method.inlineTags().length == 0) { DocFinder.Output docs = DocFinder.search(configuration, new DocFinder.Input(method)); method = docs.inlineTags != null && docs.inlineTags.length > 0 ? (MethodDoc) docs.holder : method; } // NOTE: When we fix the bug where ClassDoc.interfaceTypes() does // not pass all implemented interfaces, holder will be the // interface type. For now, it is really the erasure. writer.addComments(method.containingClass(), method, methodDocTree); } }
/** * Add the member summary for the given class. * * @param classDoc the class that is being documented * @param member the member being documented * @param firstSentenceTags the first sentence tags to be added to the summary * @param tableContents the list of contents to which the documentation will be added * @param counter the counter for determining id and style for the table row */ public void addMemberSummary( ClassDoc classDoc, ProgramElementDoc member, Tag[] firstSentenceTags, List<Content> tableContents, int counter) { HtmlTree tdSummaryType = new HtmlTree(HtmlTag.TD); tdSummaryType.addStyle(HtmlStyle.colFirst); writer.addSummaryType(this, member, tdSummaryType); HtmlTree tdSummary = new HtmlTree(HtmlTag.TD); setSummaryColumnStyle(tdSummary); addSummaryLink(classDoc, member, tdSummary); writer.addSummaryLinkComment(this, member, firstSentenceTags, tdSummary); HtmlTree tr = HtmlTree.TR(tdSummaryType); tr.addContent(tdSummary); if (member instanceof MethodDoc && !member.isAnnotationTypeElement()) { int methodType = (member.isStatic()) ? MethodTypes.STATIC.value() : MethodTypes.INSTANCE.value(); if (member.containingClass().isInterface()) { methodType = (((MethodDoc) member).isAbstract()) ? methodType | MethodTypes.ABSTRACT.value() : methodType | MethodTypes.DEFAULT.value(); } else { methodType = (((MethodDoc) member).isAbstract()) ? methodType | MethodTypes.ABSTRACT.value() : methodType | MethodTypes.CONCRETE.value(); } if (utils.isDeprecated(member) || utils.isDeprecated(classdoc)) { methodType = methodType | MethodTypes.DEPRECATED.value(); } methodTypesOr = methodTypesOr | methodType; String tableId = "i" + counter; typeMap.put(tableId, methodType); tr.addAttr(HtmlAttr.ID, tableId); } if (counter % 2 == 0) tr.addStyle(HtmlStyle.altColor); else tr.addStyle(HtmlStyle.rowColor); tableContents.add(tr); }
/** * Build the deprecation information. * * @param node the XML element that specifies which components to document * @param methodDocTree the content tree to which the documentation will be added */ public void buildDeprecationInfo(XMLNode node, Content methodDocTree) { writer.addDeprecated((MethodDoc) methods.get(currentMethodIndex), methodDocTree); }
/** * Build the signature. * * @param node the XML element that specifies which components to document * @param methodDocTree the content tree to which the documentation will be added */ public void buildSignature(XMLNode node, Content methodDocTree) { methodDocTree.addContent(writer.getSignature((MethodDoc) methods.get(currentMethodIndex))); }
/** {@inheritDoc} */ public boolean hasMembersToDocument() { return methods.size() > 0; }
/** summaryOrder.size() */ public boolean hasMembersToDocument() { return enumConstants.size() > 0; }
/** Build the tag information. */ public void buildTagInfo() { writer.writeTags((FieldDoc) enumConstants.get(currentEnumConstantsIndex)); }
/** * Build the comments for the enum constant. Do nothing if {@link Configuration#nocomment} is set * to true. */ public void buildEnumConstantComments() { if (!configuration.nocomment) { writer.writeComments((FieldDoc) enumConstants.get(currentEnumConstantsIndex)); } }
/** Build the deprecation information. */ public void buildDeprecationInfo() { writer.writeDeprecated((FieldDoc) enumConstants.get(currentEnumConstantsIndex)); }
/** Build the signature. */ public void buildSignature() { writer.writeSignature((FieldDoc) enumConstants.get(currentEnumConstantsIndex)); }
/** * Build the tag information. * * @param node the XML element that specifies which components to document * @param methodDocTree the content tree to which the documentation will be added */ public void buildTagInfo(XMLNode node, Content methodDocTree) { writer.addTags((MethodDoc) methods.get(currentMethodIndex), methodDocTree); }
/** Build the header for the individual enum constants. */ public void buildEnumConstantHeader() { writer.writeEnumConstantHeader( (FieldDoc) enumConstants.get(currentEnumConstantsIndex), currentEnumConstantsIndex == 0); }