BasicNode.java 20 KB

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