1f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved. 2f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * 3f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * This program and the accompanying materials are made available under 4f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * the terms of the Common Public License v1.0 which accompanies this distribution, 5f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * and is available at http://www.eclipse.org/legal/cpl-v10.html 6f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * 7f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * $Id: ReportDataModel.java,v 1.1.1.1 2004/05/09 16:57:38 vlad_r Exp $ 8f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */ 9f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectpackage com.vladium.emma.report; 10f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 11f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.HashMap; 12f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Iterator; 13f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Map; 14f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 15f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.Descriptors; 16f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.asserts.$assert; 17f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.IAppErrorCodes; 18f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.EMMARuntimeException; 19f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.data.ClassDescriptor; 20f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.data.IMetaData; 21f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.data.IMetadataConstants; 22f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.data.ICoverageData; 23f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.data.MethodDescriptor; 24f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 25f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ---------------------------------------------------------------------------- 26f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/** 27f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * @author Vlad Roubtsov, (C) 2003 28f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */ 29f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectfinal class ReportDataModel implements IReportDataModel 30f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project{ 31f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // public: ................................................................ 32f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 33f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 34f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public synchronized IReportDataView getView (final int viewType) 35f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 36f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO: merge the two branches together 37f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 38f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (viewType >= m_views.length) throw new IllegalArgumentException ("invalid viewType: " + viewType); 39f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 40f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project IReportDataView view = m_views [viewType]; 41f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 42f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (view != null) 43f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return view; 44f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project else 45f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 46f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final boolean srcView = viewType == IReportDataView.HIER_SRC_VIEW; 47f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 48f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (srcView && ! m_mdata.hasSrcFileData ()) 49f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throw new IllegalStateException ("source file data view requested for metadata with incomplete SourceFile debug info"); 50f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 51f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final AllItem root = new AllItem (); 52f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final Map /* String(pkg name) -> PackageItem */ packageMap = new HashMap (); 53f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final Map /* String(pkg-prefixed src file name) -> ClassItem */ srcfileMap = new HashMap (); 54f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 55f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project for (Iterator /* ClassDescriptor */ descriptors = m_mdata.iterator (); descriptors.hasNext (); ) 56f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 57f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final ClassDescriptor cls = (ClassDescriptor) descriptors.next (); 58f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project String packageVMName = cls.getPackageVMName (); 59f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 60f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project PackageItem packageItem = (PackageItem) packageMap.get (packageVMName); 61f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (packageItem == null) 62f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 63f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final String packageName = packageVMName.length () == 0 ? "default package" : Descriptors.vmNameToJavaName (packageVMName); 64f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project packageItem = new PackageItem (root, packageName, packageVMName); 65f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project packageMap.put (packageVMName, packageItem); 66f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 67f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project root.addChild (packageItem); 68f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 69f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 70f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project SrcFileItem srcfileItem = null; 71f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (srcView) 72f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 73f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final String srcFileName = cls.getSrcFileName (); 74f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if ($assert.ENABLED) $assert.ASSERT (srcFileName != null, "src file name = null"); 75f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 76f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final String fullSrcFileName = Descriptors.combineVMName (packageVMName, srcFileName); 77f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 78f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project srcfileItem = (SrcFileItem) srcfileMap.get (fullSrcFileName); 79f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (srcfileItem == null) 80f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 81f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project srcfileItem = new SrcFileItem (packageItem, srcFileName, fullSrcFileName); 82f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project srcfileMap.put (fullSrcFileName, srcfileItem); 83f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 84f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project packageItem.addChild (srcfileItem); 85f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 86f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 87f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 88f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final ICoverageData.DataHolder data = m_cdata.getCoverage (cls); 89f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 90f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // check metadata and coverage data consistency: 91f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 92f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (data != null) 93f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 94f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (data.m_stamp != cls.getStamp ()) 95f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project throw new EMMARuntimeException (IAppErrorCodes.CLASS_STAMP_MISMATCH, 96f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project new Object [] { Descriptors.vmNameToJavaName (cls.getClassVMName ()) }); 97f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 98f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 99f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final boolean [][] coverage = data != null ? data.m_coverage : null; 100f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 101f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if ($assert.ENABLED) $assert.ASSERT (! srcView || srcfileItem != null, "null srcfileItem"); 102f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 103f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final ClassItem classItem = srcView ? new ClassItem (srcfileItem, cls, coverage) : new ClassItem (packageItem, cls, coverage); 104f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final MethodDescriptor [] methods = cls.getMethods (); 105f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 106f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO: handle edge case when all methods of a class have METHOD_NO_BLOCK_DATA set 107f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project for (int m = 0; m < methods.length; ++ m) 108f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 109f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final MethodDescriptor method = methods [m]; 110f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 111f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if ((method.getStatus () & IMetadataConstants.METHOD_NO_BLOCK_DATA) != 0) continue; 112f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 113f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO: wouldn't it be more consistent to simply pass the entire descriptor into MethodItems? (eval mem savings) 114f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project final MethodItem methodItem = new MethodItem (classItem, m, method.getName (), method.getDescriptor (), method.getFirstLine ()); 115f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // 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] 116f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 117f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project classItem.addChild (methodItem); 118f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 119f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 120f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (srcView) 121f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project srcfileItem.addChild (classItem); 122f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project else 123f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project packageItem.addChild (classItem); 124f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 125f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 126f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project view = new ReportDataView (root); 127f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 128f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_views [viewType] = view; 129f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return view; 130f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 131f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 132f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 133f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // protected: ............................................................. 134f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 135f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // package: ............................................................... 136f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 137f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 138f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ReportDataModel (final IMetaData mdata, final ICoverageData cdata) 139f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 140f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (mdata == null) throw new IllegalArgumentException ("null input: mdata"); 141f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project if (cdata == null) throw new IllegalArgumentException ("null input: cdata"); 142f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 143f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_views = new IReportDataView [2]; 144f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 145f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // TODO: report generators work off data model views only; I should deref 146f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // mdata and cdata as soon as all possible views have been constructed and cached 147f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 148f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_mdata = mdata; 149f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_cdata = cdata; 150f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 151f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 152f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project // private: ............................................................... 153f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 154f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 155f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private static final class ReportDataView implements IReportDataView 156f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 157f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project public IItem getRoot() 158f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 159f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project return m_root; 160f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 161f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 162f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project ReportDataView (final IItem root) 163f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project { 164f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project m_root = root; 165f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } 166f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 167f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 168f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final IItem m_root; 169f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 170f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project } // end of nested class 171f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 172f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 173f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final IMetaData m_mdata; 174f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final ICoverageData m_cdata; 175f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 176f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project private final IReportDataView [] m_views; 177f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project 178f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} // end of class 179f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------