View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/Tag.java,v 1.6 2002/05/17 15:18:12 jstrachan Exp $ 3 * $Revision: 1.6 $ 4 * $Date: 2002/05/17 15:18:12 $ 5 * 6 * ==================================================================== 7 * 8 * The Apache Software License, Version 1.1 9 * 10 * Copyright (c) 1999-2002 The Apache Software Foundation. All rights 11 * reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in 22 * the documentation and/or other materials provided with the 23 * distribution. 24 * 25 * 3. The end-user documentation included with the redistribution, if 26 * any, must include the following acknowlegement: 27 * "This product includes software developed by the 28 * Apache Software Foundation (http://www.apache.org/)." 29 * Alternately, this acknowlegement may appear in the software itself, 30 * if and wherever such third-party acknowlegements normally appear. 31 * 32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 33 * Foundation" must not be used to endorse or promote products derived 34 * from this software without prior written permission. For written 35 * permission, please contact apache@apache.org. 36 * 37 * 5. Products derived from this software may not be called "Apache" 38 * nor may "Apache" appear in their names without prior written 39 * permission of the Apache Group. 40 * 41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 * SUCH DAMAGE. 53 * ==================================================================== 54 * 55 * This software consists of voluntary contributions made by many 56 * individuals on behalf of the Apache Software Foundation. For more 57 * information on the Apache Software Foundation, please see 58 * <http://www.apache.org/>;. 59 * 60 * $Id: Tag.java,v 1.6 2002/05/17 15:18:12 jstrachan Exp $ 61 */ 62 63 package org.apache.commons.jelly.util; 64 65 import com.sun.javadoc.*; 66 67 import java.beans.Introspector; 68 import java.io.*; 69 import java.util.*; 70 71 import org.cyberneko.html.parsers.SAXParser; 72 73 import org.dom4j.io.OutputFormat; 74 import org.dom4j.io.XMLWriter; 75 76 import org.xml.sax.*; 77 import org.xml.sax.helpers.*; 78 79 /*** 80 * Main Doclet class to generate Tag Library ML. 81 * 82 * @author <a href="mailto:gopi@aztecsoft.com">Gopinath M.R.</a> 83 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> 84 */ 85 86 // #### somehow we need to handle taglib inheritence... 87 88 public class TagXMLDoclet extends Doclet { 89 90 private String xmlns = "jvx"; 91 private String encodingFormat="UTF-8"; 92 private String localName = "javadoc"; 93 private ContentHandler cm = null; 94 private String targetFileName="target/taglib.xml"; 95 private Attributes emptyAtts = new AttributesImpl(); 96 97 public TagXMLDoclet (RootDoc root) throws Exception { 98 FileOutputStream writer = new FileOutputStream(targetFileName); 99 OutputFormat format = OutputFormat.createPrettyPrint(); 100 XMLWriter xmlWriter = new XMLWriter(writer, format); 101 try { 102 cm = xmlWriter; 103 cm.startDocument(); 104 javadocXML(root); 105 cm.endDocument(); 106 xmlWriter.close(); 107 } 108 catch (IOException e) { 109 xmlWriter.close(); 110 throw e; 111 } 112 } 113 114 /*** 115 * Generates the xml for the tag libraries 116 */ 117 private void javadocXML(RootDoc root) throws SAXException { 118 cm.startElement(xmlns, localName, "tags", emptyAtts); 119 PackageDoc[] packageArray = root.specifiedPackages(); 120 121 // Generate for packages. 122 for (int i = 0; i < packageArray.length; ++i) { 123 packageXML(packageArray[i]); 124 } 125 126 cm.endElement(xmlns, localName, "tags"); 127 } 128 129 /*** 130 * Generates doc for a tag library 131 */ 132 private void packageXML(PackageDoc packageDoc) throws SAXException { 133 ClassDoc[] classArray = packageDoc.ordinaryClasses(); 134 135 // lets see if we find a Tag 136 boolean foundTag = false; 137 for (int i = 0; i < classArray.length; ++i) { 138 ClassDoc classDoc = classArray[i]; 139 if ( isTag( classArray[i] ) ) { 140 foundTag = true; 141 break; 142 } 143 } 144 if ( ! foundTag ) { 145 return; 146 } 147 148 AttributesImpl atts = new AttributesImpl(); 149 atts.addAttribute(xmlns, localName, "name", "String", packageDoc.name()); 150 151 String name = packageDoc.name(); 152 int idx = name.lastIndexOf('.'); 153 if ( idx > 0 ) { 154 name = name.substring(idx+1); 155 } 156 atts.addAttribute(xmlns, localName, "prefix", "String", name); 157 158 String uri = "jelly:" + name; 159 160 atts.addAttribute(xmlns, localName, "uri", "String", uri ); 161 cm.startElement(xmlns, localName, "library", atts); 162 163 // generate Doc element. 164 docXML(packageDoc); 165 166 // generate tags 167 for (int i = 0; i < classArray.length; ++i) { 168 if ( isTag( classArray[i] ) ) { 169 tagXML(classArray[i]); 170 } 171 } 172 cm.endElement(xmlns, localName, "library"); 173 } 174 175 /*** 176 * @return true if this class is a Jelly Tag 177 */ 178 private boolean isTag(ClassDoc classDoc) { 179 ClassDoc[] interfaceArray = classDoc.interfaces(); 180 for (int i = 0; i < interfaceArray.length; ++i) { 181 String name = interfaceArray[i].qualifiedName(); 182 if ("org.apache.commons.jelly.Tag".equals(name)) { 183 return true; 184 } 185 } 186 ClassDoc base = classDoc.superclass(); 187 if ( base != null ) { 188 return isTag(base); 189 } 190 return false; 191 } 192 193 /*** 194 * Generates doc for a tag 195 */ 196 private void tagXML(ClassDoc classDoc) throws SAXException { 197 if (classDoc.isAbstract()) { 198 return; 199 } 200 201 AttributesImpl atts = new AttributesImpl(); 202 atts.addAttribute(xmlns, localName, "className", "String", classDoc.name()); 203 String name = classDoc.name(); 204 if ( name.endsWith( "Tag" ) ) { 205 name = name.substring(0, name.length() - 3 ); 206 } 207 name = Introspector.decapitalize(name); 208 209 atts.addAttribute(xmlns, localName, "name", "String", name); 210 cm.startElement(xmlns, localName, "tag", atts); 211 212 // generate "doc" sub-element 213 docXML(classDoc); 214 215 // generate the attributes 216 propertiesXML(classDoc); 217 218 // generate "method" sub-elements 219 cm.endElement(xmlns, localName, "tag"); 220 } 221 222 /*** 223 * Generates doc for a tag property 224 */ 225 private void propertiesXML(ClassDoc classDoc) throws SAXException { 226 MethodDoc[] methodArray = classDoc.methods(); 227 for (int i = 0; i < methodArray.length; ++i) { 228 propertyXML(methodArray[i]); 229 } 230 ClassDoc base = classDoc.superclass(); 231 if ( base != null ) { 232 propertiesXML( base ); 233 } 234 } 235 236 237 /*** 238 * Generates doc for a tag property 239 */ 240 private void propertyXML(MethodDoc methodDoc) throws SAXException { 241 if ( ! methodDoc.isPublic() || methodDoc.isStatic() ) { 242 return; 243 } 244 String name = methodDoc.name(); 245 if ( ! name.startsWith( "set" ) ) { 246 return; 247 } 248 Parameter[] parameterArray = methodDoc.parameters(); 249 if ( parameterArray == null || parameterArray.length != 1 ) { 250 return; 251 } 252 Parameter parameter = parameterArray[0]; 253 254 name = name.substring(3); 255 name = Introspector.decapitalize(name); 256 257 if ( name.equals( "body") || name.equals( "context" ) || name.equals( "parent" ) ) { 258 return; 259 } 260 AttributesImpl atts = new AttributesImpl(); 261 atts.addAttribute(xmlns, localName, "name", "String", name); 262 atts.addAttribute(xmlns, localName, "type", "String", parameter.typeName()); 263 264 cm.startElement(xmlns, localName, "attribute", atts); 265 266 // maybe do more semantics, like use custom tags to denote if its required, optional etc. 267 268 // generate "doc" sub-element 269 docXML(methodDoc); 270 271 cm.endElement(xmlns, localName, "attribute"); 272 } 273 274 /*** 275 * Generates doc for element "doc" 276 */ 277 private void docXML(Doc doc) throws SAXException { 278 cm.startElement(xmlns, localName, "doc", emptyAtts); 279 String commentText = doc.commentText(); 280 if (! commentText.equals("")) { 281 parseHTML(commentText); 282 // cm.characters(commentText.toCharArray(), 0, commentText.length()); 283 } 284 Tag[] tags = doc.tags(); 285 for (int i = 0; i < tags.length; ++i) { 286 javadocTagXML(tags[i]); 287 } 288 cm.endElement(xmlns, localName, "doc"); 289 /* 290 String commentText = ""; 291 boolean createDoc = false; 292 commentText = doc.commentText(); 293 if (! commentText.equals("")) { 294 createDoc = true; 295 } 296 Tag[] tags = doc.tags(); 297 if (tags.length > 0) { 298 createDoc = true; 299 } 300 if (createDoc) { 301 cm.startElement(xmlns, localName, "doc", emptyAtts); 302 if (! commentText.equals("")) { 303 cm.characters(commentText.toCharArray(), 0, commentText.length()); 304 } 305 for (int i = 0; i < tags.length; ++i) { 306 javadocTagXML(tags[i]); 307 } 308 cm.endElement(xmlns, localName, "doc"); 309 } 310 */ 311 } 312 313 protected void parseHTML(String text) throws SAXException { 314 SAXParser parser = new SAXParser(); 315 parser.setProperty( 316 "http://cyberneko.org/html/properties/names/elems", 317 "lower" 318 ); 319 parser.setProperty( 320 "http://cyberneko.org/html/properties/names/attrs", 321 "lower" 322 ); 323 parser.setContentHandler( 324 new DefaultHandler() { 325 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 326 if ( validDocElementName( localName ) ) { 327 cm.startElement(namespaceURI, localName, qName, atts); 328 } 329 } 330 public void endElement(String namespaceURI, String localName, String qName) throws SAXException { 331 if ( validDocElementName( localName ) ) { 332 cm.endElement(namespaceURI, localName, qName); 333 } 334 } 335 public void characters(char[] ch, int start, int length) throws SAXException { 336 cm.characters(ch, start, length); 337 } 338 } 339 ); 340 try { 341 parser.parse( new InputSource(new StringReader( text )) ); 342 } 343 catch (IOException e) { 344 System.err.println( "This should never happen!" + e ); 345 } 346 } 347 348 /*** 349 * @return true if the given name is a valid HTML markup element. 350 */ 351 protected boolean validDocElementName(String name) { 352 return ! name.equalsIgnoreCase( "html" ) && ! name.equalsIgnoreCase( "body" ); 353 } 354 355 /*** 356 * Generates doc for all tag elements. 357 */ 358 private void javadocTagXML(Tag tag) throws SAXException { 359 String name = tag.name().substring(1) + "tag"; 360 if (! tag.text().equals("")) { 361 cm.startElement(xmlns, localName, name, emptyAtts); 362 cm.characters(tag.text().toCharArray(), 0, tag.text().length()); 363 cm.endElement(xmlns, localName, name); 364 } 365 } 366 367 public static boolean start(RootDoc root) { 368 try { 369 new TagXMLDoclet(root); 370 return true; 371 } catch (Exception e) { 372 e.printStackTrace(); 373 System.exit(1); 374 return false; 375 } 376 } 377 }

This page was automatically generated by Maven