PageRenderTime 34ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/code/Node.java

http://silkin.googlecode.com/
Java | 567 lines | 484 code | 37 blank | 46 comment | 212 complexity | d94ab4ad43e54b9795b9a8586311fb49 MD5 | raw file
  1. import java.util.*;
  2. import java.io.*;
  3. import java.awt.Point;
  4. public class Node implements Serializable {
  5. public static final Node self = makeSelfNode(false);
  6. public Individual indiv;
  7. public String pcString;
  8. private int treelevel;
  9. public ArrayList<Object> miniPreds = new ArrayList<Object>();
  10. public ArrayList<Object> kinTermsRef = new ArrayList<Object>(),
  11. extKinTermsRef = new ArrayList<Object>(),
  12. kinTermsAddr = new ArrayList<Object>(),
  13. extKinTermsAddr = new ArrayList<Object>();
  14. public String ktSuffix = "";
  15. public int appearances = 1;
  16. public Node() { }
  17. public Node(Dyad d, Context ctxt) throws KSInternalErrorException {
  18. indiv = d.alter;
  19. pcString = d.pcString;
  20. if (d.addrOrRef == 0) { // terms of reference
  21. if (d.kinTermType == 0) {
  22. kinTermsRef.add(d.kinTermType);
  23. }else {
  24. extKinTermsRef.add(d.kinTermType);
  25. }
  26. }else { // must be term of address
  27. if (d.kinTermType == 0) {
  28. kinTermsAddr.add(d.kinTermType);
  29. }else {
  30. extKinTermsAddr.add(d.kinTermType);
  31. }
  32. }
  33. treelevel = d.level;
  34. miniPreds = makeMiniPreds(d, ctxt);
  35. }
  36. public ArrayList<Object> makeMiniPreds(Dyad dy, Context ctxt)
  37. throws KSInternalErrorException {
  38. ArrayList<Object> minis = new ArrayList<Object> ();
  39. ArrayList<Individual> path = new ArrayList<Individual>();
  40. Individual prior = dy.ego;
  41. for (Object o : dy.path) {
  42. if (o instanceof Individual) {
  43. path.add((Individual)o);
  44. }else {
  45. Integer i = (Integer)o;
  46. path.add(ctxt.individualCensus.get(i));
  47. }
  48. }
  49. path.add(dy.alter);
  50. for (Individual current : path) {
  51. String mini = findRelationship(current, prior);
  52. minis.add(mini);
  53. }
  54. return minis;
  55. }
  56. public String findRelationship(Individual alt, Individual ego)
  57. throws KSInternalErrorException {
  58. String pred = null,
  59. args = "(#" + ego.serialNmbr + ",#" + alt.serialNmbr + ")";
  60. if (ego.birthFamily != null) {
  61. if (alt == ego.birthFamily.husband) {
  62. return "Fa" + args;
  63. } else if (alt == ego.birthFamily.wife) {
  64. return "Mo" + args;
  65. } else {
  66. for (int k = 0; k < ego.birthFamily.children.size(); k++) {
  67. Individual kid = (Individual) ego.birthFamily.children.get(k);
  68. if (kid == alt) {
  69. pred = (kid.gender.equals("M") ? "Bro" : "Sis");
  70. return pred + args;
  71. }
  72. }
  73. }
  74. } // end of looking in birthFam for usual relationships
  75. for (int m = 0; m < ego.marriages.size(); m++) {
  76. Family fam = (Family) ego.marriages.get(m);
  77. if (alt == fam.wife) {
  78. return "Wi" + args;
  79. } else if (alt == fam.husband) {
  80. return "Hu" + args;
  81. }
  82. for (int k = 0; k < fam.children.size(); k++) {
  83. Individual kid = (Individual) fam.children.get(k);
  84. if (kid == alt) {
  85. pred = (kid.gender.equals("M") ? "So" : "Da");
  86. return pred + args;
  87. }
  88. }
  89. } // end of looking in marriages for usual relationships
  90. for (int m = 0; m < ego.marriages.size(); m++) {
  91. Family fam = (Family) ego.marriages.get(m);
  92. ArrayList<Family> otherFams = new ArrayList<Family>();
  93. if (ego == fam.husband && fam.wife != null
  94. && fam.wife.marriages.size() > 1) {
  95. for (int f = 0; f < fam.wife.marriages.size(); f++) {
  96. Family stepFam = (Family) fam.wife.marriages.get(f);
  97. if (fam != stepFam) {
  98. otherFams.add(stepFam);
  99. }
  100. }
  101. }else if (ego == fam.wife && fam.husband != null
  102. && fam.husband.marriages.size() > 1) {
  103. for (int f = 0; f < fam.husband.marriages.size(); f++) {
  104. Family stepFam = (Family) fam.husband.marriages.get(f);
  105. if (fam != stepFam) {
  106. otherFams.add(stepFam);
  107. }
  108. }
  109. }
  110. for (Family stepFam : otherFams) {
  111. for (int k = 0; k < stepFam.children.size(); k++) {
  112. Individual kid = (Individual) stepFam.children.get(k);
  113. if (kid == alt) {
  114. pred = (kid.gender.equals("M") ? "Stso" : "Stda");
  115. return pred + args;
  116. }
  117. }
  118. }
  119. } // end of looking for stepKids
  120. // SIGH! Guess I'll have to look for the REALLY weird relations
  121. if (ego.birthFamily != null) {
  122. Family fam = ego.birthFamily;
  123. Individual mom = fam.wife, dad = fam.husband;
  124. ArrayList<Family> otherFams = new ArrayList<Family>(),
  125. stillOtherFams = new ArrayList<Family>();
  126. if (mom != null && mom.marriages.size() > 1) {
  127. for (int m=0; m < mom.marriages.size(); m++) {
  128. Family f = (Family)mom.marriages.get(m);
  129. if (f != fam) {
  130. otherFams.add(f);
  131. if (f.husband != null && f.husband.marriages.size() > 1) {
  132. for (int sof=0; sof < f.husband.marriages.size(); sof++) {
  133. Family stillOther = (Family)f.husband.marriages.get(sof);
  134. if (stillOther != f) {
  135. stillOtherFams.add(stillOther);
  136. }
  137. }
  138. }
  139. }
  140. }
  141. }
  142. if (dad != null && dad.marriages.size() > 1) {
  143. for (int m=0; m < dad.marriages.size(); m++) {
  144. Family f = (Family)dad.marriages.get(m);
  145. if (f != fam) {
  146. otherFams.add(f);
  147. if (f.wife != null && f.wife.marriages.size() > 1) {
  148. for (int sof=0; sof < f.wife.marriages.size(); sof++) {
  149. Family stillOther = (Family)f.wife.marriages.get(sof);
  150. if (stillOther != f) {
  151. stillOtherFams.add(stillOther);
  152. }
  153. }
  154. }
  155. }
  156. }
  157. }
  158. for (Family stepFam : otherFams) {
  159. if (alt == stepFam.husband) {
  160. return "Stfa" + args;
  161. }else if (alt == stepFam.wife) {
  162. return "Stmo" + args;
  163. }
  164. for (int k = 0; k < stepFam.children.size(); k++) {
  165. Individual kid = (Individual) stepFam.children.get(k);
  166. if (kid == alt) {
  167. pred = (kid.gender.equals("M") ? "Hbro" : "Hsis");
  168. return pred + args;
  169. }
  170. }
  171. }
  172. for (Family so : stillOtherFams) {
  173. for (int k = 0; k < so.children.size(); k++) {
  174. Individual kid = (Individual) so.children.get(k);
  175. if (kid == alt) {
  176. pred = (kid.gender.equals("M") ? "Stbro" : "Stsis");
  177. return pred + args;
  178. }
  179. }
  180. }
  181. }
  182. throw new KSInternalErrorException("Cannot find relational predicate: ????" + args);
  183. }
  184. public Node clone() {
  185. Node copy = new Node();
  186. copy.indiv = indiv;
  187. copy.pcString = pcString;
  188. copy.treelevel = treelevel;
  189. copy.miniPreds = miniPreds;
  190. copy.kinTermsRef = kinTermsRef;
  191. copy.extKinTermsRef = extKinTermsRef;
  192. copy.kinTermsAddr = kinTermsAddr;
  193. copy.extKinTermsAddr = extKinTermsAddr;
  194. copy.ktSuffix = ktSuffix;
  195. copy.appearances = appearances;
  196. return copy;
  197. }
  198. static Node makeSelfNode(boolean adr) {
  199. Node selfNode = new Node();
  200. selfNode.pcString = "";
  201. selfNode.treelevel = 0;
  202. selfNode.kinTermsRef.add("Ego");
  203. if (adr) {
  204. selfNode.kinTermsAddr.add("Ego");
  205. }
  206. return selfNode;
  207. }
  208. public void setLevel(int myLevel) {
  209. this.treelevel = myLevel;
  210. }
  211. public int getLevel() {
  212. return treelevel;
  213. }
  214. public String toSILKString() {
  215. String image = "";
  216. image += "<pcString>" + pcString + "</pcString> ";
  217. image += "<level>" + treelevel + "</level>\n\t\t";
  218. if (!miniPreds.isEmpty()) {
  219. image += "<miniPreds> ";
  220. for (Object o : miniPreds) {
  221. image += makeMiniPredXML(o);
  222. }
  223. image += " </miniPreds> ";
  224. }
  225. image += writeKinTerms();
  226. return image;
  227. }
  228. public String makeMiniPredXML(Object mini) {
  229. String s = "<pred rel=\"",
  230. miniPred = (String)mini;
  231. int left = miniPred.indexOf("("),
  232. comma = miniPred.indexOf(","),
  233. right = miniPred.indexOf(")");
  234. String pred = miniPred.substring(0, left),
  235. arg0 = miniPred.substring(left +2, comma),
  236. arg1 = miniPred.substring(comma +2, right);
  237. s += pred + "\" arg0=\"" + arg0 + "\" arg1=\"" + arg1;
  238. return s + "\"/>";
  239. }
  240. String makeTagBlock(String tagGuts, Iterator termIter) {
  241. String s = "", term;
  242. while (termIter.hasNext()) {
  243. term = "";
  244. while (term.equals("") && termIter.hasNext()) {
  245. term = (String)termIter.next();
  246. } // got a non-blank term
  247. s += term + (termIter.hasNext() ? ", " : "");
  248. }
  249. if (s.equals("")) return s;
  250. else return "<" + tagGuts + ">" + s + "</" + tagGuts + ">";
  251. }
  252. public String writeKinTerms() {
  253. String image = "";
  254. Iterator ktIter;
  255. if ((kinTermsRef != null) && (kinTermsRef.size() > 0)) {
  256. ktIter = kinTermsRef().iterator();
  257. image += makeTagBlock("PR", ktIter);
  258. }
  259. if ((extKinTermsRef != null) && (extKinTermsRef.size() > 0)) {
  260. ktIter = extKinTermsRef().iterator();
  261. image += makeTagBlock("ER", ktIter);
  262. }
  263. if ((kinTermsAddr != null) && (kinTermsAddr.size() > 0)) {
  264. ktIter = kinTermsAddr().iterator();
  265. image += makeTagBlock("PA", ktIter);
  266. }
  267. if ((extKinTermsAddr != null) && (extKinTermsAddr.size() > 0)) {
  268. ktIter = extKinTermsAddr().iterator();
  269. image += makeTagBlock("EA", ktIter);
  270. }
  271. return image;
  272. } // end of method writeKinTerms
  273. public void replaceTerms(ArrayList<String> terms, String type, String clas) {
  274. if (clas.equals("reference")) {
  275. if (type.equals("primary")) {
  276. kinTermsRef = new ArrayList<Object>(terms);
  277. } else if (type.equals("extended")) {
  278. extKinTermsRef = new ArrayList<Object>(terms);
  279. }
  280. } else {
  281. if (type.equals("primary")) {
  282. kinTermsAddr = new ArrayList<Object>(terms);
  283. } else if (type.equals("extended")) {
  284. extKinTermsAddr = new ArrayList<Object>(terms);
  285. }
  286. }
  287. }
  288. public void addTerms(ArrayList<String> terms, String type, String clas) {
  289. for (String term : terms) {
  290. addTerm(term, type, clas);
  291. }
  292. }
  293. public void removeTerm(String term, String typ, String clas) {
  294. // Don't search Exceptions -- I'm going to delete them
  295. if (clas.equals("reference")) {
  296. if (typ.equals("primary")) {
  297. if (kinTermsRef != null) {
  298. kinTermsRef.remove(term);
  299. }
  300. } else if (typ.equals("extended")) {
  301. if (extKinTermsRef != null) {
  302. extKinTermsRef.remove(term);
  303. }
  304. }
  305. }
  306. if (clas.equals("address")) {
  307. if (typ.equals("primary")) {
  308. if (kinTermsAddr != null) {
  309. kinTermsAddr.remove(term);
  310. }
  311. } else if (typ.equals("extended")) {
  312. if (extKinTermsAddr != null) {
  313. extKinTermsAddr.remove(term);
  314. }
  315. }
  316. }
  317. }
  318. /**
  319. Add <code>term</code> to the appropriate list of kinTerms.
  320. @param term a kinship term.
  321. @param type must be 'primary' or 'extended' or 'exception'
  322. @param clas must be 'reference' or 'address'
  323. */
  324. public int addTerm(String term, String type, String clas) { // to assure only Strings are inserted
  325. int nmbr = 0;
  326. if (term == null) return 0;
  327. if (clas.equals("reference")) {
  328. if (type.equals("primary")) {
  329. if (kinTermsRef == null) {
  330. kinTermsRef = new ArrayList<Object>();
  331. }
  332. if (! kinTermsRef.contains(term)) {
  333. kinTermsRef.add(term);
  334. nmbr++;
  335. }
  336. } else if (type.equals("extended")) {
  337. if (extKinTermsRef == null) {
  338. extKinTermsRef = new ArrayList<Object>();
  339. }
  340. if (! extKinTermsRef.contains(term)) {
  341. extKinTermsRef.add(term);
  342. nmbr++;
  343. }
  344. }
  345. } else {
  346. if (type.equals("primary")) {
  347. if (kinTermsAddr == null) {
  348. kinTermsAddr = new ArrayList<Object>();
  349. }
  350. if (! kinTermsAddr.contains(term)) {
  351. kinTermsAddr.add(term);
  352. nmbr++;
  353. }
  354. } else if (type.equals("extended")) {
  355. if (extKinTermsAddr == null) {
  356. extKinTermsAddr = new ArrayList<Object>();
  357. }
  358. if (! extKinTermsAddr.contains(term)) {
  359. extKinTermsAddr.add(term);
  360. nmbr++;
  361. }
  362. }
  363. }
  364. return nmbr;
  365. } // end of method replaceTerms
  366. /** Determine whether any kinship terms are present.
  367. @return true if any term are found. */
  368. public boolean hasKinTerms() {
  369. if (kinTermsRef.size() > 0 || extKinTermsRef.size() > 0
  370. || kinTermsAddr.size() > 0 || extKinTermsAddr.size() > 0) {
  371. return true;
  372. } else return false;
  373. } // end of method hasKinTerms
  374. public boolean hasKinTerm(String kt) {
  375. if (kinTermsRef.contains(kt)|| extKinTermsRef.contains(kt)
  376. || kinTermsAddr.contains(kt) || extKinTermsAddr.contains(kt)) {
  377. return true;
  378. } else return false;
  379. }
  380. public int nmbrOfKinTerms() {
  381. ArrayList<String> terms = getKinTerms(true);
  382. int count = terms.size();
  383. terms = getKinTerms(false);
  384. count += terms.size();
  385. return count;
  386. }
  387. public void addKinTermsFrom(Node otherNode) {
  388. kinTermsRef.addAll(otherNode.kinTermsRef());
  389. extKinTermsRef.addAll(otherNode.extKinTermsRef());
  390. kinTermsAddr.addAll(otherNode.kinTermsAddr());
  391. extKinTermsAddr.addAll(otherNode.extKinTermsAddr());
  392. }
  393. public boolean sameMiniPreds(Node otherNode) {
  394. if (otherNode == null) return false;
  395. if (miniPreds.size() != otherNode.miniPreds.size()) return false;
  396. for (int i=0; i < miniPreds.size(); i++) {
  397. String myMini = (String)miniPreds.get(i);
  398. String otherMini = (String)otherNode.miniPreds.get(i);
  399. if (! myMini.equals(otherMini)) return false;
  400. }
  401. return true;
  402. }
  403. /** Return an AList of any kinship terms found.
  404. @param addr true if seeking terms of address; false = reference
  405. @return list of terms found. */
  406. public ArrayList<String> getKinTerms(boolean addr) {
  407. ArrayList<String> terms = new ArrayList<String>();
  408. if (addr) {
  409. if (kinTermsAddr != null && kinTermsAddr.size() > 0) {
  410. for (int i=0; i < kinTermsAddr.size() ; i++) {
  411. terms.add((String)kinTermsAddr.get(i));
  412. }
  413. }
  414. if (extKinTermsAddr != null && extKinTermsAddr.size() > 0) {
  415. for (int i=0; i < extKinTermsAddr.size() ; i++) {
  416. terms.add((String)extKinTermsAddr.get(i));
  417. }
  418. }
  419. }else {
  420. if (kinTermsRef != null && kinTermsRef.size() > 0) {
  421. for (int i=0; i < kinTermsRef.size() ; i++) {
  422. terms.add((String)kinTermsRef.get(i));
  423. }
  424. }
  425. if (extKinTermsRef != null && extKinTermsRef.size() > 0) {
  426. for (int i=0; i < extKinTermsRef.size() ; i++) {
  427. terms.add((String)extKinTermsRef.get(i));
  428. }
  429. }
  430. }
  431. return terms;
  432. }
  433. /** Take the pcString and miniPreds of this node and
  434. * 'invert' them for a node containing the reciprocal kinTerm.
  435. *
  436. @param altNode receiver of inverted list & string
  437. */
  438. public void invertMiniPredsAndPCStringFor(Node node) {
  439. String revPred;
  440. ArrayList<Object> revMiniPreds = new ArrayList<Object>();
  441. for (int i = miniPreds.size() -1; i >= 0; i--) {
  442. revPred = reversePred((String)miniPreds.get(i));
  443. revMiniPreds.add(revPred);
  444. }
  445. node.pcString = ClauseBody.sumStr(revMiniPreds);
  446. node.miniPreds = revMiniPreds;
  447. }
  448. /** Reverse the miniPred by inverting the predicate and
  449. * reversing the 2 arguments.
  450. *
  451. @param miniPred e.g. Fa(#2,#9). arg0 = #2 and arg1 = #9
  452. @return the reverse, e.g. Da(#9,#2) */
  453. public String reversePred(String miniPred) {
  454. ArrayList<Individual> ppl = Context.current.individualCensus;
  455. int left = miniPred.indexOf("("),
  456. comma = miniPred.indexOf(","),
  457. end = miniPred.indexOf(")");
  458. int arg0num = Integer.parseInt(miniPred.substring(left +2, comma)),
  459. arg1num = Integer.parseInt(miniPred.substring(comma +2, end));
  460. String revPred = "", rel = miniPred.substring(0, left);
  461. boolean male1 = ppl.get(arg1num).gender.equals("M");
  462. // parent-child terms
  463. if (rel.equals("Fa") || rel.equals("Mo")) {
  464. revPred = (male1 ? "So" : "Da");
  465. }else if (rel.equals("So") || rel.equals("Da")) {
  466. revPred = (male1 ? "Fa" : "Mo");
  467. }else if(rel.equals("Stfa") || rel.equals("Stmo")) {
  468. revPred = (male1 ? "Stso" : "Stda");
  469. }else if (rel.equals("Stso") || rel.equals("Stda")) {
  470. revPred = (male1 ? "Stfa" : "Stmo");
  471. // spousal terms
  472. }else if (rel.equals("Hu") || rel.equals("Wi")) {
  473. revPred = (male1 ? "Hu" : "Wi");
  474. // sibling terms
  475. }else if (rel.equals("Bro") || rel.equals("Sis")) {
  476. revPred = (male1 ? "Bro" : "Sis");
  477. }else if (rel.equals("Stbro") || rel.equals("Stsis")) {
  478. revPred = (male1 ? "Stbro" : "Stsis");
  479. }else if (rel.equals("Hbro") || rel.equals("Hsis")) {
  480. revPred = (male1 ? "Hbro" : "Hsis");
  481. }else {
  482. System.out.println("Failed to reverse relationship: " + rel);
  483. }
  484. return revPred + "(#" + arg1num + ",#" + arg0num + ")";
  485. }
  486. /** Return an ArrayList<Object> of primary kinship terms of reference which is a shallow copy of the list in this Node.
  487. @return an ArrayList<Object> of Strings, each of which is a kinship term, or null. */
  488. public ArrayList<Object> kinTermsRef() {
  489. if (kinTermsRef == null) {
  490. return null;
  491. }
  492. return new ArrayList<Object>(kinTermsRef);
  493. } // end of method kinTermsRef
  494. /**
  495. Return an ArrayList<Object> of extended kinship terms of reference which is a shallow copy of the list in this Node.
  496. @return an ArrayList<Object> of Strings, each of which is an extended kinship term, or null.
  497. */
  498. public ArrayList<Object> extKinTermsRef() {
  499. if (extKinTermsRef == null) {
  500. return null;
  501. }
  502. return new ArrayList<Object>(extKinTermsRef);
  503. } // end of method extKinTermsRef
  504. /**
  505. Return an ArrayList<Object> of primary kinship terms of address which is a shallow copy of the list in this Node.
  506. @return an ArrayList<Object> of Strings, each of which is a kinship term, or null.
  507. */
  508. public ArrayList<Object> kinTermsAddr() {
  509. if (kinTermsAddr == null) {
  510. return null;
  511. }
  512. return new ArrayList<Object>(kinTermsAddr);
  513. } // end of method kinTermsAddr
  514. /**
  515. Return an ArrayList<Object> of extended kinship terms of address which is a shallow copy of the list in this Node.
  516. @return an ArrayList<Object> of Strings, each of which is an extended kinship term, or null.
  517. */
  518. public ArrayList<Object> extKinTermsAddr() {
  519. if (extKinTermsAddr == null) {
  520. return null;
  521. }
  522. return new ArrayList<Object>(extKinTermsAddr);
  523. } // end of method extkinTermsAddr
  524. }