Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

classload.hpp

Go to the documentation of this file.
00001 #ifndef s11n_cl_S11N_CLASSLOAD_HPP_INCLUDED
00002 #define s11n_cl_S11N_CLASSLOAD_HPP_INCLUDED 1
00003 
00004 #include <s11n.net/s11n/s11n_debuggering_macros.hpp> // S11N_TRACE()
00005 #include <s11n.net/s11n/factory.hpp>
00006 
00007 
00008 namespace s11n {
00009         /**
00010            The s11n::cl namespace encapsulates the public
00011            classloader-related API for libs11n.
00012 
00013            Note that the registration functions in this namespace
00014            register with the s11n::fac family of classes. Clients wishing to use
00015            their own factories should:
00016 
00017            - register with their appropriate classloader.
00018 
00019            - specialize the object_factory class template
00020            so that it forwards calls to their classloader.
00021 
00022            This layer is used for classloading anything which s11n
00023            needs to dynamically load, including:
00024 
00025            - Serializables
00026 
00027            - Serializers
00028 
00029            - FlexLexers
00030 
00031            It supports loading types via DLLs if the optional s11n::plugin
00032        layer is enabled.
00033 
00034        Changes from 1.0.x to 1.1.x:
00035 
00036        - Now internally uses s11n::factory_mgr and s11n::plugin
00037        instead of the cllite API.
00038 
00039        Changed in 1.2.2:
00040 
00041        - operator() implementation code was moved to classload.tpp.
00042         */
00043         namespace cl {
00044 
00045         /**
00046            A default object factory functor for use
00047            with the s11n::s11n_traits type.
00048        
00049            Clients may specialize this to return objects from
00050            their own factories. By default it uses s11n::fac's
00051            mini-framework, and thus can load any type registered with
00052            that API.
00053         */
00054         template <typename InterfaceBase>
00055         struct S11N_EXPORT_API object_factory
00056         {
00057             /** Same as InterfaceBase. */
00058             typedef InterfaceBase base_type;
00059 
00060             /**
00061                The default implementation returns
00062                ::s11n::fac::factory<InterfaceBase>().create(key). The
00063                caller owns the returned pointer, which may
00064                be 0.
00065 
00066                If the underlying factory does not have the
00067                requested class and s11n is built with the
00068                s11n::plugin layer, then
00069                s11n::plugin::open(classname) is used to
00070                search for a DLL. Under the s11n classloader
00071                model, opening a plugin will register classes
00072                defined in the plugin back with the factory.
00073 
00074                This function propagates exceptions if the
00075                underlying factory's create() feature throws.
00076 
00077                a) s11n_exceptions are passed on as-is.
00078 
00079                b) std::exceptions are translated to
00080                s11n::factory_exceptions, keeping the
00081                what() text.
00082 
00083                c) Unknown exceptions (...) are translated
00084                to s11n::factory_exceptions with an
00085                unspecified non-empty what() text.
00086 
00087             */
00088             base_type * operator()( const std::string & key ) const;
00089         };
00090 
00091                 /**
00092            Returns object_factory<InterfaceBase>(key).
00093                 */
00094                 template <typename InterfaceBase>
00095                 InterfaceBase * classload( const std::string key );
00096 
00097                 /**
00098                    Registers a factory with InterfaceBase's
00099                    classloader.
00100 
00101            Trivia: 'register' is a reserved word in C++,
00102            inherited from C, so this function has an unduly
00103            long name. register() was the first choice.
00104                 */
00105                 template <typename InterfaceBase>
00106                 void classloader_register( const std::string & classname, InterfaceBase * (*factory_func)() );
00107 
00108         /**
00109            Registers a default factory which returns a SubType
00110            object. SubType must be a public subtype of
00111            InterfaceBase, or must be InterfaceBase, and must
00112            not be abstract.
00113         */
00114                 template <typename InterfaceBase, typename SubType>
00115                 inline void classloader_register_subtype( const std::string & classname )
00116         {
00117             classloader_register<InterfaceBase>( classname, 
00118                                  ::s11n::fac::create_hook<InterfaceBase,SubType>::create
00119                                  );
00120         }
00121 
00122                 /**
00123                    Registers InterfaceBase with its own classloader
00124                    using a default factory. InterfaceBase must be creatable
00125            with 'new', or the default factory implementation must
00126            be specialized to accomodate the abstract class.
00127                 */
00128                 template <typename InterfaceBase>
00129                 inline void classloader_register_base( const std::string & classname )
00130                 {
00131                         classloader_register_subtype<InterfaceBase,InterfaceBase>( classname );
00132                 }
00133 
00134 
00135         namespace Detail
00136         {
00137             /** Internal no-op factory. Always returns 0. */
00138             template <typename T>
00139             inline T * noop_factory() { return 0; }
00140         }
00141 
00142                 /**
00143                    Registers InterfaceBase as an abstract type. That is, it
00144                    assigns it a factory which always returns 0.
00145 
00146                    If types you register with classloader_register()
00147                    (and friends) have an abstract InterfaceBase then that
00148                    InterfaceBase should be registered via this function (or
00149                    equivalent).
00150 
00151            Note that this is also suitable for registering
00152            abstract subtypes of an abstract type, but
00153            InterfaceBase MUST be the type passed here (not the
00154            subtype's type), or the registrations will go to
00155            the subtype's classloader, which normally isn't
00156            what you want to do.
00157                 */
00158                 template <typename InterfaceBase>
00159                 inline void classloader_register_abstract( const std::string & classname )
00160                 {
00161             classloader_register<InterfaceBase>( classname, Detail::noop_factory<InterfaceBase> );
00162                 }
00163 
00164 
00165         /**
00166            Aliases the given classname with the underlying
00167            factory layer, such that classload<InterfaceBase>(_alias)
00168            will return the same as classload<InterfaceBase>(classname).
00169 
00170            A tip for remembering the order of the arguments:
00171            it follows the same order as when assigning an alias
00172            via a Unix shell: alias thealias="the original string"
00173 
00174            Added in 1.1.0.
00175 
00176            Maintenance reminder: this function relies directly
00177            on the s11n::fac API, which isn't "really"
00178            public. This functionality is commonly useful when
00179            hand-registering types, thus we have a public-API
00180            wrapper around this fac-layer-specific feature.
00181         */
00182                 template <typename InterfaceBase>
00183                 inline void classloader_alias( const std::string & _alias,
00184                            const std::string & classname)
00185                 {
00186             ::s11n::fac::factory<InterfaceBase>().aliases().alias( _alias, classname );
00187                 }
00188 
00189 
00190         } // namespace cl
00191 } // namespace s11n
00192 
00193 #include <s11n.net/s11n/classload.tpp> // implementations
00194 #endif // s11n_cl_S11N_CLASSLOAD_HPP_INCLUDED

Generated on Mon Dec 26 15:53:17 2005 for libs11n-1.2.3 by  doxygen 1.4.4