Coverage Report - com.thoughtworks.qdox.model.ModelBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
ModelBuilder
100%
134/134
N/A
2.062
 
 1  
 package com.thoughtworks.qdox.model;
 2  
 
 3  
 import java.util.ArrayList;
 4  
 import java.util.HashMap;
 5  
 import java.util.Iterator;
 6  
 import java.util.LinkedList;
 7  
 import java.util.List;
 8  
 import java.util.Map;
 9  
 import java.util.Set;
 10  
 
 11  
 import com.thoughtworks.qdox.parser.Builder;
 12  
 import com.thoughtworks.qdox.parser.structs.AnnoDef;
 13  
 import com.thoughtworks.qdox.parser.structs.ClassDef;
 14  
 import com.thoughtworks.qdox.parser.structs.FieldDef;
 15  
 import com.thoughtworks.qdox.parser.structs.MethodDef;
 16  
 import com.thoughtworks.qdox.parser.structs.TagDef;
 17  
 
 18  
 /**
 19  
  * @author <a href="mailto:joew@thoughtworks.com">Joe Walnes</a>
 20  
  */
 21  
 public class ModelBuilder implements Builder {
 22  
 
 23  
     private final ClassLibrary classLibrary;
 24  
     private final JavaSource source;
 25  
     private JavaClassParent currentParent;
 26  
     private JavaClass currentClass;
 27  
     private List currentAnnoDefs;
 28  
     private String lastComment;
 29  
     private List lastTagSet;
 30  
     private DocletTagFactory docletTagFactory;
 31  
 
 32  
     public ModelBuilder() {
 33  46
         this(new ClassLibrary(null), new DefaultDocletTagFactory());
 34  46
     }
 35  
 
 36  314
     public ModelBuilder(ClassLibrary classLibrary, DocletTagFactory docletTagFactory) {
 37  314
         this.classLibrary = classLibrary;
 38  314
         this.docletTagFactory = docletTagFactory;
 39  314
         source = new JavaSource();
 40  314
         source.setClassLibrary(classLibrary);
 41  314
         currentParent = source;
 42  314
         currentAnnoDefs = new ArrayList();
 43  314
     }
 44  
 
 45  
     public void addPackage(String packageName) {
 46  206
         source.setPackage(packageName);
 47  206
     }
 48  
 
 49  
     public void addImport(String importName) {
 50  207
         source.addImport(importName);
 51  207
     }
 52  
 
 53  
     public void addJavaDoc(String text) {
 54  117
         lastComment = text;
 55  117
         lastTagSet = new LinkedList();
 56  117
     }
 57  
 
 58  
     public void addJavaDocTag(TagDef tagDef) {
 59  121
         lastTagSet.add(tagDef);
 60  121
     }
 61  
 
 62  
     public void beginClass(ClassDef def) {
 63  337
         currentClass = new JavaClass();
 64  337
         currentClass.setParent(currentParent);
 65  337
         currentClass.setLineNumber(def.lineNumber);
 66  
 
 67  
         // basic details
 68  337
         currentClass.setName(def.name);
 69  337
         currentClass.setInterface(ClassDef.INTERFACE.equals(def.type));
 70  337
         currentClass.setEnum(ClassDef.ENUM.equals(def.type));
 71  337
         currentClass.setAnnotation(ClassDef.ANNOTATION_TYPE.equals(def.type));
 72  
 
 73  
 
 74  
         // superclass
 75  337
         if (currentClass.isInterface()) {
 76  53
             currentClass.setSuperClass(null);
 77  53
         } else if (!currentClass.isEnum()) {
 78  275
             currentClass.setSuperClass(def.extendz.size() > 0 ? createType((String) def.extendz.toArray()[0], 0) : null);
 79  
         }
 80  
 
 81  
         // implements
 82  
         {
 83  337
             Set implementSet = currentClass.isInterface() ? def.extendz : def.implementz;
 84  337
             Iterator implementIt = implementSet.iterator();
 85  337
             Type[] implementz = new Type[implementSet.size()];
 86  418
             for (int i = 0; i < implementz.length && implementIt.hasNext(); i++) {
 87  81
                 implementz[i] = createType((String) implementIt.next(), 0);
 88  
             }
 89  337
             currentClass.setImplementz(implementz);
 90  
         }
 91  
 
 92  
         // modifiers
 93  
         {
 94  337
             String[] modifiers = new String[def.modifiers.size()];
 95  337
             def.modifiers.toArray(modifiers);
 96  337
             currentClass.setModifiers(modifiers);
 97  
         }
 98  
 
 99  
         // javadoc
 100  337
         addJavaDoc(currentClass);
 101  
 
 102  
 //        // ignore annotation types (for now)
 103  
 //        if (ClassDef.ANNOTATION_TYPE.equals(def.type)) {
 104  
 //                System.out.println( currentClass.getFullyQualifiedName() );
 105  
 //            return;
 106  
 //        }
 107  
 
 108  
         // annotations
 109  337
         setAnnotations( currentClass );
 110  
 
 111  337
         currentParent.addClass(currentClass);
 112  337
         currentParent = currentClass;
 113  337
         classLibrary.add(currentClass.getFullyQualifiedName());
 114  337
     }
 115  
 
 116  
     public void endClass() {
 117  337
         currentParent = currentClass.getParent();
 118  337
         if (currentParent instanceof JavaClass) {
 119  12
             currentClass = (JavaClass) currentParent;
 120  12
         } else {
 121  325
             currentClass = null;
 122  
         }
 123  337
     }
 124  
 
 125  
     private Type createType(String typeName, int dimensions) {
 126  3341
         if (typeName == null || typeName.equals("")) return null;
 127  3170
         return Type.createUnresolved(typeName, dimensions, currentClass);
 128  
     }
 129  
 
 130  
     private void addJavaDoc(AbstractJavaEntity entity) {
 131  2242
         if (lastComment == null) return;
 132  
 
 133  117
         entity.setComment(lastComment);
 134  
         
 135  117
         Iterator tagDefIterator = lastTagSet.iterator();
 136  117
         List tagList = new ArrayList();
 137  238
         while (tagDefIterator.hasNext()) {
 138  121
             TagDef tagDef = (TagDef) tagDefIterator.next();
 139  121
             tagList.add( 
 140  
                 docletTagFactory.createDocletTag(
 141  
                     tagDef.name, tagDef.text, 
 142  
                     entity, tagDef.lineNumber
 143  
                 )
 144  
             );
 145  121
         }
 146  117
         entity.setTags(tagList);
 147  
         
 148  117
         lastComment = null;
 149  117
     }
 150  
 
 151  
     public void addMethod(MethodDef def) {
 152  1727
         JavaMethod currentMethod = new JavaMethod();
 153  1727
         currentMethod.setParentClass(currentClass);
 154  1727
         currentMethod.setLineNumber(def.lineNumber);
 155  
 
 156  
         // basic details
 157  1727
         currentMethod.setName(def.name);
 158  1727
         currentMethod.setReturns(createType(def.returns, def.dimensions));
 159  1727
         currentMethod.setConstructor(def.constructor);
 160  
 
 161  
         // parameters
 162  
         {
 163  1727
             JavaParameter[] params = new JavaParameter[def.params.size()];
 164  1727
             int i = 0;
 165  1727
             for (Iterator iterator = def.params.iterator(); iterator.hasNext();) {
 166  1007
                 FieldDef fieldDef = (FieldDef) iterator.next();
 167  1007
                 params[i++] = new JavaParameter(createType(fieldDef.type, fieldDef.dimensions), fieldDef.name, fieldDef.isVarArgs);
 168  1007
             }
 169  1727
             currentMethod.setParameters(params);
 170  
         }
 171  
 
 172  
         // exceptions
 173  
         {
 174  1727
             Type[] exceptions = new Type[def.exceptions.size()];
 175  1727
             int index = 0;
 176  1727
             for (Iterator iter = def.exceptions.iterator(); iter.hasNext();) {
 177  282
                 exceptions[index++] = createType((String) iter.next(), 0);
 178  282
             }
 179  1727
             currentMethod.setExceptions(exceptions);
 180  
         }
 181  
 
 182  
         // modifiers
 183  
         {
 184  1727
             String[] modifiers = new String[def.modifiers.size()];
 185  1727
             def.modifiers.toArray(modifiers);
 186  1727
             currentMethod.setModifiers(modifiers);
 187  
         }
 188  
         
 189  1727
         currentMethod.setSourceCode(def.body);
 190  
 
 191  
         // javadoc
 192  1727
         addJavaDoc(currentMethod);
 193  
 
 194  
         // annotations
 195  1727
         setAnnotations( currentMethod );
 196  
 
 197  1727
         currentClass.addMethod(currentMethod);
 198  1727
     }
 199  
 
 200  
     public void addField(FieldDef def) {
 201  178
         JavaField currentField = new JavaField();
 202  178
         currentField.setParent(currentClass);
 203  178
         currentField.setLineNumber(def.lineNumber);
 204  
 
 205  178
         currentField.setName(def.name);
 206  178
         currentField.setType(createType(def.type, def.dimensions));
 207  
 
 208  
         // modifiers
 209  
         {
 210  178
             String[] modifiers = new String[def.modifiers.size()];
 211  178
             def.modifiers.toArray(modifiers);
 212  178
             currentField.setModifiers(modifiers);
 213  
         }
 214  
         
 215  
         // code body
 216  178
         currentField.setInitializationExpression(def.body);
 217  
         
 218  
         // javadoc
 219  178
         addJavaDoc(currentField);
 220  
 
 221  
         // annotations
 222  178
         setAnnotations( currentField );
 223  
 
 224  178
         currentClass.addField(currentField);
 225  178
     }
 226  
 
 227  
     private void setAnnotations( AbstractJavaEntity entity ) {
 228  2242
         if( !currentAnnoDefs.isEmpty() ) {
 229  17
             Annotation[] annotations = new Annotation[currentAnnoDefs.size()];
 230  17
             int index = 0;
 231  17
             for (Iterator iter = currentAnnoDefs.iterator(); iter.hasNext();) {
 232  21
                     AnnoDef def = (AnnoDef)iter.next();
 233  21
                     annotations[index++] = buildAnnotation( def, entity );
 234  21
             }
 235  
 
 236  17
             entity.setAnnotations( annotations );
 237  17
             currentAnnoDefs.clear();
 238  
         }
 239  2242
     }
 240  
 
 241  
     private Annotation buildAnnotation( AnnoDef def, AbstractJavaEntity entity ) {
 242  24
             Type annoType = createType(def.name, 0);
 243  
 
 244  24
             Map args = new HashMap();
 245  24
         for (Iterator iter = def.args.entrySet().iterator(); iter.hasNext();) {
 246  21
                 Map.Entry entry = (Map.Entry)iter.next();
 247  21
                 Object value = entry.getValue();
 248  
 
 249  21
                 if( value instanceof AnnoDef ) {
 250  3
                         args.put( entry.getKey(), buildAnnotation( (AnnoDef)value, entity ) );
 251  3
                 }
 252  18
                 else if( value instanceof List ) {
 253  18
                         List values = (List)value;
 254  18
                         if( values.size() == 1 ) {
 255  
                                 // TODO: what about types?
 256  14
                                 args.put( entry.getKey(), values.get( 0 ) );
 257  14
                         }
 258  
                         else {
 259  4
                                 args.put( entry.getKey(), values );
 260  
                         }
 261  
                 }
 262  21
         }
 263  
 
 264  24
             Annotation anno = new Annotation( annoType, entity, args, def.lineNumber );
 265  24
         return anno;
 266  
     }
 267  
 
 268  
 
 269  
     // Don't resolve until we need it... class hasn't been defined yet.
 270  
     public void addAnnotation( AnnoDef def ) {
 271  22
             currentAnnoDefs.add( def );
 272  22
     }
 273  
 
 274  
     public JavaSource getSource() {
 275  313
         return source;
 276  
     }
 277  
 
 278  
 }