1 /*
2  *
3  * created: 2006
4  *
5  * This file is part of Artemis
6  *
7  * Copyright (C) 2006  Genome Research Limited
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  */
24 
25 package uk.ac.sanger.artemis.chado;
26 
27 import org.gmod.schema.cv.CvTerm;
28 import org.gmod.schema.general.DbXRef;
29 import org.gmod.schema.organism.Organism;
30 import org.gmod.schema.pub.Pub;
31 import org.gmod.schema.sequence.Feature;
32 import org.gmod.schema.sequence.FeatureCvTerm;
33 import org.gmod.schema.sequence.FeatureCvTermDbXRef;
34 import org.gmod.schema.sequence.FeatureCvTermProp;
35 import org.gmod.schema.sequence.FeatureCvTermPub;
36 import org.gmod.schema.sequence.FeatureDbXRef;
37 import org.gmod.schema.sequence.FeaturePub;
38 import org.gmod.schema.sequence.FeatureSynonym;
39 import org.gmod.schema.sequence.FeatureProp;
40 import org.gmod.schema.sequence.FeatureLoc;
41 
42 //import uk.ac.sanger.artemis.io.GFFStreamFeature;
43 //import uk.ac.sanger.artemis.util.DatabaseDocument;
44 
45 import java.awt.BorderLayout;
46 import java.awt.Container;
47 import java.awt.Cursor;
48 import java.awt.GridLayout;
49 import java.awt.event.ActionEvent;
50 import java.awt.event.ActionListener;
51 import java.awt.event.MouseAdapter;
52 import java.awt.event.MouseEvent;
53 import java.awt.Dimension;
54 import java.net.ConnectException;
55 import java.sql.SQLException;
56 import java.util.Iterator;
57 import java.util.List;
58 import java.util.Collection;
59 import java.util.Vector;
60 
61 import javax.swing.JLabel;
62 import javax.swing.JOptionPane;
63 import javax.swing.JButton;
64 import javax.swing.JTabbedPane;
65 import javax.swing.ListSelectionModel;
66 import javax.swing.JTable;
67 import javax.swing.JPasswordField;
68 import javax.swing.JTextField;
69 import javax.swing.JTextArea;
70 import javax.swing.JList;
71 import javax.swing.JScrollPane;
72 import javax.swing.JPanel;
73 import javax.swing.JFrame;
74 import javax.swing.JMenu;
75 import javax.swing.JMenuBar;
76 import javax.swing.JMenuItem;
77 import javax.swing.Box;
78 import javax.swing.event.ListSelectionListener;
79 import javax.swing.event.ListSelectionEvent;
80 
81 import uk.ac.sanger.artemis.util.ByteBuffer;
82 import uk.ac.sanger.artemis.util.DatabaseLocationParser;
83 
84 /**
85  * Chado data access example code. This searches for features by their
86  * uniquename and returns their properties and attributes.
87  *
88  * @author tjc
89  *
90  */
91 public class ChadoDemo
92 {
93   /** JDBC DAO */
94   /*private JdbcDAO jdbcDAO = null;*/
95 
96   /** iBatis DAO */
97   private IBatisDAO connIB = null;
98 
99   /** database URL */
100   private String location;
101 
102   /** password fields */
103   private JPasswordField pfield;
104 
105   /** results table */
106   private JTable result_table;
107 
108   /** feature attributes */
109   private JTextArea attr_text;
110 
111   /** <code>List</code> of <code>Feature</code> objects */
112   private List featureList;
113 
114   /** row data containing results */
115   private String rowData[][];
116 
117   private List pubDbXRefs[];
118 
119   private JTabbedPane tabbedPane;
120 
121   private static org.apache.log4j.Logger logger4j =
122 	    org.apache.log4j.Logger.getLogger(ChadoDemo.class);
123 
124   /** controlled_curation controlled vocabulary */
125   public static String CONTROLLED_CURATION_TAG_CVNAME =
126                                  "CC_";
127   /** product controlled vocabulary */
128   public static String PRODUCTS_TAG_CVNAME = "genedb_products";
129   public static String RILEY_TAG_CVNAME = "RILEY";
130 
131   /**
132    * Chado demo
133    */
ChadoDemo()134   public ChadoDemo()
135   {
136     //uk.ac.sanger.artemis.components.Splash.initLogger();
137 
138     try
139     {
140       setLocation();
141       final GmodDAO dao = getDAO();
142 
143       //
144       // TESTING - updating feature.residues
145       //
146       /*((IBatisDAO)dao).startTransaction();
147       FeatureForUpdatingResidues chadoFeature = new FeatureForUpdatingResidues();
148       chadoFeature.setStartBase(10);
149       chadoFeature.setEndBase(20);
150       dao.merge(chadoFeature);
151       ((IBatisDAO)dao).endTransaction();*/
152       //
153       //
154 
155       showFeatureSearchPanel(dao);
156       //getCvterm(dao);
157     }
158     catch(java.net.ConnectException ce)
159     {
160       ce.printStackTrace();
161     }
162     catch(SQLException sqlExp)
163     {
164       JOptionPane.showMessageDialog(null, "SQL Problems...\n"
165           + sqlExp.getMessage(), "SQL Error", JOptionPane.ERROR_MESSAGE);
166       sqlExp.printStackTrace();
167     }
168 
169   }
170 
171   /**
172    * Display a window for searching for features.
173    *
174    * @throws java.net.ConnectException
175    * @throws SQLException
176    */
showFeatureSearchPanel(final GmodDAO dao)177   private void showFeatureSearchPanel(final GmodDAO dao)
178       throws java.net.ConnectException, SQLException
179   {
180     int index = location.indexOf('=') + 1;
181     String schema = location.substring(index);
182 
183     final List schemas = dao.getOrganismsContainingSrcFeatures();
184 
185     Vector v_schemas = new Vector();
186     v_schemas.add(0, "All");
187 
188     for(int i=0; i<schemas.size(); i++)
189     {
190       Organism o = (Organism)schemas.get(i);
191       v_schemas.add(o.getCommonName());
192     }
193 
194     final JFrame frame = new JFrame("Feature Search");
195     final JPanel panel = new JPanel(new BorderLayout());
196     final JList schema_list = new JList(v_schemas);
197     schema_list.setSelectedValue(schema, true);
198     if(schema_list.getSelectedIndex() == -1)
199       schema_list.setSelectedValue("All", true);
200 
201     Box xbox2 = Box.createHorizontalBox();
202     JScrollPane jsp = new JScrollPane(schema_list);
203 
204     Box xbox = Box.createHorizontalBox();
205     final JTextField gene_text = new JTextField("PF3D7_0100100*",20);
206     xbox.add(gene_text);
207     gene_text.selectAll();
208 
209     result_table = new JTable();
210 
211     final JScrollPane scrollpane = new JScrollPane(result_table);
212     scrollpane.setPreferredSize(new Dimension(600, 250));
213 
214     //panel.add(scrollpane, BorderLayout.CENTER);
215     if(schemas != null)
216     pubDbXRefs = new List[schemas.size()];
217     else
218       pubDbXRefs = new List[1];
219 
220     JButton findButt = new JButton("FIND");
221     findButt.addActionListener(new ActionListener()
222     {
223       private String columnNames[] = { "schema", "name", "type",
224           "feature ID", "loc", "strand", "time modified" };
225 
226       public void actionPerformed(ActionEvent event)
227       {
228         frame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
229         String search_gene = gene_text.getText();
230         String schema = (String)schema_list.getSelectedValue();
231         List schema_search;
232         if(schema.equalsIgnoreCase("All"))
233           schema_search = schemas;
234         else
235         {
236           schema_search = new Vector();
237           schema_search.add(schema);
238         }
239 
240         try
241         {
242           rowData = search(search_gene, schema_search, dao);
243 
244           result_table = new JTable(rowData, columnNames);
245           result_table.getSelectionModel().addListSelectionListener(
246                                          new SelectionListener(dao, frame));
247           result_table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
248 
249           result_table.addMouseListener(new MouseAdapter()
250           {
251             public void mouseClicked(MouseEvent e)
252             {
253               frame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
254               int row = result_table.getSelectedRow();
255 
256               if(pubDbXRefs[row] == null)
257                 pubDbXRefs[row] = dao.getPubDbXRef();
258               showAttributes(dao, pubDbXRefs[row]);
259               frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
260             }
261           });
262 
263           scrollpane.setViewportView(result_table);
264         }
265         catch(SQLException sqlExp)
266         {
267           JOptionPane.showMessageDialog(null, "SQL Problems...\n"
268               + sqlExp.getMessage(), "SQL Error", JOptionPane.ERROR_MESSAGE);
269           sqlExp.printStackTrace();
270         }
271         catch(ConnectException e)
272         {
273           // TODO Auto-generated catch block
274           e.printStackTrace();
275         }
276         frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
277       }
278     });
279     xbox.add(findButt);
280     xbox.add(Box.createHorizontalGlue());
281 
282     Box ybox = Box.createVerticalBox();
283     xbox2.add(scrollpane);
284     xbox2.add(jsp);
285     xbox2.add(Box.createHorizontalGlue());
286 
287     ybox.add(xbox);
288     ybox.add(xbox2);
289 
290     panel.add(ybox, BorderLayout.NORTH);
291 
292     attr_text = new JTextArea();
293     JScrollPane jsp_attr = new JScrollPane(attr_text);
294     jsp_attr.setPreferredSize(new Dimension(600, 150));
295 
296 
297     tabbedPane = new JTabbedPane();
298     tabbedPane.add("Core", jsp_attr);
299 
300     panel.add(tabbedPane, BorderLayout.CENTER);
301 
302 
303     frame.getContentPane().add(panel);
304     frame.setJMenuBar(getJMenuBar(dao));
305     frame.pack();
306     frame.setVisible(true);
307   }
308 
309   /**
310    * Build a <code>JMenuBar</code>.
311    *
312    * @return a <code>JMenuBar</code>
313    */
getJMenuBar(final GmodDAO dao)314   public JMenuBar getJMenuBar(final GmodDAO dao)
315   {
316     JMenuBar mbar = new JMenuBar();
317     JMenu file = new JMenu("File");
318     mbar.add(file);
319 
320     JMenuItem exit = new JMenuItem("Exit");
321     exit.addActionListener(new ActionListener()
322     {
323       public void actionPerformed(ActionEvent event)
324       {
325         System.exit(0);
326       }
327     });
328     file.add(exit);
329 
330     return mbar;
331   }
332 
333 
334 
335 
336   /**
337    * Search for a feature/gene name from a <code>List</code> of schemas.
338    *
339    * @param search_gene
340    *          the feature name
341    * @param schema_search
342    *          the <code>List</code> to search
343    * @param dao
344    *          the data access object
345    * @return string array of results
346    * @throws SQLException
347    * @throws ConnectException
348    */
search(final String search_gene, final List schema_search, GmodDAO dao)349   public String[][] search(final String search_gene, final List schema_search,
350       GmodDAO dao) throws SQLException, ConnectException
351   {
352     final String search_name = search_gene.replaceAll("[*]","%");
353     Feature feature = new Feature();
354     //feature.setUniquename(search_gene.replaceAll("[*]","%"));
355     featureList = new Vector();
356 
357     for(int i=0; i<schema_search.size(); i++)
358     {
359       featureList.addAll(dao.getFeaturesByAnyCurrentName(search_name));
360     }
361 
362     String rowData[][] = new String[featureList.size()][7];
363 
364     for(int i = 0; i < featureList.size(); i++)
365     {
366       feature = (Feature) featureList.get(i);
367 
368       // assume only one featureloc
369       Collection locs = feature.getFeatureLocsForFeatureId();
370 
371       if(locs != null && locs.size() > 0)
372       {
373         Iterator it = locs.iterator();
374         FeatureLoc loc = (FeatureLoc)it.next();
375         int fmin = loc.getFmin().intValue() + 1;
376         int fmax = loc.getFmax().intValue();
377         rowData[i][4] = fmin + "..." + fmax;
378         rowData[i][5] = Integer.toString(loc.getStrand().shortValue());
379       }
380       else if(feature.getFeatureLoc() != null)
381       {
382         FeatureLoc loc = feature.getFeatureLoc();
383         int fmin = loc.getFmin().intValue() + 1;
384         int fmax = loc.getFmax().intValue();
385         rowData[i][4] = fmin + "..." + fmax;
386         rowData[i][5] = Integer.toString(loc.getStrand().shortValue());
387       }
388 
389       String schema = feature.getOrganism().getAbbreviation();
390       int ind = schema.indexOf('.');
391       if(ind > 0)
392         schema = schema.substring(0,ind)+schema.substring(ind+1);
393 
394       System.out.println("\n\nNow get feature type_id.......\n\n");
395       rowData[i][0] = schema;
396       rowData[i][1] = feature.getUniqueName();
397       rowData[i][2] = feature.getCvTerm().getName();
398       //rowData[i][2] = (String)cvterm.get(new Long(feature.getType_id()));
399       rowData[i][3] = Integer.toString(feature.getFeatureId());
400       rowData[i][6] = feature.getTimeLastModified().toString();
401 
402     }
403     return rowData;
404   }
405 
406 
407   /**
408    * Get the data access object (DAO).
409    *
410    * @return data access object
411    */
getDAO()412   private GmodDAO getDAO() throws java.net.ConnectException, SQLException
413   {
414 /*    if(System.getProperty("ibatis") == null)
415     {
416       logger4j.debug("Using JDBC");
417       if(jdbcDAO == null)
418         jdbcDAO = new JdbcDAO(location, pfield);
419       return jdbcDAO;
420     }
421     else*/
422     {
423       logger4j.debug("Using iBatis");
424       if(connIB == null)
425         connIB = new IBatisDAO(pfield);
426       return connIB;
427     }
428   }
429 
430   /**
431    * Set the database location as:
432    * jdbc:postgresql://localhost:13001/chadoCVS?user=es2
433    *
434    * @return true if location chosen
435    */
setLocation()436   private boolean setLocation()
437   {
438     Container bacross = new Container();
439     bacross.setLayout(new GridLayout(6, 2, 5, 5));
440 
441     JLabel lServer = new JLabel("Server : ");
442     bacross.add(lServer);
443     JTextField inServer = new JTextField("db.genedb.org");
444     bacross.add(inServer);
445 
446     JLabel lPort = new JLabel("Port : ");
447     bacross.add(lPort);
448     JTextField inPort = new JTextField("5432");
449     bacross.add(inPort);
450 
451     JLabel lDB = new JLabel("Database : ");
452     bacross.add(lDB);
453     JTextField inDB = new JTextField("snapshot");
454     bacross.add(inDB);
455 
456     JLabel lUser = new JLabel("User : ");
457     bacross.add(lUser);
458     JTextField inUser = new JTextField("genedb_ro");
459     bacross.add(inUser);
460 
461     JLabel lpasswd = new JLabel("Password : ");
462     bacross.add(lpasswd);
463     pfield = new JPasswordField(16);
464     bacross.add(pfield);
465 
466 
467     DatabaseLocationParser dlp = new DatabaseLocationParser();
468     // given -Dchado=localhost:port/dbname?username
469     if(System.getProperty("chado") != null)
470     {
471       String db_url = System.getProperty("chado").trim();
472       dlp.setFromURLString(db_url);
473       inServer.setText(dlp.getHost());
474       inPort.setText("" + dlp.getPort());
475       inDB.setText(dlp.getDatabase());
476       inUser.setText(dlp.getUsername());
477 
478     }
479 
480     int n = JOptionPane.showConfirmDialog(null, bacross,
481         "Enter Database Address", JOptionPane.OK_CANCEL_OPTION,
482         JOptionPane.QUESTION_MESSAGE);
483     if(n == JOptionPane.CANCEL_OPTION)
484       return false;
485 
486     dlp.setHost(inServer.getText());
487     dlp.setPort(inPort.getText());
488     dlp.setDatabase(inDB.getText());
489     dlp.setUsername(inUser.getText());
490 
491     location = dlp.getCompleteURL();
492 
493     System.setProperty("chado", location);
494 
495     return true;
496   }
497 
498 
499   public class SelectionListener implements ListSelectionListener
500   {
501 	  private GmodDAO dao;
502     private JFrame frame;
503 
SelectionListener(final GmodDAO dao, final JFrame frame)504     public SelectionListener(final GmodDAO dao, final JFrame frame)
505     {
506       super();
507       this.dao = dao;
508       this.frame = frame;
509     }
510 
valueChanged(ListSelectionEvent e)511     public void valueChanged(ListSelectionEvent e)
512     {
513       frame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
514       int row = result_table.getSelectedRow();
515       //reset(location, rowData[row][0]);
516 
517       if(pubDbXRefs[row] == null)
518         pubDbXRefs[row] = dao.getPubDbXRef();
519       showAttributes(dao, pubDbXRefs[row]);
520       frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
521     }
522   }
523 
524   /**
525    * Show the attributes of a selected feature.
526    */
showAttributes(final GmodDAO dao, final List pubDbXRefs)527   private void showAttributes(final GmodDAO dao,
528                               final List pubDbXRefs)
529   {
530     final int row = result_table.getSelectedRow();
531     final ByteBuffer attr_buff = new ByteBuffer();
532     final Feature chado_feature = (Feature)featureList.get(row);
533 
534     Collection locs = chado_feature.getFeatureLocsForFeatureId();
535     FeatureLoc loc;
536 
537     if(locs != null && locs.size() > 0)
538     {
539       Iterator it = locs.iterator();
540       loc = (FeatureLoc)it.next();
541     }
542     else
543       loc = chado_feature.getFeatureLoc();
544     /*
545     int fmin = loc.getFmin().intValue() + 1;
546     int fmax = loc.getFmax().intValue();
547     */
548     String uniquename = chado_feature.getUniqueName();
549 
550     attr_buff.append("/ID="+uniquename+"\n");
551     List attributes = (List)chado_feature.getFeatureProps();
552     List dbxrefs = dao.getFeatureDbXRefsByFeatureUniquename(uniquename);
553     List featureCvTerms       = dao.getFeatureCvTermsByFeature(chado_feature);
554     List featureCvTermDbXRefs = dao.getFeatureCvTermDbXRefByFeature(chado_feature);
555     List featureCvTermPubs    = dao.getFeatureCvTermPubByFeature(chado_feature);
556     Feature srcFeature = new Feature();
557     srcFeature.setFeatureId(loc.getSrcFeatureId());
558     List featurePubs = dao.getFeaturePubsBySrcFeature(srcFeature);
559 
560     if(dbxrefs.size() > 0)
561     {
562       attr_buff.append("/Dbxref=");
563       for(int i = 0; i < dbxrefs.size(); i++)
564       {
565         FeatureDbXRef dbxref = (FeatureDbXRef) dbxrefs.get(i);
566         attr_buff.append(dbxref.getDbXRef().getDb().getName() + ":"
567             + dbxref.getDbXRef().getAccession() + "; ");
568       }
569       attr_buff.append("\n");
570     }
571 
572     Collection synonyms = chado_feature.getFeatureSynonyms();
573 
574     // append synonyms
575     if(synonyms != null && synonyms.size() > 0)
576     {
577       FeatureSynonym alias;
578 
579       System.out.println("\n\nNow get synonym & type_id.......\n\n");
580       Iterator it = synonyms.iterator();
581       while(it.hasNext())
582       {
583         alias = (FeatureSynonym)it.next();
584         attr_buff.append("/");
585         attr_buff.append(alias.getSynonym().getCvTerm().getName() + "=");
586         attr_buff.append(alias.getSynonym().getName());
587         attr_buff.append(";");
588         attr_buff.append("\n");
589       }
590     }
591 
592     if(attributes != null)
593     {
594       Iterator it = attributes.iterator();
595       while(it.hasNext())
596       {
597         FeatureProp featprop = (FeatureProp)it.next();
598 
599         attr_buff.append("/" + featprop.getCvTerm().getName() + "="
600             + decode(featprop.getValue()) + "\n");
601       }
602     }
603 
604     if(featureCvTerms != null)
605     {
606       for(int j=0; j<featureCvTerms.size(); j++)
607       {
608         attr_buff.append("/");
609         FeatureCvTerm feature_cvterm = (FeatureCvTerm)featureCvTerms.get(j);
610 
611         appendControlledVocabulary(attr_buff, dao, feature_cvterm,
612             featureCvTermDbXRefs, featureCvTermPubs, pubDbXRefs, false);
613 
614         attr_buff.append("\n");
615       }
616     }
617 
618     // /literature
619     if(featurePubs != null)
620     {
621       for(int i=0; i<featurePubs.size(); i++)
622       {
623         FeaturePub featurePub = (FeaturePub)featurePubs.get(i);
624         if(chado_feature.getFeatureId() == featurePub.getFeature().getFeatureId())
625         {
626           attr_buff.append( "/literature=" );
627           attr_buff.append(featurePub.getPub().getUniqueName());
628           attr_buff.append("\n");
629         }
630       }
631     }
632 
633     attr_text.setText(decode((new String(attr_buff.getBytes()))));
634   }
635 
636 
637   /**
638    * Appends controlled vocabulary terms to the buffer
639    * @param attr_buff
640    * @param dao
641    * @param feature_cvterm
642    * @param featureCvTermDbXRef
643    */
appendControlledVocabulary(final ByteBuffer attr_buff, final GmodDAO dao, final FeatureCvTerm feature_cvterm, final List featureCvTermDbXRefs, final List featureCvTermPubs, final List pubDbXRefs, final boolean gene_builder)644   public static void appendControlledVocabulary(final ByteBuffer attr_buff,
645                                           final GmodDAO dao,
646                                           final FeatureCvTerm feature_cvterm,
647                                           final List featureCvTermDbXRefs,
648                                           final List featureCvTermPubs,
649                                           final List pubDbXRefs,
650                                           final boolean gene_builder)
651   {
652     CvTerm cvterm = dao.getCvTermById( feature_cvterm.getCvTerm().getCvTermId() );
653     DbXRef dbXRef = feature_cvterm.getCvTerm().getDbXRef();
654 
655     if(cvterm.getCv().getName().startsWith(CONTROLLED_CURATION_TAG_CVNAME))
656     {
657       attr_buff.append("controlled_curation=");
658 
659       attr_buff.append("term="+
660           feature_cvterm.getCvTerm().getName()+";");
661       attr_buff.append("cv="+
662           feature_cvterm.getCvTerm().getCv().getName()+";");
663 
664       // N.B. the db_xref may be a FeatureCvTermDbXRef or a Pub for /controlled_curation
665       int nfound_dbxref = 0;
666       if(feature_cvterm.getPub().getUniqueName() != null &&
667          !feature_cvterm.getPub().getUniqueName().equalsIgnoreCase("NULL"))
668       {
669         // PMID
670         Pub pub = feature_cvterm.getPub();
671 
672         // internal check
673         //checkPubDbXRef(pubDbXRefs, pub.getPubId(), pub, feature_cvterm);
674 
675         attr_buff.append("db_xref="+ pub.getUniqueName());
676         nfound_dbxref++;
677       }
678 
679       if(featureCvTermDbXRefs != null &&
680               featureCvTermDbXRefs.size() > 0)
681       {
682         for(int i=0; i<featureCvTermDbXRefs.size(); i++)
683         {
684           FeatureCvTermDbXRef featureCvTermDbXRef =
685             (FeatureCvTermDbXRef)featureCvTermDbXRefs.get(i);
686 
687           if(feature_cvterm.getFeatureCvTermId() !=
688             featureCvTermDbXRef.getFeatureCvTerm().getFeatureCvTermId())
689             continue;
690 
691           if(nfound_dbxref == 0)
692             attr_buff.append("db_xref=");
693           else if(nfound_dbxref > 0)
694             attr_buff.append("|");
695 
696           DbXRef fc_dbXRef = featureCvTermDbXRef.getDbXRef();
697           attr_buff.append(fc_dbXRef.getDb().getName()+":");
698           attr_buff.append(fc_dbXRef.getAccession());
699           nfound_dbxref++;
700         }
701       }
702 
703       if(nfound_dbxref > 0)
704         attr_buff.append("%3B");
705 
706       List feature_cvtermprops = (List) feature_cvterm.getFeatureCvTermProps();
707       for(int i = 0; i < feature_cvtermprops.size(); i++)
708       {
709         FeatureCvTermProp feature_cvtermprop =
710           (FeatureCvTermProp)feature_cvtermprops.get(i);
711         attr_buff.append( dao.getCvTermById( feature_cvtermprop.getCvTerm().getCvTermId() ).getName());
712         attr_buff.append("=");
713         attr_buff.append(feature_cvtermprop.getValue());
714         if(i < feature_cvtermprops.size()-1)
715           attr_buff.append(";");
716       }
717 
718       attr_buff.append(";");
719     }
720     else if(cvterm.getCv().getName().equals(PRODUCTS_TAG_CVNAME))
721     {
722       attr_buff.append("product=");
723       attr_buff.append(feature_cvterm.getCvTerm().getName()+";");
724     }
725     else if(cvterm.getCv().getName().equals(RILEY_TAG_CVNAME))
726     {
727       // class include the cvTermId as a convenience for looking up the term
728       attr_buff.append("class=");
729       attr_buff.append(dbXRef.getAccession()+"::"+
730                       feature_cvterm.getCvTerm().getCvTermId()+";");
731     }
732     else
733     {
734       attr_buff.append("GO=");
735 
736       if(cvterm.getCv().getName().equals("molecular_function"))
737         attr_buff.append("aspect=F%3B");
738       else if(cvterm.getCv().getName().equals("cellular_component"))
739         attr_buff.append("aspect=C%3B");
740       else if(cvterm.getCv().getName().equals("biological_process"))
741         attr_buff.append("aspect=P%3B");
742 
743       if(feature_cvterm.isNot())
744         attr_buff.append("qualifier=NOT%3B");
745 
746       attr_buff.append("GOid="+dbXRef.getDb().getName() + ":"
747           + dbXRef.getAccession() + "%3B");
748 
749       attr_buff.append("term="+
750           feature_cvterm.getCvTerm().getName()+";");
751 
752       // PMID
753       int nfound_pub = 0;
754       if(feature_cvterm.getPub() != null &&
755          feature_cvterm.getPub().getUniqueName() != null &&
756          !feature_cvterm.getPub().getUniqueName().equalsIgnoreCase("NULL"))
757       {
758         Pub pub = feature_cvterm.getPub();
759         attr_buff.append("db_xref="+
760             pub.getUniqueName());
761         nfound_pub++;
762       }
763 
764       if(featureCvTermPubs != null &&
765           featureCvTermPubs.size() > 0)
766       {
767         for(int i=0; i<featureCvTermPubs.size(); i++)
768         {
769           FeatureCvTermPub featureCvTermPub =
770             (FeatureCvTermPub)featureCvTermPubs.get(i);
771 
772           if(feature_cvterm.getFeatureCvTermId() !=
773             featureCvTermPub.getFeatureCvTerm().getFeatureCvTermId())
774             continue;
775 
776           if(nfound_pub == 0)
777             attr_buff.append("db_xref=");
778           else if(nfound_pub > 0)
779             attr_buff.append("|");
780 
781           attr_buff.append(featureCvTermPub.getPub().getUniqueName());
782           nfound_pub++;
783         }
784       }
785 
786       if(nfound_pub > 0)
787         attr_buff.append("%3B");
788 
789       if(featureCvTermDbXRefs != null &&
790           featureCvTermDbXRefs.size() > 0 )
791       {
792         int nfound = 0;
793         for(int i=0; i<featureCvTermDbXRefs.size(); i++)
794         {
795           FeatureCvTermDbXRef featureCvTermDbXRef =
796             (FeatureCvTermDbXRef)featureCvTermDbXRefs.get(i);
797 
798 
799           if(feature_cvterm.getFeatureCvTermId() !=
800             featureCvTermDbXRef.getFeatureCvTerm().getFeatureCvTermId())
801           {
802             continue;
803           }
804 
805           if(nfound == 0)
806             attr_buff.append("with=");
807           else if(nfound > 1)
808             attr_buff.append("|");
809 
810           DbXRef fc_dbXRef = featureCvTermDbXRef.getDbXRef();
811           attr_buff.append(fc_dbXRef.getDb().getName()+":");
812           attr_buff.append(fc_dbXRef.getAccession());
813           nfound++;
814         }
815 
816         if(nfound > 0)
817           attr_buff.append("%3B");
818       }
819 
820       List feature_cvtermprops = (List)feature_cvterm
821           .getFeatureCvTermProps();
822       for(int i = 0; i < feature_cvtermprops.size(); i++)
823       {
824         FeatureCvTermProp feature_cvtermprop =
825           (FeatureCvTermProp)feature_cvtermprops.get(i);
826 
827         if(feature_cvtermprop.getValue() == null)
828           continue;
829 
830         attr_buff.append(dao.getCvTermById(feature_cvtermprop.getCvTerm().getCvTermId()).getName());
831         attr_buff.append("=");
832         attr_buff.append(feature_cvtermprop.getValue());
833         if(i < feature_cvtermprops.size()-1)
834           attr_buff.append(";");
835       }
836 
837       attr_buff.append(";");
838     }
839   }
840 
841 
842 
843   /**
844   *
845   * For gff-version 3:
846   * http://song.sourceforge.net/gff3-jan04.shtml
847   *
848   * Remove URL escaping rule (e.g. space="%20" or "+")
849   *
850   */
decode(String s)851   private String decode(String s)
852   {
853     final String map[][] = {
854                              { " ",  "%20" },  // white space
855                              { ",",  "%2C" },  // comma
856                              { ";",  "%3B" },  // semi-colon
857                              { "=",  "%3D" },  // equals
858                              { "\t", "%09" },  // tab
859                              { " ",  "+"   },  // white space
860                              { "+",  "%2B" },
861                              { "(",  "%28" },  // left bracket
862                              { ")",  "%29" }   // right bracket
863                            };
864 
865     int ind;
866     String enc;
867     String dec;
868 
869     for(int i=0; i<map.length; i++)
870     {
871       enc = map[i][1];
872       dec = map[i][0];
873       while( (ind = s.indexOf(enc)) > -1)
874         s = s.substring(0,ind) + dec + s.substring(ind+enc.length());
875     }
876 
877     return s;
878   }
879 
main(String args[])880   public static void main(String args[])
881   {
882     new ChadoDemo();
883   }
884 }
885