123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757 |
- package group04;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Iterator;
- import group04.myBatis.Nodeinfo;
- /**
- * basic node class of node, it can explane a single node and the level of node
- */
- public class BasicNode implements Iterable<BasicNode>
- {
- /**
- * <0 : invalidity node
- * =0 : undifineded node
- * >0 : created node
- */
- private long id = 0l;
- private BasicNode nextNode = null;
- private BasicNode pervNode = null;
-
- private BasicNode childLevel = null;
- private BasicNode parentNode = null;
- private static ArrayList<BasicNode> NeedUpload = new ArrayList<>();
- /**
- * create new node
- * @throws IOException no mapper
- */
- public BasicNode(){}
- /**
- * create node by confirm id
- * @param id node id
- * @throws IOException no mapper
- */
- public BasicNode(long id) throws IOException
- {
- setId(Math.abs(id));
- }
-
- @Override
- public NodeIterator iterator() {
- BasicNode node = startOfNodeLevel();
- return new NodeIterator(node);
- }
- /**
- * get node id
- * @return id of this node
- */
- public long getId() {
- return id;
- }
- /**
- * get next node of this node
- * @return next node
- */
- public BasicNode getNextNode()
- {
- return nextNode;
- }
- /**
- * get previous node of this node
- * @return previous node
- */
- public BasicNode getPervNode()
- {
- return pervNode;
- }
- /**
- * get parrent node of this node
- * @return parrent node
- */
- public BasicNode getParentNode()
- {
- return parentNode;
- }
- /**
- * get child level
- * @return first node of child nodes
- */
- public BasicNode getChildLevel()
- {
- if(childLevel != null)
- {
- while(childLevel.pervNode != null)
- {
- childLevel = childLevel.pervNode;
- }
- }
- return childLevel;
- }
- public void setNeedUpload()
- {
- synchronized(NeedUpload)
- {
- if(!NeedUpload.contains(this))
- {
- NeedUpload.add(this);
- }
- }
- }
- /**
- * set Node id,also it can destroy this node by seting id to minus value
- * @param id new id
- * @throws IOException no mapper
- */
- public void setId(long id) throws IOException
- {
- synchronized(this)
- {
- //defineded id
- if(id == 0 || !vaildity()) return;
- //not null
- if(id < 0)
- {
- //delete
- NodeDao.getCurrentMapper().deleteByPrimaryKey(this.id);
- //if database vaildity, it will going on.
- dropFromLevel();
- //delete all child nodes
- BasicNode node = this.getChildLevel();
- while(node != null)
- {
- BasicNode next = node.getNextNode();
- node.deleteNode();
- node = next;
- }
- }
- else if(NodeDao.state() != NodeDao.DaoState.Reading)
- {
- Nodeinfo data = getNodeInfo();
-
- data.setId(id);
-
- try
- {
- //id is primary key of node info, we can't modify the primary key by primary key, so it need delete first
- NodeDao.getCurrentMapper().insert(data);
- //delete
- if(defineded()) NodeDao.getCurrentMapper().deleteByPrimaryKey(this.id);
- }
- catch (IOException IOEx)
- {
- //no mapper
- throw IOEx;
- }
- catch (Exception e)
- {
- //sql errery
- return;
- }
- }
- else
- {
- InitAfterLoad(id);
- }
- this.id = id;
- }
- }
- /**
- * for override, invoke when load feom database
- * @param id currectt id information
- */
- private void InitAfterLoad(long id)
- {
- }
- /**
- * convert to NodeInfo data
- * @return Node info for sql upload
- */
- public Nodeinfo getNodeInfo()
- {
- //gen data for update database
- Nodeinfo data = new Nodeinfo();
- BasicNode node = null;
- //node id
- data.setId(getId());
- //next element
- node = getNextNode();
- if(node != null && node.vaildity())data.setNextId(node.getId());
- else data.setNextId(null);
- //perv element
- node = getPervNode();
- if(node != null && node.vaildity())data.setPrevId(node.getId());
- else data.setPrevId(null);
- //parent element
- node = getParentNode();
- if(node != null && node.vaildity())data.setParentId(node.getId());
- else data.setParentId(null);
- //chile level
- node = getChildLevel();
- if(node != null && node.vaildity())
- {
- node = node.startOfNodeLevel();
- data.setChildId(node.getId());
- }
- else data.setChildId(null);
- //node class
- data.setObjType(this.getClass().getName());
- return data;
- }
- /**
- * upload to database
- * @throws IOException no mapper
- */
- public void uploadNode() throws IOException
- {
- synchronized(this)
- {
- Nodeinfo data = getNodeInfo();
- NodeDao.getCurrentMapper().updateByPrimaryKey(data);
- }
- }
- /**
- * check node vaild
- * @return if is false it should not exists in database
- */
- public boolean vaildity()
- {
- if(getId() >= 0)
- {
- for (BasicNode basicNode : NeedUpload) {
- if(this.equals(basicNode) && basicNode != this) return false;
- }
- return true;
- }
- return false;
- }
- /**
- * check id defined statue
- * @return if is true, node id should defineded
- */
- public boolean defineded()
- {
- return vaildity() && getId() > 0;
- }
- /**
- * InnerHTML of tab
- * @return DOM Context.InnerHTML
- */
- public String tabContextInnerHTML()
- {
- return "id : " + getId();
- }
- /**
- * remove itselfs from its level
- */
- public void dropFromLevel()
- {
- synchronized(this)
- {
- if(this.nextNode != null)
- {
- this.nextNode.pervNode = this.pervNode;
- this.nextNode.setNeedUpload();
-
- }
- if(this.pervNode != null)
- {
- this.pervNode.nextNode = this.nextNode;
- this.pervNode.setNeedUpload();
- }
- else
- if(this.parentNode != null)
- {
- this.parentNode.childLevel = this.nextNode;
- this.parentNode.setNeedUpload();
- }
- this.parentNode = null;
- this.nextNode = null;
- this.pervNode = null;
- this.setNeedUpload();
- }
- }
-
- /**
- * instert a {@link #node} after this node
- * @param node node to instert/
- */
- public boolean insertNext(BasicNode node)
- {
- synchronized(this)
- {
- if(node != null && node.vaildity() && this.vaildity())
- {
- if(!node.subTreeContains(this))
- {
- //remove from its level
- node.dropFromLevel();
- //cache
- BasicNode nextNode = this.nextNode;
- //replace next
- this.nextNode = node;
- node.nextNode = nextNode;
- //replace perv
- node.pervNode = this;
- //set to same parent node
- node.parentNode = this.parentNode;
- //check if exiet
- if(nextNode != null)
- {
- nextNode.pervNode = node;
- nextNode.setNeedUpload();
- }
-
- this.setNeedUpload();
- return true;
- }
- }
- return false;
- }
- }
- /**
- * instert a {@link #node} before this node
- * @param node node to instert
- */
- public boolean insertPerv(BasicNode node)
- {
- synchronized(this)
- {
- if(node != null && node.vaildity() && this.vaildity())
- {
- if(!node.subTreeContains(this))
- {
- //remove from its level
- node.dropFromLevel();
- //cache
- BasicNode pervNode = this.pervNode;
- //replace next
- this.pervNode = node;
- node.pervNode = pervNode;
- //replace last
- node.nextNode = this;
- //set to same parent node
- node.parentNode = this.parentNode;
- //check if exiet
- if(pervNode != null)
- {
- pervNode.nextNode = node;
- pervNode.setNeedUpload();
- }
- else //remove if parrentNode exiet
- if(this.parentNode != null)
- {
- this.parentNode.childLevel = node;
- this.parentNode.setNeedUpload();
- }
-
- this.setNeedUpload();
- return true;
- }
- }
- return false;
- }
- }
- /**
- * replace current pos of its level
- * @param node node for replace
- */
- public boolean replaceBy(BasicNode node)
- {
- synchronized(this)
- {
- if(!vaildity()) return false;
- if(node != null && node.vaildity())
- {
- if(!node.subTreeContains(this))
- {
- node.dropFromLevel();
- node.parentNode = this.parentNode;
- node.nextNode = this.nextNode;
- node.pervNode = this.pervNode;
- this.dropFromLevel();
- if(node.nextNode != null)
- {
- node.nextNode.pervNode = node;
- }
- if(node.pervNode != null)
- {
- node.pervNode.nextNode = node;
- }
- else
- if(node.parentNode != null)
- {
- node.parentNode.childLevel = node;
- node.parentNode.setNeedUpload();
- }
- return true;
- }
- }
- else
- {
- this.dropFromLevel();
- return true;
- }
- return false;
- }
- }
- public boolean exchangeWith(BasicNode node)
- {
- synchronized(this)
- {
- if(!vaildity()) return false;
- if(node != null && node.vaildity())
- {
- if(!node.subTreeContains(this) && !this.subTreeContains(node))
- {
- //cache
- BasicNode next = node.nextNode;
- BasicNode perv = node.pervNode;
- BasicNode parent = node.parentNode;
-
- if(next == this)
- {
- next = this.pervNode;
- this.pervNode = this;
- }
- if(perv == this)
- {
- perv = this.nextNode;
- this.nextNode = this;
- }
- //set node to this
- node.nextNode = this.nextNode;
- node.pervNode = this.pervNode;
- node.parentNode = this.parentNode;
- node.setNeedUpload();
- //check near by node update
- if(node.nextNode != null)
- {
- node.nextNode.pervNode = node;
- node.nextNode.setNeedUpload();
- }
- if(node.pervNode != null)
- {
- node.pervNode.nextNode = node;
- node.pervNode.setNeedUpload();
- }
- else
- if(node.parentNode != null)
- {
- node.parentNode.childLevel = node;
- node.parentNode.setNeedUpload();
- }
-
- //set this to next
- this.nextNode = next;
- this.pervNode = perv;
- this.parentNode = parent;
- this.setNeedUpload();
- //check near by node update
- if(this.nextNode != null)
- {
- this.nextNode.pervNode = this;
- this.nextNode.setNeedUpload();
- }
- if(this.pervNode != null)
- {
- this.pervNode.nextNode = this;
- this.pervNode.setNeedUpload();
- }
- else
- if(this.parentNode != null)
- {
- this.parentNode.childLevel = this;
- this.parentNode.setNeedUpload();
- }
- return true;
- }
- }
- else
- {
- this.dropFromLevel();
- return true;
- }
- return false;
- }
- }
-
- /**
- * Level's start
- */
- public BasicNode startOfNodeLevel()
- {
- BasicNode node = this;
- while(node.pervNode != null)
- {
- node = node.pervNode;
- }
- return node;
- }
-
- /**
- * Level's end
- */
- public BasicNode endOfNodeLevel()
- {
- BasicNode node = this;
- while(node.nextNode != null)
- {
- node = node.nextNode;
- }
- return node;
- }
-
- /**
- * get root of node tree
- * @return node of the minimum level
- */
- public BasicNode rootNode()
- {
- BasicNode node = this;
- while(node.parentNode != null)
- {
- node = node.parentNode;
- }
- return node;
- }
- /**
- * replace child level to {@link #childLevel}
- * @param childLevel target
- * @return if success , return droped node else null
- */
- public BasicNode setChildLevel(BasicNode childLevel)
- {
- //is use as level, so we need to
- if(childLevel != null && vaildity() && childLevel.vaildity())
- {
- //save usage
- childLevel = childLevel.startOfNodeLevel();
- if(childLevel.subTreeContains(this.startOfNodeLevel())) return null;
- BasicNode result = this.childLevel;
- if(childLevel != null)
- {
- for(BasicNode node : childLevel)
- {
- node.parentNode = this;
- }
- }
- if(this.childLevel != null)
- {
- for(BasicNode node : this.childLevel)
- {
- node.parentNode = null;
- }
- }
- this.childLevel = childLevel;
- return result;
- }
- return null;
- }
- /**
- * check if level contains {@ling #node}
- * @param node node for check
- * @return {@value true} mean contains {@value false} mean not contains
- */
- public boolean levelContains(BasicNode node)
- {
- if(node != null)
- {
- if(node.parentNode != null && this.parentNode != null)
- {
- return node.parentNode == this.parentNode;
- }
- else
- {
- BasicNode cache1 = node;
- BasicNode cache2 = this;
- do
- {
- //check 2 node's perv node at same time
- if(cache1.equals(this) || cache2.equals(node))
- return true;
- if(cache1.pervNode != null)
- cache1 = cache1.pervNode;
- if(cache2.pervNode != null)
- cache2 = cache2.pervNode;
- }
- while(cache2.pervNode != null || cache1.pervNode != null);
- return cache1 == cache2;
- }
- }
- return false;
- }
- /**
- * check if node tree has node
- * @param node node for check
- * @return {@value true} mean contains {@value false} mean not contains
- */
- public boolean treeContains(BasicNode node)
- {
- if(node != null)
- {
- return node.rootNode().levelContains(this.rootNode());
- }
- return false;
- }
- /**
- * check if this node is a sub node of the node
- * @param node node for check
- * @return if this node is a sub node of the node, it will return true
- */
- public boolean subTreeContains(BasicNode node)
- {
- if(node != null)
- {
- do
- {
- if(node.equals(this))
- {
- return true;
- }
- node = node.parentNode;
- }
- while(node != null);
- }
- return false;
- }
- public long getLayout()
- {
- long result = 0;
- BasicNode node =this.getParentNode();
- while(node != null)
- {
- node = node.getParentNode();
- ++result;
- }
- return result;
- }
-
- @Override
- public String toString()
- {
- String result = this.getId() + "{ ";
- for(BasicNode node : this)
- {
- result += node.getId();
- if(node.getChildLevel() != null) result += "+";
- if(node.nextNode != null) result += " , ";
- }
- return result + " }";
- }
- public void deleteNode() throws IOException
- {
- this.setId(-1l);
- }
- /**
- * check level
- * @param levelA value a
- * @param levelB value b
- * @return if is same level,it will return true
- */
- public static boolean levelEqul(BasicNode levelA,BasicNode levelB)
- {
- return levelA.startOfNodeLevel().id == levelB.startOfNodeLevel().id;
- }
- @Override
- public boolean equals(Object o) {
- // TODO Auto-generated method stub
- BasicNode other = (BasicNode)o;
- if(other != null) return other.id == this.id;
- else return super.equals(o);
- }
- /**
- * check all loaded node and upload data
- * @throws IOException no sql mapper
- */
- public static void Commit() throws IOException
- {
- synchronized(NeedUpload)
- {
- for (BasicNode basicNode : NeedUpload)
- {
- basicNode.uploadNode();
- }
- NodeDao.getCurrentMapper().commit();
- NeedUpload.clear();
- }
- }
- public static BasicNode TryGetNotCommitNodeById(long id)
- {
- synchronized(NeedUpload)
- {
- for (BasicNode basicNode : NeedUpload)
- {
- if(basicNode.getId() == id)
- {
- return basicNode;
- }
- }
- return null;
- }
- }
- /**
- * Iterator of {@link #BasicNode}
- */
- class NodeIterator implements Iterator<BasicNode>
- {
- BasicNode next;
- private NodeIterator(BasicNode node)
- {
- next = node;
- }
- @Override
- public boolean hasNext() {
- return next != null;
- }
-
- @Override
- public BasicNode next() {
- BasicNode next = this.next;
- this.next = next.nextNode;
- return next;
- }
- }
- }
|