/
RefTreeByIdEncoder.java
72 lines (62 loc) · 2.78 KB
/
RefTreeByIdEncoder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
* Copyright 2005--2008 Helsinki Institute for Information Technology
*
* This file is a part of Fuego middleware. Fuego middleware is free software; you can redistribute
* it and/or modify it under the terms of the MIT license, included as the file MIT-LICENSE in the
* Fuego middleware source distribution. If you did not receive the MIT license with the
* distribution, write to the Fuego Core project at fuego-xmldiff-users@hoslab.cs.helsinki.fi.
*/
package fc.xml.diff.encode;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import fc.xml.diff.Segment;
import fc.xml.xas.Item;
import fc.xml.xas.Qname;
import fc.xml.xas.StartTag;
public class RefTreeByIdEncoder extends RefTreeEncoder {
private static final String UNKNOWN_ID_PREFIX = "UNKNOWN_ID+";
private static final Qname ID_ATTR = new Qname("", "id");
protected List<Item> base = null;
@Override
protected String getBaseRefTarget(int branchPos, Segment<Item> match, MultiXPath xp) {
int steps = -1, depth = 0;
int offset = branchPos - match.getPosition();
int basePos = match.getOffset() + offset;
// Log.debug("<<<Start identify scan at pos "+basePos);
// Scan backwards to a parent tag with id. At the same time, we count
// the
// position in the child list of the parent.
// NOTE: We only scan up to the parent, i.e. the tag <x> in
// <t id="i"><t><x> won't get an id. (We could use a recursive scheme
// here,
// to get something like i.0.0)
while (basePos > 0 && depth >= 0 && (depth > 0 || !Item.isStartTag(base.get(basePos)))) {
// Log.debug("Identifyscan "+base.get(basePos)+",depth="+depth+",basePos="+
// basePos+",steps="+steps);
if (Item.isEndTag(base.get(basePos))) {
depth++;
} else if (Item.isStartTag(base.get(basePos))) {
depth--;
}
steps += depth == 0 ? 1 : 0;
basePos--;
}
// Log.debug("===Item to identify is "+base.get(basePos));
String baseId = null;
if (basePos > 0 && ((StartTag) base.get(basePos)).getAttribute(ID_ATTR) != null) {
baseId = ((StartTag) base.get(basePos)).getAttribute(ID_ATTR).getValue().toString();
}
if (baseId == null) return UNKNOWN_ID_PREFIX + (branchPos - match.getPosition());
if (steps >= 0) return baseId + "." + steps;
return baseId;
}
@Override
public void encodeDiff(List<Item> base, List<Item> doc, List<Segment<Item>> matches,
List<Item> preamble, OutputStream out) throws IOException {
this.base = base;
super.encodeDiff(base, doc, matches, preamble, out);
}
}
// arch-tag: aaf67f13-25b5-4141-a404-fe2ed6f0e5c4
//