public XmlSchemaCompletionData GetSchemaFromFileName(string fileName)
        {
            XmlSchemaCompletionData data = user.GetSchemaFromFileName(fileName);

            if (data == null)
            {
                data = builtin.GetSchemaFromFileName(fileName);
            }
            return(data);
        }
Beispiel #2
0
 public XmlSchemaCompletionData this [string namespaceUri] {
     get {
         XmlSchemaCompletionData val = user[namespaceUri];
         if (val == null)
         {
             val = builtin[namespaceUri];
         }
         return(val);
     }
 }
		public static void Initialise ()
		{
			if (schemas != null)
				return;
			
			schemas = new Dictionary<string, HtmlSchema> ();
			
			//load all the schemas from addin points
			//NOTE: the first ([0]) schema must be the default schema (HTML4 transitional)
			string schemaDir = Path.GetDirectoryName (System.Reflection.Assembly.GetExecutingAssembly ().Location);
			schemaDir = Path.Combine (schemaDir, "Schemas");
			
			foreach (DocTypeExtensionNode node in Mono.Addins.AddinManager.GetExtensionNodes ("/MonoDevelop/Html/DocTypes")) {
				if (schemas.ContainsKey (node.Name))
					LoggingService.LogWarning (
					    "HtmlSchemaService cannot register duplicate doctype with the name '{0}'", node.Name);
				
				if (!string.IsNullOrEmpty (node.XsdFile)) {
					string path = Path.Combine (schemaDir, node.XsdFile);
					try {
						IXmlCompletionProvider provider = new XmlSchemaCompletionData (path);
						schemas.Add (node.Name, new HtmlSchema (node.Name, node.FullName, provider));
					} catch (Exception ex) {
						LoggingService.LogWarning (
						    "HtmlSchemaService encountered an error registering the schema '" + path + "'", ex);
					}
				} else {
					schemas.Add (node.Name, new HtmlSchema (node.Name, node.FullName, node.CompletionDocTypeName));
				}
			}
			
			//initialise the default backup schema if it doesn't exist already
			if (!schemas.ContainsKey (DefaultDocTypeName)) {
				HtmlSchema defaultSubstProvider = schemas["XHTML 1.0 Transitional"];
				IXmlCompletionProvider provider;
				if (defaultSubstProvider != null) {
					//start the threaded schema loading
					LoadSchema (defaultSubstProvider, true);
					provider = defaultSubstProvider.CompletionProvider;
				} else {
					LoggingService.LogWarning ("Completion schema for default HTML doctype not found.");
					provider = new EmptyXmlCompletionProvider ();
				}
				
				schemas[DefaultDocTypeName] = new HtmlSchema ("HTML 4.01 Transitional",
				    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n"
				    + "\"http://www.w3.org/TR/html4/loose.dtd\">",
				    provider);
			}
			
			MonoDevelop.Core.LoggingService.LogDebug ("HtmlSchemaService initialised");
		}
		public void FixtureInit()
		{
			XmlSchemaCompletionDataCollection items = new XmlSchemaCompletionDataCollection();
			
			StringReader reader = new StringReader(GetSchema(firstNamespace));
			XmlSchemaCompletionData schema = new XmlSchemaCompletionData(reader);
			items.Add(schema);
			
			reader = new StringReader(GetSchema(secondNamespace));
			schema = new XmlSchemaCompletionData(reader);
			items.Add(schema);
			namespaceCompletionData = new CompletionDataList(items.GetNamespaceCompletionData());
		}
		public void FixtureInit()
		{
			XmlTextReader reader = ResourceManager.GetXhtmlStrictSchema();
			schemaCompletionData = new XmlSchemaCompletionData(reader);
			
			// Set up h1 element's path.
			h1Path = new XmlElementPath();
			h1Path.Elements.Add(new QualifiedName("html", namespaceURI));
			h1Path.Elements.Add(new QualifiedName("body", namespaceURI));
			h1Path.Elements.Add(new QualifiedName("h1", namespaceURI));
			
			// Get h1 element info.
			h1Attributes = schemaCompletionData.GetAttributeCompletionData(h1Path);
		}
		/// <summary>
		/// Gets the XmlSchemaObject that defines the currently selected xml element or attribute.
		/// </summary>
		/// <param name="currentSchemaCompletionData">This is the schema completion data for the schema currently being 
		/// displayed. This can be null if the document is not a schema.</param>
		public XmlSchemaObject GetSchemaObjectSelected (XmlSchemaCompletionData currentSchemaCompletionData)
		{
			// Find element under cursor.
			XmlElementPath path = GetElementPath ();
			
			//attribute name under cursor, if valid
			string attributeName = null;
			XAttribute xatt = Tracker.Engine.Nodes.Peek (0) as XAttribute;
			if (xatt != null) {
				XName xattName = xatt.Name;
				if (Tracker.Engine.CurrentState is XmlNameState) {
					xattName = GetCompleteName ();
				}
				attributeName = xattName.FullName;
			}
			
			// Find schema definition object.
			XmlSchemaCompletionData schemaCompletionData = FindSchema (path);
			XmlSchemaObject schemaObject = null;
			if (schemaCompletionData != null) {
				XmlSchemaElement element = schemaCompletionData.FindElement(path);
				schemaObject = element;
				if (element != null) {
					if (!string.IsNullOrEmpty (attributeName)) {
						XmlSchemaAttribute attribute = schemaCompletionData.FindAttribute(element, attributeName);
						if (attribute != null) {
							if (currentSchemaCompletionData != null) {
								schemaObject = GetSchemaObjectReferenced (currentSchemaCompletionData, element, attribute);
							} else {
								schemaObject = attribute;
							}
						}
					}
					return schemaObject;
				}
			}	
			return null;
		}
		void SetDefaultSchema ()
		{
			var filename = document.FileName;
			if (filename == null)
				return;
			
			defaultSchemaCompletionData = XmlSchemaManager.GetSchemaCompletionDataForFileName (filename);
			if (defaultSchemaCompletionData != null)
				inferredCompletionData = null;
			else
				QueueInference ();
			defaultNamespacePrefix = XmlSchemaManager.GetNamespacePrefixForFileName (filename);
		}
		public void FixtureInit()
		{
			XmlTextReader reader = ResourceManager.GetXsdSchema();
			schemaCompletionData = new XmlSchemaCompletionData(reader);
			
			// Set up choice element's path.
			choicePath = new XmlElementPath();
			choicePath.Elements.Add(new QualifiedName("schema", namespaceURI, prefix));
			choicePath.Elements.Add(new QualifiedName("element", namespaceURI, prefix));
			choicePath.Elements.Add(new QualifiedName("complexType", namespaceURI, prefix));
			
			mixedAttributeValues = schemaCompletionData.GetAttributeValueCompletionData(choicePath, "mixed");

			choicePath.Elements.Add(new QualifiedName("choice", namespaceURI, prefix));
			
			// Get choice element info.
			choiceAttributes = schemaCompletionData.GetAttributeCompletionData(choicePath);
			maxOccursAttributeValues = schemaCompletionData.GetAttributeValueCompletionData(choicePath, "maxOccurs");
			
			// Set up element path.
			elementPath = new XmlElementPath();
			elementPath.Elements.Add(new QualifiedName("schema", namespaceURI, prefix));
			
			elementFormDefaultAttributeValues = schemaCompletionData.GetAttributeValueCompletionData(elementPath, "elementFormDefault");
			blockDefaultAttributeValues = schemaCompletionData.GetAttributeValueCompletionData(elementPath, "blockDefault");
			finalDefaultAttributeValues = schemaCompletionData.GetAttributeValueCompletionData(elementPath, "finalDefault");
			
			elementPath.Elements.Add(new QualifiedName("element", namespaceURI, prefix));
				
			// Get element attribute info.
			elementAttributes = schemaCompletionData.GetAttributeCompletionData(elementPath);

			// Set up simple enum type path.
			simpleEnumPath = new XmlElementPath();
			simpleEnumPath.Elements.Add(new QualifiedName("schema", namespaceURI, prefix));
			simpleEnumPath.Elements.Add(new QualifiedName("simpleType", namespaceURI, prefix));
			simpleEnumPath.Elements.Add(new QualifiedName("restriction", namespaceURI, prefix));
			
			// Get child elements.
			simpleEnumElements = schemaCompletionData.GetChildElementCompletionData(simpleEnumPath);

			// Set up enum path.
			enumPath = new XmlElementPath();
			enumPath.Elements.Add(new QualifiedName("schema", namespaceURI, prefix));
			enumPath.Elements.Add(new QualifiedName("simpleType", namespaceURI, prefix));
			enumPath.Elements.Add(new QualifiedName("restriction", namespaceURI, prefix));
			enumPath.Elements.Add(new QualifiedName("enumeration", namespaceURI, prefix));
			
			// Get attributes.
			enumAttributes = schemaCompletionData.GetAttributeCompletionData(enumPath);
			
			// Set up xs:all path.
			allElementPath = new XmlElementPath();
			allElementPath.Elements.Add(new QualifiedName("schema", namespaceURI, prefix));
			allElementPath.Elements.Add(new QualifiedName("element", namespaceURI, prefix));
			allElementPath.Elements.Add(new QualifiedName("complexType", namespaceURI, prefix));
			allElementPath.Elements.Add(new QualifiedName("all", namespaceURI, prefix));
		
			// Get child elements of the xs:all element.
			allElementChildElements = schemaCompletionData.GetChildElementCompletionData(allElementPath);
			
			// Set up the path to the annotation element that is a child of xs:all.
			allElementAnnotationPath = new XmlElementPath();
			allElementAnnotationPath.Elements.Add(new QualifiedName("schema", namespaceURI, prefix));
			allElementAnnotationPath.Elements.Add(new QualifiedName("element", namespaceURI, prefix));
			allElementAnnotationPath.Elements.Add(new QualifiedName("complexType", namespaceURI, prefix));
			allElementAnnotationPath.Elements.Add(new QualifiedName("all", namespaceURI, prefix));
			allElementAnnotationPath.Elements.Add(new QualifiedName("annotation", namespaceURI, prefix));
			
			// Get the xs:all annotation child element.
			allElementAnnotationChildElements = schemaCompletionData.GetChildElementCompletionData(allElementAnnotationPath);
		}
		/// <summary>
		/// Reads an individual schema and adds it to the collection.
		/// </summary>
		/// <remarks>
		/// If the schema namespace exists in the collection it is not added.
		/// </remarks>
		static void LoadSchema (List<XmlSchemaCompletionData> list, string fileName, bool readOnly)
		{
			try {
				string baseUri = XmlSchemaCompletionData.GetUri (fileName);
				XmlSchemaCompletionData data = new XmlSchemaCompletionData (baseUri, fileName);
				
				if (data.NamespaceUri == null) {
					LoggingService.LogWarning (
					    "XmlSchemaManager is ignoring schema with no namespace, from file '{0}'.",
					    data.FileName);
					return;
				}
				
				foreach (XmlSchemaCompletionData d in list) {
					if (d.NamespaceUri == data.NamespaceUri) {
						LoggingService.LogWarning (
						    "XmlSchemaManager is ignoring schema with duplicate namespace '{0}'.",
						    data.NamespaceUri);
						return;
					}
				}
				
				data.ReadOnly = readOnly;
				list.Add (data);
				
			} catch (Exception ex) {
				LoggingService.LogWarning (
				    "XmlSchemaManager is unable to read schema '{0}', because of the following error: {1}",
				    fileName, ex.Message);
			}
		}
		/// <summary>
		/// Attempts to locate the type name in the specified schema.
		/// </summary>
		/// <param name="name">The type to look up.</param>
		/// <param name="schemaCompletionData">The schema completion data to use to
		/// find the type.</param>
		/// <param name="elementName">The element to determine what sort of type it is
		/// (e.g. group, attribute, element).</param>
		/// <returns><see langword="null"/> if no match can be found.</returns>
		XmlSchemaObject FindSchemaObjectType(string name, XmlSchemaCompletionData schemaCompletionData, string elementName)
		{
			QualifiedName qualifiedName = schemaCompletionData.CreateQualifiedName(name);
			XmlSchemaCompletionData qualifiedNameSchema = FindSchema(qualifiedName.Namespace);
			if (qualifiedNameSchema != null) {
				schemaCompletionData = qualifiedNameSchema;
			}
			switch (elementName) {
				case "element":
					return schemaCompletionData.FindComplexType(qualifiedName);
				case "attribute":
					return schemaCompletionData.FindSimpleType(qualifiedName.Name);
			}
			return null;
		}
		protected virtual void addRegisteredSchema (object sender, System.EventArgs args)
		{
			string fileName = XmlEditorService.BrowseForSchemaFile ();
			if (string.IsNullOrEmpty (fileName))
				return;
			
			string shortName = System.IO.Path.GetFileName (fileName);
			
			//load the schema
			XmlSchemaCompletionData schema = null;
			try {
				schema = new XmlSchemaCompletionData (fileName);
			} catch (Exception ex) {
				string msg = GettextCatalog.GetString ("Error loading schema '{0}'.", shortName);
				MessageService.ShowException (ex, msg);
				return;
			}
			
			// Make sure the schema has a target namespace.
			if (schema.NamespaceUri == null) {
				MessageService.ShowError (
				    GettextCatalog.GetString ("Schema '{0}' has no target namespace.", shortName));
				return;
			}
			
			//if namaspace conflict, ask user whether they want to replace existing schema
			XmlSchemaCompletionData oldSchema = GetRegisteredSchema (schema.NamespaceUri);
			if (oldSchema != null) {
				bool replace = MessageService.Confirm (
				    GettextCatalog.GetString (
				        "A schema is already registered with the namespace '{0}'. Would you like to replace it?",
				        schema.NamespaceUri),
				    new AlertButton (GettextCatalog.GetString ("Replace"))
				);
				if (!replace)
					return;
				
				//remove the old schema
				RemoveRegisteredSchema (oldSchema);
			}
			
			// Store the schema so we can add it for real later, if the "ok" button's clicked
			TreeIter newIter = AddRegisteredSchema (schema);
			registeredSchemasView.Selection.SelectIter (newIter);
			ScrollToSelection (registeredSchemasView);
		}
		void RemoveRegisteredSchema (XmlSchemaCompletionData schema)
		{
			if (addedSchemas.Contains (schema) && !schema.ReadOnly)
				addedSchemas.Remove (schema);
			else
				removedSchemas.Add (schema);
			
			TreeIter iter;
			bool valid = registeredSchemasStore.GetIterFirst (out iter);
			while (valid) {
				if (GetRegisteredSchema (iter) == schema) {
					registeredSchemasStore.Remove (ref iter);
					break;
				}
				valid = registeredSchemasStore.IterNext (ref iter);
			}
			
			//restore built-in schema
			if (!schema.ReadOnly) {
				XmlSchemaCompletionData builtin = XmlSchemaManager.BuiltinSchemas[schema.NamespaceUri];
				if (builtin != null)
					AppendSchemaToStore (builtin);
			}
		}
		TreeIter AddRegisteredSchema (XmlSchemaCompletionData schema)
		{
			if (removedSchemas.Contains (schema))
				removedSchemas.Remove (schema);
			else
				addedSchemas.Add (schema);
			
			return AppendSchemaToStore (schema);
		}
		TreeIter AppendSchemaToStore (XmlSchemaCompletionData schema)
		{
			return registeredSchemasStore.AppendValues (schema);
		}
		/// <summary>
		/// If the attribute value found references another item in the schema
		/// return this instead of the attribute schema object. For example, if the
		/// user can select the attribute value and the code will work out the schema object pointed to by the ref
		/// or type attribute:
		///
		/// xs:element ref="ref-name"
		/// xs:attribute type="type-name"
		/// </summary>
		/// <returns>
		/// The <paramref name="attribute"/> if no schema object was referenced.
		/// </returns>
		XmlSchemaObject GetSchemaObjectReferenced (XmlSchemaCompletionData currentSchemaCompletionData, XmlSchemaElement element, XmlSchemaAttribute attribute)
		{
			XmlSchemaObject schemaObject = null;
			if (IsXmlSchemaNamespace(element)) {
				// Find attribute value.
				//fixme implement
				string attributeValue = "";// XmlParser.GetAttributeValueAtIndex(xml, index);
				if (attributeValue.Length == 0) {
					return attribute;
				}
		
				if (attribute.Name == "ref") {
					schemaObject = FindSchemaObjectReference(attributeValue, currentSchemaCompletionData, element.Name);
				} else if (attribute.Name == "type") {
					schemaObject = FindSchemaObjectType(attributeValue, currentSchemaCompletionData, element.Name);
				}
			}
			
			if (schemaObject != null) {
				return schemaObject;
			}
			return attribute;
		}
