kitchensync

xmldiffalgo.cpp
1 /*
2  This file is part of KitchenSync.
3 
4  Copyright (c) 2006 Daniel Gollub <dgollub@suse.de>
5 
6  This program is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "xmldiffalgo.h"
23 
24 #include <kdebug.h>
25 
26 using namespace KSync;
27 
28 #ifndef KDE_USE_FINAL
29 // With --enable-final, we get the (identical) compareString from
30 // addresseediffalgo.cpp
31 //
32 static bool compareString( const TQString &left, const TQString &right )
33 {
34  if ( left.isEmpty() && right.isEmpty() )
35  return true;
36  else
37  return left == right;
38 }
39 #endif
40 
41 XmlDiffAlgo::XmlDiffAlgo( const TQString &leftXml, const TQString &rightXml )
42 {
43  kdDebug() << __func__ << " " << __LINE__ << endl;
44 
45  mLeftXml.setContent( leftXml );
46  mRightXml.setContent( rightXml );
47 
48 }
49 
50 XmlDiffAlgo::XmlDiffAlgo( const TQDomDocument &leftXml, const TQDomDocument &rightXml )
51  : mLeftXml( leftXml ), mRightXml( rightXml )
52 {
53  kdDebug() << __func__ << " " << __LINE__ << endl;
54 }
55 
56 void XmlDiffAlgo::appendSingleNodes(TQDomElement &element, bool isLeft)
57 {
58  TQDomNode node;
59 
60  for ( node = element.firstChild(); !node.isNull(); node = node.nextSibling() ) {
61  TQDomElement child = node.toElement();
62 
63  if (isLeft)
64  additionalLeftField( node.nodeName(), child.text() );
65  else
66  additionalRightField( node.nodeName(), child.text() );
67  }
68 
69 }
70 
71 void XmlDiffAlgo::appendConflictNodes(TQDomElement &leftElement, TQDomElement &rightElement)
72 {
73  TQDomNode left, right;
74  TQDomElement leftChild, rightChild;
75 
76  for ( left = leftElement.firstChild(); !left.isNull(); left = left.nextSibling() ) {
77  leftChild = left.toElement();
78 
79  for ( right = rightElement.firstChild(); !right.isNull(); right = right.nextSibling() ) {
80  rightChild = right.toElement();
81 
82  if ( leftChild.tagName() != rightChild.tagName() )
83  continue;
84 
85  if (leftChild.text().isEmpty() || rightChild.text().isEmpty())
86  continue;
87 
88  TQString id = leftChild.tagName();
89  if (id == "Content")
90  id = left.parentNode().nodeName();
91 
92  conflictField( id, leftChild.text(), rightChild.text() );
93 
94  left.parentNode().removeChild( left );
95  left = leftElement.firstChild();
96 
97  right.parentNode().removeChild( right );
98  right = rightElement.firstChild();
99 
100  }
101  }
102 }
103 
104 void XmlDiffAlgo::compareNode(TQDomElement &leftElement, TQDomElement &rightElement)
105 {
106  TQDomNode left, right;
107  TQDomElement leftChild, rightChild;
108  TQDomNodeList nlist;
109 top:;
110 
111  for ( left = leftElement.firstChild(); !left.isNull(); left = left.nextSibling() ) {
112  leftChild = left.toElement();
113 
114  for ( right = rightElement.firstChild(); !right.isNull(); right = right.nextSibling() ) {
115  rightChild = right.toElement();
116 
117  if (leftChild.tagName() != rightChild.tagName())
118  continue;
119 
120  if ( left.childNodes().count() > 1 && right.childNodes().count() > 1 ) {
121  compareNode( leftChild, rightChild );
122 
123  if ( !left.hasChildNodes() && !right.hasChildNodes() ) {
124  left.parentNode().removeChild( left );
125  right.parentNode().removeChild( right );
126  goto top;
127  }
128 
129  break;
130  }
131 
132  if ( leftChild.text() == rightChild.text() ) {
133  TQString id = leftChild.tagName();
134 
135  if ( id == "Content" )
136  id = left.parentNode().nodeName();
137 
138  if ( id != "Type" )
139  //matchingField( id, leftChild.text(), rightChild.text() );
140 
141  left.parentNode().removeChild( left );
142  right.parentNode().removeChild( right );
143  goto top;
144  }
145  }
146  }
147 
148  appendConflictNodes(rightElement, leftElement);
149 
150  appendSingleNodes(rightElement, false);
151  appendSingleNodes(leftElement, true);
152 }
153 
154 void XmlDiffAlgo::run()
155 {
156  kdDebug() << __func__ << endl;
157  begin();
158 
159  TQDomElement leftElement = mLeftXml.documentElement();
160  TQDomElement rightElement = mRightXml.documentElement();
161 
162  compareNode( leftElement, rightElement );
163 
164  end();
165 }
166