001/* 002 * Copyright (C) 2022 Ashley Scopes 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.workspaces; 017 018import io.github.ascopes.jct.workspaces.impl.AbstractManagedDirectory; 019import io.github.ascopes.jct.workspaces.impl.RamDirectoryImpl; 020import io.github.ascopes.jct.workspaces.impl.TempDirectoryImpl; 021import java.io.File; 022import java.nio.file.Path; 023import java.util.function.Function; 024import javax.annotation.processing.Filer; 025 026/** 027 * Strategy to use for creating new test directories. 028 * 029 * <p>This is used to define whether to use a totally isolated in-memory file system, 030 * or whether to use temporary directories on the default file system. 031 * 032 * @author Ashley Scopes 033 * @since 0.0.1 034 */ 035public enum PathStrategy { 036 /** 037 * Use RAM-based directories for any created directories. 038 * 039 * <p>This is faster as everything remains in-memory. It also prevents the risk of resources 040 * not being tidied up correctly if the JVM is suddenly shut down. Test directories are also kept 041 * isolated from other tests that may be running in parallel, and isolated from the host operating 042 * system. 043 * 044 * <p>If any annotation processors rely on being run in the {@link File default file system} 045 * rather than using {@link Path the NIO path API} or {@link Filer filers} directly, then they 046 * will not be compatible with reading files from this implementation of test directory. In this 047 * situation, users should opt to use {@link #TEMP_DIRECTORIES} instead. 048 * 049 * <p>Some non-Javac compiler implementations (such as ECJ) may also have some difficulties 050 * dealing with these paths. 051 */ 052 RAM_DIRECTORIES(RamDirectoryImpl::newRamDirectory), 053 054 /** 055 * Use OS-level temporary directories for any created directories. 056 * 057 * <p>This will write files to the OS temporary directory. These files will be deleted once the 058 * owning workspace is closed, but may be missed if the JVM is forcefully terminated or crashes. 059 * 060 * <p>There are fewer guarantees of speed and isolation compared to using 061 * {@link #RAM_DIRECTORIES}. However, you do gain the ability to set a breakpoint and inspect the 062 * contents of the directory in a file explorer. 063 * 064 * <p>Since the temporary directories are usually created on the 065 * {@link File default file system}, they are compatible with any annotation processors or 066 * compiler implementations that expect to be run on the default file system only. 067 * 068 * <p>Some restrictions regarding file naming may be present depending on the platform that 069 * is in use, such as file name lengths on Windows. See your system documentation for more 070 * details. 071 */ 072 TEMP_DIRECTORIES(TempDirectoryImpl::newTempDirectory); 073 074 @SuppressWarnings("ImmutableEnumChecker") 075 private final Function<String, AbstractManagedDirectory> constructor; 076 077 PathStrategy(Function<String, AbstractManagedDirectory> constructor) { 078 this.constructor = constructor; 079 } 080 081 /** 082 * Create a new instance of the test directory type with the given name. 083 * 084 * <p>Note that calling this directly will return an object that you will have to manually 085 * manage the lifetime for. Failing to do so will result in resources being leaked. 086 * 087 * <p><strong>Users should not call this method by default unless they know what they are 088 * doing.</strong> As a result of this constraint, this method is not part of the public API and 089 * may be subject to change without notice. 090 * 091 * @param name the name to use. 092 * @return the new test directory. 093 */ 094 public ManagedDirectory newInstance(String name) { 095 return constructor.apply(name); 096 } 097 098 /** 099 * Determine the default strategy to fall back onto. 100 * 101 * <p>This will be {@link #RAM_DIRECTORIES} by default, but this may be subject to change between 102 * minor versions without notice. Do not rely on this if you are testing code that may be 103 * sensitive to the type of file system being used. 104 * 105 * @return the path strategy to use by default. 106 */ 107 public static PathStrategy defaultStrategy() { 108 return RAM_DIRECTORIES; 109 } 110}