factory.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. // -*- C++ -*-
  2. // Module: Log4CPLUS
  3. // File: factory.h
  4. // Created: 2/2002
  5. // Author: Tad E. Smith
  6. //
  7. //
  8. // Copyright 2002-2015 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. /** @file */
  22. #ifndef LOG4CPLUS_SPI_FACTORY_HEADER_
  23. #define LOG4CPLUS_SPI_FACTORY_HEADER_
  24. #include <log4cplus/config.hxx>
  25. #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
  26. #pragma once
  27. #endif
  28. #include <log4cplus/appender.h>
  29. #include <log4cplus/layout.h>
  30. #include <log4cplus/tstring.h>
  31. #include <log4cplus/spi/filter.h>
  32. #include <log4cplus/spi/objectregistry.h>
  33. #include <memory>
  34. #include <vector>
  35. #include <locale>
  36. namespace log4cplus {
  37. namespace spi {
  38. /**
  39. * This is the base class for all factories.
  40. */
  41. class LOG4CPLUS_EXPORT BaseFactory {
  42. public:
  43. virtual ~BaseFactory() = 0;
  44. /**
  45. * Returns the typename of the objects this factory creates.
  46. */
  47. virtual log4cplus::tstring const & getTypeName() const = 0;
  48. };
  49. /**
  50. * This abstract class defines the "Factory" interface to create "Appender"
  51. * objects.
  52. */
  53. class LOG4CPLUS_EXPORT AppenderFactory : public BaseFactory {
  54. public:
  55. typedef Appender ProductType;
  56. typedef SharedAppenderPtr ProductPtr;
  57. AppenderFactory();
  58. virtual ~AppenderFactory() = 0;
  59. /**
  60. * Create an "Appender" object.
  61. */
  62. virtual SharedAppenderPtr createObject(const log4cplus::helpers::Properties& props) = 0;
  63. };
  64. /**
  65. * This abstract class defines the "Factory" interface to create "Layout"
  66. * objects.
  67. */
  68. class LOG4CPLUS_EXPORT LayoutFactory : public BaseFactory {
  69. public:
  70. typedef Layout ProductType;
  71. typedef std::auto_ptr<Layout> ProductPtr;
  72. LayoutFactory();
  73. virtual ~LayoutFactory() = 0;
  74. /**
  75. * Create a "Layout" object.
  76. */
  77. virtual std::auto_ptr<Layout> createObject(const log4cplus::helpers::Properties& props) = 0;
  78. };
  79. /**
  80. * This abstract class defines the "Factory" interface to create "Appender"
  81. * objects.
  82. */
  83. class LOG4CPLUS_EXPORT FilterFactory : public BaseFactory {
  84. public:
  85. typedef Filter ProductType;
  86. typedef FilterPtr ProductPtr;
  87. FilterFactory();
  88. virtual ~FilterFactory() = 0;
  89. /**
  90. * Create a "Filter" object.
  91. */
  92. virtual FilterPtr createObject(const log4cplus::helpers::Properties& props) = 0;
  93. };
  94. /**
  95. * This abstract class defines the "Factory" interface to
  96. * create std::locale instances.
  97. */
  98. class LOG4CPLUS_EXPORT LocaleFactory
  99. : public BaseFactory
  100. {
  101. public:
  102. typedef std::locale ProductType;
  103. typedef std::locale ProductPtr;
  104. LocaleFactory();
  105. virtual ~LocaleFactory() = 0;
  106. //! \returns std::locale instance
  107. virtual ProductPtr createObject (
  108. const log4cplus::helpers::Properties & props) = 0;
  109. };
  110. /**
  111. * This template class is used as a "Factory Registry". Objects are
  112. * "entered" into the registry with a "name" using the
  113. * <code>put()</code> method. (The registry then owns the object.)
  114. * These object can then be retrieved using the <code>get()</code>
  115. * method.
  116. *
  117. * <b>Note:</b> This class is Thread-safe.
  118. */
  119. template<class T>
  120. class LOG4CPLUS_EXPORT FactoryRegistry
  121. : public ObjectRegistryBase
  122. {
  123. public:
  124. typedef T product_type;
  125. virtual ~FactoryRegistry() {
  126. clear();
  127. }
  128. // public methods
  129. /**
  130. * Used to enter an object into the registry. (The registry now
  131. * owns <code>object</code>.)
  132. */
  133. bool put(std::auto_ptr<T> object) {
  134. bool putValResult = putVal(object->getTypeName(), object.get());
  135. object.release();
  136. return putValResult;
  137. }
  138. /**
  139. * Used to retrieve an object from the registry. (The registry
  140. * owns the returned pointer.)
  141. */
  142. T* get(const log4cplus::tstring& name) const {
  143. return static_cast<T*>(getVal(name));
  144. }
  145. protected:
  146. virtual void deleteObject(void *object) const {
  147. delete static_cast<T*>(object);
  148. }
  149. };
  150. typedef FactoryRegistry<AppenderFactory> AppenderFactoryRegistry;
  151. typedef FactoryRegistry<LayoutFactory> LayoutFactoryRegistry;
  152. typedef FactoryRegistry<FilterFactory> FilterFactoryRegistry;
  153. typedef FactoryRegistry<LocaleFactory> LocaleFactoryRegistry;
  154. /**
  155. * Returns the "singleton" <code>AppenderFactoryRegistry</code>.
  156. */
  157. LOG4CPLUS_EXPORT AppenderFactoryRegistry& getAppenderFactoryRegistry();
  158. /**
  159. * Returns the "singleton" <code>LayoutFactoryRegistry</code>.
  160. */
  161. LOG4CPLUS_EXPORT LayoutFactoryRegistry& getLayoutFactoryRegistry();
  162. /**
  163. * Returns the "singleton" <code>FilterFactoryRegistry</code>.
  164. */
  165. LOG4CPLUS_EXPORT FilterFactoryRegistry& getFilterFactoryRegistry();
  166. /**
  167. * Returns the "singleton" <code>LocaleFactoryRegistry</code>.
  168. */
  169. LOG4CPLUS_EXPORT LocaleFactoryRegistry& getLocaleFactoryRegistry();
  170. template <typename ProductFactoryBase>
  171. class LocalFactoryBase
  172. : public ProductFactoryBase
  173. {
  174. public:
  175. LocalFactoryBase (tchar const * n)
  176. : name (n)
  177. { }
  178. virtual log4cplus::tstring const & getTypeName() const
  179. {
  180. return name;
  181. }
  182. private:
  183. log4cplus::tstring name;
  184. };
  185. template <typename LocalProduct, typename ProductFactoryBase>
  186. class FactoryTempl
  187. : public LocalFactoryBase<ProductFactoryBase>
  188. {
  189. public:
  190. typedef typename ProductFactoryBase::ProductPtr ProductPtr;
  191. FactoryTempl (tchar const * n)
  192. : LocalFactoryBase<ProductFactoryBase> (n)
  193. { }
  194. virtual ProductPtr createObject (helpers::Properties const & props)
  195. {
  196. return ProductPtr (new LocalProduct (props));
  197. }
  198. };
  199. #define LOG4CPLUS_REG_PRODUCT(reg, productprefix, productname, productns, productfact) \
  200. reg.put ( \
  201. std::auto_ptr<productfact> ( \
  202. new log4cplus::spi::FactoryTempl<productns productname, productfact> ( \
  203. LOG4CPLUS_TEXT(productprefix) \
  204. LOG4CPLUS_TEXT(#productname))))
  205. #define LOG4CPLUS_REG_APPENDER(reg, appendername) \
  206. LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", appendername, log4cplus::, \
  207. log4cplus::spi::AppenderFactory)
  208. #define LOG4CPLUS_REG_LAYOUT(reg, layoutname) \
  209. LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", layoutname, log4cplus::, \
  210. log4cplus::spi::LayoutFactory)
  211. #define LOG4CPLUS_REG_FILTER(reg, filtername) \
  212. LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::spi::", filtername, log4cplus::spi::, \
  213. log4cplus::spi::FilterFactory)
  214. #define LOG4CPLUS_REG_LOCALE(reg, name, factory) \
  215. reg.put (std::auto_ptr<log4cplus::spi::LocaleFactory> ( \
  216. new factory (name)))
  217. } // namespace spi
  218. }
  219. #endif // LOG4CPLUS_SPI_FACTORY_HEADER_