1 // -*- C++ -*- 2 // Module: Log4CPLUS 3 // File: factory.h 4 // Created: 2/2002 5 // Author: Tad E. Smith 6 // 7 // 8 // Copyright 2002-2010 Tad E. Smith 9 // 10 // Licensed under the Apache License, Version 2.0 (the "License"); 11 // you may not use this file except in compliance with the License. 12 // You may obtain a copy of the License at 13 // 14 // http://www.apache.org/licenses/LICENSE-2.0 15 // 16 // Unless required by applicable law or agreed to in writing, software 17 // distributed under the License is distributed on an "AS IS" BASIS, 18 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 // See the License for the specific language governing permissions and 20 // limitations under the License. 21 22 /** @file */ 23 24 #ifndef DCMTK_LOG4CPLUS_SPI_FACTORY_HEADER_ 25 #define DCMTK_LOG4CPLUS_SPI_FACTORY_HEADER_ 26 27 #include "dcmtk/oflog/config.h" 28 29 #if defined (DCMTK_LOG4CPLUS_HAVE_PRAGMA_ONCE) 30 #pragma once 31 #endif 32 33 #include "dcmtk/oflog/appender.h" 34 #include "dcmtk/oflog/layout.h" 35 #include "dcmtk/oflog/tstring.h" 36 #include "dcmtk/oflog/spi/filter.h" 37 #include "dcmtk/oflog/spi/objreg.h" 38 #include <memory> 39 #include "dcmtk/ofstd/ofvector.h" 40 #include <locale> 41 42 43 namespace dcmtk { 44 namespace log4cplus { 45 namespace spi { 46 47 /** 48 * This is the base class for all factories. 49 */ 50 class DCMTK_LOG4CPLUS_EXPORT BaseFactory { 51 public: 52 virtual ~BaseFactory() = 0; 53 54 /** 55 * Returns the typename of the objects this factory creates. 56 */ 57 virtual log4cplus::tstring const & getTypeName() const = 0; 58 }; 59 60 61 /** 62 * This abstract class defines the "Factory" interface to create "Appender" 63 * objects. 64 */ 65 class DCMTK_LOG4CPLUS_EXPORT AppenderFactory : public BaseFactory { 66 public: 67 typedef Appender ProductType; 68 typedef SharedAppenderPtr ProductPtr; 69 70 AppenderFactory(); 71 virtual ~AppenderFactory() = 0; 72 73 /** 74 * Create an "Appender" object. 75 */ 76 virtual SharedAppenderPtr createObject(const log4cplus::helpers::Properties& props) = 0; 77 }; 78 79 80 81 /** 82 * This abstract class defines the "Factory" interface to create "Layout" 83 * objects. 84 */ 85 class DCMTK_LOG4CPLUS_EXPORT LayoutFactory : public BaseFactory { 86 public: 87 typedef Layout ProductType; 88 typedef OFrvalue<OFunique_ptr<Layout> > ProductPtr; 89 90 LayoutFactory(); 91 virtual ~LayoutFactory() = 0; 92 93 /** 94 * Create a "Layout" object. 95 */ 96 virtual ProductPtr createObject(const log4cplus::helpers::Properties& props) = 0; 97 }; 98 99 100 101 /** 102 * This abstract class defines the "Factory" interface to create "Appender" 103 * objects. 104 */ 105 class DCMTK_LOG4CPLUS_EXPORT FilterFactory : public BaseFactory { 106 public: 107 typedef Filter ProductType; 108 typedef FilterPtr ProductPtr; 109 110 FilterFactory(); 111 virtual ~FilterFactory() = 0; 112 113 /** 114 * Create a "Filter" object. 115 */ 116 virtual FilterPtr createObject(const log4cplus::helpers::Properties& props) = 0; 117 }; 118 119 120 /** 121 * This abstract class defines the "Factory" interface to 122 * create STD_NAMESPACE locale instances. 123 */ 124 class DCMTK_LOG4CPLUS_EXPORT LocaleFactory 125 : public BaseFactory 126 { 127 public: 128 typedef STD_NAMESPACE locale ProductType; 129 typedef STD_NAMESPACE locale ProductPtr; 130 131 LocaleFactory(); 132 virtual ~LocaleFactory() = 0; 133 134 //! \returns STD_NAMESPACE locale instance 135 virtual ProductPtr createObject ( 136 const log4cplus::helpers::Properties & props) = 0; 137 }; 138 139 140 /** 141 * This template class is used as a "Factory Registry". Objects are 142 * "entered" into the registry with a "name" using the 143 * <code>put()</code> method. (The registry then owns the object.) 144 * These object can then be retrieved using the <code>get()</code> 145 * method. 146 * 147 * <b>Note:</b> This class is Thread-safe. 148 */ 149 template<class T> 150 class DCMTK_LOG4CPLUS_EXPORT FactoryRegistry : ObjectRegistryBase { 151 public: 152 typedef T product_type; 153 ~FactoryRegistry()154 virtual ~FactoryRegistry() { 155 clear(); 156 } 157 158 // public methods 159 /** 160 * Used to enter an object into the registry. (The registry now 161 * owns <code>object</code>.) 162 */ put(OFunique_ptr<T> object)163 bool put(OFunique_ptr<T> object) { 164 bool putValResult = putVal(object->getTypeName(), object.get()); 165 object.release(); 166 return putValResult; 167 } 168 169 /** 170 * Used to retrieve an object from the registry. (The registry 171 * owns the returned pointer.) 172 */ get(const log4cplus::tstring & name)173 T* get(const log4cplus::tstring& name) const { 174 return OFstatic_cast(T*, getVal(name)); 175 } 176 177 protected: deleteObject(void * object)178 virtual void deleteObject(void *object) const { 179 delete OFstatic_cast(T*, object); 180 } 181 }; 182 183 184 typedef FactoryRegistry<AppenderFactory> AppenderFactoryRegistry; 185 typedef FactoryRegistry<LayoutFactory> LayoutFactoryRegistry; 186 typedef FactoryRegistry<FilterFactory> FilterFactoryRegistry; 187 typedef FactoryRegistry<LocaleFactory> LocaleFactoryRegistry; 188 189 190 /** 191 * Returns the "singleton" <code>AppenderFactoryRegistry</code>. 192 */ 193 DCMTK_LOG4CPLUS_EXPORT AppenderFactoryRegistry& getAppenderFactoryRegistry(); 194 195 /** 196 * Returns the "singleton" <code>LayoutFactoryRegistry</code>. 197 */ 198 DCMTK_LOG4CPLUS_EXPORT LayoutFactoryRegistry& getLayoutFactoryRegistry(); 199 200 /** 201 * Returns the "singleton" <code>FilterFactoryRegistry</code>. 202 */ 203 DCMTK_LOG4CPLUS_EXPORT FilterFactoryRegistry& getFilterFactoryRegistry(); 204 205 /** 206 * Returns the "singleton" <code>LocaleFactoryRegistry</code>. 207 */ 208 DCMTK_LOG4CPLUS_EXPORT LocaleFactoryRegistry& getLocaleFactoryRegistry(); 209 210 211 template <typename ProductFactoryBase> 212 class LocalFactoryBase 213 : public ProductFactoryBase 214 { 215 public: LocalFactoryBase(tchar const * n)216 LocalFactoryBase (tchar const * n) 217 : name (n) 218 { } 219 getTypeName()220 virtual log4cplus::tstring const & getTypeName() const 221 { 222 return name; 223 } 224 225 private: 226 log4cplus::tstring name; 227 }; 228 229 230 template <typename LocalProduct, typename ProductFactoryBase> 231 class FactoryTempl 232 : public LocalFactoryBase<ProductFactoryBase> 233 { 234 public: 235 typedef typename ProductFactoryBase::ProductPtr ProductPtr; 236 FactoryTempl(tchar const * n)237 FactoryTempl (tchar const * n) 238 : LocalFactoryBase<ProductFactoryBase> (n) 239 { } 240 createObject(helpers::Properties const & props)241 virtual ProductPtr createObject (helpers::Properties const & props) 242 { 243 return ProductPtr (new LocalProduct (props)); 244 } 245 }; 246 247 248 #define DCMTK_LOG4CPLUS_REG_PRODUCT(reg, productprefix, productname, productns, productfact) \ 249 reg.put ( \ 250 OFrvalue<OFunique_ptr<productfact> > ( \ 251 new log4cplus::spi::FactoryTempl<productns productname, productfact> ( \ 252 DCMTK_LOG4CPLUS_TEXT(productprefix) \ 253 DCMTK_LOG4CPLUS_TEXT(#productname)))) 254 255 #define DCMTK_LOG4CPLUS_REG_APPENDER(reg, appendername) \ 256 DCMTK_LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", appendername, log4cplus::, \ 257 log4cplus::spi::AppenderFactory) 258 259 #define DCMTK_LOG4CPLUS_REG_LAYOUT(reg, layoutname) \ 260 DCMTK_LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", layoutname, log4cplus::, \ 261 log4cplus::spi::LayoutFactory) 262 263 #define DCMTK_LOG4CPLUS_REG_FILTER(reg, filtername) \ 264 DCMTK_LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::spi::", filtername, log4cplus::spi::, \ 265 log4cplus::spi::FilterFactory) 266 267 #define DCMTK_LOG4CPLUS_REG_LOCALE(reg, name, factory) \ 268 reg.put (OFrvalue<OFunique_ptr<log4cplus::spi::LocaleFactory> > ( \ 269 new factory (name))) 270 } // namespace spi 271 } 272 } // end namespace dcmtk 273 274 275 #endif // DCMTK_LOG4CPLUS_SPI_FACTORY_HEADER_ 276