package org.greenstone.gatherer.gui; import java.awt.*; import java.net.*; import javax.swing.*; import java.util.*; import java.io.*; import org.greenstone.gatherer.Dictionary; import org.greenstone.gatherer.Gatherer; import org.greenstone.gatherer.Configuration; /** Modified. * Class used by WarningDialog and Gatherer which represents a textual input control * (TextField or Combobox) into which a URL can be entered. Provides some static methods * shared by these controls and by a general JTextField control which can all be used * in a WarningDialog. Class URLField also contains an inner Interface class and two * static inner classes that implement this interface: Text and DropDown. * Finally, another static inner class URLCollectionPair associates each Gliserver URL * (or Library URL) that can be displayed in the DropDown with the last opened collection * file for the Greenstone server at that URL. */ public class URLField { static public String getText(JComponent control) { if(control instanceof JTextField) { // not specifically a URL Field, therefore, we're not meant to do checking return ((JTextField)control).getText(); } else if(control instanceof URLField.DropDown) { return (String)((JComboBox)control).getSelectedItem(); } // unknown control, shouldn't happen return ""; } static public String setText(JComponent control, String text) { if(control instanceof JTextField) { // not specifically a URL Field, therefore, we're not meant to do checking ((JTextField)control).setText(text); } else if(control instanceof URLField.DropDown) { ((JComboBox)control).setSelectedItem(text); } // unknown control, shouldn't happen return ""; } static public boolean validateURL(JComponent control) { if(control instanceof URLField.Text) { return ((URLField.Text)control).validateURL(); } else if (control instanceof JTextField) { return true; // not specifically a URL Field, therefore, we're not meant to do checking } else { // control is a DropDown return ((URLField.DropDown)control).validateURL(); } } static public boolean validateURL(String url_string) { if (!url_string.equals("")) { // Check the URL string is valid by trying to create a URL object from it try { new URL(url_string); } catch (MalformedURLException exception) { // URL string is invalid return false; } } // URL string is valid return true; } static public void store(JComponent control, String affected_property) { if(control instanceof JTextField) { String value = ((JTextField)control).getText(); Configuration.setString(affected_property, true, value); Configuration.save(); // save it in case of a crash } else { // DropDown ((DropDown)control).saveProperties(); // saves it already } } /** INTERFACE CLASS IMPLEMENTED BY Static inner classes Text and DropDown */ public static interface URLFieldControl { public boolean validateURL(); } /** STATIC INNER CLASS URLTextField */ public static class Text extends JTextField implements URLFieldControl { public Text(Color foreground, Color background) { super(); this.setComponentOrientation(Dictionary.getOrientation()); setBackground(background); setForeground(foreground); } public boolean validateURL() { String url_string = getText(); return URLField.validateURL(url_string); } } /** STATIC INNER CLASS DropDown, an editable URLComboBox */ public static class DropDown extends JComboBox implements URLFieldControl { private String checkString = null; // optional string to check the URLs items against to see whether the URLs contain this private String affectedProperty = null; // the Configuration property associated with this DropDown private String coaffectedProperty = null; // the Configuration property whose suffix should change along with the affectedProperty private static final int MAX_URLS = 5; public DropDown(Color foreground, Color background, String[] defaultURLs, String affectedProperty, String coaffectedProperty) { super(URLCollectionPair.createDefaultsArray(defaultURLs)); this.setEditable(true); this.getEditor().selectAll(); this.setComponentOrientation(Dictionary.getOrientation()); setBackground(background); setForeground(foreground); this.affectedProperty = affectedProperty; this.coaffectedProperty = coaffectedProperty; // read any URLS specified in the config file setComboBoxValues(); } public DropDown(Color foreground, Color background, String[] defaultURLs, String affectedProperty, String coaffectedProperty, String checkString) { this(foreground, background, defaultURLs, affectedProperty, coaffectedProperty); this.checkString = checkString; } public boolean validateURL() { //String url_string = (String)this.getEditor().getItem(); String url_string = this.getSelectedItem().toString(); // returns url of the combobox item if(checkString != null && !url_string.endsWith(checkString)) { return false; } else { return URLField.validateURL(url_string); } } public void saveProperties() { // 1. Add the first url just edited (if any) // The user might have created a new STRING, or selected an existing URLCollectionPair // We don't know the type! Object o = this.getSelectedItem(); URLCollectionPair editedItem = (o instanceof URLCollectionPair) ? (URLCollectionPair)o : new URLCollectionPair(o.toString()); if(editedItem != null) { insertItemAt(editedItem, 0); } else { editedItem = (URLCollectionPair)getItemAt(0); // else reuse the first default: } Configuration.setString(affectedProperty, true, editedItem.getURL()); // concurrently set the last opened collection for this url String lastOpenedCollection = editedItem.getCollection(); if(lastOpenedCollection.equals("")) { Configuration.setString(coaffectedProperty, true, null); } else { Configuration.setString(coaffectedProperty, true, lastOpenedCollection); } // 2. Add the remaining urls into the combobox int url_count = 1; // remain under MAX_URLS AND under the number of actual URLs in the dropdown for(int i = 0; url_count < MAX_URLS && i < getItemCount(); i++, url_count++) { URLCollectionPair item = (URLCollectionPair)getItemAt(i); String url = item.getURL(); if(item == null || url.equals(editedItem.getURL()) || url.equals("")) { // skip any duplicates of the just-edited URL and skip empty URLs url_count--; } else { Configuration.setString(affectedProperty+url_count, true, url); // concurrently save the name of the corresponding open collection if(item.getCollection().equals("")) { Configuration.setString(coaffectedProperty+url_count, true, null); } else { Configuration.setString(coaffectedProperty+url_count, true, item.getCollection()); } } // else retain old value for this affectedProperty (general.gliserver_url) } Configuration.save(); } // Get values from Configuration file, or (if none) use defaultURLs. // Put them into the combobox private void setComboBoxValues() { String url = Configuration.getString(affectedProperty, true); String collection = Configuration.getString(coaffectedProperty, true); boolean finished = url.equals(""); if(!finished) { this.removeAllItems(); // remove defaults, since config file now contains init values this.addItem(new URLCollectionPair(url, collection)); } // else urls and combobox already contains the defaults for(int i = 1; !finished; i++) { url = Configuration.getString(affectedProperty+i, true); collection = Configuration.getString(coaffectedProperty+i, true); if(url.equals("")) { finished = true; } else { // url is not empty this.addItem(new URLCollectionPair(url, collection)); } } // setting the size of the dropdown control Dimension newSize=new Dimension(getPreferredSize().width+20, getPreferredSize().height); setPreferredSize(newSize); } } /** STATIC INNER CLASS URLCollectionPair. * Since the configuration for a (remote) Greenstone2 and Greenstone3 is now * stored in a single file for both, we can have GLI connecting to different servers * while for each server, a different collection may have been left open last time. * This class URLCollectionPair will associate a GLIServer_URL or Library_URL with * the last opened collection file for it. It is used by URLField.DropDown combobox. */ public static class URLCollectionPair { String url; // gliserverURL String collection; // last opened collection for the corresponding gliserver public static URLCollectionPair[] createDefaultsArray(String[] defaultURLs) { URLCollectionPair[] pairs = new URLCollectionPair[defaultURLs.length]; for(int i = 0; i < pairs.length; i++) { pairs[i] = new URLCollectionPair(defaultURLs[i]); // no associated open collection } return pairs; } public URLCollectionPair(String url) { this.set(url, ""); } public URLCollectionPair(String url, String collection) { this.set(url, collection); } public void set(String url, String collection) { this.url = url; this.collection = collection; } public void setURL(String url) { this.url = url; } public void setCollection(String collection) { this.collection = collection; } public String getCollection() { return collection; } public String getURL() { return url; } /** For display in comboboxes */ public String toString() { return url; } /** @returns the number that is suffixed to the gliserver_url */ public String getSuffixNumber() { String numericSuffix = ""; boolean stop = false; for(int index = url.length()-1; index >= 0 && !stop; index--) { // work from the end char character = url.charAt(index); if(Character.isDigit(character)) { numericSuffix = Character.toString(character) + numericSuffix; } else { stop = true; } } return numericSuffix; } } }