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: Command.java,v 1.1.1.1.2.1 2004/07/16 23:32:03 vlad_r Exp $
8f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */
9f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectpackage com.vladium.emma;
10f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
11f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.File;
12f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.IOException;
13f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.PrintWriter;
14f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Properties;
15f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
16f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.logging.ILogLevels;
17f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.IConstants;
18f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.Property;
19f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.Strings;
20f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.XProperties;
21f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.args.IOptsParser;
22f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.data.mergeCommand;
23f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.instr.instrCommand;
24f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.report.reportCommand;
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 Command
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 Command create (final String name, final String usageName, final String [] args)
37f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
38f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final Command tool;
39f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
40f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // TODO: dynamic load here?
41f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
42f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if ("run".equals (name))
43f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            tool = new runCommand (usageName, args);
44f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if ("instr".equals (name))
45f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            tool = new instrCommand (usageName, args);
46f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if ("report".equals (name))
47f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            tool = new reportCommand (usageName, args);
48f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if ("merge".equals (name))
49f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            tool = new mergeCommand (usageName, args);
50f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
51f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            throw new IllegalArgumentException ("unknown command: [" + name + "]");
52f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
53f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        tool.initialize ();
54f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
55f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return tool;
56f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
57f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
58f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public abstract void run ();
59f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
60f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // protected: .............................................................
61f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
62f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
63f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected Command (final String usageToolName, final String [] args)
64f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
65f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_usageToolName = usageToolName;
66f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_args = args != null ? (String []) args.clone () : IConstants.EMPTY_STRING_ARRAY;
67f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
68f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
69f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected abstract String usageArgsMsg ();
70f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
71f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // TODO: is this useful (separate from <init>)?
72f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected void initialize ()
73f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
74f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_exit = false;
75f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
76f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (m_out != null) try { m_out.flush (); } catch (Throwable ignore) {}
77f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_out = new PrintWriter (System.out, true);
78f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
79f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
80f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final String getToolName ()
81f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
82f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // TODO: embed build number etc
83f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final String clsName = getClass ().getName ();
84f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
85f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return clsName.substring (0, clsName.length () - 7);
86f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
87f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
88f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final IOptsParser getOptParser (final ClassLoader loader)
89f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
90f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return IOptsParser.Factory.create (usageResName (getToolName ()), loader,
91f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            usageMsgPrefix (m_usageToolName), USAGE_OPT_NAMES);
92f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
93f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
94f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final boolean processOpt (final IOptsParser.IOpt opt)
95f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
96f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final String on = opt.getCanonicalName ();
97f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
98f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if ("exit".equals (on)) // 'exit' should always be first in this else-if chain
99f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
100f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_exit = getOptionalBooleanOptValue (opt);
101f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return true;
102f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
103f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if ("p".equals (on))
104f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
105f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_propertyFile = new File (opt.getFirstValue ());
106f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return true;
107f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
108f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if ("verbose".equals (on))
109f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
110f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            setPropertyOverride (AppLoggers.PROPERTY_VERBOSITY_LEVEL, ILogLevels.VERBOSE_STRING);
111f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return true;
112f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
113f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if ("quiet".equals (on))
114f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
115f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            setPropertyOverride (AppLoggers.PROPERTY_VERBOSITY_LEVEL, ILogLevels.WARNING_STRING);
116f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return true;
117f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
118f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if ("silent".equals (on))
119f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
120f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            setPropertyOverride (AppLoggers.PROPERTY_VERBOSITY_LEVEL, ILogLevels.SEVERE_STRING);
121f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return true;
122f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
123f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if ("debug".equals (on))
124f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
125f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (opt.getValueCount () == 0)
126f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                setPropertyOverride (AppLoggers.PROPERTY_VERBOSITY_LEVEL, ILogLevels.TRACE1_STRING);
127f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else
128f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                setPropertyOverride (AppLoggers.PROPERTY_VERBOSITY_LEVEL, opt.getFirstValue ());
129f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
130f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return true;
131f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
132f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else if ("debugcls".equals (on))
133f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
134f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            setPropertyOverride (AppLoggers.PROPERTY_VERBOSITY_FILTER, Strings.toListForm (Strings.merge (opt.getValues (), COMMA_DELIMITERS, true), ','));
135f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return true;
136f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
137f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
138f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return false;
139f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
140f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
141f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final void processCmdPropertyOverrides (final IOptsParser.IOpts parsedopts)
142f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
143f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final IOptsParser.IOpt [] popts = parsedopts.getOpts (EMMAProperties.GENERIC_PROPERTY_OVERRIDE_PREFIX);
144f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if ((popts != null) && (popts.length != 0))
145f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
146f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final Properties cmdOverrides = new XProperties ();
147f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
148f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            for (int o = 0; o < popts.length; ++ o)
149f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
150f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final IOptsParser.IOpt opt = popts [o];
151f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final String on = opt.getName ().substring (opt.getPatternPrefix ().length ());
152f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
153f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                // TODO: support mergeable prefixed opts?
154f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
155f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                cmdOverrides.setProperty (on, opt.getFirstValue ());
156f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
157f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
158f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // command line user overrides are have highest precedence:
159f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_propertyOverrides = Property.combine (cmdOverrides, m_propertyOverrides);
160f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
161f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
162f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
163f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final boolean processFilePropertyOverrides ()
164f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
165f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (m_propertyFile != null)
166f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
167f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final Properties fileOverrides;
168f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
169f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            try
170f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
171f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                fileOverrides = Property.getPropertiesFromFile (m_propertyFile);
172f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
173f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            catch (IOException ioe)
174f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
175f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                exit (true, "property override file [" + m_propertyFile.getAbsolutePath () + "] could not be read", ioe, RC_USAGE);
176f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                return false;
177f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
178f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
179f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // props file overrides have second highest precendence:
180f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_propertyOverrides = Property.combine (m_propertyOverrides, fileOverrides);
181f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
182f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
183f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return true;
184f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
185f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
186f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final void usageexit (final IOptsParser parser, final int level, final String msg)
187f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
188f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (msg != null)
189f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
190f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_out.print (usageMsgPrefix (m_usageToolName));
191f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_out.println (msg);
192f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
193f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
194f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (parser != null)
195f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
196f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_out.println ();
197f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_out.print (usageMsgPrefix (m_usageToolName));
198f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_out.println (toolNameToCommandName (m_usageToolName) + " " + usageArgsMsg () + ",");
199f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_out.println ("  where options include:");
200f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_out.println ();
201f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            parser.usage (m_out, level, STDOUT_WIDTH);
202f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
203f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
204f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_out.println ();
205f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        exit (true, null, null, RC_USAGE);
206f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
207f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
208f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final void exit (final boolean showBuildID, final String msg, final Throwable t, final int rc)
209f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        throws EMMARuntimeException
210f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
211f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (showBuildID)
212f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
213f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_out.println (IAppConstants.APP_USAGE_BUILD_ID);
214f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
215f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
216f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (msg != null)
217f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
218f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_out.print (toolNameToCommandName (m_usageToolName) + ": "); m_out.println (msg);
219f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
220f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
221f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (rc != RC_OK)
222f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
223f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // error exit:
224f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
225f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            //if ((showBuildID) || (msg != null)) m_out.println ();
226f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
227f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (m_exit)
228f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
229f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (t != null) t.printStackTrace (m_out);
230f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                System.exit (rc);
231f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
232f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else
233f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
234f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (t instanceof EMMARuntimeException)
235f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    throw (EMMARuntimeException) t;
236f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                else if (t != null)
237f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    throw msg != null ? new EMMARuntimeException (msg, t) : new EMMARuntimeException ("unexpected failure: ", t);
238f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
239f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
240f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
241f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
242f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // normal exit: 't' is ignored
243f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
244f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (m_exit)
245f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
246f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                System.exit (0);
247f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
248f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
249f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
250f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
251f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static boolean getOptionalBooleanOptValue (final IOptsParser.IOpt opt)
252f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
253f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (opt.getValueCount () == 0)
254f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return true;
255f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
256f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
257f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String v = opt.getFirstValue ().toLowerCase ();
258f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
259f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return Property.toBoolean (v);
260f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
261f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
262f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
263f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static String [] getListOptValue (final IOptsParser.IOpt opt, final String delimiters, final boolean processAtFiles)
264f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        throws IOException
265f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
266f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return Strings.mergeAT (opt.getValues (), delimiters, processAtFiles);
267f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
268f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
269f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static String usageMsgPrefix (final String toolName)
270f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
271f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return toolNameToCommandName (toolName).concat (" usage: ");
272f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
273f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
274f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static String usageResName (final String toolName)
275f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
276f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return toolName.replace ('.', '/').concat ("_usage.res");
277f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
278f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
279f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static String toolNameToCommandName (final String toolName)
280f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
281f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final int lastDot = toolName.lastIndexOf ('.');
282f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
283f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return lastDot > 0 ? toolName.substring (lastDot + 1) : toolName;
284f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
285f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
286f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
287f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final String m_usageToolName;
288f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected final String [] m_args;
289f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
290f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected File m_propertyFile;
291f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected Properties m_propertyOverrides;
292f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected boolean m_exit;
293f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected PrintWriter m_out; // this is set independently from Logger by design
294f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
295f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final String COMMA_DELIMITERS    = "," + Strings.WHITE_SPACE;
296f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final String PATH_DELIMITERS     = ",".concat (File.pathSeparator);
297f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
298f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final String [] USAGE_OPT_NAMES = new String [] {"h", "help"};
299f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final int STDOUT_WIDTH = 80;
300f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
301f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // return codes used with System.exit():
302f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final int RC_OK          = 0;
303f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final int RC_USAGE       = 1;
304f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected static final int RC_UNEXPECTED  = 2;
305f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
306f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // package: ...............................................................
307f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
308f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // private: ...............................................................
309f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
310f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
311f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /*
312f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * Lazily instantiates m_propertyOverrides if necessary.
313f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
314f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private void setPropertyOverride (final String key, final String value)
315f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
316f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        Properties propertyOverrides = m_propertyOverrides;
317f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (propertyOverrides == null)
318f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
319f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_propertyOverrides = propertyOverrides = new XProperties ();
320f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
321f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
322f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        propertyOverrides.setProperty (key, value);
323f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
324f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
325f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} // end of class
326f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------