001package org.biopax.paxtools.controller;
002
003import org.biopax.paxtools.model.BioPAXElement;
004import org.biopax.paxtools.model.Model;
005
006import java.util.Collection;
007import java.util.HashSet;
008import java.util.Set;
009
010/**
011 * This class is used for getting a valid subgraph from a set of BioPAX elements. For instance, if a
012 * BioPAX graph contains a complex with some members, but the subgraph contains the same complex
013 * without the members, then it is not valid. Similarly, an interaction is only valid with its
014 * participants; however, including its controls is optional.
015 *
016 * @author Ozgun Babur
017 */
018public class Completer implements Visitor
019{
020        protected TraverserBilinked traverser;
021
022        private final Set<BioPAXElement> completed;
023
024        public Completer(EditorMap map)
025        {
026                this.traverser = new TraverserBilinked(map, this, new PropertyFilterBilinked()
027                {
028                        public boolean filter(PropertyEditor editor)
029                        {
030                                return editor instanceof ObjectPropertyEditor &&
031                                        ((ObjectPropertyEditor) editor).isCompleteForward();
032                        }
033
034                        public boolean filterInverse(PropertyEditor editor)
035                        {
036                                return editor instanceof ObjectPropertyEditor &&
037                                        ((ObjectPropertyEditor) editor).isCompleteBackward();
038                        }
039                });
040
041                completed = new HashSet<BioPAXElement>();
042        }
043
044        public Set<BioPAXElement> complete(Collection<BioPAXElement> elements, Model model)
045        {
046                completed.clear();
047
048                for (BioPAXElement element : elements)
049                {
050                        if (!completed.contains(element))
051                        {
052                                completed.add(element);
053                                traverser.traverse(element, model);
054                        }
055                }
056
057                return completed;
058        }
059
060        public void visit(BioPAXElement domain, Object range, Model model, PropertyEditor editor)
061        {
062                if (range instanceof BioPAXElement) //!=null works too (because of prop. filters)
063                {
064                        BioPAXElement element = (BioPAXElement) range;
065                        if (!completed.contains(element))
066                        {
067                                completed.add(element);
068                                traverser.traverse(element, model);
069                        }
070                }
071        }
072}