Merge pull request #799 from kebby/master
[mono.git] / mcs / class / Microsoft.Build.Tasks / Microsoft.Build.Tasks / AssignCulture.cs
1 //
2 // AssignCulture.cs
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //   Ankit Jain (jankit@novell.com)
7 //
8 // (C) 2006 Marek Sieradzki
9 // Copyright 2008 Novell, Inc (http://www.novell.com)
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.Collections.Generic;
34 using System.Globalization;
35 using System.IO;
36 using Microsoft.Build.Framework;
37 using Microsoft.Build.Utilities;
38
39 namespace Microsoft.Build.Tasks {
40         public class AssignCulture : TaskExtension {
41         
42                 ITaskItem[]     assignedFiles;
43                 ITaskItem[]     assignedFilesWithCulture;
44                 ITaskItem[]     assignedFilesWithNoCulture;
45                 ITaskItem[]     cultureNeutralAssignedFiles;
46                 ITaskItem[]     files;
47         
48                 public AssignCulture ()
49                 {
50                 }
51                 
52                 public override bool Execute ()
53                 {
54                         if (files.Length == 0)
55                                 return true;
56
57                         List<ITaskItem> all_files = new List<ITaskItem> ();
58                         List<ITaskItem> with_culture = new List<ITaskItem> ();
59                         List<ITaskItem> no_culture = new List<ITaskItem> ();
60                         List<ITaskItem> culture_neutral = new List<ITaskItem> ();
61
62                         foreach (ITaskItem item in files) {
63                                 string only_filename, culture, extn;
64
65                                 if (TrySplitResourceName (item.ItemSpec, out only_filename, out culture, out extn)) {
66                                         //valid culture found
67                                         ITaskItem new_item = new TaskItem (item);
68                                         new_item.SetMetadata ("Culture", culture);
69                                         all_files.Add (new_item);
70
71                                         new_item = new TaskItem (item);
72                                         new_item.SetMetadata ("Culture", culture);
73                                         with_culture.Add (new_item);
74
75                                         new_item = new TaskItem (item);
76                                         new_item.SetMetadata ("Culture", culture);
77                                         new_item.ItemSpec = only_filename + "." + extn;
78                                         culture_neutral.Add (new_item);
79                                 } else {
80                                         //No valid culture
81
82                                         all_files.Add (item);
83                                         no_culture.Add (item);
84                                         culture_neutral.Add (item);
85                                 }
86                         }
87
88                         assignedFiles = all_files.ToArray ();
89                         assignedFilesWithCulture = with_culture.ToArray ();
90                         assignedFilesWithNoCulture = no_culture.ToArray ();
91                         cultureNeutralAssignedFiles = culture_neutral.ToArray ();
92
93                         return true;
94                 }
95                 
96                 [Output]
97                 public ITaskItem[] AssignedFiles {
98                         get { return assignedFiles; }
99                 }
100                 
101                 [Output]
102                 public ITaskItem[] AssignedFilesWithCulture {
103                         get { return assignedFilesWithCulture; }
104                 }
105                 
106                 [Output]
107                 public ITaskItem[] AssignedFilesWithNoCulture {
108                         get { return assignedFilesWithNoCulture; }
109                 }
110                 
111                 [Output]
112                 public ITaskItem[] CultureNeutralAssignedFiles {
113                         get { return cultureNeutralAssignedFiles; }
114                 }
115                 
116                 [Required]
117                 public ITaskItem[] Files {
118                         get { return files; }
119                         set { files = value; }
120                 }
121
122                 //Given a filename like foo.it.resx, splits it into - foo, it, resx
123                 //Returns true only if a valid culture is found
124                 //Note: hand-written as this can get called lotsa times
125                 internal static bool TrySplitResourceName (string fname, out string only_filename, out string culture, out string extn)
126                 {
127                         only_filename = culture = extn = null;
128
129                         int last_dot = -1;
130                         int culture_dot = -1;
131                         int i = fname.Length - 1;
132                         while (i >= 0) {
133                                 if (fname [i] == '.') {
134                                         last_dot = i;
135                                         break;
136                                 }
137                                 i --;
138                         }
139                         if (i < 0)
140                                 return false;
141
142                         i--;
143                         while (i >= 0) {
144                                 if (fname [i] == '.') {
145                                         culture_dot = i;
146                                         break;
147                                 }
148                                 i --;
149                         }
150                         if (culture_dot < 0)
151                                 return false;
152
153                         culture = fname.Substring (culture_dot + 1, last_dot - culture_dot - 1);
154                         if (!CultureNamesTable.ContainsKey (culture)) {
155                                 culture = null;
156                                 return false;
157                         }
158
159                         only_filename = fname.Substring (0, culture_dot);
160                         extn = fname.Substring (last_dot + 1);
161                         return true;
162                 }
163
164                 static Dictionary<string, string> cultureNamesTable;
165                 static Dictionary<string, string> CultureNamesTable {
166                         get {
167                                 if (cultureNamesTable == null) {
168                                         cultureNamesTable = new Dictionary<string, string> ();
169                                         foreach (CultureInfo ci in CultureInfo.GetCultures (CultureTypes.AllCultures))
170                                                 cultureNamesTable [ci.Name] = ci.Name;
171                                 }
172
173                                 return cultureNamesTable;
174                         }
175                 }
176
177         }
178 }
179
180 #endif