You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			517 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			517 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections;
 | |
| using System.Xml;
 | |
| using Commons.Xml.Relaxng;
 | |
| 
 | |
| namespace Commons.Xml.Nvdl
 | |
| {
 | |
| 	public class NvdlReader
 | |
| 	{
 | |
| 		public static NvdlRules Read (XmlReader reader)
 | |
| 		{
 | |
| 			return new NvdlReader (reader).ReadRules ();
 | |
| 		}
 | |
| 
 | |
| 		XmlReader reader;
 | |
| 		IXmlLineInfo lineInfo;
 | |
| 		XmlDocument doc = new XmlDocument ();
 | |
| 
 | |
| 		private NvdlReader (XmlReader reader)
 | |
| 		{
 | |
| 			// FIXME: use .rnc validation.
 | |
| 			this.reader = reader;
 | |
| 			this.lineInfo = reader as IXmlLineInfo;
 | |
| 			reader.MoveToContent ();
 | |
| 		}
 | |
| 
 | |
| 		private void FillForeignAttribute (NvdlAttributable el)
 | |
| 		{
 | |
| 			if (!reader.MoveToFirstAttribute ())
 | |
| 				return;
 | |
| 			do {
 | |
| 				if (reader.NamespaceURI == "")
 | |
| 					continue;
 | |
| 				XmlAttribute a = doc.CreateAttribute (
 | |
| 						reader.Prefix,
 | |
| 						reader.LocalName,
 | |
| 						reader.NamespaceURI);
 | |
| 				a.Value = reader.Value;
 | |
| 				el.Foreign.Add (a);
 | |
| 			} while (reader.MoveToNextAttribute ());
 | |
| 			reader.MoveToElement ();
 | |
| 		}
 | |
| 
 | |
| 		private void FillNonXmlAttributes (NvdlMessage el)
 | |
| 		{
 | |
| 			if (!reader.MoveToFirstAttribute ())
 | |
| 				return;
 | |
| 			do {
 | |
| 				if (reader.NamespaceURI == Nvdl.XmlNamespaceUri)
 | |
| 					continue;
 | |
| 				XmlAttribute a = doc.CreateAttribute (
 | |
| 						reader.Prefix,
 | |
| 						reader.LocalName,
 | |
| 						reader.NamespaceURI);
 | |
| 				a.Value = reader.Value;
 | |
| 				el.ForeignAttributes.Add (a);
 | |
| 			} while (reader.MoveToNextAttribute ());
 | |
| 			reader.MoveToElement ();
 | |
| 		}
 | |
| 
 | |
| 		private void FillLocation (NvdlElementBase el)
 | |
| 		{
 | |
| 			el.SourceUri = reader.BaseURI;
 | |
| 			if (lineInfo != null) {
 | |
| 				el.LineNumber = lineInfo.LineNumber;
 | |
| 				el.LinePosition = lineInfo.LinePosition;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		private NvdlRuleTarget ParseMatch (string s)
 | |
| 		{
 | |
| 			if (s == null)
 | |
| 				return NvdlRuleTarget.None;
 | |
| 			if (s.IndexOf ("elements") >= 0)
 | |
| 				return (s.IndexOf ("attributes") >= 0) ?
 | |
| 					NvdlRuleTarget.Both :
 | |
| 					NvdlRuleTarget.Elements;
 | |
| 			else
 | |
| 				return (s.IndexOf ("attributes") >= 0) ?
 | |
| 					NvdlRuleTarget.Attributes :
 | |
| 					NvdlRuleTarget.None;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlRules ReadRules ()
 | |
| 		{
 | |
| 			NvdlRules el = new NvdlRules ();
 | |
| 			FillLocation (el);
 | |
| 			el.SchemaType = reader.GetAttribute ("schemaType");
 | |
| 			el.StartMode = reader.GetAttribute ("startMode");
 | |
| 			FillForeignAttribute (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				return el;
 | |
| 			}
 | |
| 			reader.Read ();
 | |
| 			do {
 | |
| 				reader.MoveToContent ();
 | |
| 				if (reader.NodeType == XmlNodeType.EndElement)
 | |
| 					break;
 | |
| 				if (reader.NamespaceURI != Nvdl.Namespace) {
 | |
| 					el.Foreign.Add (doc.ReadNode (reader));
 | |
| 					continue;
 | |
| 				}
 | |
| 				switch (reader.LocalName) {
 | |
| 				case "mode":
 | |
| 					el.Modes.Add (ReadMode ());
 | |
| 					break;
 | |
| 				case "namespace":
 | |
| 					el.Rules.Add (ReadNamespace ());
 | |
| 					break;
 | |
| 				case "anyNamespace":
 | |
| 					el.Rules.Add (ReadAnyNamespace ());
 | |
| 					break;
 | |
| 				case "trigger":
 | |
| 					el.Triggers.Add (ReadTrigger ());
 | |
| 					break;
 | |
| 				}
 | |
| 			} while (!reader.EOF);
 | |
| 			if (!reader.EOF)
 | |
| 				reader.Read ();
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlTrigger ReadTrigger ()
 | |
| 		{
 | |
| 			NvdlTrigger el = new NvdlTrigger ();
 | |
| 			FillLocation (el);
 | |
| 			el.NS = reader.GetAttribute ("ns");
 | |
| 			el.NameList = reader.GetAttribute ("nameList");
 | |
| 			FillForeignAttribute (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				return el;
 | |
| 			}
 | |
| 			reader.Read ();
 | |
| 			do {
 | |
| 				reader.MoveToContent ();
 | |
| 				if (reader.NodeType == XmlNodeType.EndElement)
 | |
| 					break;
 | |
| 				if (reader.NamespaceURI != Nvdl.Namespace) {
 | |
| 					el.Foreign.Add (doc.ReadNode (reader));
 | |
| 					continue;
 | |
| 				}
 | |
| 			} while (!reader.EOF);
 | |
| 			if (!reader.EOF)
 | |
| 				reader.Read ();
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlMode ReadMode ()
 | |
| 		{
 | |
| 			NvdlMode el = new NvdlMode ();
 | |
| 			FillLocation (el);
 | |
| 			el.Name = reader.GetAttribute ("name");
 | |
| 			ReadModeCommon (el);
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlIncludedMode ReadIncludedMode ()
 | |
| 		{
 | |
| 			NvdlIncludedMode el = new NvdlIncludedMode ();
 | |
| 			FillLocation (el);
 | |
| 			el.Name = reader.GetAttribute ("name");
 | |
| 			ReadModeCommon (el);
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlNestedMode ReadNestedMode ()
 | |
| 		{
 | |
| 			NvdlNestedMode el = new NvdlNestedMode ();
 | |
| 			FillLocation (el);
 | |
| 			ReadModeCommon (el);
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private void ReadModeCommon (NvdlModeBase el)
 | |
| 		{
 | |
| 			FillForeignAttribute (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				return;
 | |
| 			}
 | |
| 			reader.Read ();
 | |
| 			do {
 | |
| 				reader.MoveToContent ();
 | |
| 				if (reader.NodeType == XmlNodeType.EndElement)
 | |
| 					break;
 | |
| 				if (reader.NamespaceURI != Nvdl.Namespace) {
 | |
| 					el.Foreign.Add (doc.ReadNode (reader));
 | |
| 					continue;
 | |
| 				}
 | |
| 				switch (reader.LocalName) {
 | |
| 				case "mode":
 | |
| 					el.IncludedModes.Add (ReadIncludedMode ());
 | |
| 					break;
 | |
| 				case "namespace":
 | |
| 					el.Rules.Add (ReadNamespace ());
 | |
| 					break;
 | |
| 				case "anyNamespace":
 | |
| 					el.Rules.Add (ReadAnyNamespace ());
 | |
| 					break;
 | |
| 				}
 | |
| 			} while (!reader.EOF);
 | |
| 			if (!reader.EOF)
 | |
| 				reader.Read ();
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlAnyNamespace ReadAnyNamespace ()
 | |
| 		{
 | |
| 			NvdlAnyNamespace el = new NvdlAnyNamespace ();
 | |
| 			FillLocation (el);
 | |
| 			el.Match = ParseMatch (reader.GetAttribute ("match"));
 | |
| 			FillForeignAttribute (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				return el;
 | |
| 			}
 | |
| 			reader.Read ();
 | |
| 			do {
 | |
| 				reader.MoveToContent ();
 | |
| 				if (reader.NodeType == XmlNodeType.EndElement)
 | |
| 					break;
 | |
| 				if (reader.NamespaceURI != Nvdl.Namespace) {
 | |
| 					el.Foreign.Add (doc.ReadNode (reader));
 | |
| 					continue;
 | |
| 				}
 | |
| 				ReadAction (el);
 | |
| 			} while (!reader.EOF);
 | |
| 			if (!reader.EOF)
 | |
| 				reader.Read ();
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlNamespace ReadNamespace ()
 | |
| 		{
 | |
| 			NvdlNamespace el = new NvdlNamespace ();
 | |
| 			FillLocation (el);
 | |
| 			el.NS = reader.GetAttribute ("ns");
 | |
| 			el.Wildcard = reader.GetAttribute ("wildCard");
 | |
| 			el.Match = ParseMatch (reader.GetAttribute ("match"));
 | |
| 			FillForeignAttribute (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				return el;
 | |
| 			}
 | |
| 			reader.Read ();
 | |
| 			do {
 | |
| 				reader.MoveToContent ();
 | |
| 				if (reader.NodeType == XmlNodeType.EndElement)
 | |
| 					break;
 | |
| 				if (reader.NamespaceURI != Nvdl.Namespace) {
 | |
| 					el.Foreign.Add (doc.ReadNode (reader));
 | |
| 					continue;
 | |
| 				}
 | |
| 				ReadAction (el);
 | |
| 			} while (!reader.EOF);
 | |
| 			if (!reader.EOF)
 | |
| 				reader.Read ();
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private void ReadAction (NvdlRule el)
 | |
| 		{
 | |
| 			switch (reader.LocalName) {
 | |
| 			case "cancelNestedActions":
 | |
| 				el.Actions.Add (ReadCancelAction ());
 | |
| 				break;
 | |
| 			case "validate":
 | |
| 				el.Actions.Add (ReadValidate ());
 | |
| 				break;
 | |
| 			case "allow":
 | |
| 				el.Actions.Add (ReadAllow ());
 | |
| 				break;
 | |
| 			case "reject":
 | |
| 				el.Actions.Add (ReadReject ());
 | |
| 				break;
 | |
| 			case "attach":
 | |
| 				el.Actions.Add (ReadAttach ());
 | |
| 				break;
 | |
| 			case "attachPlaceHolder":
 | |
| 				el.Actions.Add (ReadAttachPlaceholder ());
 | |
| 				break;
 | |
| 			case "unwrap":
 | |
| 				el.Actions.Add (ReadUnwrap ());
 | |
| 				break;
 | |
| 			default:
 | |
| 				throw new NotSupportedException ();
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		private NvdlCancelAction ReadCancelAction ()
 | |
| 		{
 | |
| 			NvdlCancelAction el = new NvdlCancelAction ();
 | |
| 			FillLocation (el);
 | |
| 			FillForeignAttribute (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				return el;
 | |
| 			}
 | |
| 			reader.Read ();
 | |
| 			do {
 | |
| 				reader.MoveToContent ();
 | |
| 				if (reader.NodeType == XmlNodeType.EndElement)
 | |
| 					break;
 | |
| 				if (reader.NamespaceURI != Nvdl.Namespace) {
 | |
| 					el.Foreign.Add (doc.ReadNode (reader));
 | |
| 					continue;
 | |
| 				}
 | |
| 			} while (!reader.EOF);
 | |
| 			if (!reader.EOF)
 | |
| 				reader.Read ();
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlValidate ReadValidate ()
 | |
| 		{
 | |
| 			NvdlValidate el = new NvdlValidate ();
 | |
| 			NvdlModeUsage mu = new NvdlModeUsage ();
 | |
| 			el.ModeUsage = mu;
 | |
| 			FillLocation (el);
 | |
| 			el.SchemaType = reader.GetAttribute ("schemaType");
 | |
| 			el.SimpleMessage = reader.GetAttribute ("message");
 | |
| 			el.SchemaUri = reader.GetAttribute ("schema");
 | |
| 			mu.UseMode = reader.GetAttribute ("useMode");
 | |
| 			FillForeignAttribute (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				return el;
 | |
| 			}
 | |
| 			reader.Read ();
 | |
| 			do {
 | |
| 				reader.MoveToContent ();
 | |
| 				if (reader.NodeType == XmlNodeType.EndElement)
 | |
| 					break;
 | |
| 				if (reader.NamespaceURI != Nvdl.Namespace) {
 | |
| 					el.Foreign.Add (doc.ReadNode (reader));
 | |
| 					continue;
 | |
| 				}
 | |
| 				switch (reader.LocalName) {
 | |
| 				case "message":
 | |
| 					el.Messages.Add (ReadMessage ());
 | |
| 					break;
 | |
| 				case "option":
 | |
| 					el.Options.Add (ReadOption ());
 | |
| 					break;
 | |
| 				case "schema":
 | |
| 					el.SchemaBody = (XmlElement) doc.ReadNode (reader);
 | |
| 					break;
 | |
| 				case "mode":
 | |
| 					mu.NestedMode = ReadNestedMode ();
 | |
| 					break;
 | |
| 				case "context":
 | |
| 					mu.Contexts.Add (ReadContext ());
 | |
| 					break;
 | |
| 				default:
 | |
| 					throw new NotSupportedException ();
 | |
| 				}
 | |
| 			} while (!reader.EOF);
 | |
| 			if (!reader.EOF)
 | |
| 				reader.Read ();
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlAllow ReadAllow ()
 | |
| 		{
 | |
| 			NvdlAllow el = new NvdlAllow ();
 | |
| 			ReadCommonActionContent (el);
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlReject ReadReject ()
 | |
| 		{
 | |
| 			NvdlReject el = new NvdlReject ();
 | |
| 			ReadCommonActionContent (el);
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlAttach ReadAttach ()
 | |
| 		{
 | |
| 			NvdlAttach el = new NvdlAttach ();
 | |
| 			ReadCommonActionContent (el);
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlAttachPlaceholder ReadAttachPlaceholder ()
 | |
| 		{
 | |
| 			NvdlAttachPlaceholder el = new NvdlAttachPlaceholder ();
 | |
| 			ReadCommonActionContent (el);
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlUnwrap ReadUnwrap ()
 | |
| 		{
 | |
| 			NvdlUnwrap el = new NvdlUnwrap ();
 | |
| 			ReadCommonActionContent (el);
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private void ReadCommonActionContent (NvdlNoCancelAction el)
 | |
| 		{
 | |
| 			FillLocation (el);
 | |
| 			NvdlModeUsage mu = new NvdlModeUsage ();
 | |
| 			el.ModeUsage = mu;
 | |
| 			FillLocation (el);
 | |
| 			el.SimpleMessage = reader.GetAttribute ("message");
 | |
| 			mu.UseMode = reader.GetAttribute ("useMode");
 | |
| 			FillForeignAttribute (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				return;
 | |
| 			}
 | |
| 			reader.Read ();
 | |
| 			do {
 | |
| 				reader.MoveToContent ();
 | |
| 				if (reader.NodeType == XmlNodeType.EndElement)
 | |
| 					break;
 | |
| 				if (reader.NamespaceURI != Nvdl.Namespace) {
 | |
| 					el.Foreign.Add (doc.ReadNode (reader));
 | |
| 					continue;
 | |
| 				}
 | |
| 				switch (reader.LocalName) {
 | |
| 				case "mode":
 | |
| 					mu.NestedMode = ReadNestedMode ();
 | |
| 					break;
 | |
| 				case "message":
 | |
| 					el.Messages.Add (ReadMessage ());
 | |
| 					break;
 | |
| 				case "context":
 | |
| 					mu.Contexts.Add (ReadContext ());
 | |
| 					break;
 | |
| 				default:
 | |
| 					throw new NotSupportedException ();
 | |
| 				}
 | |
| 			} while (!reader.EOF);
 | |
| 			if (!reader.EOF)
 | |
| 				reader.Read ();
 | |
| 		}
 | |
| 
 | |
| 		private NvdlMessage ReadMessage ()
 | |
| 		{
 | |
| 			NvdlMessage el = new NvdlMessage ();
 | |
| 			FillLocation (el);
 | |
| 			el.XmlLang = reader.GetAttribute ("lang", Nvdl.XmlNamespaceUri);
 | |
| 			FillNonXmlAttributes (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				el.Text = "";
 | |
| 			}
 | |
| 			else
 | |
| 				el.Text = reader.ReadElementString ();
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlOption ReadOption ()
 | |
| 		{
 | |
| 			NvdlOption el = new NvdlOption ();
 | |
| 			FillLocation (el);
 | |
| 			el.Name = reader.GetAttribute ("name");
 | |
| 			el.Arg = reader.GetAttribute ("arg");
 | |
| 			el.MustSupport = reader.GetAttribute ("mustSupport");
 | |
| 			FillForeignAttribute (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				return el;
 | |
| 			}
 | |
| 			reader.Read ();
 | |
| 			do {
 | |
| 				reader.MoveToContent ();
 | |
| 				if (reader.NodeType == XmlNodeType.EndElement)
 | |
| 					break;
 | |
| 				if (reader.NamespaceURI != Nvdl.Namespace) {
 | |
| 					el.Foreign.Add (doc.ReadNode (reader));
 | |
| 					continue;
 | |
| 				}
 | |
| 			} while (!reader.EOF);
 | |
| 			if (!reader.EOF)
 | |
| 				reader.Read ();
 | |
| 			return el;
 | |
| 		}
 | |
| 
 | |
| 		private NvdlContext ReadContext ()
 | |
| 		{
 | |
| 			NvdlContext el = new NvdlContext ();
 | |
| 			FillLocation (el);
 | |
| 			el.Path = reader.GetAttribute ("path");
 | |
| 			el.UseMode = reader.GetAttribute ("useMode");
 | |
| 			FillForeignAttribute (el);
 | |
| 			if (reader.IsEmptyElement) {
 | |
| 				reader.Skip ();
 | |
| 				return el;
 | |
| 			}
 | |
| 			reader.Read ();
 | |
| 			do {
 | |
| 				reader.MoveToContent ();
 | |
| 				if (reader.NodeType == XmlNodeType.EndElement)
 | |
| 					break;
 | |
| 				if (reader.NamespaceURI != Nvdl.Namespace) {
 | |
| 					el.Foreign.Add (doc.ReadNode (reader));
 | |
| 					continue;
 | |
| 				}
 | |
| 				switch (reader.LocalName) {
 | |
| 				case "mode":
 | |
| 					el.NestedMode = ReadNestedMode ();
 | |
| 					break;
 | |
| 				default:
 | |
| 					throw new NotSupportedException ();
 | |
| 				}
 | |
| 			} while (!reader.EOF);
 | |
| 			if (!reader.EOF)
 | |
| 				reader.Read ();
 | |
| 			return el;
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 |