1 package org.catacomb.druid.util.tree;
2
3
4 import org.catacomb.interlish.structure.Related;
5 import org.catacomb.interlish.structure.Relationship;
6
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.HashSet;
10
11
12
13
14 public class RelationNode extends ArrayListNode {
15
16
17 public Related peer;
18
19
20 String[] types;
21 RelationNode[] targets;
22
23
24 HashMap<Related, RelationNode> childPeerHM;
25 HashMap<String, RelationNode> parentHM;
26
27
28 public RelationNode(Object parent, Related pr) {
29 super(parent, "anon");
30 peer = pr;
31 }
32
33
34 public Related getPeer() {
35 return peer;
36 }
37
38 public boolean samePeer(RelationNode rn) {
39 return (peer == rn.peer);
40 }
41
42
43
44 public void clearChildren() {
45 if (childPeerHM != null) {
46 childPeerHM.clear();
47 }
48 super.clearChildren();
49 }
50
51
52
53 public RelationNode makeChildlessCopy() {
54 RelationNode rn = new RelationNode(null, peer);
55 return rn;
56 }
57
58
59
60 public void addChild(ArrayListNode aln) {
61 super.addChild(aln);
62 if (aln instanceof RelationNode) {
63 RelationNode rn = (RelationNode)aln;
64 if (childPeerHM == null) {
65 childPeerHM = new HashMap<Related, RelationNode>();
66 }
67 childPeerHM.put(rn.getPeer(), rn);
68 }
69 }
70
71
72 public void removeChild(RelationNode rn) {
73 super.removeChild(rn);
74 childPeerHM.remove(rn.getPeer());
75 }
76
77
78
79 public RelationNode getPeerEquivalentChild(RelationNode rn) {
80 RelationNode ret = null;
81 Related tgtpeer = rn.getPeer();
82 if (childPeerHM != null && childPeerHM.containsKey(tgtpeer)) {
83 ret = childPeerHM.get(tgtpeer);
84 }
85 return ret;
86 }
87
88
89
90 public void resolve(HashMap<Related, RelationNode> peers, HashSet<String> relationTypes) {
91 Relationship[] rs = peer.getRelationships();
92
93 parentHM = new HashMap<String, RelationNode>();
94
95 int nrel = 0;
96 if (rs != null) {
97 nrel = rs.length;
98 }
99
100 types = new String[nrel];
101 targets = new RelationNode[nrel];
102
103 for (int i = 0; i < nrel; i++) {
104 String rel = rs[i].getType();
105 types[i] = rel;
106 Related tgt = rs[i].getTarget();
107 RelationNode rnode = peers.get(tgt);
108 targets[i] = rnode;
109
110
111 if (parentHM.containsKey(rel)) {
112
113 } else {
114 parentHM.put(rel, rnode);
115 }
116
117 if (relationTypes.contains(rel)) {
118
119 } else {
120 relationTypes.add(rel);
121 }
122
123 }
124
125 }
126
127
128
129 public String toString() {
130 return peer.toString();
131 }
132
133
134
135 public boolean fileAway(String rtyp) {
136 boolean bfiled = false;
137
138 for (int i = 0; i < types.length; i++) {
139 if (types[i].equals(rtyp)) {
140 targets[i].addChild(this);
141 bfiled = true;
142 }
143 }
144 return bfiled;
145 }
146
147
148
149
150 public RelationNode getParent(String rel) {
151 RelationNode ret = null;
152 if (parentHM.containsKey(rel)) {
153 ret = parentHM.get(rel);
154 }
155 parent = ret;
156 return ret;
157 }
158
159
160
161
162
163
164
165
166
167
168
169
170 public void subtreeify(RelationNode parentRN, ArrayList rest, String rel) {
171
172
173 System.out.println("XXX subtreeifying " + parentRN + " " + rel);
174
175
176
177 if (parentRN != null && parentHM.containsKey(rel)) {
178
179
180 System.out.println("YYY moving down " + rel + " " + this);
181
182 parentRN.removeChild(this);
183 RelationNode target = parentHM.get(rel);
184 insertUnder(parentRN, target, rest, rel);
185
186 } else {
187
188 RelationNode[] ach;
189 ach = (children.toArray(new RelationNode[0]));
190 for (int i = 0; i < ach.length; i++) {
191 ach[i].subtreeify(this, rest, rel);
192 }
193 }
194 }
195
196
197
198 private void insertUnder(RelationNode parentRN, RelationNode bot,
199 ArrayList rest, String rel) {
200 int nup = 0;
201 RelationNode[] path = new RelationNode[6];
202 path[nup++] = bot;
203 RelationNode current = bot;
204 RelationNode next;
205
206 while ((next = current.getParent(rel)) != null) {
207 path[nup++] = next;
208 current = next;
209 }
210
211
212 RelationNode branch = parentRN;
213 int id = nup-1;
214 while (id > 0) {
215 RelationNode req = branch.getPeerEquivalentChild(path[id]);
216 if (req == null) {
217 break;
218
219 } else {
220 branch = req;
221 id = id - 1;
222 }
223 }
224
225
226
227 for (int i = id; i >= 0; i--) {
228 RelationNode dtr = path[i].makeChildlessCopy();
229 branch.addChild(dtr);
230 branch = dtr;
231 rest.remove(path[i]);
232 }
233
234 branch.addChild(this);
235 }
236
237
238 }