JAL-1648 refactored and improved caching architecture implementation. The improved...
authortcofoegbu <tcnofoegbu@dundee.ac.uk>
Thu, 20 Apr 2017 12:24:32 +0000 (13:24 +0100)
committertcofoegbu <tcnofoegbu@dundee.ac.uk>
Thu, 20 Apr 2017 12:24:32 +0000 (13:24 +0100)
12 files changed:
resources/lang/Messages.properties
src/jalview/fts/api/GFTSPanelI.java
src/jalview/fts/core/GFTSPanel.java
src/jalview/fts/service/pdb/PDBFTSPanel.java
src/jalview/fts/service/uniprot/UniprotFTSPanel.java
src/jalview/gui/Finder.java
src/jalview/io/cache/AppCache.java
src/jalview/io/cache/AppCacheI.java [deleted file]
src/jalview/io/cache/CacheBoxI.java [deleted file]
src/jalview/io/cache/Cacheable.java [deleted file]
src/jalview/io/cache/JvCacheableInputBox.java [new file with mode: 0644]
src/jalview/jbgui/GFinder.java

index f284ff9..d4ae42f 100644 (file)
@@ -1294,3 +1294,5 @@ warn.name_cannot_be_duplicate = User-defined URL names must be unique and cannot
 label.invalid_name = Invalid Name !
 label.output_seq_details = Output Sequence Details to list all database references
 label.urllinks = Links
+label.default_cache_size = Default Cache Size
+action.clear_cached_items = Clear Cached Items
\ No newline at end of file
index d15f2e8..99c0c51 100644 (file)
@@ -138,4 +138,11 @@ public interface GFTSPanelI
    */
   public Map<String, Integer> getTempUserPrefs();
 
+  /**
+   * Returns unique key used for storing an FTSs instance cache items in the
+   * cache data structure
+   * 
+   * @return
+   */
+  public String getCacheKey();
 }
index a338400..99192a6 100644 (file)
@@ -29,8 +29,7 @@ import jalview.gui.IProgressIndicator;
 import jalview.gui.JvSwingUtils;
 import jalview.gui.SequenceFetcher;
 import jalview.io.cache.AppCache;
-import jalview.io.cache.CacheBoxI;
-import jalview.io.cache.Cacheable;
+import jalview.io.cache.JvCacheableInputBox;
 import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
@@ -85,7 +84,7 @@ import javax.swing.text.JTextComponent;
  */
 
 @SuppressWarnings("serial")
-public abstract class GFTSPanel extends JPanel implements GFTSPanelI, Cacheable
+public abstract class GFTSPanel extends JPanel implements GFTSPanelI
 {
   protected JInternalFrame mainFrame = new JInternalFrame(
           getFTSFrameTitle());
@@ -100,7 +99,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI, Cacheable
 
   protected JButton btn_cancel = new JButton();
 
-  protected JComboBox<String> txt_search;
+  protected JvCacheableInputBox<String> txt_search;
 
   protected SequenceFetcher seqFetcher;
 
@@ -263,10 +262,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI, Cacheable
   private void jbInit() throws Exception
   {
 
-    txt_search = new JComboBox<String>();
-    txt_search.setEditable(true);
-    txt_search
-            .setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+    txt_search = new JvCacheableInputBox<String>(getCacheKey());
     populateCmbSearchTargetOptions();
     Integer width = getTempUserPrefs().get("FTSPanel.width") == null ? 800
             : getTempUserPrefs().get("FTSPanel.width");
@@ -517,7 +513,6 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI, Cacheable
         }
       }
     });
-
     final DeferredTextInputListener listener = new DeferredTextInputListener(
             1500, new ActionListener()
             {
@@ -656,7 +651,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI, Cacheable
     getTempUserPrefs().put("FTSPanel.x", mainFrame.getX());
     getTempUserPrefs().put("FTSPanel.y", mainFrame.getY());
     mainFrame.dispose();
-    AppCache.getInstance().persistCache(this);
+    AppCache.getInstance().persistCache(getCacheKey());
   }
 
   public class DeferredTextInputListener implements DocumentListener
@@ -835,10 +830,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI, Cacheable
   @Override
   public String getTypedText()
   {
-    String typed = txt_search.getEditor().getItem() == null ? ""
-            : txt_search
-            .getEditor().getItem().toString().trim();
-    return typed;
+    return txt_search.getUserInput();
   }
 
   @Override
@@ -997,77 +989,5 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI, Cacheable
     mainFrame.setTitle(getFTSFrameTitle());
   }
 
