1 5 package xdoclet.modules.doc; 6 7 import java.beans.Introspector ; 8 9 import java.util.*; 10 11 import xjavadoc.*; 12 13 import xdoclet.TemplateSubTask; 14 import xdoclet.XDocletException; 15 import xdoclet.template.TemplateEngine; 16 import xdoclet.template.TemplateException; 17 18 28 public class AntdocSubTask extends TemplateSubTask 29 { 30 private static String ANTDOC_TEMPLATE_FILE = "resources/antdoc-xdoc.xdt"; 31 32 39 protected final Map classToAntElementMap = new HashMap(); 40 41 private final Set alreadyRecursed = new HashSet(); 42 43 public String getDestinationFile() 44 { 45 return "{0}.xml"; 46 } 47 48 public void init(XJavaDoc xJavaDoc) throws XDocletException 49 { 50 super.init(xJavaDoc); 51 52 if (getTemplateURL() == null) { 53 setTemplateURL(getClass().getResource(ANTDOC_TEMPLATE_FILE)); 54 } 55 56 discoverTasks(); 58 59 discoverDynamicElements(); 61 62 discoverChildElements(); 64 } 65 66 public void validateOptions() throws XDocletException 67 { 68 } 70 71 protected boolean processInnerClasses() 72 { 73 return true; 74 } 75 76 protected void generateForClass(XClass clazz) throws XDocletException 77 { 78 Element element = (Element) classToAntElementMap.get(clazz); 79 AntdocTagsHandler antdocTagsHandler = null; 80 81 try { 82 antdocTagsHandler = (AntdocTagsHandler) TemplateEngine.getEngineInstance().getTagHandlerFor("Antdoc"); 83 } 84 catch (TemplateException e) { 85 throw new XDocletException(e.getMessage()); 86 } 87 antdocTagsHandler.setDocElement(element); 88 super.generateForClass(clazz); 89 } 90 91 protected boolean matchesGenerationRules(XClass clazz) throws XDocletException 92 { 93 boolean result = classToAntElementMap.containsKey(clazz); 95 96 return result; 97 } 98 99 105 private Element getElement(XClass clazz) 106 { 107 Element element = (Element) classToAntElementMap.get(clazz); 108 109 if (element == null) { 110 element = new Element(clazz); 111 112 classToAntElementMap.put(clazz, element); 113 } 114 return element; 115 } 116 117 122 private void discoverTasks() 123 { 124 Collection classes = getXJavaDoc().getSourceClasses(); 126 127 for (Iterator i = classes.iterator(); i.hasNext(); ) { 128 XClass clazz = (XClass) i.next(); 129 130 if ((clazz.isA("org.apache.tools.ant.Task") || clazz.isA("org.apache.tools.ant.types.DataType")) && !clazz.isAbstract() && clazz.isPublic()) { 131 getElement(clazz); 132 } 134 } 135 } 136 137 140 private void discoverDynamicElements() 141 { 142 Collection classes = getXJavaDoc().getSourceClasses(); 143 144 for (Iterator i = classes.iterator(); i.hasNext(); ) { 145 XClass child = (XClass) i.next(); 146 XDoc doc = child.getDoc(); 147 148 String parentClassName = doc.getTagAttributeValue("ant.element", "parent"); 149 String elementName = doc.getTagAttributeValue("ant.element", "name"); 150 151 if (parentClassName != null) { 152 XClass parent = getXJavaDoc().getXClass(parentClassName); 153 154 if (parent.isA("org.apache.tools.ant.DynamicConfigurator")) { 155 Element childElement = getElement(child); 157 Element parentElement = getElement(parent); 158 SubElement subElement = new SubElement(childElement, null, elementName); 159 160 parentElement.addSubElement(subElement); 161 } 162 } 163 } 164 } 165 166 private void discoverChildElements() 167 { 168 List soFar = Arrays.asList(classToAntElementMap.values().toArray()); 171 172 for (Iterator i = soFar.iterator(); i.hasNext(); ) { 173 Element element = (Element) i.next(); 174 175 addChidrenRecursive(element); 176 } 177 } 178 179 private void addChidrenRecursive(Element element) 180 { 181 Collection methods = element.getXClass().getMethods(true); 182 183 for (Iterator i = methods.iterator(); i.hasNext(); ) { 184 XMethod method = (XMethod) i.next(); 185 186 addChildElementMaybe(element, method); 187 } 188 } 189 190 private void addChildElementMaybe(Element parentElement, XMethod method) 191 { 192 XClass clazz = null; 193 String name = null; 194 195 if (method.isPublic()) { 196 if (method.getName().startsWith("create") && method.getParameters().size() == 0 && method.getReturnType().getDimension() == 0) { 197 clazz = method.getReturnType().getType(); 199 name = Introspector.decapitalize(method.getName().substring(6)); 200 } 201 else if (method.getName().startsWith("addConfigured") && method.getParameters().size() == 1 && method.getReturnType().getType().getQualifiedName().equals("void")) { 202 clazz = ((XParameter) method.getParameters().iterator().next()).getType(); 204 name = Introspector.decapitalize(method.getName().substring(13)); 205 } 206 else if (method.getName().startsWith("add") && method.getParameters().size() == 1 && method.getReturnType().getType().getQualifiedName().equals("void")) { 207 clazz = ((XParameter) method.getParameters().iterator().next()).getType(); 209 name = Introspector.decapitalize(method.getName().substring(3)); 210 } 211 } 212 if (clazz != null) { 213 214 Element element = getElement(clazz); 215 SubElement subElement = new SubElement(element, method, name); 216 217 parentElement.addSubElement(subElement); 218 219 if (!alreadyRecursed.contains(clazz)) { 221 alreadyRecursed.add(clazz); 222 addChidrenRecursive(element); 223 } 224 } 225 } 226 227 233 public class Element 234 { 235 private final String TASK = "task"; 236 private final String SUBTASK = "subtask"; 237 private final SortedSet subElements = new TreeSet(); 238 239 private XClass clazz; 240 241 244 public Element(XClass clazz) 245 { 246 this.clazz = clazz; 247 } 248 249 public Collection getSubElements() 250 { 251 return subElements; 252 } 253 254 public XClass getXClass() 255 { 256 return clazz; 257 } 258 259 public String getName() 260 { 261 String elementName = getXClass().getDoc().getTagAttributeValue("ant.element", "name"); 262 263 if (elementName == null) { 264 String classNameDecapitalized = clazz.getName().toLowerCase(); 265 266 if (classNameDecapitalized.endsWith(SUBTASK)) { 267 elementName = classNameDecapitalized.substring(0, classNameDecapitalized.length() - SUBTASK.length()); 268 } 269 else if (classNameDecapitalized.endsWith(TASK)) { 270 elementName = classNameDecapitalized.substring(0, classNameDecapitalized.length() - TASK.length()); 271 } 272 else { 273 elementName = classNameDecapitalized; 274 } 275 } 276 return elementName; 277 } 278 279 public void addSubElement(SubElement subElement) 280 { 281 subElements.add(subElement); 282 } 283 284 public String toString() 285 { 286 return clazz.getQualifiedName() + "(" + clazz.getClass().getName() + ")"; 287 } 288 289 public boolean equals(Object o) 290 { 291 292 return o == this; 293 } 294 295 public int hashCode() 296 { 297 return toString().hashCode(); 298 } 299 } 300 301 304 public class SubElement implements Comparable 305 { 306 private final Element subject; 307 private final String name; 308 private final XMethod method; 309 310 public SubElement(Element subject, XMethod method, String name) 311 { 312 this.subject = subject; 313 this.name = name; 314 this.method = method; 315 } 316 317 public Element getSubject() 318 { 319 return subject; 320 } 321 322 public String getName() 323 { 324 return name; 325 } 326 327 public boolean isDynamicSubElement() 328 { 329 return method == null; 330 } 331 332 public XClass getXClass() 333 { 334 return getSubject().getXClass(); 335 } 336 337 public String getDescription() 338 { 339 if (isDynamicSubElement() == false) { 340 return method.getDoc().getCommentText(); 342 } 343 else { 344 return getXClass().getDoc().getFirstSentence(); 346 } 347 } 348 349 public int compareTo(Object o) 350 { 351 SubElement other = (SubElement) o; 352 353 return getName().compareTo(other.getName()); 354 } 355 } 356 } 357 | Popular Tags |