diff --git a/core/pom.xml b/core/pom.xml index ea2f9ec5d..26634e2d6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -184,6 +184,11 @@ freemarker + + com.github.ben-manes.caffeine + caffeine + + javax.servlet javax.servlet-api diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlCaffeineCache.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlCaffeineCache.java new file mode 100644 index 000000000..7bb5f69c7 --- /dev/null +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlCaffeineCache.java @@ -0,0 +1,82 @@ +/* + * Copyright 2022 Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.opensymphony.xwork2.ognl; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; + +/** + *

This OGNL Cache implementation is backed by {@link Caffeine} which uses the Window TinyLfu algorithm.

+ * + *

An appropriate eviction limit should be chosen for your specific application based on factors and requirements + * such as:

+ * + * + * @param The type for the cache key entries + * @param The type for the cache value entries + */ +public class OgnlCaffeineCache implements OgnlCache { + + private final Cache cache; + private final int evictionLimit; + + public OgnlCaffeineCache(int evictionLimit, int initialCapacity, float loadFactor) { + this.evictionLimit = evictionLimit; + this.cache = Caffeine.newBuilder().initialCapacity(initialCapacity).maximumSize(evictionLimit).build(); + } + + @Override + public Value get(Key key) { + return cache.getIfPresent(key); + } + + @Override + public void put(Key key, Value value) { + cache.put(key, value); + } + + @Override + public void putIfAbsent(Key key, Value value) { + if (cache.getIfPresent(key) == null) { + cache.put(key, value); + } + } + + @Override + public int size() { + return Math.toIntExact(cache.estimatedSize()); + } + + @Override + public void clear() { + cache.invalidateAll(); + } + + @Override + public int getEvictionLimit() { + return evictionLimit; + } + + @Override + public void setEvictionLimit(int cacheEvictionLimit) { + throw new UnsupportedOperationException("Cannot change eviction limit on a Caffeine cache after initialisation"); + } +} diff --git a/pom.xml b/pom.xml index d0a5aed20..050a598c4 100644 --- a/pom.xml +++ b/pom.xml @@ -685,6 +685,12 @@ ${freemarker.version}
+ + com.github.ben-manes.caffeine + caffeine + 3.1.8 + + org.apache.felix org.apache.felix.framework