001/* 002 * Copyright 2002-2018 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.cache.interceptor; 018 019import java.util.Collections; 020import java.util.LinkedHashSet; 021import java.util.Set; 022 023import org.springframework.lang.Nullable; 024import org.springframework.util.Assert; 025 026/** 027 * Base class for cache operations. 028 * 029 * @author Costin Leau 030 * @author Stephane Nicoll 031 * @author Marcin Kamionowski 032 * @since 3.1 033 */ 034public abstract class CacheOperation implements BasicOperation { 035 036 private final String name; 037 038 private final Set<String> cacheNames; 039 040 private final String key; 041 042 private final String keyGenerator; 043 044 private final String cacheManager; 045 046 private final String cacheResolver; 047 048 private final String condition; 049 050 private final String toString; 051 052 053 /** 054 * Create a new {@link CacheOperation} instance from the given builder. 055 * @since 4.3 056 */ 057 protected CacheOperation(Builder b) { 058 this.name = b.name; 059 this.cacheNames = b.cacheNames; 060 this.key = b.key; 061 this.keyGenerator = b.keyGenerator; 062 this.cacheManager = b.cacheManager; 063 this.cacheResolver = b.cacheResolver; 064 this.condition = b.condition; 065 this.toString = b.getOperationDescription().toString(); 066 } 067 068 069 public String getName() { 070 return this.name; 071 } 072 073 @Override 074 public Set<String> getCacheNames() { 075 return this.cacheNames; 076 } 077 078 public String getKey() { 079 return this.key; 080 } 081 082 public String getKeyGenerator() { 083 return this.keyGenerator; 084 } 085 086 public String getCacheManager() { 087 return this.cacheManager; 088 } 089 090 public String getCacheResolver() { 091 return this.cacheResolver; 092 } 093 094 public String getCondition() { 095 return this.condition; 096 } 097 098 099 /** 100 * This implementation compares the {@code toString()} results. 101 * @see #toString() 102 */ 103 @Override 104 public boolean equals(@Nullable Object other) { 105 return (other instanceof CacheOperation && toString().equals(other.toString())); 106 } 107 108 /** 109 * This implementation returns {@code toString()}'s hash code. 110 * @see #toString() 111 */ 112 @Override 113 public int hashCode() { 114 return toString().hashCode(); 115 } 116 117 /** 118 * Return an identifying description for this cache operation. 119 * <p>Returned value is produced by calling {@link Builder#getOperationDescription()} 120 * during object construction. This method is used in {@link #hashCode} and 121 * {@link #equals}. 122 * @see Builder#getOperationDescription() 123 */ 124 @Override 125 public final String toString() { 126 return this.toString; 127 } 128 129 130 /** 131 * Base class for builders that can be used to create a {@link CacheOperation}. 132 * @since 4.3 133 */ 134 public abstract static class Builder { 135 136 private String name = ""; 137 138 private Set<String> cacheNames = Collections.emptySet(); 139 140 private String key = ""; 141 142 private String keyGenerator = ""; 143 144 private String cacheManager = ""; 145 146 private String cacheResolver = ""; 147 148 private String condition = ""; 149 150 public void setName(String name) { 151 Assert.hasText(name, "Name must not be empty"); 152 this.name = name; 153 } 154 155 public void setCacheName(String cacheName) { 156 Assert.hasText(cacheName, "Cache name must not be empty"); 157 this.cacheNames = Collections.singleton(cacheName); 158 } 159 160 public void setCacheNames(String... cacheNames) { 161 this.cacheNames = new LinkedHashSet<>(cacheNames.length); 162 for (String cacheName : cacheNames) { 163 Assert.hasText(cacheName, "Cache name must be non-empty if specified"); 164 this.cacheNames.add(cacheName); 165 } 166 } 167 168 public Set<String> getCacheNames() { 169 return this.cacheNames; 170 } 171 172 public void setKey(String key) { 173 Assert.notNull(key, "Key must not be null"); 174 this.key = key; 175 } 176 177 public String getKey() { 178 return this.key; 179 } 180 181 public String getKeyGenerator() { 182 return this.keyGenerator; 183 } 184 185 public String getCacheManager() { 186 return this.cacheManager; 187 } 188 189 public String getCacheResolver() { 190 return this.cacheResolver; 191 } 192 193 public void setKeyGenerator(String keyGenerator) { 194 Assert.notNull(keyGenerator, "KeyGenerator name must not be null"); 195 this.keyGenerator = keyGenerator; 196 } 197 198 public void setCacheManager(String cacheManager) { 199 Assert.notNull(cacheManager, "CacheManager name must not be null"); 200 this.cacheManager = cacheManager; 201 } 202 203 public void setCacheResolver(String cacheResolver) { 204 Assert.notNull(cacheResolver, "CacheResolver name must not be null"); 205 this.cacheResolver = cacheResolver; 206 } 207 208 public void setCondition(String condition) { 209 Assert.notNull(condition, "Condition must not be null"); 210 this.condition = condition; 211 } 212 213 /** 214 * Return an identifying description for this caching operation. 215 * <p>Available to subclasses, for inclusion in their {@code toString()} result. 216 */ 217 protected StringBuilder getOperationDescription() { 218 StringBuilder result = new StringBuilder(getClass().getSimpleName()); 219 result.append("[").append(this.name); 220 result.append("] caches=").append(this.cacheNames); 221 result.append(" | key='").append(this.key); 222 result.append("' | keyGenerator='").append(this.keyGenerator); 223 result.append("' | cacheManager='").append(this.cacheManager); 224 result.append("' | cacheResolver='").append(this.cacheResolver); 225 result.append("' | condition='").append(this.condition).append("'"); 226 return result; 227 } 228 229 public abstract CacheOperation build(); 230 } 231 232}