[Update] Common 调整 CacheStoreBuilder 的 factory 重载过程, 增强测试覆盖率, 将 FactoryInfo 设计为不可继承;

[Change] FactoryInfo 添加 final 关键字以阻止继承;
[Change] CacheStoreBuilder 调整 factory 的重载过程, 使其尽可能符合线程安全(目前就测试结果而言应该是没问题的), 将 Factory 非空检查独立成一个方法, 以方便测试;
[Delete] Common/pom.xml 移除对 CacheStore-local 和 CacheStore-redis 的依赖;
[Change] CacheStoreBuilderTest 调整单元测试以增加测试覆盖率;
[Add] AvailabilityCheckExceptionThrowFactory, DuplicateNameFactoryA, DuplicateNameFactoryB, GetCacheStoreExceptionFactory, InitialFailureFactory, LocalFactory, MemoryFactory, NoAnnotationFactory, RemoteCacheFactory, ReturnNullFactory, SetCacheStoreFactory 增加测试用工厂;
[Add] META-INF/services/net.lamgc.cgj.bot.cache.CacheStoreFactory 添加 SPI 接口实现注册文件, 并注册测试用相关实现;
This commit is contained in:
LamGC 2020-11-14 11:02:35 +08:00
parent d4c208f2f7
commit 236f15825b
Signed by: LamGC
GPG Key ID: 6C5AE2A913941E1D
16 changed files with 1300 additions and 70 deletions

View File