-  @Override
-  public void initCache()
-  {
-    AppCache.getInstance().initCache(this);
-  }
-
-  @Override
-  public void updateCache()
-  {
-    AppCache.getInstance().updateCache(this);
-  }
-
-
-
-  @Override
-  public String getCacheKey()
-  {
-    return getCacheKey();
-  }
-
-  @Override
-  public CacheBoxI<String> getCacheComboBox()
-  {
-    return new CacheBoxI<String>()
-    {
-
-      @Override
-      public void setSelectedItem(Object anObject)
-      {
-        txt_search.setSelectedItem(anObject);
-      }
-
-      @Override
-      public void requestFocus()
-      {
-        txt_search.requestFocusInWindow();
-      }
-
-      @Override
-      public void looseFocus()
-      {
-        mainFrame.requestFocusInWindow();
-      }
-
-      @Override
-      public void addItem(String item)
-      {
-        txt_search.addItem(item);
-      }
-
-      @Override
-      public void removeAllItems()
-      {
-        txt_search.removeAllItems();
-      }
-
-      @Override
-      public int getItemCount()
-      {
-        return txt_search.getItemCount();
-      }
-
-      @Override
-      public String getUserInput()
-      {
-        return txt_search.getEditor().getItem() == null ? "" : txt_search
-                .getEditor().getItem().toString().trim();
-      }
-    };
-  }
-
-
 
 }
index c1e11b3..4a5f10d 100644 (file)
@@ -51,7 +51,6 @@ public class PDBFTSPanel extends GFTSPanel
     this.seqFetcher = seqFetcher;
     this.progressIndicator = (seqFetcher == null) ? null : seqFetcher
             .getProgressIndicator();
-    initCache();
   }
 
   @Override
@@ -143,8 +142,8 @@ public class PDBFTSPanel extends GFTSPanel
           setSearchInProgress(false);
           refreshPaginatorState();
           updateSummaryTableSelections();
-          updateCache();
         }
+        txt_search.updateCache();
       }
     }.start();
   }
@@ -278,7 +277,7 @@ public class PDBFTSPanel extends GFTSPanel
     return tempUserPrefs;
   }
 
-  @Override
+
   public String getCacheKey()
   {
     return PDB_FTS_CACHE_KEY;
index 08464c7..bff0d80 100644 (file)
@@ -53,7 +53,6 @@ public class UniprotFTSPanel extends GFTSPanel
     this.seqFetcher = seqFetcher;
     this.progressIndicator = (seqFetcher == null) ? null : seqFetcher
             .getProgressIndicator();
-    initCache();
   }
 
   @Override
@@ -142,8 +141,8 @@ public class UniprotFTSPanel extends GFTSPanel
           setSearchInProgress(false);
           refreshPaginatorState();
           updateSummaryTableSelections();
-          updateCache();
         }
+        txt_search.updateCache();
       }
     }.start();
 
index 8eabadb..5ca62b3 100755 (executable)
@@ -78,7 +78,6 @@ public class Finder extends GFinder
   {
     this(null, null);
     focusfixed = false;
-    initCache();
   }
 
   /**
@@ -332,7 +331,7 @@ public class Finder extends GFinder
         seqIndex = 0;
       }
     }
-    updateCache();
+    searchBox.updateCache();
   }
 
   /**
@@ -388,6 +387,6 @@ public class Finder extends GFinder
   protected void closeAction()
   {
     frame.dispose();
-    AppCache.getInstance().persistCache(this);
+    AppCache.getInstance().persistCache(getCacheKey());
   }
 }
index 46f6df2..9f9a25b 100644 (file)
@@ -7,9 +7,14 @@ import java.util.Arrays;
 import java.util.Hashtable;
 import java.util.LinkedHashSet;
 import java.util.List;
-import java.util.Set;
 
-public class AppCache implements AppCacheI
+/**
+ * A singleton class used for querying and persisting cache items.
+ * 
+ * @author tcnofoegbu
+ *
+ */
+public class AppCache
 {
   private static AppCache instance = null;
 
@@ -22,10 +27,14 @@ public class AppCache implements AppCacheI
     cacheItems = new Hashtable<String, LinkedHashSet<String>>();
   }
 
