Esempio n. 1
0
 public ConfigPreprocessorEnvironment(Uri input_file_path, PreprocessorUrlResolver resolver)
 {
     // Bottom-most stack frame
     _env_stack.Push(new ConstantDict());
     // Record the input file as the outer-most "include"
     _include_stack.Push(input_file_path);
     _fileset[input_file_path.LocalPath] = true;
     _resolver = resolver;
 }
 public ConfigPreprocessorEnvironment( Uri input_file_path, PreprocessorUrlResolver resolver )
 {
     // Bottom-most stack frame
     _env_stack.Push( new ConstantDict() );
     // Record the input file as the outer-most "include"
     _include_stack.Push( input_file_path );
     _fileset[ input_file_path.LocalPath ] = true;
     _resolver = resolver;
 }                        
        /// <summary>
        /// Run the given input reader through the preprocessor, writing it
        /// to the given output writer.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="output"></param>
        /// <returns></returns>
        /// <param name="resolver"></param>
        /// <param name="input_uri"></param>
        /// <exception cref="EvaluationException">Error occurred during the evaluation of a constant</exception>
        public ConfigPreprocessorEnvironment PreProcess(XmlReader input,
                                                         XmlWriter output,
            PreprocessorUrlResolver resolver,
            Uri input_uri
            )
        {
            XsltSettings xslt_settings = new XsltSettings(true, true);

            #if DEBUG
            XslCompiledTransform xslt_preprocess = new XslCompiledTransform(true);
            #else
            XslCompiledTransform xslt_preprocess = new XslCompiledTransform( false );
            #endif

            using (XmlReader xslt_reader = XmlReader.Create(Utils.GetAssemblyResourceStream(
                    "ThoughtWorks.CruiseControl.Core.configuration.preprocessor.ConfigPreprocessor.xslt")))
            {
                xslt_preprocess.Load(
                    xslt_reader, xslt_settings, new XmlUrlResolver());
            }

            // Install a special XmlResolver for the resolution of
            // preprocessor includes (which use the xslt document() function).
            // The resolver keeps track of the URI path of the outermost document and any includes
            // and uses it to resolve relative include paths.
            if ( resolver == null )
            {
                resolver = new PreprocessorUrlResolver();
            }

            XsltArgumentList xslt_args = new XsltArgumentList();

            Uri base_uri = input_uri ??
                           ( String.IsNullOrEmpty( input.BaseURI )
                                 ? new Uri(
                                       Path.Combine(
                                           programDataFolder,
                                           "nofile.xml" ) )
                                 : new Uri( input.BaseURI ) );
            _current_env = new ConfigPreprocessorEnvironment( base_uri, resolver );

            // The XSLT calls extension functions in _current_env.
            xslt_args.AddExtensionObject("environment", _current_env);
            try
            {
                xslt_preprocess.Transform( input, xslt_args, output, null );
            }
            catch( XsltException ex )
            {
                if ( ex.InnerException != null )
                {
                    // Get the _remoteStackTraceString of the Exception class
                    FieldInfo remoteStackTraceString = typeof(Exception).GetField("_remoteStackTraceString",
                    BindingFlags.Instance | BindingFlags.NonPublic );

                    // TODO: Remove this workaround after Mono Bug 425512 is resolved (CCNET-1244)
                    if (remoteStackTraceString == null)
                        remoteStackTraceString = typeof(Exception).GetField("remote_stack_trace",
                            BindingFlags.Instance | BindingFlags.NonPublic);

                    // Set the InnerException._remoteStackTraceString to the current InnerException.StackTrace
                    remoteStackTraceString.SetValue( ex.InnerException,
                    ex.InnerException.StackTrace + Environment.NewLine );
                    // Throw the new exception
                    throw ex.InnerException;
                }
                throw;
            }

            // Notify listeners of all files encountered.
            if ( SubfileLoaded != null )
            {
                foreach ( string path in _current_env.Fileset )
                {
                    SubfileLoaded( path );
                }
            }

            return _current_env;
        }