1 /** 2 License: 3 Boost Software License - Version 1.0 - August 17th, 2003 4 5 Permission is hereby granted, free of charge, to any person or organization 6 obtaining a copy of the software and accompanying documentation covered by 7 this license (the "Software") to use, reproduce, display, distribute, 8 execute, and transmit the Software, and to prepare derivative works of the 9 Software, and to permit third-parties to whom the Software is furnished to 10 do so, all subject to the following: 11 12 The copyright notices in the Software and this entire statement, including 13 the above license grant, this restriction and the following disclaimer, 14 must be included in all copies of the Software, in whole or in part, and 15 all derivative works of the Software, unless such copies or derivative 16 works are solely in the form of machine-executable object code generated by 17 a source language processor. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 DEALINGS IN THE SOFTWARE. 26 27 Authors: 28 aermicioi 29 **/ 30 module aermicioi.aedi.container.tuple_container; 31 32 import aermicioi.aedi.container.container; 33 import aermicioi.aedi.storage.storage; 34 import aermicioi.aedi.storage.locator; 35 import aermicioi.aedi.storage.object_storage; 36 import aermicioi.aedi.exception.not_found_exception; 37 import aermicioi.aedi.util.range : inheritance; 38 import std.range.interfaces; 39 40 /** 41 An aggregate container with knowledge of concrete types of aggregated containers. 42 It delegates the task of serving an object to contained containers. 43 **/ 44 @safe class TupleContainer(T...) : Container { 45 46 public { 47 /** 48 List of containers that Tuple container uses. 49 **/ 50 T containers; 51 52 /** 53 Aliasing to containers for unboxing and index based access. 54 **/ 55 alias containers this; 56 57 /** 58 Construct tuple container with a set of aggregate containers. 59 60 Params: 61 containers = a sequence of containers 62 **/ 63 this(T containers) { 64 this.containers = containers; 65 } 66 67 /** 68 Get a container, or an object that is contained by managed containers. 69 70 Get a container, or an object that is contained by managed containers. 71 72 Params: 73 identity = identity of object that is to be supplied. 74 75 Throws: 76 NotFoundException when no requested object by identity is present in container 77 78 Returns: 79 Object the object contained in one of containers or a container itself. 80 **/ 81 Object get(string identity) { 82 83 foreach (container; this.containers) { 84 foreach (type; typeid(container).inheritance) { 85 if (type.name == identity) { 86 return container; 87 } 88 } 89 90 if (container.has(identity)) { 91 return container.get(identity); 92 } 93 } 94 95 throw new NotFoundException("Component by ${identity} not found.", identity); 96 } 97 98 /** 99 Check if an object is present in one of containers, or it is a container itself. 100 101 Check if an object is present in one of containers, or it is a container itself. 102 103 Params: 104 identity = identity of object to be checked 105 106 Returns: 107 bool true if exists, false otherwise 108 **/ 109 bool has(in string identity) inout { 110 111 foreach (container; this.containers) { 112 foreach (type; typeid(container).inheritance) { 113 if (type.name == identity) { 114 return true; 115 } 116 } 117 118 if (container.has(identity)) { 119 return true; 120 } 121 } 122 123 return false; 124 } 125 126 /** 127 Finalize all unfinished initialization work in containers. 128 129 Finalize all unfinished initialization work in containers. 130 131 Returns: 132 TupleContainer 133 **/ 134 TupleContainer instantiate() { 135 136 foreach (container; this.containers) { 137 container.instantiate; 138 } 139 140 return this; 141 } 142 143 /** 144 Destruct all managed components. 145 146 Destruct all managed components. The method denotes the end of container lifetime, and therefore destruction of all managed components 147 by it. 148 **/ 149 Container terminate() { 150 foreach (container; this.containers) { 151 container.terminate; 152 } 153 154 return this; 155 } 156 } 157 }