-  @Override
-  public LinkedHashSet<String> getAllCachedItemsFor(Cacheable cacheable)
+  /**
+   * Method to obtain all the cache items for a given cache key
+   * 
+   * @param cacheKey
+   * @return
+   */
+  public LinkedHashSet<String> getAllCachedItemsFor(String cacheKey)
   {
-    String cacheKey = cacheable.getCacheKey();
     LinkedHashSet<String> foundCache = cacheItems.get(cacheKey);
     if (foundCache == null)
     {
@@ -36,6 +45,11 @@ public class AppCache implements AppCacheI
   }
 
 
+  /**
+   * Returns an singleton instance of AppCache
+   * 
+   * @return
+   */
   public static AppCache getInstance()
   {
     if (instance == null)
@@ -45,60 +59,20 @@ public class AppCache implements AppCacheI
     return instance;
   }
 
-  @Override
-  public void updateCache(Cacheable cacheable)
+  /**
+   * Method for initialising cache items for a given cache key
+   * 
+   * @param cacheKey
+   */
+  public void initCache(String cacheKey)
   {
-    CacheBoxI<String> cacheComboBox = cacheable.getCacheComboBox();
-    String cacheKey = cacheable.getCacheKey();
-    cacheComboBox.looseFocus();
-    String userInput = cacheComboBox.getUserInput();
-
-    if (userInput != null && !userInput.isEmpty())
-    {
-      LinkedHashSet<String> foundCache = getAllCachedItemsFor(cacheable);
-      foundCache.add(userInput);
-      cacheItems.put(cacheKey, foundCache);
-    }
-
-    String lastSearch = userInput;
-    if (cacheComboBox.getItemCount() > 0)
-    {
-      cacheComboBox.removeAllItems();
-    }
-
-    Set<String> cacheItems = getAllCachedItemsFor(cacheable);
-    if (cacheItems != null && !cacheItems.isEmpty())
-    {
-      for (String cacheItem : cacheItems)
-      {
-        cacheComboBox.addItem(cacheItem);
-      }
-    }
-
-    if (!lastSearch.isEmpty())
-    {
-      cacheComboBox.setSelectedItem(lastSearch);
-      cacheComboBox.requestFocus();
-    }
-    else
-    {
-      cacheable.initCache();
-      cacheComboBox.addItem("");
-      cacheComboBox.setSelectedItem("");
-    }
-  }
-
-  @Override
-  public void initCache(Cacheable cacheable)
-  {
-    String separatedStr = Cache.getProperty(cacheable.getCacheKey());
+    String separatedStr = Cache.getProperty(cacheKey);
     if (separatedStr == null || separatedStr.isEmpty())
     {
       return;
     }
 
     List<String> persistedCacheItems = Arrays.asList(separatedStr.split(CACHE_DELIMITER));
-    String cacheKey = cacheable.getCacheKey();
 
     LinkedHashSet<String> foundCacheItems = cacheItems.get(cacheKey);
     if (foundCacheItems == null)
@@ -111,14 +85,16 @@ public class AppCache implements AppCacheI
       foundCacheItems.add(cacheItem);
     }
     cacheItems.put(cacheKey, foundCacheItems);
-    updateCache(cacheable);
   }
 
-  @Override
-  public void persistCache(Cacheable cacheable)
+  /**
+   * Method for persisting cache items for a given cache key
+   * 
+   * @param cacheKey
+   */
+  public void persistCache(String cacheKey)
   {
-    String cacheKey = cacheable.getCacheKey();
-    LinkedHashSet<String> foundCacheItems = getAllCachedItemsFor(cacheable);
+    LinkedHashSet<String> foundCacheItems = getAllCachedItemsFor(cacheKey);
     StringBuffer delimitedCacheBuf = new StringBuffer();
     for (String cacheItem : foundCacheItems)
     {
@@ -132,4 +108,32 @@ public class AppCache implements AppCacheI
 
     Cache.setProperty(cacheKey, delimitedCacheString);
   }
+
+  public void deleteCacheItems(String cacheKey)
+  {
+    cacheItems.put(cacheKey, new LinkedHashSet<String>());
+    persistCache(cacheKey);
+  }
+
+  /**
+   * Method for inserting cache items for given cache key into the cache data
+   * structure
+   * 
+   * @param cacheKey
+   * @param cacheItems
+   */
+  public void putCache(String cacheKey, LinkedHashSet<String> cacheItems)
+  {
+    getCacheItems().put(cacheKey, cacheItems);
+  }
+
+  /**
+   * Getter method for obtaining cache data structure
+   * 
+   * @return
+   */
+  private Hashtable<String, LinkedHashSet<String>> getCacheItems()
+  {
+    return cacheItems;
+  }
 }
diff --git a/src/jalview/io/cache/AppCacheI.java b/src/jalview/io/cache/AppCacheI.java
deleted file mode 100644 (file)
index 8d9e9f9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-package jalview.io.cache;
-
-import java.util.Set;
-
-public interface AppCacheI
-{
-
-  public void initCache(Cacheable cacheable);
-
-  public void updateCache(Cacheable cacheable);
-
-  public void persistCache(Cacheable cacheable);
-
-  public Set<String> getAllCachedItemsFor(Cacheable cacheable);
-}
diff --git a/src/jalview/io/cache/CacheBoxI.java b/src/jalview/io/cache/CacheBoxI.java
deleted file mode 100644 (file)
index c9b65fe..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-package jalview.io.cache;
-
-public interface CacheBoxI<E>
-{
-  public void setSelectedItem(Object anObject);
-
-  public void requestFocus();
-
-  public void looseFocus();
-
-  public void addItem(E item);
-
-  public void removeAllItems();
-
-  public int getItemCount();
-
-  public String getUserInput();
-}
diff --git a/src/jalview/io/cache/Cacheable.java b/src/jalview/io/cache/Cacheable.java
deleted file mode 100644 (file)
index 0287457..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package jalview.io.cache;
-
-
-public interface Cacheable
-{
-
-  /**
-   * method executed on cache initialisation
-   */
-  public void initCache();
-
-  /**
-   * method executed on cache update
-   */
-  public void updateCache();
-
-  /**
-   * Combo-box instance for the cache component
-   * 
-   * @return
-   */
-  public CacheBoxI<String> getCacheComboBox();
-
-  /**
-   * The unique key that will be used for storing user input for this cacheable
-   * in the cache dictionary
-   * 
-   * @return
-   */
-  public String getCacheKey();
-}
diff --git a/src/jalview/io/cache/JvCacheableInputBox.java b/src/jalview/io/cache/JvCacheableInputBox.java
new file mode 100644 (file)
index 0000000..55254c5
--- /dev/null
@@ -0,0 +1,106 @@
+package jalview.io.cache;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.JComboBox;
+import javax.swing.SwingUtilities;
+
+public class JvCacheableInputBox<E> extends JComboBox<String>
+{
+
+  private static final long serialVersionUID = 5774610435079326695L;
+
+  private String cacheKey;
+
+  private AppCache appCache;
+
+  public JvCacheableInputBox(String cacheKey)
+  {
+    super();
+    this.cacheKey = cacheKey;
+    setEditable(true);
+    setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+    appCache = AppCache.getInstance();
+    appCache.initCache(cacheKey);
+    updateCache();
+  }
+
+
+  /**
+   * Answers true if input text is an integer
+   * 
+   * @param text
+   * @return
+   */
+  private boolean isInteger(String text)
+  {
+    try
+    {
+      Integer.parseInt(text);
+      return true;
+    } catch (NumberFormatException e)
+    {
+      return false;
+    }
+  }
+
+  /**
+   * Method called to update the cache with the last user input
+   */
+  public void updateCache()
+  {
+    SwingUtilities.invokeLater(new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        String userInput = getUserInput();
+        if (userInput != null && !userInput.isEmpty())
+        {
+          LinkedHashSet<String> foundCache = appCache
+                  .getAllCachedItemsFor(cacheKey);
+          // remove old cache item so as to place current input at the top of
+          // the result
+          foundCache.remove(userInput);
+          foundCache.add(userInput);
+          appCache.putCache(cacheKey, foundCache);
+        }
+
+        String lastSearch = userInput;
+        if (getItemCount() > 0)
+        {
+          removeAllItems();
+        }
+        Set<String> cacheItems = appCache.getAllCachedItemsFor(cacheKey);
+        List<String> reversedCacheItems = new ArrayList<String>();
+        reversedCacheItems.addAll(cacheItems);
+        cacheItems = null;
+        Collections.reverse(reversedCacheItems);
+        if (lastSearch.isEmpty())
+        {
+          addItem("");
+        }
+        if (reversedCacheItems != null && !reversedCacheItems.isEmpty())
+        {
+          for (String cacheItem : reversedCacheItems)
+          {
+            addItem(cacheItem);
+          }
+        }
+        setSelectedItem(lastSearch.isEmpty() ? "" : lastSearch);
+      }
+    });
+  }
+
+
+  public String getUserInput()
+  {
+    return getEditor().getItem() == null ? "" : getEditor().getItem()
+            .toString().trim();
+  }
+
+}
index f676a49..144c67d 100755 (executable)
@@ -24,9 +24,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.io.DataSourceType;
 import jalview.io.FileFormat;
 import jalview.io.FormatAdapter;
