view src/goodjava/io/FileClassLoader.java @ 1844:9147ce7f5b72 default tip

FileClassLoader use SoftCacheMap
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 02 Feb 2025 04:55:02 -0700
parents 22f73129eb4a
children
line wrap: on
line source

package goodjava.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.MalformedURLException;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import goodjava.util.SoftCacheMap;


public class FileClassLoader extends URLClassLoader {

	public static final class FileInfo {
		public final File file;
		private final long checksum;

		public FileInfo(File file) throws IOException {
			this.file = file;
			this.checksum = IoUtils.checksum( new BufferedInputStream( new FileInputStream(file) ) );
		}

		public boolean equals(Object obj) {
			if( !(obj instanceof FileInfo) )
				return false;
			FileInfo fi = (FileInfo)obj;
			return this.checksum==fi.checksum && this.file.getName().equals(fi.file.getName());
		}

		public int hashCode() {
			return (int)checksum;
		}
	}

	private static URL[] toURLs(List<FileInfo> files) {
		int n = files.size();
		URL[] urls = new URL[n];
		for( int i=0; i<n; i++ ) {
			try {
				urls[i] = files.get(i).file.toURI().toURL();
			} catch(MalformedURLException e) {
				throw new RuntimeException(e);
			}
		}
		return urls;
	}

	private final List<FileInfo> files;

	private FileClassLoader(List<FileInfo> files) {
		super(toURLs(files));
		this.files = new ArrayList<FileInfo>(files);
	}

	public List<FileInfo> getFiles() {
		return new ArrayList<FileInfo>(files);
	}

	private static final Map<List<FileInfo>,FileClassLoader> map = new SoftCacheMap<List<FileInfo>,FileClassLoader>();

	public static synchronized FileClassLoader getFileClassLoader(List<FileInfo> files) {
		FileClassLoader fcl = map.get(files);
		if( fcl == null ) {
			fcl = new FileClassLoader(files);
			map.put(fcl.files,fcl);
		}
		return fcl;
	}
}