BasicNode.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. package group04;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import java.util.Iterator;
  5. import group04.myBatis.Nodeinfo;
  6. /**
  7. * basic node class of node, it can explane a single node and the level of node
  8. */
  9. public class BasicNode implements Iterable<BasicNode>
  10. {
  11. /**
  12. * <0 : invalidity node
  13. * =0 : undifineded node
  14. * >0 : created node
  15. */
  16. private long id = 0l;
  17. private BasicNode nextNode = null;
  18. private BasicNode pervNode = null;
  19. private BasicNode childLevel = null;
  20. private BasicNode parentNode = null;
  21. private static ArrayList<BasicNode> NeedUpload = new ArrayList<>();
  22. /**
  23. * create new node
  24. * @throws IOException no mapper
  25. */
  26. public BasicNode(){}
  27. /**
  28. * create node by confirm id
  29. * @param id node id
  30. * @throws IOException no mapper
  31. */
  32. public BasicNode(long id) throws IOException
  33. {
  34. setId(Math.abs(id));
  35. }
  36. @Override
  37. public NodeIterator iterator() {
  38. BasicNode node = startOfNodeLevel();
  39. return new NodeIterator(node);
  40. }
  41. /**
  42. * get node id
  43. * @return id of this node
  44. */
  45. public long getId() {
  46. return id;
  47. }
  48. /**
  49. * get next node of this node
  50. * @return next node
  51. */
  52. public BasicNode getNextNode()
  53. {
  54. return nextNode;
  55. }
  56. /**
  57. * get previous node of this node
  58. * @return previous node
  59. */
  60. public BasicNode getPervNode()
  61. {
  62. return pervNode;
  63. }
  64. /**
  65. * get parrent node of this node
  66. * @return parrent node
  67. */
  68. public BasicNode getParentNode()
  69. {
  70. return parentNode;
  71. }
  72. /**
  73. * get child level
  74. * @return first node of child nodes
  75. */
  76. public BasicNode getChildLevel()
  77. {
  78. if(childLevel != null)
  79. {
  80. while(childLevel.pervNode != null)
  81. {
  82. childLevel = childLevel.pervNode;
  83. }
  84. }
  85. return childLevel;
  86. }
  87. public void setNeedUpload()
  88. {
  89. synchronized(NeedUpload)
  90. {
  91. if(!NeedUpload.contains(this))
  92. {
  93. NeedUpload.add(this);
  94. }
  95. }
  96. }
  97. /**
  98. * set Node id,also it can destroy this node by seting id to minus value
  99. * @param id new id
  100. * @throws IOException no mapper
  101. */
  102. public void setId(long id) throws IOException
  103. {
  104. synchronized(this)
  105. {
  106. //defineded id
  107. if(id == 0 || !vaildity()) return;
  108. //not null
  109. if(id < 0)
  110. {
  111. //delete
  112. NodeDao.getCurrentMapper().deleteByPrimaryKey(this.id);
  113. //if database vaildity, it will going on.
  114. dropFromLevel();
  115. //delete all child nodes
  116. BasicNode node = this.getChildLevel();
  117. while(node != null)
  118. {
  119. BasicNode next = node.getNextNode();
  120. node.deleteNode();
  121. node = next;
  122. }
  123. }
  124. else if(NodeDao.state() != NodeDao.DaoState.Reading)
  125. {
  126. Nodeinfo data = getNodeInfo();
  127. data.setId(id);
  128. try
  129. {
  130. //id is primary key of node info, we can't modify the primary key by primary key, so it need delete first
  131. NodeDao.getCurrentMapper().insert(data);
  132. //delete
  133. if(defineded()) NodeDao.getCurrentMapper().deleteByPrimaryKey(this.id);
  134. }
  135. catch (IOException IOEx)
  136. {
  137. //no mapper
  138. throw IOEx;
  139. }
  140. catch (Exception e)
  141. {
  142. //sql errery
  143. return;
  144. }
  145. }
  146. else
  147. {
  148. InitAfterLoad(id);
  149. }
  150. this.id = id;
  151. }
  152. }
  153. /**
  154. * for override, invoke when load feom database
  155. * @param id currectt id information
  156. */
  157. private void InitAfterLoad(long id)
  158. {
  159. }
  160. /**
  161. * convert to NodeInfo data
  162. * @return Node info for sql upload
  163. */
  164. public Nodeinfo getNodeInfo()
  165. {
  166. //gen data for update database
  167. Nodeinfo data = new Nodeinfo();
  168. BasicNode node = null;
  169. //node id
  170. data.setId(getId());
  171. //next element
  172. node = getNextNode();
  173. if(node != null && node.vaildity())data.setNextId(node.getId());
  174. else data.setNextId(null);
  175. //perv element
  176. node = getPervNode();
  177. if(node != null && node.vaildity())data.setPrevId(node.getId());
  178. else data.setPrevId(null);
  179. //parent element
  180. node = getParentNode();
  181. if(node != null && node.vaildity())data.setParentId(node.getId());
  182. else data.setParentId(null);
  183. //chile level
  184. node = getChildLevel();
  185. if(node != null && node.vaildity())
  186. {
  187. node = node.startOfNodeLevel();
  188. data.setChildId(node.getId());
  189. }
  190. else data.setChildId(null);
  191. //node class
  192. data.setObjType(this.getClass().getName());
  193. return data;
  194. }
  195. /**
  196. * upload to database
  197. * @throws IOException no mapper
  198. */
  199. public void uploadNode() throws IOException
  200. {
  201. synchronized(this)
  202. {
  203. Nodeinfo data = getNodeInfo();
  204. NodeDao.getCurrentMapper().updateByPrimaryKey(data);
  205. }
  206. }
  207. /**
  208. * check node vaild
  209. * @return if is false it should not exists in database
  210. */
  211. public boolean vaildity()
  212. {
  213. return getId() >= 0;
  214. }
  215. /**
  216. * check id defined statue
  217. * @return if is true, node id should defineded
  218. */
  219. public boolean defineded()
  220. {
  221. return getId() > 0;
  222. }
  223. /**
  224. * InnerHTML of tab
  225. * @return DOM Context.InnerHTML
  226. */
  227. public String tabContextInnerHTML()
  228. {
  229. return "id : " + getId();
  230. }
  231. /**
  232. * remove itselfs from its level
  233. */
  234. public void dropFromLevel()
  235. {
  236. synchronized(this)
  237. {
  238. if(this.nextNode != null)
  239. {
  240. this.nextNode.pervNode = this.pervNode;
  241. this.nextNode.setNeedUpload();
  242. }
  243. if(this.pervNode != null)
  244. {
  245. this.pervNode.nextNode = this.nextNode;
  246. this.pervNode.setNeedUpload();
  247. }
  248. else
  249. if(this.parentNode != null)
  250. {
  251. this.parentNode.childLevel = this.nextNode;
  252. this.parentNode.setNeedUpload();
  253. }
  254. this.parentNode = null;
  255. this.nextNode = null;
  256. this.pervNode = null;
  257. this.setNeedUpload();
  258. }
  259. }
  260. /**
  261. * instert a {@link #node} after this node
  262. * @param node node to instert/
  263. */
  264. public boolean insertNext(BasicNode node)
  265. {
  266. synchronized(this)
  267. {
  268. if(node != null && node.vaildity() && this.vaildity())
  269. {
  270. if(!node.subTreeContains(this))
  271. {
  272. //remove from its level
  273. node.dropFromLevel();
  274. //cache
  275. BasicNode nextNode = this.nextNode;
  276. //replace next
  277. this.nextNode = node;
  278. node.nextNode = nextNode;
  279. //replace perv
  280. node.pervNode = this;
  281. //set to same parent node
  282. node.parentNode = this.parentNode;
  283. //check if exiet
  284. if(nextNode != null)
  285. {
  286. nextNode.pervNode = node;
  287. nextNode.setNeedUpload();
  288. }
  289. this.setNeedUpload();
  290. return true;
  291. }
  292. }
  293. return false;
  294. }
  295. }
  296. /**
  297. * instert a {@link #node} before this node
  298. * @param node node to instert
  299. */
  300. public boolean insertPerv(BasicNode node)
  301. {
  302. synchronized(this)
  303. {
  304. if(node != null && node.vaildity() && this.vaildity())
  305. {
  306. if(!node.subTreeContains(this))
  307. {
  308. //remove from its level
  309. node.dropFromLevel();
  310. //cache
  311. BasicNode pervNode = this.pervNode;
  312. //replace next
  313. this.pervNode = node;
  314. node.pervNode = pervNode;
  315. //replace last
  316. node.nextNode = this;
  317. //set to same parent node
  318. node.parentNode = this.parentNode;
  319. //check if exiet
  320. if(pervNode != null)
  321. {
  322. pervNode.nextNode = node;
  323. pervNode.setNeedUpload();
  324. }
  325. else //remove if parrentNode exiet
  326. if(this.parentNode != null)
  327. {
  328. this.parentNode.childLevel = node;
  329. this.parentNode.setNeedUpload();
  330. }
  331. this.setNeedUpload();
  332. return true;
  333. }
  334. }
  335. return false;
  336. }
  337. }
  338. /**
  339. * replace current pos of its level
  340. * @param node node for replace
  341. */
  342. public boolean replaceBy(BasicNode node)
  343. {
  344. synchronized(this)
  345. {
  346. if(!vaildity()) return false;
  347. if(node != null && node.vaildity())
  348. {
  349. if(!node.subTreeContains(this))
  350. {
  351. node.dropFromLevel();
  352. node.parentNode = this.parentNode;
  353. node.nextNode = this.nextNode;
  354. node.pervNode = this.pervNode;
  355. this.dropFromLevel();
  356. if(node.nextNode != null)
  357. {
  358. node.nextNode.pervNode = node;
  359. }
  360. if(node.pervNode != null)
  361. {
  362. node.pervNode.nextNode = node;
  363. }
  364. else
  365. if(node.parentNode != null)
  366. {
  367. node.parentNode.childLevel = node;
  368. node.parentNode.setNeedUpload();
  369. }
  370. return true;
  371. }
  372. }
  373. else
  374. {
  375. this.dropFromLevel();
  376. return true;
  377. }
  378. return false;
  379. }
  380. }
  381. public boolean exchangeWith(BasicNode node)
  382. {
  383. synchronized(this)
  384. {
  385. if(!vaildity()) return false;
  386. if(node != null && node.vaildity())
  387. {
  388. if(!node.subTreeContains(this) && !this.subTreeContains(node))
  389. {
  390. //cache
  391. BasicNode next = node.nextNode;
  392. BasicNode perv = node.pervNode;
  393. BasicNode parent = node.parentNode;
  394. if(next == this)
  395. {
  396. next = this.pervNode;
  397. this.pervNode = this;
  398. }
  399. if(perv == this)
  400. {
  401. perv = this.nextNode;
  402. this.nextNode = this;
  403. }
  404. //set node to this
  405. node.nextNode = this.nextNode;
  406. node.pervNode = this.pervNode;
  407. node.parentNode = this.parentNode;
  408. node.setNeedUpload();
  409. //check near by node update
  410. if(node.nextNode != null)
  411. {
  412. node.nextNode.pervNode = node;
  413. node.nextNode.setNeedUpload();
  414. }
  415. if(node.pervNode != null)
  416. {
  417. node.pervNode.nextNode = node;
  418. node.pervNode.setNeedUpload();
  419. }
  420. else
  421. if(node.parentNode != null)
  422. {
  423. node.parentNode.childLevel = node;
  424. node.parentNode.setNeedUpload();
  425. }
  426. //set this to next
  427. this.nextNode = next;
  428. this.pervNode = perv;
  429. this.parentNode = parent;
  430. this.setNeedUpload();
  431. //check near by node update
  432. if(this.nextNode != null)
  433. {
  434. this.nextNode.pervNode = this;
  435. this.nextNode.setNeedUpload();
  436. }
  437. if(this.pervNode != null)
  438. {
  439. this.pervNode.nextNode = this;
  440. this.pervNode.setNeedUpload();
  441. }
  442. else
  443. if(this.parentNode != null)
  444. {
  445. this.parentNode.childLevel = this;
  446. this.parentNode.setNeedUpload();
  447. }
  448. return true;
  449. }
  450. }
  451. else
  452. {
  453. this.dropFromLevel();
  454. return true;
  455. }
  456. return false;
  457. }
  458. }
  459. /**
  460. * Level's start
  461. */
  462. public BasicNode startOfNodeLevel()
  463. {
  464. BasicNode node = this;
  465. while(node.pervNode != null)
  466. {
  467. node = node.pervNode;
  468. }
  469. return node;
  470. }
  471. /**
  472. * Level's end
  473. */
  474. public BasicNode endOfNodeLevel()
  475. {
  476. BasicNode node = this;
  477. while(node.nextNode != null)
  478. {
  479. node = node.nextNode;
  480. }
  481. return node;
  482. }
  483. /**
  484. * get root of node tree
  485. * @return node of the minimum level
  486. */
  487. public BasicNode rootNode()
  488. {
  489. BasicNode node = this;
  490. while(node.parentNode != null)
  491. {
  492. node = node.parentNode;
  493. }
  494. return node;
  495. }
  496. /**
  497. * replace child level to {@link #childLevel}
  498. * @param childLevel target
  499. * @return if success , return droped node else null
  500. */
  501. public BasicNode setChildLevel(BasicNode childLevel)
  502. {
  503. //is use as level, so we need to
  504. if(childLevel != null && vaildity() && childLevel.vaildity())
  505. {
  506. //save usage
  507. childLevel = childLevel.startOfNodeLevel();
  508. if(childLevel.subTreeContains(this.startOfNodeLevel())) return null;
  509. BasicNode result = this.childLevel;
  510. if(childLevel != null)
  511. {
  512. for(BasicNode node : childLevel)
  513. {
  514. node.parentNode = this;
  515. }
  516. }
  517. if(this.childLevel != null)
  518. {
  519. for(BasicNode node : this.childLevel)
  520. {
  521. node.parentNode = null;
  522. }
  523. }
  524. this.childLevel = childLevel;
  525. return result;
  526. }
  527. return null;
  528. }
  529. /**
  530. * check if level contains {@ling #node}
  531. * @param node node for check
  532. * @return {@value true} mean contains {@value false} mean not contains
  533. */
  534. public boolean levelContains(BasicNode node)
  535. {
  536. if(node != null)
  537. {
  538. if(node.parentNode != null && this.parentNode != null)
  539. {
  540. return node.parentNode == this.parentNode;
  541. }
  542. else
  543. {
  544. BasicNode cache1 = node;
  545. BasicNode cache2 = this;
  546. do
  547. {
  548. //check 2 node's perv node at same time
  549. if(cache1.equals(this) || cache2.equals(node))
  550. return true;
  551. if(cache1.pervNode != null)
  552. cache1 = cache1.pervNode;
  553. if(cache2.pervNode != null)
  554. cache2 = cache2.pervNode;
  555. }
  556. while(cache2.pervNode != null || cache1.pervNode != null);
  557. return cache1 == cache2;
  558. }
  559. }
  560. return false;
  561. }
  562. /**
  563. * check if node tree has node
  564. * @param node node for check
  565. * @return {@value true} mean contains {@value false} mean not contains
  566. */
  567. public boolean treeContains(BasicNode node)
  568. {
  569. if(node != null)
  570. {
  571. return node.rootNode().levelContains(this.rootNode());
  572. }
  573. return false;
  574. }
  575. /**
  576. * check if this node is a sub node of the node
  577. * @param node node for check
  578. * @return if this node is a sub node of the node, it will return true
  579. */
  580. public boolean subTreeContains(BasicNode node)
  581. {
  582. if(node != null)
  583. {
  584. do
  585. {
  586. if(node.equals(this))
  587. {
  588. return true;
  589. }
  590. node = node.parentNode;
  591. }
  592. while(node != null);
  593. }
  594. return false;
  595. }
  596. public long getLayout()
  597. {
  598. long result = 0;
  599. BasicNode node =this.getParentNode();
  600. while(node != null)
  601. {
  602. node = node.getParentNode();
  603. ++result;
  604. }
  605. return result;
  606. }
  607. @Override
  608. public String toString()
  609. {
  610. String result = this.getId() + "{ ";
  611. for(BasicNode node : this)
  612. {
  613. result += node.getId();
  614. if(node.getChildLevel() != null) result += "+";
  615. if(node.nextNode != null) result += " , ";
  616. }
  617. return result + " }";
  618. }
  619. public void deleteNode() throws IOException
  620. {
  621. this.setId(-1l);
  622. }
  623. /**
  624. * check level
  625. * @param levelA value a
  626. * @param levelB value b
  627. * @return if is same level,it will return true
  628. */
  629. public static boolean levelEqul(BasicNode levelA,BasicNode levelB)
  630. {
  631. return levelA.startOfNodeLevel().id == levelB.startOfNodeLevel().id;
  632. }
  633. @Override
  634. public boolean equals(Object o) {
  635. // TODO Auto-generated method stub
  636. BasicNode other = (BasicNode)o;
  637. if(other != null) return other.id == this.id;
  638. else return super.equals(o);
  639. }
  640. /**
  641. * check all loaded node and upload data
  642. * @throws IOException no sql mapper
  643. */
  644. public static void Commit() throws IOException
  645. {
  646. synchronized(NeedUpload)
  647. {
  648. for (BasicNode basicNode : NeedUpload)
  649. {
  650. basicNode.uploadNode();
  651. }
  652. NodeDao.getCurrentMapper().commit();
  653. NeedUpload.clear();
  654. }
  655. }
  656. public static BasicNode TryGetNotCommitNodeById(long id)
  657. {
  658. synchronized(NeedUpload)
  659. {
  660. for (BasicNode basicNode : NeedUpload)
  661. {
  662. if(basicNode.getId() == id)
  663. {
  664. return basicNode;
  665. }
  666. }
  667. return null;
  668. }
  669. }
  670. /**
  671. * Iterator of {@link #BasicNode}
  672. */
  673. class NodeIterator implements Iterator<BasicNode>
  674. {
  675. BasicNode next;
  676. private NodeIterator(BasicNode node)
  677. {
  678. next = node;
  679. }
  680. @Override
  681. public boolean hasNext() {
  682. return next != null;
  683. }
  684. @Override
  685. public BasicNode next() {
  686. BasicNode next = this.next;
  687. this.next = next.nextNode;
  688. return next;
  689. }
  690. }
  691. }