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