StoreServiceProvider.java 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package org.ssssssss.magicapi.provider;
  2. import org.ssssssss.magicapi.adapter.Resource;
  3. import org.ssssssss.magicapi.model.MagicEntity;
  4. import org.ssssssss.magicapi.utils.JsonUtils;
  5. import java.nio.charset.StandardCharsets;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.UUID;
  10. import java.util.stream.Collectors;
  11. public abstract class StoreServiceProvider<T extends MagicEntity> {
  12. String separator = "\r\n================================\r\n";
  13. protected Resource workspace;
  14. protected Resource backupResource;
  15. protected Map<String, Resource> mappings = new HashMap<>();
  16. protected Map<String, T> infos = new HashMap<>();
  17. protected GroupServiceProvider groupServiceProvider;
  18. protected Class<T> clazz;
  19. public StoreServiceProvider(Class<T> clazz, Resource workspace, GroupServiceProvider groupServiceProvider) {
  20. this.clazz = clazz;
  21. this.workspace = workspace;
  22. this.groupServiceProvider = groupServiceProvider;
  23. this.backupResource = this.workspace.parent().getResource("backups");
  24. }
  25. /**
  26. * 添加
  27. */
  28. public boolean insert(T info) {
  29. info.setId(UUID.randomUUID().toString().replace("-", ""));
  30. info.setUpdateTime(System.currentTimeMillis());
  31. info.setCreateTime(info.getUpdateTime());
  32. Resource dest = groupServiceProvider.getGroupResource(info.getGroupId()).getResource(info.getName() + ".ms");
  33. if (!dest.exists() && dest.write(serialize(info))) {
  34. mappings.put(info.getId(), dest);
  35. infos.put(info.getId(), info);
  36. return true;
  37. }
  38. return false;
  39. }
  40. /**
  41. * 备份历史记录
  42. */
  43. public boolean backup(T info) {
  44. Resource directory = this.backupResource.getResource(info.getId());
  45. if(!directory.readonly() && (directory.exists() || directory.mkdir())){
  46. Resource resource = directory.getResource(String.format("%s.ms", System.currentTimeMillis()));
  47. return resource.write(serialize(info));
  48. }
  49. return false;
  50. }
  51. /**
  52. * 查询历史记录
  53. *
  54. * @return 时间戳列表
  55. */
  56. public List<Long> backupList(String id) {
  57. Resource directory = this.backupResource.getResource(id);
  58. List<Resource> resources = directory.files(".ms");
  59. return resources.stream().map(it -> Long.valueOf(it.name().replace(".ms",""))).collect(Collectors.toList());
  60. }
  61. /**
  62. * 查询历史记录详情
  63. *
  64. * @param id ID
  65. * @param timestamp 时间戳
  66. */
  67. public T backupInfo(String id, Long timestamp) {
  68. Resource directory = this.backupResource.getResource(id);
  69. if(directory.exists()){
  70. Resource resource = directory.getResource(String.format("%s.ms", timestamp));
  71. if(resource.exists()){
  72. return deserialize(resource.read());
  73. }
  74. }
  75. return null;
  76. }
  77. /**
  78. * 修改
  79. */
  80. public boolean update(T info) {
  81. Resource dest = groupServiceProvider.getGroupResource(info.getGroupId()).getResource(info.getName() + ".ms");
  82. Resource src = mappings.get(info.getId());
  83. if (!src.name().equals(dest.name())) {
  84. if (dest.exists()) {
  85. return false;
  86. }
  87. src.renameTo(dest);
  88. }
  89. if (dest.write(serialize(info))) {
  90. mappings.put(info.getId(), dest);
  91. infos.put(info.getId(), info);
  92. return true;
  93. }
  94. return false;
  95. }
  96. /**
  97. * 删除
  98. */
  99. public boolean delete(String id) {
  100. Resource resource = mappings.get(id);
  101. if (resource != null && resource.delete()) {
  102. mappings.remove(id);
  103. infos.remove(id);
  104. return true;
  105. }
  106. return false;
  107. }
  108. /**
  109. * 查询所有(提供给页面,无需带script)
  110. */
  111. public List<T> list() {
  112. List<T> infos = listWithScript();
  113. infos.forEach(info -> info.setScript(null));
  114. return infos;
  115. }
  116. /**
  117. * 查询所有(内部使用,需要带Script)
  118. */
  119. public List<T> listWithScript() {
  120. List<Resource> resources = workspace.files(".ms");
  121. Map<String, Resource> mappings = new HashMap<>();
  122. Map<String, T> infos = new HashMap<>();
  123. List<T> result = resources.stream().map(r -> {
  124. T info = deserialize(r.read());
  125. infos.put(info.getId(), info);
  126. mappings.put(info.getId(), r);
  127. return (T) info.clone();
  128. }).collect(Collectors.toList());
  129. this.mappings = mappings;
  130. this.infos = infos;
  131. return result;
  132. }
  133. /**
  134. * 查询详情(主要给页面使用)
  135. *
  136. * @param id ID
  137. */
  138. public T get(String id) {
  139. return infos.get(id);
  140. }
  141. /**
  142. * 判断是否允许移动
  143. */
  144. public boolean allowMove(String id, String groupId) {
  145. Resource resource = mappings.get(id);
  146. if (resource == null) {
  147. return false;
  148. }
  149. return !resource.readonly() && !groupServiceProvider.getGroupResource(groupId).getResource(resource.name()).exists();
  150. }
  151. /**
  152. * 移动
  153. *
  154. * @param id 接口ID
  155. * @param groupId 分组ID
  156. */
  157. public boolean move(String id, String groupId) {
  158. Resource dest = groupServiceProvider.getGroupResource(groupId);
  159. Resource src = mappings.get(id);
  160. dest = dest.getResource(src.name());
  161. if (dest.exists()) {
  162. return false;
  163. }
  164. T info = infos.get(id);
  165. src.renameTo(dest);
  166. info.setGroupId(groupId);
  167. mappings.put(id, dest);
  168. return dest.write(serialize(info));
  169. }
  170. /**
  171. * 根据组ID删除
  172. */
  173. public boolean deleteGroup(List<String> groupIds) {
  174. for (String groupId : groupIds) {
  175. if (!groupServiceProvider.getGroupResource(groupId).delete()) {
  176. return false;
  177. }
  178. List<String> infoIds = infos.values().stream().filter(info -> groupId.equals(info.getGroupId()))
  179. .map(T::getId)
  180. .collect(Collectors.toList());
  181. infoIds.forEach(infos::remove);
  182. infoIds.forEach(mappings::remove);
  183. }
  184. return true;
  185. }
  186. /**
  187. * 包装信息(可用于加密)
  188. */
  189. public void wrap(T info) {
  190. }
  191. /**
  192. * 解除包装信息(可用于解密)
  193. */
  194. public void unwrap(T info) {
  195. }
  196. public byte[] serialize(T info) {
  197. wrap(info);
  198. String script = info.getScript();
  199. info.setScript(null);
  200. String content = JsonUtils.toJsonString(info) + separator + script;
  201. info.setScript(script);
  202. unwrap(info);
  203. return content.getBytes();
  204. }
  205. public T deserialize(byte[] data) {
  206. String content = new String(data, StandardCharsets.UTF_8);
  207. int index = content.indexOf(separator);
  208. if (index > -1) {
  209. T info = JsonUtils.readValue(content.substring(0, index), clazz);
  210. info.setScript(content.substring(index + separator.length()));
  211. unwrap(info);
  212. return info;
  213. }
  214. return null;
  215. }
  216. }