示例#1
0
        // Get the row-elem associatd w/ the region node is in.
        // If node is in a region not mapped (like document element node) the function returns false and sets elem to null)
        // This function does not work if the region is not associated w/ a DataRow (it uses DataRow association to know what is the row element associated w/ the region)
        internal bool GetRegion(XmlNode node, out XmlBoundElement rowElem)
        {
            while (node != null)
            {
                XmlBoundElement be = node as XmlBoundElement;
                // Break if found a region
                if (be != null && GetRowFromElement(be) != null)
                {
                    rowElem = be;
                    return(true);
                }

                if (node.NodeType == XmlNodeType.Attribute)
                {
                    node = ((XmlAttribute)node).OwnerElement;
                }
                else
                {
                    node = node.ParentNode;
                }
            }

            rowElem = null;
            return(false);
        }
示例#2
0
        internal DataColumn GetColumnSchemaForNode(XmlBoundElement rowElem, XmlNode node)
        {
            object    identity  = GetIdentity(rowElem.LocalName, rowElem.NamespaceURI);
            object    obj2      = GetIdentity(node.LocalName, node.NamespaceURI);
            Hashtable hashtable = (Hashtable)this.columnSchemaMap[identity];

            if (hashtable != null)
            {
                DataColumn column = (DataColumn)hashtable[obj2];
                if (column == null)
                {
                    return(null);
                }
                MappingType columnMapping = column.ColumnMapping;
                if ((node.NodeType == XmlNodeType.Attribute) && (columnMapping == MappingType.Attribute))
                {
                    return(column);
                }
                if ((node.NodeType == XmlNodeType.Element) && (columnMapping == MappingType.Element))
                {
                    return(column);
                }
            }
            return(null);
        }
示例#3
0
        internal DataColumn GetColumnSchemaForNode(XmlBoundElement rowElem, XmlNode node)
        {
            //
            Debug.Assert(rowElem != null);
            // The caller must make sure that node is not a row-element
            Debug.Assert((node is XmlBoundElement) ? ((XmlBoundElement)node).Row == null : true);

            object tid = GetIdentity(rowElem.LocalName, rowElem.NamespaceURI);
            object cid = GetIdentity(node.LocalName, node.NamespaceURI);

            Hashtable columns = (Hashtable)columnSchemaMap[tid];

            if (columns != null)
            {
                DataColumn col = (DataColumn)(columns[cid]);
                if (col == null)
                {
                    return(null);
                }

                MappingType mt = col.ColumnMapping;

                if (node.NodeType == XmlNodeType.Attribute && mt == MappingType.Attribute)
                {
                    return(col);
                }
                if (node.NodeType == XmlNodeType.Element && mt == MappingType.Element)
                {
                    return(col);
                }
                // node's (localName, ns) matches a column, but the MappingType is different (i.e. node is elem, MT is attr)
                return(null);
            }
            return(null);
        }
示例#4
0
        internal DataTable SearchMatchingTableSchema(XmlBoundElement rowElem, XmlBoundElement elem)
        {
            DataTable table = this.SearchMatchingTableSchema(elem.LocalName, elem.NamespaceURI);

            if (table != null)
            {
                if (rowElem == null)
                {
                    return(table);
                }
                if (this.GetColumnSchemaForNode(rowElem, elem) == null)
                {
                    return(table);
                }
                foreach (XmlAttribute attribute in elem.Attributes)
                {
                    if (attribute.NamespaceURI != "http://www.w3.org/2000/xmlns/")
                    {
                        return(table);
                    }
                }
                for (XmlNode node = elem.FirstChild; node != null; node = node.NextSibling)
                {
                    if (node.NodeType == XmlNodeType.Element)
                    {
                        return(table);
                    }
                }
            }
            return(null);
        }
示例#5
0
 private void AssertValid()
 {
     if (this.column != null)
     {
         XmlBoundElement node         = this.node as XmlBoundElement;
         DataRow         row          = node.Row;
         ElementState    elementState = node.ElementState;
         DataRowState    rowState     = row.RowState;
     }
 }
示例#6
0
        internal DataTable GetTableSchemaForElement(XmlElement elem)
        {
            XmlBoundElement be = elem as XmlBoundElement;

            if (be == null)
            {
                return(null);
            }
            return(this.GetTableSchemaForElement(be));
        }
示例#7
0
        internal DataTable GetTableSchemaForElement(XmlBoundElement be)
        {
            DataRow row = be.Row;

            if (row != null)
            {
                return(row.Table);
            }
            return(null);
        }
示例#8
0
        internal DataRow GetRowFromElement(XmlElement e)
        {
            XmlBoundElement element = e as XmlBoundElement;

            if (element != null)
            {
                return(element.Row);
            }
            return(null);
        }
示例#9
0
        // ATTENTION: GetRowFromElement( XmlElement ) and GetRowFromElement( XmlBoundElement ) should have the same functionality and side effects.
        // See this code fragment for why:
        //     XmlBoundElement be = ...;
        //     XmlElement e = be;
        //     GetRowFromElement( be ); // Calls GetRowFromElement( XmlBoundElement )
        //     GetRowFromElement( e );  // Calls GetRowFromElement( XmlElement ), in spite of e beeing an instance of XmlBoundElement
        internal DataRow GetRowFromElement(XmlElement e)
        {
            XmlBoundElement be = e as XmlBoundElement;

            if (be != null)
            {
                return(be.Row);
            }
            return(null);
        }
 private XPathNodePointer(DataDocumentXPathNavigator owner, XmlDataDocument doc, XmlNode node, DataColumn c, bool bOnValue, XmlBoundElement parentOfNS)
 {
     this._owner = new WeakReference(owner);
     this._doc = doc;
     this._node = node;
     this._column = c;
     this._fOnValue = bOnValue;
     this._parentOfNS = parentOfNS;
     this._doc.AddPointer(this);
     this._bNeedFoliate = false;
 }
示例#11
0
        internal DataTable GetTableSchemaForElement(XmlElement elem)
        {
            //TODO: Create an overridable that takes an XmlBoundElement.
            XmlBoundElement be = elem as XmlBoundElement;

            if (be == null)
            {
                return(null);
            }

            return(GetTableSchemaForElement(be));
        }
