diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/UI/Plugins/CAPluginCrashAnalyser/CommandLine/Inputs/CACmdLineInputParameters.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/UI/Plugins/CAPluginCrashAnalyser/CommandLine/Inputs/CACmdLineInputParameters.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,316 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +using System; +using System.Text; +using System.IO; +using System.Collections.Generic; +using CrashAnalyserEngine.Plugins; +using CrashItemLib.Engine; +using CrashItemLib.Crash; +using CrashItemLib.Crash.Container; +using CrashItemLib.PluginAPI; +using CrashAnalyserEngine.Engine; +using CrashAnalyserEngine.Interfaces; +using CAPCrashAnalysis.Plugin; +using SymbianUtils.FileSystem.Utilities; +using SymbianXmlInputLib.Parser; +using SymbianXmlInputLib.Parser.Nodes; +using SymbianXmlInputLib.Elements; +using SymbianXmlInputLib.Elements.Types.Category; +using SymbianXmlInputLib.Elements.Types.Extension; +using SymbianXmlInputLib.Elements.Types.FileSystem; +using SymbianXmlInputLib.Elements.Types.Command; +using CrashItemLib.Sink; + +namespace CAPCrashAnalysis.CommandLine +{ + internal class CACmdLineInputParameters + { + #region Constructors + public CACmdLineInputParameters( CAPluginCrashAnalysis aEngine ) + { + iEngine = aEngine; + // + Version version = aEngine.UIManager.UIVersion; + string commandLine = aEngine.UIManager.UICommandLineArguments; + // + iSinkParams = new CISinkSerializationParameters( version, commandLine ); + } + #endregion + + #region API + public void Read( string aFileName ) + { + Trace( "[CmdInput] Read() - aFileName: " + aFileName ); + try + { + // First create the tree + SXILDocument doc = CreateDocumentTree( aFileName ); + + // Then convert it to the list of elements that we care about + ExtractData( doc ); + } + catch ( CACmdLineException cmdLineException ) + { + Trace( "[CmdInput] Read() - CACmdLineException: " + cmdLineException.Message + " " + cmdLineException.StackTrace ); + throw cmdLineException; + } + catch ( Exception generalException ) + { + Trace( "[CmdInput] Read() - generalException: " + generalException.Message + " " + generalException.StackTrace ); + throw new CACmdLineException( "Error reading input xml file", generalException, CAPlugin.KErrCommandLinePluginArgumentsFileInvalid ); + } + Trace( "[CmdInput] Read() - read OK: " + aFileName ); + } + #endregion + + #region Properties + public CISinkSerializationParameters SinkParameters + { + get { return iSinkParams; } + } + + public CACmdLineFSEntityList SourceFiles + { + get { return iSources; } + } + + public CACmdLineFSEntityList MetaDataFiles + { + get { return iMetaData; } + } + #endregion + + #region Internal constants + private const string KInputFileDocumentRootNode = "crash_analysis"; + private const string KInputFileCategorySource = "source"; + private const string KInputFileCategoryDebugMetaData = "debug_meta_data"; + private const string KInputFileCategoryParameters = "parameters"; + private const string KInputFileCategoryOutput = "output"; + private const string KInputFileCommandNameAnalysis = "analysis_type"; + private const string KInputFileCommandNameAnalysisFull = "FULL"; + private const string KInputFileCommandNameAnalysisSummary = "SUMMARY"; + #endregion + + #region Internal methods + private SXILDocument CreateDocumentTree( string aFileName ) + { + SXILDocument doc = new SXILDocument(); + + // Read input file into document + using ( SXILParser parser = new SXILParser( aFileName, KInputFileDocumentRootNode, doc ) ) + { + parser.CategoryAdd( KInputFileCategorySource, new SXILParserNodeFileSystem() ); + parser.CategoryAdd( KInputFileCategoryDebugMetaData, new SXILParserNodeFileSystem() ); + parser.CategoryAdd( KInputFileCategoryParameters, + new SXILParserNodeCommand(), + new SXILParserNodeExtension() + ); + parser.CategoryAdd( KInputFileCategoryOutput, new SXILParserNodeFileSystem() ); + parser.Parse(); + } + + return doc; + } + + private void ExtractData( SXILDocument aDocument ) + { + foreach ( SXILElement element in aDocument ) + { + if ( element is SXILElementCategory ) + { + SXILElementCategory category = (SXILElementCategory) element; + string name = category.Name.ToLower(); + // + switch ( name ) + { + case KInputFileCategorySource: + ExtractFileList( iSources, category ); + break; + case KInputFileCategoryDebugMetaData: + // The debug meta data engine doesn't support directories anymore + // so we have to expand all directories to files. + ExtractFileList( iMetaData, category ); + break; + case KInputFileCategoryParameters: + ExtractParameters( category ); + break; + case KInputFileCategoryOutput: + ExtractOutput( category ); + break; + } + } + } + + // We don't require debug meta data if performing a summary operation. Otherwise, we do. + if ( iMetaData.Count == 0 && iSinkParams.DetailLevel == CISinkSerializationParameters.TDetailLevel.EFull ) + { + Trace( "[CmdInput] ExtractData() - WARNING - no debug meta data supplied for full analysis." ); + } + + } + + private void ExtractFileList( CACmdLineFSEntityList aList, SXILElementCategory aCategory ) where T : CACmdLineFSEntity, new() + { + foreach ( SXILElement element in aCategory ) + { + if ( element is SXILElementFile ) + { + SXILElementFile file = (SXILElementFile) element; + Trace( "[CmdInput] ExtractFileList() - file: " + file ); + if ( !file.Exists ) + { + throw new FileNotFoundException( "File not found", file.Name ); + } + // + aList.Add( file ); + } + else if ( element is SXILElementDirectory ) + { + SXILElementDirectory dir = (SXILElementDirectory) element; + Trace( "[CmdInput] ExtractFileList() - dir: " + dir ); + if ( !dir.Exists ) + { + throw new DirectoryNotFoundException( "Directory not found: " + dir.Name ); + } + // + aList.AddRange( dir.Files ); + } + } + } + + private void ExtractParameters( SXILElementCategory aCategory ) + { + foreach ( SXILElement element in aCategory ) + { + if ( element is SXILElementExtension ) + { + SXILElementExtension entry = (SXILElementExtension) element; + // + string extension = entry.Name; + if ( !extension.StartsWith( "." ) ) + { + extension = "." + extension; + } + // + if ( entry.Type == SXILElementExtension.TType.ETypeFailure ) + { + Trace( "[CmdInput] ExtractFileList() - failed extension: " + extension ); + iSinkParams.FileExtensionFailed = extension; + } + else if ( entry.Type == SXILElementExtension.TType.ETypeSuccess ) + { + Trace( "[CmdInput] ExtractFileList() - success extension: " + extension ); + iSinkParams.FileExtensionSuccess = extension; + } + } + else if ( element is SXILElementCommand ) + { + SXILElementCommand entry = (SXILElementCommand) element; + // + if ( entry.Name == KInputFileCommandNameAnalysis ) + { + string type = entry.Details.Trim().ToUpper(); + Trace( "[CmdInput] ExtractFileList() - command: " + type ); + switch ( type ) + { + case KInputFileCommandNameAnalysisFull: + iSinkParams.DetailLevel = CISinkSerializationParameters.TDetailLevel.EFull; + break; + case KInputFileCommandNameAnalysisSummary: + iSinkParams.DetailLevel = CISinkSerializationParameters.TDetailLevel.ESummary; + break; + default: + throw new NotSupportedException( "Unsupported analysis type" ); + } + } + else + { + throw new NotSupportedException( "Unsupported command: " + entry.Name ); + } + } + } + } + + private void ExtractOutput( SXILElementCategory aCategory ) + { + // We either output to file or directory - if both are present then bail out + FileInfo savedFile = null; + DirectoryInfo savedDir = null; + // + foreach ( SXILElement element in aCategory ) + { + if ( element is SXILElementFile ) + { + if ( savedFile != null ) + { + throw new InvalidDataException( "Output file already specified" ); + } + else + { + SXILElementFile file = (SXILElementFile) element; + savedFile = file; + } + } + else if ( element is SXILElementDirectory ) + { + if ( savedDir != null ) + { + throw new InvalidDataException( "Output directory already specified" ); + } + else + { + SXILElementDirectory dir = (SXILElementDirectory) element; + savedDir = dir; + } + } + } + + // Ensure we have only one type + if ( savedFile != null && savedDir != null ) + { + throw new InvalidDataException( "Output must be EITHER file or directory" ); + } + else if ( savedFile != null ) + { + iSinkParams.OutputFile = savedFile; + } + else if ( savedDir != null ) + { + iSinkParams.OutputDirectory = savedDir; + } + } + + public void Trace( string aMessage ) + { + iEngine.UIManager.UITrace( aMessage ); + } + + public void Trace( string aFormat, params object[] aParams ) + { + iEngine.UIManager.UITrace( aFormat, aParams ); + } + #endregion + + #region Data members + private readonly CAPluginCrashAnalysis iEngine; + private readonly CISinkSerializationParameters iSinkParams; + private CACmdLineFSEntityList iMetaData = new CACmdLineFSEntityList(); + private CACmdLineFSEntityList iSources = new CACmdLineFSEntityList(); + #endregion + } +}