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_property_reader.generic_convertor_container; 31 32 import aermicioi.aedi; 33 import aermicioi.aedi_property_reader.convertor_container; 34 import aermicioi.aedi_property_reader.convertor_factory; 35 import std.range; 36 import std.typecons; 37 38 /** 39 An implementation of ConvertorContainer. 40 41 Params: 42 FromType = original form of data based on which components are constructed. 43 DefaultConvertorFactory = convertor factory that is used by default in this container (used for some generic stuff) 44 **/ 45 class GenericConvertorContainer(FromType, alias DefaultConvertorFactory) : 46 ConvertorContainer!(FromType, string), FactoryLocator!(Factory!Object) { 47 48 private { 49 50 Locator!(FromType, string) locator_; 51 ObjectStorage!() instantiated; 52 ObjectStorage!(ConvertorFactory!(FromType, Object), string) convertors; 53 } 54 55 public { 56 57 /** 58 Default constructor for GenericConvertorContainer!(FromType, DefaultConvertorFactory) 59 **/ 60 this() { 61 this.instantiated = new ObjectStorage!(); 62 this.convertors = new ObjectStorage!(ConvertorFactory!(FromType, Object), string); 63 } 64 65 @property { 66 /** 67 Set locator 68 69 Params: 70 locator = locator that provides container with FromType data for convertor factories 71 72 Returns: 73 GenericConvertorContainer!(FromType, DefaultConvertorFactory) 74 **/ 75 GenericConvertorContainer!(FromType, DefaultConvertorFactory) locator(Locator!(FromType, string) locator) @safe nothrow { 76 this.locator_ = locator; 77 78 return this; 79 } 80 81 /** 82 Get locator of FromType data 83 84 Returns: 85 Locator!(FromType, string) 86 **/ 87 Locator!(FromType, string) locator() @safe nothrow { 88 return this.locator_; 89 } 90 } 91 92 /** 93 Save a convertor factory in GenericConvertorContainer by key identity. 94 95 Params: 96 key = identity of element in GenericConvertorContainer. 97 factory = convertor factory which is to be saved in GenericConvertorContainer. 98 99 Return: 100 GenericConvertorContainer!(FromType, DefaultConvertorFactory) 101 **/ 102 GenericConvertorContainer!(FromType, DefaultConvertorFactory) set(ConvertorFactory!(FromType, Object) factory, string key) { 103 this.convertors.set(factory, key); 104 105 return this; 106 } 107 108 /** 109 Remove an convertor factory from GenericConvertorContainer with identity. 110 111 Remove an convertor factory from GenericConvertorContainer with identity. If there is no convertor factory by provided identity, then no action is performed. 112 113 Params: 114 key = the identity of convertor factory to be removed. 115 116 Return: 117 GenericConvertorContainer!(FromType, DefaultConvertorFactory) 118 **/ 119 GenericConvertorContainer!(FromType, DefaultConvertorFactory) remove(string key) { 120 this.convertors.remove(key); 121 this.instantiated.remove(key); 122 123 return this; 124 } 125 126 /** 127 Get a component that is associated with key. 128 129 Params: 130 key = the component id. 131 132 Throws: 133 NotFoundException in case if the component wasn't found. 134 135 Returns: 136 Object, component if it is available. 137 **/ 138 Object get(string key) { 139 140 if (!this.instantiated.has(key)) { 141 if (!this.convertors.has(key)) { 142 143 throw new NotFoundException("Object with id " ~ key ~ " not found."); 144 } 145 146 auto factory = this.convertors.get(key); 147 factory.convertible = this.locator.get(key); 148 149 this.instantiated.set( 150 factory.factory(), 151 key, 152 ); 153 } 154 155 return this.instantiated.get(key); 156 } 157 158 /** 159 Check if a component is present in Locator by key id. 160 161 Params: 162 key = identity of element. 163 164 Returns: 165 bool true if an component by key is present in Locator. 166 **/ 167 bool has(in string key) inout { 168 return this.convertors.has(key) && this.locator_.has(key); 169 } 170 171 /** 172 Sets up the internal state of container. 173 174 Sets up the internal state of container (Ex, for singleton container it will spawn all objects that locator contains). 175 **/ 176 GenericConvertorContainer!(FromType, DefaultConvertorFactory) instantiate() { 177 import std.algorithm : filter; 178 179 return this; 180 } 181 182 /** 183 Get factory for constructed component identified by identity. 184 185 Get factory for constructed component identified by identity. 186 Params: 187 identity = the identity of component that factory constructs. 188 189 Throws: 190 NotFoundException when factory for it is not found. 191 192 Returns: 193 T the factory for constructed component. 194 **/ 195 ObjectFactory getFactory(string identity) { 196 return this.convertors.get(identity); 197 } 198 199 /** 200 Get all factories available in container. 201 202 Get all factories available in container. 203 204 Returns: 205 InputRange!(Tuple!(T, string)) a tuple of factory => identity. 206 **/ 207 InputRange!(Tuple!(Factory!(Object), string)) getFactories() { 208 import std.algorithm; 209 210 return this.convertors.contents.byKeyValue.map!( 211 a => tuple(cast(Factory!Object) a.value, a.key) 212 ).inputRangeObject; 213 } 214 } 215 }