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

📄 cache.java

📁 主要是对串口驱动的的一些控制源码!!! 在下载javacomm20-win32.zip后就可以使用。
💻 JAVA
字号:
package de.fhm.jkf.launch.cl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;

import de.fhm.jkf.launch.clsv.ArchiveInfo;
import de.fhm.jkf.launch.clsv.JarFilenameFilter;
import de.fhm.jkf.launch.clsv.LaunchLogger;

/**
 * $Log: Cache.java,v $
 * Revision 1.3  2003/02/25 17:16:23  willaxt
 * updated javadoc comments
 * reformatted source code
 *
 * Revision 1.2  2003/02/17 14:55:12  willaxt
 * renamed map instance variable to classMap for better understanding of the code
 *
 * Revision 1.1  2003/01/16 13:10:18  mwulff
 * initial version
 *
 *
 * @author Theodor Willax
 *
 * <br><br><center><table border="1" width="80%"><hr>
 * <strong><a href="http://jkf.sourceforge.net">The JKF Project</a></strong>
 * <p>
 * Copyright (C) 2002 by Theodor Willax
 * <p>
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * <p>
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * <p>
 * You should have received a copy of the <a href="http://www.gnu.org/copyleft/lesser.html">
 * GNU Lesser General Public License</a> along with this library; if not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA  02111-1307  USA
 * <hr></table></center>
 *
 * A simple cache for jar archives of an application. Simple means, it does only
 * store the complete archives on the local filesystem. No special sorting or
 * arrangement is done.
 * <br>
 * It checks the <tt>Implementation-Version</tt> attribute of manifest files in the archives.
 * If no <tt>Implementation-Version</tt> is available, the archive is not stored, respectively
 * deleted from the <code>Cache</code> to have not outdated versions available. 
 * 
 */
public class Cache {

	/**
	 * The direcotry this <code>Cache</code> lives in.
	 */
	private File cacheDir = null;

	/**
	 * This <code>Map</code> contains all classname - <code>byte</code>S
	 * mappings. This means if you query this <code>Map</code> for
	 * a classname, it returns the <code>ByteArray</code> the class
	 * consists of.
	 */
	private Map classMap = null;

	/**
	 * Creates a new <code>Cache</code> for the given application.
	 * The <code>Cache</code> resides in the users home directory
	 * as given by the java property <code>user.home</code> under
	 * the directory <b>".jkf/appName"</b>.
	 * 
	 * @param appName The name of the application this <code>Cache</code>
	 * is for.
	 * 
	 * @throws IOException if the cache can not be created or is not writeable.
	 */
	public Cache(String appName) throws IOException {
		if (appName == null) {
			throw new IllegalArgumentException("appName null not allowed");
		}
		cacheDir =
			new File(
				System.getProperty("user.home")
					+ File.separator
					+ ".jkf"
					+ File.separator
					+ appName);
		if (cacheDir.isDirectory() == false) {
			if (cacheDir.mkdirs() == false) {
				throw new IOException(
					"cache directory could not be created: "
						+ cacheDir.getAbsolutePath());
			}
		}
		if (cacheDir.canWrite() == false) {
			throw new IOException(
				"cache directory not writeable: " + cacheDir.getAbsolutePath());
		}
		classMap = new HashMap();
	}

