diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/RamFileSystemProvider.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/RamFileSystemProvider.java new file mode 100644 index 000000000..f792c400d --- /dev/null +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/RamFileSystemProvider.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 - 2023, the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.ascopes.jct.workspaces; + +import io.github.ascopes.jct.workspaces.impl.DefaultFileSystemProviderImpl; +import java.nio.file.FileSystem; +import java.util.ServiceLoader; +import org.apiguardian.api.API; +import org.apiguardian.api.API.Status; + +/** + * Service provider interface for a RAM-based file system provider. + * + *

This enables swapping out the default RAM file system implementation with a custom + * implementation by using Java's {@link ServiceLoader} mechanism. + * + * @author Ashley Scopes + * @since 0.0.1 (0.0.1-M9) + */ +@API(since = "0.0.1", status = Status.STABLE) +public interface RamFileSystemProvider { + + /** + * Create the new file system. + * + * @param name the file system name to use. + * @return the file system object. + */ + FileSystem createFileSystem(String name); + + /** + * Get the service provider implementation to use. + * + * @return the first service provider implementation, or a default implementation if not provided. + */ + static RamFileSystemProvider getInstance() { + return ServiceLoader + .load(RamFileSystemProvider.class) + .findFirst() + .orElseGet(DefaultFileSystemProviderImpl::getInstance); + } +} diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/impl/DefaultFileSystemProviderImpl.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/impl/DefaultFileSystemProviderImpl.java new file mode 100644 index 000000000..b8216b037 --- /dev/null +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/impl/DefaultFileSystemProviderImpl.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2022 - 2023, the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.ascopes.jct.workspaces.impl; + +import com.google.common.jimfs.Configuration; +import com.google.common.jimfs.Feature; +import com.google.common.jimfs.Jimfs; +import com.google.common.jimfs.PathType; +import io.github.ascopes.jct.workspaces.RamFileSystemProvider; +import java.nio.file.FileSystem; +import org.apiguardian.api.API; +import org.apiguardian.api.API.Status; + +/** + * RAM file system provider that uses JIMFS as the underlying file system implementation. + * + * @author Ashley Scopes + * @since 0.0.1 (0.0.1-M9) + */ +@API(since = "0.0.1", status = Status.INTERNAL) +public final class DefaultFileSystemProviderImpl implements RamFileSystemProvider { + + private static final DefaultFileSystemProviderImpl INSTANCE = new DefaultFileSystemProviderImpl(); + + /** + * Get the singleton instance of this provider. + * + * @return the singleton instance. + */ + public static DefaultFileSystemProviderImpl getInstance() { + return INSTANCE; + } + + private DefaultFileSystemProviderImpl() { + // Singleton object. + } + + @Override + public FileSystem createFileSystem(String name) { + var config = Configuration + .builder(PathType.unix()) + .setSupportedFeatures(Feature.LINKS, Feature.SYMBOLIC_LINKS, Feature.FILE_CHANNEL) + .setAttributeViews("basic", "posix") + .setRoots("/") + .setWorkingDirectory("/") + .setPathEqualityUsesCanonicalForm(true) + .build(); + + return Jimfs.newFileSystem(config); + } +} diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/impl/RamDirectoryImpl.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/impl/RamDirectoryImpl.java index 77e660087..df140d5e2 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/impl/RamDirectoryImpl.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/workspaces/impl/RamDirectoryImpl.java @@ -18,10 +18,7 @@ import static io.github.ascopes.jct.utils.FileUtils.assertValidRootName; import static io.github.ascopes.jct.utils.IoExceptionUtils.uncheckedIo; -import com.google.common.jimfs.Configuration; -import com.google.common.jimfs.Feature; -import com.google.common.jimfs.Jimfs; -import com.google.common.jimfs.PathType; +import io.github.ascopes.jct.workspaces.RamFileSystemProvider; import java.io.IOException; import java.nio.file.FileSystem; import java.nio.file.Files; @@ -95,16 +92,7 @@ public static RamDirectoryImpl newRamDirectory(String name) { assertValidRootName(name); - var config = Configuration - .builder(PathType.unix()) - .setSupportedFeatures(Feature.LINKS, Feature.SYMBOLIC_LINKS, Feature.FILE_CHANNEL) - .setAttributeViews("basic", "posix") - .setRoots("/") - .setWorkingDirectory("/") - .setPathEqualityUsesCanonicalForm(true) - .build(); - - var fileSystem = Jimfs.newFileSystem(config); + var fileSystem = RamFileSystemProvider.getInstance().createFileSystem(name); var path = fileSystem.getRootDirectories().iterator().next().resolve(name); // Ensure the base directory exists. diff --git a/java-compiler-testing/src/main/java/module-info.java b/java-compiler-testing/src/main/java/module-info.java index 743c7be97..1e8dee47b 100644 --- a/java-compiler-testing/src/main/java/module-info.java +++ b/java-compiler-testing/src/main/java/module-info.java @@ -13,6 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +import io.github.ascopes.jct.workspaces.RamFileSystemProvider; + /** * A framework for performing exhaustive integration testing against Java compilers in modern Java * libraries, with a focus on full JPMS support. @@ -116,6 +119,12 @@ exports io.github.ascopes.jct.repr; exports io.github.ascopes.jct.workspaces; + /////////////////////////////////// + /// SERVICE PROVIDER INTERFACES /// + /////////////////////////////////// + + uses RamFileSystemProvider; + ////////////////////////////////////////////////////// /// EXPOSURE OF INTERNALS TO THE TESTING NAMESPACE /// //////////////////////////////////////////////////////