示例#12
0
        internal DataTable GetTableSchemaForElement(XmlBoundElement be)
        {
            // if bound to a row, must be a table.
            DataRow row = be.Row;

            if (row != null)
            {
                return(row.Table);
            }

            return(null);
        }
示例#13
0
        // SearchMatchingTableSchema function works only when the elem has not been bound to a DataRow. If you want to get the table associated w/ an element after 
        // it has been associated w/ a DataRow use GetTableSchemaForElement function.
        // rowElem is the parent region rowElem or null if there is no parent region (in case elem is a row elem, then rowElem will be the parent region; if elem is not
        //    mapped to a DataRow, then rowElem is the region elem is part of)
        //
        // Those are the rules for determing if elem is a row element:
        //  1. node is an element (already meet, since elem is of type XmlElement)
        //  2. If the node is already associated w/ a DataRow, then the node is a row element - not applicable, b/c this function is intended to be called on a
        //    to find out if the node s/b associated w/ a DataRow (see XmlDataDocument.LoadRows)
        //  3. If the node localName/ns matches a DataTable then
        //      3.1 Take the parent region DataTable (in our case rowElem.Row.DataTable)
        //          3.2 If no parent region, then the node is associated w/ a DataTable
        //          3.3 If there is a parent region
        //              3.3.1 If the node has no elem children and no attr other than namespace declaration, and the node can match
        //                  a column from the parent region table, then the node is NOT associated w/ a DataTable (it is a potential DataColumn in the parent region)
        //              3.3.2 Else the node is a row-element (and associated w/ a DataTable / DataRow )
        //
        internal DataTable SearchMatchingTableSchema( XmlBoundElement rowElem, XmlBoundElement elem ) {
            Debug.Assert( elem != null );

            DataTable t = SearchMatchingTableSchema( elem.LocalName, elem.NamespaceURI );
            if ( t == null )
                return null;

            if ( rowElem == null )
                return t;
            // Currently we expect we map things from top of the tree to the bottom
            Debug.Assert( rowElem.Row != null );

            DataColumn col = GetColumnSchemaForNode( rowElem, elem );
            if ( col == null )
                return t;

            foreach ( XmlAttribute a in elem.Attributes ) {
#if DEBUG
                // Some sanity check to catch errors like namespace attributes have the right localName/namespace value, but a wrong atomized namespace value
                if ( a.LocalName == "xmlns" ) {
                    Debug.Assert( a.Prefix != null && a.Prefix.Length == 0 );
                    Debug.Assert( (object)a.NamespaceURI == (object)strReservedXmlns );
                }
                if ( a.Prefix == "xmlns" ) {
                    Debug.Assert( (object)a.NamespaceURI == (object)strReservedXmlns );
                }
                if ( a.NamespaceURI == strReservedXmlns )
                    Debug.Assert( (object)a.NamespaceURI == (object)strReservedXmlns );
#endif
                // No namespace attribute found, so elem cannot be a potential DataColumn, therefore is a row-elem
                if ( (object)(a.NamespaceURI) != (object)strReservedXmlns )
                    return t;
            }

            for ( XmlNode n = elem.FirstChild; n != null; n = n.NextSibling ) {
                if ( n.NodeType == XmlNodeType.Element ) {
                    // elem has an element child, so elem cannot be a potential DataColumn, therefore is a row-elem
                    return t;
                }
            }
            // Node is a potential DataColumn in rowElem region
            return null;
        }
 internal bool GetRegion(XmlNode node, out XmlBoundElement rowElem)
 {
     while (node != null)
     {
         XmlBoundElement be = node as XmlBoundElement;
         if ((be != null) && (this.GetRowFromElement(be) != null))
         {
             rowElem = be;
             return true;
         }
         if (node.NodeType == XmlNodeType.Attribute)
         {
             node = ((XmlAttribute) node).OwnerElement;
         }
         else
         {
             node = node.ParentNode;
         }
     }
     rowElem = null;
     return false;
 }
示例#15
0
        private void AssertValid()
        {
            // This pointer must be int the document list
            if (_column != null)
            {
                // We must be on a de-foliated region
                XmlBoundElement rowElem = _node as XmlBoundElement;
                Debug.Assert(rowElem != null);

                DataRow row = rowElem.Row;
                Debug.Assert(row != null);

                ElementState state = rowElem.ElementState;
                Debug.Assert(state == ElementState.Defoliated, "Region is accessed using column, but it's state is FOLIATED");

                // We cannot be on a column for which the value is DBNull
                DataRowVersion rowVersion = (row.RowState == DataRowState.Detached) ? DataRowVersion.Proposed : DataRowVersion.Current;
                Debug.Assert(!Convert.IsDBNull(row[_column, rowVersion]));

                // If we are on the Text column, we should always have fOnValue == true
                Debug.Assert((_column.ColumnMapping == MappingType.SimpleContent) ? (_fOnValue == true) : true);
            }
        }
 internal DataColumn GetColumnSchemaForNode(XmlBoundElement rowElem, XmlNode node)
 {
     object identity = GetIdentity(rowElem.LocalName, rowElem.NamespaceURI);
     object obj2 = GetIdentity(node.LocalName, node.NamespaceURI);
     Hashtable hashtable = (Hashtable) this.columnSchemaMap[identity];
     if (hashtable != null)
     {
         DataColumn column = (DataColumn) hashtable[obj2];
         if (column == null)
         {
             return null;
         }
         MappingType columnMapping = column.ColumnMapping;
         if ((node.NodeType == XmlNodeType.Attribute) && (columnMapping == MappingType.Attribute))
         {
             return column;
         }
         if ((node.NodeType == XmlNodeType.Element) && (columnMapping == MappingType.Element))
         {
             return column;
         }
     }
     return null;
 }
示例#17
0
 internal DataRow?GetRowFromElement(XmlBoundElement be) => be.Row;
示例#18
0
 internal DataTable?GetTableSchemaForElement(XmlBoundElement be) => be.Row?.Table;
示例#19
0
 private bool IsFoliated(XmlBoundElement be)
 {
     return be.IsFoliated;
 }
        internal bool OnRowElement()
        {
            XmlBoundElement currentNode = this.CurrentNode as XmlBoundElement;

            return((currentNode != null) && (currentNode.Row != null));
        }
