001package org.biopax.paxtools.controller;
002
003import org.apache.commons.logging.Log;
004import org.apache.commons.logging.LogFactory;
005import org.biopax.paxtools.model.BioPAXElement;
006import org.biopax.paxtools.model.Model;
007import org.biopax.paxtools.model.level2.physicalEntityParticipant;
008import org.biopax.paxtools.model.level2.sequenceFeature;
009import org.biopax.paxtools.model.level2.sequenceParticipant;
010
011import java.net.URI;
012import java.net.URISyntaxException;
013import java.util.HashMap;
014import java.util.Map;
015import java.util.Set;
016
017/**
018 * This class contains methods for handling reused PEPs - a historically common problem in BioPAX L2 exports.
019 *
020 * Note: This class might eventually be deprecated as this problem is mostly fixed and BioPAX L3 is making L2
021 * obsolete.
022 */
023public class ReusedPEPHelper
024{
025    private static final Log log = LogFactory.getLog(ReusedPEPHelper.class);
026    private final Model model;
027
028    private final Map<physicalEntityParticipant, physicalEntityParticipant> duplicatedPeps;
029
030    /**
031     * @param model the biopax model
032     */
033    public ReusedPEPHelper(Model model)
034    {
035        this.model = model;
036
037        duplicatedPeps =
038                new HashMap<physicalEntityParticipant, physicalEntityParticipant>();
039
040    }
041
042    public Object fixReusedPEP(physicalEntityParticipant pep, BioPAXElement bpe)
043    {
044        if (duplicated(pep, bpe))
045        {
046                if(log.isWarnEnabled())
047                        log.warn(pep.getRDFId() +
048                     " is reused, duplicating it to fix");
049
050                String syntheticID = createSyntheticID(pep, bpe);
051            
052            if (model.containsID(syntheticID))
053            {
054                pep = (physicalEntityParticipant) model.getByID(syntheticID);
055            }
056            else
057            {
058                physicalEntityParticipant duplicated = (physicalEntityParticipant) model
059                        .addNew(pep.getModelInterface(), syntheticID);
060                duplicatedPeps.put(duplicated, pep);
061                pep = duplicated;
062            }
063        }
064        return pep;
065    }
066
067    private boolean duplicated(physicalEntityParticipant pep, BioPAXElement bpe)
068    {
069        boolean result = false;
070
071        if (!pep.isPARTICIPANTSof().isEmpty())
072        {
073            if (pep.isPARTICIPANTSof().iterator().next().equals(bpe))
074            {
075                if (log.isDebugEnabled())
076                {
077                    log.debug("Unexpected multiple participant statements");
078                }
079            }
080            else
081            {
082                result = true;
083            }
084        }
085        else if (pep.isCOMPONENTof() != null)
086        {
087            if (pep.isCOMPONENTof().equals(bpe))
088            {
089                if (log.isDebugEnabled())
090                {
091                    log.debug("Unexpected multiple participant statements");
092                }
093            }
094            else
095            {
096                result = true;
097            }
098        }
099
100        return result;
101
102    }
103
104    private String createSyntheticID(physicalEntityParticipant pep,
105                                     BioPAXElement bpe)
106    {
107        return "http://patywaycommons.org/synthetic"
108               + createDataStringFromURI(pep.getRDFId(),bpe.getRDFId());
109    }
110
111    private String createDataStringFromURI(String... uris)
112    {
113        String ssp = "";
114        String fragment = "";
115
116        for (String uri : uris)
117        {
118            try
119            {
120                URI suri = new URI(uri);
121                ssp += suri.getSchemeSpecificPart() + "_";
122                fragment += suri.getFragment() + "_";
123            }
124            catch (URISyntaxException e)
125            {
126                throw new RuntimeException(e);
127            }
128        }
129        return ssp + "#" + fragment;
130    }
131
132    public void copyPEPFields()
133    {
134        Set<physicalEntityParticipant> physicalEntityParticipants =
135                duplicatedPeps.keySet();
136        for (physicalEntityParticipant dup : physicalEntityParticipants)
137        {
138            copyPEPFields(dup, duplicatedPeps.get(dup));
139        }
140
141    }
142
143    private void copyPEPFields(physicalEntityParticipant duplicated,
144                               physicalEntityParticipant pep)
145    {
146        duplicated.setCELLULAR_LOCATION(pep.getCELLULAR_LOCATION());
147        duplicated.setCOMMENT(pep.getCOMMENT());
148        duplicated
149                .setSTOICHIOMETRIC_COEFFICIENT(
150                        pep.getSTOICHIOMETRIC_COEFFICIENT());
151        duplicated.setPHYSICAL_ENTITY(pep.getPHYSICAL_ENTITY());
152        if (pep instanceof sequenceParticipant)
153        {
154            Set<sequenceFeature> sfSet =
155                    ((sequenceParticipant) pep)
156                            .getSEQUENCE_FEATURE_LIST();
157            for (sequenceFeature sf : sfSet)
158            {
159                ((sequenceParticipant) duplicated)
160                        .addSEQUENCE_FEATURE_LIST(sf);
161            }
162        }
163        }
164
165}