package com.github.marschall.memoryfilesystem; import java.io.IOException; import java.nio.file.attribute.GroupPrincipal; import java.util.concurrent.Callable; /** * Provides access to the group of the current user. */ public final class CurrentGroup { private CurrentGroup() { throw new AssertionError("not instantiable"); } private static final ThreadLocal<GroupPrincipal> GROUP = new ThreadLocal<>(); /** * Sets the current group for a certain period. * * @param group the group to use * @param task during this task the given group will be used, will be called * immediately by the current thread * @param <V> the type of the return value * @return what the task returned * @throws IOException if any of the code in the task throws an * {@link IOException} */ public static <V> V useDuring(GroupPrincipal group, GroupTask<V> task) throws IOException { GroupPrincipal previous = GROUP.get(); try { GROUP.set(group); return task.call(); } finally { if (previous == null) { GROUP.remove(); } else { GROUP.set(previous); } } } static GroupPrincipal get() { return GROUP.get(); } /** * Functional interface for a task during which a certain group should be used. * * @param <V> the type of the return value */ public interface GroupTask<V> extends Callable<V> { /** * Executes the task. * * @return the return value of the task * @throws IOException if any of the code in the task throws an * {@link IOException} */ @Override V call() throws IOException; } }