001/* 002 * Copyright (C) 2022 - 2023, the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.github.ascopes.jct.containers; 017 018import io.github.ascopes.jct.filemanagers.PathFileObject; 019import io.github.ascopes.jct.workspaces.PathRoot; 020import java.io.Closeable; 021import java.io.IOException; 022import java.lang.module.ModuleFinder; 023import java.nio.file.Path; 024import java.util.Collection; 025import java.util.Set; 026import javax.tools.FileObject; 027import javax.tools.JavaFileManager.Location; 028import javax.tools.JavaFileObject; 029import javax.tools.JavaFileObject.Kind; 030import org.apiguardian.api.API; 031import org.apiguardian.api.API.Status; 032 033/** 034 * Container that wraps a file path source of some description. 035 * 036 * <p>Closing this resource will close any internally held resources that were opened internally. 037 * Already-opened resources passed to the implementation will not be closed. 038 * 039 * @author Ashley Scopes 040 * @since 0.0.1 041 */ 042@API(since = "0.0.1", status = Status.STABLE) 043public interface Container extends Closeable { 044 045 /** 046 * Determine if this container contains the path file object. 047 * 048 * @param fileObject the file object to look up. 049 * @return {@code true} if the object exists in this container, or {@code false} otherwise. 050 */ 051 boolean contains(PathFileObject fileObject); 052 053 /** 054 * Find the physical path to a given string file path. 055 * 056 * <p>Examples: 057 * 058 * <pre><code> 059 * // Using platform-specific separators ('/' for in-memory file systems). 060 * container.getFile("foo/bar/baz.txt"); 061 * 062 * // Letting JCT infer the correct path separators to use. 063 * container.getFile("foo", "bar", "baz.txt"); 064 * </code></pre> 065 * 066 * @param fragment the first part of the file name. 067 * @param fragments any additional parts of the file name to find. 068 * @return the path if the file exists, or null if it does not exist. 069 */ 070 Path getFile(String fragment, String... fragments); 071 072 /** 073 * Get a {@link FileObject} for reading, if it exists. 074 * 075 * <p>If the file does not exist, {@code null} is returned. 076 * 077 * @param packageName the package name of the file. 078 * @param relativeName the relative name of the file in the package. 079 * @return the file object, or null if it does not exist. 080 */ 081 PathFileObject getFileForInput(String packageName, String relativeName); 082 083 /** 084 * Get a {@link FileObject} for writing. 085 * 086 * <p>If the container is read-only, {@code null} is returned. 087 * 088 * @param packageName the package name of the file. 089 * @param relativeName the relative name of the file in the package. 090 * @return the file object, or null if this container is read-only. 091 */ 092 PathFileObject getFileForOutput(String packageName, String relativeName); 093 094 /** 095 * Get a {@link JavaFileObject} for reading, if it exists. 096 * 097 * <p>If the file does not exist, {@code null} is returned. 098 * 099 * @param className the binary name of the class to open. 100 * @param kind the kind of file to open. 101 * @return the file object, or null if it does not exist. 102 */ 103 PathFileObject getJavaFileForInput(String className, Kind kind); 104 105 /** 106 * Get a {@link JavaFileObject} for writing. 107 * 108 * <p>If the container is read-only, {@code null} is returned. 109 * 110 * @param className the binary name of the class to open. 111 * @param kind the kind of file to open. 112 * @return the file object, or null if this container is read-only. 113 */ 114 PathFileObject getJavaFileForOutput(String className, Kind kind); 115 116 /** 117 * Get the location of this container. 118 * 119 * @return the location. 120 */ 121 Location getLocation(); 122 123 /** 124 * Get a module finder for this container. 125 * 126 * <p>Note that this will not detect modules that are not yet compiled. 127 * 128 * @return the module finder for this container, or {@code null} if not relevant to the 129 * implementation. 130 */ 131 ModuleFinder getModuleFinder(); 132 133 /** 134 * Get the name of this container for human consumption. 135 * 136 * @return the container name. 137 */ 138 String getName(); 139 140 /** 141 * Get the path root of the container. 142 * 143 * @return the path root. 144 */ 145 PathRoot getPathRoot(); 146 147 /** 148 * Infer the binary name of a given Java file object. 149 * 150 * @param javaFileObject the Java file object to infer the binary name of. 151 * @return the name, or null if the file does not exist in this container. 152 */ 153 String inferBinaryName(PathFileObject javaFileObject); 154 155 /** 156 * List all files within this container. 157 * 158 * @return all files within the container, relative to the container base path. 159 * @throws IOException if the file system failed to be read. 160 */ 161 Collection<Path> listAllFiles() throws IOException; 162 163 /** 164 * List all the file objects that match the given criteria in this group. 165 * 166 * <p>The results are filled into a given collection, since this call may be made many times 167 * per compliation, and this reduces the memory overhead needed in such cases. 168 * 169 * @param packageName the package name to look in. 170 * @param kinds the kinds of file to look for. Set to {@code Set.of(Kind.OTHER)} to find all 171 * types of file. 172 * @param recurse {@code true} to recurse subpackages, {@code false} to only consider the 173 * given package. 174 * @param collection the collection to fill. 175 * @throws IOException if the file system failed to be read. 176 */ 177 void listFileObjects( 178 String packageName, 179 Set<? extends Kind> kinds, 180 boolean recurse, 181 Collection<JavaFileObject> collection 182 ) throws IOException; 183}