示例#21
0
 private void UpdateAllColumns(DataRow row, XmlBoundElement rowElement)
 {
     foreach (DataColumn c in row.Table.Columns)
     {
         OnColumnValueChanged(row, c, rowElement);
     }
 }
示例#22
0
 internal bool IsRegionRadical(XmlBoundElement rowElem)
 {
     if (rowElem.ElementState != ElementState.Defoliated)
     {
         DataColumnCollection columns = this.GetTableSchemaForElement(rowElem).Columns;
         int iColumn = 0;
         int count   = rowElem.Attributes.Count;
         for (int i = 0; i < count; i++)
         {
             XmlAttribute node = rowElem.Attributes[i];
             if (!node.Specified)
             {
                 return(false);
             }
             DataColumn columnSchemaForNode = this.GetColumnSchemaForNode(rowElem, node);
             if (columnSchemaForNode == null)
             {
                 return(false);
             }
             if (!this.IsNextColumn(columns, ref iColumn, columnSchemaForNode))
             {
                 return(false);
             }
             XmlNode node3 = node.FirstChild;
             if (((node3 == null) || (node3.NodeType != XmlNodeType.Text)) || (node3.NextSibling != null))
             {
                 return(false);
             }
         }
         iColumn = 0;
         XmlNode firstChild = rowElem.FirstChild;
         while (firstChild != null)
         {
             if (firstChild.NodeType != XmlNodeType.Element)
             {
                 return(false);
             }
             XmlElement e = firstChild as XmlElement;
             if (this.GetRowFromElement(e) != null)
             {
                 break;
             }
             DataColumn col = this.GetColumnSchemaForNode(rowElem, e);
             if (col == null)
             {
                 return(false);
             }
             if (!this.IsNextColumn(columns, ref iColumn, col))
             {
                 return(false);
             }
             if (e.HasAttributes)
             {
                 return(false);
             }
             XmlNode node2 = e.FirstChild;
             if (((node2 == null) || (node2.NodeType != XmlNodeType.Text)) || (node2.NextSibling != null))
             {
                 return(false);
             }
             firstChild = firstChild.NextSibling;
         }
         while (firstChild != null)
         {
             if (firstChild.NodeType != XmlNodeType.Element)
             {
                 return(false);
             }
             if (this.GetRowFromElement((XmlElement)firstChild) == null)
             {
                 return(false);
             }
             firstChild = firstChild.NextSibling;
         }
     }
     return(true);
 }
示例#23
0
        // Disconnect the DataRow associated w/ the rowElem region
        private void EnsureDisconnectedDataRow(XmlBoundElement rowElem)
        {
            Debug.Assert(rowElem.Row != null);

            DataRow row = rowElem.Row;
            DataRowState rowState = row.RowState;

            switch (rowState)
            {
                case DataRowState.Detached:
#if DEBUG
                    try
                    {
                        Debug.Assert(row.Table.DataSet.EnforceConstraints == false);
#endif
                        SetNestedParentRegion(rowElem);
#if DEBUG
                    }
                    catch
                    {
                        // We should not get any exceptions here
                        Debug.Assert(false);
                        throw;
                    }
#endif
                    break;

                case DataRowState.Deleted:
                    // Nothing to do: moving a region associated w/ a deleted row to another disconnected tree is a NO-OP.
                    break;

                case DataRowState.Unchanged:
                case DataRowState.Modified:
                    EnsureFoliation(rowElem, ElementState.WeakFoliation);
                    row.Delete();
                    break;

                case DataRowState.Added:
                    EnsureFoliation(rowElem, ElementState.WeakFoliation);
                    row.Delete();
                    SetNestedParentRegion(rowElem);
                    break;

                default:
                    // Handle your case above
                    Debug.Assert(false);
                    break;
            }

            Debug.Assert(!IsRowLive(rowElem.Row));
        }
示例#24
0
 internal bool MoveToNamespace(string name) {
     //Debug.WriteLineIf( XmlTrace.traceXPathNodePointerFunctions.Enabled, "XPathNodePointer:MoveToNamespace(name)");
     _parentOfNS = this._node as XmlBoundElement;
     //only need to check with _node, even if _column is not null and its mapping type is element, it can't have attributes
     if ( _parentOfNS == null )
         return false; 
     string attrName = name;
     if ( attrName == "xmlns" )
         attrName = "xmlns:xmlns";
     if ( attrName != null && attrName.Length == 0 )
         attrName = "xmlns";
     RealFoliate();
     XmlNode node = this._node;
     XmlNodeType nt = node.NodeType;
     XmlAttribute attr = null;
     XmlBoundElement be = null;
     while ( node != null ) {
         //check current element node
         be = node as XmlBoundElement;
         if ( be != null ) {
             if ( be.IsFoliated ) {
                 attr = be.GetAttributeNode ( name, s_strReservedXmlns );
                 if ( attr != null ) {
                     MoveTo( attr );
                     return true;
                 }
             } 
             else {//defoliated so that we need to search through its column 
                 DataRow curRow = be.Row;
                 if ( curRow == null )
                     return false;
                 //going through its attribute columns
                 DataColumn curCol = PreviousColumn( curRow, null, true );
                 while ( curCol != null ) {
                     if ( curCol.Namespace == s_strReservedXmlns && curCol.ColumnName == name ) {
                         MoveTo( be, curCol, false );
                         return true;
                     }
                     curCol = PreviousColumn( curRow, curCol, true );
                 }
             }
         } 
         //didn't find it, try the next element anccester.
         do {
             node = node.ParentNode;
         } while ( node != null && node.NodeType != XmlNodeType.Element );
     }
     //nothing happens, the name doesn't exist as a namespace node.
     _parentOfNS = null;
     return false;
 }
