001package org.biopax.paxtools.query.wrapperL3;
002
003import org.apache.commons.logging.Log;
004import org.apache.commons.logging.LogFactory;
005import org.biopax.paxtools.model.BioPAXElement;
006import org.biopax.paxtools.model.BioPAXLevel;
007import org.biopax.paxtools.model.Model;
008import org.biopax.paxtools.model.level3.*;
009import org.biopax.paxtools.query.model.AbstractGraph;
010import org.biopax.paxtools.query.model.GraphObject;
011import org.biopax.paxtools.query.model.Node;
012
013import java.util.*;
014
015/**
016 * Wrapper for L3 Graphs.
017 *
018 * @author Ozgun Babur
019 */
020public class GraphL3 extends AbstractGraph 
021{
022        /**
023         * The model to be wrapped.
024         */
025        protected Model model;
026
027        protected List<Filter> filters;
028
029        /**
030         * Log for logging.
031         */
032        protected final Log log = LogFactory.getLog(GraphL3.class);
033
034        /**
035         * Constructor with the model and the IDs of the ubiquitous molecules. IDs can be null, meaning
036         * no labeling is desired.
037         * @param model Model to wrap
038         * @param filters for filtering graph elements
039         */
040        public GraphL3(Model model, Filter... filters)
041        {
042                assert model.getLevel() == BioPAXLevel.L3;
043                this.model = model;
044
045                if (filters.length > 0)
046                {
047                        this.filters = Arrays.asList(filters);
048                }
049        }
050
051        /**
052         * There must be no filter opposing to traverse this object to traverse it.
053         * @param ele element to check
054         * @return true if ok to traverse
055         */
056        private boolean passesFilters(Level3Element ele)
057        {
058                if (filters == null) return true;
059
060                for (Filter filter : filters)
061                {
062                        if (!filter.okToTraverse(ele)) return false;
063                }
064                return true;
065        }
066
067        /**
068         * This method creates a wrapper for every wrappable L3 element.
069         * @param obj Object to wrap
070         * @return The wrapper
071         */
072        @Override
073        public Node wrap(Object obj)
074        {
075                // Check if the object is level3
076                if (!(obj instanceof Level3Element)) throw new IllegalArgumentException(
077                        "An object other than a Level3Element is trying to be wrapped: " + obj);
078
079                // Check if the object passes the filter
080                if (!passesFilters((Level3Element) obj)) return null;
081
082                // Wrap if traversible
083
084                if (obj instanceof PhysicalEntity)
085                {
086                        return new PhysicalEntityWrapper((PhysicalEntity) obj, this);
087                }
088                else if (obj instanceof Conversion)
089                {
090                        return new ConversionWrapper((Conversion) obj, this);
091                }
092                else if (obj instanceof TemplateReaction)
093                {
094                        return new TemplateReactionWrapper((TemplateReaction) obj, this);
095                }
096                else if (obj instanceof Control)
097                {
098                        return new ControlWrapper((Control) obj, this);
099                }
100                else
101                {
102                        if (log.isWarnEnabled())
103                        {
104                                log.warn("Invalid BioPAX object to wrap as node. Ignoring: " + obj);
105                        }
106                        return null;
107                }
108        }
109
110        /**
111         * RDF IDs of elements is used as key in the object map.
112         * @param wrapped Object to wrap
113         * @return Key
114         */
115        @Override
116        public String getKey(Object wrapped)
117        {
118                if (wrapped instanceof BioPAXElement)
119                {
120                        return ((BioPAXElement) wrapped).getRDFId();
121                }
122
123                throw new IllegalArgumentException("Object cannot be wrapped: " + wrapped);
124        }
125
126        /**
127         * Gets wrappers of given elements
128         * @param objects Wrapped objects
129         * @return wrappers
130         */
131        public Set<Node> getWrapperSet(Set<?> objects)
132        {
133                Set<Node> wrapped = new HashSet<Node>();
134
135                for (Object object : objects)
136                {
137                        Node node = (Node) getGraphObject(object);
138                        if (node != null)
139                        {
140                                wrapped.add(node);
141                        }
142                }
143                return wrapped;
144        }
145
146        /**
147         * Gets an element-to-wrapper map for the given elements.
148         * @param objects Wrapped objects
149         * @return object-to-wrapper map
150         */
151        public Map<Object, Node> getWrapperMap(Set<?> objects)
152        {
153                Map<Object, Node> map = new HashMap<Object, Node>();
154
155                for (Object object : objects)
156                {
157                        Node node = (Node) getGraphObject(object);
158                        if (node != null)
159                        {
160                                map.put(object, node);
161                        }
162                }
163                return map;
164        }
165
166        /**
167         * Gets the wrapped objects of the given wrappers.
168         * @param wrappers Wrappers
169         * @return Wrapped objects
170         */
171        public Set<Object> getWrappedSet(Set<? extends GraphObject> wrappers)
172        {
173                Set<Object> objects = new HashSet<Object>();
174
175                for (GraphObject wrapper : wrappers)
176                {
177                        if (wrapper instanceof PhysicalEntityWrapper)
178                        {
179                                objects.add(((PhysicalEntityWrapper) wrapper).getPhysicalEntity());
180                        }
181                        else if (wrapper instanceof ConversionWrapper)
182                        {
183                                objects.add(((ConversionWrapper) wrapper).getConversion());
184                        }
185                        else if (wrapper instanceof TemplateReactionWrapper)
186                        {
187                                objects.add(((TemplateReactionWrapper) wrapper).getTempReac());
188                        }
189                        else if (wrapper instanceof ControlWrapper)
190                        {
191                                objects.add(((ControlWrapper) wrapper).getControl());
192                        }
193                }
194                return objects;
195        }
196
197        /**
198         * @return Wrapped model
199         */
200        public Model getModel()
201        {
202                return model;
203        }
204}