diff --git a/.gitignore b/.gitignore index ea8c4bf..35d0a6c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,9 @@ -/target +/* +!.gitignore +!.src/ +!.travis.yml +!.classpath +!pom.xml +!README.md +!LICENSE +/src/META-INF/* diff --git a/README.md b/README.md index 232a0e3..6576f32 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,16 @@ ### This project and repository are no longer maintained by Salesforce.org +This version is maintained by Mike Lockett :-) ApexDoc ======= -ApexDoc is a java app that you can use to document your Salesforce Apex classes. You tell ApexDoc where your class files are, and it will generate a set of static HTML pages that fully document each class, including its properties and methods. Each static HTML page will include an expandable menu on its left hand side, that shows a 2-level tree structure of all of your classes. Command line parameters allow you to control many aspects of ApexDoc, such as providing your own banner HTML for the pages to use. +ApexDoc is a java app that you can use to document your Salesforce Apex classes. You tell ApexDoc where your class files are, and it will generate a set of static HTML pages that fully document each class, including its properties and methods. Each static HTML page will include an expandable menu on its left hand side, that shows a 2-level tree structure of all of your classes. Command line parameters allow you to control many aspects of ApexDoc, such as providing your own banner HTML for the pages to use. +## New in this branch +Classes and/or methods can be marked as *deprecated*; you can also provide a description of what to use instead. +Methods can use the *exception*; add as many lines as needed to indicate exceptions a method might throw. ## Credits -ApexDoc was originally created by Aslam Bari (http://techsahre.blogspot.com/2011/01/apexdoc-salesforce-code-documentation.html). It was then taken and extended by David Habib, at Groundwire, in 2011. It has subsequently been enhanced by David Habib of the Salesforce Foundation in late 2014 for use with Nonprofit Success Pack (https://github.com/SalesforceFoundation/Cumulus). We are unable to offer direct support of reported issues or incorporate enhancement requests at this time, however pull requests are welcome. +ApexDoc was originally created by Aslam Bari (http://techsahre.blogspot.com/2011/01/apexdoc-salesforce-code-documentation.html). It was then taken and extended by David Habib, at Groundwire, in 2011. It has subsequently been enhanced by David Habib of the Salesforce Foundation in late 2014 for use with Nonprofit Success Pack (https://github.com/SalesforceFoundation/Cumulus). We are unable to offer direct support of reported issues or incorporate enhancement requests at this time, however pull requests are welcome. ## Command Line Parameters | parameter | description | @@ -16,10 +20,10 @@ ApexDoc was originally created by Aslam Bari (http://techsahre.blogspot.com/2011 | -g *source_url* | A URL where the source is hosted (so ApexDoc can provide links to your source). Optional.| | -h *home_page* | The full path to an html file that contains the contents for the home page's content area. Optional.| | -a *banner_page* | The full path to an html file that contains the content for the banner section of each generated page. Optional.| -| -p *scope* | A semicolon separated list of scopes to document. Defaults to 'global;public;webService'. Optional.| +| -p *scope* | A semicolon separated list of scopes to document. Defaults to 'global;public;webService'. Optional.| ## Usage -Copy apexdoc.jar file to your local machine, somewhere on your path. Each release tag in gitHub has the matching apexdoc.jar attached to it. Make sure that java is on your path. Invoke ApexDoc like this example: +Copy apexdoc.jar file to your local machine, somewhere on your path. Each release tag in gitHub has the matching apexdoc.jar attached to it. Make sure that java is on your path. Invoke ApexDoc like this example: ``` java -jar apexdoc.jar -s '/Users/dhabib/Workspaces/Force.com IDE/Cumulus3/src/classes' @@ -31,9 +35,9 @@ java -jar apexdoc.jar ``` ## Documenting Class Files -ApexDoc scans each class file, and looks for comment blocks with special keywords to identify the documentation to include for a given class, property, or method. The comment blocks must always begin with /** (or additional *'s) and can cover multiple lines. Each line must start with * (or whitespace and then *). The comment block ends with */. Special tokens are called out with @token. +ApexDoc scans each class file, and looks for comment blocks with special keywords to identify the documentation to include for a given class, property, or method. The comment blocks must always begin with /** (or additional *'s) and can cover multiple lines. Each line must start with * (or whitespace and then *). The comment block ends with */. Special tokens are called out with @token. ### Class Comments -Located in the lines above the class declaration. The special tokens are all optional. +Located in the lines above the class declaration. The special tokens are all optional. | token | description | |-------|-------------| @@ -42,6 +46,7 @@ Located in the lines above the class declaration. The special tokens are all op | @group | a group to display this class under, in the menu hierarchy| | @group-content | a relative path to a static html file that provides content about the group| | @description | one or more lines that provide an overview of the class| +| @deprecated | indicates class should no longer be used; message should indicate replacement | Example ``` @@ -60,7 +65,7 @@ public with sharing class ACCT_Accounts_TDTM extends TDTM_Runnable { ``` ### Property Comments -Located in the lines above a property. The special tokens are all optional. +Located in the lines above a property. The special tokens are all optional. | token | description | |-------|-------------| @@ -84,6 +89,8 @@ In order for ApexDoc to identify class methods, the method line must contain an | @description | one or more lines that provide an overview of the method| | @param *param name* | a description of what the parameter does| | @return | a description of the return value from the method| +| @deprecated | indicates method should no longer be used; message should indicate replacement | +| @exception | a description of an Exception that might be thrown | | @example | Example code usage. This will be wrapped in tags to preserve whitespace| Example ``` @@ -97,3 +104,18 @@ Example */ public static Schema.DescribeFieldResult getFieldDescribe(String objectName, String fieldName) { ``` + +*** +## Javadocs things that might be nice in ApexDocs +| Tag | Usage | Applies to... | Added | +|-----|-------|---------------|-------| +| @see _reference_ |Provides a link to other element of documentation.|Class, Interface, Enum, Field, Method| +| @throws _classname description_ | Describes an exception that may be thrown from this method. | Method| +| @deprecated _description_ | Describes an outdated method. | Class, Interface, Enum, Field, Method | 2019-01-05 +| {@inheritDoc} | Copies the description from the overridden method. | Overriding Method | +| {@link reference} |Link to other symbol. | Class, Interface, Enum, Field, Method | +| {@linkplain reference} | Identical to {@link}, except the link's label is displayed in plain text than code font. | Class, Interface, Enum, Field, Method | +| {@value #STATIC_FIELD} | Return the value of a static field. | Static Field | +| {@code literal} | Formats literal text in the code font. It is equivalent to {@literal}. | Class, Interface, Enum, Field, Method | +| {@literal literal} | Denotes literal text. The enclosed text is interpreted as not containing HTML markup or nested javadoc tags. | Class, Interface, Enum, Field, Method| +| {@serial literal} | Used in the doc comment for a default serializable field. | Field | diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..81f1021 --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: org.salesforce.apexdoc.ApexDoc + diff --git a/src/org/salesforce/apexdoc/ApexDoc.css b/src/org/salesforce/apexdoc/ApexDoc.css index f0c7429..0b7a61a 100644 --- a/src/org/salesforce/apexdoc/ApexDoc.css +++ b/src/org/salesforce/apexdoc/ApexDoc.css @@ -297,4 +297,10 @@ div.navbar ul li a.scopeprivate { } +/* placed at end so it overwrites other settings */ +.warning { + color: #660000; + font-weight: bold; +} + /* END - SIDEBAR STYLES */ diff --git a/src/org/salesforce/apexdoc/ApexDoc.java b/src/org/salesforce/apexdoc/ApexDoc.java index 8da4f97..6dca9f8 100644 --- a/src/org/salesforce/apexdoc/ApexDoc.java +++ b/src/org/salesforce/apexdoc/ApexDoc.java @@ -146,7 +146,7 @@ private static void printHelp() { } private static TreeMap createMapGroupNameToClassGroup(ArrayList cModels, - String sourceDirectory) { + String sourceDirectory) { TreeMap map = new TreeMap(); for (ClassModel cmodel : cModels) { String strGroup = cmodel.getClassGroup(); @@ -215,12 +215,12 @@ public static ClassModel parseFileContents(String filePath) { commentsStarted = true; boolean commentEnded = false; if(strLine.startsWith("/**")){ - if (strLine.endsWith("*/")) { + if (strLine.endsWith("*/")) { strLine = strLine.replace("*/", ""); commentEnded = true; - } - lstComments.add(strLine); - docBlockStarted = true; + } + lstComments.add(strLine); + docBlockStarted = true; } if (strLine.endsWith("*/") || commentEnded) { commentsStarted = false; @@ -232,17 +232,17 @@ public static ClassModel parseFileContents(String filePath) { if (commentsStarted && strLine.endsWith("*/")) { strLine = strLine.replace("*/", ""); if(docBlockStarted){ - lstComments.add(strLine); - docBlockStarted = false; + lstComments.add(strLine); + docBlockStarted = false; } commentsStarted = false; continue; } if (commentsStarted) { - if(docBlockStarted){ - lstComments.add(strLine); - } + if(docBlockStarted){ + lstComments.add(strLine); + } continue; } @@ -356,23 +356,23 @@ public static String strContainsScope(String str) { } private static void fillPropertyModel(PropertyModel propertyModel, String name, ArrayList lstComments, - int iLine) { + int iLine) { propertyModel.setNameLine(name, iLine); boolean inDescription = false; int i = 0; for (String comment : lstComments) { - i++; + i++; comment = comment.trim(); int idxStart = comment.toLowerCase().indexOf("@description"); if (idxStart != -1 || i == 1) { - if (idxStart != -1 && comment.length() > idxStart + 13) - propertyModel.setDescription(comment.substring(idxStart + 13).trim()); - else{ - Pattern p = Pattern.compile("\\s"); - Matcher m = p.matcher(comment); - if (m.find()) { - propertyModel.setDescription(comment.substring(m.start()).trim()); - } + if (idxStart != -1 && comment.length() > idxStart + 13) + propertyModel.setDescription(comment.substring(idxStart + 13).trim()); + else{ + Pattern p = Pattern.compile("\\s"); + Matcher m = p.matcher(comment); + if (m.find()) { + propertyModel.setDescription(comment.substring(m.start()).trim()); + } } inDescription = true; continue; @@ -400,7 +400,7 @@ private static void fillMethodModel(MethodModel mModel, String name, ArrayList= idxStart + 12) mModel.setDescription(comment.substring(idxStart + 12).trim()); else{ - Pattern p = Pattern.compile("\\s"); - Matcher m = p.matcher(comment); - if (m.find()) { - mModel.setDescription(comment.substring(m.start()).trim()); - } + Pattern p = Pattern.compile("\\s"); + Matcher m = p.matcher(comment); + if (m.find()) { + mModel.setDescription(comment.substring(m.start()).trim()); + } } inDescription = true; inExample = false; @@ -456,12 +472,12 @@ private static void fillMethodModel(MethodModel mModel, String name, ArrayList= idxStart + 8) { mModel.setExample(comment.substring(idxStart + 8).trim()); } else { - Pattern p = Pattern.compile("\\s"); - Matcher m = p.matcher(comment.substring(8)); + Pattern p = Pattern.compile("\\s"); + Matcher m = p.matcher(comment.substring(8)); - if (m.find()) { - mModel.setExample(comment.substring(m.start()).trim()); - } + if (m.find()) { + mModel.setExample(comment.substring(m.start()).trim()); + } } inDescription = false; inExample = true; @@ -486,8 +502,8 @@ private static void fillMethodModel(MethodModel mModel, String name, ArrayList lstComments, int iLine) { + ArrayList lstComments, int iLine) { cModel.setNameLine(name, iLine); if (name.toLowerCase().contains(" interface ")) cModel.setIsInterface(true); boolean inDescription = false; int i = 0; for (String comment : lstComments) { - i++; + i++; comment = comment.trim(); int idxStart = comment.toLowerCase().indexOf("@author"); @@ -520,6 +536,13 @@ private static void fillClassModel(ClassModel cModelParent, ClassModel cModel, S continue; } + idxStart = comment.toLowerCase().indexOf("@deprecated"); + if (idxStart != -1) { + cModel.setDeprecated(comment.substring(idxStart + 11).trim()); + inDescription = false; + continue; + } + idxStart = comment.toLowerCase().indexOf("@group "); // needed to include space to not match group-content. if (idxStart != -1) { cModel.setClassGroup(comment.substring(idxStart + 6).trim()); @@ -536,14 +559,14 @@ private static void fillClassModel(ClassModel cModelParent, ClassModel cModel, S idxStart = comment.toLowerCase().indexOf("@description"); if (idxStart != -1 || i == 1) { - if (idxStart != -1 && comment.length() > idxStart + 13) - cModel.setDescription(comment.substring(idxStart + 12).trim()); - else{ - Pattern p = Pattern.compile("\\s"); - Matcher m = p.matcher(comment); - if (m.find()) { - cModel.setDescription(comment.substring(m.start()).trim()); - } + if (idxStart != -1 && comment.length() > idxStart + 13) + cModel.setDescription(comment.substring(idxStart + 12).trim()); + else{ + Pattern p = Pattern.compile("\\s"); + Matcher m = p.matcher(comment); + if (m.find()) { + cModel.setDescription(comment.substring(m.start()).trim()); + } } inDescription = true; continue; diff --git a/src/org/salesforce/apexdoc/ApexModel.java b/src/org/salesforce/apexdoc/ApexModel.java index 027bae5..46179e5 100644 --- a/src/org/salesforce/apexdoc/ApexModel.java +++ b/src/org/salesforce/apexdoc/ApexModel.java @@ -1,6 +1,8 @@ package org.salesforce.apexdoc; public class ApexModel { + private String deprecated; + public String getNameLine() { return nameLine; } @@ -31,6 +33,13 @@ public void setAuthor(String author) { this.author = author; } + public void setDeprecated(String dep) { + this.deprecated = dep; + } + public String getDeprecated() { + return deprecated == null ? "" : deprecated; + } + public String getDate() { return date == null ? "" : date; } diff --git a/src/org/salesforce/apexdoc/FileManager.java b/src/org/salesforce/apexdoc/FileManager.java index 86ed5ad..84a6056 100644 --- a/src/org/salesforce/apexdoc/FileManager.java +++ b/src/org/salesforce/apexdoc/FileManager.java @@ -112,7 +112,7 @@ private String strHTMLScopingPanel() { * @param monitor */ private void makeFile(TreeMap mapGroupNameToClassGroup, ArrayList cModels, - String projectDetail, String homeContents, String hostedSourceURL, IProgressMonitor monitor) { + String projectDetail, String homeContents, String hostedSourceURL, IProgressMonitor monitor) { String links = ""; links += strHTMLScopingPanel(); links += ""; @@ -179,12 +179,21 @@ private String htmlForClassModel(ClassModel cModel, String hostedSourceURL) { strLinkfromModel(cModel, cModel.getTopmostClassName(), hostedSourceURL) + escapeHTML(cModel.getNameLine()) + ""; + contents += "
"; + + if(cModel.getDeprecated() != ""){ + contents +="Deprecated: " + escapeHTML(cModel.getDeprecated()) + "