示例#25
0
        // SearchMatchingTableSchema function works only when the elem has not been bound to a DataRow. If you want to get the table associated w/ an element after
        // it has been associated w/ a DataRow use GetTableSchemaForElement function.
        // rowElem is the parent region rowElem or null if there is no parent region (in case elem is a row elem, then rowElem will be the parent region; if elem is not
        //    mapped to a DataRow, then rowElem is the region elem is part of)
        //
        // Those are the rules for determing if elem is a row element:
        //  1. node is an element (already meet, since elem is of type XmlElement)
        //  2. If the node is already associated w/ a DataRow, then the node is a row element - not applicable, b/c this function is intended to be called on a
        //    to find out if the node s/b associated w/ a DataRow (see XmlDataDocument.LoadRows)
        //  3. If the node localName/ns matches a DataTable then
        //      3.1 Take the parent region DataTable (in our case rowElem.Row.DataTable)
        //          3.2 If no parent region, then the node is associated w/ a DataTable
        //          3.3 If there is a parent region
        //              3.3.1 If the node has no elem children and no attr other than namespace declaration, and the node can match
        //                  a column from the parent region table, then the node is NOT associated w/ a DataTable (it is a potential DataColumn in the parent region)
        //              3.3.2 Else the node is a row-element (and associated w/ a DataTable / DataRow )
        //
        internal DataTable SearchMatchingTableSchema(XmlBoundElement rowElem, XmlBoundElement elem)
        {
            Debug.Assert(elem != null);

            DataTable t = SearchMatchingTableSchema(elem.LocalName, elem.NamespaceURI);

            if (t == null)
            {
                return(null);
            }

            if (rowElem == null)
            {
                return(t);
            }
            // Currently we expect we map things from top of the tree to the bottom
            Debug.Assert(rowElem.Row != null);

            DataColumn col = GetColumnSchemaForNode(rowElem, elem);

            if (col == null)
            {
                return(t);
            }

            foreach (XmlAttribute a in elem.Attributes)
            {
#if DEBUG
                // Some sanity check to catch errors like namespace attributes have the right localName/namespace value, but a wrong atomized namespace value
                if (a.LocalName == "xmlns")
                {
                    Debug.Assert(a.Prefix != null && a.Prefix.Length == 0);
                    Debug.Assert((object)a.NamespaceURI == (object)strReservedXmlns);
                }
                if (a.Prefix == "xmlns")
                {
                    Debug.Assert((object)a.NamespaceURI == (object)strReservedXmlns);
                }
                if (a.NamespaceURI == strReservedXmlns)
                {
                    Debug.Assert((object)a.NamespaceURI == (object)strReservedXmlns);
                }
#endif
                // No namespace attribute found, so elem cannot be a potential DataColumn, therefore is a row-elem
                if ((object)(a.NamespaceURI) != (object)strReservedXmlns)
                {
                    return(t);
                }
            }

            for (XmlNode n = elem.FirstChild; n != null; n = n.NextSibling)
            {
                if (n.NodeType == XmlNodeType.Element)
                {
                    // elem has an element child, so elem cannot be a potential DataColumn, therefore is a row-elem
                    return(t);
                }
            }
            // Node is a potential DataColumn in rowElem region
            return(null);
        }
 internal RegionIterator(XmlBoundElement rowElement) : base(((XmlDataDocument)rowElement.OwnerDocument).Mapper)
 {
     this.rowElement  = rowElement;
     this.currentNode = rowElement;
 }
示例#27
0
        // A non-row-elem was inserted into disconnected tree (fragment) from oldParent==null state (i.e. was disconnected)
        private void OnNonRowElementInsertedInFragment(XmlNode node, XmlBoundElement rowElement, ArrayList rowElemList)
        {
            // non-row-elem is beeing inserted
            DataRow row = rowElement.Row;
            // Region should already have an associated data row (otherwise how was the original row-elem inserted ?)
            Debug.Assert(row != null);
            // Since oldParent == null, the only 2 row states should have been Detached or Deleted
            Debug.Assert(row.RowState == DataRowState.Detached || row.RowState == DataRowState.Deleted);

            if (row.RowState == DataRowState.Detached)
                SynchronizeRowFromRowElementEx(rowElement, rowElemList);
            // Nothing to do if the row is deleted (there is no sync-ing from XML to ROM for deleted rows)
        }
示例#28
0
 // A non-row-elem was inserted into the connected tree (connected) from oldParent==null state
 private void OnNonRowElementInsertedInTree(XmlNode node, XmlBoundElement rowElement, ArrayList rowElemList)
 {
     // non-row-elem is beeing inserted
     DataRow row = rowElement.Row;
     // Region should already have an associated data row (otherwise how was the original row-elem inserted ?)
     Debug.Assert(row != null);
     SynchronizeRowFromRowElement(rowElement);
     if (rowElemList != null)
     {
         TreeIterator iter = new TreeIterator(node);
         for (bool fMore = iter.NextRowElement(); fMore; fMore = iter.NextRightRowElement())
             rowElemList.Add(iter.CurrentNode);
     }
 }
示例#29
0
 private XPathNodePointer( DataDocumentXPathNavigator owner, XmlDataDocument doc, XmlNode node, DataColumn c, bool bOnValue, XmlBoundElement parentOfNS ) {
     Debug.Assert( owner != null );
     this._owner = new WeakReference( owner );
     this._doc = doc;
     this._node = node;
     this._column = c;
     this._fOnValue = bOnValue;
     this._parentOfNS = parentOfNS;
     // Add this pointer to the document so it will be updated each time region changes it's foliation state.
     this._doc.AddPointer( (IXmlDataVirtualNode)this );
     _bNeedFoliate = false;
     AssertValid();
 }
示例#30
0
        //Caller( DataDocumentXPathNavigator will make sure that the node is at the right position for this call )
        internal bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) {
            //Debug.WriteLineIf( XmlTrace.traceXPathNodePointerFunctions.Enabled, "XPathNodePointer:MoveToFirstNamespace(namespaceScope)");
            RealFoliate();
            _parentOfNS = this._node as XmlBoundElement;
            //only need to check with _node, even if _column is not null and its mapping type is element, it can't have attributes
            if ( _parentOfNS == null )
                return false; 
            XmlNode node = this._node;
            XmlBoundElement be = null;
            while ( node != null ) {
                be = node as XmlBoundElement;
                if ( MoveToNextNamespace( be, null, null ) )
                    return true;
                //didn't find it
                if ( namespaceScope == XPathNamespaceScope.Local )
                    goto labelNoNS;
                //try the next element anccestor.
                do {
                    node = node.ParentNode;
                } while ( node != null && node.NodeType != XmlNodeType.Element );
            }
            if ( namespaceScope == XPathNamespaceScope.All ) {
                MoveTo( this._doc.attrXml, null, false );
                return true;
            }
labelNoNS:
            //didn't find one namespace node
            _parentOfNS = null;
            return false;
        }
