/* XBN Java: Generically useful, non-GUI Java code. http://sourceforge.net/projects/xbnjava Copyright (C) 1997-2003, Jeff Epstein All rights reserved. Modifications: No Redistribution in binary form, with or without modifications, are permitted provided that the following conditions are met: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * If modifications are made to source code then this license should indicate that fact in the "Modifications" section above. * Neither the author, nor the contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [NOTE: This license contains NO advertising clause.] */ package xbn.jdlcode; import xbn.XBNObject; import xbn.AssertException; import xbn.array.VWObject; import xbn.array.VWString; import xbn.array.BinarySearchData; import xbn.output.OConfig; import xbn.output.Outputter; import xbn.output.OWriter; import xbn.placeholder.i_i; import xbn.placeholder.s_s; import xbn.string.FLRString; import xbn.string.StringOrBuffer; import xbn.string.SOBStringBuffer; import xbn.string.TCInvisible; import xbn.string.UtilSOB; import xbn.string.UtilString; import xbn.string.UtilStringBuffer; import xbn.template.*; import xbn.template.util.UtilTemplate; import xbn.util.DirFile; import xbn.util.FLRFile; import xbn.util.ForLineRetrieval; import java.io.File; import java.io.FileFilter; import java.lang.reflect.*; import java.util.Vector; /**
Random functions used throughout the xbn.jdlcode package.
Source code: UtilJDLCode.java.
To shorten code and Javadoc.
Equal to "xbn.jdlcode.UtilJDLCode."
**/ public static final String sUD = "xbn.jdlcode.UtilJDLCode."; private UtilSOB uSOB = new UtilSOB(); private UtilStringBuffer uSB = new UtilStringBuffer(); private UtilString uStr = new UtilString(); private final TCInvisible trimInvis = new TCInvisible(); private UtilGap uGap = new UtilGap(); private UtilTemplate uTemplate = new UtilTemplate(); /**Create a UtilJDLCode. This constructor does nothing.
**/ public UtilJDLCode() { } /**Get the text used for the JavaDoc Link Code start gap.
@return JD **/ public static final String getJDLinkGapTextStart() { return "JD"; } /**Get the text used for the JavaDoc Link Code end gap.
@return EJD **/ public static final String getJDLinkGapTextEnd() { return "EJD"; } /**Get the JavaDoc Link Code start gap.
@returnUtilGap.getTag(getJDLinkGapTextStart())
**/
public final String getJDLinkGapStart() {
return uGap.getTag(getJDLinkGapTextStart());
}
/**
Get the JavaDoc Link Code end gap.
@returnUtilGap.getTag(getJDLinkGapTextEnd())
**/
public final String getJDLinkGapEnd() {
return uGap.getTag(getJDLinkGapTextEnd());
}
/**
How many "parts" do the provided JDFiles have in common, starting from the left?
@param jd_file1 The JDFile to compare against jd_file2. May not be null. @param jd_file2 The JDFile to compare against jd_file1. May not be null. @return For example:If jd_file1 is... | ...and jd_file2 is... | ...then this is returned |
xbn.jdlcode.JDFile |
xbn.jdlcode.JDFile |
3 |
xbn.jdlcode.UtilJDLCode |
xbn.jdlcode.JDFile |
2 |
xbn.array.VWObject |
xbn.array.UtilArray |
1 |
overview-summary |
xbn.jdlcode.JDFile |
0 |
xbn.jdlcode.subdoclet.SDClass |
xbn.jdlcode.JDFile |
2 |
xbn.jdlcode.subdoclet.JDFile |
xbn.jdlcode.JDFile |
2 |
xbn.jdlcode.JDFile |
xbn.jdlcode.subdoclet.JDFile |
2 |
Get the relative url from one html file to another. This is only a link from one file to another, not to a location within the file.
@return The contents of the SOBStringBuffer:appendRelUrlToFile((new SOBStringBuffer("")), jdf_linkSource, jdc_toLinkTo)
**/
public final String getRelUrlToFile(JDFile jdf_linkSource, JDClass jdc_toLinkTo) {
SOBStringBuffer ssb = new SOBStringBuffer(sES);
appendRelUrlToFile(ssb, jdf_linkSource, jdc_toLinkTo);
return ssb.toString();
}
/**
Append the relative url from one html file to another onto the StringBuffer.
Equal to appendRelUrlToFile([UtilStringBuffer].getSOBSB(str_buffer, sUD + "appendRelUrlToFile"), jdf_linkSource, jdc_toLinkTo)
**/
public final void appendRelUrlToFile(StringBuffer str_buffer, JDFile jdf_linkSource, JDClass jdc_toLinkTo) {
appendRelUrlToFile(uSB.getSOBSB(str_buffer, sUD + "appendRelUrlToFile"), jdf_linkSource, jdc_toLinkTo);
}
/**
Get the relative url from one html file to another onto the StringOrBuffer. This is only a link from one file to another, not to a location within the file.
See appendRelUrlToFile.
@param jdf_linkSource The JDFile representing the html file in which the link will reside. May not be null. @param jdc_toLinkTo The JDClass representing the html file the link should point to. Must not be primitive. @return The relative url from the html/class file represented by jf_linkFrom to the html/class file represented jdc_linkTo. For example:From | To | Url to file |
xbn.jdlcode.UtilJDLCode |
xbn.string.UtilString |
~JD~utils~EJD~ |
xbn.string.UtilString |
xbn.array.VWString |
VWString.html |
xbn.string.UtilString |
xbn.string.UtilString |
Empty string |
xbn.jdlcode.UtilJDLCode |
java.lang.Object |
~JD~o~EJD~ |
Get two strings from a single line in a class map configuration text file. All lines in the class map must be in the form.
[str_one][one_or_more_tabs][str_two]
Get a new JDClass based on the two values in a line from the class map configuration text file. See getJDCAFromFLR.
@param s_cfgFileLine The line from the class map configuration text file. Must contain exactly two strings (at least one character each), divided by at least one tab. The first string is the abbreviation, and the second string is the fully qualified class name (or file name). Examples:i int o java.lang.Object srq javax.servlet.ServletRequest pkgjdlc xbn.jdlcode.package-summary vwo xbn.array.VWObject@param i_lineNumber The line number of s_cfgFileLine, for potential error messages only. @param pt_array The PTArray containing all legal package name prefixes. @return
(new JDClass([string1], [string2], pt_array))
**/
public final JDClass getJDClassFromLine(String s_cfgFileLine, int i_lineNumber, PTArray pt_array) {
s_s ss = get2StringsFromLine(s_cfgFileLine, "getJDClassFromLine", i_lineNumber, "abbreviation", "fully qualified class name", true);
return (new JDClass(ss.s1, ss.s2, pt_array));
}
/**
Get a new PackageType based on the one-or-two values in a line from the class map configuration text file. See getJDCAFromFLR and PackageType.
@param s_cfgFileLine The line from the class map configuration text file. Must contain exactly two strings (at least one character each), divided by at least one tab. The first string is the PackageType, and the second string (if any) is the base url for that package's JavaDoc. Examples:java http://java.sun.com/j2se/1.3/docs/api/ javax http://java.sun.com/products/servlet/2.2/javadoc/ random_util file:/home/java_code/random_util/javadoc/ eckggg xbn@param i_lineNumber The line number of s_cfgFileLine, for potential error messages only. @param pt_array The PTArray containing all legal package name prefixes. @return
(new PackageType([string1], [string2]))
**/
public final PackageType getPackageTypeFromLine(String s_cfgFileLine, int i_lineNumber) {
s_s ss = get2StringsFromLine(s_cfgFileLine, "getPackageTypeFromLine", i_lineNumber, "package prefix", "external url", false);
return (new PackageType(ss.s1, ss.s2));
}
/**
Create a JDCArray from a file.
@param s_mapFile The full path and file name to the class map configuration text file. Must be non-null, and point to an existing and readable text file. @returngetJDCAFromFLR(new FLRFile(s_mapFile))
**/
public final JDCArray getJDCAFromMapFile(String s_mapFile) {
throwAXIfBadStr(s_mapFile, "s_mapFile", "getJDCAFromMapFile");
return getJDCAFromFLR(new FLRFile(s_mapFile));
}
/**
Create a JDCArray from the provided Doclet Class Map.
Example code XmplUtilJDLCode_gjdcafflr.java. Take a look at the actual XBN Doclet Class Map.
[package_type_line1]
[package_type_line2]
[package_type_line3]
...
[divider line]
[class_map_line1]
[class_map_line2]
[class_map_line3]
...
[package_type_line]
is in the form required by getPackageTypeFromLine. See PackageType[divider_line]
is a line that starts with a single "\~" (ignoring trailing tabs and spaces). All characters after it are ignored.[class_map_line]
is in the form required by getJDClassFromLine. See JDClassThere must be at least one package type that is local (in other words, has no referring url).
@exception AssertException The special PackageType "overview-summary", with an abbreviation of "over" is defined in this function. An exception is thrown if you also define either in your class map. **/ public final JDCArray getJDCAFromFLR(ForLineRetrieval for_lineRetrieval) { throwAXIfNull(for_lineRetrieval, "for_lineRetrieval", "getJDCAFromFLR"); VWObject acoJDC = new VWObject(); VWObject acoPT = new VWObject(); PTArray pta = null; boolean bFoundPTDivider = false; while(for_lineRetrieval.hasMoreLines()) { String sLine = for_lineRetrieval.getNextLine().toString(); sLine = sLine.trim(); if(sLine.length() > 0) { if(!bFoundPTDivider) { if(sLine.startsWith("~")) { if(acoPT.size() == 0) { throwAX("getJDCAFromFLR: No PackageTypes found before the '~' divider line. PackageTypes belong before it, and JDClasses after. At least one of each is required."); } Object[] ao = acoPT.getAOObject(); PackageType[] aPT = new PackageType[ao.length + 1]; for(int i = 0; i < ao.length; i++) { aPT[i] = (PackageType)ao[i]; } aPT[aPT.length - 1] = new PackageType("overview-summary", null); pta = new PTArray(aPT); bFoundPTDivider = true; } else { acoPT.add(getPackageTypeFromLine(sLine, for_lineRetrieval.getLineNumberPrev())); } } else { JDClass jdc = getJDClassFromLine(sLine, for_lineRetrieval.getLineNumberPrev(), pta); acoJDC.add(jdc); } } } if(!bFoundPTDivider) { throwAX("getJDCAFromFLR: So far, there are " + acoPT.size() + " PackageTypes, but I've reached the end of the file, and have not found the '~' divider line. PackageTypes belong before it, and JDClasses after. At least one of each is required."); } //Add the most special and reserved JDClass... JDClass jdc = getJDClassFromLine("over overview-summary", 1, pta); acoJDC.add(jdc); Object[] ao = acoJDC.getAOObject(); JDClass[] aJDC = new JDClass[ao.length]; for(int i = 0; i < aJDC.length; i++) { aJDC[i] = (JDClass)ao[i]; } return new JDCArray(aJDC, pta); } /**Get the TLAObjects needed for getJavadocLine. See getJavadocLine.
The object is created each time this function is called.
@param optr_dbg The Outputter for debugging output. May not be null. **/ public final TLAObjects getTLAOForGJL(Outputter optr_dbg) { return (new TLAObjects( new TParseConfig( new GapConfig(getJDLinkGapTextStart(), getJDLinkGapTextEnd()), true, optr_dbg))); } /**Given the provided line of Javadoc, return the same line with all JavaDoc Link Codes translated to actual urls.
Equal to getJavadocLine(s_line, jdf_current, jdc_array, b_cibJDLCTarget, b_ignoreIndirectJDLCs, (new TLAObjects()))
Given the provided line of Javadoc, return the same line with all JavaDoc Link Codes translated to actual urls.
It is assumed that jdf_current is legal (represents an html file that actually exists). When called by xbn_doclet.XBNDoclet (via the JavaDoc command), it is. You could easily pass in an invalid one...
@param s_line The line of javadoc html. May not be null or zero characters in length. @param jdf_current The JDFile representing the file in which s_line exists. It is therefore the html file in which links will be "from". May not be null. Passed directly to getRelUrl. @param jdc_array The JDCArray containing all existing JDClasses (abbreviations and fully qualified class/file names.). May not be null. Passed directly to getRelUrl. @param b_ignoreIndirectJDLCs Passed directly to the SplitLinkCode constructor. @param tla_objects The TLAObjects provided directly to the TemplateLineAnalyzer constructor. May not be null. This also contains the Outputter used for debugging output. See getTLAOForGJL. **/ public final String getJavadocLine(String s_line, JDFile jdf_current, JDCArray jdc_array, boolean b_cibJDLCTarget, boolean b_ignoreIndirectJDLCs, TLAObjects tla_objects) throws TemplateFormatException { StringBuffer sbOutput = new StringBuffer(sES); FLRString flrsLine = new FLRString(s_line); while(flrsLine.hasMoreLines()) { StringBuffer sbLine = flrsLine.getNextLine(); TemplateLineAnalyzer tla = new TemplateLineAnalyzer(null, flrsLine.getLineNumberPrev(), sbLine, tla_objects); if(!tla.isDoneAnalyzing()) { while(tla.hasAnotherGap()) { s_s ss = tla.getNextSurrTxtAndGap(); sbOutput.append(ss.s1); appendLinkFromCode(sbOutput, ss.s2, jdf_current, jdc_array, b_cibJDLCTarget, b_ignoreIndirectJDLCs); } //The end of the line has been reached. sbOutput.append(tla.getFinalSurrTxt()); } } return sbOutput.toString(); } /**[SLASH]**
, alone on a line (after trimming tabs and spaces), is the start of a JavaDoc comment. **[SLASH]
, alone on a line (after trimming tabs and spaces), is the end of a JavaDoc comment. This may not exist in any function or code.
Use a single asterisk for internal (existing in functions), multi-lined documentation. For any other multi-line comments that exist outside of functions, but should still be ignored (such as license text), also use a single asterisk. This is not required (as long as the license text has nothing "illegal" in it), but will speed up the javadoc process.
**/ public final StringBuffer getJDTextFromJava(ForLineRetrieval flr_javaSourceCode) { throwAXIfNull(flr_javaSourceCode, "flr_javaSourceCode", "getJDTextFromJava"); StringBuffer sbJDText = new StringBuffer(sES); boolean bInJD = false; while(flr_javaSourceCode.hasMoreLines()) { StringBuffer sbLine = flr_javaSourceCode.getNextLine(); trimInvis.trim(sbLine); if(sbLine.length() == 3 && sbLine.charAt(0) == '/' && sbLine.charAt(1) == '*' && sbLine.charAt(2) == '*') { bInJD = true; //This is the start of a JD comment, but the starting line //itself needs to be discarded. continue; } else if(sbLine.length() == 3 && sbLine.charAt(0) == '*' && sbLine.charAt(1) == '*' && sbLine.charAt(2) == '/') { bInJD = false; //Discard the ending line, too. continue; } if(bInJD) { sbJDText.append(sbLine.toString()); } } return sbJDText; } /**Get the Class for the provided fully-qualified name.
Equal to getClassForName(sUD + "getClassForName", s_fqClassName)
Get the Class for the provided fully-qualified name. See Class.forName.
@param s_callingClsFnc The class-name-plus-function from which potential error messages should appear as coming from. @param s_fqClassName The fully-qualified class name to be analyzed. **/ public final Class getClassForName(String s_callingClsFnc, String s_fqClassName) { try { return Class.forName(s_fqClassName); } catch(ClassNotFoundException cnfx) { throwAXSpoof(s_callingClsFnc + ": s_fqClassName ('" + s_fqClassName + "') does not exist according to Class.forName()."); } //Never reached. Required for compile. return null; } //Used only by crashIfBadTarget() private Classes classes = new Classes(); /**If the JavaDoc Link Code points to a non-existant target, die with a descriptive error message. Otherwise, do nothing.
Example code XmplUtilJDLCode_cibt.java
Note: This validates JavaDoc Link Codes only, not hard-coded links (or portions thereof). So this link
<A HREF="\~JD\~getClassForName(s,s)\~EJD\~#bogus_name_link">my link</A>
is considered legal, because only the part within \~JD\~
and \~EJD\~
is recognized (and therefore analyzed).
As long as a JavaDoc Link Code exists somewhere within a JavaDoc block, they are all analyzed, even if they're not in the url of an "A HREF
" tag.
jdf_linkSource.getList(".")
.
@param jdc_array Contains information generated from the doclet class map. May not be null.
@param b_ignoreIndirectJDLCs If true and jdf_linkSource.hasJDLCsIndirectly
equals true and jdf_linkSource.hasJDLCsDirectly
equals false, then this function does nothing. If this parameter is false, then indirect links are validated. No matter what, when jdf_linkSource.hasJDLCsDirectly
equals true, the JavaDoc Link Code is always validated.
**/
public final void crashIfBadTarget(JDFile jdf_linkSource, SplitLinkCode split_linkCode, JDCArray jdc_array, boolean b_ignoreIndirectJDLCs) {
String sCIBL = sUD + "crashIfBadTarget: ";
try {
if(jdf_linkSource.hasNoJDLCodes()) {
throwAXSpoof(sCIBL + "jdf_linkSource.hasNoJDLCodes() equals true. Extra information... jdf_linkSource.getList('.')='" + jdf_linkSource.getList(sPD) + "'.");
}
} catch(NullPointerException npx) {
throwAXSpoof(sCIBL + "jdf_linkSource is null.");
}
//jdf_linkSource has links either directly or indirectly
boolean bIndSrc = jdf_linkSource.hasJDLCsIndirectly();
if(bIndSrc && b_ignoreIndirectJDLCs) {
//Secondary links may or may not be bad. We don't care.
//They don't care.
return;
}
//What is the target class name?
String sTargetClass = null;
try {
if(split_linkCode.getClassName() == null) {
//There is no class name in slc. Therefore, the
//link's source and target file/class is one and the
//same.
//(The source file has links in it, either primarily or secondarily.)
sTargetClass = jdf_linkSource.getList(sPD);
if(!jdc_array.getJDCAFromFQCN().doesExist(sTargetClass)) {
throwAXSpoof(sCIBL + "The link's target class ('" + sTargetClass + "') does not exist according to jdc_array.getJDCAFromFQCN().doesExist()." + (bIndSrc?" NOTE: jdf_linkSource.hasJDLCsIndirectly() equals true and b_ignoreIndirectJDLCs=false.":sES));
}
} else {
//There is a class name in SplitLinkCode.
if(!jdc_array.doesExist(split_linkCode.getClassName())) {
throwAXSpoof(sCIBL + "The target class (JavaDoc abbreviation='" + split_linkCode.getClassName() + "') does not exist in jdc_array.");
}
sTargetClass = jdc_array.getJDClass(split_linkCode.getClassName()).getList(sPD);
}
} catch(NullPointerException npx) {
if(split_linkCode == null) {
throwAXSpoof(sCIBL + "split_linkCode is null.");
}
throwAXSpoof(sCIBL + "jdc_array is null.");
}
//One special page-type to deal with: *-summary
if(sTargetClass.endsWith("-summary")) {
//This is a link to a -summary page, not a
//class. These pages contain no functions or
//constructors.
if(split_linkCode.getCnstrFuncName() != null) {
throwAXSpoof(sCIBL + "The link does contain a constructor or function, but no constructors or functions exist in *-summary pages (the target one for this particular link is '" + sTargetClass + "').");
}
//The link has no constructor/function in it. GOOD.
return;
}
//Ensure that the target page/class is one that exists in
//jdc_array (in the jdlcode class map).
try {
if(!jdc_array.getJDCAFromFQCN().doesExist(sTargetClass)) {
throwAXSpoof(sCIBL + "The link's target class ('" + sTargetClass + "') does not exist according to jdc_array.getJDCAFromFQCN().doesExist().");
}
} catch(NullPointerException npx) {
throwAXSpoof(sCIBL + "jdc_array is null.");
}
if(!classes.doesExist(sTargetClass)) {
//We've not yet retrieved this class' information.
Class cls = getClassForName(sUD + "crashIfBadTarget", sTargetClass);
//The class does (actually) exist.
classes.add(cls);
//We now have all the public and protected constructors
//and functions for this class.
}
if(split_linkCode.getCnstrFuncName() == null) {
//This is a link to a(n overall) class, not a
//constructor or function therein. GOOD.
return;
}
//There is a constructor/function link.
if(jdc_array.doesExist(split_linkCode.getCnstrFuncName()) &&
jdc_array.getJDClass(split_linkCode.getCnstrFuncName()).getName().equals(sTargetClass)) {
//This is a link to a constructor.
Constructor[] aConstructor = classes.getClassStuff(sTargetClass).aConstructors;
for(int i = 0; i < aConstructor.length; i++) {
if(hasSameParams(split_linkCode, aConstructor[i].getParameterTypes(), jdc_array)) {
//Every parameter in split_linkCode and this
//actually-existing constructor/function are
//exactly the same. This target exists!
return;
}
}
throwAXSpoof(sCIBL + "The target class ('" + sTargetClass + "') does exist. But the target constructor has a parameter list ([" + split_linkCode.getParamList(",") + "]) that does not represent any actually-existing (public or protected) constructor.");
}
//This link is to a function.
if(split_linkCode.getParameterCount() == 0) {
throwAXSpoof(sCIBL + "This link contains only a zero-parameter function. It must be put outside of the JavaDoc Link Code (for example '~JD~class~EJD~#function()' instead of '~JD~class#function()~EJD~'). This is not caught by SplitLinkCode, because it cannot tell the difference between a constructor name, and a function name. However, I can. :' )");
}
Method[] aMethod = classes.getClassStuff(sTargetClass).aMethods;
boolean bFuncExists = false;
for(int i = 0; i < aMethod.length; i++) {
if(split_linkCode.getCnstrFuncName().equals(aMethod[i].getName())) {
//The function names are the same...
bFuncExists = true;
if(hasSameParams(split_linkCode, aMethod[i].getParameterTypes(), jdc_array)) {
//...and every parameter in split_linkCode and
// this actually-existing
// constructor/function are exactly the
// same. This target exists! GOOD.
return;
}
}
}
if(bFuncExists) {
throwAXSpoof(sCIBL + "Both the target class ('" + sTargetClass + "') and function ('" + split_linkCode.getCnstrFuncName() + "') exist. But the parameter list ([" + split_linkCode.getParamList(",") + "]) does not represent any actually-existing (public or protected) version of that function.");
} else {
String sOthr = sES;
if(jdc_array.doesExist(split_linkCode.getCnstrFuncName())) {
sOthr = " The target function *is* equal to the abbreviation for another class: '" + jdc_array.getJDClass(split_linkCode.getCnstrFuncName()).getList(sPD) + "'.";
}
throwAXSpoof(sCIBL + "The target class ('" + sTargetClass + "') does exist, but the target function ('" + split_linkCode.getCnstrFuncName() + "') does not exist in that class." + sOthr);
}
}
/**
Do the SplitLinkCode and Class array share the same exact parameter list (including order)?
@param split_linkCode The SplitLinkCode whose parameters should be compared to ac_parameters. May not be null. @param ac_parameters The array of Class objects, which should be compared to split_linkCode's parameter list. @param jdc_array The mapping of full class name to JavaDoc Link Code. May not be null. @return true If split_linkCode contains the same amount of parameters asac_parameters.length
, and every element X in split_linkCode represents the same class as element X in ac_parameters.
Get the relative url (to the class-dot-function or constructor or local function), as defined by the parts existing in this SplitLinkCode.
@returngetRelUrlAppended(SplitLinkCode split_linkCode, "", jdf_linkSource, jdc_array, b_cibJDLCTarget, b_ignoreIndirectJDLCs)
**/
public final String getRelUrl(SplitLinkCode split_linkCode, JDFile jdf_linkSource, JDCArray jdc_array, boolean b_crashIfBadTarget, boolean b_ignoreIndirectJDLCs) {
return getRelUrlAppended(split_linkCode, sES, jdf_linkSource, jdc_array, b_crashIfBadTarget, b_ignoreIndirectJDLCs);
}
/**
Get a copy of the string where the relative url (to the class-dot-function or constructor or local function), as defined by the parts existing in this SplitLinkCode, is appended.
@return The contents of getSOBSB:appendRelUrl(split_linkCode, [UtilString].getSOBSB(s_tr, sUD + "getRelUrlAppended"), jdf_linkSource, jdc_array, b_crashIfBadTarget, b_ignoreIndirectJDLCs))
**/
public final String getRelUrlAppended(SplitLinkCode split_linkCode, String s_tr, JDFile jdf_linkSource, JDCArray jdc_array, boolean b_crashIfBadTarget, boolean b_ignoreIndirectJDLCs) {
SOBStringBuffer ssb = uStr.getSOBSB(s_tr, sUD + "getRelUrlAppended");
appendRelUrl(split_linkCode, ssb, jdf_linkSource, jdc_array, b_crashIfBadTarget, b_ignoreIndirectJDLCs);
return ssb.toString();
}
/**
Get a copy of the StringBuffer where the relative url (to the class-dot-function or constructor or local function), as defined by the parts existing in this SplitLinkCode, is appended.
@return The contents of getSOBSB:appendRelUrl(split_linkCode, [UtilStringBuffer].getSOBSB(str_buffer, sUD + "getRelUrlAppended"), jdf_linkSource, jdc_array, b_crashIfBadTarget, b_ignoreIndirectJDLCs))
**/
public final StringBuffer getRelUrlAppended(SplitLinkCode split_linkCode, StringBuffer str_buffer, JDFile jdf_linkSource, JDCArray jdc_array, boolean b_crashIfBadTarget, boolean b_ignoreIndirectJDLCs) {
SOBStringBuffer ssb = uSB.getSOBSB(str_buffer, sUD + "getRelUrlAppended");
appendRelUrl(split_linkCode, ssb, jdf_linkSource, jdc_array, b_crashIfBadTarget, b_ignoreIndirectJDLCs);
return ssb.getStringBuffer();
}
/**
Append a relative url to the class-dot-function (or constructor or local function) represented by the parts existing in this SplitLinkCode.
Equal to appendRelUrl(split_linkCode, [UtilSOB].getSOBSB(str_orBfr, sUD + "getRelUrlAppended"), jdf_linkSource, jdc_array, b_crashIfBadTarget, b_ignoreIndirectJDLCs))
Get a copy of the StringOrBuffer (as an SOBStringBuffer) where the relative url (to the class-dot-function or constructor or local function), as defined by the parts existing in this SplitLinkCode, is appended.
@return The contents of getSOBSB:appendRelUrl(split_linkCode, [UtilSOB].getSOBSB(str_orBfr, sUD + "getRelUrlAppended"), jdf_linkSource, jdc_array, b_crashIfBadTarget, b_ignoreIndirectJDLCs))
**/
public final SOBStringBuffer getRelUrlAppended(SplitLinkCode split_linkCode, StringOrBuffer str_orBfr, JDFile jdf_linkSource, JDCArray jdc_array, boolean b_crashIfBadTarget, boolean b_ignoreIndirectJDLCs) {
SOBStringBuffer ssb = uSOB.getSOBSB(str_orBfr, sUD + "getRelUrlAppended");
appendRelUrl(split_linkCode, ssb, jdf_linkSource, jdc_array, b_crashIfBadTarget, b_ignoreIndirectJDLCs);
return ssb;
}
/**
Append a relative url to the class-dot-function (or constructor or local function) represented by the parts existing in this SplitLinkCode.
@param split_linkCode The SplitLinkCode containing the JavaDoc Link Code. @param str_buffer The StringBuffer to append the link to. @param jdf_linkSource The JDFile representing the html file in which the link will exist. @param jdc_array The JDCArray containing all class abbreviations. @param b_crashIfBadTarget If true, then the link is checked to ensure that it's target truly exists, and crashes if it doesn't (see crashIfBadTarget). If false, then the link is not checked for validity (and b_ignoreIndirectJDLCs is ignored). @param b_ignoreIndirectJDLCs This parameter is only used when b_crashIfBadTarget equals true. If this parameter is true, then links on indirect link pages are not checked for validity. If false, then when links on indirect link pages are invalid, a crash occurs, with a descriptive error message.Links found on inderict pages are actually the first sentence in your function/class/constructor's JavaDoc block (for example: "Append a relative url to the..." is the first sentence in this function's JavaDoc block). If they have a link to a function/constructor within the same class, then you would usually not put a class prefix in the JavaDoc Link Code (for example: \~JD\~crashIfBadTarget(jdf,slc,jdca,b)\~EJD\~
is the JavaDoc Link Code for the crashIfBadTarget link, right above). However, JavaDoc Link Codes in the first sentence are also displayed in indirect link pages (such as index pages). If no class prefix exists for the JavaDoc Link Code, then, although the link is valid in the class itself, it is not valid in the inderct link page. Therefore, if the crashIfBadTarget were found in the first sentence, it should have the class prefix: \~JD\~utiljdlc#crashIfBadTarget(jdf,slc,jdca,b)\~EJD\~
.
Note: No matter what, functions outside of the JavaDoc Link Code are not validated. So although this link (url equals \~JD\~utiljdlc\~EJD\~#nonExistingFunction()
) is broken, since the function is outside the JavaDoc Link Code it's not checked for validity.
Remember also, that zero parameter functions are not allowed inside a JavaDoc Link Code, ever. This is validated by crashIfBadTarget but not the SplitLinkCode constructor (SplitLinkCode just checks formatting, so it assumes that a zero-parameter function is actually a zero-parameter constructor. It does not verify that the target exists, and therefore cannot distinguish between constructors and functions).
**/ public final void appendRelUrl(SplitLinkCode split_linkCode, StringOrBuffer str_orBfr, JDFile jdf_linkSource, JDCArray jdc_array, boolean b_crashIfBadTarget, boolean b_ignoreIndirectJDLCs) { throwAXIfNull(str_orBfr, "str_orBfr", "appendRelUrl"); throwAXIfNull(jdc_array, "jdc_array", "appendRelUrl"); if(b_crashIfBadTarget) { try { crashIfBadTarget(jdf_linkSource, split_linkCode, jdc_array, b_ignoreIndirectJDLCs); } catch(AssertException ax) { throwAX("appendRelUrl: Attempting to generate link for JavaDoc code '" + getOriginalCode(split_linkCode) + "', in source file '" + jdf_linkSource.getList(sPD) + "'..." + ax.toString()); } } //We've made it this far, so the link points to a truly- //existing target. String sClass = null; try { sClass = split_linkCode.getClassName(); } catch(NullPointerException npx) { throwAX("appendRelUrl: split_linkCode is null."); } if(sClass != null) { if(!jdc_array.doesExist(sClass)) { throwAX("appendRelUrl: split_linkCode has a class name abbreviation of '" + sClass + "', but this is not an abbreviation that exists in jdc_array."); } appendRelUrlToFile(str_orBfr, jdf_linkSource, jdc_array.getJDClass(sClass)); } String sFunction = split_linkCode.getCnstrFuncName(); if(sFunction == null) { return; } str_orBfr.append("#"); if(jdc_array.doesExist(sFunction)) { //The only way a function can be the name of a class, is when //we're calling the constructor. So we only need the very last //part of the fully qualified class name...the file name itself. JDFile jdf = jdc_array.getJDClass(sFunction); str_orBfr.append(jdf.getPart(jdf.getPartCount() - 1) + "("); } else { //This is an actual function. We must trust that it's legal. str_orBfr.append(sFunction + "("); } if(split_linkCode.getParameterCount() == 0) { str_orBfr.append(")"); return; } //There is at least one parameter. for(int i = 0; i < split_linkCode.getParameterCount(); i++) { if(!jdc_array.doesExist(split_linkCode.getParamName(i))) { throwAX("appendRelUrl: Parameter abbreviation at array index " + i + " ('" + split_linkCode.getParamName(i) + "') does not exist in jdc_array."); } str_orBfr.append(jdc_array.getJDClass(split_linkCode.getParamName(i)).getList(sPD)); if(split_linkCode.isParamArray(i)) { str_orBfr.append("[]"); } if(i < (split_linkCode.getParameterCount() - 1)) { str_orBfr.append(", "); } } str_orBfr.append(")"); } /**Get the original code, exactly as passed into the SplitLinkCode constructor. See the SplitLinkCode constructor.
**/ public final String getOriginalCode(SplitLinkCode split_linkCode) { StringBuffer sbLink = new StringBuffer(sES); try { if(split_linkCode.getClassName() != null) { sbLink.append(split_linkCode.getClassName()); if(split_linkCode.getCnstrFuncName() != null) { sbLink.append("#"); } } } catch(NullPointerException npx) { throwAX("getOriginalCode: split_linkCode is null."); } if(split_linkCode.getCnstrFuncName() != null) { sbLink.append(split_linkCode.getCnstrFuncName()); sbLink.append("("); } if(split_linkCode.getParameterCount() > 0) { for(int i = 0; i < split_linkCode.getParameterCount(); i++) { sbLink.append(split_linkCode.getParamName(i)); if(split_linkCode.isParamArray(i)) { sbLink.append("[]"); } if(i < (split_linkCode.getParameterCount() - 1)) { sbLink.append(","); } } } if(split_linkCode.getCnstrFuncName() != null) { sbLink.append(")"); } return sbLink.toString(); } //Used only by reportJDLinkCodeErrors private String sPreviousFile = sES; private String sCurrentFile = sES; private String sPreviousFileSCLR = sES; private String sCurrentFileSCLR = sES; private static final String sLS = sLINE_SEP; private int iFiles = 0; private int iUniqueJDLCs = 0; private int iAbsoluteJDLCs = 0; /**This analyzes the source code existing in a directory, verifying all JavaDoc Link Codes, as well as links to source code.
This checks the basic syntax of all JavaDoc Link Codes existing in your code (via the SplitLinkCode constructor), as well as verifying that each abbreviation (class, function/constructor and parameter) within each JavaDoc Link Code actually exists in your class map configuration text file (via SplitLinkCode.getRelUrl).
Also note that this analyzes the JavaDoc existing directly in your java code (and package.html-s), and not the generated JavaDoc files. So if you have "sandbox" and "build" versions of your code, the sandbox code is analyzed, but the targets are expected to exist in the build-version of the source-code directory.
Param name | Description | Notes |
s_docletClassMapFile | The path to the DocletClassMap | |
s_dirToAnalyze | All *.java and *.html files in this directory will be analyzed. |
Must end with a File.separator. For example, say you want to analyze all XBN Java code, and the source code exists in 'C:\\xbnjava\\xbn '. This should equal 'C:\\xbnjava\\xbn\\ ' and s_pkgPrefix should equal null. Alternatively, if you only want to analyze xbn.jdlcode , then this should equal 'C:\\xbnjava\\xbn\\jdlcode\\ ' and s_pkgPrefix should equal 'xbn ' |
b_analyzeJDLCodes | If true, then JavaDoc Link Codes are analyzed for syntax errors. If false, JavaDoc link codes are not analyzed. | When false, both b_cibJDLCTarget and b_ignoreIndirectJDLCs are ignored. Also note that you must analyze either JavaDoc Link Codes or source code links, or both. So if this is false, s_sourceCodeBaseDir must be non-null. If s_sourceCodeBaseDir is null, this must equal true. |
s_sourceCodeBaseDir | If non-null, then source code links are analyzed to ensure they point to existing files. If null, source code links are not analyzed. | See Notes for b_analyzeJDLCodes. In addition, when this is non-null, s_relUrlJDToCodeBases is required, and b_listAllSCLs is not ignored. When this is null, s_relUrlJDToCodeBases must also be null, and b_listAllSCLs is ignored. |
s_relUrlJDToCodeBases | The relative directory (including the final url slash) between the JavaDoc and source-code base directories. | Say your JavaDoc root directory is C:\\\\xbnjava\\\\documentation\\\\javadoc\\\\ , and the source code root directory is C:\\\\xbnjava\\\\CODE\\\\ . In this case, the relative url between these two directories is ../../CODE/ . |
b_listAllSCLs | If true, then all source code links (regardless if they're valid or not) are printed out in the report, before any potential errors (errors in either source code links or JavaDoc Link Codes) are printed. | See Notes for s_sourceCodeBaseDirp. |
b_cibJDLCTarget | Passed directly to getRelUrl, as b_crashIfBadTarget. | See Notes for b_analyzeJDLCodes. |
b_printXOnTheFly | Should exception messages be printed during the analysis? If true, print exception messages both during analysis and in the report. If false, only in the report. | |
s_pkgPrefix | The package name prefix, when s_dirToAnalyze points to a sub-package directory. | See Notes for s_sourceCodeBaseDir. |
ow_output | The OWriter to print output to. | May not be null. |