kitchensync

xmldiffalgo.cpp
00001 /*
00002     This file is part of KitchenSync.
00003 
00004     Copyright (c) 2006 Daniel Gollub <dgollub@suse.de> 
00005 
00006     This program is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "xmldiffalgo.h"
00023 
00024 #include <kdebug.h>
00025 
00026 using namespace KSync;
00027 
00028 #ifndef KDE_USE_FINAL
00029 // With --enable-final, we get the (identical) compareString from
00030 // addresseediffalgo.cpp
00031 //
00032 static bool compareString( const TQString &left, const TQString &right )
00033 {
00034   if ( left.isEmpty() && right.isEmpty() )
00035     return true;
00036   else
00037     return left == right;
00038 }
00039 #endif
00040 
00041 XmlDiffAlgo::XmlDiffAlgo( const TQString &leftXml, const TQString &rightXml )
00042 {
00043   kdDebug() << __func__ << " " << __LINE__ << endl;
00044 
00045   mLeftXml.setContent( leftXml );
00046   mRightXml.setContent( rightXml );
00047 
00048 }
00049 
00050 XmlDiffAlgo::XmlDiffAlgo( const TQDomDocument &leftXml, const TQDomDocument &rightXml )
00051   : mLeftXml( leftXml ), mRightXml( rightXml )
00052 {
00053   kdDebug() << __func__ << " " << __LINE__ << endl;
00054 }
00055 
00056 void XmlDiffAlgo::appendSingleNodes(TQDomElement &element, bool isLeft)
00057 {
00058   TQDomNode node;
00059 
00060   for ( node = element.firstChild(); !node.isNull(); node = node.nextSibling() ) {
00061     TQDomElement child = node.toElement();
00062 
00063     if (isLeft)
00064       additionalLeftField( node.nodeName(), child.text() );
00065     else
00066       additionalRightField( node.nodeName(), child.text() );
00067   }
00068 
00069 }
00070 
00071 void XmlDiffAlgo::appendConflictNodes(TQDomElement &leftElement, TQDomElement &rightElement)
00072 {
00073   TQDomNode left, right;
00074   TQDomElement leftChild, rightChild;
00075 
00076   for ( left = leftElement.firstChild(); !left.isNull(); left = left.nextSibling() ) {
00077     leftChild = left.toElement();
00078 
00079     for ( right = rightElement.firstChild(); !right.isNull(); right = right.nextSibling() ) {
00080       rightChild = right.toElement();
00081 
00082       if ( leftChild.tagName() != rightChild.tagName() )
00083         continue;
00084 
00085       if (leftChild.text().isEmpty() || rightChild.text().isEmpty())
00086         continue;
00087 
00088       TQString id = leftChild.tagName();
00089       if (id == "Content")
00090         id = left.parentNode().nodeName();
00091 
00092       conflictField( id, leftChild.text(), rightChild.text() );
00093 
00094       left.parentNode().removeChild( left );
00095       left = leftElement.firstChild();
00096 
00097       right.parentNode().removeChild( right );
00098       right = rightElement.firstChild();
00099 
00100     }
00101   }
00102 }
00103 
00104 void XmlDiffAlgo::compareNode(TQDomElement &leftElement, TQDomElement &rightElement)
00105 {
00106   TQDomNode left, right;
00107   TQDomElement leftChild, rightChild;
00108   TQDomNodeList nlist;
00109 top:;
00110 
00111   for ( left = leftElement.firstChild(); !left.isNull(); left = left.nextSibling() ) {
00112     leftChild = left.toElement();
00113 
00114     for ( right = rightElement.firstChild(); !right.isNull(); right = right.nextSibling() ) {
00115       rightChild = right.toElement();
00116 
00117       if (leftChild.tagName() != rightChild.tagName())
00118         continue;
00119 
00120       if ( left.childNodes().count() > 1 && right.childNodes().count() > 1 ) {
00121         compareNode( leftChild, rightChild );
00122 
00123         if ( !left.hasChildNodes() && !right.hasChildNodes() ) {
00124           left.parentNode().removeChild( left );
00125           right.parentNode().removeChild( right );
00126           goto top;
00127         }
00128 
00129         break;
00130       }
00131 
00132       if ( leftChild.text() == rightChild.text() ) {
00133         TQString id = leftChild.tagName();
00134 
00135         if ( id == "Content" )
00136           id = left.parentNode().nodeName(); 
00137  
00138     if ( id != "Type" )
00139           //matchingField( id, leftChild.text(), rightChild.text() );
00140 
00141         left.parentNode().removeChild( left );
00142         right.parentNode().removeChild( right );
00143         goto top;
00144       }
00145     }
00146   }
00147 
00148   appendConflictNodes(rightElement, leftElement);
00149 
00150   appendSingleNodes(rightElement, false);
00151   appendSingleNodes(leftElement, true);
00152 }
00153 
00154 void XmlDiffAlgo::run()
00155 {
00156   kdDebug() << __func__ << endl;    
00157   begin();
00158 
00159   TQDomElement leftElement = mLeftXml.documentElement();
00160   TQDomElement rightElement = mRightXml.documentElement();
00161 
00162   compareNode( leftElement, rightElement );
00163 
00164   end();
00165 }
00166