|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 * TraceCompiler command-line main class |
|
17 * |
|
18 */ |
|
19 package com.nokia.tracecompiler; |
|
20 |
|
21 import java.io.BufferedReader; |
|
22 import java.io.File; |
|
23 import java.io.IOException; |
|
24 import java.io.InputStreamReader; |
|
25 import java.net.URL; |
|
26 import java.util.ArrayList; |
|
27 import java.util.Arrays; |
|
28 import java.util.Iterator; |
|
29 import java.util.regex.Matcher; |
|
30 import java.util.regex.Pattern; |
|
31 |
|
32 import com.nokia.tracecompiler.document.FileDocumentMonitor; |
|
33 import com.nokia.tracecompiler.document.StringDocumentFactory; |
|
34 import com.nokia.tracecompiler.engine.TraceCompilerEngineEvents; |
|
35 import com.nokia.tracecompiler.engine.TraceCompilerEngineGlobals; |
|
36 import com.nokia.tracecompiler.engine.TraceCompilerEngineInterface; |
|
37 import com.nokia.tracecompiler.engine.TraceLocationList; |
|
38 import com.nokia.tracecompiler.engine.project.ProjectEngine; |
|
39 import com.nokia.tracecompiler.file.FileUtils; |
|
40 import com.nokia.tracecompiler.model.TraceCompilerException; |
|
41 import com.nokia.tracecompiler.model.TraceModel; |
|
42 import com.nokia.tracecompiler.plugin.TraceCompilerPlugin; |
|
43 import com.nokia.tracecompiler.project.GroupNames; |
|
44 import com.nokia.tracecompiler.source.SourceConstants; |
|
45 import com.nokia.tracecompiler.utils.DocumentFactory; |
|
46 import com.nokia.tracecompiler.utils.TraceCompilerVersion; |
|
47 |
|
48 /** |
|
49 * TraceCompiler command-line main class |
|
50 * |
|
51 */ |
|
52 public class TraceCompilerMain { |
|
53 |
|
54 /** line separator */ |
|
55 private static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$ |
|
56 |
|
57 /** |
|
58 * Index of third character |
|
59 */ |
|
60 private static final int INDEX_OF_THIRD_CHARACTER = 2; |
|
61 |
|
62 /** |
|
63 * Index of first character |
|
64 */ |
|
65 private static final int INDEX_OF_FIRST_CHARACTER = 0; |
|
66 |
|
67 /** |
|
68 * TraceCompiler options |
|
69 */ |
|
70 |
|
71 /** |
|
72 * UID : it is used to create the dictionary file |
|
73 */ |
|
74 private static final String UID_SWITCH = Messages.getString("TraceCompiler.UidStwich"); //$NON-NLS-1$ |
|
75 private static final String UID_SWITCH_TEXT = Messages.getString("TraceCompiler.UidText"); //$NON-NLS-1$ |
|
76 /** |
|
77 * project name : it is used to create the dictionary file |
|
78 */ |
|
79 private static final String PRJ_NAME_SWITCH = Messages.getString("TraceCompiler.ProjectSwitch");//$NON-NLS-1$ |
|
80 private static final String PRJ_NAME_SWITCH_TEXT = Messages.getString("TraceCompiler.ProjectText"); //$NON-NLS-1$ |
|
81 /** |
|
82 * mmp file path: may be used to compute the traces folder |
|
83 */ |
|
84 private static final String MMP_PATH_SWITCH = Messages.getString("TraceCompiler.MmpSwitch");//$NON-NLS-1$ |
|
85 private static final String MMP_PATH_SWITCH_TEXT = Messages.getString("TraceCompiler.MmpText"); //$NON-NLS-1$ |
|
86 /** |
|
87 * traces folder: absolute or relative to the mmp folder |
|
88 */ |
|
89 private static final String TRACES_PATH_SWITCH = Messages.getString("TraceCompiler.TracesSwitch");//$NON-NLS-1$ |
|
90 private static final String TRACES_PATH_SWITCH_TEXT = Messages.getString("TraceCompiler.TracesText"); //$NON-NLS-1$ |
|
91 |
|
92 |
|
93 /** |
|
94 * Version option |
|
95 */ |
|
96 private static final String VERSION_OPTION = Messages.getString("TraceCompiler.VersionSwitchLong"); //$NON-NLS-1$ |
|
97 private static final String VERSION_OPTION_SF = Messages.getString("TraceCompiler.VersionSwitchShort"); //$NON-NLS-1$ |
|
98 private static final String VERSION_OPTION_INSTRUCTION_TEXT = Messages.getString("TraceCompiler.VersionText"); //$NON-NLS-1$ |
|
99 |
|
100 |
|
101 /** |
|
102 * help option |
|
103 */ |
|
104 private static final String HELP_OPTION = Messages.getString("TraceCompiler.HelpSwicthLong"); //$NON-NLS-1$ |
|
105 private static final String HELP_OPTION_SF = Messages.getString("TraceCompiler.HelpSwitchShort"); //$NON-NLS-1$ |
|
106 private static final String HELP_OPTION_INSTRUCTION_TEXT = Messages.getString("TraceCompiler.HelpText"); //$NON-NLS-1$ |
|
107 |
|
108 /** |
|
109 * Verbose option |
|
110 */ |
|
111 private static final String VERBOSE_OPTION = Messages.getString("TraceCompiler.VerboseSwitchLong"); //$NON-NLS-1$ |
|
112 private static final String VERBOSE_OPTION_SF = Messages.getString("TraceCompiler.VerboseSwitchShort"); //$NON-NLS-1$ |
|
113 private static final String VERBOSE_OPTION_INSTRUCTION_TEXT = Messages.getString("TraceCompiler.VerboseText"); //$NON-NLS-1$ |
|
114 |
|
115 /** |
|
116 * keep going option |
|
117 */ |
|
118 private static final String STOP_ON_ERROR_OPTION = Messages.getString("TraceCompiler.StopSwitchLong"); //$NON-NLS-1$ |
|
119 private static final String STOP_ON_ERROR_OPTION_SF = Messages.getString("TraceCompiler.StopSwitchShort"); //$NON-NLS-1$ |
|
120 private static final String STOP_ON_ERROR_OPTION_INSTRUCTION_TEXT = Messages.getString("TraceCompiler.StopText"); //$NON-NLS-1$ |
|
121 |
|
122 |
|
123 |
|
124 /** |
|
125 * Version text |
|
126 */ |
|
127 private static final String VERSION_TEXT = Messages.getString("TraceCompiler.DisplayVersionText"); //$NON-NLS-1$ |
|
128 |
|
129 /** |
|
130 * Option instruction text |
|
131 */ |
|
132 private static final String OPTION_INSTRUCTION_TEXT = Messages.getString("TraceCompiler.Options"); //$NON-NLS-1$ |
|
133 private static final String VALUE=Messages.getString("TraceCompiler.Value"); //$NON-NLS-1$ |
|
134 |
|
135 |
|
136 |
|
137 private static final String USAGE = Messages.getString("TraceCompiler.Usage") + LINE_SEPARATOR + //$NON-NLS-1$ |
|
138 Messages.getString("TraceCompiler.UsageText") + LINE_SEPARATOR + //$NON-NLS-1$ |
|
139 "\t" + OPTION_INSTRUCTION_TEXT + LINE_SEPARATOR + //$NON-NLS-1$ |
|
140 "\t" + HELP_OPTION_SF + ", " + HELP_OPTION + ", " + HELP_OPTION_INSTRUCTION_TEXT + LINE_SEPARATOR + //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ |
|
141 "\t" + VERSION_OPTION_SF + ", " + VERSION_OPTION + "\t" + VERSION_OPTION_INSTRUCTION_TEXT + LINE_SEPARATOR + //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ |
|
142 "\t" + VERBOSE_OPTION_SF + ", " + VERBOSE_OPTION + "\t\t" + VERBOSE_OPTION_INSTRUCTION_TEXT + LINE_SEPARATOR + //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ |
|
143 "\t" + STOP_ON_ERROR_OPTION_SF + ", " + STOP_ON_ERROR_OPTION + "\t" + STOP_ON_ERROR_OPTION_INSTRUCTION_TEXT + LINE_SEPARATOR + //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ |
|
144 "\t" + UID_SWITCH + "=" + VALUE + "\t" + UID_SWITCH_TEXT + LINE_SEPARATOR + //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ |
|
145 "\t" + PRJ_NAME_SWITCH + "=" + VALUE + "\t" + PRJ_NAME_SWITCH_TEXT + LINE_SEPARATOR + //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ |
|
146 "\t" + MMP_PATH_SWITCH + "=" + VALUE + "\t" + MMP_PATH_SWITCH_TEXT + LINE_SEPARATOR + //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ |
|
147 "\t" + TRACES_PATH_SWITCH + "=" + VALUE + "\t" + TRACES_PATH_SWITCH_TEXT; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ |
|
148 |
|
149 |
|
150 |
|
151 /** |
|
152 * End of source files tag |
|
153 */ |
|
154 private static final String ENDOFSOURCEFILES = Messages.getString("TraceCompiler.EndOfList"); //$NON-NLS-1$ |
|
155 |
|
156 /** |
|
157 * MMP file extension |
|
158 */ |
|
159 private static final String MMP_FILE_TYPE = Messages.getString("TraceCompiler.MmpExtension"); //$NON-NLS-1$ |
|
160 |
|
161 /** |
|
162 * Decode plugins path |
|
163 */ |
|
164 private String DECODE_PLUGINS_PATH = Messages.getString("TraceCompiler.PluginPath"); //$NON-NLS-1$ |
|
165 |
|
166 /** |
|
167 * Decode plugin name tag |
|
168 */ |
|
169 private String DECODE_PLUGIN_NAME_TAG = Messages.getString("TraceCompiler.DecodeText1"); //$NON-NLS-1$ |
|
170 |
|
171 /** |
|
172 * Decode plugin class name tag |
|
173 */ |
|
174 private String DECODE_PLUGIN_CLASS_NAME_TAG = Messages.getString("TraceCompiler.DecodeText2"); //$NON-NLS-1$ |
|
175 |
|
176 /** |
|
177 * Decode plugin engine class name template |
|
178 */ |
|
179 private String ENGINE_CLASS_NAME_TEMPLATE = DECODE_PLUGIN_NAME_TAG |
|
180 + "Engine"; //$NON-NLS-1$ |
|
181 |
|
182 /** |
|
183 * Decode plugin engine file name template |
|
184 */ |
|
185 private String ENGINE_FILE_NAME_TEMPLATE = DECODE_PLUGIN_CLASS_NAME_TAG |
|
186 + ".class"; //$NON-NLS-1$ |
|
187 |
|
188 /** |
|
189 * Decode plugins class template |
|
190 */ |
|
191 private String CLASS_TEMPLATE = Messages.getString("TraceCompiler.DecodePluginsNameSpace") + DECODE_PLUGIN_NAME_TAG + "." + DECODE_PLUGIN_CLASS_NAME_TAG; //$NON-NLS-1$ //$NON-NLS-2$ |
|
192 |
|
193 //switch with value such as --uid=value |
|
194 private Pattern valueSwitchPattern = Pattern.compile("(--\\S+)=(\\S+)"); //$NON-NLS-1$ |
|
195 //switches with no values such -v, --version |
|
196 private Pattern singleSwitchPattern = Pattern.compile("-{1,2}([^=]+)"); //$NON-NLS-1$ |
|
197 |
|
198 /** |
|
199 * list of source files |
|
200 */ |
|
201 private ArrayList<String> sources = new ArrayList<String>(); |
|
202 /** |
|
203 * traces path |
|
204 */ |
|
205 private String traces_path = null; |
|
206 |
|
207 |
|
208 |
|
209 |
|
210 /** |
|
211 * Main function |
|
212 * |
|
213 * @param args |
|
214 * the command line arguments |
|
215 */ |
|
216 public static void main(String[] args) { |
|
217 if (args.length == 0) { |
|
218 printUsage(); |
|
219 return; |
|
220 } |
|
221 |
|
222 ArrayList<String> list = null; |
|
223 |
|
224 //support spaces in switches, build a long string, clean it and convert it back to array - a bit expensive |
|
225 String tmpString = ""; //$NON-NLS-1$ |
|
226 for (int i = 0; i < args.length; i++) { |
|
227 tmpString = tmpString + " " + args[i]; //$NON-NLS-1$ |
|
228 } |
|
229 tmpString = tmpString.replaceAll("\\s*=\\s*", "="); //$NON-NLS-1$ //$NON-NLS-2$ |
|
230 tmpString = tmpString.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$ |
|
231 String[] split = tmpString.trim().split(" "); //$NON-NLS-1$ |
|
232 tmpString = null; // not needed anymore |
|
233 |
|
234 //rebuild array of arguments |
|
235 if (split.length > 0) { |
|
236 list = new ArrayList<String>(Arrays.asList(split)); |
|
237 } |
|
238 |
|
239 long startTime = System.currentTimeMillis(); |
|
240 //create a new session of TraceCompiler |
|
241 TraceCompilerMain console = new TraceCompilerMain(); |
|
242 |
|
243 try { |
|
244 console.parseCommandLine(list); |
|
245 } catch (Exception e) { //should cover IOException and TraceCompilerIllegalArgumentsException |
|
246 //There is no point to continue if there are problems with the arguments. |
|
247 TraceCompilerLogger.printError(e.getMessage()); |
|
248 printUsage(); |
|
249 System.exit(1); |
|
250 } |
|
251 |
|
252 boolean error = false; |
|
253 try { |
|
254 if(list.size() != 0) { |
|
255 console.createPlugins(); |
|
256 console.start(); |
|
257 console.buildTraceFiles(); |
|
258 } |
|
259 } catch (Exception e) { |
|
260 if (e instanceof TraceCompilerRootException) { |
|
261 TraceCompilerLogger.printError(e.getMessage()); |
|
262 } //else the error should have been reported earlier |
|
263 error = true; |
|
264 } finally { |
|
265 try { |
|
266 if (!error) { //check if errors have been logged by EventEngine |
|
267 TraceCompilerEngineEvents events = TraceCompilerEngineGlobals.getEvents(); |
|
268 if (events != null && events.hasErrorHappened()) { |
|
269 error = true; |
|
270 } |
|
271 } |
|
272 console.shutdown(); |
|
273 } catch (TraceCompilerException e) { |
|
274 error = true; |
|
275 } |
|
276 } |
|
277 |
|
278 if (console.projectName != null) { |
|
279 TraceCompilerLogger.printMessage(console.projectName + Messages.getString("TraceCompiler.Took") //$NON-NLS-1$ |
|
280 + (System.currentTimeMillis() - startTime) + Messages.getString("TraceCompiler.MS")); //$NON-NLS-1$ |
|
281 } |
|
282 if (error) { |
|
283 System.exit(1); |
|
284 } else { |
|
285 System.exit(0); |
|
286 } |
|
287 } |
|
288 |
|
289 /** |
|
290 * With Eclipse, the plug-ins are loaded by Eclipse framework. Here they |
|
291 * must be manually created and started |
|
292 */ |
|
293 private ArrayList<TraceCompilerPlugin> plugIns = new ArrayList<TraceCompilerPlugin>(); |
|
294 |
|
295 /** |
|
296 * Model listener |
|
297 */ |
|
298 private TraceCompilerModelListener modelListener; |
|
299 |
|
300 /** |
|
301 * Name of the component |
|
302 */ |
|
303 private String projectName = null; |
|
304 |
|
305 |
|
306 /** |
|
307 * UID of the component |
|
308 */ |
|
309 private long componentUID = 0L; |
|
310 |
|
311 /** |
|
312 * Component path |
|
313 */ |
|
314 private String componentPath = null; |
|
315 |
|
316 /** |
|
317 * MMP file path |
|
318 */ |
|
319 private File mmpPath = null; |
|
320 |
|
321 /** |
|
322 * Constructor |
|
323 */ |
|
324 TraceCompilerMain() { |
|
325 |
|
326 // Creates listeners and preferences |
|
327 modelListener = new TraceCompilerModelListener(); |
|
328 } |
|
329 |
|
330 /** |
|
331 * Creates the plug-ins to be registered with TraceCompiler |
|
332 * @throws TraceCompilerRootException if fail to create a valid plugins |
|
333 */ |
|
334 private void createPlugins() throws TraceCompilerRootException { |
|
335 |
|
336 // Get location of the TraceCompiler |
|
337 URL path = getClass().getProtectionDomain().getCodeSource() |
|
338 .getLocation(); |
|
339 String decodePluginsPath = path.getPath(); |
|
340 |
|
341 // If first character is forward slash and it is located before drive |
|
342 // letter remove it |
|
343 if (decodePluginsPath.charAt(INDEX_OF_FIRST_CHARACTER) == SourceConstants.FORWARD_SLASH_CHAR |
|
344 && decodePluginsPath.charAt(INDEX_OF_THIRD_CHARACTER) == SourceConstants.COLON_CHAR) { |
|
345 decodePluginsPath = decodePluginsPath.substring(1); |
|
346 } |
|
347 |
|
348 // Concatenate decode plugins path |
|
349 decodePluginsPath = decodePluginsPath.concat(DECODE_PLUGINS_PATH); |
|
350 |
|
351 // Replace slashes with correct separator character |
|
352 decodePluginsPath = decodePluginsPath.replace( |
|
353 SourceConstants.FORWARD_SLASH_CHAR, File.separatorChar); |
|
354 decodePluginsPath = decodePluginsPath.replace( |
|
355 SourceConstants.BACKSLASH_CHAR, File.separatorChar); |
|
356 File decodePluginsDir = new File(decodePluginsPath); |
|
357 String[] decodePlugins = decodePluginsDir.list(); |
|
358 if (decodePlugins != null) { |
|
359 for (int i = 0; i < decodePlugins.length; i++) { |
|
360 |
|
361 // Get decode plugin name |
|
362 String decodePluginName = decodePlugins[i]; |
|
363 |
|
364 // Get decode plugin path |
|
365 String decodePluginPath = decodePluginsPath |
|
366 + File.separatorChar + decodePluginName; |
|
367 |
|
368 // Decode plugin must be in own directory |
|
369 Boolean isDirectory = (new File(decodePluginPath)) |
|
370 .isDirectory(); |
|
371 if (isDirectory) { |
|
372 |
|
373 // Construct decode plugin engine class name |
|
374 String engineClassName = ENGINE_CLASS_NAME_TEMPLATE |
|
375 .replaceFirst(DECODE_PLUGIN_NAME_TAG, |
|
376 decodePluginName.substring(0, 1) |
|
377 .toUpperCase() |
|
378 + decodePluginName.substring(1)); |
|
379 |
|
380 // Construct decode plugin engine file name |
|
381 String engineFileName = ENGINE_FILE_NAME_TEMPLATE |
|
382 .replaceFirst(DECODE_PLUGIN_CLASS_NAME_TAG, |
|
383 engineClassName); |
|
384 String engineFileFullName = decodePluginPath |
|
385 + File.separatorChar + engineFileName; |
|
386 |
|
387 // Check does engine file exist |
|
388 Boolean exists = (new File(engineFileFullName)).exists(); |
|
389 if (exists) { |
|
390 String engineClassFullName = CLASS_TEMPLATE |
|
391 .replaceFirst(DECODE_PLUGIN_NAME_TAG, |
|
392 decodePluginName).replaceFirst( |
|
393 DECODE_PLUGIN_CLASS_NAME_TAG, |
|
394 engineClassName); |
|
395 try { |
|
396 Class<?> engineClass = Class |
|
397 .forName(engineClassFullName); |
|
398 TraceCompilerPlugin engine = (TraceCompilerPlugin) engineClass |
|
399 .newInstance(); |
|
400 plugIns.add(engine); |
|
401 TraceCompilerLogger.printInfo(Messages.getString(Messages.getString("TraceCompiler.DecodePlugin") + engineClassFullName + Messages.getString("TraceCompiler.Added"))); //$NON-NLS-1$ //$NON-NLS-2$ |
|
402 } catch (Exception e) { |
|
403 String msg = Messages.getString("TraceCompiler.DecodePlugin" + engineClassFullName + Messages.getString("TraceCompiler.AddingFailed")); //$NON-NLS-1$ //$NON-NLS-2$ |
|
404 throw new TraceCompilerRootException(msg, e); |
|
405 } |
|
406 } else { |
|
407 String msg = Messages.getString("TraceCompiler.DecodePluginFile") + Messages.getString("TraceCompiler.EngineFullName") + engineFileFullName + Messages.getString("TraceCompiler.DoesNotExist"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
|
408 throw new TraceCompilerRootException(msg, null); |
|
409 } |
|
410 } |
|
411 } |
|
412 } |
|
413 } |
|
414 |
|
415 /** |
|
416 * Parses the command line |
|
417 * |
|
418 * @param args |
|
419 * the arguments |
|
420 * @throws TraceCompilerRootException if arguments are invalid |
|
421 * @throws IOException |
|
422 */ |
|
423 private void parseCommandLine(ArrayList<String> list) throws TraceCompilerIllegalArgumentsException, IOException { |
|
424 TraceCompilerLogger.printInfo(Messages.getString("TraceCompiler.BuildingTracesMess")); //$NON-NLS-1$ |
|
425 Iterator<String> argIterator = list.iterator(); |
|
426 |
|
427 if (list.size() == 0) { |
|
428 printUsage(); |
|
429 System.exit(0); |
|
430 } |
|
431 while (argIterator.hasNext()) { |
|
432 String element = argIterator.next().trim(); |
|
433 Matcher m = singleSwitchPattern.matcher(element); |
|
434 |
|
435 if (m.matches()) { //it's one of the single switches |
|
436 if (element.equalsIgnoreCase(HELP_OPTION) || element.equalsIgnoreCase(HELP_OPTION_SF)) { |
|
437 printUsage(); |
|
438 System.exit(0); |
|
439 } |
|
440 if (element.equalsIgnoreCase(VERBOSE_OPTION) || element.equalsIgnoreCase(VERBOSE_OPTION_SF)) { |
|
441 TraceCompilerGlobals.setVerbose(true); |
|
442 TraceCompilerLogger.printInfo(Messages.getString("TraceCompiler.veboseEnabled")); //$NON-NLS-1$ |
|
443 continue; |
|
444 } |
|
445 if ( element.equalsIgnoreCase(VERSION_OPTION) || element.equalsIgnoreCase(VERSION_OPTION_SF)) { |
|
446 TraceCompilerLogger.printMessage(VERSION_TEXT + TraceCompilerVersion.getVersion()); |
|
447 System.exit(0); |
|
448 } |
|
449 if (element.equalsIgnoreCase(STOP_ON_ERROR_OPTION) || element.equalsIgnoreCase(STOP_ON_ERROR_OPTION_SF)) { |
|
450 TraceCompilerGlobals.setKeepGoing(false); |
|
451 TraceCompilerLogger.printInfo(Messages.getString("TraceCompiler.StopOnErrorEnabled")); //$NON-NLS-1$ |
|
452 continue; |
|
453 } |
|
454 TraceCompilerLogger.printMessage(Messages.getString("TraceCompiler.UnsupportedSwitch") + element); //$NON-NLS-1$ |
|
455 } else { |
|
456 m = valueSwitchPattern.matcher(element.trim()); |
|
457 if (m.matches()) { //it's one of the swithes with values |
|
458 if (m.group(1).equalsIgnoreCase(UID_SWITCH)) { |
|
459 // UID |
|
460 try { |
|
461 componentUID = Long.parseLong(m.group(2),TraceCompilerConstants.HEX_RADIX); |
|
462 TraceCompilerLogger.printInfo("Component UID: 0x" + Long.toHexString(componentUID)); //$NON-NLS-1$ |
|
463 if (componentUID <= 0L) { |
|
464 String msg = Messages.getString("TraceCompiler.componentUidIsNotValidExceptionText") + componentUID; //$NON-NLS-1$ |
|
465 throw new TraceCompilerIllegalArgumentsException(msg, null); |
|
466 } |
|
467 } catch (NumberFormatException e) { |
|
468 String msg = Messages.getString("TraceCompiler.componentUidIsNotValidExceptionText") + componentUID; //$NON-NLS-1$ |
|
469 throw new TraceCompilerIllegalArgumentsException(msg, null); |
|
470 } |
|
471 } else { |
|
472 if (m.group(1).equalsIgnoreCase(PRJ_NAME_SWITCH)) { |
|
473 // project name |
|
474 projectName = m.group(2); |
|
475 TraceCompilerLogger.printInfo(Messages.getString("TraceCompiler.CompNameSet") + projectName); //$NON-NLS-1$ |
|
476 } else { |
|
477 if (m.group(1).equalsIgnoreCase(MMP_PATH_SWITCH)) { |
|
478 //mmp path. for the moment only the mmp folder is used. |
|
479 mmpPath = new File(m.group(2)); |
|
480 TraceCompilerLogger.printInfo(Messages.getString("TraceCompiler.MMPPathSet") + mmpPath); //$NON-NLS-1$ |
|
481 } else { |
|
482 if (m.group(1).equalsIgnoreCase(TRACES_PATH_SWITCH)) { |
|
483 //traces path |
|
484 traces_path = m.group(2); |
|
485 } else { |
|
486 //unsupported switch |
|
487 TraceCompilerLogger.printMessage(Messages.getString("TraceCompiler.UnsupportedSwitch") + element); //$NON-NLS-1$ |
|
488 } |
|
489 } |
|
490 } |
|
491 } |
|
492 |
|
493 } else { |
|
494 //it must be a file name |
|
495 //it's a good time to stop TC here if the file does not exist |
|
496 if (!(new File(element)).exists()) { |
|
497 throw new TraceCompilerIllegalArgumentsException(Messages.getString("TraceCompiler.sourceFileDoesNotExist") + element, null); //$NON-NLS-1$ |
|
498 } |
|
499 sources.add(element); |
|
500 } |
|
501 } |
|
502 } |
|
503 |
|
504 // by now, if the user wanted just help or version they would have got it and TC stopped |
|
505 |
|
506 if (componentUID <= 0L) { |
|
507 String msg = Messages.getString("TraceCompiler.componentUidIsNotValidExceptionText") + componentUID; //$NON-NLS-1$ |
|
508 throw new TraceCompilerIllegalArgumentsException(msg, null); |
|
509 } |
|
510 |
|
511 if (projectName == null) { |
|
512 throw new TraceCompilerIllegalArgumentsException(Messages.getString("TraceCompiler.projectNameMissing"), null); //$NON-NLS-1$ |
|
513 } |
|
514 |
|
515 //if files have not been provided , get them from stdin |
|
516 if (sources.size() == 0) { |
|
517 //get them from the stdin |
|
518 readFromStdin(); |
|
519 } |
|
520 |
|
521 if (mmpPath == null ) { |
|
522 throw new TraceCompilerIllegalArgumentsException(Messages.getString("TraceCompiler.mmpPathMissing"), null); //$NON-NLS-1$ |
|
523 } else if (!isMmpValid()) { |
|
524 throw new TraceCompilerIllegalArgumentsException(Messages.getString("TraceCompiler.invalidMmpExceptionText") + mmpPath, null); //$NON-NLS-1$ |
|
525 } |
|
526 |
|
527 if (traces_path == null ) { |
|
528 throw new TraceCompilerIllegalArgumentsException(Messages.getString("TraceCompiler.tracesPathMissing"), null); //$NON-NLS-1$ |
|
529 } else { |
|
530 computeTracesPath(traces_path); |
|
531 } |
|
532 |
|
533 if (sources.size() == 0 ) { |
|
534 throw new TraceCompilerIllegalArgumentsException(Messages.getString("TraceCompiler.fileListMissing"), null); //$NON-NLS-1$ |
|
535 } |
|
536 |
|
537 //we have all parameters input and validated, register files. |
|
538 registerSourceFiles(sources); |
|
539 } |
|
540 |
|
541 |
|
542 /** |
|
543 * If traces path is relative, work out the full path relative to the location of the mmp file |
|
544 * @param path |
|
545 * @throws TraceCompilerIllegalArgumentsException |
|
546 */ |
|
547 private void computeTracesPath(String path) throws TraceCompilerIllegalArgumentsException { |
|
548 String traces_pathString = path; |
|
549 traces_pathString = traces_pathString.replace('/', File.separatorChar); |
|
550 traces_pathString = traces_pathString.replace('\\', File.separatorChar); |
|
551 |
|
552 File traces_path = new File(traces_pathString); |
|
553 |
|
554 Pattern p = Pattern.compile("(([a-zA-Z]:[\\\\/])|([\\\\/])).*"); //$NON-NLS-1$ |
|
555 Matcher m = p.matcher(traces_pathString); |
|
556 |
|
557 if (!m.matches() /* workaround for isAbsolute in java */) { |
|
558 //traces path is relative to mmp location |
|
559 traces_pathString = mmpPath.getAbsoluteFile().getParent() + File.separator + traces_pathString; |
|
560 } |
|
561 |
|
562 traces_path = new File(traces_pathString); |
|
563 |
|
564 if (traces_path.isDirectory() && !traces_path.canWrite()) { |
|
565 throw new TraceCompilerIllegalArgumentsException(Messages.getString("TraceCompiler.TracesPathWriteProtected") + traces_path, null); //$NON-NLS-1$ |
|
566 } |
|
567 |
|
568 boolean dirExists = true; |
|
569 if (!traces_path.exists()) { |
|
570 dirExists = FileUtils.createDirectories(traces_path); |
|
571 } |
|
572 if (!dirExists) { |
|
573 throw new TraceCompilerIllegalArgumentsException(Messages.getString("TraceCompiler.mkdirFailed") + traces_path, null); //$NON-NLS-1$ |
|
574 } |
|
575 |
|
576 //set component path and trace folder |
|
577 componentPath = traces_path.getParent(); |
|
578 ProjectEngine.traceFolderName = traces_path.getName(); |
|
579 TraceCompilerLogger.printInfo(Messages.getString("TraceCompiler.settingComponentPath") + componentPath); //$NON-NLS-1$ |
|
580 TraceCompilerLogger.printInfo(Messages.getString("TraceCompiler.settingTracesPath") + ProjectEngine.traceFolderName); //$NON-NLS-1$ |
|
581 } |
|
582 |
|
583 private static void printUsage() { |
|
584 TraceCompilerLogger.printMessage(VERSION_TEXT + TraceCompilerVersion.getVersion()); |
|
585 TraceCompilerLogger.printMessage(USAGE); |
|
586 } |
|
587 |
|
588 /** |
|
589 * Read information from STDIN |
|
590 * @throws IOException if fails to read the input |
|
591 * @throws TraceCompilerRootException if the list of files is empty |
|
592 */ |
|
593 private void readFromStdin() throws IOException, TraceCompilerIllegalArgumentsException { |
|
594 TraceCompilerLogger.printInfo(Messages.getString("TraceCompiler.ReadingFilesMess") + ENDOFSOURCEFILES); //$NON-NLS-1$ |
|
595 // Create reader |
|
596 BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); |
|
597 |
|
598 String line = stdin.readLine(); |
|
599 |
|
600 while (line != null) { |
|
601 line = line.trim(); |
|
602 if (line.length() > 0) { |
|
603 // End of source files received |
|
604 if (line.equals(ENDOFSOURCEFILES)) { |
|
605 break; |
|
606 } |
|
607 line = line.replaceAll("\\s+", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
|
608 Matcher m = valueSwitchPattern.matcher(line.trim()); |
|
609 //because mmp path and traces path can be very long, we should allow them to be input'ed through stdin too. |
|
610 if (m.matches()) { //it's one of the swithes with values |
|
611 if (m.group(1).equalsIgnoreCase(MMP_PATH_SWITCH)) { |
|
612 //mmp path. for the moment only the mmp folder is used. |
|
613 mmpPath = new File(m.group(2)); |
|
614 TraceCompilerLogger.printInfo(Messages.getString("TraceCompiler.MMPPathSet") + mmpPath); //$NON-NLS-1$ |
|
615 } else { |
|
616 if (m.group(1).equalsIgnoreCase(TRACES_PATH_SWITCH)) { |
|
617 //traces path |
|
618 traces_path = m.group(2); |
|
619 } else { |
|
620 //unsupported switch |
|
621 TraceCompilerLogger.printMessage(Messages.getString("TraceCompiler.UnsupportedSwitch") + line); //$NON-NLS-1$ |
|
622 } |
|
623 } |
|
624 } else { |
|
625 |
|
626 //it must be a file name |
|
627 //it's a good time to stop TC here if the file does not exist |
|
628 if (!(new File(line)).exists()) { |
|
629 throw new TraceCompilerIllegalArgumentsException(Messages.getString("TraceCompiler.sourceFileDoesNotExist") + line, null); //$NON-NLS-1$ |
|
630 } |
|
631 sources.add(line); |
|
632 } |
|
633 } |
|
634 // Read new line from STDIN |
|
635 line = stdin.readLine(); |
|
636 } |
|
637 stdin.close(); |
|
638 } |
|
639 |
|
640 /** |
|
641 * Registers source files |
|
642 * |
|
643 * @param files |
|
644 */ |
|
645 private void registerSourceFiles(ArrayList<String> files) throws TraceCompilerIllegalArgumentsException { |
|
646 if (sources.size() == 0) { |
|
647 throw new TraceCompilerIllegalArgumentsException(Messages.getString("TraceCompiler.noSourceFilesExceptionText"), null); //$NON-NLS-1$ |
|
648 } |
|
649 if (files.size() > 0) { |
|
650 String[] fileArr = new String[files.size()]; |
|
651 files.toArray(fileArr); |
|
652 |
|
653 // Sets the source files to the TraceCompiler document |
|
654 // factory. It will create a document from each source in the array |
|
655 FileDocumentMonitor.setFiles(fileArr); |
|
656 DocumentFactory.registerDocumentFramework( |
|
657 new FileDocumentMonitor(), StringDocumentFactory.class); |
|
658 } |
|
659 } |
|
660 |
|
661 /** |
|
662 * Initializes TraceCompiler |
|
663 * @throws TraceCompilerRootException if fail to initialize the plugins |
|
664 * @throws TraceCompilerException |
|
665 */ |
|
666 private void start() throws TraceCompilerRootException, TraceCompilerException { |
|
667 |
|
668 // Starts TraceCompiler. This is normally called from the Eclipse |
|
669 // plug-in |
|
670 // activator, but in console case that does not exist |
|
671 TraceCompilerEngineGlobals.start(); |
|
672 |
|
673 //Reads the GroupId values from opensystemtrace_types.h |
|
674 //If this fails a message is logged and trace compiler stops |
|
675 GroupNames.initialiseGroupName(); |
|
676 |
|
677 |
|
678 // Registers a view to TraceCompiler |
|
679 TraceCompilerEngineGlobals |
|
680 .setView(new TraceCompilerView(componentPath)); |
|
681 |
|
682 // Registers all plug-in components |
|
683 for (TraceCompilerPlugin plugin : plugIns) { |
|
684 TraceCompilerEngineGlobals.registerPlugin(plugin); |
|
685 } |
|
686 // Adds a model event listener |
|
687 TraceCompilerEngineGlobals.getTraceModel().addModelListener( |
|
688 modelListener); |
|
689 TraceCompilerEngineGlobals.getTraceModel().addExtensionListener( |
|
690 modelListener); |
|
691 TraceCompilerEngineGlobals.getTraceModel().getExtension( |
|
692 TraceLocationList.class).addLocationListListener(modelListener); |
|
693 TraceCompilerEngineGlobals.getTraceModel().addProcessingListener(modelListener); |
|
694 } |
|
695 |
|
696 /** |
|
697 * Parses the sources and generates trace files |
|
698 * @throws Exception |
|
699 */ |
|
700 private void buildTraceFiles() throws Exception { |
|
701 TraceCompilerEngineInterface tbi = TraceCompilerEngineGlobals |
|
702 .getTraceCompiler(); |
|
703 try { |
|
704 // Opens a trace project |
|
705 |
|
706 // Set project path before opening project |
|
707 TraceCompilerEngineGlobals.setProjectPath(componentPath); |
|
708 tbi.openProject(projectName); |
|
709 TraceModel model = TraceCompilerEngineGlobals.getTraceModel(); |
|
710 if (model.isValid()) { |
|
711 model.setID((int) componentUID); |
|
712 |
|
713 // Location errors are printed after a file changes, but the |
|
714 // last file is not detected by the listener |
|
715 if (modelListener.getErrors().size() > 0) { |
|
716 modelListener.printLocationErrors(); |
|
717 tbi.closeProject(); |
|
718 throw new TraceCompilerRootException(null, null); |
|
719 } |
|
720 tbi.exportProject(); |
|
721 tbi.closeProject(); |
|
722 } else { |
|
723 String msg = Messages.getString("TraceCompiler.ProjectCancelledMess"); //$NON-NLS-1$ |
|
724 throw new TraceCompilerRootException(msg, null); |
|
725 } |
|
726 } catch (TraceCompilerException e) { |
|
727 TraceCompilerEngineGlobals.getEvents().postError(e); |
|
728 throw new TraceCompilerRootException(Messages.getString("TraceCompiler.BuildFailed"), e); //$NON-NLS-1$ |
|
729 } |
|
730 } |
|
731 |
|
732 /** |
|
733 * Shuts down TraceCompiler |
|
734 * @throws TraceCompilerException |
|
735 */ |
|
736 private void shutdown() throws TraceCompilerException { |
|
737 for (TraceCompilerPlugin plugin : plugIns) { |
|
738 TraceCompilerEngineGlobals.unregisterPlugin(plugin); |
|
739 } |
|
740 TraceCompilerEngineGlobals.shutdown(); |
|
741 } |
|
742 |
|
743 /** |
|
744 * Checks if the MMP file is valid |
|
745 * |
|
746 * @return true if MMP file is valid |
|
747 */ |
|
748 private boolean isMmpValid() { |
|
749 boolean valid = false; |
|
750 String pathStr = mmpPath.getAbsolutePath(); |
|
751 |
|
752 if (mmpPath.exists() && pathStr.length() > MMP_FILE_TYPE.length()) { |
|
753 String end = pathStr.substring(pathStr.length() - MMP_FILE_TYPE.length()); |
|
754 if (end.equalsIgnoreCase(MMP_FILE_TYPE)) { |
|
755 valid = true; |
|
756 } else { |
|
757 TraceCompilerLogger.printError(Messages.getString("TraceCompiler.invalidMmpExceptionText") + mmpPath.getAbsolutePath()); //$NON-NLS-1$ |
|
758 } |
|
759 } else { |
|
760 TraceCompilerLogger.printError(Messages.getString("TraceCompiler.InvalidMMP2") + mmpPath.getAbsolutePath()); //$NON-NLS-1$ |
|
761 } |
|
762 return valid; |
|
763 |
|
764 } |
|
765 |
|
766 } |