	/**
	 * Initializes the <code>Cache</code> with the available
	 * archives. Compares the version info from the archives
	 * in the <code>Cache</code> with the versions on the
	 * list. If an old version lives in the <code>Cache</code>,
	 * no classes from it go into the <code>Map</code>. If
	 * a class from one of this old archives is wanted,
	 * <code>null</code> is returned. Removes archives from
	 * the cache which are no longer listet in the archive
	 * info list.
	 * <br>
	 * If no version information at all is found, we delete the
	 * archive from the cache. So we are sure we have no old
	 * outdated versions in the <code>Cache</code>.
	 * <br>
	 * Repeated calls to this method initialze the <code>Cache</code>
	 * repeatedly.
	 * 
	 * @param archives <code>Map</code> of archives an their version
	 * 
	 * @throws IOException if something with the file handling in the
	 * cache doesn't work.
	 */
	public void init(List archiveInfo) throws IOException {
		LaunchLogger.debug(getClass().getName() + ".init() called");
		classMap.clear();
		File[] jars = cacheDir.listFiles(new JarFilenameFilter());
		for (int i = 0; i < jars.length; i++) {
			// @todo better version info compare logics
			String localVersion = getVersion(jars[i].getName());
			String remoteVersion = null;
			Iterator it = archiveInfo.iterator();
			while (it.hasNext()) {
				ArchiveInfo ai = (ArchiveInfo) it.next();
				if (ai.getName().equalsIgnoreCase(jars[i].getName())) {
					remoteVersion = ai.getVersion();
					break;
				}
			}
			if ((localVersion != null)
				&& (localVersion.equalsIgnoreCase(remoteVersion))) {
				addToMap(jars[i]);
			} else {
				// delete from cache, to get rid of old unused archives
				get(jars[i].getName());
				LaunchLogger.info(
					"removed " + jars[i].getName() + " from cache");
			}
		}
	}

