* TaskLoggingHelperExtensios.cs (.ctor): Mark internal.
[mono.git] / mcs / class / Microsoft.Build.Tasks / Microsoft.Build.Tasks / GenerateResource.cs
1 //
2 // GenerateResource.cs: Task that generates the resources.
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //   Paolo Molaro (lupus@ximian.com)
7 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 //
9 // (C) 2005 Marek Sieradzki
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 #if NET_2_0
31
32 using System;
33 using System.Text;
34 using System.IO;
35 using System.Collections;
36 using System.Collections.Generic;
37 using System.Resources;
38 using System.Reflection;
39 using Microsoft.Build.Framework;
40 using Mono.XBuild.Tasks.GenerateResourceInternal;
41
42 namespace Microsoft.Build.Tasks {
43         public sealed class GenerateResource : TaskExtension {
44         
45                 ITaskItem[]     filesWritten;
46                 bool            neverLockTypeAssemblies;
47                 ITaskItem[]     outputResources;
48                 bool            publicClass;
49                 ITaskItem[]     references;
50                 ITaskItem[]     sources;
51                 ITaskItem       stateFile;
52                 string          stronglyTypedClassName;
53                 string          stronglyTypedFilename;
54                 string          stronglyTypedLanguage;
55                 string          stronglyTypedNamespace;
56                 bool            useSourcePath;
57                 
58                 public GenerateResource ()
59                 {
60                         useSourcePath = false;
61                 }
62
63                 public override bool Execute ()
64                 {
65                         List  <ITaskItem> temporaryFilesWritten = new List <ITaskItem> ();
66                         if (sources.Length != outputResources.Length) {
67                                 Log.LogErrorFromException (new Exception ("Sources count is different than OutputResources count."));
68                                 return false;
69                         }
70                         
71                         if (outputResources == null) {
72                                 foreach (ITaskItem source in sources) {
73                                         string sourceFile = source.ItemSpec;
74                                         string outputFile = Path.ChangeExtension (sourceFile, "resources");
75                                         CompileResourceFile (sourceFile, outputFile);
76                                 }
77                         } else {
78                                 for (int i = 0; i < sources.Length; i ++) {
79                                         string sourceFile = sources [i].ItemSpec;
80                                         string outputFile = outputResources [i].ItemSpec;
81
82                                         if (outputFile == String.Empty) {
83                                                 Log.LogErrorFromException (new Exception ("Filename of output can not be empty."));
84                                                 return false;
85                                         }
86                                         if (CompileResourceFile (sourceFile, outputFile) == false) {
87                                                 Log.LogErrorFromException (new Exception ("Error during compiling resource file."));
88                                                 return false;
89                                         }
90                                         temporaryFilesWritten.Add (outputResources [i]);
91                                 }
92                         }
93                         
94                         filesWritten = temporaryFilesWritten.ToArray ();
95                         
96                         return true;
97                 }
98                 
99                 private IResourceReader GetReader (Stream stream, string name)
100                 {
101                         string format = Path.GetExtension (name);
102                         switch (format.ToLower ()) {
103                         case ".po":
104                                 return new PoResourceReader (stream);
105                         case ".txt":
106                         case ".text":
107                                 return new TxtResourceReader (stream);
108                         case ".resources":
109                                 return new ResourceReader (stream);
110                         case ".resx":
111                                 ResXResourceReader reader = new ResXResourceReader (stream);
112
113                                 // set correct basepath to resolve relative paths in file refs
114                                 if (useSourcePath)
115                                         reader.BasePath = Path.GetDirectoryName (Path.GetFullPath (name));
116
117                                 return reader;
118                         default:
119                                 throw new Exception ("Unknown format in file " + name);
120                         }
121                 }
122                 
123                 private IResourceWriter GetWriter (Stream stream, string name)
124                 {
125                         string format = Path.GetExtension (name);
126                         switch (format.ToLower ()) {
127                         case ".po":
128                                 return new PoResourceWriter (stream);
129                         case ".txt":
130                         case ".text":
131                                 return new TxtResourceWriter (stream);
132                         case ".resources":
133                                 return new ResourceWriter (stream);
134                         case ".resx":
135                                 return new System.Resources.ResXResourceWriter (stream);
136                         default:
137                                 throw new Exception ("Unknown format in file " + name);
138                         }
139                 }
140                 
141                 private bool CompileResourceFile (string sname, string dname )
142                 {
143                         FileStream source, dest;
144                         IResourceReader reader;
145                         IResourceWriter writer;
146
147                         Log.LogMessage ("Compiling resource file '{0}' into '{1}'", sname, dname);
148                         try {
149                                 source = new FileStream (sname, FileMode.Open, FileAccess.Read);
150
151                                 reader = GetReader (source, sname);
152
153                                 dest = new FileStream (dname, FileMode.Create, FileAccess.Write);
154                                 writer = GetWriter (dest, dname);
155
156                                 int rescount = 0;
157                                 foreach (DictionaryEntry e in reader) {
158                                         rescount++;
159                                         object val = e.Value;
160                                         if (val is string)
161                                                 writer.AddResource ((string)e.Key, (string)e.Value);
162                                         else
163                                                 writer.AddResource ((string)e.Key, e.Value);
164                                 }
165
166                                 reader.Close ();
167                                 writer.Close ();
168                         } catch (Exception e) {
169                                 Log.LogErrorFromException (e);
170                                 return false;
171                         }
172                         return true;
173                 }
174
175                 [Output]
176                 public ITaskItem[] FilesWritten {
177                         get {
178                                 return filesWritten;
179                         }
180                 }
181
182                 [MonoTODO]
183                 public bool NeverLockTypeAssemblies {
184                         get {
185                                 return neverLockTypeAssemblies;
186                         }
187                         set {
188                                 neverLockTypeAssemblies = value;
189                         }
190                 }
191
192                 [Output]
193                 public ITaskItem[] OutputResources {
194                         get {
195                                 return outputResources;
196                         }
197                         set {
198                                 outputResources = value;
199                         }
200                 }
201                 
202                 public bool PublicClass {
203                         get { return publicClass; }
204                         set { publicClass = value; }
205                 }
206
207                 public ITaskItem[] References {
208                         get {
209                                 return references;
210                         }
211                         set {
212                                 references = value;
213                         }
214                 }
215
216                 [Required]
217                 public ITaskItem[] Sources {
218                         get {
219                                 return sources;
220                         }
221                         set {
222                                 sources = value;
223                         }
224                 }
225
226                 public ITaskItem StateFile {
227                         get {
228                                 return stateFile;
229                         }
230                         set {
231                                 stateFile = value;
232                         }
233                 }
234
235                 [Output]
236                 public string StronglyTypedClassName {
237                         get {
238                                 return stronglyTypedClassName;
239                         }
240                         set {
241                                 stronglyTypedClassName = value;
242                         }
243                 }
244
245                 [Output]
246                 public string StronglyTypedFileName {
247                         get {
248                                 return stronglyTypedFilename;
249                         }
250                         set {
251                                 stronglyTypedFilename = value;
252                         }
253                 }
254
255                 public string StronglyTypedLanguage {
256                         get {
257                                 return stronglyTypedLanguage;
258                         }
259                         set {
260                                 stronglyTypedLanguage = value;
261                         }
262                 }
263
264                 public string StronglyTypedNamespace {
265                         get {
266                                 return stronglyTypedNamespace;
267                         }
268                         set {
269                                 stronglyTypedNamespace = value;
270                         }
271                 }
272
273                 public bool UseSourcePath {
274                         get {
275                                 return useSourcePath;
276                         }
277                         set {
278                                 useSourcePath = value;
279                         }
280                 }
281         }
282 }
283
284 #endif