@ -34,19 +34,6 @@
<artifactId>ContentGrabbingJi-CacheStore-api</artifactId> <artifactId>ContentGrabbingJi-CacheStore-api</artifactId>
<version>3.0.0-alpha-SNAPSHOT</version> <version>3.0.0-alpha-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>net.lamgc</groupId>
<artifactId>ContentGrabbingJi-CacheStore-local</artifactId>
<version>3.0.0-alpha-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.lamgc</groupId>
<artifactId>ContentGrabbingJi-CacheStore-redis</artifactId>
<version>3.0.0-alpha-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -37,15 +37,25 @@ import java.util.function.Function;
* @see CacheStoreFactory * @see CacheStoreFactory
* @author LamGC * @author LamGC
*/ */
public class CacheStoreBuilder { public final class CacheStoreBuilder {
private final static Logger log = LoggerFactory.getLogger(CacheStoreBuilder.class); private final static Logger log = LoggerFactory.getLogger(CacheStoreBuilder.class);
private final List<CacheStoreFactory> FACTORY_LIST = new ArrayList<>(); private volatile List<CacheStoreFactory> factoryList;
private final Map<CacheStoreFactory, FactoryInfo> FACTORY_INFO_MAP = new Hashtable<>(); private final Map<CacheStoreFactory, FactoryInfo> factoryInfoMap = new Hashtable<>();
private final ServiceLoader<CacheStoreFactory> factoryLoader = ServiceLoader.load(CacheStoreFactory.class);
private final File dataDirectory; private final File dataDirectory;
/**
* 获取 CacheStoreBuilder 实例.
* <p> 该方法仅提供给 ContentGrabbingJiBot 调用, 请勿通过该方法私自创建 CacheStoreBuilder.
* @param cacheDataDirectory 缓存组件数据目录的根目录(例如提供 File {@code /data/cache},
* 缓存组件名为 {@code example}, 则缓存组件的缓存路径为 {@code /data/cache/example}).
* @return 返回新的 CacheStoreBuilder 实例, 各实例之间是没有任何关系的(包括创建的 CacheStore, 除非缓存组件设计错误).
* @throws IOException 当路径检查失败时抛出.
*/
public static CacheStoreBuilder getInstance(File cacheDataDirectory) throws IOException { public static CacheStoreBuilder getInstance(File cacheDataDirectory) throws IOException {
Objects.requireNonNull(cacheDataDirectory, "Cache component data directory is null");
if (!cacheDataDirectory.exists() && !cacheDataDirectory.mkdirs()) { if (!cacheDataDirectory.exists() && !cacheDataDirectory.mkdirs()) {
throw new IOException("Data directory creation failed: " + cacheDataDirectory.getAbsolutePath()); throw new IOException("Data directory creation failed: " + cacheDataDirectory.getAbsolutePath());
} else if (!cacheDataDirectory.isDirectory()) { } else if (!cacheDataDirectory.isDirectory()) {
@ -59,6 +69,7 @@ public class CacheStoreBuilder {
private CacheStoreBuilder(File dataDirectory) { private CacheStoreBuilder(File dataDirectory) {
this.dataDirectory = dataDirectory; this.dataDirectory = dataDirectory;
loadFactory();
} }
/** /**
@ -70,20 +81,18 @@ public class CacheStoreBuilder {
* (除非必要, 否则不要使用 执行可能会发生异常的代码.). * (除非必要, 否则不要使用 执行可能会发生异常的代码.).
*/ */
private synchronized void loadFactory() { private synchronized void loadFactory() {
if (FACTORY_LIST.size() != 0) { factoryLoader.reload();
return; List<CacheStoreFactory> newFactoryList = new ArrayList<>();
}
final ServiceLoader<CacheStoreFactory> factoryLoader = ServiceLoader.load(CacheStoreFactory.class);
try { try {
for (CacheStoreFactory factory : factoryLoader) { for (CacheStoreFactory factory : factoryLoader) {
FactoryInfo info; FactoryInfo info;
try { try {
info = new FactoryInfo(factory.getClass()); info = new FactoryInfo(factory.getClass());
if (FACTORY_INFO_MAP.containsValue(info)) { if (factoryInfoMap.containsValue(info)) {
log.warn("发现 Name 重复的 Factory, 已跳过. (被拒绝的实现: {})", factory.getClass().getName()); log.warn("发现 Name 重复的 Factory, 已跳过. (被拒绝的实现: {})", factory.getClass().getName());
continue; continue;
} }
FACTORY_INFO_MAP.put(factory, info); factoryInfoMap.put(factory, info);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
log.warn("Factory {} 加载失败: {}", factory.getClass().getName(), e.getMessage()); log.warn("Factory {} 加载失败: {}", factory.getClass().getName(), e.getMessage());
continue; continue;
@ -94,13 +103,15 @@ public class CacheStoreBuilder {
log.warn("Factory {} 初始化失败.", info.getFactoryName()); log.warn("Factory {} 初始化失败.", info.getFactoryName());
continue; continue;
} }
FACTORY_LIST.add(factory); newFactoryList.add(factory);
log.info("Factory {} 已加载(优先级: {}, 实现类: {}).", log.info("Factory {} 已加载(优先级: {}, 实现类: {}).",
info.getFactoryName(), info.getFactoryName(),
info.getFactoryPriority(), info.getFactoryPriority(),
factory.getClass().getName()); factory.getClass().getName());
} }
FACTORY_LIST.sort(new PriorityComparator()); newFactoryList.sort(new PriorityComparator());
factoryList = newFactoryList;
optimizeFactoryInfoMap();
} catch (Error error) { } catch (Error error) {
// 防止发生 Error 又不输出到日志导致玄学问题难以排查. // 防止发生 Error 又不输出到日志导致玄学问题难以排查.
log.error("加载 CacheStoreFactory 时发生严重错误.", error); log.error("加载 CacheStoreFactory 时发生严重错误.", error);
@ -108,6 +119,19 @@ public class CacheStoreBuilder {
} }
} }
/**
* 清除无效的 {@link FactoryInfo}
*/
private void optimizeFactoryInfoMap() {
factoryInfoMap.keySet().removeIf(factory -> !factoryList.contains(factory));
}
/**
* 初始化 Factory.
* @param factory Factory 对象.
* @param info Factory Info.
* @return 初始化成功则返回 {@code true}, 否则返回 {@code false}.
*/
private boolean initialFactory(CacheStoreFactory factory, FactoryInfo info) { private boolean initialFactory(CacheStoreFactory factory, FactoryInfo info) {
File factoryDataDirectory = new File(dataDirectory, info.getFactoryName()); File factoryDataDirectory = new File(dataDirectory, info.getFactoryName());
if (!factoryDataDirectory.exists() && !factoryDataDirectory.mkdirs()) { if (!factoryDataDirectory.exists() && !factoryDataDirectory.mkdirs()) {
@ -130,8 +154,8 @@ public class CacheStoreBuilder {
private final class PriorityComparator implements Comparator<CacheStoreFactory> { private final class PriorityComparator implements Comparator<CacheStoreFactory> {
@Override @Override
public int compare(CacheStoreFactory o1, CacheStoreFactory o2) { public int compare(CacheStoreFactory o1, CacheStoreFactory o2) {
FactoryInfo info1 = Objects.requireNonNull(FACTORY_INFO_MAP.get(o1)); FactoryInfo info1 = Objects.requireNonNull(factoryInfoMap.get(o1));
FactoryInfo info2 = Objects.requireNonNull(FACTORY_INFO_MAP.get(o2)); FactoryInfo info2 = Objects.requireNonNull(factoryInfoMap.get(o2));
return info2.getFactoryPriority() - info1.getFactoryPriority(); return info2.getFactoryPriority() - info1.getFactoryPriority();
} }
} }
@ -143,13 +167,10 @@ public class CacheStoreBuilder {
private <R extends CacheStore<?>> R getFactory(CacheStoreSource storeSource, private <R extends CacheStore<?>> R getFactory(CacheStoreSource storeSource,
Function<CacheStoreFactory, R> function) Function<CacheStoreFactory, R> function)
throws NoSuchFactoryException { throws NoSuchFactoryException {
if (FACTORY_LIST.size() == 0) { Iterator<CacheStoreFactory> iterator = factoryList.iterator();
loadFactory();
}
Iterator<CacheStoreFactory> iterator = FACTORY_LIST.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
CacheStoreFactory factory = iterator.next(); CacheStoreFactory factory = iterator.next();
FactoryInfo info = FACTORY_INFO_MAP.get(factory); FactoryInfo info = factoryInfoMap.get(factory);
if (storeSource != null && info.getStoreSource() != storeSource) { if (storeSource != null && info.getStoreSource() != storeSource) {
continue; continue;
} }
@ -191,6 +212,21 @@ public class CacheStoreBuilder {
throw new NoSuchFactoryException(); throw new NoSuchFactoryException();
} }
/**
* 检查是否为 {@code null}.
* @param cacheStore 缓存库.
* @param factory 工厂对象.
* @param <V> 缓存库类型.
* @return 如果不为 null, 则正常返回.
* @throws GetCacheStoreException cacheStore {@code null} 时抛出.
*/
private <V extends CacheStore<?>> V returnRequireNonNull(V cacheStore, CacheStoreFactory factory) {
if (cacheStore == null) {
throw new GetCacheStoreException("Factory '" + factory.getClass().getName() + "' returned null");
}
return cacheStore;
}
/** /**
* 获取单项缓存存储容器. * 获取单项缓存存储容器.
* @param identify 缓存容器标识. * @param identify 缓存容器标识.
@ -215,13 +251,8 @@ public class CacheStoreBuilder {
public <V> SingleCacheStore<V> newSingleCacheStore(CacheStoreSource storeSource, String identify, public <V> SingleCacheStore<V> newSingleCacheStore(CacheStoreSource storeSource, String identify,
StringConverter<V> converter) { StringConverter<V> converter) {
try { try {
return getFactory(storeSource, factory -> { return getFactory(storeSource, factory ->
SingleCacheStore<V> singleCacheStoreInstance = factory.newSingleCacheStore(identify, converter); returnRequireNonNull(factory.newSingleCacheStore(identify, converter), factory));
if (singleCacheStoreInstance == null) {
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
}
return singleCacheStoreInstance;
});
} catch (NoSuchFactoryException e) { } catch (NoSuchFactoryException e) {
throw new GetCacheStoreException("无可用的 Factory.", e); throw new GetCacheStoreException("无可用的 Factory.", e);
} }
@ -251,13 +282,8 @@ public class CacheStoreBuilder {
public <E> ListCacheStore<E> newListCacheStore(CacheStoreSource storeSource, String identify, public <E> ListCacheStore<E> newListCacheStore(CacheStoreSource storeSource, String identify,
StringConverter<E> converter) { StringConverter<E> converter) {
try { try {
return getFactory(storeSource, factory -> { return getFactory(storeSource, factory ->
ListCacheStore<E> listCacheStoreInstance = factory.newListCacheStore(identify, converter); returnRequireNonNull(factory.newListCacheStore(identify, converter), factory));
if (listCacheStoreInstance == null) {
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
}
return listCacheStoreInstance;
});
} catch (NoSuchFactoryException e) { } catch (NoSuchFactoryException e) {
throw new GetCacheStoreException("无可用的 Factory.", e); throw new GetCacheStoreException("无可用的 Factory.", e);
} }
@ -286,13 +312,8 @@ public class CacheStoreBuilder {
public <E> SetCacheStore<E> newSetCacheStore(CacheStoreSource storeSource, String identify, public <E> SetCacheStore<E> newSetCacheStore(CacheStoreSource storeSource, String identify,
StringConverter<E> converter) { StringConverter<E> converter) {
try { try {
return getFactory(storeSource, factory -> { return getFactory(storeSource, factory ->
SetCacheStore<E> setCacheStoreInstance = factory.newSetCacheStore(identify, converter); returnRequireNonNull(factory.newSetCacheStore(identify, converter), factory));
if (setCacheStoreInstance == null) {
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
}
return setCacheStoreInstance;
});
} catch (NoSuchFactoryException e) { } catch (NoSuchFactoryException e) {
throw new GetCacheStoreException("无可用的 Factory.", e); throw new GetCacheStoreException("无可用的 Factory.", e);
} }
@ -322,13 +343,8 @@ public class CacheStoreBuilder {
public <V> MapCacheStore<V> newMapCacheStore(CacheStoreSource storeSource, String identify, public <V> MapCacheStore<V> newMapCacheStore(CacheStoreSource storeSource, String identify,
StringConverter<V> converter) { StringConverter<V> converter) {
try { try {
return getFactory(storeSource, factory -> { return getFactory(storeSource, factory ->
MapCacheStore<V> mapCacheStoreInstance = factory.newMapCacheStore(identify, converter); returnRequireNonNull(factory.newMapCacheStore(identify, converter), factory));
if (mapCacheStoreInstance == null) {
throw new GetCacheStoreException("Factory " + factory.getClass().getName() + " 返回 null.");
}
return mapCacheStoreInstance;
});
} catch (NoSuchFactoryException e) { } catch (NoSuchFactoryException e) {
throw new GetCacheStoreException("无可用的 Factory.", e); throw new GetCacheStoreException("无可用的 Factory.", e);
} }

View File

@ -25,7 +25,7 @@ import java.util.Objects;
* CacheStoreFactory 的标识信息. * CacheStoreFactory 的标识信息.
* @author LamGC * @author LamGC
*/ */
public class FactoryInfo { public final class FactoryInfo {
private final String factoryName; private final String factoryName;
private final int factoryPriority; private final int factoryPriority;

View File

@ -20,17 +20,24 @@ package net.lamgc.cgj.bot.cache;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import net.lamgc.cgj.bot.cache.convert.StringConverter; import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.convert.StringToStringConverter; import net.lamgc.cgj.bot.cache.convert.StringToStringConverter;
import net.lamgc.cgj.bot.cache.local.CopyOnWriteArrayListCacheStore; import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import net.lamgc.cgj.bot.cache.local.HashSetCacheStore; import net.lamgc.cgj.bot.cache.factory.*;
import net.lamgc.cgj.bot.cache.redis.RedisMapCacheStore;
import net.lamgc.cgj.bot.cache.redis.RedisSingleCacheStore;
import org.junit.Assert; import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
/** /**
* @see CacheStoreBuilder * @see CacheStoreBuilder
@ -38,6 +45,7 @@ import java.io.IOException;
public class CacheStoreBuilderTest { public class CacheStoreBuilderTest {
private final static TemporaryFolder tempDirectory = TemporaryFolder.builder().build(); private final static TemporaryFolder tempDirectory = TemporaryFolder.builder().build();
private final static Logger log = LoggerFactory.getLogger(CacheStoreBuilderTest.class);
@BeforeClass @BeforeClass
public static void beforeAction() { public static void beforeAction() {
@ -62,20 +70,266 @@ public class CacheStoreBuilderTest {
SingleCacheStore<String> singleCacheStore = cacheStoreBuilder.newSingleCacheStore(CacheStoreSource.REMOTE, identify, converter); SingleCacheStore<String> singleCacheStore = cacheStoreBuilder.newSingleCacheStore(CacheStoreSource.REMOTE, identify, converter);
Assert.assertNotNull(singleCacheStore); Assert.assertNotNull(singleCacheStore);
Assert.assertEquals(RedisSingleCacheStore.class, singleCacheStore.getClass()); Assert.assertEquals(RemoteCacheFactory.RemoteSingleCacheFactory.class, singleCacheStore.getClass());
ListCacheStore<String> listCacheStore = cacheStoreBuilder.newListCacheStore(CacheStoreSource.MEMORY, identify, converter); ListCacheStore<String> listCacheStore = cacheStoreBuilder.newListCacheStore(CacheStoreSource.MEMORY, identify, converter);
Assert.assertNotNull(listCacheStore); Assert.assertNotNull(listCacheStore);
Assert.assertEquals(CopyOnWriteArrayListCacheStore.class, listCacheStore.getClass()); Assert.assertEquals(MemoryFactory.MemoryListCacheStore.class, listCacheStore.getClass());
MapCacheStore<String> mapCacheStore = cacheStoreBuilder.newMapCacheStore(CacheStoreSource.REMOTE, identify, converter); MapCacheStore<String> mapCacheStore = cacheStoreBuilder.newMapCacheStore(CacheStoreSource.LOCAL, identify, converter);
Assert.assertNotNull(mapCacheStore); Assert.assertNotNull(mapCacheStore);
Assert.assertEquals(RedisMapCacheStore.class, mapCacheStore.getClass()); Assert.assertEquals(LocalFactory.LocalMapCacheStore.class, mapCacheStore.getClass());
SetCacheStore<String> setCacheStore = cacheStoreBuilder.newSetCacheStore(identify, converter); SetCacheStore<String> setCacheStore = cacheStoreBuilder.newSetCacheStore(identify, converter);
Assert.assertNotNull(setCacheStore); Assert.assertNotNull(setCacheStore);
Assert.assertEquals(HashSetCacheStore.class, setCacheStore.getClass()); Assert.assertEquals(SetCacheStoreFactory.OnlySetCacheStore.class, setCacheStore.getClass());
}
@Test
public void loadFailureTest() throws IllegalAccessException, NoSuchFieldException {
CacheStoreBuilder cacheStoreBuilder;
try {
cacheStoreBuilder = CacheStoreBuilder.getInstance(tempDirectory.getRoot());
} catch (IOException e) {
Assert.fail(Throwables.getStackTraceAsString(e));
return;
}
Field factoryListField;
factoryListField = CacheStoreBuilder.class.getDeclaredField("factoryList");
factoryListField.setAccessible(true);
Object o = factoryListField.get(cacheStoreBuilder);
Assert.assertTrue(o instanceof List);
@SuppressWarnings("unchecked")
List<CacheStoreFactory> factoryList = (List<CacheStoreFactory>) o;
Set<Class<? extends CacheStoreFactory>> classSet = new HashSet<>();
factoryList.forEach(factory -> classSet.add(factory.getClass()));
// 重名检查
if (classSet.contains(DuplicateNameFactoryA.class) && classSet.contains(DuplicateNameFactoryB.class)) {
Assert.fail("There are different factories with the same name");
return;
}
if (classSet.contains(NoAnnotationFactory.class)) {
Assert.fail("Factory without @Factory added is loaded");
return;
}
if (classSet.contains(InitialFailureFactory.class)) {
Assert.fail("The factory that failed to initialize was loaded");
}
}
@Test
public void multiThreadReloadTest() throws IOException, NoSuchMethodException, InterruptedException {
final String identify = "test";
final StringConverter<String> converter = new StringToStringConverter();
final CacheStoreBuilder cacheStoreBuilder = CacheStoreBuilder.getInstance(tempDirectory.getRoot());
final Method loadFactoryMethod = CacheStoreBuilder.class.getDeclaredMethod("loadFactory");
loadFactoryMethod.setAccessible(true);
Thread accessThread = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
SingleCacheStore<String> singleCacheStore = cacheStoreBuilder.newSingleCacheStore(CacheStoreSource.REMOTE, identify, converter);
Assert.assertNotNull(singleCacheStore);
Assert.assertEquals(RemoteCacheFactory.RemoteSingleCacheFactory.class, singleCacheStore.getClass());
ListCacheStore<String> listCacheStore = cacheStoreBuilder.newListCacheStore(CacheStoreSource.MEMORY, identify, converter);
Assert.assertNotNull(listCacheStore);
Assert.assertEquals(MemoryFactory.MemoryListCacheStore.class, listCacheStore.getClass());
MapCacheStore<String> mapCacheStore = cacheStoreBuilder.newMapCacheStore(CacheStoreSource.LOCAL, identify, converter);
Assert.assertNotNull(mapCacheStore);
Assert.assertEquals(LocalFactory.LocalMapCacheStore.class, mapCacheStore.getClass());
SetCacheStore<String> setCacheStore = cacheStoreBuilder.newSetCacheStore(identify, converter);
Assert.assertNotNull(setCacheStore);
Assert.assertEquals(SetCacheStoreFactory.OnlySetCacheStore.class, setCacheStore.getClass());
}
}, "Thread-AccessBuilder");
Thread reloadThread = new Thread(() -> {
int count = 0;
final Random random = new Random();
while(count++ < 100000) {
if (random.nextInt() % 2 == 0) {
try {
loadFactoryMethod.invoke(cacheStoreBuilder);
} catch (IllegalAccessException | InvocationTargetException e) {
log.error("重载 Builder 时发生异常.",
e instanceof InvocationTargetException ?
((InvocationTargetException) e).getTargetException() :
e);
}
}
}
}, "Thread-ReloadBuilder");
accessThread.start();
reloadThread.start();
accessThread.join();
reloadThread.join();
}
@Test
public void noSpecifiedGetCacheStoreTest() {
final String identify = "test";
final StringConverter<String> converter = new StringToStringConverter();
CacheStoreBuilder cacheStoreBuilder;
try {
cacheStoreBuilder = CacheStoreBuilder.getInstance(tempDirectory.getRoot());
} catch (IOException e) {
Assert.fail(Throwables.getStackTraceAsString(e));
return;
}
SingleCacheStore<String> singleCacheStore = cacheStoreBuilder.newSingleCacheStore(identify, converter);
Assert.assertNotNull(singleCacheStore);
ListCacheStore<String> listCacheStore = cacheStoreBuilder.newListCacheStore(identify, converter);
Assert.assertNotNull(listCacheStore);
MapCacheStore<String> mapCacheStore = cacheStoreBuilder.newMapCacheStore(identify, converter);
Assert.assertNotNull(mapCacheStore);
SetCacheStore<String> setCacheStore = cacheStoreBuilder.newSetCacheStore(identify, converter);
Assert.assertNotNull(setCacheStore);
}
@Test
public void noSuchFactoryExceptionThrowTest() throws NoSuchFieldException, IllegalAccessException {
final String identify = "test";
final StringConverter<String> converter = new StringToStringConverter();
CacheStoreBuilder cacheStoreBuilder;
try {
cacheStoreBuilder = CacheStoreBuilder.getInstance(tempDirectory.getRoot());
} catch (IOException e) {
Assert.fail(Throwables.getStackTraceAsString(e));
return;
}
Field factoryListField;
factoryListField = CacheStoreBuilder.class.getDeclaredField("factoryList");
factoryListField.setAccessible(true);
Object o = factoryListField.get(cacheStoreBuilder);
Assert.assertTrue(o instanceof List);
@SuppressWarnings("unchecked")
List<CacheStoreFactory> factoryList = (List<CacheStoreFactory>) o;
factoryList.clear();
try {
cacheStoreBuilder.newSingleCacheStore(identify, converter);
} catch (GetCacheStoreException e) {
if (!(e.getCause() instanceof NoSuchFactoryException)) {
Assert.fail("The exception is not due to NoSuchFactoryException");
}
}
try {
cacheStoreBuilder.newMapCacheStore(identify, converter);
} catch (GetCacheStoreException e) {
if (!(e.getCause() instanceof NoSuchFactoryException)) {
Assert.fail("The exception is not due to NoSuchFactoryException");
}
}
try {
cacheStoreBuilder.newListCacheStore(identify, converter);
} catch (GetCacheStoreException e) {
if (!(e.getCause() instanceof NoSuchFactoryException)) {
Assert.fail("The exception is not due to NoSuchFactoryException");
}
}
try {
cacheStoreBuilder.newSetCacheStore(identify, converter);
} catch (GetCacheStoreException e) {
if (!(e.getCause() instanceof NoSuchFactoryException)) {
Assert.fail("The exception is not due to NoSuchFactoryException");
}
}
}
@Test
public void getInstanceFailureTest() throws IOException {
Assert.assertThrows(IOException.class, () ->
CacheStoreBuilder.getInstance(tempDirectory.newFile("invalid file.bin")));
File onlyReadableDirectory = tempDirectory.newFile("onlyReadable");
// Assert.assertTrue(onlyReadableDirectory.setWritable(false));
Assert.assertThrows(IOException.class, () ->
CacheStoreBuilder.getInstance(new File(onlyReadableDirectory, "cache")));
Assert.assertNotNull(
CacheStoreBuilder.getInstance(new File(tempDirectory.newFolder("valid directory"), "cache")));
}
@Test
public void lastFactoryThrowExceptionTest() throws NoSuchFieldException, IllegalAccessException {
final String identify = "test";
final StringConverter<String> converter = new StringToStringConverter();
CacheStoreBuilder cacheStoreBuilder;
try {
cacheStoreBuilder = CacheStoreBuilder.getInstance(tempDirectory.getRoot());
} catch (IOException e) {
Assert.fail(Throwables.getStackTraceAsString(e));
return;
}
Field factoryListField;
factoryListField = CacheStoreBuilder.class.getDeclaredField("factoryList");
factoryListField.setAccessible(true);
Object o = factoryListField.get(cacheStoreBuilder);
Assert.assertTrue(o instanceof List);
@SuppressWarnings("unchecked")
List<CacheStoreFactory> factoryList = (List<CacheStoreFactory>) o;
factoryList.removeIf(factory -> !(factory instanceof GetCacheStoreExceptionFactory));
try {
cacheStoreBuilder.newSingleCacheStore(identify, converter);
} catch (GetCacheStoreException e) {
if (!(e.getCause() instanceof NoSuchFactoryException)) {
Assert.fail("The exception is not due to NoSuchFactoryException");
}
}
try {
cacheStoreBuilder.newMapCacheStore(identify, converter);
} catch (GetCacheStoreException e) {
if (!(e.getCause() instanceof NoSuchFactoryException)) {
Assert.fail("The exception is not due to NoSuchFactoryException");
}
}
try {
cacheStoreBuilder.newListCacheStore(identify, converter);
} catch (GetCacheStoreException e) {
if (!(e.getCause() instanceof NoSuchFactoryException)) {
Assert.fail("The exception is not due to NoSuchFactoryException");
}
}
try {
cacheStoreBuilder.newSetCacheStore(identify, converter);
} catch (GetCacheStoreException e) {
if (!(e.getCause() instanceof NoSuchFactoryException)) {
Assert.fail("The exception is not due to NoSuchFactoryException");
}
}
} }
} }

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import java.io.File;
@Factory(name = "test-throwException")
public class AvailabilityCheckExceptionThrowFactory implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public boolean canGetCacheStore() {
throw new IllegalStateException();
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import java.io.File;
@Factory(name = "duplicate")
public class DuplicateNameFactoryA implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public boolean canGetCacheStore() {
return false;
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import java.io.File;
@Factory(name = "duplicate", priority = FactoryPriority.PRIORITY_HIGHEST)
public class DuplicateNameFactoryB implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public boolean canGetCacheStore() {
return false;
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import java.io.File;
@Factory(name = "test-getCacheStoreException", priority = FactoryPriority.PRIORITY_HIGHEST)
public class GetCacheStoreExceptionFactory implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
throw new IllegalStateException();
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
throw new IllegalStateException();
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
throw new IllegalStateException();
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
throw new IllegalStateException();
}
@Override
public boolean canGetCacheStore() {
return true;
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import java.io.File;
@Factory(name = "initialFailure")
public class InitialFailureFactory implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
throw new IllegalStateException();
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public boolean canGetCacheStore() {
return false;
}
}

View File

@ -0,0 +1,153 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import org.junit.Assert;
import java.io.File;
import java.util.Map;
import java.util.Set;
@Factory(name = "test-local", source = CacheStoreSource.LOCAL)
public class LocalFactory implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
Assert.assertNotNull(dataDirectory);
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return new LocalMapCacheStore<>();
}
@Override
public boolean canGetCacheStore() {
return true;
}
public static class LocalMapCacheStore<V> implements MapCacheStore<V> {
@Override
public int mapSize(CacheKey key) {
return 0;
}
@Override
public Set<String> mapFieldSet(CacheKey key) {
return null;
}
@Override
public Set<V> mapValueSet(CacheKey key) {
return null;
}
@Override
public boolean put(CacheKey key, String field, V value) {
return false;
}
@Override
public boolean putAll(CacheKey key, Map<String, V> map) {
return false;
}
@Override
public boolean putIfNotExist(CacheKey key, String field, V value) {
return false;
}
@Override
public V get(CacheKey key, String field) {
return null;
}
@Override
public boolean removeField(CacheKey key, String field) {
return false;
}
@Override
public boolean containsField(CacheKey key, String field) {
return false;
}
@Override
public boolean mapIsEmpty(CacheKey key) {
return false;
}
@Override
public boolean clearMap(CacheKey key) {
return false;
}
@Override
public boolean setTimeToLive(CacheKey key, long ttl) {
return false;
}
@Override
public long getTimeToLive(CacheKey key) {
return 0;
}
@Override
public long size() {
return 0;
}
@Override
public boolean clear() {
return false;
}
@Override
public boolean exists(CacheKey key) {
return false;
}
@Override
public boolean remove(CacheKey key) {
return false;
}
@Override
public Set<String> keySet() {
return null;
}
}
}

View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import org.junit.Assert;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@Factory(name = "test-memory", source = CacheStoreSource.MEMORY)
public class MemoryFactory implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
Assert.assertNotNull(dataDirectory);
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return new MemoryListCacheStore<>();
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public boolean canGetCacheStore() {
return true;
}
public static class MemoryListCacheStore<E> implements ListCacheStore<E> {
@Override
public E getElement(CacheKey key, int index) {
return null;
}
@Override
public List<E> getElementsByRange(CacheKey key, int index, int length) {
return null;
}
@Override
public boolean removeElement(CacheKey key, int index) {
return false;
}
@Override
public boolean addElement(CacheKey key, E element) {
return false;
}
@Override
public boolean addElements(CacheKey key, Collection<E> elements) {
return false;
}
@Override
public boolean containsElement(CacheKey key, E element) {
return false;
}
@Override
public boolean isEmpty(CacheKey key) {
return false;
}
@Override
public int elementsLength(CacheKey key) {
return 0;
}
@Override
public boolean clearCollection(CacheKey key) {
return false;
}
@Override
public boolean removeElement(CacheKey key, E element) {
return false;
}
@Override
public boolean setTimeToLive(CacheKey key, long ttl) {
return false;
}
@Override
public long getTimeToLive(CacheKey key) {
return 0;
}
@Override
public long size() {
return 0;
}
@Override
public boolean clear() {
return false;
}
@Override
public boolean exists(CacheKey key) {
return false;
}
@Override
public boolean remove(CacheKey key) {
return false;
}
@Override
public Set<String> keySet() {
return null;
}
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import java.io.File;
public class NoAnnotationFactory implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public boolean canGetCacheStore() {
return true;
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import org.junit.Assert;
import java.io.File;
import java.util.Set;
@Factory(name = "test-remote", source = CacheStoreSource.REMOTE)
public class RemoteCacheFactory implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
Assert.assertNotNull(dataDirectory);
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return new RemoteSingleCacheFactory<>();
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public boolean canGetCacheStore() {
return true;
}
public static class RemoteSingleCacheFactory<V> implements SingleCacheStore<V> {
@Override
public boolean set(CacheKey key, V value) {
return false;
}
@Override
public boolean setIfNotExist(CacheKey key, V value) {
return false;
}
@Override
public V get(CacheKey key) {
return null;
}
@Override
public boolean setTimeToLive(CacheKey key, long ttl) {
return false;
}
@Override
public long getTimeToLive(CacheKey key) {
return 0;
}
@Override
public long size() {
return 0;
}
@Override
public boolean clear() {
return false;
}
@Override
public boolean exists(CacheKey key) {
return false;
}
@Override
public boolean remove(CacheKey key) {
return false;
}
@Override
public Set<String> keySet() {
return null;
}
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import java.io.File;
@Factory(name = "test-returnNull", priority = FactoryPriority.PRIORITY_HIGHEST)
public class ReturnNullFactory implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public boolean canGetCacheStore() {
return true;
}
}

View File

@ -0,0 +1,131 @@
/*
* Copyright (C) 2020 LamGC
*
* ContentGrabbingJi is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* ContentGrabbingJi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package net.lamgc.cgj.bot.cache.factory;
import net.lamgc.cgj.bot.cache.*;
import net.lamgc.cgj.bot.cache.convert.StringConverter;
import net.lamgc.cgj.bot.cache.exception.GetCacheStoreException;
import java.io.File;
import java.util.Collection;
import java.util.Set;
@Factory(name = "test-onlySet")
public class SetCacheStoreFactory implements CacheStoreFactory {
@Override
public void initial(File dataDirectory) {
}
@Override
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return null;
}
@Override
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) throws GetCacheStoreException {
return new OnlySetCacheStore<>();
}
@Override
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) throws GetCacheStoreException {
return null;
}
@Override
public boolean canGetCacheStore() {
return true;
}
public static class OnlySetCacheStore<E> implements SetCacheStore<E> {
@Override
public boolean addElement(CacheKey key, E element) {
return false;
}
@Override
public boolean addElements(CacheKey key, Collection<E> elements) {
return false;
}
@Override
public boolean containsElement(CacheKey key, E element) {
return false;
}
@Override
public boolean isEmpty(CacheKey key) {
return false;
}
@Override
public int elementsLength(CacheKey key) {
return 0;
}
@Override
public boolean clearCollection(CacheKey key) {
return false;
}
@Override
public boolean removeElement(CacheKey key, E element) {
return false;
}
@Override
public boolean setTimeToLive(CacheKey key, long ttl) {
return false;
}
@Override
public long getTimeToLive(CacheKey key) {
return 0;
}
@Override
public long size() {
return 0;
}
@Override
public boolean clear() {
return false;
}
@Override
public boolean exists(CacheKey key) {
return false;
}
@Override
public boolean remove(CacheKey key) {
return false;
}
@Override
public Set<String> keySet() {
return null;
}
}
}

View File

@ -0,0 +1,29 @@
# Copyright (C) 2020 LamGC
#
# ContentGrabbingJi is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# ContentGrabbingJi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
net.lamgc.cgj.bot.cache.factory.DuplicateNameFactoryA
net.lamgc.cgj.bot.cache.factory.DuplicateNameFactoryB
net.lamgc.cgj.bot.cache.factory.NoAnnotationFactory
net.lamgc.cgj.bot.cache.factory.InitialFailureFactory
net.lamgc.cgj.bot.cache.factory.AvailabilityCheckExceptionThrowFactory
net.lamgc.cgj.bot.cache.factory.GetCacheStoreExceptionFactory
net.lamgc.cgj.bot.cache.factory.LocalFactory
net.lamgc.cgj.bot.cache.factory.MemoryFactory
net.lamgc.cgj.bot.cache.factory.RemoteCacheFactory
net.lamgc.cgj.bot.cache.factory.SetCacheStoreFactory