package uk.ac.ebi.ep.adapter.intenz; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Hashtable; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import uk.ac.ebi.ep.adapter.intenz.IntenzCallable.GetCofactorsCaller; import uk.ac.ebi.ep.adapter.intenz.IntenzCallable.GetEcHierarchyCaller; import uk.ac.ebi.ep.adapter.intenz.IntenzCallable.GetIntenzCaller; import uk.ac.ebi.ep.adapter.intenz.IntenzCallable.GetSynonymsCaller; import uk.ac.ebi.ep.adapter.intenz.util.IntenzUtil; import uk.ac.ebi.ep.enzyme.model.Enzyme; import uk.ac.ebi.ep.enzyme.model.EnzymeHierarchy; import uk.ac.ebi.ep.enzyme.model.EnzymeModel; import uk.ac.ebi.ep.enzyme.model.Molecule; import uk.ac.ebi.ep.search.exception.MultiThreadingException; import uk.ac.ebi.intenz.xml.jaxb.Intenz; import uk.ac.ebi.util.result.DataTypeConverter; /** * * @since 1.0 * @version $LastChangedRevision$ <br/> * $LastChangedDate$ <br/> * $Author$ * @author $Author$ */ public class IntenzAdapter implements IintenzAdapter{ private IntenzConfig config; private static final Logger LOGGER = Logger.getLogger(IntenzAdapter.class); public IntenzConfig getConfig() { return config; } public void setConfig(IntenzConfig config) { this.config = config; } public IntenzAdapter() { config = new IntenzConfig(); } public Map<String, Set<String>> getSynonyms(Set<String> ecNumbers) throws MultiThreadingException { ExecutorService pool = Executors.newCachedThreadPool(); System.out.println("config "+ config); CompletionService<Set<String>> ecs = new ExecutorCompletionService<Set<String>>(pool); Map<String, Set<String>> resultMap = new Hashtable<String, Set<String>>(); Map<Future<Set<String>>, String> future2ec = new HashMap<Future<Set<String>>, String>(); try { for (String ecNumber:ecNumbers) { // Avoid dashes, there are no IntEnzXML files for those: if (ecNumber.indexOf('-') > -1) continue; Callable<Set<String>> callable = new GetSynonymsCaller( IntenzUtil.createIntenzEntryUrl( config.getIntenzXmlUrl(), ecNumber)); future2ec.put(ecs.submit(callable), ecNumber); } for (int i = 0; i < future2ec.size(); i++){ try { Future<Set<String>> future = ecs.poll(config.getTimeout(), TimeUnit.MILLISECONDS); String ec = future2ec.get(future); if (future != null){ Set<String> synonyms = future.get(); if (synonyms.size() > 0) { resultMap.put(ec, synonyms); } } else { LOGGER.warn("Job not returned getting synonyms!"); } } catch (Exception e) { // Don't stop the others LOGGER.error("Getting synonyms", e); } } // LOGGER.debug("SEARCH synonyms after getting futures"); } finally { pool.shutdown(); } return resultMap; } public EnzymeModel getEnzymeDetails(EnzymeModel enzymeModel) throws MultiThreadingException { Set<String> ecList = DataTypeConverter.getUniprotEcs(enzymeModel); //DataTypeConverter.getUniprotEcs(enzymeModel); //Synonyms are merged into one list if there are more than 1 ec number Set<String> synonyms = new LinkedHashSet<String>(); // LOGGER.debug("SEARCH before getIntenz"); List<Intenz> intenzList = getIntenz(ecList); // LOGGER.debug("SEARCH after getIntenz"); List<EnzymeHierarchy> enzymeHierarchies = new ArrayList<EnzymeHierarchy>(); if (intenzList.size() > 0) { // LOGGER.debug("SEARCH before intenzList"); for (Intenz intenz : intenzList) { GetSynonymsCaller synonymsCaller = new GetSynonymsCaller(); GetEcHierarchyCaller ecCaller = new GetEcHierarchyCaller(); // LOGGER.debug("SEARCH before getSynonyms"); synonyms.addAll(synonymsCaller.getSynonyms(intenz)); // LOGGER.debug("SEARCH before getEcHierarchy"); EnzymeHierarchy enzymeHierarchy = ecCaller.getEcHierarchy(intenz); if (enzymeHierarchy != null) { enzymeHierarchies.add(enzymeHierarchy); } // LOGGER.debug("SEARCH after getEcHierarchy"); } // LOGGER.debug("SEARCH after intenzList"); if (synonyms.size() > 0) { @SuppressWarnings("unchecked") Collection<String> newSynonyms = CollectionUtils.subtract( synonyms, enzymeModel.getSynonym()); enzymeModel.getSynonym().addAll(newSynonyms); } //Enzyme has previously initiatized to set Sequence info //Enzyme enzyme = new Enzyme(); if (enzymeModel.getEnzyme() == null) { Enzyme enzyme = new Enzyme(); enzymeModel.setEnzyme(enzyme); } if (enzymeHierarchies.size() > 0) { enzymeModel.getEnzyme().setEchierarchies(enzymeHierarchies); } } return enzymeModel; } public List<Intenz> getIntenz(Collection<String> ecList) { List<Intenz> results = new ArrayList<Intenz>(); ExecutorService pool = Executors.newCachedThreadPool(); CompletionService<Intenz> ecs = new ExecutorCompletionService<Intenz>(pool); try { // LOGGER.debug("SEARCH before callables loop"); List<String> incompleteEcs = new ArrayList<String>(); for (String ec : ecList) { if (ec.indexOf('-') > -1){ incompleteEcs.add(ec); continue; // ignore incomplete ECs } Callable<Intenz> callable = new GetIntenzCaller( IntenzUtil.createIntenzEntryUrl( config.getIntenzXmlUrl(), ec)); ecs.submit(callable); } if (!incompleteEcs.isEmpty()){ LOGGER.warn("Unable to retrieve info from IntEnz on " + incompleteEcs); } // LOGGER.debug("SEARCH before futures loop"); int completeEcs = ecList.size() - incompleteEcs.size(); for (int i = 0; i < completeEcs; i++) { try { Future<Intenz> future = ecs.poll(config.getTimeout(), TimeUnit.MILLISECONDS); if (future != null) { Intenz intenz = future.get(); if (intenz != null) results.add(intenz); } else { LOGGER.warn("Job not returned!"); } } catch (Exception e){ // Don't stop the others LOGGER.error("Callable " + (i+1) + " of " + completeEcs + " - " + e.getMessage(), e); } } // LOGGER.debug("SEARCH after futures loop"); } finally { pool.shutdown(); } return results; } public Collection<Molecule> getCofactors(String ec) { // Incomplete EC numbers won't get anything from IntEnzXML: if (ec.indexOf('-') > -1) return null; Collection<Molecule> cofactors = null; GetCofactorsCaller cofactorsCaller = new GetCofactorsCaller( IntenzUtil.createIntenzEntryUrl(config.getIntenzXmlUrl(), ec)); try { cofactors = cofactorsCaller.call(); } catch (Exception e) { LOGGER.error("Unable to retrieve cofactors for " + ec, e); } return cofactors; } public Collection<Molecule> getCofactors(Collection<String> ecs) { Collection<Molecule> cofactors = null; for (String ec : ecs) { if (ec.indexOf('-') > -1) continue; final Collection<Molecule> newCofactors = getCofactors(ec); if (cofactors == null){ cofactors = newCofactors; } else if (newCofactors != null){ cofactors.addAll(newCofactors); } } return cofactors; } }