You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 lines
8.4 KiB

  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. /** @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 : ObjectRegistryBase {
  121. public:
  122. typedef T product_type;
  123. virtual ~FactoryRegistry() {
  124. clear();
  125. }
  126. // public methods
  127. /**
  128. * Used to enter an object into the registry. (The registry now
  129. * owns <code>object</code>.)
  130. */
  131. bool put(std::auto_ptr<T> object) {
  132. bool putValResult = putVal(object->getTypeName(), object.get());
  133. object.release();
  134. return putValResult;
  135. }
  136. /**
  137. * Used to retrieve an object from the registry. (The registry
  138. * owns the returned pointer.)
  139. */
  140. T* get(const log4cplus::tstring& name) const {
  141. return static_cast<T*>(getVal(name));
  142. }
  143. protected:
  144. virtual void deleteObject(void *object) const {
  145. delete static_cast<T*>(object);
  146. }
  147. };
  148. typedef FactoryRegistry<AppenderFactory> AppenderFactoryRegistry;
  149. typedef FactoryRegistry<LayoutFactory> LayoutFactoryRegistry;
  150. typedef FactoryRegistry<FilterFactory> FilterFactoryRegistry;
  151. typedef FactoryRegistry<LocaleFactory> LocaleFactoryRegistry;
  152. /**
  153. * Returns the "singleton" <code>AppenderFactoryRegistry</code>.
  154. */
  155. LOG4CPLUS_EXPORT AppenderFactoryRegistry& getAppenderFactoryRegistry();
  156. /**
  157. * Returns the "singleton" <code>LayoutFactoryRegistry</code>.
  158. */
  159. LOG4CPLUS_EXPORT LayoutFactoryRegistry& getLayoutFactoryRegistry();
  160. /**
  161. * Returns the "singleton" <code>FilterFactoryRegistry</code>.
  162. */
  163. LOG4CPLUS_EXPORT FilterFactoryRegistry& getFilterFactoryRegistry();
  164. /**
  165. * Returns the "singleton" <code>LocaleFactoryRegistry</code>.
  166. */
  167. LOG4CPLUS_EXPORT LocaleFactoryRegistry& getLocaleFactoryRegistry();
  168. template <typename ProductFactoryBase>
  169. class LocalFactoryBase
  170. : public ProductFactoryBase
  171. {
  172. public:
  173. LocalFactoryBase (tchar const * n)
  174. : name (n)
  175. { }
  176. virtual log4cplus::tstring const & getTypeName() const
  177. {
  178. return name;
  179. }
  180. private:
  181. log4cplus::tstring name;
  182. };
  183. template <typename LocalProduct, typename ProductFactoryBase>
  184. class FactoryTempl
  185. : public LocalFactoryBase<ProductFactoryBase>
  186. {
  187. public:
  188. typedef typename ProductFactoryBase::ProductPtr ProductPtr;
  189. FactoryTempl (tchar const * n)
  190. : LocalFactoryBase<ProductFactoryBase> (n)
  191. { }
  192. virtual ProductPtr createObject (helpers::Properties const & props)
  193. {
  194. return ProductPtr (new LocalProduct (props));
  195. }
  196. };
  197. #define LOG4CPLUS_REG_PRODUCT(reg, productprefix, productname, productns, productfact) \
  198. reg.put ( \
  199. std::auto_ptr<productfact> ( \
  200. new log4cplus::spi::FactoryTempl<productns productname, productfact> ( \
  201. LOG4CPLUS_TEXT(productprefix) \
  202. LOG4CPLUS_TEXT(#productname))))
  203. #define LOG4CPLUS_REG_APPENDER(reg, appendername) \
  204. LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", appendername, log4cplus::, \
  205. log4cplus::spi::AppenderFactory)
  206. #define LOG4CPLUS_REG_LAYOUT(reg, layoutname) \
  207. LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", layoutname, log4cplus::, \
  208. log4cplus::spi::LayoutFactory)
  209. #define LOG4CPLUS_REG_FILTER(reg, filtername) \
  210. LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::spi::", filtername, log4cplus::spi::, \
  211. log4cplus::spi::FilterFactory)
  212. #define LOG4CPLUS_REG_LOCALE(reg, name, factory) \
  213. reg.put (std::auto_ptr<log4cplus::spi::LocaleFactory> ( \
  214. new factory (name)))
  215. } // namespace spi
  216. }
  217. #endif // LOG4CPLUS_SPI_FACTORY_HEADER_