示例#31
0
        //The function only helps to find out if there is a namespace declaration of given name is defined on the given node
        //It will not check the accestors of the given node.
        private string GetNamespace( XmlBoundElement be, string name ) {
            //Debug.WriteLineIf( XmlTrace.traceXPathNodePointerFunctions.Enabled, "XPathNodePointer:GetNamespace(be,name)");

            if ( be == null )
                return null;
            XmlAttribute attr = null;
            if ( be.IsFoliated ) {
                attr = be.GetAttributeNode ( name, s_strReservedXmlns );
                if ( attr != null )
                    return attr.Value;
                else
                    return null;
            } 
            else { //defoliated so that we need to search through its column 
                DataRow curRow = be.Row;
                if ( curRow == null )
                    return null;
                //going through its attribute columns
                DataColumn curCol = PreviousColumn( curRow, null, true );
                while ( curCol != null ) {
                    if ( curCol.Namespace == s_strReservedXmlns ) {
                        //
                        DataRowVersion rowVersion = ( curRow.RowState == DataRowState.Detached ) ? DataRowVersion.Proposed : DataRowVersion.Current;
                        return curCol.ConvertObjectToXml( curRow[curCol,rowVersion] );
                    }
                    curCol = PreviousColumn( curRow, curCol, true );
                }
                return null;
            }
        }
示例#32
0
        // A row-elem was inserted into the connected tree (connected) from oldParent==null state
        private void OnRowElementInsertedInTree(XmlBoundElement rowElem, ArrayList rowElemList)
        {
            Debug.Assert(rowElem.Row != null);

            DataRow row = rowElem.Row;
            DataRowState rowState = row.RowState;

            switch (rowState)
            {
                case DataRowState.Detached:
#if DEBUG
                    try
                    {
                        Debug.Assert(row.Table.DataSet.EnforceConstraints == false);
#endif
                        row.Table.Rows.Add(row);
                        SetNestedParentRegion(rowElem);
#if DEBUG
                    }
                    catch
                    {
                        // We should not get any exceptions here
                        Debug.Assert(false);
                        throw;
                    }
#endif
                    // Add all sub-regions to the list if the caller needs this
                    if (rowElemList != null)
                    {
                        RegionIterator iter = new RegionIterator(rowElem);
                        for (bool fMore = iter.NextRowElement(); fMore; fMore = iter.NextRightRowElement())
                            rowElemList.Add(iter.CurrentNode);
                    }
                    break;
                case DataRowState.Deleted:
#if DEBUG
                    try
                    {
                        Debug.Assert(row.Table.DataSet.EnforceConstraints == false);
#endif
                        // Change the row status to be alive (unchanged)
                        row.RejectChanges();
                        // Set ROM from XML
                        SynchronizeRowFromRowElement(rowElem, rowElemList);
                        // Set nested parent data row according to where is the row positioned in the tree
                        SetNestedParentRegion(rowElem);
#if DEBUG
                    }
                    catch
                    {
                        // We should not get any exceptions here
                        Debug.Assert(false);
                        throw;
                    }
#endif
                    break;
                default:
                    // Handle your case above
                    Debug.Assert(false);
                    break;
            }
            Debug.Assert(IsRowLive(rowElem.Row));
        }
示例#33
0
        //the function will find the next namespace node on the given bound element starting with the given column or attribte
        // wether to use column or attribute depends on if the bound element is folicated or not.
        private bool MoveToNextNamespace( XmlBoundElement be, DataColumn col, XmlAttribute curAttr ) {
            //Debug.WriteLineIf( XmlTrace.traceXPathNodePointerFunctions.Enabled, "XPathNodePointer:MoveToNextNamespace(be,col,curAttr)");
            if ( be != null ) {
                if ( be.IsFoliated ) {
                    XmlAttributeCollection attrs = be.Attributes;
                    XmlAttribute attr = null;
                    bool bFound = false;
                    if ( curAttr == null )
                        bFound = true; //the first namespace will be the one
#if DEBUG
                    if ( curAttr != null )
                        Debug.Assert( curAttr.NamespaceURI == s_strReservedXmlns );
#endif
                    Debug.Assert( attrs!=null );
                    int attrInd = attrs.Count;                
                    while ( attrInd > 0 ) {
                        attrInd--;
                        attr = attrs[attrInd];
                        if ( bFound && attr.NamespaceURI == s_strReservedXmlns && !DuplicateNS( be, attr.LocalName ) ) {
                            MoveTo(attr);
                            return true;
                        }
                        if ( attr == curAttr )
                            bFound = true;
                    }
                } 
                else {//defoliated so that we need to search through its column 
                    DataRow curRow = be.Row;
                    if ( curRow == null )
                        return false;
                    //going through its attribute columns
                    DataColumn curCol = PreviousColumn( curRow, col, true );
                    while ( curCol != null ) {
                        if ( curCol.Namespace == s_strReservedXmlns && !DuplicateNS( be, curCol.ColumnName ) ) {
                            MoveTo( be, curCol, false );
                            return true;
                        }
                        curCol = PreviousColumn( curRow, curCol, true );
                    }
                }
            } 
            return false;
        }
示例#34
0
        internal DataColumn GetColumnSchemaForNode( XmlBoundElement rowElem, XmlNode node ) {
            // 
            Debug.Assert( rowElem != null );
            // The caller must make sure that node is not a row-element
            Debug.Assert( (node is XmlBoundElement) ? ((XmlBoundElement)node).Row == null : true );

            object tid = GetIdentity( rowElem.LocalName, rowElem.NamespaceURI );
            object cid = GetIdentity( node.LocalName, node.NamespaceURI );

            Hashtable columns = (Hashtable) columnSchemaMap[ tid ];
            if ( columns != null ) {
                DataColumn col = (DataColumn)(columns[ cid ]);
                if ( col == null )
                    return null;

                MappingType mt = col.ColumnMapping;

                if ( node.NodeType == XmlNodeType.Attribute && mt == MappingType.Attribute )
                    return col;
                if ( node.NodeType == XmlNodeType.Element && mt == MappingType.Element )
                    return col;
                // node's (localName, ns) matches a column, but the MappingType is different (i.e. node is elem, MT is attr)
                return null;
            }
            return null;
        }
