001package org.biopax.paxtools.controller;
002
003import org.apache.commons.collections15.set.CompositeSet;
004import org.biopax.paxtools.model.BioPAXElement;
005import org.biopax.paxtools.util.IllegalBioPAXArgumentException;
006
007import java.util.Set;
008
009/**
010 *  In OWL a single property can have multiple domains. This is not supported in OO. This class amends this by
011 *  using a Facade pattern. A Union property will act like a OWL property with a union domain but in fact is composed
012 *  of multiple single domain properties.
013 */
014public class UnionPropertyAccessor<D extends BioPAXElement,R> extends PropertyAccessorAdapter<D,R>
015{
016
017        Set<PropertyAccessor<? extends D, ? extends R>> union;
018
019                public UnionPropertyAccessor(Set<PropertyAccessor<? extends D, ? extends R>> union, Class<D> domain)
020        {
021                super(domain, (Class<R>) union.iterator().next().getRange(), true);
022                if(union == null || union.isEmpty())
023                {
024                        throw new IllegalBioPAXArgumentException("Empty set of editors. Can't create a union");
025                }
026                this.union = union;
027                this.multipleCardinality = union.iterator().next().isMultipleCardinality();
028        }
029
030        @Override public Set getValueFromBean(D bean) throws IllegalBioPAXArgumentException
031        {
032                CompositeSet valueFromBean =new CompositeSet();
033
034                for (PropertyAccessor atomicAccessor : union)
035                {
036                        if(atomicAccessor.getDomain().isAssignableFrom(bean.getModelInterface()))
037                        {
038                                valueFromBean.addComposited(atomicAccessor.getValueFromBean(bean));
039                        }
040                }
041                return valueFromBean;
042        }
043
044        @Override public boolean isUnknown(Object value)
045        {
046                return union.iterator().next().isUnknown(value);
047        }
048}