PageRenderTime 35ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/code/DyadTMap.java

http://silkin.googlecode.com/
Java | 379 lines | 305 code | 30 blank | 44 comment | 96 complexity | 9f0ed26f7218ee3f64c392081883c138 MD5 | raw file
  1. import java.util.*;
  2. import java.io.*;
  3. /** A <code>DyadTMap</code> contains a normal TreeMap and has 1 convenience method, <code>dyAdd</code>, which type-checks
  4. items added to the TreeMap (only {@link Dyad}s allowed) and stores them indexed by kin term & PCString.
  5. *
  6. * The DyadTMap itself is a 2-level TMap: kinTerm -> pcString -> AList of Dyads
  7. * It is where we store all the Dyads gathered for an entire context (language).
  8. * So all dyads for 'uncle' are stored under the index term 'uncle.'
  9. * Within the group of 'uncle' dyads, we further index them on kinType
  10. * (specifically on pcString). So all the 'uncle' dyads are indexed under
  11. * 'FaBro' or 'MoBro'. Etc.
  12. @author Gary Morris, Northern Virginia Community College garymorris2245@verizon.net
  13. */
  14. public class DyadTMap extends TreeMap implements Serializable {
  15. /** The total number of dyads in this TreeMap. */
  16. public int total = 0;
  17. // public DyadTMap() { }
  18. //
  19. // public DyadTMap(DyadTMap model) {
  20. // return model.clone();
  21. // }
  22. public int total() {
  23. return DT_Abstract1.countLeaves(this);
  24. }
  25. /** Add this Dyad to the TreeMap.
  26. @param item the Dyad to be added. */
  27. public void dyAdd(Dyad item) {
  28. if (item.kinTerm.equals("Ego")) {
  29. return; // 'Ego' is not a kin term -- it just marks ego
  30. }
  31. if (get(item.kinTerm) == null) {
  32. put(item.kinTerm, new TreeMap());
  33. }
  34. TreeMap termTM = (TreeMap) get(item.kinTerm);
  35. if (termTM.get(item.pcString) == null) {
  36. termTM.put(item.pcString, new ArrayList<Object>());
  37. }
  38. ArrayList<Object> dyList = (ArrayList<Object>)termTM.get(item.pcString);
  39. if (nonDuplicate(item, dyList)) dyList.add(item);
  40. } // end of method dyAdd
  41. static boolean nonDuplicate(Dyad item, ArrayList<Object> dyList) {
  42. for (Object o : dyList) {
  43. Dyad dy = (Dyad)o;
  44. if (dy.ego == item.ego && dy.alter == item.alter) {
  45. return false;
  46. }
  47. }
  48. return true;
  49. }
  50. /** If this dyad is already present, replace with this one.
  51. * Otherwise, add this dyad to the DyadTMap.
  52. @param item the Dyad to be inserted. */
  53. public void dyAddOrUpdate(Dyad item) {
  54. if (item.kinTerm.equals("Ego")) {
  55. return; // 'Ego' is not a kin term -- it just marks ego
  56. }
  57. if (get(item.kinTerm) == null) {
  58. put(item.kinTerm, new TreeMap());
  59. }
  60. TreeMap termTM = (TreeMap) get(item.kinTerm);
  61. if (termTM.get(item.pcString) == null) {
  62. termTM.put(item.pcString, new ArrayList<Object>());
  63. }
  64. ArrayList<Object> dyadList = (ArrayList<Object>)termTM.get(item.pcString);
  65. int ndx = findExistingDyad(dyadList, item);
  66. if (ndx == -1) {
  67. dyadList.add(item);
  68. }
  69. else dyadList.set(ndx, item);
  70. } // end of method dyAddOrUpdate
  71. public ArrayList<Dyad> findDyadList(Dyad dy) {
  72. TreeMap subTree = (TreeMap)get(dy.kinTerm);
  73. ArrayList<Dyad> dyList = new ArrayList<Dyad>();
  74. if (subTree == null) {
  75. return dyList;
  76. }
  77. ArrayList<Object> list = (ArrayList<Object>)subTree.get(dy.pcString);
  78. if (list == null) {
  79. return dyList;
  80. }
  81. for (Object o : list) {
  82. dyList.add((Dyad)o);
  83. }
  84. return dyList;
  85. }
  86. int findExistingDyad(ArrayList<Object> dyadList, Dyad item) {
  87. for (int ndx = 0; ndx < dyadList.size(); ndx++) {
  88. Dyad cand = (Dyad)dyadList.get(ndx);
  89. if (cand.ego.serialNmbr == item.ego.serialNmbr &&
  90. cand.alter.serialNmbr == item.alter.serialNmbr &&
  91. cand.kinTerm.equals(item.kinTerm)) {
  92. return ndx;
  93. }
  94. }
  95. return -1;
  96. }
  97. /** A special remove method that overrides <code>TreeMap</code>'s method; it adjusts <code>total</code>.
  98. @param key the key for the sub-tree to be removed. */
  99. public Object remove(String key) {
  100. TreeMap subTree = (TreeMap) super.remove(key);
  101. return subTree;
  102. } // end of overriding method remove
  103. /** A special put method that overrides <code>TreeMap</code>'s method; it adjusts <code>total</code>.
  104. If there is a prior sub-tree associated with <code>key</code>, it is replaced with the new one.
  105. The number of dyads in the prior sub-tree is subtracted from <code>total</code> before the
  106. number in the new one is added.
  107. @param key the key for the sub-tree to be put into this TreeMap.
  108. @param subTree the sub-tree to be inserted. */
  109. public Object put(String key, TreeMap subTree) {
  110. Object oldVal = super.put(key, subTree);
  111. return oldVal;
  112. } // end of overriding method put
  113. void removeDyad(String kinTerm, String pcString, Individual ego,
  114. Individual alter, DomainTheory dt) {
  115. TreeMap termTM = (TreeMap) get(kinTerm);
  116. if (termTM == null && dt.synonyms != null && dt.synonyms.get(kinTerm) != null) {
  117. // If it's a synonym, all dyads may have already been moved to base term
  118. String synTerm = (String) dt.synonyms.get(kinTerm);
  119. termTM = (TreeMap) get(synTerm);
  120. }
  121. if (termTM == null) {
  122. return;
  123. }
  124. ArrayList<Object> dyList = (ArrayList<Object>) termTM.get(pcString);
  125. if (dyList == null) {
  126. return;
  127. }
  128. Iterator dyIter = dyList.iterator();
  129. while (dyIter.hasNext()) {
  130. Dyad dy = (Dyad)dyIter.next();
  131. if (dy.ego == ego && dy.alter == alter) {
  132. dyIter.remove();
  133. break;
  134. }
  135. }
  136. if (dyList.isEmpty()) {
  137. termTM.remove(pcString);
  138. }
  139. if (termTM.isEmpty()) {
  140. remove(kinTerm);
  141. }
  142. } // end of method removeDyad
  143. boolean removeDyad(Dyad dy, DomainTheory lrnDT) {
  144. TreeMap termTM = (TreeMap) get(dy.kinTerm);
  145. if (termTM == null && lrnDT.synonyms != null && lrnDT.synonyms.get(dy.kinTerm) != null) {
  146. // If it's a synonym, all dyads may have already been moved to base term
  147. String synTerm = (String) lrnDT.synonyms.get(dy.kinTerm);
  148. termTM = (TreeMap) get(synTerm);
  149. }
  150. if (termTM == null) {
  151. return false;
  152. }
  153. ArrayList<Object> dyList = (ArrayList<Object>) termTM.get(dy.pcString);
  154. if (dyList == null) {
  155. return false;
  156. }
  157. int where = dyList.indexOf(dy);
  158. if (where == -1) {
  159. return false;
  160. }
  161. dyList.remove(where);
  162. if (dyList.isEmpty()) {
  163. termTM.remove(dy.pcString);
  164. }
  165. System.out.println("\t\t*********** Removed a bad Dyad: " + dy);
  166. return true;
  167. } // end of method removeDyad
  168. public void removeDyad(DomainTheory dt, int egoInt, int alterInt, String term, String pcString) {
  169. TreeMap termTM = (TreeMap) get(term);
  170. if (termTM == null && dt.synonyms != null && dt.synonyms.get(term) != null) {
  171. // If it's a synonym, all dyads may have already been moved to base term
  172. String synTerm = (String) dt.synonyms.get(term);
  173. termTM = (TreeMap) get(synTerm);
  174. }
  175. if (termTM == null) {
  176. return;
  177. }
  178. ArrayList<Object> dyList = (ArrayList<Object>) termTM.get(pcString);
  179. if (dyList == null) {
  180. return;
  181. }
  182. Individual ego = Context.current.individualCensus.get(egoInt),
  183. alter = Context.current.individualCensus.get(alterInt);
  184. Dyad target = null;
  185. for (Object o : dyList) {
  186. Dyad dy = (Dyad)o;
  187. if (dy.ego == ego && dy.alter == alter) {
  188. target = dy;
  189. break;
  190. }
  191. }
  192. if (target != null) {
  193. dyList.remove(target);
  194. }
  195. }
  196. /** Integrate all the dyads in <code>otherMap</code> into this one.
  197. @param otherMap the DyadTMap to be assimilated. */
  198. public void assimlate(DyadTMap otherMap) {
  199. Iterator termIter = otherMap.entrySet().iterator();
  200. while (termIter.hasNext()) {
  201. Map.Entry entry = (Map.Entry) termIter.next();
  202. String otherKinterm = (String) entry.getKey();
  203. TreeMap otherTerMap = (TreeMap) entry.getValue();
  204. if (!this.containsKey(otherKinterm)) {
  205. put(otherKinterm, otherTerMap);
  206. } else { // must merge the 2 entries
  207. TreeMap thisTerMap = (TreeMap) remove(otherKinterm);
  208. put(otherKinterm, DomainTheory.mergeTrees(thisTerMap, otherTerMap));
  209. }
  210. } // end of loop thru otherMap's keys
  211. } // end of method assimlate
  212. public DyadTMap convertToAdr() {
  213. DyadTMap newMap = new DyadTMap();
  214. Iterator kinTermIter = entrySet().iterator();
  215. while (kinTermIter.hasNext()) {
  216. Map.Entry entry = (Map.Entry) kinTermIter.next();
  217. String kinTerm = (String) entry.getKey();
  218. TreeMap subTree = (TreeMap) entry.getValue();
  219. TreeMap newSubTree = new TreeMap();
  220. newMap.put(kinTerm, newSubTree);
  221. Iterator kinTypeIter = subTree.entrySet().iterator();
  222. while (kinTypeIter.hasNext()) {
  223. Map.Entry subEntry = (Map.Entry) kinTypeIter.next();
  224. String kinType = (String) subEntry.getKey();
  225. ArrayList dyads = (ArrayList) subEntry.getValue();
  226. ArrayList adrDyads = new ArrayList();
  227. newSubTree.put(kinType, adrDyads);
  228. for (Object o : dyads) {
  229. Dyad dy = (Dyad) o;
  230. Dyad newDy = new Dyad(dy);
  231. newDy.addrOrRef = Dyad.ADDR;
  232. adrDyads.add(newDy);
  233. }
  234. }
  235. }
  236. return newMap;
  237. }
  238. /** This method builds a string that represents a DyadTMap in a SILKin data (_.silk) file. */
  239. public String toSILKString() {
  240. String result = "";
  241. Iterator termIter = entrySet().iterator();
  242. while (termIter.hasNext()) {
  243. Map.Entry entry = (Map.Entry) termIter.next();
  244. String kinterm = (String) entry.getKey();
  245. TreeMap kinTypeMap = (TreeMap) entry.getValue();
  246. result += "<dyadKinTerm kinTerm=\"" + kinterm + "\">\n";
  247. Iterator typIter = kinTypeMap.entrySet().iterator();
  248. while (typIter.hasNext()) {
  249. Map.Entry typEntry = (Map.Entry) typIter.next();
  250. String kinType = (String) typEntry.getKey();
  251. result += "\t<kinType type=\"" + kinType + "\">\n";
  252. ArrayList<Object> dyList = (ArrayList<Object>) typEntry.getValue();
  253. for (int d = 0; d < dyList.size(); d++) {
  254. result += ((Dyad) dyList.get(d)).toSILKString();
  255. }
  256. result += "\t</kinType>\n";
  257. } // end of loop thru kin types
  258. result += "</dyadKinTerm>\n";
  259. } // end of loop thru kin terms
  260. return result;
  261. } // end of method toSILKString
  262. /** <code>summaryString</code> builds a printable table of the contents .
  263. @return the string. */
  264. public String summaryString() throws KSInternalErrorException {
  265. String image = "", header = "";
  266. int size,
  267. totals = 0;
  268. String kinTerm, spacer = " ";
  269. if (size() > 0) {
  270. header += "\n\n* * * * * * * * * * Dyads by KinTerm & PCString * * * * * * * * * *\n";
  271. header += "KinTerm PCString Nmbr of Dyads\n";
  272. header += "=================================================================\n";
  273. Iterator iter = entrySet().iterator();
  274. while (iter.hasNext()) {
  275. Map.Entry termEntry = (Map.Entry) iter.next();
  276. kinTerm = (String) termEntry.getKey();
  277. TreeMap termTM = (TreeMap) termEntry.getValue(); // the values are TreeMaps
  278. if (termTM.isEmpty()) {
  279. iter.remove();
  280. } else {
  281. Iterator pcStrIter = termTM.entrySet().iterator();
  282. Map.Entry pcStrEntry = (Map.Entry) pcStrIter.next(); // first entry in the PCStr TMap
  283. String pcStr = (String) pcStrEntry.getKey();
  284. ArrayList<Object> dyList = (ArrayList<Object>) pcStrEntry.getValue();
  285. size = dyList.size();
  286. totals += size;
  287. image += kinTerm + space(kinTerm) + pcStr + space(pcStr) + size + " "
  288. + sexCount(dyList, "M") + "M " + sexCount(dyList, "F") + "F\n";
  289. while (pcStrIter.hasNext()) {
  290. pcStrEntry = (Map.Entry) pcStrIter.next();
  291. pcStr = (String) pcStrEntry.getKey();
  292. dyList = (ArrayList<Object>) pcStrEntry.getValue();
  293. size = dyList.size();
  294. totals += size;
  295. image += spacer + pcStr + space(pcStr) + size + " "
  296. + sexCount(dyList, "M") + "M " + sexCount(dyList, "F") + "F\n";
  297. } // end of loop thru remaining PCStrs
  298. image += "\n";
  299. }
  300. } // end of loop thru kinTerms map
  301. } // end of there is something to display
  302. return header + image + spacer + spacer + "---\n" + spacer + spacer + totals;
  303. } // end of method summaryString
  304. String space(String item) {
  305. String spacer = "";
  306. for (int i = 0; i < (28 - item.length()); i++) {
  307. spacer += " ";
  308. }
  309. return spacer;
  310. } // end of method space
  311. int sexCount(ArrayList<Object> dyList, String typ) {
  312. int count = 0;
  313. for (int i = 0; i < dyList.size(); i++) {
  314. if (((Dyad) dyList.get(i)).ego.gender.equals(typ)) {
  315. count++;
  316. }
  317. }
  318. return count;
  319. } // end of method sexCount
  320. public int nmbrOfDyads(String kTerm) {
  321. int total = 0;
  322. TreeMap termTM = (TreeMap) get(kTerm);
  323. Iterator listIter = termTM.values().iterator();
  324. while (listIter.hasNext()) {
  325. total += ((ArrayList<Object>) listIter.next()).size();
  326. }
  327. return total;
  328. } // end of method nmbrOfDyads
  329. public int avgDyadsPerPCStr(String kTerm) {
  330. // Return the avg nmbr of dyads per PC_String, rounded
  331. // to nearest int.
  332. TreeMap termTM = (TreeMap) get(kTerm);
  333. int total = 0,
  334. lists = termTM.size();
  335. if (lists == 0) {
  336. return 0;
  337. }
  338. Iterator listIter = termTM.values().iterator();
  339. while (listIter.hasNext()) {
  340. total += ((ArrayList<Object>) listIter.next()).size();
  341. }
  342. double avg = 0.5d + (total / lists);
  343. return (new Double(Math.floor(avg))).intValue();
  344. }
  345. } // end of class DyadTMap