xref: /trunk/main/cppuhelper/source/stdidlclass.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cppuhelper.hxx"
26 
27 #include <osl/mutex.hxx>
28 
29 #include <cppuhelper/weakref.hxx>
30 #include <cppuhelper/weak.hxx>
31 #include <cppuhelper/stdidlclass.hxx>
32 
33 #include <com/sun/star/reflection/XIdlClassProvider.hpp>
34 #include <com/sun/star/reflection/XIdlReflection.hpp>
35 #include <com/sun/star/uno/XComponentContext.hpp>
36 #include <com/sun/star/uno/DeploymentException.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 
39 using namespace com::sun::star;
40 using namespace com::sun::star::uno;
41 using namespace com::sun::star::lang;
42 using namespace com::sun::star::reflection;
43 using namespace rtl;
44 
45 namespace cppu {
46 
47 /*---------------------------------------------------------
48 *   This helper class implements XIdlClass. Is used by
49 *   createStdIdlClass()
50 *---------------------------------------------------------*/
51 class OStdIdlClass :
52             public OWeakObject,
53             public XIdlClass,
54             public XIdlClassProvider
55 {
56 public:
57     OStdIdlClass(
58                     const Reference < XMultiServiceFactory > &rSMgr ,
59                     const OUString & sImplementationName ,
60                     const Reference < XIdlClass > & rSuperClass,
61                     const Sequence < OUString > &seq
62                 ) SAL_THROW( () );
63 
64     // XInterface
65     Any                 SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType );
66 
acquire()67     void                SAL_CALL acquire() throw()   { OWeakObject::acquire(); }
release()68     void                SAL_CALL release() throw()   { OWeakObject::release(); }
69 
70     // XIdlClassProvider
71     Sequence< Reference < XIdlClass > > SAL_CALL getIdlClasses(void);
72 
73     // XIdlClass
getClasses()74     virtual Sequence< Reference< XIdlClass > > SAL_CALL getClasses(  )
75                                         { return Sequence < Reference < XIdlClass > > (); }
getClass(const::rtl::OUString &)76     virtual Reference< XIdlClass > SAL_CALL getClass( const ::rtl::OUString& )
77                                         { return Reference < XIdlClass > (); }
equals(const Reference<XIdlClass> & Type)78     virtual sal_Bool SAL_CALL equals( const Reference< XIdlClass >& Type )
79                                         { return getName() == Type->getName(); }
isAssignableFrom(const Reference<XIdlClass> & xType)80     virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass >& xType )
81                                         { return equals( xType ); }
getTypeClass()82     virtual TypeClass SAL_CALL getTypeClass(  )
83                                         { return TypeClass_UNKNOWN; }
getName()84     virtual OUString SAL_CALL getName(  )
85                                         { return m_sImplementationName; }
getUik()86     virtual Uik SAL_CALL getUik(  )
87                                         { return Uik(); }
getSuperclasses()88     virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses(  )
89                                         { return m_seqSuperClasses; }
90     virtual Sequence< Reference< XIdlClass > > SAL_CALL getInterfaces(  );
91 
getComponentType()92     virtual Reference< XIdlClass > SAL_CALL getComponentType(  )
93                                         { return Reference < XIdlClass > (); }
getField(const::rtl::OUString &)94     virtual Reference< XIdlField > SAL_CALL getField( const ::rtl::OUString& )
95                                         { return Reference < XIdlField > (); }
getFields()96     virtual Sequence< Reference< XIdlField > > SAL_CALL getFields(  )
97                                         { return Sequence< Reference < XIdlField > > (); }
getMethod(const::rtl::OUString &)98     virtual Reference< XIdlMethod > SAL_CALL getMethod( const ::rtl::OUString& )
99                                         { return Reference < XIdlMethod > (); }
getMethods()100     virtual Sequence< Reference< XIdlMethod > > SAL_CALL getMethods(  )
101                                         { return Sequence < Reference < XIdlMethod > > (); }
getArray()102     virtual Reference< XIdlArray > SAL_CALL getArray(  )
103                                         { return Reference < XIdlArray > (); }
createObject(Any &)104     virtual void SAL_CALL createObject( Any& ) {}
105 
106 private:
107     OUString                                m_sImplementationName;
108     Sequence < OUString >                   m_seqSupportedInterface;
109     Sequence < Reference < XIdlClass > >    m_seqSuperClasses;
110     Reference < XMultiServiceFactory >      m_rSMgr;
111 
112     Reference< XIdlReflection > m_xCorefl;
113     Reference< XIdlReflection > const & get_corefl();
114 };
115 
get_corefl()116 Reference< XIdlReflection > const & OStdIdlClass::get_corefl()
117 {
118     if (! m_xCorefl.is())
119     {
120         if( m_rSMgr.is() )
121         {
122             Reference< beans::XPropertySet > xProps( m_rSMgr, UNO_QUERY );
123             OSL_ASSERT( xProps.is() );
124             if (xProps.is())
125             {
126                 Reference< XComponentContext > xContext;
127                 xProps->getPropertyValue(
128                     OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
129                 OSL_ASSERT( xContext.is() );
130                 if (xContext.is())
131                 {
132                     Reference < XIdlReflection > x;
133                     xContext->getValueByName(
134                         OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection") ) ) >>= x;
135                     OSL_ENSURE( x.is(), "### CoreReflection singleton not accessible!?" );
136 
137                     if (x.is())
138                     {
139                         ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
140                         if (! m_xCorefl.is())
141                         {
142                             m_xCorefl = x;
143                         }
144                     }
145                 }
146             }
147         }
148         if (! m_xCorefl.is())
149         {
150             throw DeploymentException(
151                 OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible") ),
152                 Reference< XInterface >() );
153         }
154     }
155     return m_xCorefl;
156 }
157 
OStdIdlClass(const Reference<XMultiServiceFactory> & rSMgr,const OUString & sImplementationName,const Reference<XIdlClass> & rSuperClass,const Sequence<OUString> & seq)158 OStdIdlClass::OStdIdlClass(
159                     const Reference < XMultiServiceFactory > &rSMgr ,
160                     const OUString & sImplementationName ,
161                     const Reference < XIdlClass > & rSuperClass,
162                     const Sequence < OUString > &seq
163                           ) SAL_THROW( () ) :
164                 m_sImplementationName( sImplementationName ) ,
165                 m_seqSupportedInterface( seq ),
166                 m_rSMgr( rSMgr )
167 {
168     if( rSuperClass.is() )
169         m_seqSuperClasses = Sequence< Reference < XIdlClass > >( &rSuperClass, 1 );
170 
171 }
172 
queryInterface(const Type & rType)173 Any SAL_CALL OStdIdlClass::queryInterface( const Type & rType )
174 {
175     Any aRet( ::cppu::queryInterface(
176         rType, static_cast< XIdlClass * >( this ), static_cast< XIdlClassProvider * >( this ) ) );
177 
178     return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
179 }
180 
181 
getInterfaces()182 Sequence< Reference< XIdlClass > > SAL_CALL OStdIdlClass::getInterfaces(  )
183 {
184     int nMax = m_seqSupportedInterface.getLength();
185 
186     Reference< XIdlReflection > const & rCoreRefl = get_corefl();
187     if( rCoreRefl.is() )
188     {
189         Sequence< Reference< XIdlClass > > seqClasses( nMax );
190 
191         for( int n = 0 ; n < nMax ; n++ )
192         {
193             seqClasses.getArray()[n] = rCoreRefl->forName( m_seqSupportedInterface.getArray()[n] );
194         }
195 
196         return seqClasses;
197     }
198     return Sequence< Reference< XIdlClass > > () ;
199 }
200 
201 
202 // XIdlClassProvider
getIdlClasses(void)203 Sequence< Reference < XIdlClass > > SAL_CALL OStdIdlClass::getIdlClasses(void)
204 {
205     // weak reference to cache the standard class
206     static WeakReference< XIdlClass >   weakRef;
207 
208     // try to make weakref hard
209     Reference < XIdlClass > r = weakRef;
210 
211     if( ! r.is() ) {
212         // xidlclass has not been initialized before or has been destroyed already.
213         r = ::cppu::createStandardClass(
214                                         m_rSMgr ,
215                                         OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.cppuhelper.OStdIdlClass") ) ,
216                                         Reference < XIdlClass > () ,
217                                         SAL_STATIC_CAST( XIdlClassProvider * , this ) ,
218                                         SAL_STATIC_CAST( XIdlClass * , this )
219                                         );
220 
221         // store reference for later use
222         weakRef = r;
223     }
224 
225     return Sequence < Reference < XIdlClass > > ( &r , 1 );
226 }
227 
228 
229 
230 
231 // external constructor
createStandardClassWithSequence(const Reference<XMultiServiceFactory> & rSMgr,const OUString & sImplementationName,const Reference<XIdlClass> & rSuperClass,const Sequence<OUString> & seqInterfaceNames)232 XIdlClass *  SAL_CALL createStandardClassWithSequence(
233                     const Reference < XMultiServiceFactory > &rSMgr ,
234                     const OUString & sImplementationName ,
235                     const Reference < XIdlClass > & rSuperClass,
236                     const Sequence < OUString > &seqInterfaceNames )
237     SAL_THROW( () )
238 {
239     return SAL_STATIC_CAST(
240                         XIdlClass * ,
241                         new OStdIdlClass(
242                                             rSMgr ,
243                                             sImplementationName,
244                                             rSuperClass,
245                                             seqInterfaceNames
246                                           )
247                        );
248 }
249 
250 } //end namespace cppu
251