示例#35
0
 //endElem is on the path from startElem to root is enforced by the caller
 private bool DuplicateNS( XmlBoundElement endElem, string lname) {
     //Debug.WriteLineIf( XmlTrace.traceXPathNodePointerFunctions.Enabled, "XPathNodePointer:DuplicateNS(endElem, lname)");
     if ( this._parentOfNS == null || endElem == null )
         return false;
     XmlBoundElement be = this._parentOfNS; 
     XmlNode node = null;
     while ( be != null && be != endElem ) {
         if ( GetNamespace( be, lname ) != null )
             return true;
         node = (XmlNode)be;
         do {
             node = node.ParentNode;
         } while ( node != null && node.NodeType != XmlNodeType.Element );
         be = node as XmlBoundElement;
     }
     return false;            
 }
示例#36
0
 internal DataRow GetRowFromElement( XmlBoundElement be ) {
     return be.Row;
 }
示例#37
0
        private void SetNestedParentRegion(XmlBoundElement childRowElem)
        {
            Debug.Assert(childRowElem.Row != null);

            XmlBoundElement parentRowElem;
            _mapper.GetRegion(childRowElem.ParentNode, out parentRowElem);
            SetNestedParentRegion(childRowElem, parentRowElem);
        }
示例#38
0
        internal bool IsRegionRadical( XmlBoundElement rowElem ) {
            // You must pass a row element (which s/b associated w/ a DataRow)
            Debug.Assert( rowElem.Row != null );

            if ( rowElem.ElementState == ElementState.Defoliated )
                return true;

            DataTable table = GetTableSchemaForElement( rowElem );
            DataColumnCollection columns = table.Columns;
            int iColumn = 0;

            // check column attributes...
            int cAttrs = rowElem.Attributes.Count;
            for ( int iAttr = 0; iAttr < cAttrs; iAttr++ ) {
                XmlAttribute attr = rowElem.Attributes[iAttr];

                // only specified attributes are radical
                if ( !attr.Specified )
                    return false;

                // only mapped attrs are valid
                DataColumn schema = GetColumnSchemaForNode( rowElem, attr );
                if ( schema == null ) {
                    //Console.WriteLine("Region has unmapped attribute");
                    return false;
                }

                // check to see if column is in order
                if ( !IsNextColumn( columns, ref iColumn, schema ) ) {
                    //Console.WriteLine("Region has attribute columns out of order or duplicate");
                    return false;
                }

                // must have exactly one text node (XmlNodeType.Text) child
                // 
                XmlNode fc = attr.FirstChild;
                if ( fc == null || fc.NodeType != XmlNodeType.Text || fc.NextSibling != null ) {
                    //Console.WriteLine("column element has other than a single child text node");
                    return false;
                }
            }

            // check column elements
            iColumn = 0;
            XmlNode n = rowElem.FirstChild;
            for ( ; n != null; n = n.NextSibling ) {
                // only elements can exist in radically structured data
                if ( n.NodeType != XmlNodeType.Element ) {
                    //Console.WriteLine("Region has non-element child");
                    return false;
                }
                XmlElement e = n as XmlElement;

                // only checking for column mappings in this loop
                if ( GetRowFromElement( e ) != null )
                    break;

                // element's must have schema to be radically structured
                DataColumn schema = GetColumnSchemaForNode( rowElem, e );
                if ( schema == null ) {
                    //Console.WriteLine("Region has unmapped child element");
                    return false;
                }

                // check to see if column is in order
                if ( !IsNextColumn( columns, ref iColumn, schema ) ) {
                    //Console.WriteLine("Region has element columns out of order or duplicate");
                    return false;
                }

                // must have no attributes
                if ( e.HasAttributes )
                    return false;

                // must have exactly one text node child
                XmlNode fc = e.FirstChild;
                if ( fc == null || fc.NodeType != XmlNodeType.Text || fc.NextSibling != null ) {
                    //Console.WriteLine("column element has other than a single child text node");
                    return false;
                }
            }

            // check for remaining sub-regions
            for (; n != null; n = n.NextSibling ) {
                // only elements can exist in radically structured data
                if ( n.NodeType != XmlNodeType.Element ) {
                    //Console.WriteLine("Region has non-element child");
                    return false;
                }

                // element's must be regions in order to be radially structured
                DataRow row = GetRowFromElement( (XmlElement)n );
                if ( row == null ) {
                    //Console.WriteLine("Region has unmapped element");
                    return false;
                }
            }

            return true;
        }
示例#39
0
 internal DataRow GetRowFromElement(XmlBoundElement be)
 {
     return(be.Row);
 }
示例#40
0
        private void SetNestedParentRegion(XmlBoundElement childRowElem, XmlBoundElement parentRowElem)
        {
            DataRow childRow = childRowElem.Row;
            if (parentRowElem == null)
            {
                SetNestedParentRow(childRow, null);
                return;
            }

            DataRow parentRow = parentRowElem.Row;
            Debug.Assert(parentRow != null);
            // We should set it only if there is a nested relationship between this child and parent regions
            DataRelation[] relations = childRow.Table.NestedParentRelations;
            if (relations.Length != 0 && relations[0].ParentTable == parentRow.Table) // just backward compatable
            {
                SetNestedParentRow(childRow, parentRow);
            }
            else
            {
                SetNestedParentRow(childRow, null);
            }
        }