-import jalview.io.cache.AppCache;
-import jalview.io.cache.CacheBoxI;
-import jalview.io.cache.Cacheable;
+import jalview.io.cache.JvCacheableInputBox;
 import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
@@ -39,7 +37,6 @@ import java.awt.event.KeyEvent;
 
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.SwingConstants;
@@ -48,7 +45,7 @@ import javax.swing.event.CaretEvent;
 import javax.swing.event.CaretListener;
 import javax.swing.text.JTextComponent;
 
-public class GFinder extends JPanel implements Cacheable
+public class GFinder extends JPanel
 {
   JLabel jLabelFind = new JLabel();
 
@@ -62,7 +59,7 @@ public class GFinder extends JPanel implements Cacheable
 
   protected JButton createNewGroup = new JButton();
 
-  protected JComboBox<String> searchBox = new JComboBox<String>();
+  protected JvCacheableInputBox<String> searchBox = new JvCacheableInputBox<String>(getCacheKey());
 
   BorderLayout mainBorderLayout = new BorderLayout();
 
@@ -137,9 +134,6 @@ public class GFinder extends JPanel implements Cacheable
       }
     });
     searchBox.setFont(new java.awt.Font("Verdana", Font.PLAIN, 12));
-    searchBox.setEditable(true);
-    searchBox
-.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
     ((JTextComponent) searchBox.getEditor().getEditorComponent())
             .addCaretListener(new CaretListener()
     {
@@ -247,73 +241,18 @@ public class GFinder extends JPanel implements Cacheable
 
 
 
-  @Override
-  public CacheBoxI<String> getCacheComboBox()
-  {
-    return new CacheBoxI<String>()
-    {
-
-      @Override
-      public void setSelectedItem(Object anObject)
-      {
-        searchBox.setSelectedItem(anObject);
-      }
-
-      @Override
-      public void requestFocus()
-      {
-        searchBox.requestFocusInWindow();
-      }
-
-      @Override
-      public void looseFocus()
-      {
-        jPanel6.requestFocusInWindow();
-      }
-
-      @Override
-      public void addItem(String item)
-      {
-        searchBox.addItem(item);
-      }
 
-      @Override
-      public void removeAllItems()
-      {
-        searchBox.removeAllItems();
-      }
-
-      @Override
-      public int getItemCount()
-      {
-        return searchBox.getItemCount();
-      }
-
-      @Override
-      public String getUserInput()
-      {
-        return searchBox.getEditor().getItem() == null ? "" : searchBox
-                .getEditor().getItem().toString().trim();
-      }
-    };
-  }
-
-  @Override
+  /**
+   * Returns unique key used for storing Finder cache items in the cache data
+   * structure
+   * 
+   * @return
+   */
   public String getCacheKey()
   {
     return FINDER_CACHE_KEY;
   }
 
-  @Override
-  public void initCache()
-  {
-    AppCache.getInstance().initCache(this);
-  }
 
-  @Override
-  public void updateCache()
-  {
-    AppCache.getInstance().updateCache(this);
-  }
 
 }