X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FSequenceFetcher.java;h=3fa00f5d491c1a6583f1b56db8bde4cbfe0b5035;hb=797df64fa2a0a30773d0f48f5494d4155e5a8be3;hp=c82f3831e7de613470b202e893f362b32dd2f037;hpb=3b24654f2ada868e8a3771427cc9b180f78f2020;p=jalview.git diff --git a/src/jalview/gui/SequenceFetcher.java b/src/jalview/gui/SequenceFetcher.java index c82f383..3fa00f5 100755 --- a/src/jalview/gui/SequenceFetcher.java +++ b/src/jalview/gui/SequenceFetcher.java @@ -1,20 +1,19 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer - * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7) + * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Jalview. If not, see . */ package jalview.gui; @@ -59,6 +58,76 @@ public class SequenceFetcher extends JPanel implements Runnable private static String dasRegistry = null; + private static boolean _initingFetcher = false; + + private static Thread initingThread = null; + + /** + * Blocking method that initialises and returns the shared instance of the + * SequenceFetcher client + * + * @param guiWindow + * - where the initialisation delay message should be shown + * @return the singleton instance of the sequence fetcher client + */ + public static jalview.ws.SequenceFetcher getSequenceFetcherSingleton( + final IProgressIndicator guiWindow) + { + if (_initingFetcher && initingThread != null && initingThread.isAlive()) + { + if (guiWindow != null) + { + guiWindow.setProgressBar( + "Waiting for Sequence Database Fetchers to initialise", + Thread.currentThread().hashCode()); + } + // initting happening on another thread - so wait around to see if it + // finishes. + while (_initingFetcher && initingThread != null + && initingThread.isAlive()) + { + try + { + Thread.sleep(10); + } catch (Exception e) + { + } + ; + } + if (guiWindow != null) + { + guiWindow.setProgressBar( + "Waiting for Sequence Database Fetchers to initialise", + Thread.currentThread().hashCode()); + } + } + if (sfetch == null + || dasRegistry != DasSourceBrowser.getDasRegistryURL()) + { + _initingFetcher = true; + initingThread = Thread.currentThread(); + /** + * give a visual indication that sequence fetcher construction is occuring + */ + if (guiWindow != null) + { + guiWindow.setProgressBar("Initialising Sequence Database Fetchers", + Thread.currentThread().hashCode()); + } + dasRegistry = DasSourceBrowser.getDasRegistryURL(); + jalview.ws.SequenceFetcher sf = new jalview.ws.SequenceFetcher(); + if (guiWindow != null) + { + guiWindow.setProgressBar("Initialising Sequence Database Fetchers", + Thread.currentThread().hashCode()); + } + sfetch = sf; + _initingFetcher = false; + initingThread = null; + } + return sfetch; + } + public SequenceFetcher(IProgressIndicator guiIndic) { final IProgressIndicator guiWindow = guiIndic; @@ -69,31 +138,27 @@ public class SequenceFetcher extends JPanel implements Runnable public void run() { - if (sfetch == null - || dasRegistry != DasSourceBrowser.getDasRegistryURL()) + if (getSequenceFetcherSingleton(guiWindow) != null) { - /** - * give a visual indication that sequence fetcher construction is - * occuring - */ - if (guiWindow != null) - { - guiWindow.setProgressBar( - "Initialising Sequence Database Fetchers", this - .hashCode()); - } - dasRegistry = DasSourceBrowser.getDasRegistryURL(); - jalview.ws.SequenceFetcher sf = new jalview.ws.SequenceFetcher(); - if (guiWindow != null) + us.initGui(guiWindow); + } + else + { + javax.swing.SwingUtilities.invokeLater(new Runnable() { - guiWindow.setProgressBar( - "Initialising Sequence Database Fetchers", this - .hashCode()); - } - sfetch = sf; - + public void run() + { + JOptionPane + .showInternalMessageDialog( + Desktop.desktop, + "Could not create the sequence fetcher client. Check error logs for details.", + "Couldn't create SequenceFetcher", + JOptionPane.ERROR_MESSAGE); + } + }); + + // raise warning dialog } - us.initGui(guiWindow); } }); sf.start(); @@ -146,11 +211,11 @@ public class SequenceFetcher extends JPanel implements Runnable frame.setContentPane(this); if (new jalview.util.Platform().isAMac()) { - Desktop.addInternalFrame(frame, getFrameTitle(), 400, 140); + Desktop.addInternalFrame(frame, getFrameTitle(), 400, 240); } else { - Desktop.addInternalFrame(frame, getFrameTitle(), 400, 125); + Desktop.addInternalFrame(frame, getFrameTitle(), 400, 180); } } @@ -164,12 +229,16 @@ public class SequenceFetcher extends JPanel implements Runnable { this.setLayout(borderLayout2); - database.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); + database.setFont(JvSwingUtils.getLabelFont()); dbeg.setFont(new java.awt.Font("Verdana", Font.BOLD, 11)); jLabel1.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11)); jLabel1.setHorizontalAlignment(SwingConstants.CENTER); - jLabel1 - .setText("Separate multiple accession ids with semi colon \";\""); + jLabel1.setText("Separate multiple accession ids with semi colon \";\""); + + replacePunctuation.setHorizontalAlignment(SwingConstants.CENTER); + replacePunctuation + .setFont(new java.awt.Font("Verdana", Font.ITALIC, 11)); + replacePunctuation.setText("Replace commas with semi-colons"); ok.setText("OK"); ok.addActionListener(new ActionListener() { @@ -203,7 +272,7 @@ public class SequenceFetcher extends JPanel implements Runnable close_actionPerformed(e); } }); - textArea.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); + textArea.setFont(JvSwingUtils.getLabelFont()); textArea.setLineWrap(true); textArea.addKeyListener(new KeyAdapter() { @@ -232,10 +301,13 @@ public class SequenceFetcher extends JPanel implements Runnable { db = sfetch.getSourceProxy((String) sources.get(database .getSelectedItem())); - dbeg.setText("Example query: " + db.getTestQuery()); + String eq = db.getTestQuery(); + dbeg.setText("Example query: " + eq); + replacePunctuation.setEnabled(!(eq != null && eq.indexOf(",") > -1)); } catch (Exception ex) { dbeg.setText(""); + replacePunctuation.setEnabled(true); } jPanel2.repaint(); } @@ -243,7 +315,10 @@ public class SequenceFetcher extends JPanel implements Runnable dbeg.setText(""); jPanel2.add(database, java.awt.BorderLayout.NORTH); jPanel2.add(dbeg, java.awt.BorderLayout.CENTER); - jPanel2.add(jLabel1, java.awt.BorderLayout.SOUTH); + JPanel jPanel2a = new JPanel(new BorderLayout()); + jPanel2a.add(jLabel1, java.awt.BorderLayout.NORTH); + jPanel2a.add(replacePunctuation, java.awt.BorderLayout.SOUTH); + jPanel2.add(jPanel2a, java.awt.BorderLayout.SOUTH); // jPanel2.setPreferredSize(new Dimension()) jPanel3.add(jScrollPane1, java.awt.BorderLayout.CENTER); this.add(jPanel1, java.awt.BorderLayout.SOUTH); @@ -279,6 +354,8 @@ public class SequenceFetcher extends JPanel implements Runnable JLabel jLabel1 = new JLabel(); + JCheckBox replacePunctuation = new JCheckBox(); + JButton ok = new JButton(); JButton clear = new JButton(); @@ -341,9 +418,23 @@ public class SequenceFetcher extends JPanel implements Runnable { error += "Please select the source database\n"; } - com.stevesoft.pat.Regex empty = new com.stevesoft.pat.Regex("\\s+", ""); + // TODO: make this transformation more configurable + com.stevesoft.pat.Regex empty; + if (replacePunctuation.isEnabled() && replacePunctuation.isSelected()) + { + empty = new com.stevesoft.pat.Regex( + // replace commas and spaces with a semicolon + "(\\s|[,; ])+", ";"); + } + else + { + // just turn spaces and semicolons into single semicolons + empty = new com.stevesoft.pat.Regex("(\\s|[; ])+", ";"); + } textArea.setText(empty.replaceAll(textArea.getText())); - if (textArea.getText().length() == 0) + // see if there's anthing to search with + if (!new com.stevesoft.pat.Regex("[A-Za-z0-9_.]").search(textArea + .getText())) { error += "Please enter a (semi-colon separated list of) database id(s)"; } @@ -353,15 +444,82 @@ public class SequenceFetcher extends JPanel implements Runnable resetDialog(); return; } - AlignmentI aresult = null; + ArrayList aresultq=new ArrayList(); + ArrayList aresult = new ArrayList(); + Object source = database.getSelectedItem(); + Enumeration en = new StringTokenizer(textArea.getText(), ";"); + boolean isAliSource=false; try { - guiWindow.setProgressBar("Fetching Sequences from " - + database.getSelectedItem(), Thread.currentThread() - .hashCode()); - aresult = sfetch.getSourceProxy( - (String) sources.get(database.getSelectedItem())) - .getSequenceRecords(textArea.getText()); + guiWindow.setProgressBar( + "Fetching Sequences from " + database.getSelectedItem(), + Thread.currentThread().hashCode()); + DbSourceProxy proxy = sfetch.getSourceProxy((String) sources + .get(source)); + isAliSource = proxy.isA(DBRefSource.ALIGNMENTDB); + if (proxy.getAccessionSeparator() == null) + { + while (en.hasMoreElements()) + { + String item = (String) en.nextElement(); + try + { + if (aresult != null) + { + try + { + // give the server a chance to breathe + Thread.sleep(5); + } catch (Exception e) + { + // + } + + } + + AlignmentI indres = null; + try + { + indres = proxy.getSequenceRecords(item); + } catch (OutOfMemoryError oome) + { + new OOMWarning("fetching " + item + " from " + + database.getSelectedItem(), oome, this); + } + if (indres != null) + { + aresultq.add(item); + aresult.add(indres); + } + } catch (Exception e) + { + jalview.bin.Cache.log.info("Error retrieving " + item + + " from " + source, e); + } + } + } + else + { + StringBuffer multiacc = new StringBuffer(); + while (en.hasMoreElements()) + { + multiacc.append(en.nextElement()); + if (en.hasMoreElements()) + { + multiacc.append(proxy.getAccessionSeparator()); + } + } + try + { + aresultq.add(multiacc.toString()); + aresult.add(proxy.getSequenceRecords(multiacc.toString())); + } catch (OutOfMemoryError oome) + { + new OOMWarning("fetching " + multiacc + " from " + + database.getSelectedItem(), oome, this); + } + + } } catch (Exception e) { @@ -374,6 +532,7 @@ public class SequenceFetcher extends JPanel implements Runnable e.printStackTrace(); } catch (OutOfMemoryError e) { + // resets dialog box - so we don't use OOMwarning here. showErrorMessage("Out of Memory when retrieving " + textArea.getText() + " from " @@ -386,11 +545,27 @@ public class SequenceFetcher extends JPanel implements Runnable + " from " + database.getSelectedItem()); e.printStackTrace(); } - guiWindow.setProgressBar(null, Thread.currentThread().hashCode()); - if (aresult != null) + if (aresult != null && aresult.size()>0) { - parseResult(aresult, null, null); + AlignmentI ar=null; + if (isAliSource) { + // new window for each result + while (aresult.size()>0) + { + parseResult(aresult.remove(0), aresultq.remove(0)+" "+getDefaultRetrievalTitle(), null); + } + } else { + // concatenate all results in one window + while (aresult.size()>0) + { + if (ar==null) { ar = aresult.remove(0);} + else { ar.append(aresult.remove(0)); }; + } + parseResult(ar, null, null); + } } + // only remove visual delay after we finished parsing. + guiWindow.setProgressBar(null, Thread.currentThread().hashCode()); resetDialog(); } @@ -404,15 +579,15 @@ public class SequenceFetcher extends JPanel implements Runnable * jalview.datamodel.DBRefSource.EMBLCDS : jalview.datamodel.DBRefSource.EMBL; * * StringTokenizer st = new StringTokenizer(textArea.getText(), ";"); - * SequenceI[] seqs = null; while(st.hasMoreTokens()) { EBIFetchClient dbFetch = - * new EBIFetchClient(); String qry = + * SequenceI[] seqs = null; while(st.hasMoreTokens()) { EBIFetchClient dbFetch + * = new EBIFetchClient(); String qry = * database.getSelectedItem().toString().toLowerCase( ) + ":" + * st.nextToken(); File reply = dbFetch.fetchDataAsFile( qry, "emblxml",null); * * jalview.datamodel.xdb.embl.EmblFile efile=null; if (reply != null && * reply.exists()) { efile = - * jalview.datamodel.xdb.embl.EmblFile.getEmblFile(reply); } if (efile!=null) { - * for (Iterator i=efile.getEntries().iterator(); i.hasNext(); ) { EmblEntry + * jalview.datamodel.xdb.embl.EmblFile.getEmblFile(reply); } if (efile!=null) + * { for (Iterator i=efile.getEntries().iterator(); i.hasNext(); ) { EmblEntry * entry = (EmblEntry) i.next(); SequenceI[] seqparts = * entry.getSequences(false,true, DBRefSource); if (seqparts!=null) { * SequenceI[] newseqs = null; int si=0; if (seqs==null) { newseqs = new @@ -422,33 +597,34 @@ public class SequenceFetcher extends JPanel implements Runnable * for (;si0) { if (parseResult(new Alignment(seqs), null, null)!=null) { - * result.append("# Successfully parsed the "+database.getSelectedItem()+" - * Queries into an Alignment"); } } } else if + * seqs=newseqs; } } } else { result.append("# no response for "+qry); } } if + * (seqs!=null && seqs.length>0) { if (parseResult(new Alignment(seqs), null, + * null)!=null) { result.append("# Successfully parsed the + * "+database.getSelectedItem()+" Queries into an Alignment"); } } } else if * (database.getSelectedItem().equals("PDB")) { StringTokenizer qset = new * StringTokenizer(textArea.getText(), ";"); String query; SequenceI[] seqs = * null; while (qset.hasMoreTokens() && ((query = qset.nextToken())!=null)) { * SequenceI[] seqparts = getPDBFile(query.toUpperCase()); if (seqparts != * null) { if (seqs == null) { seqs = seqparts; } else { SequenceI[] newseqs = * new SequenceI[seqs.length+seqparts.length]; int i=0; for (; i < - * seqs.length; i++) { newseqs[i] = seqs[i]; seqs[i] = null; } for (int j=0;j 0) { if (parseResult(new Alignment(seqs), null, null)!=null) { - * result.append( "# Successfully parsed the PDB File Queries into an + * seqs.length; i++) { newseqs[i] = seqs[i]; seqs[i] = null; } for (int + * j=0;j 0) { if (parseResult(new + * Alignment(seqs), null, null)!=null) { result.append( "# Successfully parsed + * the PDB File Queries into an * Alignment"); } } } else if( database.getSelectedItem().equals("PFAM")) { * try { result.append(new FastaFile( * "http://www.sanger.ac.uk/cgi-bin/Pfam/getalignment.pl?format=fal&acc=" + * textArea.getText().toUpperCase(), "URL").print() ); * * if(result.length()>0) { parseResult( result.toString(), - * textArea.getText().toUpperCase() ); } - * } catch (java.io.IOException ex) { result = null; } } + * textArea.getText().toUpperCase() ); } } catch (java.io.IOException ex) { + * result = null; } } * * if (result == null || result.length() == 0) { showErrorMessage("Error - * retrieving " + textArea.getText() + " from " + database.getSelectedItem()); } + * retrieving " + textArea.getText() + " from " + database.getSelectedItem()); + * } * * resetDialog(); return; } * @@ -472,8 +648,7 @@ public class SequenceFetcher extends JPanel implements Runnable * entry.getProtein().getName().elementAt(0)); } * * result.append(name + "\n" + entry.getUniprotSequence().getContent() + - * "\n"); - * } + * "\n"); } * * //Then read in the features and apply them to the dataset Alignment al = * parseResult(result.toString(), null); for (int i = 0; i < entries.size(); @@ -496,15 +671,16 @@ public class SequenceFetcher extends JPanel implements Runnable * (entry.getFeature() != null) { e = entry.getFeature().elements(); while * (e.hasMoreElements()) { SequenceFeature sf = (SequenceFeature) * e.nextElement(); sf.setFeatureGroup("Uniprot"); - * al.getSequenceAt(i).getDatasetSequence().addSequenceFeature( sf ); } } } } } + * al.getSequenceAt(i).getDatasetSequence().addSequenceFeature( sf ); } } } } + * } * * SequenceI[] getPDBFile(String id) { Vector result = new Vector(); String * chain = null; if (id.indexOf(":") > -1) { chain = * id.substring(id.indexOf(":") + 1); id = id.substring(0, id.indexOf(":")); } * * EBIFetchClient ebi = new EBIFetchClient(); String file = - * ebi.fetchDataAsFile("pdb:" + id, "pdb", "raw"). getAbsolutePath(); if (file == - * null) { return null; } try { PDBfile pdbfile = new PDBfile(file, + * ebi.fetchDataAsFile("pdb:" + id, "pdb", "raw"). getAbsolutePath(); if (file + * == null) { return null; } try { PDBfile pdbfile = new PDBfile(file, * jalview.io.AppletFormatAdapter.FILE); for (int i = 0; i < * pdbfile.chains.size(); i++) { if (chain == null || ( (PDBChain) * pdbfile.chains.elementAt(i)).id. toUpperCase().equals(chain)) { PDBChain @@ -517,17 +693,17 @@ public class SequenceFetcher extends JPanel implements Runnable * Construct the PDBEntry entry.setId(id); if (entry.getProperty() == null) * entry.setProperty(new Hashtable()); entry.getProperty().put("chains", * pdbchain.id + "=" + sq.getStart() + "-" + sq.getEnd()); - * sq.getDatasetSequence().addPDBId(entry); - * // Add PDB DB Refs // We make a DBRefEtntry because we have obtained the - * PDB file from a verifiable source // JBPNote - PDB DBRefEntry should also - * carry the chain and mapping information DBRefEntry dbentry = new + * sq.getDatasetSequence().addPDBId(entry); // Add PDB DB Refs // We make a + * DBRefEtntry because we have obtained the PDB file from a verifiable source + * // JBPNote - PDB DBRefEntry should also carry the chain and mapping + * information DBRefEntry dbentry = new * DBRefEntry(jalview.datamodel.DBRefSource.PDB, "0", id + pdbchain.id); * sq.addDBRef(dbentry); // and add seuqence to the retrieved set * result.addElement(sq.deriveSequence()); } } * * if (result.size() < 1) { throw new Exception("WsDBFetch for PDB id resulted - * in zero result size"); } } catch (Exception ex) // Problem parsing PDB file { - * jalview.bin.Cache.log.warn("Exception when retrieving " + + * in zero result size"); } } catch (Exception ex) // Problem parsing PDB file + * { jalview.bin.Cache.log.warn("Exception when retrieving " + * textArea.getText() + " from " + database.getSelectedItem(), ex); return * null; } * @@ -565,6 +741,13 @@ public class SequenceFetcher extends JPanel implements Runnable return null; } + /** + * + * @return a standard title for any results retrieved using the currently selected source and settings + */ + public String getDefaultRetrievalTitle() { + return "Retrieved from " + database.getSelectedItem(); + } AlignmentI parseResult(AlignmentI al, String title, String currentFileFormat) { @@ -578,16 +761,30 @@ public class SequenceFetcher extends JPanel implements Runnable if (currentFileFormat != null) { af.currentFileFormat = currentFileFormat; // WHAT IS THE DEFAULT - // FORMAT FOR - // NON-FormatAdapter Sourced - // Alignments? + // FORMAT FOR + // NON-FormatAdapter Sourced + // Alignments? } if (title == null) { - title = "Retrieved from " + database.getSelectedItem(); + title = getDefaultRetrievalTitle(); } + SequenceFeature[] sfs = null; + for (Enumeration sq = al.getSequences().elements(); sq + .hasMoreElements();) + { + if ((sfs = ((SequenceI) sq.nextElement()).getDatasetSequence() + .getSequenceFeatures()) != null) + { + if (sfs.length > 0) + { + af.setShowSeqFeatures(true); + break; + } + } + } Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); @@ -606,11 +803,11 @@ public class SequenceFetcher extends JPanel implements Runnable for (int i = 0; i < al.getHeight(); i++) { alignFrame.viewport.alignment.addSequence(al.getSequenceAt(i)); // this - // also - // creates - // dataset - // sequence - // entries + // also + // creates + // dataset + // sequence + // entries } alignFrame.viewport.setEndSeq(alignFrame.viewport.alignment .getHeight());