"; + } + if (cModel.getDescription() != "") - contents += "
" + escapeHTML(cModel.getDescription()); + contents += "" + escapeHTML(cModel.getDescription()) + "

"; + if (cModel.getAuthor() != "") - contents += "

" + escapeHTML(cModel.getAuthor()); + contents += "Author: " + escapeHTML(cModel.getAuthor()) + "
"; + if (cModel.getDate() != "") - contents += "
" + escapeHTML(cModel.getDate()); + contents += "Date: " + escapeHTML(cModel.getDate()); + contents += "

"; contents += "

"; if (cModel.getProperties().size() > 0) { @@ -233,6 +242,11 @@ private String htmlForClassModel(ClassModel cModel, String hostedSourceURL) { strLinkfromModel(method, cModel.getTopmostClassName(), hostedSourceURL) + escapeHTML(method.getNameLine()) + ""; + if(method.getDeprecated() != ""){ + contents +="

Deprecated
"; + contents += "
" + escapeHTML(method.getDeprecated()) + "
"; + } + if (method.getDescription() != "") contents += "
" + escapeHTML(method.getDescription()) + "
"; @@ -247,7 +261,7 @@ private String htmlForClassModel(ClassModel cModel, String hostedSourceURL) { String paramName; String paramDescription; if (m.find()) { - int ich = m.start(); + int ich = m.start(); paramName = param.substring(0, ich); paramDescription = param.substring(ich + 1); } else { @@ -278,6 +292,13 @@ private String htmlForClassModel(ClassModel cModel, String hostedSourceURL) { contents += "
" + escapeHTML(method.getAuthor()) + "
"; } + if (method.getExceptionList().size() > 0) { + contents += "
Exceptions
"; + for(String except : method.getExceptionList()){ + contents += "
" + escapeHTML(except) + "
"; + } + } + if (method.getDate() != "") { contents += "
Date
"; contents += "
" + escapeHTML(method.getDate()) + "
"; @@ -295,8 +316,8 @@ private String htmlForClassModel(ClassModel cModel, String hostedSourceURL) { // create our Class Group content files private void createClassGroupContent(TreeMap mapFNameToContent, String links, String projectDetail, - TreeMap mapGroupNameToClassGroup, - ArrayList cModels, IProgressMonitor monitor) { + TreeMap mapGroupNameToClassGroup, + ArrayList cModels, IProgressMonitor monitor) { for (String strGroup : mapGroupNameToClassGroup.keySet()) { ClassGroup cg = mapGroupNameToClassGroup.get(strGroup); @@ -430,7 +451,7 @@ public ArrayList getFiles(String path) { } public void createDoc(TreeMap mapGroupNameToClassGroup, ArrayList cModels, - String projectDetail, String homeContents, String hostedSourceURL, IProgressMonitor monitor) { + String projectDetail, String homeContents, String hostedSourceURL, IProgressMonitor monitor) { makeFile(mapGroupNameToClassGroup, cModels, projectDetail, homeContents, hostedSourceURL, monitor); } diff --git a/src/org/salesforce/apexdoc/MethodModel.java b/src/org/salesforce/apexdoc/MethodModel.java index 0663391..e6e46b0 100644 --- a/src/org/salesforce/apexdoc/MethodModel.java +++ b/src/org/salesforce/apexdoc/MethodModel.java @@ -6,6 +6,7 @@ public class MethodModel extends ApexModel { public MethodModel() { params = new ArrayList(); + exceptions = new ArrayList(); } public void setNameLine(String nameLine, int iLine) { @@ -22,6 +23,10 @@ public ArrayList getParams() { return params; } + public ArrayList getExceptionList() { + return exceptions; + } + public void setParams(ArrayList params) { this.params = params; } @@ -47,5 +52,7 @@ public String getMethodName() { } private ArrayList params; + private ArrayList exceptions; private String returnType; + }