Copied remotely
[mono.git] / mcs / nant / src / Tasks / StyleTask.cs
1 // NAnt - A .NET build tool\r
2 // Copyright (C) 2001 Gerry Shaw\r
3 //\r
4 // This program is free software; you can redistribute it and/or modify\r
5 // it under the terms of the GNU General Public License as published by\r
6 // the Free Software Foundation; either version 2 of the License, or\r
7 // (at your option) any later version.\r
8 //\r
9 // This program is distributed in the hope that it will be useful,\r
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12 // GNU General Public License for more details.\r
13 //\r
14 // You should have received a copy of the GNU General Public License\r
15 // along with this program; if not, write to the Free Software\r
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
17 //\r
18 // Serge (serge@wildwestsoftware.com)\r
19 // Gerry Shaw (gerry_shaw@yahoo.com)\r
20 \r
21 namespace SourceForge.NAnt {\r
22 \r
23     using System;\r
24     using System.IO;\r
25     using System.Xml;\r
26     using System.Xml.Xsl;\r
27     using System.Xml.XPath;\r
28     using System.Text.RegularExpressions;\r
29 \r
30     [TaskName("style")]\r
31     public class StyleTask : Task {\r
32 \r
33         // TODO: consider prefixing private fields with _ to stay consistent (gs)\r
34 \r
35         [TaskAttribute("basedir", Required=false)]\r
36         string baseDir = null;\r
37 \r
38         [TaskAttribute("destdir", Required=false)]\r
39         string destDir = null;\r
40 \r
41         [TaskAttribute("extension", Required=false)]\r
42         string extension = "html";\r
43 \r
44         [TaskAttribute("style", Required=true)]\r
45         string xsltFile = null;\r
46 \r
47         [TaskAttribute("in", Required=true)]\r
48         string srcFile = null;\r
49 \r
50         [TaskAttribute("out", Required=false)]\r
51         string destFile = null;\r
52 \r
53         private static string GetPath(string dir, string file) {\r
54             // TODO: remove platform dependencies by using System.IO.Path (gs)\r
55             string d = (dir == null)\r
56                 ? ""\r
57                 : Regex.Replace(dir, "/", "\\");\r
58 \r
59             return (d==null || d=="")\r
60                 ? (file==null || file=="") ? "" : file\r
61                 : d.EndsWith("\\")\r
62                 ? d +file : d + "\\" + file;\r
63         }\r
64 \r
65         private XmlReader CreateXmlReader(string dir, string file) {\r
66             string xmlPath = GetPath(dir, file);\r
67             XmlTextReader xmlReader = null;\r
68 \r
69             try {\r
70                 xmlReader = new XmlTextReader(new FileStream(xmlPath, FileMode.Open));\r
71             } catch (Exception) {\r
72                 xmlReader = null;\r
73             }\r
74 \r
75             return xmlReader;\r
76         }\r
77 \r
78         private XmlWriter CreateXmlWriter(string dir, string file) {\r
79             string xmlPath = GetPath(dir, file);\r
80 \r
81             XmlWriter xmlWriter = null;\r
82 \r
83             string targetDir = Path.GetDirectoryName(Path.GetFullPath(xmlPath));\r
84             if (targetDir != null && targetDir != "" && !Directory.Exists(targetDir)) {\r
85                 Directory.CreateDirectory(targetDir);\r
86             }\r
87 \r
88             try {\r
89                 // UTF-8 encoding will be used\r
90                 xmlWriter = new XmlTextWriter(xmlPath, null);\r
91             } catch (Exception) {\r
92                 xmlWriter = null;\r
93             }\r
94 \r
95             return xmlWriter;\r
96         }\r
97 \r
98         protected override void ExecuteTask() {\r
99             string destFile = this.destFile;\r
100 \r
101             if (destFile == null || destFile == "") {\r
102                 // TODO: use System.IO.Path (gs)\r
103                 string ext = extension[0]=='.'\r
104                     ? extension\r
105                     : "." + extension;\r
106 \r
107                 int extPos = srcFile.LastIndexOf('.');\r
108 \r
109                 if (extPos == -1) {\r
110                     destFile = srcFile + ext;\r
111                 } else {\r
112                     destFile = srcFile.Substring(0, extPos) + ext;\r
113                 }\r
114             }\r
115 \r
116             string srcPath = GetPath(baseDir, srcFile);\r
117             string destPath = GetPath(destDir, destFile);\r
118             string xsltPath = GetPath(baseDir, xsltFile);\r
119 \r
120             FileInfo srcInfo = new FileInfo(srcPath);\r
121             FileInfo destInfo = new FileInfo(destPath);\r
122             FileInfo xsltInfo = new FileInfo(xsltPath);\r
123 \r
124             if (!srcInfo.Exists) {\r
125                 throw new BuildException("Unable to find source xml file.");\r
126             }\r
127             if (!xsltInfo.Exists) {\r
128                 throw new BuildException("Unable to find stylesheet file.");\r
129             }\r
130 \r
131             bool destOutdated = !destInfo.Exists\r
132                 || srcInfo.LastWriteTime > destInfo.LastWriteTime\r
133                 || xsltInfo.LastWriteTime > destInfo.LastWriteTime;\r
134 \r
135             if (destOutdated) {\r
136                 XmlReader xmlReader = CreateXmlReader(baseDir, srcFile);\r
137                 XmlReader xslReader = CreateXmlReader(baseDir, xsltFile);\r
138                 XmlWriter xmlWriter = CreateXmlWriter(destDir, destFile);\r
139 \r
140                 Log.WriteLine(LogPrefix + "Transforming into " + Path.GetFullPath(destDir));\r
141 \r
142                 // TODO: remove assignments from conditional statement (gs)\r
143                 if (xmlReader != null && xslReader != null && xmlWriter != null) {\r
144                     XslTransform xslt = new XslTransform();\r
145                     XPathDocument xml = new XPathDocument(xmlReader);\r
146 \r
147                     Log.WriteLine(LogPrefix + "Loading stylesheet " + Path.GetFullPath(xsltPath));\r
148                     try {\r
149                         xslt.Load(xslReader);\r
150                     } catch (XsltCompileException xce) {\r
151                         throw new BuildException(xce.Message, xce);\r
152                     } catch (Exception e) {\r
153                         throw new BuildException(e.Message, e);\r
154                     }\r
155 \r
156                     Log.WriteLine(LogPrefix + "Processing " + Path.GetFullPath(srcPath) + " to " + Path.GetFullPath(destPath));\r
157                     try {\r
158                         xslt.Transform(xml, null, xmlWriter);\r
159                     } catch (Exception e) {\r
160                         throw new BuildException(e.Message, e);\r
161                     }\r
162                 } else {\r
163                     // not sure how to deal with this...\r
164                     // TODO: remove this statement or do something useful (gs)\r
165                     // Can this condition occur? I would have thought\r
166                     // that an exception would be thrown. (gs)\r
167                 }\r
168             }\r
169         }\r
170     }\r
171 }\r