Beispiel #16
0
        public XmlSchemasPanelWidget()
        {
            this.Build();

            //set up tree view for default schemas
            CellRendererText textRenderer = new CellRendererText();

            registeredSchemasStore      = new ListStore(typeof(XmlSchemaCompletionData));
            registeredSchemasView.Model = registeredSchemasStore;

            registeredSchemasView.AppendColumn(GettextCatalog.GetString("Namespace"), textRenderer,
                                               delegate(TreeViewColumn col, CellRenderer cell, TreeModel model, TreeIter iter) {
                ((Gtk.CellRendererText)cell).Text = ((MonoDevelop.XmlEditor.Completion.XmlSchemaCompletionData)model.GetValue(iter, 0)).NamespaceUri;
            });

            registeredSchemasView.AppendColumn(GettextCatalog.GetString("Type"), textRenderer,
                                               delegate(TreeViewColumn col, CellRenderer cell, TreeModel model, TreeIter iter) {
                bool builtIn = ((MonoDevelop.XmlEditor.Completion.XmlSchemaCompletionData)model.GetValue(iter, 0)).ReadOnly;
                ((Gtk.CellRendererText)cell).Text = builtIn?
                                                    GettextCatalog.GetString("Built in")
                                        : GettextCatalog.GetString("User schema");
            });

            registeredSchemasStore.SetSortFunc(0,
                                               delegate(TreeModel model, TreeIter a, TreeIter b) {
                return(string.Compare(
                           ((MonoDevelop.XmlEditor.Completion.XmlSchemaCompletionData)model.GetValue(a, 0)).NamespaceUri,
                           ((MonoDevelop.XmlEditor.Completion.XmlSchemaCompletionData)model.GetValue(b, 0)).NamespaceUri
                           ));
            });
            registeredSchemasStore.SetSortColumnId(0, SortType.Ascending);

            //update state of "remove" button depending on whether schema is read-only and anything's slected
            registeredSchemasView.Selection.Changed += delegate {
                MonoDevelop.XmlEditor.Completion.XmlSchemaCompletionData data = GetSelectedSchema();
                registeredSchemasRemoveButton.Sensitive = (data != null && !data.ReadOnly);
            };
            registeredSchemasRemoveButton.Sensitive = false;

            //set up cells for associations
            CellRendererText extensionTextRenderer = new CellRendererText();

            extensionTextRenderer.Editable = true;
            CellRendererText prefixTextRenderer = new CellRendererText();

            prefixTextRenderer.Editable = true;

            CellRendererCombo comboEditor = new CellRendererCombo();

            registeredSchemasComboModel = new ListStore(typeof(string));
            comboEditor.Model           = registeredSchemasComboModel;
            comboEditor.Mode            = CellRendererMode.Editable;
            comboEditor.TextColumn      = 0;
            comboEditor.Editable        = true;
            comboEditor.HasEntry        = false;

            //rebuild combo's model from default schemas whenever editing starts
            comboEditor.EditingStarted += delegate(object sender, EditingStartedArgs args) {
                registeredSchemasComboModel.Clear();
                registeredSchemasComboModel.AppendValues(string.Empty);
                foreach (Gtk.TreeIter iter in WalkStore(registeredSchemasStore))
                {
                    registeredSchemasComboModel.AppendValues(
                        ((MonoDevelop.XmlEditor.Completion.XmlSchemaCompletionData)registeredSchemasStore.GetValue(iter, 0)).NamespaceUri
                        );
                }
                args.RetVal = true;
                registeredSchemasComboModel.SetSortColumnId(0, Gtk.SortType.Ascending);
            };

            //set up tree view for associations
            defaultAssociationsStore      = new ListStore(typeof(string), typeof(string), typeof(string), typeof(bool));
            defaultAssociationsView.Model = defaultAssociationsStore;
            defaultAssociationsView.AppendColumn(GettextCatalog.GetString("File Extension"), extensionTextRenderer, "text", DACols.Extension);
            defaultAssociationsView.AppendColumn(GettextCatalog.GetString("Namespace"), comboEditor, "text", DACols.Namespace);
            defaultAssociationsView.AppendColumn(GettextCatalog.GetString("Prefix"), prefixTextRenderer, "text", DACols.Prefix);
            defaultAssociationsStore.SetSortColumnId((int)DACols.Extension, SortType.Ascending);

            //editing handlers
            extensionTextRenderer.Edited += handleExtensionSet;
            comboEditor.Edited           += delegate(object sender, EditedArgs args) {
                setAssocValAndMarkChanged(args.Path, DACols.Namespace, args.NewText);
            };
            prefixTextRenderer.Edited += delegate(object sender, EditedArgs args) {
                foreach (char c in args.NewText)
                {
                    if (!char.IsLetterOrDigit(c))
                    {
                        //FIXME: give an error message?
                        return;
                    }
                }
                setAssocValAndMarkChanged(args.Path, DACols.Prefix, args.NewText);
            };

            //update state of "remove" button depending on whether anything's slected
            defaultAssociationsView.Selection.Changed += delegate {
                Gtk.TreeIter iter;
                defaultAssociationsRemoveButton.Sensitive =
                    defaultAssociationsView.Selection.GetSelected(out iter);
            };
            defaultAssociationsRemoveButton.Sensitive = false;
        }
		/// <summary>
		/// Attempts to locate the reference name in the specified schema.
		/// </summary>
		/// <param name="name">The reference to look up.</param>
		/// <param name="schemaCompletionData">The schema completion data to use to
		/// find the reference.</param>
		/// <param name="elementName">The element to determine what sort of reference it is
		/// (e.g. group, attribute, element).</param>
		/// <returns><see langword="null"/> if no match can be found.</returns>
		XmlSchemaObject FindSchemaObjectReference(string name, XmlSchemaCompletionData schemaCompletionData, string elementName)
		{
			QualifiedName qualifiedName = schemaCompletionData.CreateQualifiedName(name);
			XmlSchemaCompletionData qualifiedNameSchema = FindSchema(qualifiedName.Namespace);
			if (qualifiedNameSchema != null) {
				schemaCompletionData = qualifiedNameSchema;
			}
			switch (elementName) {
				case "element":
					return schemaCompletionData.FindElement(qualifiedName);
				case "attribute":
					return schemaCompletionData.FindAttribute(qualifiedName.Name);
				case "group":
					return schemaCompletionData.FindGroup(qualifiedName.Name);
				case "attributeGroup":
					return schemaCompletionData.FindAttributeGroup(qualifiedName.Name);
			}
			return null;
		}
		/// <summary>
		/// Adds the schema to the user schemas folder and makes the
		/// schema available to the xml editor.
		/// </summary>
		public static void AddUserSchema (XmlSchemaCompletionData schemaData)
		{
			if (UserSchemas [schemaData.NamespaceUri] == null) {

				if (!Directory.Exists(UserSchemaFolder)) {
					Directory.CreateDirectory (UserSchemaFolder);
				}			
	
				string fileName = Path.GetFileName (schemaData.FileName);
				string destinationFileName = Path.Combine (UserSchemaFolder, fileName);
				File.Copy (schemaData.FileName, destinationFileName);
				schemaData.FileName = destinationFileName;
				UserSchemas.Add (schemaData);
				OnUserSchemaAdded ();
			} else {
				LoggingService.LogWarning ("XmlSchemaManager cannot register two schemas with the same namespace '{0}'.", schemaData.NamespaceUri);
			}
		}	
		void SetDefaultSchema (string extension)
		{
			if (extension == null)
				return;
			
			defaultSchemaCompletionData = XmlSchemaManager.GetSchemaCompletionData (extension);
			if (defaultSchemaCompletionData != null)
				inferredCompletionData = null;
			else
				QueueInference ();
			defaultNamespacePrefix = XmlSchemaManager.GetNamespacePrefix (extension);
		}
		public void FixtureInitBase()
		{
			schemaCompletionData = CreateSchemaCompletionDataObject();
			FixtureInit();
		}