	/**
	 * Adds given archive to the <code>Map</code>. Replaces
	 * any old classes with new ones if duplicates are in
	 * this archive.
	 * 
	 * @param arch The archive which classes are added to
	 * the <code>Map</code>.
	 * @exception IOException if I/O errors occur during
	 * handling with the archive.
	 */
	private void addToMap(File arch) throws IOException {
		JarFile jf = new JarFile(arch);
		Enumeration enum = jf.entries();
		while (enum.hasMoreElements()) {
			ZipEntry ze = (ZipEntry) enum.nextElement();
			InputStream in = jf.getInputStream(ze);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			int len = 0;
			byte[] buf = new byte[4096];
			while ((len = in.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			// make class loader class name out of jar file name
			String cn = ze.getName();
			if (cn.endsWith(".class")) {
				cn = cn.replace('/', '.');
				cn = cn.substring(0, cn.lastIndexOf(".class"));
			}
			LaunchLogger.debug("className: " + cn);
			// replaces old entry!
			classMap.put(cn, new ByteArray(out.toByteArray()));
			out.close();
			in.close();
		}
	}

	/**
	 * Puts this archive into the cache. Replaces any old copy.
	 * 
	 * @param arch The archive to put into the cache.
	 * 
	 * @throws FileNotFoundException if the name of the <code>Archive</code>
	 * is a directory or is not writeable due to any case.
	 * 
	 * @throws IOException if an I/O error occurs during writing the
	 * <code>Archive</code>
	 */
	public void put(Archive arch) throws FileNotFoundException, IOException {
		File f =
			new File(
				cacheDir.getAbsolutePath() + File.separator + arch.getName());
		OutputStream out = new BufferedOutputStream(new FileOutputStream(f));
		out.write(arch.getBytes());
		out.close();
		// put class bytes in classMap
		addToMap(f);
	}

	/**
	 * Puts an archive which contains configuration files
	 * into the cache directory.
	 * 
	 * @param arch java archive which contains configuration files.
	 */
	public void putConfiguration(Archive arch)
		throws FileNotFoundException, IOException {
		JarInputStream jin =
			new JarInputStream(new ByteArrayInputStream(arch.getBytes()));
		JarEntry je;
		int len = 0;
		byte buf[] = new byte[1024];
		while ((je = jin.getNextJarEntry()) != null) {
			File f =
				new File(
					cacheDir.getAbsolutePath() + File.separator + je.getName());
			BufferedOutputStream out =
				new BufferedOutputStream(new FileOutputStream(f));
			while ((len = jin.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			out.close();
			jin.closeEntry();
		}
		jin.close();
	}

	/**
	 * Retrieves the archive from the cache. If it is not found,
	 * <code>null</code> is returned. It also deletes the archive
	 * from the cache.
	 * 
	 * @param arch The archive to search for.
	 * @return The <code>Archive</code> if found, <code>null</code> otherwise.
	 * @throws FileNotFoundException if the name of the <code>Archive</code>
	 * is a directory or is not readable due to any case.
	 * 
	 * @throws IOException if an I/O error occurs during reading or deleting the
	 * <code>Archive</code>
	 */
	public Archive get(String arch) throws FileNotFoundException, IOException {
		File f = new File(cacheDir.getAbsolutePath() + File.separator + arch);
		if (f.isFile()) {
			byte[] b = new byte[(int) f.length()];
			InputStream in = new BufferedInputStream(new FileInputStream(f));
			in.read(b);
			in.close();
			if (f.delete() == false) {
				throw new IOException(arch + " could not be deleted");
			}
			return new Archive(arch, b);
		}
		// no valid file ==> no archive returned
		return null;
	}

	/**
	 * Returns the <code>File</code> object for the given archive
	 * name.
	 * 
	 * @param arch The archive name.
	 * @return the <code>File</code> object for the archive name.
	 */
	public File getFile(String arch) throws FileNotFoundException {
		return new File(cacheDir.getAbsolutePath() + File.separator + arch);
	}

	/**
	 * Retrieves the version of an archive. The version information
	 * is taken from the version entry in the MANIFEST.MF file in
	 * the jar archive. If the archive is not in the cache or no
	 * MANIFEST.MF is found, <code>null</code> is returned.
	 * 
	 * The version string must be in the entry
	 * <code>Implementation-Version</code> of the main attributes
	 * of the MANIFEST.MF file.
	 * 
	 * @param arch The archive from which the version info is wanted
	 * @return the version info of the archive if available,
	 * <code>null</code> otherwise.
	 * @throws FileNotFoundException if the name of the <code>Archive</code>
	 * is a directory or is not readable due to any case.
	 * 
	 * @throws IOException if an I/O error occurs during reading the
	 * <code>Archive</code>
	 */
	public String getVersion(String arch)
		throws FileNotFoundException, IOException {
		File f = new File(cacheDir.getAbsolutePath() + File.separator + arch);
		JarInputStream in =
			new JarInputStream(new BufferedInputStream(new FileInputStream(f)));
		Manifest mf = in.getManifest();
		if (mf != null) {
			Attributes a = mf.getMainAttributes();
			return a.getValue("Implementation-Version");
		}
		return null;
	}

	/**
	 * Searches for the given class in the <code>Cache</code>. If
	 * not found, <code>null</code> is returned. If found, an
	 * <code>ByteArray</code> is delivered.
	 * 
	 * @param name the class to search for
	 * @return the <code>ByteArray</code> if found, <code>null</code> otherwise.
	 */
	public ByteArray getBytesForClass(String name) {
		return (ByteArray) classMap.get(name);
	}

	/**
	 * Clears this <code>Cache</code>. Removes the files from
	 * the local file system.
	 * */
	public void clear() {
		classMap.clear();
		File[] files = cacheDir.listFiles();
		for (int i = 0; i < files.length; i++) {
			if (files[i].delete() == false) {
				LaunchLogger.error(
					files[i].getName()
						+ " could not be deleted from local cache");
			}
		}
	}

	/**
	 * Returns true if this <code>Cache</code> is empty.
	 * 
	 * @return boolean <code>true</code> if this <code>Cache</code> is empty,
	 * <code>false</code> otherwise.
	 */
	public boolean isEmtpy() {
		File[] files = cacheDir.listFiles();
		return files.length == 0;
	}

	/**
	 * Returns the directory this <code>Cache</code> lives in.
	 * 
	 * @returnString the dir this <code>Cache</code> lives in.
	 */
	public String getCacheDir() {
		return cacheDir.getAbsolutePath();
	}
}

⌨️ 快捷键说明

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