⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nantbuildfile.cs

📁 c#源代码
💻 CS
字号:
//
// SharpDevelop NAnt add-in.
//
// Copyright (C) 2004 Matthew Ward
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Matthew Ward (mrward@users.sourceforge.net)


using System;
using System.IO;
using System.Xml;

namespace ICSharpCode.NAntAddIn
{
	/// <summary>
	/// Represents a NAnt Build File.
	/// </summary>
	public class NAntBuildFile
	{
		/// <summary>
		/// Standard NAnt build file's extension.
		/// </summary>
		public static readonly string BuildFileNameExtension = ".build";
		
		/// <summary>
		/// Standard NAnt include file's extension.
		/// </summary>
		public static readonly string IncludeFileNameExtension = ".include";
		
		static readonly string TargetElementName = "target";
		static readonly string ProjectElementName = "project";
		
		static readonly string NameAttributeName = "name";
		static readonly string DefaultAttributeName = "default";
		
		string directory = String.Empty;
		string fileName = String.Empty;
		string name = String.Empty;
		string defaultTargetName = String.Empty;
		NAntBuildFileError buildFileError;
		
		NAntBuildTargetCollection targets = new NAntBuildTargetCollection();
		NAntBuildTarget defaultTarget;
		
		enum ParseState
		{
			Nothing = 0,
			WaitingForProjectName = 1,
			WaitingForTargetName = 2
		}
		
		/// <summary>
		/// Creates a new instance of the <see cref="NAntBuildFile"/>
		/// class.
		/// </summary>
		/// <param name="fileName">The build filename.</param>
		public NAntBuildFile(string fileName)
		{
			this.directory = Path.GetDirectoryName(fileName);
			this.fileName = Path.GetFileName(fileName);
			
			ReadBuildFile(fileName);
		}
		
		/// <summary>
		/// Creates a new instance of the <see cref="NAntBuildFile"/>
		/// class.
		/// </summary>
		/// <param name="reader">The <see cref="TextReader"/> used to 
		/// feed the XML data into the <see cref="NAntBuildFile"/> 
		/// object.</param>
		public NAntBuildFile(TextReader reader)
		{
			ParseBuildFile(reader);
		}
		
		/// <summary>
		/// Gets or sets the filename without the path information.
		/// </summary>
		public string FileName {
			get {
				return fileName;
			}
			
			set {
				fileName = value;
			}
		}
		
		/// <summary>
		/// Gets the build file's path information.
		/// </summary>
		public string Directory {
			get {
				return directory;
			}
		}
		
		/// <summary>
		/// Gets the project name.
		/// </summary>
		public string Name {
			get {
				return name;
			}
		}
		
		/// <summary>
		/// Checks the build file is a NAnt build file.
		/// </summary>
		public static bool IsBuildFile(string fileName)
		{
			bool isBuildFile = false;
			
			string extension = Path.GetExtension(fileName);
			
			if (String.Compare(extension, BuildFileNameExtension, true) == 0) {
				isBuildFile = true;
			} else if (String.Compare(extension, IncludeFileNameExtension, true) == 0) {
				isBuildFile = true;
			}
			
			return isBuildFile;
		}
		
		/// <summary>
		/// Gets the NAnt build targets.
		/// </summary>
		public NAntBuildTargetCollection Targets {
			get {
				return targets;
			}
		}
		
		/// <summary>
		/// Gets the default NAnt target.
		/// </summary>
		public NAntBuildTarget DefaultTarget {
			get {
				return defaultTarget;
			}
		}
		
		/// <summary>
		/// Gets whether there is an error with this build file.
		/// </summary>
		public bool HasError {
			get {
				return (buildFileError != null);
			}
		}
		
		/// <summary>
		/// Gets the error associated with the build file.
		/// </summary>
		public NAntBuildFileError Error {
			get {
				return buildFileError;
			}
		}
		
		/// <summary>
		/// Reads the NAnt build file and extracts target names.
		/// </summary>
		/// <param name="fileName">The name of the build file.</param>
		void ReadBuildFile(string fileName)
		{
			StreamReader reader = new StreamReader(fileName, true);
			ParseBuildFile(reader);
		}
		
		/// <summary>
		/// Gets the default target's name or returns an empty string.
		/// </summary>
		/// <param name="root">The root node of the build file.</param>
		/// <returns>The default target's name or an empty string if
		/// it does not exist.</returns>
		string GetDefaultTargetName(XmlElement root)
		{
			string defaultTargetName = String.Empty;
			
			XmlAttribute nameAttribute = root.Attributes["default"];
			
			if (nameAttribute != null) {
				defaultTargetName = nameAttribute.Value;
			}
			
			return defaultTargetName;
		}
		
