<strong>Opening URLs from Jalview</strong><br> Both the applet
and the desktop application are able to open URLs as 'popups' in
your web browser. <br> Double-clicking on the ID of a sequence
- will open the first URL that can be generated from its sequence ID.
+ will open the URL designated for 'popups' in the "Connections" tab of the <a
+ href="../features/preferences.html">Jalview desktop
+ preferences</a>.
This is by default the EMBL-EBI site, but you can easily configure your own <a
href="#urllinks">sequence URL links</a>.
</p>
href="../features/preferences.html">Jalview desktop
preferences</a>, or specified as <a
href="http://www.jalview.org/examples/appletParameters.html#parameters">applet
- parameters</a>. <br> By default the item "EMBL-EBI Search" is added
- to this link menu. This link will show a web page in your default
- browser with the selected sequence id as part of the URL.<br>
- In the preferences dialog box, click <strong>new</strong> to add a
+ parameters</a>.</p>
+ <p>
+ By default, the list of available links in the preferences dialog box
+ contains the item "EMBL-EBI Search",
+ which is set as the URL which opens on double-clicking on a sequence ID, and as a
+ menu item in the Links menu. This link will show a web page in your default
+ browser with the selected sequence id as part of the URL.
+ <br>
+ Also by default, the list of available links contains persistent URLs for many common
+ bioinformatics databases. These links are downloaded by Jalview from
+ the <em>identifiers.org</em> website, and the names and URLs are not user editable.
+ <br>
+ The list of links is sortable, by clicking on the headers of the table. The list
+ can be filtered using the free text search box below the table, or the
+ "Custom Only" button, which displays only user-defined links.
+ </p>
+ <p>
+ In the preferences dialog box, the links which appear in the Links menu
+ can be configured by selecting or deselecting links in the "In Menu"
+ column. The names of selected links will be displayed
+ on new menu items under the "Link" menu when you right
+ click on a sequence id.<br>
+ You can configure which link is used when double-clicking on a sequence
+ by selecting or deselecting links in the "On Click" column. Exactly one
+ link must be configured for double-clicking. Since the link uses the sequence id
+ to construct the URL to open, the selected link must contain the
+ "$SEQUENCE_ID$" token (see below for details of the "$SEQUENCE_ID$"
+ and other tokens).</p>
+ <p>
+ Additionally you can click <strong>new</strong> to add a
new link, and <strong>edit</strong> to modify an existing link, or <strong>delete</strong>
- to remove it.<br> You can name the link, this will be displayed
- on a new menu item under the "Link" menu when you right
- click on a sequence id. <br> The URL string must contain a
+ to remove it. Only URLs entered by the user (or the default EMBL-EBI link) may
+ be edited or deleted. When adding or editing a link, the URL string must contain a
token that can be replaced with a sequence ID or DB accession ID. The simplest token is
"$SEQUENCE_ID$", which will be replaced by the chosen
sequence id when you click on it.
label.view_flanking_regions = Show sequence data either side of the subsequences involved in this alignment
label.structures_manager = Structures Manager
label.nickname = Nickname:
-label.url = URL:
+label.url = URL
+label.url\: = URL:
label.input_file_url = Enter URL or Input File
label.select_feature = Select feature
label.name = Name
label.vamsas_document_import_failed = Vamsas Document Import Failed
label.couldnt_locate = Couldn't locate {0}
label.url_not_found = URL not found
-label.no_link_selected = No link selected
label.new_sequence_url_link = New sequence URL link
label.cannot_edit_annotations_in_wrapped_view = Cannot edit annotations in wrapped view
label.wrapped_view_no_edit = Wrapped view - no edit
label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window:
label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'.
label.do_not_display_again = Do not display this message again
-label.output_seq_details = Output Sequence Details to list all database references
+exception.url_cannot_have_miriam_id = {0} is a MIRIAM id and cannot be used as a custom url name
+exception.url_cannot_have_duplicate_id = {0} cannot be used as a label for more than one line
+label.filter = Filter text:
+action.customfilter = Custom only
+action.showall = Show All
+label.insert = Insert:
+action.seq_id = $SEQUENCE_ID$
+action.db_acc = $DB_ACCESSION$
+label.default = On Click
+label.inmenu = In Menu
+label.id = ID
+label.urltooltip = Only one url, which must use a sequence id, can be selected for the 'On Click' option
+label.edit_sequence_url_link = Edit sequence URL link
+warn.name_cannot_be_duplicate = URL names must be unique and cannot be MIRIAM ids
+label.invalid_name = Invalid Name !
+label.output_seq_details = Output Sequence Details to list all database references
\ No newline at end of file
label.view_flanking_regions = Mostrar los datos de la secuencia a ambos lados de las subsecuencias implicadas en este alineamiento
label.structures_manager = Administrar estructuras
label.nickname = Sobrenombre:
-label.url = URL:
+label.url\: = URL:
+label.url = URL
label.input_file_url = Introducir URL en el fichero de entrada
label.select_feature = Seleccionar característica
label.name = Nombre
label.vamsas_document_import_failed = Fallo en la importación del documento Vamsas
label.couldnt_locate = No se pudo localizar {0}
label.url_not_found = URL no encontrada
-label.no_link_selected = Enlace no seleccionado
label.new_sequence_url_link = Enlace a una nueva secuencia URL
label.cannot_edit_annotations_in_wrapped_view = No se pueden editar anotaciones en vista envolvente
label.wrapped_view_no_edit = Vista envolvente - no editar
label.SEQUENCE_ID_for_DB_ACCESSION1 = Por favor, revise sus URLs en la pestaña 'Conexiones' de la ventana de Preferencias:
label.SEQUENCE_ID_for_DB_ACCESSION2 = URL enlaza usando '$SEQUENCE_ID$' para accesiones DB ahora usar '$DB_ACCESSION$'.
label.do_not_display_again = No mostrar este mensaje de nuevo
-label.output_seq_details = Seleccionar Detalles de la secuencia para ver todas
+exception.url_cannot_have_miriam_id = {0} is a MIRIAM id and cannot be used as a custom url name
+exception.url_cannot_have_duplicate_id = {0} cannot be used as a label for more than one link
+label.filter = Filter text:
+action.customfilter = Custom only
+action.showall = Show All
+label.insert = Insert:
+action.seq_id = $SEQUENCE_ID$
+action.db_acc = $DB_ACCESSION$
+label.default = On Click
+label.inmenu = In Menu
+label.id = ID
+label.urltooltip = Only one url, which must use a sequence id, can be selected for the 'On Click' option
+label.edit_sequence_url_link = Edit sequence URL link
+warn.name_cannot_be_duplicate = URL names must be unique and cannot be MIRIAM ids
+label.invalid_name = Invalid Name !
+label.output_seq_details = Seleccionar Detalles de la secuencia para ver todas
\ No newline at end of file
*/
package jalview.appletgui;
-import static jalview.util.UrlConstants.EMBLEBI_STRING;
-import static jalview.util.UrlConstants.SRS_STRING;
-
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
-import jalview.util.UrlLink;
+import jalview.urls.api.UrlProviderFactoryI;
+import jalview.urls.api.UrlProviderI;
+import jalview.urls.applet.AppletUrlProviderFactory;
import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
+import java.util.HashMap;
import java.util.List;
import java.util.Vector;
boolean mouseDragging = false;
- java.util.Vector links = new java.util.Vector();
+ UrlProviderI urlProvider = null;
public IdPanel(AlignViewport av, AlignmentPanel parent)
{
String label, url;
// TODO: add in group link parameter
+
+ // make a list of label,url pairs
+ HashMap<String, String> urlList = new HashMap<String, String>();
if (av.applet != null)
{
for (int i = 1; i < 10; i++)
label = av.applet.getParameter("linkLabel_" + i);
url = av.applet.getParameter("linkURL_" + i);
- if (label != null && url != null)
- {
- links.addElement(label + "|" + url);
- }
-
+ urlList.put(label, url);
}
- }
- {
- // upgrade old SRS link
- int srsPos = links.indexOf(SRS_STRING);
- if (srsPos > -1)
+
+ if (!urlList.isEmpty())
{
- links.setElementAt(EMBLEBI_STRING, srsPos);
+ // set default as first entry in list
+ String defaultUrl = av.applet.getParameter("linkLabel_1");
+ UrlProviderFactoryI factory = new AppletUrlProviderFactory(
+ defaultUrl, urlList);
+ urlProvider = factory.createUrlProvider();
}
}
- if (links.size() < 1)
- {
- links = new java.util.Vector();
- links.addElement(EMBLEBI_STRING);
- }
}
Tooltip tooltip;
return;
}
- // DEFAULT LINK IS FIRST IN THE LINK LIST
+ // get the sequence details
int seq = alignPanel.seqPanel.findSeq(e);
SequenceI sq = av.getAlignment().getSequenceAt(seq);
if (sq == null)
}
String id = sq.getName();
- String target = null;
- String url = null;
- int i = 0;
- while (url == null && i < links.size())
- {
- // DEFAULT LINK IS FIRST IN THE LINK LIST
- // BUT IF ITS A REGEX AND DOES NOT MATCH THE NEXT ONE WILL BE TRIED
- url = links.elementAt(i++).toString();
- jalview.util.UrlLink urlLink = null;
- try
- {
- urlLink = new UrlLink(url);
- target = urlLink.getTarget();
- } catch (Exception foo)
- {
- System.err.println("Exception for URLLink '" + url + "'");
- foo.printStackTrace();
- url = null;
- continue;
- }
-
- if (urlLink.usesDBAccession())
- {
- // this URL requires an accession id, not the name of a sequence
- url = null;
- continue;
- }
-
- if (!urlLink.isValid())
- {
- System.err.println(urlLink.getInvalidMessage());
- url = null;
- continue;
- }
-
- String urls[] = urlLink.makeUrls(id, true);
- if (urls == null || urls[0] == null || urls[0].length() < 1)
- {
- url = null;
- continue;
- }
- // just take first URL made from regex
- url = urls[1];
- }
+ // get the default url with the sequence details filled in
+ String url = urlProvider.getDefaultUrl(id);
+ String target = urlProvider.getDefaultTarget(id);
try
{
-
alignPanel.alignFrame.showURL(url, target);
} catch (Exception ex)
{
// build a new links menu based on the current links + any non-positional
// features
- Vector nlinks = new Vector();
- for (int l = 0, lSize = links.size(); l < lSize; l++)
- {
- nlinks.addElement(links.elementAt(l));
- }
+ Vector<String> nlinks = urlProvider.getLinksForMenu();
+
SequenceFeature sf[] = sq == null ? null : sq.getSequenceFeatures();
for (int sl = 0; sf != null && sl < sf.length; sl++)
{
import jalview.datamodel.PDBEntry;
import jalview.structure.StructureImportSettings;
+import jalview.urls.IdOrgSettings;
import jalview.ws.dbsources.das.api.DasSourceRegistryI;
import jalview.ws.dbsources.das.datamodel.DasSourceRegistry;
import jalview.ws.sifts.SiftsSettings;
* <li>SORT_ALIGNMENT (No sort|Id|Pairwise Identity)</li>
* <li>SEQUENCE_LINKS list of name|URL pairs for opening a url with
* $SEQUENCE_ID$</li>
+ * <li>STORED_LINKS list of name|url pairs which user has entered but are not
+ * currently used
+ * <li>DEFAULT_LINK name of single url to be used when user double clicks a
+ * sequence id (must be in SEQUENCE_LINKS or STORED_LINKS)
* <li>GROUP_LINKS list of name|URL[|<separator>] tuples - see
* jalview.utils.GroupURLLink for more info</li>
* <li>DAS_REGISTRY_URL the registry to query</li>
public static final String DAS_ACTIVE_SOURCE = "DAS_ACTIVE_SOURCE";
+ /**
+ * Sifts settings
+ */
public static final String DEFAULT_SIFTS_DOWNLOAD_DIR = System
.getProperty("user.home")
+ File.separatorChar
private final static String DEFAULT_FAIL_SAFE_PID_THRESHOLD = "30";
/**
+ * Identifiers.org download settings
+ */
+ private static final String ID_ORG_FILE = System.getProperty("user.home")
+ + File.separatorChar + ".jalview_identifiers";
+
+ private static final String ID_ORG_URL = "http://identifiers.org/rest/collections/";
+
+ /**
* Allowed values are PDB or mmCIF
*/
private final static String PDB_DOWNLOAD_FORMAT = PDBEntry.Type.MMCIF
"sifts_cache_threshold_in_days",
DEFAULT_CACHE_THRESHOLD_IN_DAYS));
+ IdOrgSettings.setUrl(ID_ORG_URL);
+ IdOrgSettings.setDownloadLocation(ID_ORG_FILE);
+
System.out
.println("Jalview Version: " + codeVersion + codeInstallation);
pane12.add(nametf, BorderLayout.EAST);
panel.add(pane12, BorderLayout.NORTH);
pane12 = new JPanel(new BorderLayout());
- pane12.add(new JLabel(MessageManager.getString("label.url")),
+ pane12.add(new JLabel(MessageManager.getString("label.url:")),
BorderLayout.NORTH);
pane12.add(seqs, BorderLayout.SOUTH);
pane12.add(urltf, BorderLayout.EAST);
*/
package jalview.gui;
-import static jalview.util.UrlConstants.EMBLEBI_STRING;
import static jalview.util.UrlConstants.SEQUENCE_ID;
import jalview.api.AlignViewportI;
import jalview.jbgui.GSplitFrame;
import jalview.jbgui.GStructureViewer;
import jalview.structure.StructureSelectionManager;
+import jalview.urls.IdOrgSettings;
import jalview.util.ImageMaker;
import jalview.util.MessageManager;
import jalview.util.Platform;
+import jalview.util.UrlConstants;
import jalview.viewmodel.AlignmentViewport;
+import jalview.ws.UrlDownloadClient;
import jalview.ws.params.ParamManager;
import java.awt.BorderLayout;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
showNews.setVisible(false);
+ getIdentifiersOrgData();
+
checkURLLinks();
this.addWindowListener(new WindowAdapter()
});
}
+ public void getIdentifiersOrgData()
+ {
+ // Thread off the identifiers fetcher
+ addDialogThread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ Cache.log.debug("Downloading data from identifiers.org");
+ UrlDownloadClient client = new UrlDownloadClient();
+ try
+ {
+ client.download(IdOrgSettings.getUrl(),
+ IdOrgSettings.getDownloadLocation());
+ } catch (IOException e)
+ {
+ Cache.log.debug("Exception downloading identifiers.org data"
+ + e.getMessage());
+ }
+ }
+ });
+ }
+
@Override
protected void showNews_actionPerformed(ActionEvent e)
{
{
// check what the actual links are - if it's just the default don't
// bother with the warning
- Vector<String> links = Preferences.sequenceURLLinks;
+ Vector<String> links = Preferences.sequenceUrlLinks
+ .getLinksForMenu();
// only need to check links if there is one with a
// SEQUENCE_ID which is not the default EMBL_EBI link
while (li.hasNext())
{
String link = li.next();
- if (link.contains(SEQUENCE_ID) && !link.equals(EMBLEBI_STRING))
+ if (link.contains(SEQUENCE_ID)
+ && !link.equals(UrlConstants.DEFAULT_STRING))
{
check = true;
int barPos = link.indexOf("|");
import jalview.io.SequenceAnnotationReport;
import jalview.util.MessageManager;
import jalview.util.Platform;
-import jalview.util.UrlLink;
import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
return;
}
- Vector links = Preferences.sequenceURLLinks;
- if (links == null || links.size() < 1)
- {
- return;
- }
-
int seq = alignPanel.getSeqPanel().findSeq(e);
- String url = null;
- int i = 0;
String id = av.getAlignment().getSequenceAt(seq).getName();
- while (url == null && i < links.size())
- {
- // DEFAULT LINK IS FIRST IN THE LINK LIST
- // BUT IF ITS A REGEX AND DOES NOT MATCH THE NEXT ONE WILL BE TRIED
- url = links.elementAt(i++).toString();
- jalview.util.UrlLink urlLink = null;
- try
- {
- urlLink = new UrlLink(url);
- } catch (Exception foo)
- {
- jalview.bin.Cache.log.error("Exception for URLLink '" + url + "'",
- foo);
- url = null;
- continue;
- }
+ String url = Preferences.sequenceUrlLinks.getDefaultUrl(id);
- if (urlLink.usesDBAccession())
- {
- // this URL requires an accession id, not the name of a sequence
- url = null;
- continue;
- }
-
- if (!urlLink.isValid())
- {
- jalview.bin.Cache.log.error(urlLink.getInvalidMessage());
- url = null;
- continue;
- }
-
- String urls[] = urlLink.makeUrls(id, true);
- if (urls == null || urls[0] == null || urls[0].length() < 4)
- {
- url = null;
- continue;
- }
- // just take first URL made from regex
- url = urls[1];
- }
try
{
jalview.util.BrowserLauncher.openURL(url);
Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq2);
// build a new links menu based on the current links + any non-positional
// features
- Vector<String> nlinks = new Vector<String>(Preferences.sequenceURLLinks);
+ Vector<String> nlinks = Preferences.sequenceUrlLinks.getLinksForMenu();
SequenceFeature sfs[] = sq == null ? null : sq.getSequenceFeatures();
if (sfs != null)
{
*/
package jalview.gui;
-import static jalview.util.UrlConstants.DB_ACCESSION;
-import static jalview.util.UrlConstants.EMBLEBI_STRING;
-import static jalview.util.UrlConstants.SEQUENCE_ID;
-import static jalview.util.UrlConstants.SRS_STRING;
-
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.bin.Cache;
import jalview.gui.Help.HelpId;
import jalview.jbgui.GPreferences;
import jalview.jbgui.GSequenceLink;
import jalview.schemes.ColourSchemeProperty;
+import jalview.urls.UrlLinkTableModel;
+import jalview.urls.api.UrlProviderFactoryI;
+import jalview.urls.api.UrlProviderI;
+import jalview.urls.desktop.DesktopUrlProviderFactory;
import jalview.util.MessageManager;
import jalview.util.Platform;
+import jalview.util.UrlConstants;
import jalview.ws.sifts.SiftsSettings;
import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
-import java.util.StringTokenizer;
-import java.util.Vector;
import javax.help.HelpSetException;
import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
+import javax.swing.ListSelectionModel;
+import javax.swing.RowFilter;
+import javax.swing.RowSorter;
+import javax.swing.SortOrder;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
+import javax.swing.table.TableRowSorter;
import ext.edu.ucsf.rbvi.strucviz2.StructureManager;
* Holds name and link separated with | character. Sequence ID must be
* $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$
*/
- public static Vector<String> sequenceURLLinks;
+ public static UrlProviderI sequenceUrlLinks;
+
+ public static UrlLinkTableModel dataModel;
/**
* Holds name and link separated with | character. Sequence IDS and Sequences
public static List<String> groupURLLinks;
static
{
- String string = Cache.getDefault("SEQUENCE_LINKS", EMBLEBI_STRING);
- sequenceURLLinks = new Vector<String>();
-
- try
+ // get links selected to be in the menu (SEQUENCE_LINKS)
+ // and links entered by the user but not selected (STORED_LINKS)
+ String inMenuString = Cache.getDefault("SEQUENCE_LINKS", "");
+ String notInMenuString = Cache.getDefault("STORED_LINKS", "");
+ String defaultUrl = Cache.getDefault("DEFAULT_URL",
+ UrlConstants.DEFAULT_LABEL);
+
+ // if both links lists are empty, add the DEFAULT_URL link
+ // otherwise we assume the default link is in one of the lists
+ if (inMenuString.isEmpty() && notInMenuString.isEmpty())
{
- StringTokenizer st = new StringTokenizer(string, "|");
- while (st.hasMoreElements())
- {
- String name = st.nextToken();
- String url = st.nextToken();
- // check for '|' within a regex
- int rxstart = url.indexOf("$" + DB_ACCESSION + "$");
- if (rxstart == -1)
- {
- rxstart = url.indexOf("$" + SEQUENCE_ID + "$");
- }
- while (rxstart == -1 && url.indexOf("/=$") == -1)
- {
- url = url + "|" + st.nextToken();
- }
- sequenceURLLinks.addElement(name + "|" + url);
- }
- } catch (Exception ex)
- {
- System.out.println(ex + "\nError parsing sequence links");
- }
- {
- // upgrade old SRS link
- int srsPos = sequenceURLLinks.indexOf(SRS_STRING);
- if (srsPos > -1)
- {
- sequenceURLLinks.setElementAt(EMBLEBI_STRING, srsPos);
- }
+ inMenuString = UrlConstants.DEFAULT_STRING;
}
+ UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl,
+ inMenuString, notInMenuString);
+ sequenceUrlLinks = factory.createUrlProvider();
+ dataModel = new UrlLinkTableModel(sequenceUrlLinks);
/**
* TODO: reformulate groupURL encoding so two or more can be stored in the
groupURLLinks = new ArrayList<String>();
}
- Vector<String> nameLinks, urlLinks;
-
JInternalFrame frame;
DasSourceBrowser dasSource;
/*
* Set Connections tab defaults
*/
- nameLinks = new Vector<String>();
- urlLinks = new Vector<String>();
- for (int i = 0; i < sequenceURLLinks.size(); i++)
+
+ // set up sorting
+ linkUrlTable.setModel(dataModel);
+ final TableRowSorter<TableModel> sorter = new TableRowSorter<>(
+ linkUrlTable.getModel());
+ linkUrlTable.setRowSorter(sorter);
+ List<RowSorter.SortKey> sortKeys = new ArrayList<>();
+
+ UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel();
+ sortKeys.add(new RowSorter.SortKey(m.getDefaultColumn(),
+ SortOrder.DESCENDING));
+ sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(),
+ SortOrder.DESCENDING));
+ sortKeys.add(new RowSorter.SortKey(m.getNameColumn(),
+ SortOrder.ASCENDING));
+
+ sorter.setSortKeys(sortKeys);
+ sorter.sort();
+
+ // set up filtering
+ ActionListener onReset;
+ onReset = new ActionListener()
{
- String link = sequenceURLLinks.elementAt(i).toString();
- nameLinks.addElement(link.substring(0, link.indexOf("|")));
- urlLinks.addElement(link.substring(link.indexOf("|") + 1));
- }
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ filterTB.setText("");
+ sorter.setRowFilter(RowFilter.regexFilter(""));
+ }
+
+ };
+ doReset.addActionListener(onReset);
+
+ // filter to display only custom urls
+ final RowFilter<TableModel, Object> customUrlFilter = new RowFilter<TableModel, Object>()
+ {
+ @Override
+ public boolean include(
+ Entry<? extends TableModel, ? extends Object> entry)
+ {
+ return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry);
+ }
+ };
+
+ final TableRowSorter<TableModel> customSorter = new TableRowSorter<>(
+ linkUrlTable.getModel());
+ customSorter.setRowFilter(customUrlFilter);
+
+ ActionListener onCustomOnly;
+ onCustomOnly = new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ filterTB.setText("");
+ sorter.setRowFilter(customUrlFilter);
+ }
+ };
+ userOnly.addActionListener(onCustomOnly);
+
+ filterTB.getDocument().addDocumentListener(new DocumentListener()
+ {
+ String caseInsensitiveFlag = "(?i)";
- updateLinkData();
+ @Override
+ public void changedUpdate(DocumentEvent e)
+ {
+ sorter.setRowFilter(RowFilter.regexFilter(caseInsensitiveFlag
+ + filterTB.getText()));
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e)
+ {
+ sorter.setRowFilter(RowFilter.regexFilter(caseInsensitiveFlag
+ + filterTB.getText()));
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e)
+ {
+ sorter.setRowFilter(RowFilter.regexFilter(caseInsensitiveFlag
+ + filterTB.getText()));
+ }
+ });
+
+ // set up list selection functionality
+ linkUrlTable.getSelectionModel().addListSelectionListener(
+ new UrlListSelectionHandler());
+
+ // set up radio buttons
+ int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel())
+ .getDefaultColumn();
+ String onClickName = linkUrlTable.getColumnName(onClickCol);
+ linkUrlTable.getColumn(onClickName).setCellRenderer(
+ new RadioButtonRenderer());
+ linkUrlTable.getColumn(onClickName)
+ .setCellEditor(new RadioButtonEditor());
+
+ // get boolean columns and resize those to min possible
+ for (int column = 0; column < linkUrlTable.getColumnCount(); column++)
+ {
+ if (linkUrlTable.getModel().getColumnClass(column)
+ .equals(Boolean.class))
+ {
+ TableColumn tableColumn = linkUrlTable.getColumnModel().getColumn(
+ column);
+ int preferredWidth = tableColumn.getMinWidth();
+
+ TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0,
+ column);
+ Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column);
+ int cwidth = c.getPreferredSize().width
+ + linkUrlTable.getIntercellSpacing().width;
+ preferredWidth = Math.max(preferredWidth, cwidth);
+
+ tableColumn.setPreferredWidth(preferredWidth);
+ }
+ }
useProxy.setSelected(Cache.getDefault("USE_PROXY", false));
+ useProxy_actionPerformed(); // make sure useProxy is correctly initialised
proxyServerTB.setEnabled(useProxy.isSelected());
proxyPortTB.setEnabled(useProxy.isSelected());
proxyServerTB.setText(Cache.getDefault("PROXY_SERVER", ""));
jalview.util.BrowserLauncher.resetBrowser();
- if (nameLinks.size() > 0)
+ // save user-defined and selected links
+ String menuLinks = sequenceUrlLinks.writeUrlsAsString(true);
+ if (menuLinks.isEmpty())
+ {
+ Cache.applicationProperties.remove("SEQUENCE_LINKS");
+ }
+ else
{
- StringBuffer links = new StringBuffer();
- sequenceURLLinks = new Vector<String>();
- for (int i = 0; i < nameLinks.size(); i++)
- {
- sequenceURLLinks.addElement(nameLinks.elementAt(i) + "|"
- + urlLinks.elementAt(i));
- links.append(sequenceURLLinks.elementAt(i).toString());
- links.append("|");
- }
- // remove last "|"
- links.setLength(links.length() - 1);
Cache.applicationProperties.setProperty("SEQUENCE_LINKS",
- links.toString());
+ menuLinks.toString());
+ }
+
+ String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false);
+ if (nonMenuLinks.isEmpty())
+ {
+ Cache.applicationProperties.remove("STORED_LINKS");
}
else
{
- Cache.applicationProperties.remove("SEQUENCE_LINKS");
- sequenceURLLinks.clear();
+ Cache.applicationProperties.setProperty("STORED_LINKS",
+ nonMenuLinks.toString());
}
+ Cache.applicationProperties.setProperty("DEFAULT_URL",
+ sequenceUrlLinks.getDefaultUrlId());
+
Cache.applicationProperties.setProperty("USE_PROXY",
Boolean.toString(useProxy.isSelected()));
@Override
public void newLink_actionPerformed(ActionEvent e)
{
-
GSequenceLink link = new GSequenceLink();
boolean valid = false;
while (!valid)
{
if (link.checkValid())
{
- nameLinks.addElement(link.getName());
- urlLinks.addElement(link.getURL());
- updateLinkData();
- valid = true;
+ if (((UrlLinkTableModel) linkUrlTable.getModel())
+ .isUniqueName(link.getName()))
+ {
+ ((UrlLinkTableModel) linkUrlTable.getModel()).insertRow(
+ link.getName(), link.getURL());
+ valid = true;
+ }
+ else
+ {
+ link.notifyDuplicate();
+ continue;
+ }
}
}
else
{
GSequenceLink link = new GSequenceLink();
- int index = linkNameList.getSelectedIndex();
+ int index = linkUrlTable.getSelectedRow();
if (index == -1)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
- MessageManager.getString("label.no_link_selected"),
- MessageManager.getString("label.no_link_selected"),
- JvOptionPane.WARNING_MESSAGE);
+ // button no longer enabled if row is not selected
+ Cache.log.debug("Edit with no row selected in linkUrlTable");
return;
}
- link.setName(nameLinks.elementAt(index).toString());
- link.setURL(urlLinks.elementAt(index).toString());
+ link.setName(linkUrlTable.getValueAt(index, 0).toString());
+ link.setURL(linkUrlTable.getValueAt(index, 1).toString());
boolean valid = false;
while (!valid)
{
-
if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
- MessageManager.getString("label.new_sequence_url_link"),
+ MessageManager.getString("label.edit_sequence_url_link"),
JvOptionPane.OK_CANCEL_OPTION, -1, null) == JvOptionPane.OK_OPTION)
{
if (link.checkValid())
{
- nameLinks.setElementAt(link.getName(), index);
- urlLinks.setElementAt(link.getURL(), index);
- updateLinkData();
- valid = true;
+ if (((UrlLinkTableModel) linkUrlTable.getModel())
+ .isUniqueName(link.getName()))
+ {
+ linkUrlTable.setValueAt(link.getName(), index, 0);
+ linkUrlTable.setValueAt(link.getURL(), index, 1);
+ valid = true;
+ }
+ else
+ {
+ link.notifyDuplicate();
+ continue;
+ }
}
}
-
else
{
break;
@Override
public void deleteLink_actionPerformed(ActionEvent e)
{
- int index = linkNameList.getSelectedIndex();
+ int index = linkUrlTable.getSelectedRow();
+ int modelIndex = -1;
if (index == -1)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
- MessageManager.getString("label.no_link_selected"),
- MessageManager.getString("label.no_link_selected"),
- JvOptionPane.WARNING_MESSAGE);
+ // button no longer enabled if row is not selected
+ Cache.log.debug("Delete with no row selected in linkUrlTable");
return;
}
- nameLinks.removeElementAt(index);
- urlLinks.removeElementAt(index);
- updateLinkData();
- }
+ else
+ {
+ modelIndex = linkUrlTable.convertRowIndexToModel(index);
+ }
- void updateLinkData()
- {
- linkNameList.setListData(nameLinks);
- linkURLList.setListData(urlLinks);
+ // make sure we use the model index to delete, and not the table index
+ ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex);
}
+
@Override
public void defaultBrowser_mouseClicked(MouseEvent e)
{
return name.hashCode() + code.hashCode();
}
}
+
+ private class UrlListSelectionHandler implements ListSelectionListener
+ {
+
+ @Override
+ public void valueChanged(ListSelectionEvent e)
+ {
+ ListSelectionModel lsm = (ListSelectionModel) e.getSource();
+
+ int index = lsm.getMinSelectionIndex();
+ if (index == -1)
+ {
+ // no selection, so disable delete/edit buttons
+ editLink.setEnabled(false);
+ deleteLink.setEnabled(false);
+ return;
+ }
+ int modelIndex = linkUrlTable.convertRowIndexToModel(index);
+
+ // enable/disable edit and delete link buttons
+ if (((UrlLinkTableModel) linkUrlTable.getModel())
+ .isRowDeletable(modelIndex))
+ {
+ deleteLink.setEnabled(true);
+ }
+ else
+ {
+ deleteLink.setEnabled(false);
+ }
+
+ if (((UrlLinkTableModel) linkUrlTable.getModel())
+ .isRowEditable(modelIndex))
+ {
+ editLink.setEnabled(true);
+ }
+ else
+ {
+ editLink.setEnabled(false);
+ }
+ }
+}
}
JTextField urltf = new JTextField(url, 40);
JPanel panel = new JPanel(new BorderLayout());
JPanel pane12 = new JPanel(new BorderLayout());
- pane12.add(new JLabel(MessageManager.getString("label.url")),
+ pane12.add(new JLabel(MessageManager.getString("label.url:")),
BorderLayout.CENTER);
pane12.add(urltf, BorderLayout.EAST);
panel.add(pane12, BorderLayout.NORTH);
new Thread(new Runnable()
{
+ @Override
public void run()
{
// force a refresh.
new Thread(new Runnable()
{
+ @Override
public void run()
{
progressBar.setVisible(true);
new Thread(new Runnable()
{
+ @Override
public void run()
{
long ct = System.currentTimeMillis();
new Thread(new Runnable()
{
+ @Override
public void run()
{
updateWsMenuConfig(false);
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
-import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
+import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
/**
* Base class for the Preferences panel.
/*
* Connections tab components
*/
- protected JList linkURLList = new JList();
+ protected JTable linkUrlTable = new JTable();
+
+ protected JButton editLink = new JButton();
+
+ protected JButton deleteLink = new JButton();
+
+ protected JTextField filterTB = new JTextField();
+
+ protected JButton doReset = new JButton();
+
+ protected JButton userOnly = new JButton();
+
+ protected JLabel portLabel = new JLabel();
+
+ protected JLabel serverLabel = new JLabel();
protected JTextField proxyServerTB = new JTextField();
protected JTextField defaultBrowser = new JTextField();
- protected JList linkNameList = new JList();
-
protected JCheckBox useProxy = new JCheckBox();
protected JCheckBox usagestats = new JCheckBox();
{
JPanel connectTab = new JPanel();
connectTab.setLayout(new GridBagLayout());
- JLabel serverLabel = new JLabel();
+
+ // Label for browser text box
+ JLabel browserLabel = new JLabel();
+ browserLabel.setFont(LABEL_FONT);
+ browserLabel.setHorizontalAlignment(SwingConstants.TRAILING);
+ browserLabel.setText(MessageManager
+ .getString("label.default_browser_unix"));
+ defaultBrowser.setFont(LABEL_FONT);
+ defaultBrowser.setText("");
+
+ defaultBrowser.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ if (e.getClickCount() > 1)
+ {
+ defaultBrowser_mouseClicked(e);
+ }
+ }
+ });
+
+ JPanel proxyPanel = initConnTabProxyPanel();
+ JPanel linkPanel = initConnTabUrlLinks();
+ initConnTabCheckboxes();
+
+ // Add URL link panel
+ connectTab.add(linkPanel, new GridBagConstraints(0, 0, 2, 1, 2.0, 2.0,
+ GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(
+ 16, 0, 0, 12), 359, 32));
+
+ // Add default Browser text box
+ connectTab.add(browserLabel, new GridBagConstraints(0, 1, 1, 1, 0.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
+ new Insets(10, 0, 0, 0), 5, 1));
+
+ connectTab.add(defaultBrowser, new GridBagConstraints(1, 1, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(10, 0, 0, 10), 307, 1));
+
+ // Add proxy server panel
+ connectTab.add(proxyPanel, new GridBagConstraints(0, 2, 2, 1, 1.0, 0.0,
+ GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
+ new Insets(10, 0, 0, 12), 4, 10));
+
+ // Add usage stats, version check and questionnaire checkboxes
+ connectTab.add(usagestats, new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 4, 2), 70, 1));
+ connectTab.add(questionnaire, new GridBagConstraints(1, 3, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 4, 10), 70, 1));
+ connectTab.add(versioncheck, new GridBagConstraints(0, 4, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 4, 2), 70, 1));
+ return connectTab;
+ }
+
+ /**
+ * Initialises the proxy server panel in the Connections tab
+ *
+ * @return the proxy server panel
+ */
+ private JPanel initConnTabProxyPanel()
+ {
+ // Label for server text box
serverLabel.setText(MessageManager.getString("label.address"));
serverLabel.setHorizontalAlignment(SwingConstants.RIGHT);
serverLabel.setFont(LABEL_FONT);
+
+ // Proxy server and port text boxes
proxyServerTB.setFont(LABEL_FONT);
proxyPortTB.setFont(LABEL_FONT);
- JLabel portLabel = new JLabel();
+
+ // Label for Port text box
portLabel.setFont(LABEL_FONT);
portLabel.setHorizontalAlignment(SwingConstants.RIGHT);
portLabel.setText(MessageManager.getString("label.port"));
- JLabel browserLabel = new JLabel();
- browserLabel.setFont(new java.awt.Font("SansSerif", 0, 11));
- browserLabel.setHorizontalAlignment(SwingConstants.TRAILING);
- browserLabel.setText(MessageManager
- .getString("label.default_browser_unix"));
- defaultBrowser.setFont(LABEL_FONT);
- defaultBrowser.setText("");
+
+ // Use proxy server checkbox
+ useProxy.setFont(LABEL_FONT);
+ useProxy.setHorizontalAlignment(SwingConstants.RIGHT);
+ useProxy.setHorizontalTextPosition(SwingConstants.LEADING);
+ useProxy.setText(MessageManager.getString("label.use_proxy_server"));
+ useProxy.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ useProxy_actionPerformed();
+ }
+ });
+
+ // Make proxy server panel
+ JPanel proxyPanel = new JPanel();
+ TitledBorder titledBorder1 = new TitledBorder(
+ MessageManager.getString("label.proxy_server"));
+ proxyPanel.setBorder(titledBorder1);
+ proxyPanel.setLayout(new GridBagLayout());
+ proxyPanel.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
+ new Insets(0, 2, 2, 0), 5, 0));
+ proxyPanel.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
+ 0, 2, 0), 11, 0));
+ proxyPanel.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
+ GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
+ 2, 5, 185), 2, -4));
+ proxyPanel.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 2, 2), 54, 1));
+ proxyPanel.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0,
+ 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
+ new Insets(0, 2, 2, 0), 263, 1));
+
+ return proxyPanel;
+ }
+
+ /**
+ * Initialises the checkboxes in the Connections tab
+ */
+ private void initConnTabCheckboxes()
+ {
+ // Usage stats checkbox label
usagestats.setText(MessageManager
.getString("label.send_usage_statistics"));
usagestats.setFont(LABEL_FONT);
usagestats.setHorizontalAlignment(SwingConstants.RIGHT);
usagestats.setHorizontalTextPosition(SwingConstants.LEADING);
+
+ // Questionnaire checkbox label
questionnaire.setText(MessageManager
.getString("label.check_for_questionnaires"));
questionnaire.setFont(LABEL_FONT);
questionnaire.setHorizontalAlignment(SwingConstants.RIGHT);
questionnaire.setHorizontalTextPosition(SwingConstants.LEADING);
+
+ // Check for latest version checkbox label
versioncheck.setText(MessageManager
.getString("label.check_for_latest_version"));
versioncheck.setFont(LABEL_FONT);
versioncheck.setHorizontalAlignment(SwingConstants.RIGHT);
versioncheck.setHorizontalTextPosition(SwingConstants.LEADING);
+ }
+
+ /**
+ * Initialises the URL links panel in the Connection tab
+ *
+ * @return the URL links panel
+ */
+ private JPanel initConnTabUrlLinks()
+ {
+ // Set up table for Url links
+ linkUrlTable.setFillsViewportHeight(true);
+ linkUrlTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
+ linkUrlTable.setAutoCreateRowSorter(true);
+ linkUrlTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+ // adjust row height so radio buttons actually fit
+ // don't do this in the renderer, it causes the awt thread to activate
+ // constantly
+ JRadioButton temp = new JRadioButton();
+ linkUrlTable.setRowHeight(temp.getMinimumSize().height);
+
+ // Table in scrollpane so that the table is given a scrollbar
+ JScrollPane linkScrollPane = new JScrollPane(linkUrlTable);
+ linkScrollPane.setBorder(null);
+
+ // Panel for links functionality
+ JPanel linkPanel = new JPanel(new GridBagLayout());
+ linkPanel.setBorder(new TitledBorder(MessageManager
+ .getString("label.url_linkfrom_sequence_id")));
+
+ // Put the Url links panel together
+
+ // Buttons go at top right, resizing only resizes the blank space vertically
+ JPanel buttonPanel = initConnTabUrlButtons();
+ GridBagConstraints linkConstraints1 = new GridBagConstraints();
+ linkConstraints1.gridx = 1;
+ linkConstraints1.gridy = 0;
+ linkConstraints1.fill = GridBagConstraints.VERTICAL;
+ linkPanel.add(buttonPanel, linkConstraints1);
+
+ // Links table goes at top left, resizing resizes the table
+ GridBagConstraints linkConstraints2 = new GridBagConstraints();
+ linkConstraints2.gridx = 0;
+ linkConstraints2.gridy = 0;
+ linkConstraints2.weightx = 1.0;
+ linkConstraints2.weighty = 1.0;
+ linkConstraints2.fill = GridBagConstraints.BOTH;
+ linkPanel.add(linkScrollPane, linkConstraints2);
+
+ // Filter box and buttons goes at bottom left, resizing resizes the text box
+ JPanel filterPanel = initConnTabFilterPanel();
+ GridBagConstraints linkConstraints3 = new GridBagConstraints();
+ linkConstraints3.gridx = 0;
+ linkConstraints3.gridy = 1;
+ linkConstraints3.weightx = 1.0;
+ linkConstraints3.fill = GridBagConstraints.HORIZONTAL;
+ linkPanel.add(filterPanel, linkConstraints3);
+
+ return linkPanel;
+ }
+
+ private JPanel initConnTabFilterPanel()
+ {
+ // Filter textbox and reset button
+ JLabel filterLabel = new JLabel(
+ MessageManager.getString("label.filter"));
+ filterLabel.setFont(LABEL_FONT);
+ filterLabel.setHorizontalAlignment(SwingConstants.RIGHT);
+ filterLabel.setHorizontalTextPosition(SwingConstants.LEADING);
+
+ filterTB.setFont(LABEL_FONT);
+ filterTB.setText("");
+
+ doReset.setText(MessageManager.getString("action.showall"));
+ userOnly.setText(MessageManager.getString("action.customfilter"));
+
+ // Panel for filter functionality
+ JPanel filterPanel = new JPanel(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.fill = GridBagConstraints.NONE;
+ gbc.anchor = GridBagConstraints.WEST;
+
+ filterPanel.add(filterLabel, gbc);
+
+ GridBagConstraints gbc1 = new GridBagConstraints();
+ gbc1.gridx = 0;
+ gbc1.gridx = 1;
+ gbc1.fill = GridBagConstraints.HORIZONTAL;
+ gbc1.anchor = GridBagConstraints.WEST;
+ gbc1.weightx = 1.0;
+ filterPanel.add(filterTB, gbc1);
+
+ GridBagConstraints gbc2 = new GridBagConstraints();
+ gbc2.gridx = 2;
+ gbc2.fill = GridBagConstraints.NONE;
+ gbc2.anchor = GridBagConstraints.WEST;
+ filterPanel.add(doReset, gbc2);
+
+ GridBagConstraints gbc3 = new GridBagConstraints();
+ gbc3.gridx = 3;
+ gbc3.fill = GridBagConstraints.NONE;
+ gbc3.anchor = GridBagConstraints.WEST;
+ filterPanel.add(userOnly, gbc3);
+
+ return filterPanel;
+ }
+
+ private JPanel initConnTabUrlButtons()
+ {
+ // Buttons for new / edit / delete Url links
JButton newLink = new JButton();
newLink.setText(MessageManager.getString("action.new"));
newLink.addActionListener(new java.awt.event.ActionListener()
newLink_actionPerformed(e);
}
});
- JButton editLink = new JButton();
+
editLink.setText(MessageManager.getString("action.edit"));
editLink.addActionListener(new java.awt.event.ActionListener()
{
editLink_actionPerformed(e);
}
});
- JButton deleteLink = new JButton();
+
deleteLink.setText(MessageManager.getString("action.delete"));
deleteLink.addActionListener(new java.awt.event.ActionListener()
{
}
});
- linkURLList.addListSelectionListener(new ListSelectionListener()
- {
- @Override
- public void valueChanged(ListSelectionEvent e)
- {
- int index = linkURLList.getSelectedIndex();
- linkNameList.setSelectedIndex(index);
- }
- });
+ // no current selection, so initially disable delete/edit buttons
+ editLink.setEnabled(false);
+ deleteLink.setEnabled(false);
- linkNameList.addListSelectionListener(new ListSelectionListener()
- {
- @Override
- public void valueChanged(ListSelectionEvent e)
- {
- int index = linkNameList.getSelectedIndex();
- linkURLList.setSelectedIndex(index);
- }
- });
+ // Panels for new/edit/delete link buttons
+ // buttonContent prevents the buttons from being resized when the window is
+ JPanel buttonContent = new JPanel(new GridLayout(0, 1, 0, 0));
+ JPanel buttonPanel = new JPanel(new BorderLayout());
- JScrollPane linkScrollPane = new JScrollPane();
- linkScrollPane.setBorder(null);
- JPanel linkPanel = new JPanel();
- linkPanel.setBorder(new TitledBorder(MessageManager
- .getString("label.url_linkfrom_sequence_id")));
- linkPanel.setLayout(new BorderLayout());
- GridLayout gridLayout1 = new GridLayout();
- JPanel editLinkButtons = new JPanel();
- editLinkButtons.setLayout(gridLayout1);
- gridLayout1.setRows(3);
- linkNameList.setFont(LABEL_FONT);
- linkNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- BorderLayout borderLayout3 = new BorderLayout();
- JPanel linkPanel2 = new JPanel();
- linkPanel2.setLayout(borderLayout3);
- linkURLList.setFont(LABEL_FONT);
- linkURLList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ buttonContent.add(newLink, null);
+ buttonContent.add(editLink, null);
+ buttonContent.add(deleteLink, null);
+ buttonPanel.add(buttonContent, BorderLayout.NORTH);
- defaultBrowser.addMouseListener(new MouseAdapter()
- {
- @Override
- public void mouseClicked(MouseEvent e)
- {
- if (e.getClickCount() > 1)
- {
- defaultBrowser_mouseClicked(e);
- }
- }
- });
- useProxy.setFont(LABEL_FONT);
- useProxy.setHorizontalAlignment(SwingConstants.RIGHT);
- useProxy.setHorizontalTextPosition(SwingConstants.LEADING);
- useProxy.setText(MessageManager.getString("label.use_proxy_server"));
- useProxy.addActionListener(new ActionListener()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- useProxy_actionPerformed();
- }
- });
- linkPanel.add(editLinkButtons, BorderLayout.EAST);
- editLinkButtons.add(newLink, null);
- editLinkButtons.add(editLink, null);
- editLinkButtons.add(deleteLink, null);
- linkPanel.add(linkScrollPane, BorderLayout.CENTER);
- linkScrollPane.getViewport().add(linkPanel2, null);
- linkPanel2.add(linkURLList, BorderLayout.CENTER);
- linkPanel2.add(linkNameList, BorderLayout.WEST);
- JPanel jPanel1 = new JPanel();
- TitledBorder titledBorder1 = new TitledBorder(
- MessageManager.getString("label.proxy_server"));
- jPanel1.setBorder(titledBorder1);
- jPanel1.setLayout(new GridBagLayout());
- jPanel1.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
- 2, 4, 0), 5, 0));
- jPanel1.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
- 0, 4, 0), 11, 6));
- connectTab.add(linkPanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0,
- GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
- 16, 0, 0, 12), 359, -17));
- connectTab.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0,
- GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
- 21, 0, 35, 12), 4, 6));
- connectTab.add(browserLabel, new GridBagConstraints(0, 1, 1, 1, 0.0,
- 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE,
- new Insets(16, 0, 0, 0), 5, 1));
- jPanel1.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
- 2, 5, 185), 2, -4));
- jPanel1.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 54, 1));
- jPanel1.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 0), 263, 1));
- connectTab.add(defaultBrowser, new GridBagConstraints(1, 1, 1, 1, 1.0,
- 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(15, 0, 0, 15), 307, 1));
- connectTab.add(usagestats, new GridBagConstraints(0, 4, 1, 1, 1.0, 0.0,
- GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 70, 1));
- connectTab.add(questionnaire, new GridBagConstraints(1, 4, 1, 1, 1.0,
- 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 70, 1));
- connectTab.add(versioncheck, new GridBagConstraints(0, 5, 1, 1, 1.0,
- 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
- new Insets(0, 2, 4, 2), 70, 1));
- return connectTab;
+ return buttonPanel;
}
/**
public void useProxy_actionPerformed()
{
- proxyServerTB.setEnabled(useProxy.isSelected());
- proxyPortTB.setEnabled(useProxy.isSelected());
+ boolean enabled = useProxy.isSelected();
+ portLabel.setEnabled(enabled);
+ serverLabel.setEnabled(enabled);
+ proxyServerTB.setEnabled(enabled);
+ proxyPortTB.setEnabled(enabled);
}
+ /**
+ * Customer renderer for JTable: supports column of radio buttons
+ */
+ public class RadioButtonRenderer extends JRadioButton implements
+ TableCellRenderer
+ {
+ public RadioButtonRenderer()
+ {
+ setHorizontalAlignment(CENTER);
+ setToolTipText(MessageManager.getString("label.urltooltip"));
+ }
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table,
+ Object value, boolean isSelected, boolean hasFocus, int row,
+ int column)
+ {
+ setSelected((boolean) value);
+
+ // set colours to match rest of table
+ if (isSelected)
+ {
+ setBackground(table.getSelectionBackground());
+ setForeground(table.getSelectionForeground());
+ }
+ else
+ {
+ setBackground(table.getBackground());
+ setForeground(table.getForeground());
+ }
+ return this;
+ }
+ }
+
+ /**
+ * Customer cell editor for JTable: supports column of radio buttons in
+ * conjunction with renderer
+ */
+ public class RadioButtonEditor extends AbstractCellEditor implements
+ TableCellEditor
+ {
+ private JRadioButton button = new JRadioButton();
+
+ public RadioButtonEditor()
+ {
+ button.setHorizontalAlignment(SwingConstants.CENTER);
+ this.button.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ fireEditingStopped();
+ }
+ });
+ }
+
+ @Override
+ public Component getTableCellEditorComponent(JTable table,
+ Object value, boolean isSelected, int row, int column)
+ {
+ button.setSelected((boolean) value);
+ return button;
+ }
+
+ @Override
+ public Object getCellEditorValue()
+ {
+ return button.isSelected();
+ }
+
+ }
}
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
-import java.awt.Panel;
import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.BorderFactory;
+import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
-public class GSequenceLink extends Panel
+public class GSequenceLink extends JPanel
{
+
+ JTextField nameTB = new JTextField();
+
+ JTextField urlTB = new JTextField();
+
+ JButton insertSeq = new JButton();
+
+ JButton insertDBAcc = new JButton();
+
+ JLabel insert = new JLabel();
+
+ JLabel jLabel1 = new JLabel();
+
+ JLabel jLabel2 = new JLabel();
+
+ JLabel jLabel3 = new JLabel();
+
+ JLabel jLabel4 = new JLabel();
+
+ JLabel jLabel5 = new JLabel();
+
+ JLabel jLabel6 = new JLabel();
+
+ JPanel jPanel1 = new JPanel();
+
+ GridBagLayout gridBagLayout1 = new GridBagLayout();
+
public GSequenceLink()
{
try
urlTB_keyTyped(e);
}
});
+
+ insertSeq.setLocation(77, 75);
+ insertSeq.setSize(141, 24);
+ insertSeq.setText(MessageManager.getString("action.seq_id"));
+ insertSeq.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ insertSeq_action(e);
+ }
+ });
+
+ insertDBAcc.setLocation(210, 75);
+ insertDBAcc.setSize(141, 24);
+ insertDBAcc.setText(MessageManager.getString("action.db_acc"));
+ insertDBAcc.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ insertDBAcc_action(e);
+ }
+ });
+
+ insert.setText(MessageManager.getString("label.insert"));
+ insert.setFont(JvSwingUtils.getLabelFont());
+ insert.setHorizontalAlignment(SwingConstants.RIGHT);
+ insert.setBounds(17, 78, 58, 16);
+
jLabel1.setFont(JvSwingUtils.getLabelFont());
jLabel1.setHorizontalAlignment(SwingConstants.TRAILING);
jLabel1.setText(MessageManager.getString("label.link_name"));
jLabel1.setBounds(new Rectangle(4, 10, 71, 24));
jLabel2.setFont(JvSwingUtils.getLabelFont());
jLabel2.setHorizontalAlignment(SwingConstants.TRAILING);
- jLabel2.setText(MessageManager.getString("label.url"));
+ jLabel2.setText(MessageManager.getString("label.url:"));
jLabel2.setBounds(new Rectangle(17, 37, 54, 27));
jLabel3.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
jLabel3.setText(MessageManager.getString("label.use_sequence_id_1"));
- jLabel3.setBounds(new Rectangle(21, 72, 351, 15));
+ jLabel3.setBounds(new Rectangle(21, 102, 351, 15));
jLabel4.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
jLabel4.setText(MessageManager.getString("label.use_sequence_id_2"));
- jLabel4.setBounds(new Rectangle(21, 88, 351, 15));
+ jLabel4.setBounds(new Rectangle(21, 118, 351, 15));
jLabel5.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
jLabel5.setText(MessageManager.getString("label.use_sequence_id_3"));
- jLabel5.setBounds(new Rectangle(21, 106, 351, 15));
+ jLabel5.setBounds(new Rectangle(21, 136, 351, 15));
String lastLabel = MessageManager.getString("label.use_sequence_id_4");
if (lastLabel.length() > 0)
// e.g. Spanish version has longer text
jLabel6.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
jLabel6.setText(lastLabel);
- jLabel6.setBounds(new Rectangle(21, 122, 351, 15));
+ jLabel6.setBounds(new Rectangle(21, 152, 351, 15));
}
jPanel1.setBorder(BorderFactory.createEtchedBorder());
jPanel1.add(jLabel1);
jPanel1.add(nameTB);
jPanel1.add(urlTB);
+ jPanel1.add(insertSeq);
+ jPanel1.add(insertDBAcc);
+ jPanel1.add(insert);
jPanel1.add(jLabel2);
jPanel1.add(jLabel3);
jPanel1.add(jLabel4);
jPanel1.add(jLabel5);
- int height = 130;
+ int height = 160;
if (lastLabel.length() > 0)
{
jPanel1.add(jLabel6);
- height = 146;
+ height = 176;
}
this.add(jPanel1, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
return false;
}
- JTextField nameTB = new JTextField();
-
- JTextField urlTB = new JTextField();
-
- JLabel jLabel1 = new JLabel();
-
- JLabel jLabel2 = new JLabel();
-
- JLabel jLabel3 = new JLabel();
-
- JLabel jLabel4 = new JLabel();
-
- JLabel jLabel5 = new JLabel();
-
- JLabel jLabel6 = new JLabel();
-
- JPanel jPanel1 = new JPanel();
-
- GridBagLayout gridBagLayout1 = new GridBagLayout();
+ public void notifyDuplicate()
+ {
+ JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop,
+ MessageManager.getString("warn.name_cannot_be_duplicate"),
+ MessageManager.getString("label.invalid_name"),
+ JvOptionPane.WARNING_MESSAGE);
+ }
public void nameTB_keyTyped(KeyEvent e)
{
// }
}
+
+ public void insertSeq_action(ActionEvent e)
+ {
+ insertIntoUrl(insertSeq.getText());
+ }
+
+ public void insertDBAcc_action(ActionEvent e)
+ {
+ insertIntoUrl(insertDBAcc.getText());
+ }
+
+ private void insertIntoUrl(String insertion)
+ {
+ int pos = urlTB.getCaretPosition();
+ String text = urlTB.getText();
+ String newText = text.substring(0, pos) + insertion
+ + text.substring(pos);
+ urlTB.setText(newText);
+ }
}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.DELIM;
+import static jalview.util.UrlConstants.SEP;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+
+import jalview.util.MessageManager;
+import jalview.util.UrlConstants;
+import jalview.util.UrlLink;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ *
+ * Implements the UrlProviderI interface for a UrlProvider object which serves
+ * custom URLs defined by the user
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class CustomUrlProvider extends UrlProviderImpl
+{
+ // Default sequence URL link label for SRS
+ private static final String SRS_LABEL = "SRS";
+
+ // map of string ids to urlLinks (selected)
+ private HashMap<String, UrlLink> selectedUrls;
+
+ // map of string ids to urlLinks (not selected)
+ private HashMap<String, UrlLink> nonselectedUrls;
+
+ /**
+ * Construct UrlProvider for custom (user-entered) URLs
+ *
+ * @param inMenuUrlList
+ * list of URLs set to be displayed in menu, in form stored in Cache.
+ * i.e. SEP delimited string
+ * @param storedUrlList
+ * list of custom URLs entered by user but not currently displayed in
+ * menu, in form stored in Cache
+ */
+ public CustomUrlProvider(String inMenuUrlList, String storedUrlList)
+ {
+ try
+ {
+ selectedUrls = parseUrlStrings(inMenuUrlList);
+ nonselectedUrls = parseUrlStrings(storedUrlList);
+ } catch (Exception ex)
+ {
+ System.out
+ .println(ex.getMessage() + "\nError parsing sequence links");
+ }
+ }
+
+ /**
+ * Construct UrlProvider for custom (user-entered) URLs
+ *
+ * @param urlList
+ * list of URLs to be displayed in menu, as (label,url) pairs
+ * @param storedUrlList
+ * list of custom URLs entered by user but not currently displayed in
+ * menu, as (label,url) pairs
+ */
+ public CustomUrlProvider(Map<String, String> inMenuUrlList,
+ Map<String, String> storedUrlList)
+ {
+ try
+ {
+ selectedUrls = parseUrlList(inMenuUrlList);
+ nonselectedUrls = parseUrlList(storedUrlList);
+ } catch (Exception ex)
+ {
+ System.out
+ .println(ex.getMessage() + "\nError parsing sequence links");
+ }
+ }
+
+ private HashMap<String, UrlLink> parseUrlStrings(String urlStrings)
+ {
+ // cachedUrlList is in form <label>|<url>|<label>|<url>...
+ // parse cachedUrlList into labels (used as id) and url links
+ HashMap<String, UrlLink> urls = new HashMap<String, UrlLink>();
+
+ StringTokenizer st = new StringTokenizer(urlStrings, SEP);
+ while (st.hasMoreElements())
+ {
+ String name = st.nextToken();
+
+ if (!isMiriamId(name))
+ {
+ // this one of our custom urls
+ String url = st.nextToken();
+ // check for '|' within a regex
+ int rxstart = url.indexOf(DELIM + DB_ACCESSION + DELIM);
+ if (rxstart == -1)
+ {
+ rxstart = url.indexOf(DELIM + SEQUENCE_ID + DELIM);
+ }
+ while (rxstart == -1 && url.indexOf("/=" + DELIM) == -1
+ && st.hasMoreTokens())
+ {
+ url = url + SEP + st.nextToken();
+ }
+ urls.put(name, new UrlLink(name + SEP + url));
+ }
+ }
+ upgradeOldLinks(urls);
+ return urls;
+ }
+
+ private HashMap<String, UrlLink> parseUrlList(Map<String, String> urlList)
+ {
+ HashMap<String, UrlLink> urls = new HashMap<String, UrlLink>();
+ if (urlList == null)
+ {
+ return urls;
+ }
+
+ Iterator<Map.Entry<String, String>> it = urlList.entrySet().iterator();
+ while (it.hasNext())
+ {
+ Map.Entry<String, String> pair = it.next();
+ urls.put(pair.getKey(),
+ new UrlLink(pair.getKey() + SEP + pair.getValue()));
+ }
+ upgradeOldLinks(urls);
+ return urls;
+ }
+
+ /*
+ * Upgrade any legacy links which may have been left lying around
+ */
+ private void upgradeOldLinks(HashMap<String, UrlLink> urls)
+ {
+ // upgrade old SRS link
+ if (urls.containsKey(SRS_LABEL))
+ {
+ urls.remove(SRS_LABEL);
+ urls.put(UrlConstants.DEFAULT_LABEL, new UrlLink(UrlConstants.DEFAULT_STRING));
+ }
+ }
+
+ @Override
+ public Vector<String> getLinksForMenu()
+ {
+ Vector<String> links = new Vector<String>();
+ Iterator<Map.Entry<String, UrlLink>> it = selectedUrls.entrySet()
+ .iterator();
+ while (it.hasNext())
+ {
+ Map.Entry<String, UrlLink> pair = it.next();
+ links.add(pair.getValue().toString());
+ }
+ return links;
+ }
+
+ @Override
+ public List<UrlLinkDisplay> getLinksForTable()
+ {
+ ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
+ displayLinks = getLinksForTable(selectedUrls, true);
+ displayLinks.addAll(getLinksForTable(nonselectedUrls, false));
+ return displayLinks;
+ }
+
+ private ArrayList<UrlLinkDisplay> getLinksForTable(
+ HashMap<String, UrlLink> urlList, boolean selected)
+ {
+ return super.getLinksForTable(urlList, null, selected);
+ }
+
+ @Override
+ public boolean setDefaultUrl(String id)
+ {
+ if (selectedUrls.containsKey(id))
+ {
+ defaultUrl = id;
+ }
+ else if (nonselectedUrls.containsKey(id))
+ {
+ defaultUrl = id;
+ }
+ else
+ {
+ defaultUrl = null;
+ }
+
+ return (defaultUrl != null);
+ }
+
+ @Override
+ public String writeUrlsAsString(boolean selected)
+ {
+ StringBuffer links = new StringBuffer();
+ HashMap<String, UrlLink> urls;
+ if (selected)
+ {
+ urls = selectedUrls;
+ }
+ else
+ {
+ urls = nonselectedUrls;
+ }
+ if (urls.size() > 0)
+ {
+ for (Entry<String, UrlLink> entry : urls.entrySet())
+ {
+ links.append(entry.getValue().toString());
+ links.append(SEP);
+ }
+
+ // remove last SEP
+ links.setLength(links.length() - 1);
+ }
+ else
+ {
+ urls.clear();
+ }
+ return links.toString();
+ }
+
+ @Override
+ public String getDefaultUrl(String seqid)
+ {
+ String result = super.getDefaultUrl(seqid, selectedUrls);
+ if (result == null)
+ {
+ result = super.getDefaultUrl(seqid, nonselectedUrls);
+ }
+ return result;
+ }
+
+ @Override
+ public String getDefaultUrlId()
+ {
+ return defaultUrl;
+ }
+
+ @Override
+ public String getDefaultTarget(String seqid)
+ {
+ return selectedUrls.get(defaultUrl).getTarget();
+ }
+
+ @Override
+ public void setUrlData(List<UrlLinkDisplay> links)
+ {
+ HashMap<String, UrlLink> unselurls = new HashMap<String, UrlLink>();
+ HashMap<String, UrlLink> selurls = new HashMap<String, UrlLink>();
+
+ Iterator<UrlLinkDisplay> it = links.iterator();
+ while (it.hasNext())
+ {
+ UrlLinkDisplay link = it.next();
+
+ // MIRIAM ids will be handled by a different UrlProvider class
+ if (!isMiriamId(link.getId()))
+ {
+ // don't allow duplicate key names as entries will be overwritten
+ if (unselurls.containsKey(link.getId())
+ || selurls.containsKey(link.getId()))
+ {
+ throw new IllegalArgumentException(MessageManager.formatMessage(
+ "exception.url_cannot_have_duplicate_id", link.getId()));
+ }
+ if (link.getIsSelected())
+ {
+ selurls.put(link.getId(),
+ new UrlLink(link.getName() + SEP + link.getUrl()));
+ }
+ else
+ {
+ unselurls.put(link.getId(), new UrlLink(link.getName() + SEP
+ + link.getUrl()));
+ }
+ // sort out default and selected ids
+ if (link.getIsDefault())
+ {
+ setDefaultUrl(link.getId());
+ }
+ }
+
+ }
+ nonselectedUrls = unselurls;
+ selectedUrls = selurls;
+ }
+
+ @Override
+ public String chooseDefaultUrl()
+ {
+ // unilaterally set the default id to the EMBL_EBI link
+ if ((!nonselectedUrls.containsKey(UrlConstants.DEFAULT_LABEL))
+ && (!selectedUrls.containsKey(UrlConstants.DEFAULT_LABEL)))
+ {
+ selectedUrls.put(UrlConstants.DEFAULT_LABEL, new UrlLink(
+ UrlConstants.DEFAULT_STRING));
+ }
+ defaultUrl = UrlConstants.DEFAULT_LABEL;
+ return UrlConstants.DEFAULT_LABEL;
+ }
+
+ @Override
+ public boolean contains(String id)
+ {
+ return (selectedUrls.containsKey(id) || nonselectedUrls.containsKey(id));
+ }
+
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+/**
+ * Holds settings for identifiers.org e.g. url, download location
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class IdOrgSettings
+{
+ private static String url;
+
+ private static String location;
+
+ public static void setUrl(String seturl)
+ {
+ url = seturl;
+ }
+
+ public static void setDownloadLocation(String setloc)
+ {
+ location = setloc;
+ }
+
+ public static String getUrl()
+ {
+ return url;
+ }
+
+ public static String getDownloadLocation()
+ {
+ return location;
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.DELIM;
+import static jalview.util.UrlConstants.SEP;
+
+import jalview.util.UrlLink;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+/**
+ *
+ * Implements the UrlProviderI interface for a UrlProvider object which serves
+ * URLs from identifiers.org
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class IdentifiersUrlProvider extends UrlProviderImpl
+{
+
+ // map of string ids to urls
+ private HashMap<String, UrlLink> urls;
+
+ // list of selected urls
+ private ArrayList<String> selectedUrls;
+
+ public IdentifiersUrlProvider(String cachedUrlList)
+ {
+ urls = readIdentifiers(IdOrgSettings.getDownloadLocation());
+ selectedUrls = new ArrayList<String>();
+ checkSelectionMatchesUrls(cachedUrlList);
+ }
+
+ /**
+ * Read data from an identifiers.org download file
+ *
+ * @param idFileName
+ * name of identifiers.org download file
+ * @return hashmap of identifiers.org data, keyed by MIRIAM id
+ */
+ private HashMap<String, UrlLink> readIdentifiers(
+ String idFileName)
+ {
+ JSONParser parser = new JSONParser();
+
+ // identifiers.org data
+ HashMap<String, UrlLink> idData = new HashMap<String, UrlLink>();
+
+ try
+ {
+ FileReader reader = new FileReader(idFileName);
+
+ JSONArray jsonarray = (JSONArray) parser.parse(reader);
+
+ // loop over each entry in JSON array and build HashMap entry
+ for (int i = 0; i < jsonarray.size(); i++)
+ {
+ JSONObject item = (JSONObject) jsonarray.get(i);
+
+ String url = (String) item.get("url") + "/" + DELIM + DB_ACCESSION
+ + DELIM;
+ UrlLink link = new UrlLink((String) item.get("name") + SEP + url);
+ idData.put((String) item.get("id"), link);
+ }
+ } catch (FileNotFoundException e)
+ {
+ e.printStackTrace();
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ } catch (ParseException e)
+ {
+ e.printStackTrace();
+ }
+ return idData;
+ }
+
+ private void checkSelectionMatchesUrls(String cachedUrlList)
+ {
+ StringTokenizer st = new StringTokenizer(cachedUrlList, SEP);
+ while (st.hasMoreElements())
+ {
+ String id = st.nextToken();
+
+ if (isMiriamId(id))
+ {
+ // this is an identifiers.org MIRIAM id
+ if (urls.containsKey(id))
+ {
+ selectedUrls.add(id);
+ }
+ }
+ }
+
+ // reset defaultUrl in case it is no longer selected
+ setDefaultUrl(defaultUrl);
+ }
+
+ @Override
+ public boolean setDefaultUrl(String id)
+ {
+ if (urls.containsKey(id))
+ {
+ defaultUrl = id;
+ }
+ else
+ {
+ defaultUrl = null;
+ }
+
+ return urls.containsKey(id);
+ }
+
+ @Override
+ public String writeUrlsAsString(boolean selected)
+ {
+ if (!selected)
+ {
+ return ""; // we don't cache unselected identifiers.org urls
+ }
+
+ StringBuffer links = new StringBuffer();
+ if (!selectedUrls.isEmpty())
+ {
+ for (String k : selectedUrls)
+ {
+ links.append(k);
+ links.append(SEP);
+ }
+ // remove last SEP
+ links.setLength(links.length() - 1);
+ }
+ return links.toString();
+ }
+
+ @Override
+ public Vector<String> getLinksForMenu()
+ {
+ Vector<String> links = new Vector<String>();
+ for (String key : selectedUrls)
+ {
+ links.add(urls.get(key).toString());
+ }
+ return links;
+ }
+
+ @Override
+ public List<UrlLinkDisplay> getLinksForTable()
+ {
+ return super.getLinksForTable(urls, selectedUrls, false);
+ }
+
+ @Override
+ public void setUrlData(List<UrlLinkDisplay> links)
+ {
+ selectedUrls = new ArrayList<String>();
+
+ Iterator<UrlLinkDisplay> it = links.iterator();
+ while (it.hasNext())
+ {
+ UrlLinkDisplay link = it.next();
+
+ // Handle links with MIRIAM ids only
+ if (isMiriamId(link.getId()))
+ {
+ // select/deselect links accordingly and set default url
+ if (urls.containsKey(link.getId()))
+ {
+ if (link.getIsSelected())
+ {
+ selectedUrls.add(link.getId());
+ }
+ if (link.getIsDefault())
+ {
+ setDefaultUrl(link.getId());
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public String getDefaultUrl(String seqid)
+ {
+ return super.getDefaultUrl(seqid, urls);
+ }
+
+ @Override
+ public String getDefaultUrlId()
+ {
+ return defaultUrl;
+ }
+
+ @Override
+ public String getDefaultTarget(String seqid)
+ {
+ return null;
+ }
+
+ @Override
+ public String chooseDefaultUrl()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean contains(String id)
+ {
+ return (urls.containsKey(id));
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import jalview.util.MessageManager;
+import jalview.util.UrlLink;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * UrlLink table row definition
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+
+public class UrlLinkDisplay
+{
+ private String id; // id is not supplied to display, but used to identify
+ // entries when saved
+
+ private boolean isDefault;
+
+ private boolean isSelected;
+
+ private UrlLink link;
+
+ // Headers for columns in table
+ private final static List<String> colNames = new ArrayList<String>()
+ {
+ {
+ add(MessageManager.formatMessage("label.name"));
+ add(MessageManager.formatMessage("label.url"));
+ add(MessageManager.formatMessage("label.inmenu"));
+ add(MessageManager.formatMessage("label.default"));
+ add(MessageManager.formatMessage("label.id"));
+ }
+ };
+
+ // column positions
+ public final static int NAME = 0;
+
+ public final static int URL = 1;
+
+ public final static int SELECTED = 2;
+
+ public final static int DEFAULT = 3;
+
+ public final static int ID = 4;
+
+ public UrlLinkDisplay(String rowId, UrlLink rowLink,
+ boolean rowSelected, boolean rowDefault)
+ {
+ id = rowId;
+ isDefault = rowDefault;
+ isSelected = rowSelected;
+
+ link = rowLink;
+ }
+
+ // getters/setters
+ public String getId()
+ {
+ return id;
+ }
+
+ public String getName()
+ {
+ return link.getLabel();
+ }
+
+ public String getUrl()
+ {
+ return link.getUrlWithToken();
+ }
+
+ public boolean getIsDefault()
+ {
+ return isDefault;
+ }
+
+ public boolean getIsSelected()
+ {
+ return isSelected;
+ }
+
+ public void setName(String name)
+ {
+ link.setLabel(name);
+ }
+
+ public void setUrl(String rowUrl)
+ {
+ link = new UrlLink(getName(), rowUrl);
+ }
+
+ public void setIsDefault(boolean rowDefault)
+ {
+ isDefault = rowDefault;
+ }
+
+ public void setIsSelected(boolean rowSelected)
+ {
+ isSelected = rowSelected;
+ }
+
+ public Object getValue(int index)
+ {
+ switch (index)
+ {
+ case ID:
+ return id;
+ case URL:
+ return getUrl();
+ case DEFAULT:
+ return isDefault;
+ case SELECTED:
+ return isSelected;
+ case NAME:
+ return getName();
+ default:
+ return null;
+ }
+ }
+
+ public void setValue(int index, Object value)
+ {
+ switch (index)
+ {
+ case ID:
+ id = (String) value;
+ break;
+ case URL:
+ setUrl((String) value);
+ break;
+ case DEFAULT:
+ isDefault = (boolean) value;
+ break;
+ case SELECTED:
+ isSelected = (boolean) value;
+ break;
+ case NAME:
+ setName((String) value);
+ break;
+ default:
+ // do nothing
+ }
+ }
+
+ /**
+ * Identify editable columns
+ *
+ * @param index
+ * index of column
+ * @return whether column can be edited in table
+ */
+ public boolean isEditable(int index)
+ {
+ if (index == DEFAULT)
+ {
+ // default link must not be a $DB_ACCESSION$ link
+ // so only allow editing if it is not
+ return (!link.usesDBAccession());
+ }
+ else if (index == SELECTED)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Get list of column names to display in UI
+ *
+ * @return column names
+ */
+ public static List<String> getDisplayColumnNames()
+ {
+ // Display names between NAME and ID (excludes ID)
+ return colNames.subList(NAME, ID);
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import jalview.bin.Cache;
+import jalview.urls.api.UrlProviderI;
+import jalview.util.UrlLink;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.swing.RowFilter.Entry;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableModel;
+
+/**
+ * TableModel for UrlLinks table
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+
+public class UrlLinkTableModel extends AbstractTableModel
+{
+ // local storage of data
+ private List<UrlLinkDisplay> data;
+
+ // supplier of url data
+ private UrlProviderI dataProvider;
+
+ // list of columns to display in table in correct order
+ private List<String> displayColumns;
+
+ // row in table which is currently the default
+ private int defaultRow;
+
+ /**
+ * UrlLinkTableModel constructor
+ *
+ * @param baseData
+ * base data set to be presented in table
+ * @param entryNames
+ * keys of entries in baseData's nested hashmap. Should match order
+ * in displayColNames
+ * @param displayColNames
+ * names of columns to display in order.
+ * @param keyColName
+ * name of column corresponding to keys in baseData
+ */
+ public UrlLinkTableModel(UrlProviderI baseData)
+ {
+ dataProvider = baseData;
+ data = baseData.getLinksForTable();
+ displayColumns = UrlLinkDisplay.getDisplayColumnNames();
+
+ // find the default row
+ defaultRow = 0;
+ Iterator<UrlLinkDisplay> it = data.iterator();
+ while (it.hasNext())
+ {
+ if (it.next().getIsDefault())
+ {
+ break;
+ }
+ else
+ {
+ defaultRow++;
+ }
+ }
+
+ // set up listener which updates data source when table changes
+ this.addTableModelListener(new TableModelListener()
+ {
+ @Override
+ public void tableChanged(TableModelEvent e)
+ {
+ try
+ {
+ // update the UrlProvider from data list
+ dataProvider.setUrlData(data);
+ } catch (IllegalArgumentException ex)
+ {
+ Cache.log.error(ex.getMessage());
+ }
+ }
+ });
+
+ }
+
+ @Override
+ public int getRowCount()
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+ else
+ {
+ return data.size();
+ }
+ }
+
+ @Override
+ public int getColumnCount()
+ {
+ return displayColumns.size();
+ }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex)
+ {
+ return data.get(rowIndex).getValue(columnIndex);
+ }
+
+ @Override
+ public boolean isCellEditable(int rowIndex, int columnIndex)
+ {
+ return data.get(rowIndex).isEditable(columnIndex);
+ }
+
+ /**
+ * Determine if a row is editable indirectly (rather than directly in table as
+ * in isCellEditable)
+ *
+ * @param rowIndex
+ * @return true if row can be edited indirectly
+ */
+ public boolean isRowEditable(int rowIndex)
+ {
+ // to edit, row must be a user entered row
+ return (dataProvider.isUserEntry(data.get(rowIndex).getId()));
+ }
+
+ /**
+ * Determine if a row is deletable
+ *
+ * @param rowIndex
+ * the row to be tested
+ * @return true if row can be deleted
+ */
+ public boolean isRowDeletable(int rowIndex)
+ {
+ // to delete, row must be a user entered row, and not the default row
+ return (dataProvider.isUserEntry(data.get(rowIndex).getId()) && !data
+ .get(rowIndex).getIsDefault());
+ }
+
+ @Override
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex)
+ {
+ if (columnIndex == UrlLinkDisplay.DEFAULT)
+ {
+ // Default url column: exactly one row must always be true
+ if (rowIndex != defaultRow)
+ {
+ // selected row is not currently the default
+ // set the current default to false
+ data.get(defaultRow).setValue(columnIndex, false);
+ fireTableRowsUpdated(defaultRow, defaultRow);
+
+ // set the default to be the selected row
+ defaultRow = rowIndex;
+ data.get(rowIndex).setValue(columnIndex, aValue);
+
+ fireTableRowsUpdated(rowIndex, rowIndex);
+ }
+ }
+ else
+ {
+ data.get(rowIndex).setValue(columnIndex, aValue);
+ fireTableRowsUpdated(rowIndex, rowIndex);
+ }
+ }
+
+ @Override
+ public Class<?> getColumnClass(int columnIndex)
+ {
+ return getValueAt(0, columnIndex).getClass();
+ }
+
+ @Override
+ public String getColumnName(int columnIndex)
+ {
+ return displayColumns.get(columnIndex);
+ }
+
+ public void removeRow(int rowIndex)
+ {
+ // remove the row from data
+ data.remove(rowIndex);
+
+ // update default row
+ if (defaultRow > rowIndex)
+ {
+ defaultRow--;
+ }
+
+ // fire update which will update data source
+ fireTableRowsDeleted(rowIndex, rowIndex);
+ }
+
+ public int insertRow(String name, String url)
+ {
+ // add a row to the data
+ UrlLink link = new UrlLink(name, url);
+ UrlLinkDisplay u = new UrlLinkDisplay(name, link, true, false);
+ int index = data.size();
+ data.add(u);
+
+ // fire update which will update data source
+ fireTableRowsInserted(index, index);
+ return index;
+ }
+
+ public int getDefaultColumn()
+ {
+ return UrlLinkDisplay.DEFAULT;
+ }
+
+ public int getNameColumn()
+ {
+ return UrlLinkDisplay.NAME;
+ }
+
+ public int getIdColumn()
+ {
+ return UrlLinkDisplay.ID;
+ }
+
+ public int getUrlColumn()
+ {
+ return UrlLinkDisplay.URL;
+ }
+
+ public int getSelectedColumn()
+ {
+ return UrlLinkDisplay.SELECTED;
+ }
+
+ public boolean isUserEntry(
+ Entry<? extends TableModel, ? extends Object> entry)
+ {
+ return dataProvider
+ .isUserEntry(entry.getStringValue(UrlLinkDisplay.ID));
+ }
+
+ public boolean isUniqueName(String name)
+ {
+ return !dataProvider.contains(name);
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls;
+
+import static jalview.util.UrlConstants.SEP;
+
+import jalview.urls.api.UrlProviderI;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+/**
+ *
+ * Implements the UrlProviderI interface for a composite UrlProvider object
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class UrlProvider implements UrlProviderI
+{
+ // List of actual URL link providers
+ private List<UrlProviderI> providers;
+
+ // Specific reference to custom URL link provider
+ private UrlProviderI customProvider;
+
+ /**
+ * Constructor for UrlProvider composite
+ *
+ * @param defaultUrlString
+ * id of default url
+ * @param allProviders
+ * list of UrlProviders this provider gives access to
+ */
+ public UrlProvider(String defaultUrlString,
+ List<UrlProviderI> allProviders)
+ {
+ providers = allProviders;
+
+ customProvider = findCustomProvider();
+
+ // check that the defaultUrl still exists
+ if (!contains(defaultUrlString))
+ {
+ // if the defaultUrl can't be found in any of the providers
+ // set up a custom default url
+ chooseDefaultUrl();
+ }
+ else
+ {
+ setDefaultUrl(defaultUrlString);
+ }
+ }
+
+ /*
+ * Store ref to custom url provider
+ */
+ private UrlProviderI findCustomProvider()
+ {
+ for (UrlProviderI p : providers)
+ {
+ if (p.getClass().equals(CustomUrlProvider.class))
+ {
+ return p;
+ }
+ }
+
+ System.out
+ .println("Error initialising UrlProvider - no custom url provider");
+ return null;
+ }
+
+ @Override
+ public boolean setDefaultUrl(String id)
+ {
+ boolean outcome = false;
+ for (UrlProviderI p : providers)
+ {
+ if (p.setDefaultUrl(id))
+ {
+ outcome = true;
+ }
+ }
+ if (!outcome)
+ {
+ throw new IllegalArgumentException();
+ }
+ return outcome;
+ }
+
+ @Override
+ public boolean contains(String id)
+ {
+ boolean outcome = false;
+ for (UrlProviderI p : providers)
+ {
+ if (p.contains(id))
+ {
+ outcome = true;
+ }
+ }
+ return outcome;
+ }
+
+ @Override
+ public String writeUrlsAsString(boolean selected)
+ {
+ String result = "";
+ for (UrlProviderI p : providers)
+ {
+ String next = p.writeUrlsAsString(selected);
+ if (!next.isEmpty())
+ {
+ result += next;
+ result += SEP;
+ }
+ }
+ // remove last sep
+ if (!result.isEmpty())
+ {
+ result = result.substring(0, result.length() - 1);
+ }
+ return result;
+ }
+
+ @Override
+ public Vector<String> getLinksForMenu()
+ {
+ Vector<String> fullLinks = new Vector<String>();
+ for (UrlProviderI p : providers)
+ {
+ List<String> links = p.getLinksForMenu();
+ if (links != null)
+ {
+ // will obliterate links with same keys from different providers
+ // must have checks in place to prevent user from duplicating ids
+ fullLinks.addAll(links);
+ }
+ }
+ return fullLinks;
+ }
+
+ @Override
+ public List<UrlLinkDisplay> getLinksForTable()
+ {
+ ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
+ for (UrlProviderI p : providers)
+ {
+ displayLinks.addAll(p.getLinksForTable());
+ }
+ return displayLinks;
+ }
+
+ @Override
+ public void setUrlData(List<UrlLinkDisplay> links)
+ {
+ for (UrlProviderI p : providers)
+ {
+ p.setUrlData(links);
+ }
+ }
+
+ @Override
+ public String getDefaultUrl(String seqid)
+ {
+ String link = null;
+ for (UrlProviderI p : providers)
+ {
+ if (p.getDefaultUrl(seqid) == null)
+ {
+ continue;
+ }
+ else
+ {
+ link = p.getDefaultUrl(seqid);
+ break;
+ }
+ }
+ return link;
+ }
+
+ @Override
+ public String getDefaultUrlId()
+ {
+ String id = null;
+ for (UrlProviderI p : providers)
+ {
+ if (p.getDefaultUrlId() == null)
+ {
+ continue;
+ }
+ else
+ {
+ id = p.getDefaultUrlId();
+ break;
+ }
+ }
+ return id;
+ }
+
+ @Override
+ public String getDefaultTarget(String seqid)
+ {
+ String target = null;
+ for (UrlProviderI p : providers)
+ {
+ if (p.getDefaultTarget(seqid) == null)
+ {
+ continue;
+ }
+ else
+ {
+ target = p.getDefaultTarget(seqid);
+ break;
+ }
+ }
+ return target;
+ }
+
+ @Override
+ public String chooseDefaultUrl()
+ {
+ // choose a custom url default
+ return customProvider.chooseDefaultUrl();
+ }
+
+ @Override
+ public boolean isUserEntry(String id)
+ {
+ return customProvider.isUserEntry(id);
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls;
+
+import jalview.urls.api.UrlProviderI;
+import jalview.util.UrlLink;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+
+/**
+ * Leaf node of UrlProvider composite
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+
+public abstract class UrlProviderImpl implements UrlProviderI
+{
+ // minimum length of substitution in url link string
+ protected static final int MIN_SUBST_LENGTH = 4;
+
+ private static final Pattern MIRIAM_PATTERN = Pattern
+ .compile("^MIR:\\d{8}$");
+
+ protected String defaultUrl;
+
+ protected String getDefaultUrl(String seqid, HashMap<String, UrlLink> urls)
+ {
+ if (seqid.length() < MIN_SUBST_LENGTH)
+ {
+ return null;
+ }
+ else if (defaultUrl == null)
+ {
+ return null;
+ }
+ else if (!urls.containsKey(defaultUrl))
+ {
+ return null;
+ }
+ else
+ {
+ String url = null;
+ UrlLink urlLink = urls.get(defaultUrl);
+ String[] defaultUrls = urlLink.makeUrls(seqid, true);
+ if (defaultUrls == null || defaultUrls[0] == null
+ || defaultUrls[0].length() < MIN_SUBST_LENGTH)
+ {
+ url = null;
+ }
+ else
+ {
+ // just take first URL made from regex
+ url = defaultUrls[1];
+ }
+ return url;
+ }
+ }
+
+ @Override
+ public List<UrlLinkDisplay> getLinksForTable()
+ {
+ return null;
+ }
+
+ protected ArrayList<UrlLinkDisplay> getLinksForTable(
+ HashMap<String, UrlLink> urls, ArrayList<String> selectedUrls,
+ boolean selected)
+ {
+ ArrayList<UrlLinkDisplay> displayLinks = new ArrayList<UrlLinkDisplay>();
+ for (Entry<String, UrlLink> entry : urls.entrySet())
+ {
+ String key = entry.getKey();
+ boolean isDefault = (key.equals(defaultUrl));
+ boolean isSelected;
+ if (selectedUrls != null)
+ {
+ isSelected = selectedUrls.contains(key);
+ }
+ else
+ {
+ isSelected = selected;
+ }
+ displayLinks.add(new UrlLinkDisplay(key, entry.getValue(),
+ isSelected, isDefault));
+ }
+ return displayLinks;
+ }
+
+ protected boolean isMiriamId(String id)
+ {
+ return MIRIAM_PATTERN.matcher(id).matches();
+ }
+
+ @Override
+ public boolean isUserEntry(String id)
+ {
+ return !isMiriamId(id);
+ }
+}
+
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls.api;
+
+
+/**
+ * Interface to UrlProvider factories
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public interface UrlProviderFactoryI
+{
+ public UrlProviderI createUrlProvider();
+
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls.api;
+
+import jalview.urls.UrlLinkDisplay;
+
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * Methods for providing consistent access to up-to-date URLs
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public interface UrlProviderI
+{
+
+ /**
+ * Get names and urls in the UrlProvider as strings for display
+ *
+ */
+ Vector<String> getLinksForMenu();
+
+ /**
+ * Get names and urls as strings for display
+ *
+ */
+ List<UrlLinkDisplay> getLinksForTable();
+
+ /**
+ * Set names and urls from display settings
+ */
+ void setUrlData(List<UrlLinkDisplay> links);
+
+ /**
+ * Get the link for the default URL
+ *
+ * @seqid sequence id for which to build link
+ * @return link for the default URL
+ */
+ String getDefaultUrl(String seqid);
+
+ /**
+ * Get the default URL id
+ *
+ * @return id for default URL
+ */
+ String getDefaultUrlId();
+
+ /**
+ * Get the target of the link for the default URL
+ *
+ * @seqid sequence id for which to build link
+ * @return target of link for the default URL
+ */
+ String getDefaultTarget(String seqid);
+
+ /**
+ * Set the default URL
+ *
+ * @param id
+ * the id of the URL to set as default
+ * @return true if setting is successful
+ * @throws IllegalArgumentException
+ * if id does not exist as a url in the UrlProvider
+ */
+ boolean setDefaultUrl(String id) throws IllegalArgumentException;
+
+ /**
+ * Test if UrlProvider contains a url
+ *
+ * @param id
+ * to test for
+ * @return true of UrlProvider contains this id, false otherwise
+ */
+ boolean contains(String id);
+
+ /**
+ * Write out all URLs as a string suitable for serialising
+ *
+ * @return string representation of available URLs
+ */
+ String writeUrlsAsString(boolean selected);
+
+ /**
+ * Choose the default URL in the event of the selected default being
+ * unavailable
+ *
+ * @return id of chosen default url
+ */
+ String chooseDefaultUrl();
+
+ /**
+ * Determine if id is for a user-defined URL
+ */
+ boolean isUserEntry(String id);
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls.applet;
+
+import jalview.urls.CustomUrlProvider;
+import jalview.urls.UrlProvider;
+import jalview.urls.api.UrlProviderFactoryI;
+import jalview.urls.api.UrlProviderI;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * UrlProvider factory for applet code
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+
+public class AppletUrlProviderFactory implements UrlProviderFactoryI
+{
+ private String provDefaultUrl;
+
+ private Map<String, String> provUrlList;
+
+ public AppletUrlProviderFactory(String defaultUrlString,
+ Map<String, String> urlList)
+ {
+ provDefaultUrl = defaultUrlString;
+ provUrlList = urlList;
+ }
+
+ @Override
+ public UrlProviderI createUrlProvider()
+ {
+ // create all the UrlProviders we need
+ List<UrlProviderI> providers = new ArrayList<UrlProviderI>();
+ UrlProviderI customProvider = new CustomUrlProvider(provUrlList, null);
+ providers.add(customProvider);
+
+ UrlProviderI prov = new UrlProvider(provDefaultUrl, providers);
+ return prov;
+ }
+
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls.desktop;
+
+import jalview.urls.CustomUrlProvider;
+import jalview.urls.IdentifiersUrlProvider;
+import jalview.urls.UrlProvider;
+import jalview.urls.api.UrlProviderFactoryI;
+import jalview.urls.api.UrlProviderI;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * UrlProvider factory for desktop code
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+
+public class DesktopUrlProviderFactory implements UrlProviderFactoryI
+{
+
+ private String provDefaultUrl;
+
+ private String menuUrlList;
+
+ private String nonMenuUrlList;
+
+ public DesktopUrlProviderFactory(String defaultUrlString,
+ String cachedUrlList, String userUrlList)
+ {
+ provDefaultUrl = defaultUrlString;
+ menuUrlList = cachedUrlList;
+ nonMenuUrlList = userUrlList;
+ }
+
+ @Override
+ public UrlProviderI createUrlProvider()
+ {
+ // create all the UrlProviders we need
+ List<UrlProviderI> providers = new ArrayList<UrlProviderI>();
+
+ UrlProviderI idProvider = new IdentifiersUrlProvider(menuUrlList);
+ UrlProviderI customProvider = new CustomUrlProvider(menuUrlList,
+ nonMenuUrlList);
+ providers.add(idProvider);
+ providers.add(customProvider);
+
+ return new UrlProvider(provDefaultUrl, providers);
+ }
+
+}
public static final String SEQUENCE_ID = "SEQUENCE_ID";
/*
- * Default sequence URL link string for EMBL-EBI search
+ * Separator character used in Url links
+ */
+ public static final String SEP = "|";
+
+ /*
+ * Delimiter character used in Url links
*/
- public static final String EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
+ public static final String DELIM = "$";
/*
- * Default sequence URL link string for SRS
+ * Default sequence URL link label for EMBL-EBI search
+ */
+ public static final String DEFAULT_LABEL = "EMBL-EBI Search";
+
+ /*
+ * Default sequence URL link string for EMBL-EBI search
*/
- public static final String SRS_STRING = "SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry";
+ public static final String DEFAULT_STRING = DEFAULT_LABEL
+ + "|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
/*
* not instantiable
package jalview.util;
import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.DELIM;
+import static jalview.util.UrlConstants.SEP;
import static jalview.util.UrlConstants.SEQUENCE_ID;
import jalview.datamodel.DBRefEntry;
* documentation todo.
*/
- // Internal constants
- private static final String SEP = "|";
-
- private static final String DELIM = "$";
-
private String urlSuffix;
private String urlPrefix;
}
/**
+ * Alternative constructor for separate name and link
+ *
+ * @param name
+ * @param url
+ */
+ public UrlLink(String name, String url)
+ {
+ this(name + SEP + url);
+ }
+
+ /**
* @return the url_suffix
*/
public String getUrl_suffix()
return label;
}
+ public String getUrlWithToken()
+ {
+ String var = (usesDBaccession ? DB_ACCESSION : SEQUENCE_ID);
+
+ return urlPrefix
+ + (dynamic ? (DELIM + var + ((regexReplace != null) ? "="
+ + regexReplace + "=" + DELIM : DELIM)) : "")
+ + ((urlSuffix == null) ? "" : urlSuffix);
+ }
+
/**
* @return the regexReplace
*/
@Override
public String toString()
{
- String var = (usesDBaccession ? DB_ACCESSION : SEQUENCE_ID);
-
- return label
- + SEP
- + urlPrefix
- + (dynamic ? (DELIM + var + ((regexReplace != null) ? "="
- + regexReplace + "=" + DELIM : DELIM)) : "")
- + ((urlSuffix == null) ? "" : urlSuffix);
+ return label + SEP + getUrlWithToken();
}
/**
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.ws;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+
+public class UrlDownloadClient
+{
+ public UrlDownloadClient()
+ {
+
+ }
+
+ /**
+ * Download persistent database URLs from identifiers.org
+ *
+ * @param urlstring
+ * url to download from, as string
+ * @param outfile
+ * the name of file to save the URLs to
+ * @throws IOException
+ */
+ public void download(String urlstring, String outfile) throws IOException
+ {
+ FileOutputStream fos = null;
+ ReadableByteChannel rbc = null;
+ Path temp = null;
+ try
+ {
+ temp = Files.createTempFile(".jalview_", ".tmp");
+
+ URL url = new URL(urlstring);
+ rbc = Channels.newChannel(url.openStream());
+ fos = new FileOutputStream(temp.toString());
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+
+ // copy tempfile to outfile once our download completes
+ // incase something goes wrong
+ Files.copy(temp, Paths.get(outfile),
+ StandardCopyOption.REPLACE_EXISTING);
+ } catch (IOException e)
+ {
+ throw e;
+ } finally
+ {
+ try
+ {
+ if (fos != null)
+ {
+ fos.close();
+ }
+ } catch (IOException e)
+ {
+ System.out
+ .println("Exception while closing download file output stream: "
+ + e.getMessage());
+ }
+ try
+ {
+ if (rbc != null)
+ {
+ rbc.close();
+ }
+ } catch (IOException e)
+ {
+ System.out.println("Exception while closing download channel: "
+ + e.getMessage());
+ }
+ try
+ {
+ if (temp != null)
+ {
+ Files.deleteIfExists(temp);
+ }
+ } catch (IOException e)
+ {
+ System.out.println("Exception while deleting download temp file: "
+ + e.getMessage());
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls;
+
+import jalview.urls.api.UrlProviderFactoryI;
+import jalview.urls.api.UrlProviderI;
+import jalview.urls.applet.AppletUrlProviderFactory;
+import jalview.util.UrlConstants;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class AppletUrlProviderFactoryTest {
+
+ @Test(groups = { "Functional" })
+ public void testCreateUrlProvider()
+ {
+ final String defaultUrl = UrlConstants.DEFAULT_STRING.substring(
+ UrlConstants.DEFAULT_STRING.indexOf(UrlConstants.SEP) + 1,
+ UrlConstants.DEFAULT_STRING.length());
+ Map<String, String> urlList = new HashMap<String, String>()
+ {
+ {
+ put("Test1", "http://identifiers.org/uniprot/$DB_ACCESSION$");
+ put("Test2", defaultUrl);
+ }
+ };
+
+ UrlProviderFactoryI factory = new AppletUrlProviderFactory("Test2",
+ urlList);
+ UrlProviderI prov = factory.createUrlProvider();
+
+ // default url correctly set
+ Assert.assertEquals(prov.getDefaultUrlId(), "Test2");
+ Assert.assertEquals(prov.getDefaultUrl("FER_CAPAN"),
+ defaultUrl.replace("$SEQUENCE_ID$",
+ "FER_CAPAN"));
+
+ List<UrlLinkDisplay> allLinks = prov.getLinksForTable();
+
+ // 2 links in provider
+ Assert.assertEquals(allLinks.size(), 2);
+
+ // first link set correctly
+ Assert.assertEquals(allLinks.get(0).getId(), "Test1");
+ Assert.assertEquals(allLinks.get(0).getName(), "Test1");
+ Assert.assertEquals(allLinks.get(0).getUrl(),
+ "http://identifiers.org/uniprot/$DB_ACCESSION$");
+ Assert.assertFalse(allLinks.get(0).getIsDefault());
+ Assert.assertTrue(allLinks.get(0).getIsSelected());
+
+ // second link set correctly
+ Assert.assertEquals(allLinks.get(1).getId(), "Test2");
+ Assert.assertEquals(allLinks.get(1).getName(), "Test2");
+ Assert.assertEquals(allLinks.get(1).getUrl(), defaultUrl);
+ Assert.assertTrue(allLinks.get(1).getIsDefault());
+ Assert.assertTrue(allLinks.get(1).getIsSelected());
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.urls.api.UrlProviderI;
+import jalview.util.UrlConstants;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Vector;
+
+import org.testng.annotations.Test;
+
+public class CustomUrlProviderTest
+{
+
+ private static final String cachedList = "TEST|http://someurl.blah/$DB_ACCESSION$|"
+ + "ANOTHER|http://test/t$SEQUENCE_ID$|"
+ + "TEST2|http://address/$SEQUENCE_ID$|SRS|"
+ + "http://theSRSlink/$SEQUENCE_ID$";
+
+ private static final String unselectedList = "NON1|http://x/y/$DB_ACCESSION$|"
+ + "NON2|http://a/b/c/$DB_ACCESSION";
+
+ private static final HashMap<String, String> urlMap = new HashMap<String, String>()
+ {
+ {
+ put("TEST","http://someurl.blah/$DB_ACCESSION$");
+ put("ANOTHER","http://test/t$SEQUENCE_ID$");
+ put("TEST2", "http://address/$SEQUENCE_ID$");
+ put("SRS", "http://theSRSlink/$SEQUENCE_ID$");
+ }
+ };
+
+ private static final HashMap<String, String> unselUrlMap = new HashMap<String, String>()
+ {
+ {
+ put("NON1", "http://x/y/$DB_ACCESSION$");
+ put("NON2", "http://a/b/c/$DB_ACCESSION");
+ }
+ };
+
+ private static final String[] dlinks = {
+ "TEST|http://someurl.blah/$DB_ACCESSION$",
+ "ANOTHER|http://test/t$SEQUENCE_ID$",
+ "TEST2|http://address/$SEQUENCE_ID$",
+ UrlConstants.DEFAULT_STRING };
+
+ private static final String[] unselDlinks = {
+ "NON1|http://x/y/$DB_ACCESSION$", "NON2|http://a/b/c/$DB_ACCESSION" };
+
+ private static final Vector<String> displayLinks = new Vector<String>(
+ Arrays.asList(dlinks));
+
+ private static final Vector<String> unselDisplayLinks = new Vector<String>(
+ Arrays.asList(unselDlinks));
+
+ private static final String[] dlinks2 = { "a|http://x.y.z/$SEQUENCE_ID$" };
+
+ private static final Vector<String> displayLinks2 = new Vector<String>(
+ Arrays.asList(dlinks2));
+
+ private static final String[] list1 = { "a" };
+
+ private static final String[] list2 = { "http://x.y.z/$SEQUENCE_ID$" };
+
+ private static final Vector<String> names = new Vector<String>(
+ Arrays.asList(list1));
+
+ private static final Vector<String> urls = new Vector<String>(
+ Arrays.asList(list2));
+
+ /*
+ * Test default url is set and returned correctly
+ */
+ @Test(groups = { "Functional" })
+ public void testDefaultUrl()
+ {
+ UrlProviderI customProv = new CustomUrlProvider(cachedList,
+ unselectedList);
+
+ // default url can be set
+ assertTrue(customProv.setDefaultUrl("ANOTHER"));
+
+ // supplied replacement id must be more than 4 chars
+ String result = customProv.getDefaultUrl("123");
+ assertEquals(null, result);
+
+ // default url can be retrieved given a sequence id
+ result = customProv.getDefaultUrl("seqid");
+ assertEquals("http://test/tseqid", result);
+
+ // if there is no default url it sets the default to null
+ assertFalse(customProv.setDefaultUrl("No default"));
+ result = customProv.getDefaultUrl("testid");
+ assertEquals(null, result);
+
+ // choosing the default picks the DEFAULT_STRING option
+ customProv.chooseDefaultUrl();
+ result = customProv.getDefaultUrl("seqid");
+ assertEquals(
+ UrlConstants.DEFAULT_STRING.split("\\|")[1].split("\\$")[0]
+ + "seqid",
+ result);
+ }
+
+ /*
+ * Test urls are set and returned correctly
+ */
+ @Test(groups = { "Functional" })
+ public void testUrlLinks()
+ {
+ // creation from cached url list works + old links upgraded
+ UrlProviderI customProv = new CustomUrlProvider(cachedList,
+ unselectedList);
+ assertTrue(displayLinks.containsAll(customProv.getLinksForMenu()));
+
+ // creation from map works + old links upgraded
+ UrlProviderI customProv2 = new CustomUrlProvider(urlMap, unselUrlMap);
+ assertTrue(displayLinks.containsAll(customProv2.getLinksForMenu()));
+
+ // writing url links as a string works
+ // because UrlProvider does not guarantee order of links, we can't just
+ // compare the output of writeUrlsAsString to a string, hence the hoops here
+ String result = customProv.writeUrlsAsString(true);
+ UrlProviderI up = new CustomUrlProvider(result, "");
+ assertTrue(displayLinks.containsAll(up.getLinksForMenu()));
+
+ result = customProv.writeUrlsAsString(false);
+ up = new CustomUrlProvider("", result);
+ assertTrue(unselDisplayLinks.containsAll(up.getLinksForMenu()));
+
+ result = customProv2.writeUrlsAsString(true);
+ UrlProviderI up2 = new CustomUrlProvider(result, "");
+ assertTrue(displayLinks.containsAll(up2.getLinksForMenu()));
+
+ result = customProv2.writeUrlsAsString(false);
+ up2 = new CustomUrlProvider("", result);
+ assertTrue(displayLinks.containsAll(up2.getLinksForMenu()));
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.urls;
+
+import jalview.urls.api.UrlProviderI;
+import jalview.urls.desktop.DesktopUrlProviderFactory;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+import java.util.Vector;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class DesktopUrlProviderFactoryTest
+{
+ // Test identifiers.org download file
+ private static final String testIdOrgString = "[{\"id\":\"MIR:00000002\",\"name\":\"ChEBI\",\"pattern\":\"^CHEBI:\\d+$\","
+ + "\"definition\":\"Chemical Entities of Biological Interest (ChEBI)\",\"prefix\":\"chebi\","
+ + "\"url\":\"http://identifiers.org/chebi\"},{\"id\":\"MIR:00000005\",\"name\":\"UniProt Knowledgebase\","
+ + "\"pattern\":\"^([A-N,R-Z][0-9]([A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(\\.\\d+)?$\","
+ + "\"definition\":\"The UniProt Knowledgebase (UniProtKB)\",\"prefix\":\"uniprot\",\"url\":\"http://identifiers.org/uniprot\"},"
+ + "{\"id\":\"MIR:00000011\",\"name\":\"InterPro\",\"pattern\":\"^IPR\\d{6}$\",\"definition\":\"InterPro\",\"prefix\":\"interpro\","
+ + "\"url\":\"http://identifiers.org/interpro\"},"
+ + "{\"id\":\"MIR:00000372\",\"name\":\"ENA\",\"pattern\":\"^[A-Z]+[0-9]+(\\.\\d+)?$\",\"definition\":\"The European Nucleotide Archive (ENA),\""
+ + "\"prefix\":\"ena.embl\",\"url\":\"http://identifiers.org/ena.embl\"}]";
+
+ @BeforeMethod(alwaysRun = true)
+ public void setup()
+ {
+ // make a dummy identifiers.org download file
+ File temp = null;
+
+ try
+ {
+ temp = File.createTempFile("tempfile", ".tmp");
+ temp.deleteOnExit();
+ BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
+ bw.write(testIdOrgString);
+ bw.close();
+ } catch (IOException e)
+ {
+ System.out
+ .println("Error initialising DesktopUrlProviderFactoryTest test: "
+ + e.getMessage());
+ }
+
+ IdOrgSettings.setDownloadLocation(temp.getPath());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testCreateUrlProvider()
+ {
+ String defaultUrlString = "Test1";
+ String defaultUrl = "http://blah.blah/$SEQUENCE_ID$";
+ String cachedUrlList = "MIR:00000005|MIR:00000011|Test1|http://blah.blah/$SEQUENCE_ID$|"
+ + "Test2|http://test2/$DB_ACCESSION$|Test3|http://test3/$SEQUENCE_ID$";
+ String userUrlList = "MIR:00000372|Test4|httpL//another.url/$SEQUENCE_ID$";
+
+ DesktopUrlProviderFactory factory = new DesktopUrlProviderFactory(
+ defaultUrlString, cachedUrlList, userUrlList);
+ UrlProviderI prov = factory.createUrlProvider();
+
+ // default url correctly set
+ Assert.assertEquals(prov.getDefaultUrlId(), "Test1");
+ Assert.assertEquals(prov.getDefaultUrl("FER_CAPAN"),
+ defaultUrl.replace("$SEQUENCE_ID$", "FER_CAPAN"));
+
+ Vector<String> menulinks = prov.getLinksForMenu();
+ List<UrlLinkDisplay> allLinks = prov.getLinksForTable();
+
+ // 8 links in provider - 4 from id file, 4 custom links
+ Assert.assertEquals(allLinks.size(), 8);
+
+ // 5 links in menu (cachedUrlList)
+ Assert.assertEquals(menulinks.size(), 5);
+
+ Assert.assertTrue(menulinks
+ .contains("Test1|http://blah.blah/$SEQUENCE_ID$"));
+ Assert.assertTrue(menulinks
+ .contains("Test2|http://test2/$DB_ACCESSION$"));
+ Assert.assertTrue(menulinks
+ .contains("Test3|http://test3/$SEQUENCE_ID$"));
+ Assert.assertTrue(menulinks
+ .contains("UniProt Knowledgebase|http://identifiers.org/uniprot/$DB_ACCESSION$"));
+ Assert.assertTrue(menulinks
+ .contains("InterPro|http://identifiers.org/interpro/$DB_ACCESSION$"));
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.urls.api.UrlProviderI;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Vector;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IdentifiersUrlProviderTest
+{
+ // Test identifiers.org download file
+ private static final String testIdOrgFile = "[{\"id\":\"MIR:00000002\",\"name\":\"ChEBI\",\"pattern\":\"^CHEBI:\\d+$\","
+ + "\"definition\":\"Chemical Entities of Biological Interest (ChEBI)\",\"prefix\":\"chebi\","
+ + "\"url\":\"http://identifiers.org/chebi\"},{\"id\":\"MIR:00000005\",\"name\":\"UniProt Knowledgebase\","
+ + "\"pattern\":\"^([A-N,R-Z][0-9]([A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(\\.\\d+)?$\","
+ + "\"definition\":\"The UniProt Knowledgebase (UniProtKB)\",\"prefix\":\"uniprot\",\"url\":\"http://identifiers.org/uniprot\"},"
+ + "{\"id\":\"MIR:00000011\",\"name\":\"InterPro\",\"pattern\":\"^IPR\\d{6}$\",\"definition\":\"InterPro\",\"prefix\":\"interpro\","
+ + "\"url\":\"http://identifiers.org/interpro\"},"
+ + "{\"id\":\"MIR:00000372\",\"name\":\"ENA\",\"pattern\":\"^[A-Z]+[0-9]+(\\.\\d+)?$\",\"definition\":\"The European Nucleotide Archive (ENA),\""
+ + "\"prefix\":\"ena.embl\",\"url\":\"http://identifiers.org/ena.embl\"}]";
+
+ private static final String[] dlinks = {
+ "UniProt Knowledgebase|http://identifiers.org/uniprot/$DB_ACCESSION$",
+ "InterPro|http://identifiers.org/interpro/$DB_ACCESSION$",
+ "ENA|http://identifiers.org/ena.embl/$DB_ACCESSION$" };
+
+ private static final String[] dlinks1 = {
+ "MIR:00000011|http://identifiers.org/interpro/$DB_ACCESSION$",
+ "MIR:00000372|http://identifiers.org/ena.embl/$DB_ACCESSION$" };
+
+ private static final String[] dlinks2 = {
+ "MIR:00000005|http://identifiers.org/uniprot/$DB_ACCESSION$",
+ "MIR:00000011|http://identifiers.org/interpro/$DB_ACCESSION$" };
+
+ private static final String stringLinks = "MIR:00000005|http://identifiers.org/uniprot/$DB_ACCESSION$"
+ + "MIR:00000011|http://identifiers.org/interpro/$DB_ACCESSION$"
+ + "MIR:00000372|http://identifiers.org/ena.embl/$DB_ACCESSION$";
+
+ private static final String[] unselDlinks = { "ChEBI|http://identifiers.org/chebi/$DB_ACCESSION$" };
+
+ private static final Vector<String> displayLinks = new Vector<String>(
+ Arrays.asList(dlinks));
+
+ private static final Vector<String> unselDisplayLinks = new Vector<String>(
+ Arrays.asList(unselDlinks));
+
+ private static final Vector<String> displayLinks1 = new Vector<String>(
+ Arrays.asList(dlinks1));
+
+ private static final Vector<String> displayLinks2 = new Vector<String>(
+ Arrays.asList(dlinks2));
+
+ private static final HashMap<String, String> urlMap = new HashMap<String, String>()
+ {
+ {
+ put("MIR:00000005", "http://identifiers.org/uniprot/$DB_ACCESSION$");
+ put("MIR:00000011", "http://identifiers.org/interpro/$DB_ACCESSION$");
+ put("MIR:00000372", "http://identifiers.org/ena.embl/$DB_ACCESSION$");
+ }
+ };
+
+ private String testfile = "";
+
+
+ @BeforeClass(alwaysRun = true)
+ public void setup()
+ {
+ // setup test ids in a file
+ File outFile = null;
+ try
+ {
+ outFile = File.createTempFile("testidsfile", "txt");
+ outFile.deleteOnExit();
+
+ FileWriter fw = new FileWriter(outFile);
+ fw.write(testIdOrgFile);
+ fw.close();
+
+ testfile = outFile.getAbsolutePath();
+
+ } catch (Exception ex)
+ {
+ System.err.println(ex);
+ }
+
+ IdOrgSettings.setDownloadLocation(testfile);
+ }
+
+ /*
+ * Test urls are set and returned correctly
+ */
+ @Test(groups = { "Functional" })
+ public void testUrlLinks()
+ {
+ // creation from cached id list
+ String idList = "MIR:00000005|MIR:00000011|MIR:00000372";
+ UrlProviderI idProv = new IdentifiersUrlProvider(idList);
+
+ assertTrue(displayLinks.containsAll(idProv.getLinksForMenu()));
+
+ // because UrlProvider does not guarantee order of links, we can't just
+ // compare the output of writeUrlsAsString to a string, hence the hoops here
+ String result = idProv.writeUrlsAsString(true);
+ UrlProviderI up = new IdentifiersUrlProvider(result);
+ assertTrue(displayLinks.containsAll(up.getLinksForMenu()));
+
+ result = idProv.writeUrlsAsString(false);
+ up = new IdentifiersUrlProvider(result);
+ assertTrue(unselDisplayLinks.containsAll(up.getLinksForMenu()));
+
+ }
+
+ /*
+ * Test default is set and returned correctly
+ */
+ @Test(groups = { "Functional" })
+ public void testDefaultUrl()
+ {
+ // creation from cached id list
+ String idList = "MIR:00000005|MIR:00000011|MIR:00000372";
+ UrlProviderI idProv = new IdentifiersUrlProvider(idList);
+
+ // initially no default
+ assertEquals(null, idProv.getDefaultUrl("seqid"));
+
+ // set and then retrieve default
+ assertTrue(idProv.setDefaultUrl("MIR:00000005"));
+ assertEquals("http://identifiers.org/uniprot/seqid",
+ idProv.getDefaultUrl("seqid"));
+
+ // ids less than length 4 return null
+ assertEquals(null,
+ idProv.getDefaultUrl("123"));
+
+ // attempt to set bad default
+ assertFalse(idProv.setDefaultUrl("MIR:00001234"));
+ // default set to null (as default should have been set elsewhere)
+ assertEquals(null, idProv.getDefaultUrl("seqid"));
+
+ // chooseDefaultUrl not implemented for IdentifiersUrlProvider
+ assertEquals(null, idProv.chooseDefaultUrl());
+ }
+}
--- /dev/null
+package jalview.urls;
+
+import jalview.util.UrlLink;
+
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class UrlLinkDisplayTest {
+
+ @Test(groups = { "Functional" })
+ public void testDisplayColumnNames()
+ {
+ // 4 column names returned although 5 names internal to UrlLinkDisplay
+ List<String> names = UrlLinkDisplay.getDisplayColumnNames();
+ Assert.assertEquals(names.size(), 4);
+ }
+
+ @Test(groups = { "Functional" })
+ public void getValue()
+ {
+ UrlLink link = new UrlLink("Test Url",
+ "http://identifiers.org/$DB_ACCESSION$");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ Assert.assertFalse((boolean) u.getValue(UrlLinkDisplay.DEFAULT));
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.ID), "Test");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.NAME), "Test Url");
+ Assert.assertFalse((boolean) u.getValue(UrlLinkDisplay.SELECTED));
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.URL),
+ "http://identifiers.org/$DB_ACCESSION$");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testIsEditable()
+ {
+ // only default and selected columns are editable ever
+ // default only editable if link contains $SEQUENCE_ID$
+
+ UrlLink link = new UrlLink("Test Url",
+ "http://identifiers.org/$DB_ACCESSION$");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ Assert.assertFalse(u.isEditable(UrlLinkDisplay.DEFAULT));
+ Assert.assertTrue(u.isEditable(UrlLinkDisplay.SELECTED));
+ Assert.assertFalse(u.isEditable(UrlLinkDisplay.ID));
+ Assert.assertFalse(u.isEditable(UrlLinkDisplay.URL));
+ Assert.assertFalse(u.isEditable(UrlLinkDisplay.NAME));
+
+ UrlLink vlink = new UrlLink("Test Sequence ID Url",
+ "http://myurl/$SEQUENCE_ID$");
+ UrlLinkDisplay v = new UrlLinkDisplay("Test", vlink, false, false);
+
+ Assert.assertTrue(v.isEditable(UrlLinkDisplay.DEFAULT));
+ Assert.assertTrue(v.isEditable(UrlLinkDisplay.SELECTED));
+ Assert.assertFalse(v.isEditable(UrlLinkDisplay.ID));
+ Assert.assertFalse(v.isEditable(UrlLinkDisplay.URL));
+ Assert.assertFalse(v.isEditable(UrlLinkDisplay.NAME));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testName()
+ {
+ UrlLink link = new UrlLink("Test Url",
+ "http://identifiers.org/$DB_ACCESSION$");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ // Name initially as input in link
+ Assert.assertEquals(u.getName(), "Test Url");
+
+ // Setting updates name
+ u.setName("New Name");
+ Assert.assertEquals(u.getName(), "New Name");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testUrl()
+ {
+ UrlLink link = new UrlLink("Test Url",
+ "http://identifiers.org/$DB_ACCESSION$");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ // Url initially as input in link
+ Assert.assertEquals(u.getUrl(), "http://identifiers.org/$DB_ACCESSION$");
+
+ // Setting updates url
+ u.setUrl("http://something.new/$SEQUENCE_ID$");
+ Assert.assertEquals(u.getUrl(), "http://something.new/$SEQUENCE_ID$");
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetSetValue()
+ {
+ UrlLink link = new UrlLink("Test Url",
+ "http://identifiers.org/$DB_ACCESSION$");
+ UrlLinkDisplay u = new UrlLinkDisplay("Test", link, false, false);
+
+ Assert.assertFalse((boolean) u.getValue(UrlLinkDisplay.DEFAULT));
+ Assert.assertFalse((boolean) u.getValue(UrlLinkDisplay.SELECTED));
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.NAME), "Test Url");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.ID), "Test");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.URL),
+ "http://identifiers.org/$DB_ACCESSION$");
+
+ u.setValue(UrlLinkDisplay.DEFAULT, true);
+ Assert.assertTrue((boolean) u.getValue(UrlLinkDisplay.DEFAULT));
+
+ u.setValue(UrlLinkDisplay.SELECTED, true);
+ Assert.assertTrue((boolean) u.getValue(UrlLinkDisplay.SELECTED));
+
+ u.setValue(UrlLinkDisplay.NAME, "New Name");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.NAME), "New Name");
+
+ u.setValue(UrlLinkDisplay.ID, "New ID");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.ID), "New ID");
+
+ u.setValue(UrlLinkDisplay.URL, "http://something.new/$SEQUENCE_ID$");
+ Assert.assertEquals(u.getValue(UrlLinkDisplay.URL),
+ "http://something.new/$SEQUENCE_ID$");
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+package jalview.urls;
+
+import static jalview.util.UrlConstants.DELIM;
+import static jalview.util.UrlConstants.SEP;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+
+import jalview.urls.api.UrlProviderI;
+import jalview.util.MessageManager;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.event.TableModelListener;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class UrlLinkTableModelTest {
+
+ private static final String inmenu = "TEST|http://someurl.blah/$DB_ACCESSION$|"
+ + "ANOTHER|http://test/t$SEQUENCE_ID$|"
+ + "TEST2|http://address/$SEQUENCE_ID$|SRS|"
+ + "http://theSRSlink/$SEQUENCE_ID$|"
+ + "MIR:00000005|MIR:00000011|MIR:00000372";
+
+ private static final String notinmenu = "Not1|http://not.in.menu/$DB_ACCESSION$|"
+ + "Not2|http://not.in.menu.either/$DB_ACCESSION$";
+
+ // Test identifiers.org download file
+ private static final String testIdOrgString = "[{\"id\":\"MIR:00000002\",\"name\":\"ChEBI\",\"pattern\":\"^CHEBI:\\d+$\","
+ + "\"definition\":\"Chemical Entities of Biological Interest (ChEBI)\",\"prefix\":\"chebi\","
+ + "\"url\":\"http://identifiers.org/chebi\"},{\"id\":\"MIR:00000005\",\"name\":\"UniProt Knowledgebase\","
+ + "\"pattern\":\"^([A-N,R-Z][0-9]([A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(\\.\\d+)?$\","
+ + "\"definition\":\"The UniProt Knowledgebase (UniProtKB)\",\"prefix\":\"uniprot\",\"url\":\"http://identifiers.org/uniprot\"},"
+ + "{\"id\":\"MIR:00000011\",\"name\":\"InterPro\",\"pattern\":\"^IPR\\d{6}$\",\"definition\":\"InterPro\",\"prefix\":\"interpro\","
+ + "\"url\":\"http://identifiers.org/interpro\"},"
+ + "{\"id\":\"MIR:00000372\",\"name\":\"ENA\",\"pattern\":\"^[A-Z]+[0-9]+(\\.\\d+)?$\",\"definition\":\"The European Nucleotide Archive (ENA),\""
+ + "\"prefix\":\"ena.embl\",\"url\":\"http://identifiers.org/ena.embl\"}]";
+
+ private UrlProviderI prov;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setup()
+ {
+ // set up UrlProvider data as the source for the TableModel
+ // the data gets updated by the TableModel, so needs to be reinitialised for
+ // each test
+
+ // make a dummy identifiers.org download file
+ File temp = null;
+ try
+ {
+ temp = File.createTempFile("tempfile", ".tmp");
+ temp.deleteOnExit();
+ BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
+ bw.write(testIdOrgString);
+ bw.close();
+ } catch (IOException e)
+ {
+ System.out.println("Error initialising UrlLinkTableModel test: "
+ + e.getMessage());
+ }
+
+ // set up custom and identifiers.org url providers
+ IdOrgSettings.setDownloadLocation(temp.getPath());
+ IdentifiersUrlProvider idprov = new IdentifiersUrlProvider(inmenu);
+ CustomUrlProvider cprov = new CustomUrlProvider(inmenu, notinmenu);
+ List<UrlProviderI> provlist = new ArrayList<UrlProviderI>();
+ provlist.add(idprov);
+ provlist.add(cprov);
+
+ prov = new UrlProvider("TEST2", provlist);
+ }
+
+ /*
+ * Test that the table model is correctly initialised
+ * Display columns and default row are set; data provider listening event set up
+ */
+ @Test(groups = { "Functional" })
+ public void testInitialisation()
+ {
+ int defaultCol = 3;
+ int nameCol = 0;
+
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ // exactly one table model listener
+ TableModelListener[] listeners = m
+ .getListeners(TableModelListener.class);
+ Assert.assertEquals(listeners.length, 1);
+
+ // default row exists, there is exactly 1, and it matches the supplied
+ // default
+ int count = 0;
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ boolean isDefault = (boolean) m.getValueAt(row, defaultCol);
+ if (isDefault)
+ {
+ count++;
+ String defaultName = (String) m.getValueAt(row, nameCol);
+ Assert.assertEquals(defaultName, "TEST2");
+ }
+ }
+ Assert.assertEquals(count, 1);
+ }
+
+ /*
+ * Test row and column counts
+ */
+ @Test(groups = { "Functional" })
+ public void testCounts()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ // correct numbers of column and rows
+ Assert.assertEquals(m.getColumnCount(), 4);
+ Assert.assertEquals(m.getRowCount(), 10);
+ }
+
+ /*
+ * Test column access
+ */
+ @Test(groups = { "Functional" })
+ public void testColumns()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ // check column names
+ Assert.assertEquals(m.getColumnName(0),
+ MessageManager.formatMessage("label.name"));
+ Assert.assertEquals(m.getColumnName(1),
+ MessageManager.formatMessage("label.url"));
+ Assert.assertEquals(m.getColumnName(2),
+ MessageManager.formatMessage("label.inmenu"));
+ Assert.assertEquals(m.getColumnName(3),
+ MessageManager.formatMessage("label.default"));
+
+ // check column classes
+ Assert.assertEquals(m.getColumnClass(0), String.class);
+ Assert.assertEquals(m.getColumnClass(1), String.class);
+ Assert.assertEquals(m.getColumnClass(2), Boolean.class);
+ Assert.assertEquals(m.getColumnClass(3), Boolean.class);
+ }
+
+ /*
+ * Test row insertion
+ */
+ @Test(groups = { "Functional" })
+ public void testRowInsert()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ m.insertRow("newname", "newurl");
+
+ // check table has new row inserted
+ Assert.assertEquals(m.getValueAt(10, 0), "newname");
+ Assert.assertEquals(m.getValueAt(10, 1), "newurl");
+ Assert.assertEquals(m.getValueAt(10, 2), true);
+ Assert.assertEquals(m.getValueAt(10, 3), false);
+
+ // check data source has new row insrte
+ Assert.assertTrue(prov.getLinksForMenu().contains(
+ "newname" + SEP + "newurl"));
+ }
+
+ /*
+ * Test row deletion
+ */
+ @Test(groups = { "Functional" })
+ public void testRowDelete()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ // get name and url at row 0
+ String name = (String) m.getValueAt(0, 0);
+ String url = (String) m.getValueAt(0, 1);
+
+ m.removeRow(0);
+
+ // check table no longer has row 0 elements in it
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ Assert.assertNotEquals(m.getValueAt(row, 0), name);
+ }
+
+ // check data source likewise
+ Assert.assertFalse(prov.getLinksForMenu().contains(name + SEP + url));
+ }
+
+ /*
+ * Test value setting and getting
+ */
+ @Test(groups = { "Functional" })
+ public void testValues()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ // get original default
+ int olddefault;
+ boolean isDefault = false;
+ for (olddefault = 0; olddefault < m.getRowCount() && !isDefault; olddefault++)
+ {
+ isDefault = (boolean) m.getValueAt(olddefault, 3);
+ }
+
+ // set new values, one in each row
+ m.setValueAt("namechanged", 6, 0);
+ m.setValueAt("urlchanged", 7, 1);
+ m.setValueAt(false, 8, 2);
+ m.setValueAt(true, 6, 3);
+
+ // check values updated in table
+ Assert.assertEquals(m.getValueAt(6, 0), "namechanged");
+ Assert.assertEquals(m.getValueAt(7, 1), "urlchanged");
+ Assert.assertFalse((boolean) m.getValueAt(8, 2));
+ Assert.assertTrue((boolean) m.getValueAt(6, 3));
+ Assert.assertFalse((boolean) m.getValueAt(olddefault, 3));
+
+ // check default row is exactly one row still
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ isDefault = (boolean) m.getValueAt(row, 3);
+
+ // if isDefault is true, row is 9
+ // if isDefault is false, row is not 9
+ Assert.assertFalse(isDefault && !(row == 6));
+ }
+
+ // check table updated
+ Assert.assertTrue(prov.writeUrlsAsString(true).contains("namechanged" +SEP + m.getValueAt(6, 1)));
+ Assert.assertTrue(prov.writeUrlsAsString(true).contains(m.getValueAt(7,0) + SEP + "urlchanged"));
+ Assert.assertTrue(prov.writeUrlsAsString(false).contains(
+ (String) m.getValueAt(8, 0)));
+ Assert.assertEquals(prov.getDefaultUrl("seqid"), m.getValueAt(6, 1)
+ .toString().replace(DELIM + SEQUENCE_ID + DELIM, "seqid"));
+
+ }
+
+ /*
+ * Test cell editability
+ */
+ @Test(groups = { "Functional" })
+ public void testEditable()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ Assert.assertFalse(m.isCellEditable(row, 0));
+ Assert.assertFalse(m.isCellEditable(row, 1));
+ Assert.assertTrue(m.isCellEditable(row, 2));
+
+ if ((row == 4) || (row == 6) || (row == 7))
+ {
+ Assert.assertTrue(m.isCellEditable(row, 3));
+ }
+ else
+ {
+ Assert.assertFalse(m.isCellEditable(row, 3));
+ }
+ }
+ }
+
+ /*
+ * Test row 'deletability'
+ */
+ @Test(groups = { "Functional" })
+ public void testDeletable()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ if (row > 4)
+ {
+ Assert.assertTrue(m.isRowDeletable(row));
+ }
+ else
+ {
+ Assert.assertFalse(m.isRowDeletable(row));
+ }
+ }
+ }
+
+ /*
+ * Test indirect row editability
+ */
+ @Test(groups = { "Functional" })
+ public void testRowEditable()
+ {
+ UrlLinkTableModel m = new UrlLinkTableModel(prov);
+
+ for (int row = 0; row < m.getRowCount(); row++)
+ {
+ if (row > 3)
+ {
+ Assert.assertTrue(m.isRowEditable(row));
+ }
+ else
+ {
+ Assert.assertFalse(m.isRowEditable(row));
+ }
+ }
+ }
+}
--- /dev/null
+package jalview.urls;
+
+import jalview.urls.api.UrlProviderI;
+import jalview.urls.desktop.DesktopUrlProviderFactory;
+import jalview.util.UrlConstants;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+import java.util.Vector;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+
+public class UrlProviderTest {
+
+ // Test identifiers.org download file
+ private static final String testIdOrgString = "[{\"id\":\"MIR:00000002\",\"name\":\"ChEBI\",\"pattern\":\"^CHEBI:\\d+$\","
+ + "\"definition\":\"Chemical Entities of Biological Interest (ChEBI)\",\"prefix\":\"chebi\","
+ + "\"url\":\"http://identifiers.org/chebi\"},{\"id\":\"MIR:00000005\",\"name\":\"UniProt Knowledgebase\","
+ + "\"pattern\":\"^([A-N,R-Z][0-9]([A-Z][A-Z, 0-9][A-Z, 0-9][0-9]){1,2})|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(\\.\\d+)?$\","
+ + "\"definition\":\"The UniProt Knowledgebase (UniProtKB)\",\"prefix\":\"uniprot\",\"url\":\"http://identifiers.org/uniprot\"},"
+ + "{\"id\":\"MIR:00000011\",\"name\":\"InterPro\",\"pattern\":\"^IPR\\d{6}$\",\"definition\":\"InterPro\",\"prefix\":\"interpro\","
+ + "\"url\":\"http://identifiers.org/interpro\"},"
+ + "{\"id\":\"MIR:00000372\",\"name\":\"ENA\",\"pattern\":\"^[A-Z]+[0-9]+(\\.\\d+)?$\",\"definition\":\"The European Nucleotide Archive (ENA),\""
+ + "\"prefix\":\"ena.embl\",\"url\":\"http://identifiers.org/ena.embl\"}]";
+
+ private UrlProviderI prov;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setup()
+ {
+ // make a dummy identifiers.org download file
+ File temp = null;
+
+ try
+ {
+ temp = File.createTempFile("tempfile", ".tmp");
+ temp.deleteOnExit();
+ BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
+ bw.write(testIdOrgString);
+ bw.close();
+ } catch (IOException e)
+ {
+ System.out.println("Error initialising UrlProviderTest test: "
+ + e.getMessage());
+ }
+
+ IdOrgSettings.setDownloadLocation(temp.getPath());
+
+ String defaultUrlString = "No default";
+ String cachedUrlList = "MIR:00000005|MIR:00000011|Test1|http://blah.blah/$SEQUENCE_ID$|"
+ + "Test2|http://test2/$DB_ACCESSION$|Test3|http://test3/$SEQUENCE_ID$";
+ String userUrlList = "MIR:00000372|Test4|httpL//another.url/$SEQUENCE_ID$";
+
+ DesktopUrlProviderFactory factory = new DesktopUrlProviderFactory(
+ defaultUrlString, cachedUrlList, userUrlList);
+ prov = factory.createUrlProvider();
+ }
+
+ @Test(groups = { "Functional" })
+ public void testInitUrlProvider()
+ {
+ String emblUrl = UrlConstants.DEFAULT_STRING.substring(
+ UrlConstants.DEFAULT_STRING.indexOf(UrlConstants.SEP) + 1,
+ UrlConstants.DEFAULT_STRING.length());
+
+ // chooses EMBL url when default Url id does not exist in provided url lists
+ Assert.assertEquals(prov.getDefaultUrlId(), UrlConstants.DEFAULT_LABEL);
+ Assert.assertEquals(prov.getDefaultUrl("FER_CAPAN"),
+ emblUrl.replace("$SEQUENCE_ID$", "FER_CAPAN"));
+
+ Vector<String> menulinks = prov.getLinksForMenu();
+ List<UrlLinkDisplay> allLinks = prov.getLinksForTable();
+
+ // 9 links in provider - 4 from id file, 4 custom links, 1 additional
+ // default
+ Assert.assertEquals(allLinks.size(), 9);
+
+ // 6 links in menu (cachedUrlList) + new default
+ Assert.assertEquals(menulinks.size(), 6);
+
+ Assert.assertTrue(menulinks
+ .contains("Test1|http://blah.blah/$SEQUENCE_ID$"));
+ Assert.assertTrue(menulinks
+ .contains("Test2|http://test2/$DB_ACCESSION$"));
+ Assert.assertTrue(menulinks
+ .contains("Test3|http://test3/$SEQUENCE_ID$"));
+ Assert.assertTrue(menulinks
+ .contains("UniProt Knowledgebase|http://identifiers.org/uniprot/$DB_ACCESSION$"));
+ Assert.assertTrue(menulinks
+ .contains("InterPro|http://identifiers.org/interpro/$DB_ACCESSION$"));
+ Assert.assertTrue(menulinks.contains(UrlConstants.DEFAULT_LABEL
+ + UrlConstants.SEP + emblUrl));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetDefaultUrl()
+ {
+ // set custom url as default
+ Assert.assertTrue(prov.setDefaultUrl("Test1"));
+ Assert.assertEquals(prov.getDefaultUrlId(), "Test1");
+
+ // set identifiers url as default
+ Assert.assertTrue(prov.setDefaultUrl("MIR:00000011"));
+ Assert.assertEquals(prov.getDefaultUrlId(), "MIR:00000011");
+ }
+
+ @Test(
+ groups = { "Functional" },
+ expectedExceptions = { IllegalArgumentException.class })
+ public void testSetDefaultUrlWrongly()
+ {
+ // don't allow default to be a non-key
+ prov.setDefaultUrl("not-a-key");
+ }
+}
--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ws;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class UrlDownloadClientTest {
+
+ /**
+ * Test that url is successfully loaded into download file
+ */
+ @Test(groups = { "Network" }, enabled = true)
+ public void UrlDownloadTest()
+ {
+ UrlDownloadClient client = new UrlDownloadClient();
+ String urlstring = "http://identifiers.org/rest/collections/";
+ String outfile = "testfile.tmp";
+
+ try
+ {
+ client.download(urlstring, outfile);
+ } catch (IOException e)
+ {
+ Assert.fail("Exception was thrown from UrlDownloadClient download: "
+ + e.getMessage());
+ File f = new File(outfile);
+ if (f.exists())
+ {
+ f.delete();
+ }
+ }
+
+ // download file exists
+ File f = new File(outfile);
+ Assert.assertTrue(f.exists());
+
+ // download file has a believable size
+ // identifiers.org file typically at least 250K
+ Assert.assertTrue(f.length() > 250000);
+
+ if (f.exists())
+ {
+ f.delete();
+ }
+
+ }
+
+ /**
+ * Test that garbage in results in IOException
+ */
+ @Test(
+ groups = { "Network" },
+ enabled = true,
+ expectedExceptions = { IOException.class })
+ public void DownloadGarbageUrlTest() throws IOException
+ {
+ UrlDownloadClient client = new UrlDownloadClient();
+ String urlstring = "identifiers.org/rest/collections/";
+ String outfile = "testfile.tmp";
+
+ client.download(urlstring, outfile);
+ }
+}