001package org.biopax.paxtools.impl.level3;
002
003import org.biopax.paxtools.model.BioPAXElement;
004import org.biopax.paxtools.model.level3.BindingFeature;
005import org.hibernate.annotations.Cache;
006import org.hibernate.annotations.CacheConcurrencyStrategy;
007import org.hibernate.annotations.DynamicInsert;
008import org.hibernate.annotations.DynamicUpdate;
009import org.hibernate.annotations.Proxy;
010import org.hibernate.search.annotations.Indexed;
011
012import javax.persistence.Entity;
013import javax.persistence.OneToOne;
014import javax.persistence.Transient;
015
016@Entity
017@Proxy(proxyClass= BindingFeature.class)
018@Indexed
019@DynamicUpdate @DynamicInsert
020@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
021public class BindingFeatureImpl extends EntityFeatureImpl
022                implements BindingFeature
023{
024
025        private BindingFeature bindsTo;
026        private Boolean intramolecular;
027
028        //
029        // BioPAXElement interface implementation
030        //
031        ////////////////////////////////////////////////////////////////////////////
032
033        public BindingFeatureImpl() {
034        }
035        
036        
037        @Transient
038        public Class<? extends BindingFeature> getModelInterface()
039        {
040                return BindingFeature.class;
041        }
042
043
044        //
045        // nonCovalentFeature interface implementation
046        //
047        ////////////////////////////////////////////////////////////////////////////
048
049        // Property BOUND-TO
050
051        @OneToOne(targetEntity = BindingFeatureImpl.class)//, cascade={CascadeType.ALL})
052        public BindingFeature getBindsTo()
053        {
054                return bindsTo;
055        }
056
057        /**
058         * This method will set the paired binding feature that binds to this feature.
059         * This method will preserve the symmetric bidirectional semantics. If not-null old feature's
060         * bindsTo will be set to null and if not null new feature's binds to will set to this
061         * @param bindsTo paired binding feature.
062         */
063        public void setBindsTo(BindingFeature bindsTo)
064        {
065                //Check if we need to update
066                if (this.bindsTo != bindsTo)
067                {
068                        //ok go ahead - first get a pointer to the old binds to as we will swap this soon.
069                        BindingFeature old = this.bindsTo;
070                        //swap it
071                        this.bindsTo = bindsTo;
072
073                        //make sure old feature no longer points to this
074                        if (old != null && old.getBindsTo() == this)
075                        {
076                                old.setBindsTo(null);
077                        }
078                        //make sure new feature points to this
079                        if (!(this.bindsTo == null || this.bindsTo.getBindsTo() == this))
080                        {
081                                this.bindsTo.setBindsTo(this);
082                        }
083                }
084        }
085
086        public Boolean getIntraMolecular()
087        {
088                return intramolecular;
089        }
090
091        public void setIntraMolecular(Boolean intramolecular)
092        {
093                this.intramolecular = intramolecular;
094        }
095
096
097        @Override
098        protected boolean semanticallyEquivalent(BioPAXElement element)
099        {
100                if(!(element instanceof BindingFeature))
101                        return false;
102                
103                BindingFeature that = (BindingFeature) element;
104                
105                return  super.semanticallyEquivalent(element) 
106                                && this.getIntraMolecular() == that.getIntraMolecular() 
107                        && ((this.bindsTo == null) 
108                                        ? that.getBindsTo()==null 
109                                : this.bindsTo.equals(that.getBindsTo())
110                                ); //todo check equivalence sem.
111        }
112
113        @Override
114        public int equivalenceCode()
115        {
116                int value = super.equivalenceCode();
117                if(this.intramolecular!=null)
118                {
119                        value +=(this.intramolecular?29:17);
120                }
121                return value;
122        }
123}