All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.redhat.ceylon.langtools.tools.javac.file.JImageZipFile Maven / Gradle / Ivy

There is a newer version: 1.3.3
Show newest version
package com.redhat.ceylon.langtools.tools.javac.file;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.redhat.ceylon.javax.tools.JavaFileObject;
import com.redhat.ceylon.langtools.tools.javac.file.JavacFileManager.Archive;
import com.redhat.ceylon.langtools.tools.javac.file.RelativePath.RelativeDirectory;
import com.redhat.ceylon.langtools.tools.javac.util.List;
import com.redhat.ceylon.langtools.tools.javac.util.ListBuffer;

public class JImageZipFile implements Archive {

	public class JImageFileObject extends BaseFileObject {

		private Path path;

		public JImageFileObject(Path path) {
			super(JImageZipFile.this.fileManager);
			this.path = path;
		}

		@Override
		public URI toUri() {
			return path.toUri();
		}

		@Override
		public String getName() {
			return path.toString();
		}

		@Override
		public InputStream openInputStream() throws IOException {
			return Files.newInputStream(path);
		}

		@Override
		public OutputStream openOutputStream() throws IOException {
            throw new UnsupportedOperationException();
		}

		@Override
		public Kind getKind() {
            return getKind(getName());
		}

		@Override
		public boolean isNameCompatible(String cn, Kind k) {
            cn.getClass();
            // null check
            if (k == Kind.OTHER && getKind() != k) {
                return false;
            }
            return getName().equals(cn + k.extension);
		}

		@Override
		public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
            CharBuffer cb = fileManager.getCachedContent(this);
            if (cb == null) {
                InputStream in = openInputStream();
                try {
                    ByteBuffer bb = fileManager.makeByteBuffer(in);
                    JavaFileObject prev = fileManager.log.useSource(this);
                    try {
                        cb = fileManager.decode(bb, ignoreEncodingErrors);
                    } finally {
                        fileManager.log.useSource(prev);
                    }
                    fileManager.recycleByteBuffer(bb);
                    if (!ignoreEncodingErrors) {
                        fileManager.cache(this, cb);
                    }
                } finally {
                    in.close();
                }
            }
            return cb;
		}

		@Override
		public Writer openWriter() throws IOException {
            throw new UnsupportedOperationException();
		}

		@Override
		public long getLastModified() {
			try {
				return Files.getLastModifiedTime(path).toMillis();
			} catch (IOException e) {
				return 0;
			}
		}

		@Override
		public boolean delete() {
            throw new UnsupportedOperationException();
		}

		@Override
		public String getShortName() {
			return path.toString();
		}

		@Override
		protected String inferBinaryName(Iterable path) {
            String entryName = getName();
            return removeExtension(entryName).replace('/', '.');
		}

		@Override
		public boolean equals(Object other) {
			if(other == null)
				return false;
			if(other instanceof JImageFileObject == false)
				return false;
			return path.equals(((JImageFileObject)other).path);
		}

		@Override
		public int hashCode() {
			return path.hashCode();
		}


	}

	private static class Entry {
		Map entries = new HashMap<>();
		boolean isFolder;
		String name;
		Entry parent;
		String module;
		
		Entry(Entry parent, String name, boolean isFolder, String module){
			this.module = module;
			this.parent = parent;
			this.name = name;
			this.isFolder = isFolder;
		}

		public void addEntry(Entry entry) {
			entries.put(entry.name, entry);
		}

		public Entry getEntry(String name) {
			return entries.get(name);
		}

		public String getAbsolutePath() {
			return parent != null 
					? parent.getAbsolutePath() + "/" + name
							: "/" + name;
		}

		public String getFullPathWithModule() {
			return "/modules/"+module+getAbsolutePath();
		}
	}
	
	private FileSystem fileSystem;
	private JavacFileManager fileManager;
	private Map roots = new HashMap<>();
	Map absoluteEntries = new HashMap();

	public JImageZipFile(JavacFileManager fm, File fileName) {
		fileManager = fm;
		fileSystem = FileSystems.getFileSystem(URI.create("jrt:/"));
		try {
			loadModules();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void loadModules() throws IOException {
		for(Path module : Files.newDirectoryStream(fileSystem.getPath("/modules"))){
			for(Path root : Files.newDirectoryStream(module)){
				scan(root, null, "", module.getFileName().toString());
			}
		}
	}

	public void scan(Path path, Entry container, String parentPath, String module) throws IOException {
		Entry entry;
		String name = path.getFileName().toString();
		String thisPath = parentPath+name;
		boolean newEntry = false;
		if(Files.isDirectory(path)){
			thisPath += "/";
			if(container != null)
				entry = container.getEntry(name);
			else
				entry = roots.get(name);
			if(entry == null){
				entry = new Entry(container, name, true, module);
				newEntry = true;
			}
			for(Path child : Files.newDirectoryStream(path)){
				scan(child, entry, thisPath, module);
			}
		}else{
			// in theory we can't have a single file more than once
			entry = new Entry(container, path.getFileName().toString(), false, module);
			newEntry = true;
		}
		if(newEntry){
			//System.err.println("Adding path "+thisPath);
			absoluteEntries.put(thisPath, entry);
			if(container != null)
				container.addEntry(entry);
			else
				roots.put(entry.name, entry);
		}
	}

	@Override
	public void close() throws IOException {
		// DO NOT call that: 
		// java.lang.UnsupportedOperationException
		// at jdk.internal.jrtfs.JrtFileSystemProvider$1.close([email protected]/JrtFileSystemProvider.java:130)

//		fileSystem.close();
	}

	@Override
	public boolean contains(RelativePath name) {
		//System.err.println("contains " + name.getPath());
		return absoluteEntries.containsKey(name.getPath());
	}

	@Override
	public JavaFileObject getFileObject(RelativeDirectory subdirectory, String file) {
		//System.err.println("getFileObject " + subdirectory.getPath()+file);
		Entry entry = absoluteEntries.get(subdirectory.getPath()+file);
		if(entry != null && !entry.isFolder){
			String path = entry.getFullPathWithModule();
			//System.err.println(" => " + path);
			return new JImageFileObject(fileSystem.getPath(path));
		}
		return null;
	}

	@Override
	public List getFiles(RelativeDirectory subdirectory) {
		//System.err.println("getFiles " + subdirectory.getPath());
		Entry entry = absoluteEntries.get(subdirectory.getPath());
		if(entry != null && entry.isFolder){
	        ListBuffer ret = new ListBuffer();
	        for (String child : entry.entries.keySet()) {
	        	ret.add(child);
	        }
	        return ret.toList();
		}
		return List.nil();
	}

	@Override
	public Set getSubdirectories() {
		//System.err.println("getSubdirectories");
		final Set ret = new HashSet<>();
		for(Entry entry : absoluteEntries.values()){
			if(entry.isFolder)
				ret.add(new RelativeDirectory(entry.getAbsolutePath()));
		}
		return ret;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy