package org.csstudio.archive.cache;

import java.util.LinkedList;

import org.csstudio.archive.ArchiveImplementationRegistry;
import org.csstudio.archive.ArchiveServer;
import org.csstudio.trends.databrowser.Plugin;

/** Cache access to archive servers.
 *  <p>
 *  While the first call of most chache methods will go directly
 *  to the underlying archive API and thus take however long it takes,
 *  subsequent calls for the same information might return immediately,
 *  using cached data.
 *  
 *  @author Kay Kasemir
 */
public class ArchiveCache
{
    private static ArchiveCache singleton = null;
    private LinkedList<CachingArchiveServer> server_cache =
        new LinkedList<CachingArchiveServer>();
    
    /** Hidden contructor.
     *  @see #getInstance()
     */
    private ArchiveCache()
    { /* prevent instantiation */ }
    
    /** @return The one and only instance of this cache. */
    synchronized public static ArchiveCache getInstance()
    {
        if (singleton == null)
            singleton = new ArchiveCache();           
        return singleton;
    }
    
    /** Get an archive server.
     *  <p>
     *  Further calls to the returned server obviously go directly
     *  to that server.
     *  Alternatively, one can try to use the returned server
     *  in subsequent calls to the cache.
     *  @return ArchiveServer for given URL.
     */
    synchronized public ArchiveServer getServer(String url) throws Exception
    { 
        // Is that URL a cached server?
        for (ArchiveServer server : server_cache)
            if (server.getURL().equals(url))
                return server;
        Plugin.getLogger().debug("ArchiveCache connects to " + url); //$NON-NLS-1$
        // Not cached, create new connection.
        // Since we're 'synchronized', this blocks all other calls.
        // But the alternative would be to risk multiple concurrent
        // connection attempts, which is overall worse.
        ArchiveServer real_server = 
            ArchiveImplementationRegistry.getInstance().getServer(url);
        // ArchiveImplementationRegistry didn't throw exception to
        // tell us anything, but also didn't return a server?
        if (real_server == null)
            return null;
        CachingArchiveServer server = new CachingArchiveServer(real_server);
    	server_cache.add(server);
        return server;
    }    
}
@@ -289,17 +289,16 @@
 f most c
-h
 ache met
@@ -487,18 +487,16 @@
 data.%0A *
-  
 %0A *  @au
@@ -527,13 +527,12 @@
 lic 
-class
+enum
  Arc
@@ -551,53 +551,18 @@
     
-private static ArchiveCache singleton = null;
+INSTANCE;%0A
 %0A   
@@ -570,16 +570,22 @@
 private 
+final 
 LinkedLi
@@ -672,20 +672,16 @@
 ver%3E();%0A
-    
 %0A    /**
@@ -799,20 +799,16 @@
 on */ %7D%0A
-    
 %0A    /**
@@ -860,37 +860,24 @@
 che. */%0A    
-synchronized 
 public stati
@@ -923,118 +923,31 @@
     
-if (singleton == null)%0A            singleton = new ArchiveCache();           %0A        return singleton
+return INSTANCE
 ;%0A    %7D%0A
     
@@ -942,20 +942,16 @@
 ;%0A    %7D%0A
-    
 %0A    /**
@@ -1282,16 +1282,22 @@
 tServer(
+final 
 String u
@@ -1322,17 +1322,16 @@
 on%0A    %7B
- 
 %0A       
@@ -1376,16 +1376,22 @@
    for (
+final 
 ArchiveS
@@ -1418,16 +1418,18 @@
 r_cache)
+ %7B
 %0A       
@@ -1465,16 +1465,18 @@
 ls(url))
+ %7B
 %0A       
@@ -1495,24 +1495,48 @@
 urn server;%0A
+            %7D%0A        %7D%0A
         Plug
@@ -1848,24 +1848,30 @@
 se.%0A        
+final 
 ArchiveServe
@@ -1885,17 +1885,16 @@
 server =
- 
 %0A       
@@ -2119,16 +2119,18 @@
 == null)
+ %7B
 %0A       
@@ -2155,16 +2155,32 @@
         
+%7D%0A        final 
 CachingA
@@ -2299,14 +2299,10 @@
 r;%0A    %7D
-    
 %0A%7D

use enum pattern singleton (gets synchonization, serialisation for free)