		/// <summary>
		/// Gets the build file's project name or returns an empty string.
		/// </summary>
		/// <param name="root">The root node of the build file.</param>
		/// <returns>The project name or an empty string if
		/// it does not exist.</returns>
		string GetProjectName(XmlElement root)
		{
			string projectName = String.Empty;
			
			XmlAttribute nameAttribute = root.Attributes["name"];
			
			if (nameAttribute != null) {
				projectName = nameAttribute.Value;
			}
			
			return projectName;
		}	
		
		/// <summary>
		/// Tests whether <paramref name="name"/> matches the
		/// default target name.
		/// </summary>
		/// <param name="defaultTargetName">The default target
		/// name.</param>
		/// <param name="targetName">A target's name.</param>
		/// <returns><see langword="true"/> if the target name matches
		/// the default; otherwise <see langword="false"/>.</returns>
		bool IsDefaultTargetName(string defaultTargetName, string targetName)
		{
			bool isDefault = false;
			
			if (defaultTargetName.Length > 0) {
				if (String.Compare(defaultTargetName, targetName, true) == 0) {
					isDefault = true;
				}
			}
			
			return isDefault;
		}
		
		/// <summary>
		/// Parse the NAnt build file.
		/// </summary>
		/// <param name="textReader">A TextReader from which to read
		/// the build file.</param>
		void ParseBuildFile(TextReader textReader)
		{
			XmlTextReader xmlReader = new XmlTextReader(textReader);
			
			try
			{
				ParseState state = ParseState.WaitingForProjectName;
				
				while(xmlReader.Read())
				{
					if (state == ParseState.WaitingForProjectName) {
						if (IsProjectElement(xmlReader)) {
						    ParseProjectElement(xmlReader);
							state = ParseState.WaitingForTargetName;						    	
						}
					} else {
						if (IsTargetElement(xmlReader)) {
							ParseTargetElement(xmlReader);
						}
					}
				}
			} catch(XmlException ex) {
				buildFileError = new NAntBuildFileError(ex.Message, ex.LineNumber - 1, ex.LinePosition - 1);
			} finally {
				xmlReader.Close();
			}
		}
		
		/// <summary>
		/// Parses the current XmlTextReader node if it
		/// is the NAnt Project element.
		/// </summary>
		/// <param name="xmlReader">An XmlTextReader currently being
		/// read.</param>
		void ParseProjectElement(XmlTextReader xmlReader)
		{
			name = GetAttribute(xmlReader, NameAttributeName);
			defaultTargetName = GetAttribute(xmlReader, DefaultAttributeName);
		}
		
		/// <summary>
		/// Tests whether the current element is the project element.
		/// </summary>
		/// <param name="xmlReader"></param>
		/// <returns><see langword="true"/> if the current 
		/// element is the project element; 
		/// <see langword="false"/> otherwise</returns>
		bool IsProjectElement(XmlTextReader xmlReader)
		{
			bool isProjectElement = false;
			
			if (xmlReader.NodeType == XmlNodeType.Element) {
				if (xmlReader.Name == ProjectElementName) {
					isProjectElement = true;
				}
			}
			
			return isProjectElement;
		}
		
		/// <summary>
		/// Tests whether the current element is a target element.
		/// </summary>
		/// <param name="xmlReader">An xml text reader currently
		/// reading the build file xml.</param>
		/// <returns><see langword="true"/> if the current 
		/// element is a target element; 
		/// <see langword="false"/> otherwise</returns>
		bool IsTargetElement(XmlTextReader xmlReader)
		{
			bool isTargetElement = false;
			
			if (xmlReader.NodeType == XmlNodeType.Element) {
				if (xmlReader.Name == TargetElementName) {
					isTargetElement = true;
				}
			}
			
			return isTargetElement;
		}		
		
		/// <summary>
		/// Parses the current XmlTextReader node if it
		/// is the NAnt Target element.
		/// </summary>
		void ParseTargetElement(XmlTextReader xmlReader)
		{
			// Take off one for line/col since SharpDevelop is zero based.
			int line = xmlReader.LineNumber - 1;
			int col = xmlReader.LinePosition - 1;
			
			string targetName = GetAttribute(xmlReader, NameAttributeName);
			
			bool isDefaultTarget = IsDefaultTargetName(defaultTargetName, targetName);
			
			NAntBuildTarget target = 
				new NAntBuildTarget(targetName, isDefaultTarget, line, col);
			    
			targets.Add(target);
			
			if (isDefaultTarget) {
				defaultTarget = target;
			}
		}
		
		/// <summary>
		/// Gets the named attribute's value.
		/// </summary>
		/// <returns>The attribute's value or an empty string if
		/// it was not found.
		/// </returns>
		string GetAttribute(XmlTextReader xmlReader, string name)
		{
			string attributeValue = String.Empty;
			
			if (xmlReader.MoveToAttribute(name)) {
				if (xmlReader.Value != null) {
					attributeValue = xmlReader.Value;
				}
			}
			
			return attributeValue;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -