2003-10-25 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaAttribute.cs
index 8851fffde7343f6455e6b0cc4949aa948ff3a063..d6f30f5f7888d0f3da2389a130f4eca90d39e291 100755 (executable)
@@ -1,5 +1,10 @@
-// Author: Dwivedi, Ajay kumar\r
-//            Adwiv@Yahoo.com\r
+//\r
+// System.Xml.Schema.XmlSchemaAttribute.cs\r
+//\r
+// Authors:\r
+//     Dwivedi, Ajay kumar  Adwiv@Yahoo.com\r
+//     Enomoto, Atsushi     ginga@kit.hi-ho.ne.jp\r
+//\r
 using System;\r
 using System.Xml;\r
 using System.ComponentModel;\r
@@ -15,15 +20,20 @@ namespace System.Xml.Schema
                private object attributeType;\r
                private string defaultValue;\r
                private string fixedValue;\r
+               private string validatedDefaultValue;\r
+               private string validatedFixedValue;\r
                private XmlSchemaForm form;\r
                private string name;\r
+               private string targetNamespace;\r
                private XmlQualifiedName qualifiedName;\r
                private XmlQualifiedName refName;\r
                private XmlSchemaSimpleType schemaType;\r
                private XmlQualifiedName schemaTypeName;\r
                private XmlSchemaUse use;\r
+               private XmlSchemaUse validatedUse;\r
                //Compilation fields\r
-               internal bool parentIsSchema = false;\r
+               internal bool ParentIsSchema = false;\r
+               private XmlSchemaAttribute referencedAttribute;\r
                private static string xmlname = "attribute";\r
 \r
                public XmlSchemaAttribute()\r
@@ -122,8 +132,31 @@ namespace System.Xml.Schema
 \r
                [XmlIgnore]\r
                public object AttributeType \r
-               { //FIXME: This is not correct. Is it?\r
-                       get{ return attributeType; }\r
+               {\r
+                       get{\r
+                               if (referencedAttribute != null)\r
+                                       return referencedAttribute.AttributeType;\r
+                               else\r
+                                       return attributeType;\r
+                       }\r
+               }\r
+\r
+               // Post compilation default value (normalized)\r
+               internal string ValidatedDefaultValue\r
+               {\r
+                       // DefaultValue can be overriden in case of ref.\r
+                       get { return validatedDefaultValue; }\r
+               }\r
+\r
+               // Post compilation fixed value (normalized)\r
+               internal string ValidatedFixedValue \r
+               {\r
+                       // FixedValue can be overriden in case of ref.\r
+                       get { return validatedFixedValue; }\r
+               }\r
+               internal XmlSchemaUse ValidatedUse\r
+               {\r
+                       get { return validatedUse; }\r
                }\r
 \r
                #endregion\r
@@ -167,8 +200,7 @@ namespace System.Xml.Schema
                ///             3. default and fixed must not both be present. \r
                ///     4. If default and use are both present, use must have the ·actual value· optional.\r
                /// </remarks>\r
-               [MonoTODO]\r
-               internal int Compile(ValidationEventHandler h, XmlSchema schema)\r
+               internal override int Compile(ValidationEventHandler h, XmlSchema schema)\r
                {\r
                        // If this is already compiled this time, simply skip.\r
                        if (this.IsComplied (schema.CompilationId))\r
@@ -176,7 +208,7 @@ namespace System.Xml.Schema
 \r
                        errorCount = 0;\r
                        \r
-                       if(parentIsSchema)//a\r
+                       if(ParentIsSchema || isRedefineChild)//a\r
                        {\r
                                if(RefName!= null && !RefName.IsEmpty) // a.1\r
                                        error(h,"ref must be absent in the top level <attribute>");\r
@@ -187,6 +219,8 @@ namespace System.Xml.Schema
                                if(Use != XmlSchemaUse.None)            // a.3\r
                                        error(h,"use must be absent in the top level <attribute>");\r
 \r
+                               targetNamespace = schema.TargetNamespace;\r
+\r
                                // TODO: a.10, a.11, a.12, a.13\r
                                CompileCommon(h, schema, true);\r
                        }\r
@@ -195,6 +229,11 @@ namespace System.Xml.Schema
                                //FIXME: How to Use of AttributeFormDefault????\r
                                if(RefName == null || RefName.IsEmpty)\r
                                {\r
+                                       if(form == XmlSchemaForm.Qualified || (form == XmlSchemaForm.None && schema.AttributeFormDefault == XmlSchemaForm.Qualified))\r
+                                               this.targetNamespace = schema.TargetNamespace;\r
+                                       else\r
+                                               this.targetNamespace = "";\r
+\r
                                        //TODO: b.8\r
                                        CompileCommon(h, schema, true);\r
                                }\r
@@ -208,6 +247,7 @@ namespace System.Xml.Schema
                                                error(h,"simpletype must be absent if ref is present");\r
                                        if(this.schemaTypeName != null && !this.schemaTypeName.IsEmpty)\r
                                                error(h,"type must be absent if ref is present");\r
+\r
                                        CompileCommon(h, schema, false);\r
                                }\r
                        }\r
@@ -227,7 +267,7 @@ namespace System.Xml.Schema
                                else if(Name == "xmlns") // a.14 , b5\r
                                        error(h,"attribute name must not be xmlns");\r
                                else\r
-                                       qualifiedName = new XmlQualifiedName(Name, schema.TargetNamespace);     \r
+                                       qualifiedName = new XmlQualifiedName(Name, targetNamespace);\r
 \r
                                if(SchemaType != null)\r
                                {\r
@@ -243,7 +283,7 @@ namespace System.Xml.Schema
                        else\r
                        {\r
                                if(RefName == null || RefName.IsEmpty) \r
-                                       error(h,"Error: Should Never Happen. refname must be present");\r
+                                       throw new InvalidOperationException ("Error: Should Never Happen. refname must be present");\r
                                else\r
                                        qualifiedName = RefName;\r
                        }\r
@@ -265,58 +305,97 @@ namespace System.Xml.Schema
                /// Schema Component: \r
                ///                     QName, SimpleType, Scope, Default|Fixed, annotation\r
                /// </summary>\r
-               [MonoTODO]\r
-               internal int Validate(ValidationEventHandler h, XmlSchema schema)\r
+               internal override int Validate(ValidationEventHandler h, XmlSchema schema)\r
                {\r
-                       if(isCompiled)\r
+                       if(IsValidated (schema.ValidationId))\r
                                return errorCount;\r
 \r
-                       //If Parent is schema:\r
-                       if(parentIsSchema)\r
+                       // -- Attribute Declaration Schema Component --\r
+                       // {name}, {target namespace} -> QualifiedName. Already Compile()d.\r
+                       // {type definition} -> attributeType. From SchemaType or SchemaTypeName.\r
+                       // {scope} -> ParentIsSchema | isRedefineChild.\r
+                       // {value constraint} -> ValidatedFixedValue, ValidatedDefaultValue.\r
+                       // {annotation}\r
+                       // -- Attribute Use Schema Component --\r
+                       // {required}\r
+                       // {attribute declaration}\r
+                       // {value constraint}\r
+\r
+                       // First, fill type information for type reference\r
+                       if (SchemaTypeName != null && SchemaTypeName != XmlQualifiedName.Empty)\r
                        {\r
-                               if(SchemaType != null)\r
-                               {\r
-                                       errorCount += SchemaType.Validate(h, schema);\r
-                                       attributeType = SchemaType;\r
+                               // If type is null, then it is missing sub components .\r
+                               XmlSchemaType type = schema.SchemaTypes [SchemaTypeName] as XmlSchemaType;\r
+                               if (type is XmlSchemaComplexType)\r
+                                       error(h,"An attribute can't have complexType Content");\r
+                               else if (type != null) {        // simple type\r
+                                       errorCount += type.Validate (h, schema);\r
+                                       attributeType = type;\r
                                }\r
-                               else if(SchemaTypeName != null && !SchemaTypeName.IsEmpty)\r
-                               {\r
-                                       //First Try to get a Inbuilt DataType\r
-                                       XmlSchemaDatatype dtype = XmlSchemaDatatype.FromName(SchemaTypeName);\r
-                                       if(dtype != null)\r
-                                       {\r
-                                               attributeType = dtype;\r
+                               else if (SchemaTypeName == XmlSchemaComplexType.AnyTypeName)\r
+                                       attributeType = XmlSchemaComplexType.AnyType;
+                               else if (SchemaTypeName.Namespace == XmlSchema.Namespace) {\r
+                                       attributeType = XmlSchemaDatatype.FromName (SchemaTypeName);\r
+                                       if (attributeType == null)\r
+                                               error (h, "Invalid xml schema namespace datatype was specified.");\r
+                               }\r
+                               // otherwise, it might be missing sub components.\r
+                               else if (!schema.IsNamespaceAbsent (SchemaTypeName.Namespace))\r
+                                       error (h, "Referenced schema type " + SchemaTypeName + " was not found in the corresponding schema.");\r
+                       }\r
+\r
+                       // Then, fill type information for the type references for the referencing attributes\r
+                       if (RefName != null && RefName != XmlQualifiedName.Empty)\r
+                       {\r
+                               referencedAttribute = schema.Attributes [RefName] as XmlSchemaAttribute;\r
+                               // If el is null, then it is missing sub components .\r
+                               if (referencedAttribute != null)\r
+                                       errorCount += referencedAttribute.Validate (h, schema);\r
+                               // otherwise, it might be missing sub components.\r
+                               else if (!schema.IsNamespaceAbsent (RefName.Namespace))\r
+                                       error (h, "Referenced attribute " + RefName + " was not found in the corresponding schema.");\r
+                       }\r
+\r
+                       if (attributeType == null)\r
+                               attributeType = XmlSchemaSimpleType.AnySimpleType;\r
+\r
+                       // Validate {value constraints}\r
+                       if (defaultValue != null || fixedValue != null) {\r
+                               XmlSchemaDatatype datatype = attributeType as XmlSchemaDatatype;\r
+                               if (datatype == null)\r
+                                       datatype = ((XmlSchemaSimpleType) attributeType).Datatype;\r
+                               if (datatype.TokenizedType == XmlTokenizedType.QName)\r
+                                       error (h, "By the defection of the W3C XML Schema specification, it is impossible to supply QName default or fixed values.");\r
+                               else {\r
+                                       try {\r
+                                               if (defaultValue != null) {\r
+                                                       validatedDefaultValue = datatype.Normalize (defaultValue);\r
+                                                       datatype.ParseValue (validatedDefaultValue, null, null);\r
+                                               }\r
+                                       } catch (Exception ex) {\r
+                                               // FIXME: This is not a good way to handle exception.\r
+                                               error (h, "The Attribute's default value is invalid with its type definition.", ex);\r
                                        }\r
-                                       else\r
-                                       {\r
-                                               XmlSchemaObject obj = schema.SchemaTypes[SchemaTypeName];\r
-\r
-                                               if(obj is XmlSchemaSimpleType)\r
-                                               {\r
-                                                       XmlSchemaSimpleType stype = (XmlSchemaSimpleType) obj;\r
-                                                       errorCount += stype.Validate(h, schema);\r
-                                                       attributeType = stype;\r
+                                       try {\r
+                                               if (fixedValue != null) {\r
+                                                       validatedFixedValue = datatype.Normalize (fixedValue);\r
+                                                       datatype.ParseValue (validatedFixedValue, null, null);\r
                                                }\r
-                                               else if(attributeType == null)\r
-                                                       error(h,"The type '"+ SchemaTypeName +"' is not defined in the schema");\r
-                                               else if(attributeType is XmlSchemaComplexType)\r
-                                                       error(h,"An attribute can't have complexType Content");\r
-                                               else\r
-                                                       error(h, "Should Never Happen. Illegal content in SchemaTypes");\r
+                                       } catch (Exception ex) {\r
+                                               // FIXME: This is not a good way to handle exception.\r
+                                               error (h, "The Attribute's fixed value is invalid with its type definition.", ex);\r
                                        }\r
                                }\r
-                               else\r
-                               {\r
-                                       error(h,"Should Never Happen. Attribute SimpleType Not set. Should have been caught in the Compile() phase");\r
-                               }\r
                        }\r
+                       if (Use == XmlSchemaUse.None)\r
+                               validatedUse = XmlSchemaUse.Optional;\r
                        else\r
-                       {\r
-                               //TODO: Local Attribute Validation\r
-                       }\r
-                       isCompiled = true;\r
+                               validatedUse = Use;\r
+\r
+                       ValidationId = schema.ValidationId;\r
                        return errorCount;\r
                }\r
+\r
                //<attribute\r
                //  default = string\r
                //  fixed = string\r