View Javadoc
1   /*
2    * Copyright 2002-2014 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.web.servlet.config.annotation;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.springframework.cache.Cache;
23  import org.springframework.cache.concurrent.ConcurrentMapCache;
24  import org.springframework.util.Assert;
25  import org.springframework.web.servlet.resource.CachingResourceResolver;
26  import org.springframework.web.servlet.resource.CachingResourceTransformer;
27  import org.springframework.web.servlet.resource.CssLinkResourceTransformer;
28  import org.springframework.web.servlet.resource.PathResourceResolver;
29  import org.springframework.web.servlet.resource.ResourceResolver;
30  import org.springframework.web.servlet.resource.ResourceTransformer;
31  import org.springframework.web.servlet.resource.VersionResourceResolver;
32  
33  /**
34   * Assists with the registration of resource resolvers and transformers.
35   *
36   * @author Rossen Stoyanchev
37   * @since 4.1
38   */
39  public class ResourceChainRegistration {
40  
41  	private static final String DEFAULT_CACHE_NAME = "spring-resource-chain-cache";
42  
43  	private final List<ResourceResolver> resolvers = new ArrayList<ResourceResolver>(4);
44  
45  	private final List<ResourceTransformer> transformers = new ArrayList<ResourceTransformer>(4);
46  
47  	private boolean hasVersionResolver;
48  
49  	private boolean hasPathResolver;
50  
51  	private boolean hasCssLinkTransformer;
52  
53  
54  	public ResourceChainRegistration(boolean cacheResources) {
55  		this(cacheResources, cacheResources ? new ConcurrentMapCache(DEFAULT_CACHE_NAME) : null);
56  	}
57  
58  	public ResourceChainRegistration(boolean cacheResources, Cache cache) {
59  		Assert.isTrue(!cacheResources || cache != null, "'cache' is required when cacheResources=true");
60  		if (cacheResources) {
61  			this.resolvers.add(new CachingResourceResolver(cache));
62  			this.transformers.add(new CachingResourceTransformer(cache));
63  		}
64  	}
65  
66  
67  	/**
68  	 * Add a resource resolver to the chain.
69  	 * @param resolver the resolver to add
70  	 * @return the current instance for chained method invocation
71  	 */
72  	public ResourceChainRegistration addResolver(ResourceResolver resolver) {
73  		Assert.notNull(resolver, "The provided ResourceResolver should not be null");
74  		this.resolvers.add(resolver);
75  		if (resolver instanceof VersionResourceResolver) {
76  			this.hasVersionResolver = true;
77  		}
78  		else if (resolver instanceof PathResourceResolver) {
79  			this.hasPathResolver = true;
80  		}
81  		return this;
82  	}
83  
84  	/**
85  	 * Add a resource transformer to the chain.
86  	 * @param transformer the transformer to add
87  	 * @return the current instance for chained method invocation
88  	 */
89  	public ResourceChainRegistration addTransformer(ResourceTransformer transformer) {
90  		Assert.notNull(transformer, "The provided ResourceTransformer should not be null");
91  		this.transformers.add(transformer);
92  		if (transformer instanceof CssLinkResourceTransformer) {
93  			this.hasCssLinkTransformer = true;
94  		}
95  		return this;
96  	}
97  
98  	protected List<ResourceResolver> getResourceResolvers() {
99  		if (!this.hasPathResolver) {
100 			List<ResourceResolver> result = new ArrayList<ResourceResolver>(this.resolvers);
101 			result.add(new PathResourceResolver());
102 			return result;
103 		}
104 		return this.resolvers;
105 	}
106 
107 	protected List<ResourceTransformer> getResourceTransformers() {
108 		if (this.hasVersionResolver  && !this.hasCssLinkTransformer) {
109 			List<ResourceTransformer> result = new ArrayList<ResourceTransformer>(this.transformers);
110 			boolean hasTransformers = !this.transformers.isEmpty();
111 			boolean hasCaching = hasTransformers && this.transformers.get(0) instanceof CachingResourceTransformer;
112 			result.add(hasCaching ? 1 : 0, new CssLinkResourceTransformer());
113 			return result;
114 		}
115 		return this.transformers;
116 	}
117 
118 }