package net.filebot; import java.util.function.Function; @FunctionalInterface public interface Resource { R get() throws Exception; default MemoizedResource memoize() { return new MemoizedResource(this); } default Resource transform(Function function) { return new TransformedResource(this, function); } static MemoizedResource lazy(Resource resource) { return resource.memoize(); } } class MemoizedResource implements Resource { private final Resource resource; private R value; public MemoizedResource(Resource resource) { this.resource = resource; } @Override public synchronized R get() throws Exception { if (value == null) { value = resource.get(); } return value; } public synchronized void clear() { value = null; } } class TransformedResource implements Resource { private final Resource resource; private final Function function; public TransformedResource(Resource resource, Function function) { this.resource = resource; this.function = function; } @Override public T get() throws Exception { return function.apply(resource.get()); } }