package com.diodesoftware.scb.agents; import com.diodesoftware.dbmapper.DBMapper; import com.diodesoftware.scb.S3FileHandler; import com.diodesoftware.scb.tables.Clip; import com.diodesoftware.scb.tables.ClipS3Object; import org.apache.log4j.Logger; import org.jets3t.service.S3ServiceException; import java.sql.Connection; import java.util.*; /** * Copyright 2008 Sensemaker Software Inc. * User: rob * Date: Mar 16, 2008 * Time: 3:04:25 PM */ public class S3AccessAgent implements Runnable{ private static Logger log = Logger.getLogger(S3AccessAgent.class); private S3FileHandler s3FileHandler = new S3FileHandler(); private Map<Integer, Loc> open = new HashMap<Integer, Loc>(); private static S3AccessAgent instance = null; public static S3AccessAgent getInstance(){ if(instance == null)instance = new S3AccessAgent(); return instance; } private S3AccessAgent(){ Thread t = new Thread(this); t.start(); } // Record access to an object public String open(Clip clip, ClipS3Object cs3o, Connection con) { String key = null; int downloadCount = cs3o.getDownloadCount(); downloadCount++; cs3o.setLastDownloaded(Calendar.getInstance()); cs3o.setDownloadCount(downloadCount); DBMapper.save(cs3o, con); try { key = s3FileHandler.openKey(clip, cs3o.getName()); Loc loc = null; synchronized (open) { loc = open.get(cs3o.getNumber()); } if (loc == null) { loc = new Loc(key, cs3o.getName(), System.currentTimeMillis()); synchronized (open) { open.put(cs3o.getNumber(), loc); } } else { loc.lastAccess = System.currentTimeMillis(); } } catch (S3ServiceException e) { log.error("Error Opening access to " + clip.getNumber(), e); } return key; } // Keep open for a while private static final int OPEN_FOR = 20 * 60 * 1000; private static final Object mutext = new Object(); private boolean stopRequested; public void run() { try { while (!stopRequested) { synchronized (mutext) { mutext.wait(60 * 1000); } long now = System.currentTimeMillis(); long before = now - OPEN_FOR; synchronized (open) { List<Integer> toRemove = new ArrayList<Integer>(); Iterator<Integer> iter = open.keySet().iterator(); while(iter.hasNext()){ int i = iter.next(); Loc loc = open.get(i); if(loc.lastAccess > before){ toRemove.add(i); } } iter = toRemove.iterator(); while(iter.hasNext()){ Loc loc = open.remove(iter.next()); // Close the door try{ s3FileHandler.close(loc.key, loc.name); }catch(S3ServiceException e){ log.warn("Error closing S3 Access", e); } } } } } catch (InterruptedException e) { } } public void kill() { stopRequested = true; synchronized (mutext) { mutext.notifyAll(); } } class Loc { String key; String name; long lastAccess; Loc(String key, String name, long lastAccess) { this.key = key; this.name = name; this.lastAccess = lastAccess; } } }