BasicNode.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  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. if(getId() >= 0)
  214. {
  215. for (BasicNode basicNode : NeedUpload) {
  216. if(this.equals(basicNode) && basicNode != this) return false;
  217. }
  218. return true;
  219. }
  220. return false;
  221. }
  222. /**
  223. * check id defined statue
  224. * @return if is true, node id should defineded
  225. */
  226. public boolean defineded()
  227. {
  228. return vaildity() && getId() > 0;
  229. }
  230. /**
  231. * InnerHTML of tab
  232. * @return DOM Context.InnerHTML
  233. */
  234. public String tabContextInnerHTML()
  235. {
  236. return "id : " + getId();
  237. }
  238. /**
  239. * remove itselfs from its level
  240. */
  241. public void dropFromLevel()
  242. {
  243. synchronized(this)
  244. {
  245. if(this.nextNode != null)
  246. {
  247. this.nextNode.pervNode = this.pervNode;
  248. this.nextNode.setNeedUpload();
  249. }
  250. if(this.pervNode != null)
  251. {
  252. this.pervNode.nextNode = this.nextNode;
  253. this.pervNode.setNeedUpload();
  254. }
  255. else
  256. if(this.parentNode != null)
  257. {
  258. this.parentNode.childLevel = this.nextNode;
  259. this.parentNode.setNeedUpload();
  260. }
  261. this.parentNode = null;
  262. this.nextNode = null;
  263. this.pervNode = null;
  264. this.setNeedUpload();
  265. }
  266. }
  267. /**
  268. * instert a {@link #node} after this node
  269. * @param node node to instert/
  270. */
  271. public boolean insertNext(BasicNode node)
  272. {
  273. synchronized(this)
  274. {
  275. if(node != null && node.vaildity() && this.vaildity())
  276. {
  277. if(!node.subTreeContains(this))
  278. {
  279. //remove from its level
  280. node.dropFromLevel();
  281. //cache
  282. BasicNode nextNode = this.nextNode;
  283. //replace next
  284. this.nextNode = node;
  285. node.nextNode = nextNode;
  286. //replace perv
  287. node.pervNode = this;
  288. //set to same parent node
  289. node.parentNode = this.parentNode;
  290. //check if exiet
  291. if(nextNode != null)
  292. {
  293. nextNode.pervNode = node;
  294. nextNode.setNeedUpload();
  295. }
  296. this.setNeedUpload();
  297. return true;
  298. }
  299. }
  300. return false;
  301. }
  302. }
  303. /**
  304. * instert a {@link #node} before this node
  305. * @param node node to instert
  306. */
  307. public boolean insertPerv(BasicNode node)
  308. {
  309. synchronized(this)
  310. {
  311. if(node != null && node.vaildity() && this.vaildity())
  312. {
  313. if(!node.subTreeContains(this))
  314. {
  315. //remove from its level
  316. node.dropFromLevel();
  317. //cache
  318. BasicNode pervNode = this.pervNode;
  319. //replace next
  320. this.pervNode = node;
  321. node.pervNode = pervNode;
  322. //replace last
  323. node.nextNode = this;
  324. //set to same parent node
  325. node.parentNode = this.parentNode;
  326. //check if exiet
  327. if(pervNode != null)
  328. {
  329. pervNode.nextNode = node;
  330. pervNode.setNeedUpload();
  331. }
  332. else //remove if parrentNode exiet
  333. if(this.parentNode != null)
  334. {
  335. this.parentNode.childLevel = node;
  336. this.parentNode.setNeedUpload();
  337. }
  338. this.setNeedUpload();
  339. return true;
  340. }
  341. }
  342. return false;
  343. }
  344. }
  345. /**
  346. * replace current pos of its level
  347. * @param node node for replace
  348. */
  349. public boolean replaceBy(BasicNode node)
  350. {
  351. synchronized(this)
  352. {
  353. if(!vaildity()) return false;
  354. if(node != null && node.vaildity())
  355. {
  356. if(!node.subTreeContains(this))
  357. {
  358. node.dropFromLevel();
  359. node.parentNode = this.parentNode;
  360. node.nextNode = this.nextNode;
  361. node.pervNode = this.pervNode;
  362. this.dropFromLevel();
  363. if(node.nextNode != null)
  364. {
  365. node.nextNode.pervNode = node;
  366. }
  367. if(node.pervNode != null)
  368. {
  369. node.pervNode.nextNode = node;
  370. }
  371. else
  372. if(node.parentNode != null)
  373. {
  374. node.parentNode.childLevel = node;
  375. node.parentNode.setNeedUpload();
  376. }
  377. return true;
  378. }
  379. }
  380. else
  381. {
  382. this.dropFromLevel();
  383. return true;
  384. }
  385. return false;
  386. }
  387. }
  388. public boolean exchangeWith(BasicNode node)
  389. {
  390. synchronized(this)
  391. {
  392. if(!vaildity()) return false;
  393. if(node != null && node.vaildity())
  394. {
  395. if(!node.subTreeContains(this) && !this.subTreeContains(node))
  396. {
  397. //cache
  398. BasicNode next = node.nextNode;
  399. BasicNode perv = node.pervNode;
  400. BasicNode parent = node.parentNode;
  401. if(next == this)
  402. {
  403. next = this.pervNode;
  404. this.pervNode = this;
  405. }
  406. if(perv == this)
  407. {
  408. perv = this.nextNode;
  409. this.nextNode = this;
  410. }
  411. //set node to this
  412. node.nextNode = this.nextNode;
  413. node.pervNode = this.pervNode;
  414. node.parentNode = this.parentNode;
  415. node.setNeedUpload();
  416. //check near by node update
  417. if(node.nextNode != null)
  418. {
  419. node.nextNode.pervNode = node;
  420. node.nextNode.setNeedUpload();
  421. }
  422. if(node.pervNode != null)
  423. {
  424. node.pervNode.nextNode = node;
  425. node.pervNode.setNeedUpload();
  426. }
  427. else
  428. if(node.parentNode != null)
  429. {
  430. node.parentNode.childLevel = node;
  431. node.parentNode.setNeedUpload();
  432. }
  433. //set this to next
  434. this.nextNode = next;
  435. this.pervNode = perv;
  436. this.parentNode = parent;
  437. this.setNeedUpload();
  438. //check near by node update
  439. if(this.nextNode != null)
  440. {
  441. this.nextNode.pervNode = this;
  442. this.nextNode.setNeedUpload();
  443. }
  444. if(this.pervNode != null)
  445. {
  446. this.pervNode.nextNode = this;
  447. this.pervNode.setNeedUpload();
  448. }
  449. else
  450. if(this.parentNode != null)
  451. {
  452. this.parentNode.childLevel = this;
  453. this.parentNode.setNeedUpload();
  454. }
  455. return true;
  456. }
  457. }
  458. else
  459. {
  460. this.dropFromLevel();
  461. return true;
  462. }
  463. return false;
  464. }
  465. }
  466. /**
  467. * Level's start
  468. */
  469. public BasicNode startOfNodeLevel()
  470. {
  471. BasicNode node = this;
  472. while(node.pervNode != null)
  473. {
  474. node = node.pervNode;
  475. }
  476. return node;
  477. }
  478. /**
  479. * Level's end
  480. */
  481. public BasicNode endOfNodeLevel()
  482. {
  483. BasicNode node = this;
  484. while(node.nextNode != null)
  485. {
  486. node = node.nextNode;
  487. }
  488. return node;
  489. }
  490. /**
  491. * get root of node tree
  492. * @return node of the minimum level
  493. */
  494. public BasicNode rootNode()
  495. {
  496. BasicNode node = this;
  497. while(node.parentNode != null)
  498. {
  499. node = node.parentNode;
  500. }
  501. return node;
  502. }
  503. /**
  504. * replace child level to {@link #childLevel}
  505. * @param childLevel target
  506. * @return if success , return droped node else null
  507. */
  508. public BasicNode setChildLevel(BasicNode childLevel)
  509. {
  510. //is use as level, so we need to
  511. if(childLevel != null && vaildity() && childLevel.vaildity())
  512. {
  513. //save usage
  514. childLevel = childLevel.startOfNodeLevel();
  515. if(childLevel.subTreeContains(this.startOfNodeLevel())) return null;
  516. BasicNode result = this.childLevel;
  517. if(childLevel != null)
  518. {
  519. for(BasicNode node : childLevel)
  520. {
  521. node.parentNode = this;
  522. }
  523. }
  524. if(this.childLevel != null)
  525. {
  526. for(BasicNode node : this.childLevel)
  527. {
  528. node.parentNode = null;
  529. }
  530. }
  531. this.childLevel = childLevel;
  532. return result;
  533. }
  534. return null;
  535. }
  536. /**
  537. * check if level contains {@ling #node}
  538. * @param node node for check
  539. * @return {@value true} mean contains {@value false} mean not contains
  540. */
  541. public boolean levelContains(BasicNode node)
  542. {
  543. if(node != null)
  544. {
  545. if(node.parentNode != null && this.parentNode != null)
  546. {
  547. return node.parentNode == this.parentNode;
  548. }
  549. else
  550. {
  551. BasicNode cache1 = node;
  552. BasicNode cache2 = this;
  553. do
  554. {
  555. //check 2 node's perv node at same time
  556. if(cache1.equals(this) || cache2.equals(node))
  557. return true;
  558. if(cache1.pervNode != null)
  559. cache1 = cache1.pervNode;
  560. if(cache2.pervNode != null)
  561. cache2 = cache2.pervNode;
  562. }
  563. while(cache2.pervNode != null || cache1.pervNode != null);
  564. return cache1 == cache2;
  565. }
  566. }
  567. return false;
  568. }
  569. /**
  570. * check if node tree has node
  571. * @param node node for check
  572. * @return {@value true} mean contains {@value false} mean not contains
  573. */
  574. public boolean treeContains(BasicNode node)
  575. {
  576. if(node != null)
  577. {
  578. return node.rootNode().levelContains(this.rootNode());
  579. }
  580. return false;
  581. }
  582. /**
  583. * check if this node is a sub node of the node
  584. * @param node node for check
  585. * @return if this node is a sub node of the node, it will return true
  586. */
  587. public boolean subTreeContains(BasicNode node)
  588. {
  589. if(node != null)
  590. {
  591. do
  592. {
  593. if(node.equals(this))
  594. {
  595. return true;
  596. }
  597. node = node.parentNode;
  598. }
  599. while(node != null);
  600. }
  601. return false;
  602. }
  603. public long getLayout()
  604. {
  605. long result = 0;
  606. BasicNode node =this.getParentNode();
  607. while(node != null)
  608. {
  609. node = node.getParentNode();
  610. ++result;
  611. }
  612. return result;
  613. }
  614. @Override
  615. public String toString()
  616. {
  617. String result = this.getId() + "{ ";
  618. for(BasicNode node : this)
  619. {
  620. result += node.getId();
  621. if(node.getChildLevel() != null) result += "+";
  622. if(node.nextNode != null) result += " , ";
  623. }
  624. return result + " }";
  625. }
  626. public void deleteNode() throws IOException
  627. {
  628. this.setId(-1l);
  629. }
  630. /**
  631. * check level
  632. * @param levelA value a
  633. * @param levelB value b
  634. * @return if is same level,it will return true
  635. */
  636. public static boolean levelEqul(BasicNode levelA,BasicNode levelB)
  637. {
  638. return levelA.startOfNodeLevel().id == levelB.startOfNodeLevel().id;
  639. }
  640. @Override
  641. public boolean equals(Object o) {
  642. // TODO Auto-generated method stub
  643. BasicNode other = (BasicNode)o;
  644. if(other != null) return other.id == this.id;
  645. else return super.equals(o);
  646. }
  647. /**
  648. * check all loaded node and upload data
  649. * @throws IOException no sql mapper
  650. */
  651. public static void Commit() throws IOException
  652. {
  653. synchronized(NeedUpload)
  654. {
  655. for (BasicNode basicNode : NeedUpload)
  656. {
  657. basicNode.uploadNode();
  658. }
  659. NodeDao.getCurrentMapper().commit();
  660. NeedUpload.clear();
  661. }
  662. }
  663. public static BasicNode TryGetNotCommitNodeById(long id)
  664. {
  665. synchronized(NeedUpload)
  666. {
  667. for (BasicNode basicNode : NeedUpload)
  668. {
  669. if(basicNode.getId() == id)
  670. {
  671. return basicNode;
  672. }
  673. }
  674. return null;
  675. }
  676. }
  677. /**
  678. * Iterator of {@link #BasicNode}
  679. */
  680. class NodeIterator implements Iterator<BasicNode>
  681. {
  682. BasicNode next;
  683. private NodeIterator(BasicNode node)
  684. {
  685. next = node;
  686. }
  687. @Override
  688. public boolean hasNext() {
  689. return next != null;
  690. }
  691. @Override
  692. public BasicNode next() {
  693. BasicNode next = this.next;
  694. this.next = next.nextNode;
  695. return next;
  696. }
  697. }
  698. }