LibreOffice Module xmerge (master)  1
IteratorRowCompare.java
Go to the documentation of this file.
1 /*
2  * This file is part of the LibreOffice project.
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * This file incorporates work covered by the following license notice:
9  *
10  * Licensed to the Apache Software Foundation (ASF) under one or more
11  * contributor license agreements. See the NOTICE file distributed
12  * with this work for additional information regarding copyright
13  * ownership. The ASF licenses this file to you under the Apache
14  * License, Version 2.0 (the "License"); you may not use this file
15  * except in compliance with the License. You may obtain a copy of
16  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
17  */
18 
19 package org.openoffice.xmerge.merger.diff;
20 
21 import org.w3c.dom.Node;
22 import org.w3c.dom.Element;
23 
24 import java.util.ArrayList;
29 
61 public class IteratorRowCompare implements DiffAlgorithm {
62 
77  public Difference[] computeDiffs(Iterator orgSeq, Iterator modSeq) {
78 
79  ArrayList<Difference> diffVector = new ArrayList<Difference>();
80 
81  // i and j are counters to keep track the current position in the
82  // iterator
83  int i = 0;
84  int j = 0;
85  Object orgSeqObject = orgSeq.start();
86  Object modSeqObject = modSeq.start();
87  Element orgRow, modRow;
88  boolean different = false;
89  boolean orgSplited = false;
90  boolean modSplited = false;
91 
92  while (orgSeqObject != null) {
93 
94  different = true;
95 
96  if (modSeqObject == null) {
97  // no more modsequence, all the remaining org sequence objs
98  // should consider as a delete.
99  Difference diff = new Difference(Difference.DELETE, i, j);
100  diffVector.add(diff);
101  orgSeqObject = orgSeq.next();
102 
103  } else {
104  if (!orgSeq.equivalent(orgSeqObject, modSeqObject)) {
105 
106  orgRow = (Element)orgSeqObject;
107  modRow = (Element)modSeqObject;
108 
109  // check whether the original Row with multiple row
110  // if so, need to split one out for merge
111  String orgRowRepeated = orgRow.getAttribute(
113  String modRowRepeated = modRow.getAttribute(
115 
116 
117  int orgRowNum = 1;
118  int modRowNum = 1;
119 
120  if (orgRowRepeated.length() > 0) {
121  orgRowNum = Integer.parseInt(orgRowRepeated);
122  }
123  if (modRowRepeated.length() > 0) {
124  modRowNum = Integer.parseInt(modRowRepeated);
125  }
126 
127  // try to find out the common number of repeated Rows
128  if (orgRowNum == modRowNum) {
129  orgSeqObject = orgSeq.next();
130  modSeqObject = modSeq.next();
131 
132  // cut the original row into two halves, first half
133  // have the repeated attribute = modify row attr
134  } else if (orgRowNum > modRowNum) {
135  Element orgSplitRow = splitRepeatedRow(
136  orgRow, modRowNum,
137  orgRowNum - modRowNum);
138  // it may equal after the split!
139  if (orgSeq.equivalent(orgSplitRow, modRow)) {
140  different = false;
141  }
142  orgSplited = true;
143  modSeqObject = modSeq.next();
144 
145  // cut the modified Row into two halves, first half
146  // have the repeated attribute = original Row attr
147  } else {
148  Element modSplitRow = splitRepeatedRow(
149  modRow, orgRowNum,
150  modRowNum - orgRowNum);
151 
152  // check whether rows are equal after the split
153  if (modSeq.equivalent(orgRow, modSplitRow)) {
154  different = false;
155  }
156  modSplited = true;
157  orgSeqObject = orgSeq.next();
158  }
159 
160  if (different) {
162  i, j);
163  diffVector.add(diff);
164  }
165 
166  } else {
167  // Rows are equivalent, move on to next one.
168  orgSeqObject = orgSeq.next();
169  modSeqObject = modSeq.next();
170  } // end if-else
171  j++;
172  } // end if-else
173  i++;
174  } // end while loop
175 
176  // any extra objects in modify sequence should consider as an add
177  // to the original sequence
178  for (; modSeqObject != null; modSeqObject = modSeq.next(), j++) {
179  Difference diff = new Difference(Difference.ADD, i, j);
180  diffVector.add(diff);
181  }
182 
183  // need to refresh the iterator if we split the rows
184  if (orgSplited) {
185  orgSeq.refresh();
186  }
187 
188  if (modSplited) {
189  modSeq.refresh();
190  }
191 
192  // convert the vector to array
193  Difference[] diffArray = new Difference[diffVector.size()];
194  diffVector.toArray(diffArray);
195 
196  return diffArray;
197  }
198 
199  private Element splitRepeatedRow(Element orgRow, int splitNum, int orgNum) {
200  // NOTE: should we really want to do deep clone?
201  // in most the case, it is an empty Row, but the
202  // specification didn't forbid any node to use multiple
203  // column attributes. i.e. the node can contain text
204  // nodes or other things under it.
205  Element splitRow = (Element)(orgRow.cloneNode(true));
206 
207  if (splitNum > 1) {
208  splitRow.setAttribute(
210  String.valueOf(splitNum));
211  } else if (splitNum == 1) {
212  splitRow.removeAttribute(
214  }
215  if (orgNum > 1) {
216  orgRow.setAttribute(
218  String.valueOf(orgNum));
219  } else if (orgNum == 1) {
220  orgRow.removeAttribute(
222  }
223 
224  Node parentNode = orgRow.getParentNode();
225  parentNode.insertBefore(splitRow, orgRow);
226 
227  return splitRow;
228  }
229 }
Difference[] computeDiffs(Iterator orgSeq, Iterator modSeq)
Compute the differences of the given two sequences.
boolean equivalent(Object obj1, Object obj2)
A method to allow the difference algorithm to test whether the.
static final int DELETE
Delete operation.
Definition: Difference.java:33
This interface contains constants for StarOffice XML tags, attributes (StarCalc cell types...
Element splitRepeatedRow(Element orgRow, int splitNum, int orgNum)
static final int CHANGE
Change operation.
Definition: Difference.java:36
exports com.sun.star. java
int i
String ATTRIBUTE_TABLE_NUM_ROWS_REPEATED
Attribute tag for table:number-rows-repeated of element table:table-row.
Object start()
Move to the beginning of the sequence.
Object next()
Move to next element in the sequence.
This is the difference algorithm interface.
Provides interfaces for converting between two.
Definition: Convert.java:19
static final int ADD
Add operation.
Definition: Difference.java:30
A very simple and direct difference algorithm for row.
void refresh()
A method to force the.
This is an interface used by the DiffAlgorithm and MergeAlgorithm to access a.
Definition: Iterator.java:27