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}