~ubuntu-branches/ubuntu/feisty/nant/feisty

« back to all changes in this revision

Viewing changes to src/NAnt.DotNet/Tasks/ResGenTask.cs

  • Committer: Bazaar Package Importer
  • Author(s): Dave Beckett
  • Date: 2006-06-12 23:30:36 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060612233036-a1uwh0949z0218ep
Tags: 0.84+0.85-rc4-1
* New upstream release
* Acknowledge NMU (Closes: #372588)
* Standards-Version 3.7.2
* Update to latest CLI policy package split.  Build-Depends-Indep: on
  cli-common-dev, libmono-winforms1.0-cil, libmono-winforms2.0-cil and
  mono-gmcs to get 1.0 and 2.0 packages
* Removed patches no longer needed:
  - 01-AssemblyInfoTask.cs.patch
  - 02-ScriptTask.cs.patch
  - 03-XmlResultFormatter.cs.patch
  - 04-SourceControl.patch
  - 05-ExceptionTest.cs

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
// Giuseppe Greco (giuseppe.greco@agamura.com)
24
24
 
25
25
using System;
 
26
using System.Collections;
26
27
using System.Collections.Specialized;
27
28
using System.Diagnostics;
28
29
using System.Globalization;
29
30
using System.IO;
 
31
using System.Text;
30
32
using System.Xml;
31
33
using System.Xml.XPath;
32
34
 
78
80
    public class ResGenTask : ExternalProgramBase {
79
81
        #region Private Instance Fields
80
82
 
81
 
        private string _arguments;
 
83
        private StringBuilder _arguments = new StringBuilder();
82
84
        private AssemblyFileSet _assemblies = new AssemblyFileSet();
83
85
        private FileInfo _inputFile; 
84
86
        private FileInfo _outputFile;
88
90
        private DirectoryInfo _toDir;
89
91
        private DirectoryInfo _workingDirectory;
90
92
        private bool _useSourcePath;
 
93
        private ArrayList _qualifiedResources = new ArrayList();
91
94
 
92
95
        // framework configuration settings
93
96
        private bool _supportsAssemblyReferences;
101
104
 
102
105
        #endregion Private Static Fields
103
106
 
104
 
 
105
107
        #region Public Instance Properties
106
108
 
107
109
        /// <summary>
194
196
            set { _supportsExternalFileReferences = value; }
195
197
        }
196
198
 
 
199
        /// <summary>
 
200
        /// For internal use only !
 
201
        /// </summary>
 
202
        public ArrayList QualifiedResources {
 
203
            get { return _qualifiedResources; }
 
204
        }
 
205
 
197
206
        #endregion Public Instance Properties
198
207
 
199
208
        #region Private Instance Properties
200
209
 
201
210
        private bool RequiresAssemblyReferences {
202
211
            get {
203
 
                if (Resources.FileNames.Count > 0) {
 
212
                if (Resources.FileNames.Count > 0 || QualifiedResources.Count > 0) {
204
213
                    foreach (string resourceFile in Resources.FileNames) {
205
214
                        if (ReferencesThirdPartyAssemblies(resourceFile)) {
206
215
                            return true;
207
216
                        }
208
217
                    }
 
218
 
 
219
                    foreach (QualifiedResource resource in QualifiedResources) {
 
220
                        if (ReferencesThirdPartyAssemblies(resource.Input.FullName)) {
 
221
                            return true;
 
222
                        }
 
223
                    }
209
224
                } else if (InputFile != null) {
210
225
                    return ReferencesThirdPartyAssemblies(InputFile.FullName);
211
226
                }
242
257
        /// The command line arguments for the external program.
243
258
        /// </value>
244
259
        public override string ProgramArguments { 
245
 
            get { return _arguments; } 
 
260
            get { return _arguments.ToString(); } 
246
261
        }
247
262
 
248
263
        /// <summary>
351
366
                    Path.GetFileName(base.ProgramFileName));
352
367
            } else {
353
368
                foreach (string assembly in Assemblies.FileNames) {
354
 
                    AppendArgument(string.Format(CultureInfo.InvariantCulture,
355
 
                        " /r:\"{0}\"", assembly));
 
369
                    _arguments.Insert(0, string.Format(CultureInfo.InvariantCulture,
 
370
                        " /r:\"{0}\" ", assembly));
356
371
                }
357
372
            }
358
373
 
373
388
                Resources.BaseDirectory = new DirectoryInfo(Project.BaseDirectory);
374
389
            }
375
390
 
376
 
            _arguments = "";
377
 
            if (Resources.FileNames.Count > 0) {
 
391
            // clear buffer
 
392
            _arguments.Length = 0;
 
393
 
 
394
            if (Resources.FileNames.Count > 0 || QualifiedResources.Count > 0) {
378
395
                if (OutputFile != null) {
379
396
                    throw new BuildException(ResourceUtils.GetString("NA2026"), Location);
380
397
                }
381
 
                foreach (string filename in Resources.FileNames) {
 
398
 
 
399
                foreach (string fileName in Resources.FileNames) {
 
400
                    FileInfo inputFile = new FileInfo(fileName);
382
401
                    FileInfo outputFile = GetOutputFile(new FileInfo(Path.Combine(
383
 
                        Path.GetDirectoryName(filename), Resources.GetManifestResourceName(filename))));
384
 
 
385
 
                    if (NeedsCompiling(new FileInfo(filename), outputFile)) {
386
 
                        // ensure output directory exists
387
 
                        if (!outputFile.Directory.Exists) {
388
 
                            outputFile.Directory.Create();
389
 
                        }
390
 
 
391
 
                        string cmdLineArg = string.Format(CultureInfo.InvariantCulture, 
392
 
                            " \"{0},{1}\"", filename, outputFile.FullName);
393
 
 
394
 
                        // check if adding arguments to compile current resx to 
395
 
                        // total command line would cause it to exceed maximum
396
 
                        // length
397
 
                        bool maxCmdLineExceeded = (_arguments.Length + cmdLineArg.Length > _maxCmdLineLength);
398
 
 
399
 
                        // if this is the first resx that we're compiling, or the
400
 
                        // first one of the next execution of the resgen tool, then
401
 
                        // add options to command line
402
 
                        if (StringUtils.IsNullOrEmpty(_arguments) || maxCmdLineExceeded) {
403
 
                            if (UseSourcePath) {
404
 
                                if (SupportsExternalFileReferences) {
405
 
                                    cmdLineArg = " /usesourcepath";
406
 
                                } else {
407
 
                                    Log(Level.Warning, ResourceUtils.GetString(
408
 
                                        "String_ResourceCompilerDoesNotSupportExternalReferences"), 
409
 
                                        Project.TargetFramework.Description);
410
 
                                }
411
 
                            }
412
 
 
413
 
                            cmdLineArg = "/compile" + cmdLineArg;
414
 
                        }
415
 
 
416
 
                        // if maximum length would have been exceeded by compiling
417
 
                        // the current resx file, then first execute the resgen
418
 
                        // tool
419
 
                        if (maxCmdLineExceeded) {
420
 
                            try {
421
 
                                // call base class to do the work
422
 
                                base.ExecuteTask();
423
 
                            } catch {
424
 
                                // we only need to remove temporary directory when 
425
 
                                // an error occurred and if it was actually created
426
 
                                if (_workingDirectory != null) {
427
 
                                    // delete temporary directory and all files in it
428
 
                                    DeleteTask deleteTask = new DeleteTask();
429
 
                                    deleteTask.Project = Project;
430
 
                                    deleteTask.Parent = this;
431
 
                                    deleteTask.InitializeTaskConfiguration();
432
 
                                    deleteTask.Directory = _workingDirectory;
433
 
                                    deleteTask.Threshold = Level.None; // no output in build log
434
 
                                    deleteTask.Execute();
435
 
                                }
436
 
 
437
 
                                // rethrow exception
438
 
                                throw;
439
 
                            }
440
 
 
441
 
                            // reset command line arguments as we've processed them
442
 
                            _arguments = string.Empty;
443
 
                        }
444
 
 
445
 
                        // append command line arguments to compile current resx
446
 
                        // file to the total command line
447
 
                        AppendArgument(cmdLineArg);
448
 
                    }
 
402
                        inputFile.DirectoryName, Resources.GetManifestResourceName(fileName))));
 
403
                    WriteCommandLineOptions(inputFile, outputFile);
 
404
                }
 
405
 
 
406
                // used by <solution> task
 
407
                foreach (QualifiedResource resource in QualifiedResources) {
 
408
                    WriteCommandLineOptions(resource.Input, resource.Output);
449
409
                }
450
410
            } else {
451
411
                // Single file situation
463
423
 
464
424
                    if (UseSourcePath) {
465
425
                        if (SupportsExternalFileReferences) {
466
 
                            AppendArgument("/usesourcepath");
 
426
                            _arguments.Append("/useSourcePath");
467
427
                        } else {
468
428
                            Log(Level.Warning, ResourceUtils.GetString(
469
429
                                "String_ResourceCompilerDoesNotSupportExternalReferences"), 
471
431
                        }
472
432
                    }
473
433
 
474
 
                    AppendArgument(string.Format(CultureInfo.InvariantCulture, 
 
434
                    _arguments.Append(string.Format(CultureInfo.InvariantCulture, 
475
435
                        " \"{0}\" \"{1}\"", InputFile.FullName, outputFile.FullName));
476
436
                }
477
437
            }
478
438
 
479
 
            if (!StringUtils.IsNullOrEmpty(_arguments)) {
 
439
            if (_arguments.Length != 0) {
480
440
                try {
481
441
                    // call base class to do the work
482
442
                    base.ExecuteTask();
513
473
                }
514
474
            }
515
475
 
 
476
            foreach (QualifiedResource resource in QualifiedResources) {
 
477
                resource.Output.Delete();
 
478
            }
 
479
 
516
480
            if (InputFile != null) {
517
481
                FileInfo outputFile = GetOutputFile(InputFile);
518
482
                if (InputFile.FullName != outputFile.FullName) {
574
538
            return false;
575
539
        }
576
540
 
577
 
        /// <summary>
578
 
        /// Adds a command line argument to the command line for the external
579
 
        /// program that is used to convert the resource files.
580
 
        /// </summary>
581
 
        /// <param name="s">The argument that should be added to the command line.</param>
582
 
        protected void AppendArgument(string s) {
583
 
            _arguments += s;
584
 
        }
585
 
        
586
541
        #endregion Protected Instance Methods
587
542
 
588
543
        #region Private Instance Methods
641
596
                using (StreamReader sr = new StreamReader(resourceFile, true)) {
642
597
                    XPathDocument xpathDoc = new XPathDocument(new XmlTextReader(sr));
643
598
 
644
 
                    // determine the number of <data> elements that have a "type"
645
 
                    // attribute with a value that does not start with "System."
646
 
                    // and is not fully qualified
647
 
                    int count = xpathDoc.CreateNavigator().Select("/root/data[@type and not(starts-with(@type, 'System.') and contains(@type,'PublicKeyToken='))]").Count;
 
599
                    // determine the number of <data> elements that either have
 
600
                    // a "mimetype" attribute (meaning it contains a serialized
 
601
                    // instance that might be of a referenced assembly) or a
 
602
                    // "type" attribute with a value that does not start with 
 
603
                    // "System." and is not fully qualified
 
604
                    int count = xpathDoc.CreateNavigator().Select("/root/data[@mimetype or (@type and not(starts-with(@type, 'System.') and contains(@type,'PublicKeyToken=')))]").Count;
648
605
 
649
606
                    // if there are no <data> elements of a third party type, we 
650
607
                    // assume that the resource file does not reference types from
706
663
            }
707
664
        }
708
665
 
 
666
        private void WriteCommandLineOptions(FileInfo inputFile, FileInfo outputFile) {
 
667
            if (NeedsCompiling(inputFile, outputFile)) {
 
668
                // ensure output directory exists
 
669
                if (!outputFile.Directory.Exists) {
 
670
                    outputFile.Directory.Create();
 
671
                }
 
672
 
 
673
                string cmdLineArg = string.Format(CultureInfo.InvariantCulture, 
 
674
                    " \"{0},{1}\"", inputFile, outputFile.FullName);
 
675
 
 
676
                // check if adding arguments to compile current resx to 
 
677
                // total command line would cause it to exceed maximum
 
678
                // length
 
679
                bool maxCmdLineExceeded = (_arguments.Length + cmdLineArg.Length > _maxCmdLineLength);
 
680
 
 
681
                // if this is the first resx that we're compiling, or the
 
682
                // first one of the next execution of the resgen tool, then
 
683
                // add options to command line
 
684
                if (_arguments.Length == 0 || maxCmdLineExceeded) {
 
685
                    if (UseSourcePath) {
 
686
                        if (SupportsExternalFileReferences) {
 
687
                            cmdLineArg = " /useSourcePath /compile" + cmdLineArg;
 
688
                        } else {
 
689
                            cmdLineArg = " /compile" + cmdLineArg;
 
690
 
 
691
                            Log(Level.Warning, ResourceUtils.GetString(
 
692
                                "String_ResourceCompilerDoesNotSupportExternalReferences"), 
 
693
                                Project.TargetFramework.Description);
 
694
                        }
 
695
                    } else {
 
696
                        cmdLineArg = "/compile" + cmdLineArg;
 
697
                    }
 
698
                }
 
699
 
 
700
                // if maximum length would have been exceeded by compiling
 
701
                // the current resx file, then first execute the resgen
 
702
                // tool
 
703
                if (maxCmdLineExceeded) {
 
704
                    try {
 
705
                        // call base class to do the work
 
706
                        base.ExecuteTask();
 
707
                    } catch {
 
708
                        // we only need to remove temporary directory when 
 
709
                        // an error occurred and if it was actually created
 
710
                        if (_workingDirectory != null) {
 
711
                            // delete temporary directory and all files in it
 
712
                            DeleteTask deleteTask = new DeleteTask();
 
713
                            deleteTask.Project = Project;
 
714
                            deleteTask.Parent = this;
 
715
                            deleteTask.InitializeTaskConfiguration();
 
716
                            deleteTask.Directory = _workingDirectory;
 
717
                            deleteTask.Threshold = Level.None; // no output in build log
 
718
                            deleteTask.Execute();
 
719
                        }
 
720
 
 
721
                        // rethrow exception
 
722
                        throw;
 
723
                    }
 
724
 
 
725
                    // reset command line arguments as we've processed them
 
726
                    _arguments.Length = 0;
 
727
                }
 
728
 
 
729
                // append command line arguments to compile current resx
 
730
                // file to the total command line
 
731
                _arguments.Append(cmdLineArg);
 
732
            }
 
733
        }
 
734
 
709
735
        #endregion Private Instance Methods
710
736
    }
 
737
 
 
738
    /// <summary>
 
739
    /// For internal use only !
 
740
    /// </summary>
 
741
    public class QualifiedResource {
 
742
        #region Private Instance Fields
 
743
 
 
744
        private FileInfo _inputFile;
 
745
        private FileInfo _outputFile;
 
746
 
 
747
        #endregion Private Instance Fields
 
748
 
 
749
        #region Public Instance Constructors
 
750
 
 
751
        /// <summary>
 
752
        /// Initializes a new instance of the <see cref="QualifiedResource" />
 
753
        /// class for a given input and output file.
 
754
        /// </summary>
 
755
        /// <param name="input">The resource to compile.</param>
 
756
        /// <param name="output">The compiled resource.</param>
 
757
        public QualifiedResource(FileInfo input, FileInfo output) {
 
758
            _inputFile = input;
 
759
            _outputFile = output;
 
760
        }
 
761
 
 
762
        #endregion Public Instance Constructors
 
763
 
 
764
        #region Public Instance Properties
 
765
 
 
766
        /// <summary>
 
767
        /// Gets the resource file to compile.
 
768
        /// </summary>
 
769
        /// <value>
 
770
        /// The resource file to compile.
 
771
        /// </value>
 
772
        public FileInfo Input {
 
773
            get { return _inputFile; }
 
774
        }
 
775
 
 
776
        /// <summary>
 
777
        /// Gets the compiled resource file.
 
778
        /// </summary>
 
779
        /// <value>
 
780
        /// The compiled resource file.
 
781
        /// </value>
 
782
        public FileInfo Output {
 
783
            get { return _outputFile; }
 
784
        }
 
785
 
 
786
        #endregion Public Instance Properties
 
787
    }
711
788
}