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: ReportProperties.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.io.File;
12f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.HashSet;
13f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Set;
14f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.StringTokenizer;
15f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
16f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.Files;
17f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.IProperties;
18f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.IntIntMap;
19f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.IntVector;
20f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.ObjectIntMap;
21f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.Property;
22f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.asserts.$assert;
23f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.IAppErrorCodes;
24f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.EMMARuntimeException;
25f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
26f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------
27f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/**
28f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * @author Vlad Roubtsov, (C) 2003
29f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */
30f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectpublic
31f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectabstract class ReportProperties implements IAppErrorCodes
32f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project{
33f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // public: ................................................................
34f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
35f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
36f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static final IProperties.IMapper REPORT_PROPERTY_MAPPER; // set in <clinit>
37f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
38f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
39f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static final class ParsedProperties
40f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
41f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public void setOutEncoding (final String outEncoding)
42f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
43f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED) $assert.ASSERT (outEncoding != null, "null input: outEncoding");
44f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
45f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_outEncoding = outEncoding;
46f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
47f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
48f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public String getOutEncoding ()
49f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
50f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_outEncoding;
51f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
52f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
53f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public void setOutDir (final File outDir)
54f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
55f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED) $assert.ASSERT (outDir != null, "null input: outDir");
56f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
57f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_outDir = outDir;
58f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
59f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
60f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public File getOutDir ()
61f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
62f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_outDir;
63f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
64f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
65f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public void setOutFile (final File outFile)
66f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
67f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED) $assert.ASSERT (outFile != null, "null input: outFile");
68f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
69f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_outFile = outFile;
70f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
71f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
72f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public File getOutFile ()
73f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
74f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_outFile;
75f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
76f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
77f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public void setUnitsType (final int unitsType)
78f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
79f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED) $assert.ASSERT (unitsType >= IItemAttribute.UNITS_COUNT && unitsType <= IItemAttribute.UNITS_INSTR, "invalid units type: " + unitsType);
80f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
81f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_unitsType = unitsType;
82f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
83f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
84f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public int getUnitsType ()
85f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
86f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_unitsType;
87f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
88f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
89f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public void setViewType (final int viewType)
90f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
91f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED) $assert.ASSERT (viewType >= IReportDataView.HIER_CLS_VIEW && viewType <= IReportDataView.HIER_SRC_VIEW, "invalid view type: " + viewType);
92f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
93f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_viewType = viewType;
94f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
95f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
96f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public int getViewType ()
97f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
98f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_viewType;
99f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
100f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
101f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public void setDepth (final int depth)
102f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
103f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED) $assert.ASSERT (depth >= IItemMetadata.TYPE_ID_ALL && depth <= IItemMetadata.TYPE_ID_METHOD, "invalid depth: " + depth);
104f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
105f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_depth = depth;
106f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
107f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
108f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public int getDepth()
109f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
110f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_depth;
111f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
112f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
113f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public void setHideClasses (final boolean hideClasses)
114f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
115f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_hideClasses = hideClasses;
116f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
117f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
118f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public boolean getHideClasses ()
119f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
120f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_hideClasses;
121f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
122f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
123f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public void setColumnOrder (final int [] columnOrder)
124f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
125f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED) $assert.ASSERT (columnOrder != null && columnOrder.length != 0, "null/empty input: outEncoding");
126f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
127f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_columnOrder = columnOrder;
128f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
129f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
130f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public int [] getColumnOrder ()
131f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
132f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_columnOrder;
133f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
134f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
135f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public void setSortOrder (final int [] sortOrder)
136f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
137f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED) $assert.ASSERT (sortOrder != null, "null input: sortOrder");
138f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
139f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_sortOrder = sortOrder;
140f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
141f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
142f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public int [] getSortOrder ()
143f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
144f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_sortOrder;
145f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
146f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
147f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public void setMetrics (final IntIntMap metrics)
148f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
149f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED) $assert.ASSERT (metrics != null, "null input: metrics");
150f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
151f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_metrics = metrics;
152f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
153f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
154f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public IntIntMap getMetrics ()
155f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
156f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_metrics;
157f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
158f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
159f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // TODO: toString/logging
160f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
161f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        void validate () throws IllegalArgumentException
162f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
163f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED)
164f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
165f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                $assert.ASSERT (m_outEncoding != null, "m_outEncoding not set");
166f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                $assert.ASSERT (m_outDir != null || m_outFile != null, "either m_outDir or m_outFile must be set");
167f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                $assert.ASSERT (m_columnOrder != null, "m_columnOrder not set");
168f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                $assert.ASSERT (m_sortOrder != null, "m_sortOrder not set");
169f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                $assert.ASSERT (m_metrics != null, "m_metrics not set");
170f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
171f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
172f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
173f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
174f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private String m_outEncoding;
175f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private File m_outDir;
176f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private File m_outFile;
177f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
178f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private int m_unitsType;
179f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private int m_viewType;
180f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
181f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private boolean m_hideClasses;
182f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private int m_depth;
183f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
184f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // TODO: fraction/number format strings...
185f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
186f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private int [] m_columnOrder; // attribute IDs [order indicates column order]
187f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private int [] m_sortOrder; // if m_sortOrder[i+1]>0 , sort m_columnOrder[m_sortOrder[i]] in ascending order
188f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private IntIntMap m_metrics; // pass criteria (column attribute ID -> metric)
189f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
190f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    } // end of nested class
191f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
192f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
193f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    /**
194f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//     * Creates a property view specific to 'reportType' report type.
195f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//     *
196f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//     * @param appProperties
197f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//     * @param reportType
198f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//     * @return
199f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//     */
200f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    public static Properties getReportProperties (final Properties appProperties, final String reportType)
201f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    {
202f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        if ((reportType == null) || (reportType.length () == 0))
203f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//             throw new IllegalArgumentException ("null/empty input: reportType");
204f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
205f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        if (appProperties == null) return new XProperties ();
206f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
207f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        return new ReportPropertyLookup (appProperties, reportType);
208f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    }
209f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
210f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
211f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    /**
212f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//     * @param type [null/empty indicates type-neutral property]
213f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//     */
214f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    public static String getReportProperty (final String type, final Map properties, final String key)
215f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    {
216f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        if (properties == null) throw new IllegalArgumentException ("null input: properties");
217f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        if (key == null) throw new IllegalArgumentException ("null input: key");
218f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
219f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        String fullKey;
220f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
221f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        if ((type == null) || (type.length () == 0))
222f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            fullKey = IReportParameters.PREFIX.concat (key);
223f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        else
224f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        {
225f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            fullKey = IReportParameters.PREFIX.concat (type).concat (".").concat (key);
226f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
227f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            if (! properties.containsKey (fullKey)) // default to type-neutral lookup
228f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//                fullKey = IReportParameters.PREFIX.concat (key);
229f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        }
230f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
231f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        return (String) properties.get (fullKey);
232f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    }
233f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
234f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    public static String getReportParameter (final String type, final Map properties, final String key, final String def)
235f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    {
236f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        final String value = getReportProperty (type, properties, key);
237f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
238f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        return (value == null) ? def : value;
239f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    }
240f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
241f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
242f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static ParsedProperties parseProperties (final IProperties properties, final String type)
243f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
244f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if ($assert.ENABLED) $assert.ASSERT (properties != null, "properties = null");
245f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
246f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final ParsedProperties result = new ParsedProperties ();
247f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
248f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result.setOutEncoding (getReportProperty (properties, type, IReportProperties.OUT_ENCODING, false));
249f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
250f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
251f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // TODO: outDirName is no longer supported
252f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
253f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
254f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String outDirName = getReportProperty (properties, type, IReportProperties.OUT_DIR, true);
255f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String outFileName = getReportProperty (properties, type, IReportProperties.OUT_FILE, false);
256f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
257f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // renormalize the out dir and file combination:
258f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
259f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (outFileName != null)
260f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
261f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final File fullOutFile = Files.newFile (outDirName, outFileName);
262f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
263f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final File dir = fullOutFile.getParentFile ();
264f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (dir != null) result.setOutDir (dir);
265f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
266f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.setOutFile (new File (fullOutFile.getName ()));
267f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
268f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else if (outDirName != null)
269f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
270f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.setOutDir (new File (outDirName));
271f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
272f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
273f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
274f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
275f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String unitsType = getReportProperty (properties, type, IReportProperties.UNITS_TYPE, true, IReportProperties.DEFAULT_UNITS_TYPE);
276f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result.setUnitsType (IReportProperties.COUNT_UNITS.equals (unitsType) ? IItemAttribute.UNITS_COUNT : IItemAttribute.UNITS_INSTR);
277f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
278f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // TODO: invalid setting not checked
279f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
280f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
281f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            /* view type is no longer a user-overridable property [it is driven by SourceFile attribute presence]
282f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
283f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String viewType = getReportProperty (properties, type, IReportProperties.VIEW_TYPE, IReportProperties.DEFAULT_VIEW_TYPE);
284f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result.setViewType (IReportProperties.SRC_VIEW.equals (viewType) ? IReportDataView.HIER_SRC_VIEW : IReportDataView.HIER_CLS_VIEW);
285f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            */
286f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
287f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result.setViewType (IReportDataView.HIER_SRC_VIEW);
288f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
289f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
290f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
291f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String hideClasses = getReportProperty (properties, type, IReportProperties.HIDE_CLASSES, true, IReportProperties.DEFAULT_HIDE_CLASSES);
292f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result.setHideClasses (Property.toBoolean (hideClasses));
293f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
294f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // TODO: log this
295f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (result.getViewType () == IReportDataView.HIER_CLS_VIEW)
296f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.setHideClasses (false);
297f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
298f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
299f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String depth = getReportProperty (properties, type, IReportProperties.DEPTH, false, IReportProperties.DEFAULT_DEPTH);
300f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
301f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (IReportProperties.DEPTH_ALL.equals (depth))
302f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.setDepth (AllItem.getTypeMetadata ().getTypeID ());
303f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else if (IReportProperties.DEPTH_PACKAGE.equals (depth))
304f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.setDepth (PackageItem.getTypeMetadata ().getTypeID ());
305f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else if (IReportProperties.DEPTH_SRCFILE.equals (depth))
306f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.setDepth (SrcFileItem.getTypeMetadata ().getTypeID ());
307f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else if (IReportProperties.DEPTH_CLASS.equals (depth))
308f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.setDepth (ClassItem.getTypeMetadata ().getTypeID ());
309f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else if (IReportProperties.DEPTH_METHOD.equals (depth))
310f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.setDepth (MethodItem.getTypeMetadata ().getTypeID ());
311f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else
312f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                // TODO: properly prefixes prop name
313f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                throw new EMMARuntimeException (INVALID_PARAMETER_VALUE, new Object [] {IReportProperties.DEPTH, depth});
314f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
315f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
316f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (result.getHideClasses () &&
317f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project           (result.getViewType () == IReportDataView.HIER_SRC_VIEW) &&
318f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project           (result.getDepth () == IItemMetadata.TYPE_ID_CLASS))
319f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
320f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result.setDepth (IItemMetadata.TYPE_ID_SRCFILE);
321f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
322f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
323f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final Set /* String */ columnNames = new HashSet ();
324f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
325f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String columnList = getReportProperty (properties, type, IReportProperties.COLUMNS, false, IReportProperties.DEFAULT_COLUMNS);
326f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final IntVector _columns = new IntVector ();
327f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
328f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final int [] out = new int [1];
329f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
330f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            for (StringTokenizer tokenizer = new StringTokenizer (columnList, ","); tokenizer.hasMoreTokens (); )
331f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
332f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final String columnName = tokenizer.nextToken ().trim ();
333f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (! COLUMNS.get (columnName, out))
334f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
335f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    // TODO: generate the entire enum list in the err msg
336f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    throw new EMMARuntimeException (INVALID_COLUMN_NAME, new Object [] {columnName});
337f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
338f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
339f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (! REMOVE_DUPLICATE_COLUMNS || ! columnNames.contains (columnName))
340f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
341f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    columnNames.add (columnName);
342f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    _columns.add (out [0]);
343f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
344f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
345f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
346f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result.setColumnOrder (_columns.values ());
347f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
348f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // [assertion: columnNames contains all columns for the report (some
349f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // may get removed later by individual report generators if some debug info
350f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // is missing)]
351f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
352f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
353f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String sortList = getReportProperty (properties, type, IReportProperties.SORT, false, IReportProperties.DEFAULT_SORT);
354f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final IntVector _sort = new IntVector ();
355f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
356f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final int [] out = new int [1];
357f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
358f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            for (StringTokenizer tokenizer = new StringTokenizer (sortList, ","); tokenizer.hasMoreTokens (); )
359f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
360f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final String sortSpec = tokenizer.nextToken ().trim ();
361f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final String columnName;
362f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final int dir;
363f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
364f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                switch (sortSpec.charAt (0))
365f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
366f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    case IReportProperties.ASC:
367f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
368f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        dir = +1;
369f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        columnName = sortSpec.substring (1);
370f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
371f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    break;
372f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
373f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    case IReportProperties.DESC:
374f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
375f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        dir = -1;
376f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        columnName = sortSpec.substring (1);
377f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
378f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    break;
379f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
380f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    default:
381f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
382f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        dir = +1;
383f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        columnName = sortSpec;
384f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
385f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    break;
386f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
387f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                } // end of switch
388f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
389f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                // silently ignore columns not in the column list:
390f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (columnNames.contains (columnName))
391f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
392f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    COLUMNS.get (columnName, out);
393f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
394f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    _sort.add (out [0]);    // sort attribute ID
395f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    _sort.add (dir);        // sort direction
396f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
397f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
398f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.setSortOrder (_sort.values ());
399f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
400f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
401f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
402f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String metricList = getReportProperty (properties, type, IReportProperties.METRICS, true, IReportProperties.DEFAULT_METRICS);
403f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final IntIntMap _metrics = new IntIntMap ();
404f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
405f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final int [] out = new int [1];
406f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
407f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // TODO: perhaps should throw on invalid input here
408f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            for (StringTokenizer tokenizer = new StringTokenizer (metricList, ","); tokenizer.hasMoreTokens (); )
409f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
410f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final String metricSpec = tokenizer.nextToken ().trim ();
411f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final String columnName;
412f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final double criterion;
413f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
414f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final int separator = metricSpec.indexOf (IReportProperties.MSEPARATOR);
415f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (separator > 0) // silently ignore invalid entries
416f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
417f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    // silently ignore invalid cutoff values:
418f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    try
419f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
420f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        criterion = Double.parseDouble (metricSpec.substring (separator + 1));
421f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        if ((criterion < 0.0) || (criterion > 101.0)) continue;
422f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
423f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    catch (NumberFormatException nfe)
424f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
425f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        nfe.printStackTrace (System.out);
426f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        continue;
427f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
428f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
429f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    columnName = metricSpec.substring (0, separator);
430f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
431f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    // silently ignore columns not in the column list:
432f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if (columnNames.contains (columnName))
433f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
434f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        COLUMNS.get (columnName, out);
435f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
436f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        _metrics.put (out [0], (int) Math.round (((criterion * IItem.PRECISION) / 100.0)));
437f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
438f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
439f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
440f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
441f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result.setMetrics (_metrics);
442f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
443f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
444f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        result.validate ();
445f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
446f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return result;
447f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
448f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
449f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
450f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // protected: .............................................................
451f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
452f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // package: ...............................................................
453f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
454f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // private: ...............................................................
455f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
456f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
457f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final class ReportPropertyMapper implements IProperties.IMapper
458f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
459f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public String getMappedKey (final String key)
460f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
461f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (key != null)
462f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
463f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (key.startsWith (IReportProperties.PREFIX))
464f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
465f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    final int secondDot = key.indexOf ('.', IReportProperties.PREFIX.length ());
466f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if (secondDot > 0)
467f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
468f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        // TODO: make this more precise (actually check the report type value string)
469f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
470f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        return IReportProperties.PREFIX.concat (key.substring (secondDot + 1));
471f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
472f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
473f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
474f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
475f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return null;
476f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
477f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
478f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    } // end of nested class
479f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
480f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
481f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    private static final class ReportPropertyLookup extends XProperties
482f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    {
483f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        // note: due to incredibly stupid coding in java.util.Properties
484f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        // (getProperty() uses a non-virtual call to super.get(), while propertyNames()
485f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        // uses a virtual call to the same method instead of delegating to getProperty())
486f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        // I must override both methods below
487f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
488f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        public String getProperty (String key)
489f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        {
490f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            return (String) get (key);
491f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        }
492f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
493f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        // TODO: this kind of lookup makes the property listing confusing
494f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
495f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        public Object get (final Object _key)
496f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        {
497f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            if (! (_key instanceof String)) return null;
498f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
499f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            String key = (String) _key;
500f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
501f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            if (key.startsWith (IReportProperties.PREFIX))
502f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//                key = key.substring (IReportProperties.PREFIX.length ());
503f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
504f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            if (key.startsWith (m_reportType))
505f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//                key = key.substring (m_reportType.length () + 1);
506f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
507f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            String fullKey = IReportProperties.PREFIX.concat (m_reportType).concat (".").concat (key);
508f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
509f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            String result = defaults.getProperty (fullKey, null);
510f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            if (result != null) return result;
511f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
512f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            // fall back to report type-neutral namespace:
513f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            fullKey = IReportProperties.PREFIX.concat (key);
514f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
515f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            result = defaults.getProperty (fullKey, null);
516f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            if (result != null) return result;
517f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
518f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            return null;
519f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        }
520f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
521f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
522f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        ReportPropertyLookup (final Properties appProperties, final String reportType)
523f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        {
524f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            super (appProperties);
525f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
526f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//            m_reportType = reportType;
527f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        }
528f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
529f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
530f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//        private final String m_reportType; // never null or empty [factory-ensured]
531f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//
532f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project//    } // end of nested class
533f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
534f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
535f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private ReportProperties () {} // prevent subclassing
536f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
537f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
538f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static String getReportProperty (final IProperties properties, final String type, final String key, final boolean allowBlank)
539f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
540f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return getReportProperty (properties, type, key, allowBlank, null);
541f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
542f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
543f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static String getReportProperty (final IProperties properties, final String type, final String key, final boolean allowBlank, final String dflt)
544f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
545f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if ($assert.ENABLED) $assert.ASSERT (properties != null, "null input: properties");
546f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if ($assert.ENABLED) $assert.ASSERT (key != null, "null input: key");
547f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
548f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final String result = properties.getProperty (IReportProperties.PREFIX.concat (type).concat (".").concat (key), dflt);
549f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
550f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (! allowBlank && (result != null) && (result.trim ().length () == 0))
551f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return dflt;
552f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
553f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return result;
554f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
555f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
556f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
557f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final boolean REMOVE_DUPLICATE_COLUMNS = true;
558f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final ObjectIntMap /* col name:String -> metadata:IItemMetadata */ COLUMNS; // set in <clinit>
559f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
560f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    static
561f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
562f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        REPORT_PROPERTY_MAPPER = new ReportPropertyMapper ();
563f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
564f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final ObjectIntMap columns = new ObjectIntMap ();
565f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
566f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        columns.put (IReportProperties.ITEM_NAME_COLUMN, IItemAttribute.ATTRIBUTE_NAME_ID);
567f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        columns.put (IReportProperties.CLASS_COVERAGE_COLUMN, IItemAttribute.ATTRIBUTE_CLASS_COVERAGE_ID);
568f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        columns.put (IReportProperties.METHOD_COVERAGE_COLUMN, IItemAttribute.ATTRIBUTE_METHOD_COVERAGE_ID);
569f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        columns.put (IReportProperties.BLOCK_COVERAGE_COLUMN, IItemAttribute.ATTRIBUTE_BLOCK_COVERAGE_ID);
570f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        columns.put (IReportProperties.LINE_COVERAGE_COLUMN, IItemAttribute.ATTRIBUTE_LINE_COVERAGE_ID);
571f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
572f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        COLUMNS = columns;
573f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
574f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
575f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} // end of class
576f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------