1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 module hunt.shiro.cache.AbstractCacheManager; 20 21 import hunt.shiro.cache.Cache; 22 import hunt.shiro.cache.CacheManager; 23 24 import hunt.shiro.util.Common; 25 import hunt.shiro.util.LifecycleUtils; 26 // import hunt.shiro.util.StringUtils; 27 28 import hunt.Exceptions; 29 import hunt.util.StringBuilder; 30 31 import std.array; 32 33 // import java.util.Collection; 34 // import java.util.concurrent.ConcurrentHashMap; 35 // import java.util.concurrent.ConcurrentMap; 36 37 /** 38 * Very simple abstract {@code CacheManager} implementation that retains all created {@link Cache Cache} instances in 39 * an in-memory {@link ConcurrentMap ConcurrentMap}. {@code Cache} instance creation is left to subclasses via 40 * the {@link #createCache createCache} method implementation. 41 * 42 * @since 1.0 43 */ 44 abstract class AbstractCacheManager(K, V) : CacheManager, Destroyable { 45 46 /** 47 * Retains all Cache objects maintained by this cache manager. 48 */ 49 private Cache!(K, V)[string] caches; 50 51 /** 52 * Default no-arg constructor that instantiates an internal name-to-cache {@code ConcurrentMap}. 53 */ 54 this() { 55 // this.caches = new ConcurrentHashMap<string, Cache>(); 56 } 57 58 /** 59 * Returns the cache with the specified {@code name}. If the cache instance does not yet exist, it will be lazily 60 * created, retained for further access, and then returned. 61 * 62 * @param name the name of the cache to acquire. 63 * @return the cache with the specified {@code name}. 64 * @throws IllegalArgumentException if the {@code name} argument is {@code null} or does not contain text. 65 * @throws CacheException if there is a problem lazily creating a {@code Cache} instance. 66 */ 67 Cache!(K, V) getCache(string name) { 68 if (name.empty()) { 69 throw new IllegalArgumentException("Cache name cannot be null or empty."); 70 } 71 Cache!(K, V) cache = caches.get(name, null); 72 if (cache is null) { 73 cache = createCache(name); 74 caches[name] = cache; 75 } 76 77 //noinspection unchecked 78 return cache; 79 } 80 81 /** 82 * Creates a new {@code Cache} instance associated with the specified {@code name}. 83 * 84 * @param name the name of the cache to create 85 * @return a new {@code Cache} instance associated with the specified {@code name}. 86 * @throws CacheException if the {@code Cache} instance cannot be created. 87 */ 88 protected abstract Cache!(K, V) createCache(string name); 89 90 /** 91 * Cleanup method that first {@link LifecycleUtils#destroy destroys} all of it's managed caches and then 92 * {@link java.util.Map#clear clears} out the internally referenced cache map. 93 * 94 * @throws Exception if any of the managed caches can't destroy properly. 95 */ 96 void destroy() { 97 while (caches !is null) { 98 foreach (Cache!(K, V) cache; caches.byValue) { 99 LifecycleUtils.destroy(cast(Object)cache); 100 } 101 caches.clear(); 102 } 103 } 104 105 override string toString() { 106 107 StringBuilder sb = new StringBuilder(typeof(this).stringof) 108 .append(" with ") 109 .append(caches.length) 110 .append(" cache(s)): ["); 111 int i = 0; 112 foreach (Cache!(K, V) cache ; caches.byValue) { 113 if (i > 0) { 114 sb.append(", "); 115 } 116 sb.append((cast(Object)cache).toString()); 117 i++; 118 } 119 sb.append("]"); 120 return sb.toString(); 121 } 122 }