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

Generated on Sun Apr 27 13:16:03 2008 for libs11n by  doxygen 1.5.3