001/* 002 * Copyright 2002-2019 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 * https://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 */ 016 017package org.springframework.web.reactive.resource; 018 019import org.apache.commons.logging.Log; 020import org.apache.commons.logging.LogFactory; 021import reactor.core.publisher.Mono; 022 023import org.springframework.cache.Cache; 024import org.springframework.cache.CacheManager; 025import org.springframework.core.io.Resource; 026import org.springframework.util.Assert; 027import org.springframework.web.server.ServerWebExchange; 028 029/** 030 * A {@link ResourceTransformer} that checks a {@link Cache} to see if a 031 * previously transformed resource exists in the cache and returns it if found, 032 * or otherwise delegates to the resolver chain and caches the result. 033 * 034 * @author Rossen Stoyanchev 035 * @since 5.0 036 */ 037public class CachingResourceTransformer implements ResourceTransformer { 038 039 private static final Log logger = LogFactory.getLog(CachingResourceTransformer.class); 040 041 private final Cache cache; 042 043 044 public CachingResourceTransformer(Cache cache) { 045 Assert.notNull(cache, "Cache is required"); 046 this.cache = cache; 047 } 048 049 public CachingResourceTransformer(CacheManager cacheManager, String cacheName) { 050 Cache cache = cacheManager.getCache(cacheName); 051 if (cache == null) { 052 throw new IllegalArgumentException("Cache '" + cacheName + "' not found"); 053 } 054 this.cache = cache; 055 } 056 057 058 /** 059 * Return the configured {@code Cache}. 060 */ 061 public Cache getCache() { 062 return this.cache; 063 } 064 065 066 @Override 067 public Mono<Resource> transform(ServerWebExchange exchange, Resource resource, 068 ResourceTransformerChain transformerChain) { 069 070 Resource cachedResource = this.cache.get(resource, Resource.class); 071 if (cachedResource != null) { 072 if (logger.isTraceEnabled()) { 073 logger.trace(exchange.getLogPrefix() + "Resource resolved from cache"); 074 } 075 return Mono.just(cachedResource); 076 } 077 078 return transformerChain.transform(exchange, resource) 079 .doOnNext(transformed -> this.cache.put(resource, transformed)); 080 } 081 082}