/*
* Copyright (c) 2001, 2002 The XDoclet team
* All rights reserved.
*/
package xdoclet.modules.doc;
import java.util.*;
import org.apache.tools.ant.types.EnumeratedAttribute;
import xjavadoc.XClass;
import xjavadoc.XTag;
import xdoclet.DocletContext;
import xdoclet.DocletTask;
import xdoclet.XDocletException;
import xdoclet.XDocletTagSupport;
/**
* This tag handler is used to generate Ant documentation
*
* @author Aslak Hellesoy
* @created 13. juni 2002
* @xdoclet.taghandler namespace="Antdoc"
* @version $Revision: 1.10 $
*/
public class AntdocTagsHandler extends XDocletTagSupport
{
/**
* The element being documented
*/
protected AntdocSubTask.Element docElement;
/**
* Current parent or child element
*/
protected AntdocSubTask.SubElement subElement;
public void setDocElement(AntdocSubTask.Element antElement)
{
docElement = antElement;
setCurrentClass(antElement.getXClass());
}
/**
* The name of the current sub-element.
*
* @return name
* @exception XDocletException
* @doc.tag type="content"
*/
public String subElementName() throws XDocletException
{
return subElement.getName();
}
/**
* The name of the current element.
*
* @return name
* @exception XDocletException
* @doc.tag type="content"
*/
public String elementName() throws XDocletException
{
return docElement.getName();
}
/**
* Generate the tag's body if the current element has any sub-elements.
*
* @param template The body of the block tag
* @exception XDocletException
* @doc.tag type="block"
*/
public void ifHasSubElements(String template) throws XDocletException
{
if (docElement.getSubElements() != null && docElement.getSubElements().size() > 0) {
generate(template);
}
}
/**
* Generate the tag's body for each of the current element's sub-elements.
*
* @param template The body of the block tag
* @exception XDocletException
* @doc.tag type="block"
*/
public void forAllSubElements(String template) throws XDocletException
{
XClass old_cur_class = getCurrentClass();
for (Iterator i = docElement.getSubElements().iterator(); i.hasNext(); ) {
subElement = (AntdocSubTask.SubElement) i.next();
setCurrentClass(subElement.getXClass());
generate(template);
}
setCurrentClass(old_cur_class);
}
/**
* The description of the current sub-element.
*
* @return description
* @doc.tag type="content"
*/
public String subElementDescription()
{
return subElement.getDescription();
}
/**
* The Required status (i.e. is it mandatory or optional) of an attribute. Uses the value text if it is present,
* otherwise defaults to "Yes." or "No." depending on whether an \@ant.required or \@ant.not-required tag is found.
*
* @return required
* @doc.tag type="content"
*/
public String required()
{
// default value
String result = null;
XTag required = getCurrentMethod().getDoc().getTag("ant.required");
if (required != null) {
result = required.getValue().trim();
if (result.equals("")) {
result = "Yes.";
}
}
else {
XTag not_required = getCurrentMethod().getDoc().getTag("ant.not-required");
if (not_required != null) {
result = not_required.getValue().trim();
if (result.equals("")) {
result = "No.";
}
}
else
result = "No.";
}
return result;
}
/**
* Links to the root folder. Only required to generate links to CSS.
*
* @return link
* @todo refactor this. It's copied more or less from InfoTagsHandler
* @doc.tag type="content"
*/
public String rootlink()
{
return getRootlinkFor(getCurrentClass());
}
/**
* Links to the documentation page of a nested sub-element.
*
* @return link
* @doc.tag type="content"
*/
public String subElementLink()
{
XClass subElementClass = subElement.getSubject().getXClass();
// see if there is a link from config params
AntdocSubTask subtask = ((AntdocSubTask) DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(AntdocSubTask.class)));
String link = (String) subtask.getConfigParamsAsMap().get(subElementClass.getQualifiedName());
if (link == null) {
// we only replace . with / in package. Dots in inner class names are replaced by $
link = getRootlinkFor(docElement.getXClass()) + subElementClass.getContainingPackage().getName().replace('.', '/')
+ '/' + subElementClass.getTransformedName() + ".html";
}
return link;
}
/**
* List the possible values for the current method. The property must be an Ant {@link EnumeratedAttribute}.
*
* @return Comma-separated list of values
* @exception XDocletException
* @doc.tag type="content"
*/
public String enumerateValues() throws XDocletException
{
String ret = "";
xjavadoc.XMethod method = getCurrentMethod();
if (method != null) {
xjavadoc.Type type = method.getPropertyType();
if (type != null) {
try {
StringBuffer sb = new StringBuffer();
String className = type.getType().getTransformedQualifiedName();
EnumeratedAttribute enumClass = (EnumeratedAttribute) Class.forName(className).newInstance();
String[] values = enumClass.getValues();
for (int i = 0; i < values.length; i++) {
if (i > 0)
sb.append(", ");
sb.append(values[i]);
}
ret = sb.toString();
}
catch (ClassCastException e) {
throw new XDocletException(e, e.getMessage());
//ignore
}
catch (ClassNotFoundException e) {
throw new XDocletException(e, e.getMessage());
//ignore
}
catch (IllegalAccessException e) {
throw new XDocletException(e, e.getMessage());
//ignore
}
catch (InstantiationException e) {
throw new XDocletException(e, e.getMessage());
//ignore
}
}
}
return ret;
}
private String getRootlinkFor(XClass clazz)
{
StringTokenizer st = new StringTokenizer(clazz.getQualifiedName(), ".");
int n = st.countTokens() - 1;
StringBuffer sbuf = new StringBuffer();
for (int i = 0; i < n; i++) {
sbuf.append("../");
}
return sbuf.toString();
}
}