View Javadoc

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                 // do nothing  ? POSERR;
113             } else {
114                 parentHM.put(rel, rnode);
115             }
116 
117             if (relationTypes.contains(rel)) {
118                 // nothing to do;
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     // recurse down until we find a node with a
164     // relation rel
165     // run up that relation as far as possible and insert section
166     // check for top being already a child of parent
167     // if so insert, run down and insert branch if needed
168     // ow, insert whole new section
169 
170     public void subtreeify(RelationNode parentRN, ArrayList rest, String rel) {
171 
172 
173         System.out.println("XXX subtreeifying  " + parentRN + " " + rel);
174 
175 
176         // what if multiple occurences of rel (here have just the first) POSERR
177         if (parentRN != null && parentHM.containsKey(rel)) {
178             // skips root nodes, but maybe these could also have a rel parent? POSERR
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         // maybe this path matches existing children of parent;
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         // insert the remaining segment;
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 }