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: InstrProcessor.java,v 1.1.1.1.2.3 2004/07/17 16:57:14 vlad_r Exp $
8f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */
9f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectpackage com.vladium.emma.instr;
10f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
11f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.File;
12f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
13f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.Files;
14f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.IConstants;
15f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.IPathEnumerator;
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.Processor;
20f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.filter.IInclExclFilter;
21f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
22f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------
23f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/*
24f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * This class was not meant to be public by design. It is made to to work around
25f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * access bugs in reflective invocations.
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 InstrProcessor extends Processor
32f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                              implements IPathEnumerator.IPathHandler
33f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project{
34f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // public: ................................................................
35f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
36f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
37f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static final String PROPERTY_EXCLUDE_SYNTHETIC_METHODS   = "instr.exclude_synthetic_methods";
38f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static final String PROPERTY_EXCLUDE_BRIDGE_METHODS      = "instr.exclude_bridge_methods";
39f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static final String PROPERTY_DO_SUID_COMPENSATION        = "instr.do_suid_compensation";
40f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
41f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static final String DEFAULT_EXCLUDE_SYNTHETIC_METHODS    = "true";
42f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static final String DEFAULT_EXCLUDE_BRIDGE_METHODS       = "true";
43f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static final String DEFAULT_DO_SUID_COMPENSATION         = "true";
44f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
45f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static InstrProcessor create ()
46f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
47f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return new InstrProcessorST ();
48f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
49f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
50f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
51f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
52f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param path [null is equivalent to an empty array]
53f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param canonical
54f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
55f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public synchronized final void setInstrPath (final String [] path, final boolean canonical)
56f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
57f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if ((path == null) || (path.length == 0))
58f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_instrPath = IConstants.EMPTY_FILE_ARRAY;
59f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
60f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_instrPath = Files.pathToFiles (path, canonical);
61f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
62f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_canonical = canonical;
63f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
64f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
65f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public synchronized final void setDependsMode (final boolean enable)
66f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
67f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_dependsMode = enable;
68f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
69f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
70f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
71f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
72f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param specs [null is equivalent to no filtering (everything is included)]
73f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
74f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public synchronized final void setInclExclFilter (final String [] specs)
75f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
76f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (specs == null)
77f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_coverageFilter = null;
78f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
79f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_coverageFilter = IInclExclFilter.Factory.create (specs);
80f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
81f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
82f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
83f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
84f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param fileName [null unsets the previous override setting]
85f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
86f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public synchronized final void setMetaOutFile (final String fileName)
87f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
88f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (fileName == null)
89f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_mdataOutFile = null;
90f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
91f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
92f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final File _file = new File (fileName);
93f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
94f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (_file.exists () && ! _file.isFile ())
95f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                throw new IllegalArgumentException ("not a file: [" + _file.getAbsolutePath () + "]");
96f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
97f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_mdataOutFile = _file;
98f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
99f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
100f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
101f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
102f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
103f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param merge [null unsets the previous override setting]
104f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
105f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public synchronized final void setMetaOutMerge (final Boolean merge)
106f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
107f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_mdataOutMerge = merge;
108f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
109f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
110f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
111f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
112f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param dir [null unsets the previous setting]
113f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
114f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public synchronized final void setInstrOutDir (final String dir)
115f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
116f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (dir == null)
117f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_outDir = null;
118f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
119f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
120f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final File _outDir = new File (dir);
121f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (_outDir.exists () && ! _outDir.isDirectory ())
122f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                throw new IllegalArgumentException ("not a directory: [" + _outDir.getAbsolutePath () + "]");
123f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
124f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_outDir = _outDir;
125f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
126f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
127f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
128f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
129f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
130f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param mode [may not be null]
131f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
132f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public synchronized final void setOutMode (final OutMode mode)
133f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
134f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (mode == null)
135f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            throw new IllegalArgumentException ("null input: mode");
136f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
137f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_outMode = mode;
138f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
139f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
140f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // protected: .............................................................
141f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
142f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
143f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected InstrProcessor ()
144f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
145f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_dependsMode = true;
146f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
147f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
148f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
149f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected void validateState ()
150f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
151f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        super.validateState ();
152f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
153f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if ((m_instrPath == null) || (m_instrPath.length == 0))
154f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            throw new IllegalStateException ("instrumentation path not set");
155f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
156f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // [m_coverageFilter can be null]
157f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
158f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (m_outMode == null)
159f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            throw new IllegalStateException ("output mode not set");
160f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
161f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (m_outMode != OutMode.OUT_MODE_OVERWRITE)
162f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
163f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (m_outDir == null)
164f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                throw new IllegalStateException ("output directory not set");
165f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
166f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // for non-overwrite modes output directory must not overlap
167f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // with the instr path:
168f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
169f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // [the logic below does not quite catch all possibilities due to
170f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // Class-Path: manifest attributes and dir nesting, but it should
171f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // intercept most common mistakes]
172f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
173f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ($assert.ENABLED)
174f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
175f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                $assert.ASSERT (m_outDir != null, "m_outDir = null");
176f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                $assert.ASSERT (m_instrPath != null, "m_instrPath = null");
177f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
178f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
179f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final File canonicalOutDir = Files.canonicalizeFile (m_outDir);
180f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final File [] canonicalInstrPath;
181f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
182f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (m_canonical)
183f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                canonicalInstrPath = m_instrPath;
184f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else
185f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
186f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                canonicalInstrPath = new File [m_instrPath.length];
187f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
188f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                for (int ip = 0; ip < canonicalInstrPath.length; ++ ip)
189f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
190f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    canonicalInstrPath [ip] = Files.canonicalizeFile (m_instrPath [ip]);
191f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
192f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
193f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
194f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // FR_SF988785: detect if the user attempted to use a parent of m_outDir as one of
195f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // the input directories (prevents spurious "already instrumented" errors)
196f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
197f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final int instrPathLength = canonicalInstrPath.length;
198f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            for (File dir = canonicalOutDir; dir != null; dir = dir.getParentFile ()) // getParentFile() does no real I/O
199f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
200f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                for (int ip = 0; ip < instrPathLength; ++ ip)
201f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
202f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if (dir.equals (canonicalInstrPath [ip]))
203f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        throw new IllegalStateException ("output directory [" + canonicalOutDir + "] cannot be one of the instrumentation path directories (or a child thereof)");
204f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
205f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
206f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
207f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
208f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // [m_mdataOutFile can be null]
209f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // [m_mdataOutMerge can be null]
210f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
211f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
212f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected void reset ()
213f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
214f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_classCopies = m_classInstrs = 0;
215f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
216f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
217f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final void createDir (final File dir, final boolean mkall)
218f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        throws EMMARuntimeException
219f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
220f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (mkall)
221f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
222f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (! dir.mkdirs () && ! dir.exists ())
223f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                throw new EMMARuntimeException (IAppErrorCodes.OUT_MKDIR_FAILURE, new Object [] {dir.getAbsolutePath ()});
224f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
225f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
226f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
227f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (! dir.mkdir () && ! dir.exists ())
228f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                throw new EMMARuntimeException (IAppErrorCodes.OUT_MKDIR_FAILURE, new Object [] {dir.getAbsolutePath ()});
229f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
230f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
231f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
232f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final File getFullOutDir (final File pathDir, final boolean isClass)
233f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
234f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (m_outMode == OutMode.OUT_MODE_OVERWRITE)
235f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
236f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return pathDir;
237f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
238f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if (m_outMode == OutMode.OUT_MODE_COPY)
239f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
240f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_outDir;
241f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
242f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if (m_outMode == OutMode.OUT_MODE_FULLCOPY)
243f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
244f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return isClass ? Files.newFile (m_outDir, CLASSES) : Files.newFile (m_outDir, LIB);
245f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
246f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else throw new IllegalStateException ("invalid out mode state: " + m_outMode);
247f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
248f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
249f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final File getFullOutFile (final File pathDir, final File file, final boolean isClass)
250f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
251f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return Files.newFile (getFullOutDir (pathDir, isClass), file.getPath ());
252f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
253f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
254f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
255f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // caller-settable state [scoped to this runner instance]:
256f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
257f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected File [] m_instrPath; // required to be non-null/non-empty for run()
258f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected boolean m_dependsMode;
259f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected boolean m_canonical;
260f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected IInclExclFilter m_coverageFilter; // can be null for run()
261f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected OutMode m_outMode; // required to be set for run()
262f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected File m_outDir; // required to be non-null for run(), unless output mode is 'overwrite'
263f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected File m_mdataOutFile; // user override; can be null for run()
264f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected Boolean m_mdataOutMerge; // user override; can be null for run()
265f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
266f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // internal run()-scoped state:
267f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
268f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected int m_classCopies, m_classInstrs;
269f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
270f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final String CLASSES   = "classes";
271f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final String LIB       = "lib";
272f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final boolean IN_CLASSES   = true;
273f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final boolean IN_LIB       = ! IN_CLASSES;
274f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
275f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // package: ...............................................................
276f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
277f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// TODO: access level [public to workaround Sun's bugs in access level in reflective invocations]
278f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static final class OutMode
279f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
280f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public static final OutMode OUT_MODE_COPY = new OutMode ("copy");
281f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public static final OutMode OUT_MODE_FULLCOPY = new OutMode ("fullcopy");
282f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public static final OutMode OUT_MODE_OVERWRITE = new OutMode ("overwrite");
283f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
284f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public String getName ()
285f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
286f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_name;
287f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
288f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
289f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public String toString ()
290f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
291f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_name;
292f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
293f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
294f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public static OutMode nameToMode (final String name)
295f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
296f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (OUT_MODE_COPY.m_name.equals (name))
297f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                return OUT_MODE_COPY;
298f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else if (OUT_MODE_FULLCOPY.m_name.equals (name))
299f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                return OUT_MODE_FULLCOPY;
300f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else if (OUT_MODE_OVERWRITE.m_name.equals (name))
301f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                return OUT_MODE_OVERWRITE;
302f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
303f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return null;
304f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
305f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
306f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private OutMode (final String name)
307f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
308f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_name = name;
309f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
310f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
311f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
312f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private final String m_name;
313f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
314f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    } // end of nested class
315f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
316f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // private: ...............................................................
317f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
318f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} // end of class
319f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------