PageRenderTime 59ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/external/emma/core/java12/com/vladium/emma/runCommand.java

https://bitbucket.org/rlyspn/androidrr
Java | 332 lines | 241 code | 57 blank | 34 comment | 59 complexity | ef5ef9ec2987d5589d13a500ce73cb47 MD5 | raw file
  1. /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
  2. *
  3. * This program and the accompanying materials are made available under
  4. * the terms of the Common Public License v1.0 which accompanies this distribution,
  5. * and is available at http://www.eclipse.org/legal/cpl-v10.html
  6. *
  7. * $Id: runCommand.java,v 1.1.1.1.2.1 2004/07/16 23:32:03 vlad_r Exp $
  8. */
  9. package com.vladium.emma;
  10. import java.io.File;
  11. import java.io.IOException;
  12. import java.util.jar.Attributes;
  13. import java.util.jar.JarFile;
  14. import java.util.jar.Manifest;
  15. import com.vladium.util.ClassLoaderResolver;
  16. import com.vladium.util.Strings;
  17. import com.vladium.util.args.IOptsParser;
  18. import com.vladium.util.asserts.$assert;
  19. import com.vladium.emma.rt.AppRunner;
  20. // ----------------------------------------------------------------------------
  21. /**
  22. * @author Vlad Roubtsov, (C) 2003
  23. */
  24. public
  25. final class runCommand extends Command
  26. {
  27. // public: ................................................................
  28. public synchronized void run ()
  29. {
  30. ClassLoader loader;
  31. try
  32. {
  33. loader = ClassLoaderResolver.getClassLoader ();
  34. }
  35. catch (Throwable t)
  36. {
  37. loader = getClass ().getClassLoader ();
  38. }
  39. try
  40. {
  41. // process 'args':
  42. {
  43. final IOptsParser parser = getOptParser (loader);
  44. final IOptsParser.IOpts parsedopts = parser.parse (m_args);
  45. // check if usage is requested before checking args parse errors etc:
  46. {
  47. final int usageRequestLevel = parsedopts.usageRequestLevel ();
  48. if (usageRequestLevel > 0)
  49. {
  50. usageexit (parser, usageRequestLevel, null);
  51. return;
  52. }
  53. }
  54. final IOptsParser.IOpt [] opts = parsedopts.getOpts ();
  55. if (opts == null) // this means there were args parsing errors
  56. {
  57. parsedopts.error (m_out, STDOUT_WIDTH);
  58. usageexit (parser, IOptsParser.SHORT_USAGE, null);
  59. return;
  60. }
  61. // process parsed args:
  62. try
  63. {
  64. for (int o = 0; o < opts.length; ++ o)
  65. {
  66. final IOptsParser.IOpt opt = opts [o];
  67. final String on = opt.getCanonicalName ();
  68. if (! processOpt (opt))
  69. {
  70. if ("cp".equals (on))
  71. {
  72. m_classpath = getListOptValue (opt, PATH_DELIMITERS, true);
  73. }
  74. else if ("jar".equals (on))
  75. {
  76. m_jarMode = true;
  77. }
  78. else if ("f".equals (on))
  79. {
  80. m_scanCoveragePath = getOptionalBooleanOptValue (opt);
  81. }
  82. else if ("sp".equals (on))
  83. {
  84. m_srcpath = getListOptValue (opt, PATH_DELIMITERS, true);
  85. }
  86. else if ("raw".equals (on))
  87. {
  88. m_dumpRawData = getOptionalBooleanOptValue (opt);
  89. }
  90. else if ("out".equals (on))
  91. {
  92. m_outFileName = opt.getFirstValue ();
  93. }
  94. else if ("merge".equals (on))
  95. {
  96. m_outDataMerge = getOptionalBooleanOptValue (opt) ? Boolean.TRUE : Boolean.FALSE;
  97. }
  98. else if ("r".equals (on))
  99. {
  100. m_reportTypes = Strings.merge (opt.getValues (), COMMA_DELIMITERS, true);
  101. }
  102. else if ("ix".equals (on))
  103. {
  104. m_ixpath = getListOptValue (opt, COMMA_DELIMITERS, true);
  105. }
  106. }
  107. }
  108. // user '-props' file property overrides:
  109. if (! processFilePropertyOverrides ()) return;
  110. // process prefixed opts:
  111. processCmdPropertyOverrides (parsedopts);
  112. }
  113. catch (IOException ioe)
  114. {
  115. throw new EMMARuntimeException (IAppErrorCodes.ARGS_IO_FAILURE, ioe);
  116. }
  117. // process free args:
  118. {
  119. final String [] freeArgs = parsedopts.getFreeArgs ();
  120. if (m_jarMode)
  121. {
  122. if ((freeArgs == null) || (freeArgs.length == 0))
  123. {
  124. usageexit (parser, IOptsParser.SHORT_USAGE, "missing jar file name");
  125. return;
  126. }
  127. if ($assert.ENABLED) $assert.ASSERT (freeArgs != null && freeArgs.length > 0, "invalid freeArgs");
  128. final File jarfile = new File (freeArgs [0]);
  129. final String jarMainClass;
  130. try
  131. {
  132. jarMainClass = openJarFile (jarfile); // the rest of free args are *not* ignored
  133. }
  134. catch (IOException ioe)
  135. {
  136. // TODO: is the right error code?
  137. throw new EMMARuntimeException (IAppErrorCodes.ARGS_IO_FAILURE, ioe);
  138. }
  139. if (jarMainClass == null)
  140. {
  141. exit (true, "failed to load Main-Class manifest attribute from [" + jarfile.getAbsolutePath () + "]", null, RC_UNEXPECTED);
  142. return;
  143. }
  144. if ($assert.ENABLED) $assert.ASSERT (jarMainClass != null, "invalid jarMainClass");
  145. m_appArgs = new String [freeArgs.length];
  146. System.arraycopy (freeArgs, 1, m_appArgs, 1, freeArgs.length - 1);
  147. m_appArgs [0] = jarMainClass;
  148. m_classpath = new String [] { jarfile.getPath () };
  149. }
  150. else
  151. {
  152. if ((freeArgs == null) || (freeArgs.length == 0))
  153. {
  154. usageexit (parser, IOptsParser.SHORT_USAGE, "missing application class name");
  155. return;
  156. }
  157. m_appArgs = freeArgs;
  158. }
  159. }
  160. // [m_appArgs: { mainclass, arg1, arg2, ... }]
  161. // handle cmd line-level defaults and option interaction
  162. {
  163. if (DEFAULT_TO_SYSTEM_CLASSPATH)
  164. {
  165. if (m_classpath == null)
  166. {
  167. // TODO" this is not guaranteed to work (in WebStart etc), so double check if I should remove this
  168. final String systemClasspath = System.getProperty ("java.class.path", "");
  169. if (systemClasspath.length () == 0)
  170. {
  171. // TODO: assume "." just like Sun JVMs in this case?
  172. usageexit (parser, IOptsParser.SHORT_USAGE, "could not infer coverage classpath from 'java.class.path'; use an explicit -cp option");
  173. return;
  174. }
  175. m_classpath = new String [] {systemClasspath};
  176. }
  177. }
  178. else
  179. {
  180. if (m_classpath == null)
  181. {
  182. usageexit (parser, IOptsParser.SHORT_USAGE, "either '-cp' or '-jar' option is required");
  183. return;
  184. }
  185. }
  186. // TODO: who owns setting this 'txt' default? most likely AppRunner
  187. if (m_reportTypes == null)
  188. {
  189. m_reportTypes = new String [] {"txt"};
  190. }
  191. }
  192. }
  193. // run the app:
  194. {
  195. if ($assert.ENABLED) $assert.ASSERT (m_appArgs != null && m_appArgs.length > 0, "invalid m_appArgs");
  196. final String [] appargs = new String [m_appArgs.length - 1];
  197. System.arraycopy (m_appArgs, 1, appargs, 0, appargs.length);
  198. final AppRunner processor = AppRunner.create (loader);
  199. processor.setAppName (IAppConstants.APP_NAME); // for log prefixing
  200. processor.setAppClass (m_appArgs [0], appargs);
  201. processor.setCoveragePath (m_classpath, true); // TODO: an option to set 'canonical'?
  202. processor.setScanCoveragePath (m_scanCoveragePath);
  203. processor.setSourcePath (m_srcpath);
  204. processor.setInclExclFilter (m_ixpath);
  205. processor.setDumpSessionData (m_dumpRawData);
  206. processor.setSessionOutFile (m_outFileName);
  207. processor.setSessionOutMerge (m_outDataMerge);
  208. if ($assert.ENABLED) $assert.ASSERT (m_reportTypes != null, "m_reportTypes no set");
  209. processor.setReportTypes (m_reportTypes);
  210. processor.setPropertyOverrides (m_propertyOverrides);
  211. processor.run ();
  212. }
  213. }
  214. catch (EMMARuntimeException yre)
  215. {
  216. // TODO: see below
  217. exit (true, yre.getMessage (), yre, RC_UNEXPECTED); // does not return
  218. return;
  219. }
  220. catch (Throwable t)
  221. {
  222. // TODO: embed: OS/JVM fingerprint, build #, etc
  223. // TODO: save stack trace in a file and prompt user to send it to ...
  224. exit (true, "unexpected failure: ", t, RC_UNEXPECTED); // does not return
  225. return;
  226. }
  227. exit (false, null, null, RC_OK);
  228. }
  229. // protected: .............................................................
  230. protected runCommand (final String usageToolName, final String [] args)
  231. {
  232. super (usageToolName, args);
  233. }
  234. protected void initialize ()
  235. {
  236. // TODO: clean up instance state
  237. super.initialize ();
  238. }
  239. protected String usageArgsMsg ()
  240. {
  241. return "[options] class [args...] | -jar [options] jarfile [args...]";
  242. }
  243. // package: ...............................................................
  244. // private: ...............................................................
  245. private static String openJarFile (final File file)
  246. throws IOException
  247. {
  248. JarFile jarfile = null;
  249. try
  250. {
  251. jarfile = new JarFile (file, false);
  252. final Manifest manifest = jarfile.getManifest ();
  253. if (manifest == null) return null;
  254. final Attributes attributes = manifest.getMainAttributes ();
  255. if (attributes == null) return null;
  256. final String jarMainClass = attributes.getValue (Attributes.Name.MAIN_CLASS);
  257. return jarMainClass;
  258. }
  259. finally
  260. {
  261. if (jarfile != null) try { jarfile.close (); } catch (IOException ignore) {}
  262. }
  263. }
  264. private String [] m_classpath, m_srcpath;
  265. private boolean m_jarMode;
  266. private boolean m_scanCoveragePath; // defaults to false
  267. private String [] m_ixpath;
  268. private String [] m_appArgs;
  269. private boolean m_dumpRawData; // defaults to false
  270. private String m_outFileName;
  271. private Boolean m_outDataMerge;
  272. private String [] m_reportTypes;
  273. private static final boolean DEFAULT_TO_SYSTEM_CLASSPATH = false;
  274. } // end of class
  275. // ----------------------------------------------------------------------------