⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileexpirationservice.java

📁 jxme的一些相关程序,主要是手机上程序开发以及手机和计算机通信的一些程序资料,程序编译需要Ant支持
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 2001 Sun Microsystems, Inc. All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 * if any, must include the following acknowledgment:
 * "This product includes software developed by the
 * Sun Microsystems, Inc. for Project JXTA."
 * Alternately, this acknowledgment may appear in the software itself,
 * if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
 * must not be used to endorse or promote products derived from this
 * software without prior written permission. For written
 * permission, please contact Project JXTA at http://www.jxta.org.
 *
 * 5. Products derived from this software may not be called "JXTA",
 * nor may "JXTA" appear in their name, without prior written
 * permission of Sun.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of Project JXTA. For more
 * information on Project JXTA, please see
 * <http://www.jxta.org/>.
 *
 * This license is based on the BSD license adopted by the Apache Foundation.
 *
 * $Id: FileExpirationService.java,v 1.2 2002/03/04 21:38:14 echtcherbina Exp $
 */
package net.jxta.impl.cm;

import java.io.*;
import java.util.*;
import org.apache.log4j.Category; import org.apache.log4j.Priority;


class FileExpirationService {

    File             dir;
    File             db;
    File             tmpDb;
    Vector           docDirs;
    SchedulerService ss;
    RandomAccessFile out;
    Hashtable        hash;
    int              mods;
    SchedulerService.PendingAction pendingCompressAction;
    ExpirationListener listener;
    
    static final int  SCHEDULE          = 1;
    static final int  CANCEL            = 2;
    static final long COMPRESS_INTERVAL = 1000 * 60 * 30;
    static final int  MOD_THRESHOLD     = 128;

    static final Category LOG = 
	Category.getInstance(FileExpirationService.class.getName());

    interface ExpirationListener {

		public void expiredAndRemove (File file);
    }


    class Entry {

	File file;
	SchedulerService.PendingAction myPendingAction;
	long timeInMyCache;
	long timeoutForOthers;
	
	Entry (File file, 
	       long timeInMyCache, 
	       long timeoutForOthers)
	{
	    this.file                = file;
	    this.timeInMyCache       = timeInMyCache;
	    this.timeoutForOthers    = timeoutForOthers;
	}
    }

    /**
     * @param dir - The directory used for storing persistent scheduler data.
     * @param docDirs - The directories where documents will actually be 
     * stored.  In those directories we will delete the files which are
     * not scheduled to be expired.  We do this in case the scheduler
     * data becomes corrupt, so that when new scheduler data is written,
     * the old files expire anyway.
     */
    FileExpirationService (SchedulerService   ss, 
			   File               dir,
			   File[]             docDirs,
			   ExpirationListener listener)
	throws IOException
    {
	db    = new File (dir, "scheduler.db");
	tmpDb = new File (dir, ".tmp.scheduler.db");

	if (! dir.exists ())
	    dir.mkdirs ();
	
	this.ss       = ss;
	this.dir      = dir;
	this.listener = listener;
	this.docDirs  = new Vector ();
	this.hash     = new Hashtable ();


	if (db.exists ()) {
	    compress ();	
	} else {
	    out = new RandomAccessFile (db, "rw");
	}
	
	pendingCompressAction = 
	    ss.scheduleAction (new CleanupAction (), COMPRESS_INTERVAL);
	
	for (int i = 0;  docDirs != null && i < docDirs.length;  i++)
	    addDocDir (dir);
    }


    void addDocDir (File dir) {
	docDirs.addElement (dir);
    }

    void stop () {
	
	ss.cancelAction (pendingCompressAction);
	
	try {
	    if (db.exists ())
	        compress ();
	    
	    out.close ();
	} catch (IOException e) {
	    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("Compression of log stream failed on stop()", e);
	}
	
    }

    class CleanupAction implements SchedulerService.Action {
	
	public void perform (SchedulerService ss) {
	    
            try{
                if (db.exists ())
                    compress ();
            } catch (IOException e) {
                if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("Compression of log stream failed.", e);
            }

	    // still re-schedule, because the administrator may
	    // see the log messages and do something that will
	    // make the compress action succeed later.  or something.
	    pendingCompressAction = 
		ss.scheduleAction (this, COMPRESS_INTERVAL);
	    
	}
    }


    class ExpireAction implements SchedulerService.Action {
	Entry entry;
		
	ExpireAction (Entry entry) {
	    this.entry = entry;
	}

	public void perform (SchedulerService ss) {

            // Do not synchronize for the listener, it never changes after
            // construction.
            // But do synchronize for hash.remove. Other methods rely
            // on the hashtable not changing while they're synchronized.

            try {
                if (listener != null) listener.expiredAndRemove (entry.file);
            } catch (Throwable t) {
                if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug ("Throwable caught while dispatching expiration " + "listener.", t);
            } finally {

                synchronized(FileExpirationService.this) {
                    entry.file.delete ();
			
                    hash.remove (entry.file.getAbsolutePath ());
                }
            }
        }
    }

    public synchronized long getExpirationTime (File f) {
	Entry entry = (Entry) hash.get (f.getAbsolutePath ());

	if (entry == null)
	    return -1;
	else
            return Math.min(entry.timeInMyCache,
                            entry.timeoutForOthers+System.currentTimeMillis());
    }
    
    public void scheduleFileExpiration (File file, 
                                        long timeInMyCache,
                                        long timeoutForOthers) 
	throws IOException
    {
        while (true) {
            // We must do a collision mechanism here. We must release
            // the synchro top cancel, but we must keep it once we've
            // managed to get rid of it. Everytime we release the synchro
            // the situation may change and we may have to cancel again
            // or discover that the file re-appeared with a longer life-time.
            Entry entry = null;
            synchronized(this) {
                entry         = (Entry) hash.get (file.getAbsolutePath ());
                if (entry == null) { 
                    // Bingo we can proceed.

                    long   myTimeout     = timeInMyCache - System.currentTimeMillis ();
                    ExpireAction action1;

                    entry   = new Entry (file, timeInMyCache, timeoutForOthers);
                    action1 = new ExpireAction (entry);
	
                    entry.myPendingAction     = ss.scheduleAction (action1, 
                                                               myTimeout);

                    if (entry.myPendingAction != null) {
	
                        hash.put (file.getAbsolutePath (), entry); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -