FileDocCategorySizeDatePackage
ReportDataModel.javaAPI DocAndroid 1.5 API7464Wed May 06 22:41:16 BST 2009com.vladium.emma.report

ReportDataModel

public final class ReportDataModel extends Object implements IReportDataModel
author
Vlad Roubtsov, (C) 2003

Fields Summary
private final com.vladium.emma.data.IMetaData
m_mdata
private final com.vladium.emma.data.ICoverageData
m_cdata
private final IReportDataView[]
m_views
Constructors Summary
ReportDataModel(com.vladium.emma.data.IMetaData mdata, com.vladium.emma.data.ICoverageData cdata)

        if (mdata == null) throw new IllegalArgumentException ("null input: mdata");
        if (cdata == null) throw new IllegalArgumentException ("null input: cdata");
        
        m_views = new IReportDataView [2];
        
        // TODO: report generators work off data model views only; I should deref
        // mdata and cdata as soon as all possible views have been constructed and cached
        
        m_mdata = mdata;
        m_cdata = cdata;
    
Methods Summary
public synchronized IReportDataViewgetView(int viewType)

        // TODO: merge the two branches together
        
        if (viewType >= m_views.length) throw new IllegalArgumentException ("invalid viewType: " + viewType);
        
        IReportDataView view = m_views [viewType];
        
        if (view != null)
            return view;
        else
        {
            final boolean srcView = viewType == IReportDataView.HIER_SRC_VIEW;
            
            if (srcView && ! m_mdata.hasSrcFileData ())
                throw new IllegalStateException ("source file data view requested for metadata with incomplete SourceFile debug info");

            final AllItem root = new AllItem ();
            final Map /* String(pkg name) -> PackageItem */ packageMap = new HashMap ();
            final Map /* String(pkg-prefixed src file name) -> ClassItem */ srcfileMap = new HashMap ();
            
            for (Iterator /* ClassDescriptor */ descriptors = m_mdata.iterator (); descriptors.hasNext (); )
            {    
                final ClassDescriptor cls = (ClassDescriptor) descriptors.next ();
                String packageVMName = cls.getPackageVMName ();
                
                PackageItem packageItem = (PackageItem) packageMap.get (packageVMName);
                if (packageItem == null)
                {
                    final String packageName = packageVMName.length () == 0 ? "default package" : Descriptors.vmNameToJavaName (packageVMName); 
                    packageItem = new PackageItem (root, packageName, packageVMName);
                    packageMap.put (packageVMName, packageItem);
                    
                    root.addChild (packageItem);
                }
                
                SrcFileItem srcfileItem = null;
                if (srcView)
                {                
                    final String srcFileName = cls.getSrcFileName ();
                    if ($assert.ENABLED) $assert.ASSERT (srcFileName != null, "src file name = null");
                    
                    final String fullSrcFileName = Descriptors.combineVMName (packageVMName, srcFileName);
                    
                    srcfileItem = (SrcFileItem) srcfileMap.get (fullSrcFileName);
                    if (srcfileItem == null)
                    {
                        srcfileItem = new SrcFileItem (packageItem, srcFileName, fullSrcFileName);
                        srcfileMap.put (fullSrcFileName, srcfileItem);
                        
                        packageItem.addChild (srcfileItem);
                    }
                }
                
                final ICoverageData.DataHolder data = m_cdata.getCoverage (cls);
                
                // check metadata and coverage data consistency:
                
                if (data != null)
                {
                    if (data.m_stamp != cls.getStamp ())
                        throw new EMMARuntimeException (IAppErrorCodes.CLASS_STAMP_MISMATCH,
                                                        new Object [] { Descriptors.vmNameToJavaName (cls.getClassVMName ()) }); 
                }
                
                final boolean [][] coverage = data != null ? data.m_coverage : null;
                
                if ($assert.ENABLED) $assert.ASSERT (! srcView || srcfileItem != null, "null srcfileItem");
                
                final ClassItem classItem = srcView ? new ClassItem (srcfileItem, cls, coverage) : new ClassItem (packageItem, cls, coverage);
                final MethodDescriptor [] methods = cls.getMethods ();
                
                // TODO: handle edge case when all methods of a class have METHOD_NO_BLOCK_DATA set
                for (int m = 0; m < methods.length; ++ m)
                {
                    final MethodDescriptor method = methods [m];
                        
                    if ((method.getStatus () & IMetadataConstants.METHOD_NO_BLOCK_DATA) != 0) continue;
                    
                    // TODO: wouldn't it be more consistent to simply pass the entire descriptor into MethodItems? (eval mem savings)
                    final MethodItem methodItem = new MethodItem (classItem, m, method.getName (), method.getDescriptor (), method.getFirstLine ());                    
                    // TODO: need to fold class's name into a method name prefix for collapsing case [only when it is not the same as the file name]
                    
                    classItem.addChild (methodItem);
                }
                
                if (srcView)
                    srcfileItem.addChild (classItem);
                else
                    packageItem.addChild (classItem);
            }
            
            view = new ReportDataView (root);
            
            m_views [viewType] = view;
            return view;
        }