示例#41
0
        internal bool IsRegionRadical(XmlBoundElement rowElem)
        {
            // You must pass a row element (which s/b associated w/ a DataRow)
            Debug.Assert(rowElem.Row != null);

            if (rowElem.ElementState == ElementState.Defoliated)
            {
                return(true);
            }

            DataTable            table   = GetTableSchemaForElement(rowElem);
            DataColumnCollection columns = table.Columns;
            int iColumn = 0;

            // check column attributes...
            int cAttrs = rowElem.Attributes.Count;

            for (int iAttr = 0; iAttr < cAttrs; iAttr++)
            {
                XmlAttribute attr = rowElem.Attributes[iAttr];

                // only specified attributes are radical
                if (!attr.Specified)
                {
                    return(false);
                }

                // only mapped attrs are valid
                DataColumn schema = GetColumnSchemaForNode(rowElem, attr);
                if (schema == null)
                {
                    //Console.WriteLine("Region has unmapped attribute");
                    return(false);
                }

                // check to see if column is in order
                if (!IsNextColumn(columns, ref iColumn, schema))
                {
                    //Console.WriteLine("Region has attribute columns out of order or duplicate");
                    return(false);
                }

                // must have exactly one text node (XmlNodeType.Text) child
                //
                XmlNode fc = attr.FirstChild;
                if (fc == null || fc.NodeType != XmlNodeType.Text || fc.NextSibling != null)
                {
                    //Console.WriteLine("column element has other than a single child text node");
                    return(false);
                }
            }

            // check column elements
            iColumn = 0;
            XmlNode n = rowElem.FirstChild;

            for ( ; n != null; n = n.NextSibling)
            {
                // only elements can exist in radically structured data
                if (n.NodeType != XmlNodeType.Element)
                {
                    //Console.WriteLine("Region has non-element child");
                    return(false);
                }
                XmlElement e = n as XmlElement;

                // only checking for column mappings in this loop
                if (GetRowFromElement(e) != null)
                {
                    break;
                }

                // element's must have schema to be radically structured
                DataColumn schema = GetColumnSchemaForNode(rowElem, e);
                if (schema == null)
                {
                    //Console.WriteLine("Region has unmapped child element");
                    return(false);
                }

                // check to see if column is in order
                if (!IsNextColumn(columns, ref iColumn, schema))
                {
                    //Console.WriteLine("Region has element columns out of order or duplicate");
                    return(false);
                }

                // must have no attributes
                if (e.HasAttributes)
                {
                    return(false);
                }

                // must have exactly one text node child
                XmlNode fc = e.FirstChild;
                if (fc == null || fc.NodeType != XmlNodeType.Text || fc.NextSibling != null)
                {
                    //Console.WriteLine("column element has other than a single child text node");
                    return(false);
                }
            }

            // check for remaining sub-regions
            for (; n != null; n = n.NextSibling)
            {
                // only elements can exist in radically structured data
                if (n.NodeType != XmlNodeType.Element)
                {
                    //Console.WriteLine("Region has non-element child");
                    return(false);
                }

                // element's must be regions in order to be radially structured
                DataRow row = GetRowFromElement((XmlElement)n);
                if (row == null)
                {
                    //Console.WriteLine("Region has unmapped element");
                    return(false);
                }
            }

            return(true);
        }
示例#42
0
        private void DefoliateRegion(XmlBoundElement rowElem)
        {
            // You must pass a row element (which s/b associated w/ a DataRow)
            Debug.Assert(rowElem.Row != null);

            if (!_optimizeStorage)
                return;

            if (rowElem.ElementState != ElementState.WeakFoliation)
                return;

            if (!_mapper.IsRegionRadical(rowElem))
            {
                return;
            }

            bool saveIgnore = IgnoreXmlEvents;
            IgnoreXmlEvents = true;

            rowElem.ElementState = ElementState.Defoliating;

            try
            {
                // drop all attributes
                rowElem.RemoveAllAttributes();

                XmlNode node = rowElem.FirstChild;
                while (node != null)
                {
                    XmlNode next = node.NextSibling;

                    XmlBoundElement be = node as XmlBoundElement;
                    if (be != null && be.Row != null)
                        break;

                    // The node must be mapped to a column (since the region is radically structured)
                    Debug.Assert(_mapper.GetColumnSchemaForNode(rowElem, node) != null);
                    rowElem.RemoveChild(node);

                    node = next;
                }
#if DEBUG
                // All subsequent siblings must be sub-regions
                for (; node != null; node = node.NextSibling)
                {
                    Debug.Assert((node is XmlBoundElement) && (((XmlBoundElement)node).Row != null));
                }
#endif

                rowElem.ElementState = ElementState.Defoliated;
            }
            finally
            {
                IgnoreXmlEvents = saveIgnore;
            }
        }
示例#43
0
 internal RegionIterator(XmlBoundElement rowElement) : base(((XmlDataDocument)(rowElement.OwnerDocument)).Mapper)
 {
     Debug.Assert(rowElement != null && rowElement.Row != null);
     _rowElement = rowElement;
     _currentNode = rowElement;
 }
示例#44
0
        private XmlElement EnsureDocumentElement()
        {
            XmlElement docelem = DocumentElement;
            if (docelem == null)
            {
                string docElemName = XmlConvert.EncodeLocalName(DataSet.DataSetName);
                if (docElemName == null || docElemName.Length == 0)
                    docElemName = "Xml";
                string ns = DataSet.Namespace;
                if (ns == null)
                    ns = string.Empty;
                docelem = new XmlBoundElement(string.Empty, docElemName, ns, this);
                AppendChild(docelem);
            }

            return docelem;
        }
示例#45
0
 internal RegionIterator(XmlBoundElement rowElement) : base(((XmlDataDocument)(rowElement.OwnerDocument)).Mapper)
 {
     Debug.Assert(rowElement != null && rowElement.Row != null);
     _rowElement  = rowElement;
     _currentNode = rowElement;
 }
示例#46
0
        // This function accepts node params that are not row-elements. In this case, calling this function is a no-op
        internal void Foliate(XmlBoundElement node, ElementState newState)
        {
            Debug.Assert(newState == ElementState.WeakFoliation || newState == ElementState.StrongFoliation);
#if DEBUG
            // If we want to strong foliate one of the non-row-elem in a region, then the region MUST be strong-foliated (or there must be no region)
            // Do this only when we are not loading
            if (IsFoliationEnabled)
            {
                if (newState == ElementState.StrongFoliation && node.Row == null)
                {
                    XmlBoundElement rowElem;
                    ElementState rowElemState = ElementState.None;
                    if (_mapper.GetRegion(node, out rowElem))
                    {
                        rowElemState = rowElem.ElementState;
                        Debug.Assert(rowElemState == ElementState.StrongFoliation || rowElemState == ElementState.WeakFoliation);
                    }
                    // Add a no-op, so we can still debug in the assert fails

#pragma warning disable 1717 // assignment to self
                    rowElemState = rowElemState;
#pragma warning restore 1717
                }
            }
#endif

            if (IsFoliationEnabled)
            {
                if (node.ElementState == ElementState.Defoliated)
                {
                    ForceFoliation(node, newState);
                }
                else if (node.ElementState == ElementState.WeakFoliation && newState == ElementState.StrongFoliation)
                {
                    // Node must be a row-elem
                    Debug.Assert(node.Row != null);
                    node.ElementState = newState;
                }
            }
        }
