001/**
002 * Copyright (C) 2007 - 2016, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package org.dllearner.core;
020
021import java.util.Collection;
022import java.util.HashSet;
023import java.util.LinkedList;
024import java.util.List;
025import java.util.Set;
026
027import org.dllearner.utilities.datastructures.AbstractSearchTree;
028import org.dllearner.utilities.datastructures.SearchTreeNode;
029import org.semanticweb.owlapi.model.OWLClassExpression;
030
031public abstract class AbstractSearchTreeNode <T extends AbstractSearchTreeNode> implements SearchTreeNode {
032
033        protected Set< AbstractSearchTree<T> > trees = new HashSet<>();
034        protected T parent;
035        protected List<T> children = new LinkedList<>();
036
037        @Override
038        public abstract OWLClassExpression getExpression();
039
040        /**
041         * add a child node to this node
042         * @param node the child node
043         */
044        public void addChild(T node) {
045                node.setParent(this);
046                children.add(node);
047                node.notifyTrees(this.trees);
048        }
049        
050        /**
051         * set the parent of this node
052         * @param node parent node
053         */
054        protected void setParent(T node) {
055                if (this.parent == node) {
056                        return;
057                } else if (this.parent != null) {
058                        throw new Error("Parent already set on node");
059                }
060                this.parent = node;
061        }
062
063        /**
064         * internally used by the tree<->node contract to add this node to a set of trees
065         * @param trees the set of owning trees
066         */
067        public void notifyTrees( Collection<? extends AbstractSearchTree<T>> trees ) {
068                updatePrepareTree();
069                this.trees.addAll(trees);
070                notifyTree();
071        }
072
073        public void notifyTree( AbstractSearchTree<T> tree ) {
074                updatePrepareTree();
075                this.trees.add(tree);
076                notifyTree();
077        }
078        
079        private void notifyTree() {
080                for(AbstractSearchTree<T> tree : trees) {
081                        tree.notifyNode((T)this);
082                }
083        }
084        
085        private void updatePrepareTree() {
086                for(AbstractSearchTree<T> tree : trees) {
087                        tree.updatePrepare((T)this);
088                }
089        }
090
091        /**
092         * @return the parent
093         */
094        public T getParent() {
095                return parent;
096        }
097
098        /**
099         * @return the children
100         */
101        @Override
102        public Collection<T> getChildren() {
103                return children;
104        }
105}