// -*- C++ -*- // Module: Log4CPLUS // File: factory.h // Created: 2/2002 // Author: Tad E. Smith // // // Copyright 2002-2013 Tad E. Smith // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** @file */ #ifndef LOG4CPLUS_SPI_FACTORY_HEADER_ #define LOG4CPLUS_SPI_FACTORY_HEADER_ #include #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) #pragma once #endif #include #include #include #include #include #include #include #include namespace log4cplus { namespace spi { /** * This is the base class for all factories. */ class LOG4CPLUS_EXPORT BaseFactory { public: virtual ~BaseFactory() = 0; /** * Returns the typename of the objects this factory creates. */ virtual log4cplus::tstring const & getTypeName() const = 0; }; /** * This abstract class defines the "Factory" interface to create "Appender" * objects. */ class LOG4CPLUS_EXPORT AppenderFactory : public BaseFactory { public: typedef Appender ProductType; typedef SharedAppenderPtr ProductPtr; AppenderFactory(); virtual ~AppenderFactory() = 0; /** * Create an "Appender" object. */ virtual SharedAppenderPtr createObject(const log4cplus::helpers::Properties& props) = 0; }; /** * This abstract class defines the "Factory" interface to create "Layout" * objects. */ class LOG4CPLUS_EXPORT LayoutFactory : public BaseFactory { public: typedef Layout ProductType; typedef std::auto_ptr ProductPtr; LayoutFactory(); virtual ~LayoutFactory() = 0; /** * Create a "Layout" object. */ virtual std::auto_ptr createObject(const log4cplus::helpers::Properties& props) = 0; }; /** * This abstract class defines the "Factory" interface to create "Appender" * objects. */ class LOG4CPLUS_EXPORT FilterFactory : public BaseFactory { public: typedef Filter ProductType; typedef FilterPtr ProductPtr; FilterFactory(); virtual ~FilterFactory() = 0; /** * Create a "Filter" object. */ virtual FilterPtr createObject(const log4cplus::helpers::Properties& props) = 0; }; /** * This abstract class defines the "Factory" interface to * create std::locale instances. */ class LOG4CPLUS_EXPORT LocaleFactory : public BaseFactory { public: typedef std::locale ProductType; typedef std::locale ProductPtr; LocaleFactory(); virtual ~LocaleFactory() = 0; //! \returns std::locale instance virtual ProductPtr createObject ( const log4cplus::helpers::Properties & props) = 0; }; /** * This template class is used as a "Factory Registry". Objects are * "entered" into the registry with a "name" using the * put() method. (The registry then owns the object.) * These object can then be retrieved using the get() * method. * * Note: This class is Thread-safe. */ template class LOG4CPLUS_EXPORT FactoryRegistry : ObjectRegistryBase { public: typedef T product_type; virtual ~FactoryRegistry() { clear(); } // public methods /** * Used to enter an object into the registry. (The registry now * owns object.) */ bool put(std::auto_ptr object) { bool putValResult = putVal(object->getTypeName(), object.get()); object.release(); return putValResult; } /** * Used to retrieve an object from the registry. (The registry * owns the returned pointer.) */ T* get(const log4cplus::tstring& name) const { return static_cast(getVal(name)); } protected: virtual void deleteObject(void *object) const { delete static_cast(object); } }; typedef FactoryRegistry AppenderFactoryRegistry; typedef FactoryRegistry LayoutFactoryRegistry; typedef FactoryRegistry FilterFactoryRegistry; typedef FactoryRegistry LocaleFactoryRegistry; /** * Returns the "singleton" AppenderFactoryRegistry. */ LOG4CPLUS_EXPORT AppenderFactoryRegistry& getAppenderFactoryRegistry(); /** * Returns the "singleton" LayoutFactoryRegistry. */ LOG4CPLUS_EXPORT LayoutFactoryRegistry& getLayoutFactoryRegistry(); /** * Returns the "singleton" FilterFactoryRegistry. */ LOG4CPLUS_EXPORT FilterFactoryRegistry& getFilterFactoryRegistry(); /** * Returns the "singleton" LocaleFactoryRegistry. */ LOG4CPLUS_EXPORT LocaleFactoryRegistry& getLocaleFactoryRegistry(); template class LocalFactoryBase : public ProductFactoryBase { public: LocalFactoryBase (tchar const * n) : name (n) { } virtual log4cplus::tstring const & getTypeName() const { return name; } private: log4cplus::tstring name; }; template class FactoryTempl : public LocalFactoryBase { public: typedef typename ProductFactoryBase::ProductPtr ProductPtr; FactoryTempl (tchar const * n) : LocalFactoryBase (n) { } virtual ProductPtr createObject (helpers::Properties const & props) { return ProductPtr (new LocalProduct (props)); } }; #define LOG4CPLUS_REG_PRODUCT(reg, productprefix, productname, productns, productfact) \ reg.put ( \ std::auto_ptr ( \ new log4cplus::spi::FactoryTempl ( \ LOG4CPLUS_TEXT(productprefix) \ LOG4CPLUS_TEXT(#productname)))) #define LOG4CPLUS_REG_APPENDER(reg, appendername) \ LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", appendername, log4cplus::, \ log4cplus::spi::AppenderFactory) #define LOG4CPLUS_REG_LAYOUT(reg, layoutname) \ LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", layoutname, log4cplus::, \ log4cplus::spi::LayoutFactory) #define LOG4CPLUS_REG_FILTER(reg, filtername) \ LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::spi::", filtername, log4cplus::spi::, \ log4cplus::spi::FilterFactory) #define LOG4CPLUS_REG_LOCALE(reg, name, factory) \ reg.put (std::auto_ptr ( \ new factory (name))) } // namespace spi } #endif // LOG4CPLUS_SPI_FACTORY_HEADER_