示例#47
0
        internal DataTable GetTableSchemaForElement( XmlBoundElement be ) {
            // if bound to a row, must be a table.
            DataRow row = be.Row;
            if ( row != null )
                return row.Table;

            return null;
        }
示例#48
0
 private void EnsureFoliation(XmlBoundElement rowElem, ElementState foliation)
 {
     if (rowElem.IsFoliated) //perf reason, avoid unecessary lock.
         return;
     ForceFoliation(rowElem, foliation);
 }
示例#49
0
        // Get the row-elem associatd w/ the region node is in.
        // If node is in a region not mapped (like document element node) the function returns false and sets elem to null)
        // This function does not work if the region is not associated w/ a DataRow (it uses DataRow association to know what is the row element associated w/ the region)
        internal bool GetRegion( XmlNode node, out XmlBoundElement rowElem ) {
            while ( node != null ) {
                XmlBoundElement be = node as XmlBoundElement;
                // Break if found a region
                if ( be != null && GetRowFromElement( be ) != null ) {
                    rowElem = be;
                    return true;
                }

                if ( node.NodeType == XmlNodeType.Attribute )
                    node = ((XmlAttribute)node).OwnerElement;
                else
                    node = node.ParentNode;
            }

            rowElem = null;
            return false;
        }
示例#50
0
        private void ForceFoliation(XmlBoundElement node, ElementState newState)
        {
            lock (_foliationLock)
            {
                if (node.ElementState != ElementState.Defoliated)
                    // The region was foliated by an other thread while this thread was locked
                    return;

                // Node must be a row-elem associated w/ a non-deleted row
                Debug.Assert(node.Row != null);
                Debug.Assert(node.Row.RowState != DataRowState.Deleted);

                node.ElementState = ElementState.Foliating;

                bool saveIgnore = IgnoreXmlEvents;
                IgnoreXmlEvents = true;

                try
                {
                    XmlNode priorNode = null;
                    DataRow row = node.Row;

                    // create new attrs & elements for row
                    // For detached rows: we are in sync w/ temp values
                    // For non-detached rows: we are in sync w/ the current values
                    // For deleted rows: we never sync
                    DataRowVersion rowVersion = (row.RowState == DataRowState.Detached) ? DataRowVersion.Proposed : DataRowVersion.Current;
                    foreach (DataColumn col in row.Table.Columns)
                    {
                        if (!IsNotMapped(col))
                        {
                            object value = row[col, rowVersion];

                            if (!Convert.IsDBNull(value))
                            {
                                if (col.ColumnMapping == MappingType.Attribute)
                                {
                                    node.SetAttribute(col.EncodedColumnName, col.Namespace, col.ConvertObjectToXml(value));
                                }
                                else
                                {
                                    XmlNode newNode = null;
                                    if (col.ColumnMapping == MappingType.Element)
                                    {
                                        newNode = new XmlBoundElement(string.Empty, col.EncodedColumnName, col.Namespace, this);
                                        newNode.AppendChild(CreateTextNode(col.ConvertObjectToXml(value)));
                                        if (priorNode != null)
                                        {
                                            node.InsertAfter(newNode, priorNode);
                                        }
                                        else if (node.FirstChild != null)
                                        {
                                            node.InsertBefore(newNode, node.FirstChild);
                                        }
                                        else
                                        {
                                            node.AppendChild(newNode);
                                        }
                                        priorNode = newNode;
                                    }
                                    else
                                    {
                                        Debug.Assert(col.ColumnMapping == MappingType.SimpleContent);
                                        newNode = CreateTextNode(col.ConvertObjectToXml(value));
                                        if (node.FirstChild != null)
                                            node.InsertBefore(newNode, node.FirstChild);
                                        else
                                            node.AppendChild(newNode);
                                        if (priorNode == null)
                                            priorNode = newNode;
                                    }
                                }
                            }
                            else
                            {
                                if (col.ColumnMapping == MappingType.SimpleContent)
                                {
                                    XmlAttribute attr = CreateAttribute(XSI, Keywords.XSI_NIL, Keywords.XSINS);
                                    attr.Value = Keywords.TRUE;
                                    node.SetAttributeNode(attr);
                                    _bHasXSINIL = true;
                                }
                            }
                        }
                    }
                }
                finally
                {
                    IgnoreXmlEvents = saveIgnore;
                    node.ElementState = newState;
                }
                // update all live pointers
                OnFoliated(node);
            }
        }
示例#51
0
        //Determine best radical insert position for inserting column elements
        private XmlNode GetColumnInsertAfterLocation(DataRow row, DataColumn col, XmlBoundElement rowElement)
        {
            XmlNode prev = null;
            XmlNode node = null;

            // text only columns appear first
            if (IsTextOnly(col))
                return null;

            // insert location must be after free text
            for (node = rowElement.FirstChild; node != null; prev = node, node = node.NextSibling)
            {
                if (!IsTextLikeNode(node))
                    break;
            }

            for (; node != null; prev = node, node = node.NextSibling)
            {
                // insert location must be before any non-element nodes
                if (node.NodeType != XmlNodeType.Element)
                    break;
                XmlElement e = node as XmlElement;

                // insert location must be before any non-mapped elements or separate regions
                if (_mapper.GetRowFromElement(e) != null)
                    break;

                object schema = _mapper.GetColumnSchemaForNode(rowElement, node);
                if (schema == null || !(schema is DataColumn))
                    break;

                // insert location must be before any columns logically after this column
                if (((DataColumn)schema).Ordinal > col.Ordinal)
                    break;
            }

            return prev;
        }
        // Returns true if the current node is on a row element (head of a region)
        internal bool OnRowElement()
        {
            XmlBoundElement be = CurrentNode as XmlBoundElement;

            return((be != null) && (be.Row != null));
        }