1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_stoc.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "tdmgr_common.hxx"
32*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx"
33*cdf0e10cSrcweir #include "typelib/typedescription.h"
34*cdf0e10cSrcweir #include "com/sun/star/beans/PropertyAttribute.hpp"
35*cdf0e10cSrcweir #include "com/sun/star/reflection/XConstantsTypeDescription.hpp"
36*cdf0e10cSrcweir #include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
37*cdf0e10cSrcweir #include "com/sun/star/reflection/XEnumTypeDescription.hpp"
38*cdf0e10cSrcweir #include "com/sun/star/reflection/XStructTypeDescription.hpp"
39*cdf0e10cSrcweir #include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
40*cdf0e10cSrcweir #include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp"
41*cdf0e10cSrcweir #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
42*cdf0e10cSrcweir #include "com/sun/star/reflection/XServiceTypeDescription2.hpp"
43*cdf0e10cSrcweir #include "com/sun/star/reflection/XSingletonTypeDescription2.hpp"
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir using ::rtl::OUString;
47*cdf0e10cSrcweir using ::rtl::OUStringBuffer;
48*cdf0e10cSrcweir using namespace ::com::sun::star;
49*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
50*cdf0e10cSrcweir using namespace ::stoc_tdmgr;
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir namespace {
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir OUString getTypeClassName( TypeClass tc )
55*cdf0e10cSrcweir {
56*cdf0e10cSrcweir     typelib_EnumTypeDescription * typeDescr = 0;
57*cdf0e10cSrcweir     OUString name = OUSTR("com.sun.star.uno.TypeClass");
58*cdf0e10cSrcweir     typelib_typedescription_getByName(
59*cdf0e10cSrcweir         reinterpret_cast<typelib_TypeDescription **>(&typeDescr), name.pData );
60*cdf0e10cSrcweir     OSL_ASSERT( typeDescr != 0 );
61*cdf0e10cSrcweir     if (typeDescr == 0)
62*cdf0e10cSrcweir         return OUSTR("Cannot get type description of ") + name;
63*cdf0e10cSrcweir     typelib_typedescription_complete(
64*cdf0e10cSrcweir         reinterpret_cast<typelib_TypeDescription **>(&typeDescr) );
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir     sal_Int32 const * pValues = typeDescr->pEnumValues;
67*cdf0e10cSrcweir     sal_Int32 nPos = typeDescr->nEnumValues;
68*cdf0e10cSrcweir     while (nPos--)
69*cdf0e10cSrcweir     {
70*cdf0e10cSrcweir         if (pValues[ nPos ] == (sal_Int32) tc)
71*cdf0e10cSrcweir             break;
72*cdf0e10cSrcweir     }
73*cdf0e10cSrcweir     if (nPos >= 0)
74*cdf0e10cSrcweir         name = typeDescr->ppEnumNames[ nPos ];
75*cdf0e10cSrcweir     else
76*cdf0e10cSrcweir         name = OUSTR("unknown TypeClass value: ") +
77*cdf0e10cSrcweir             OUString::valueOf( (sal_Int32) tc );
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir     typelib_typedescription_release(
80*cdf0e10cSrcweir         reinterpret_cast<typelib_TypeDescription *>(typeDescr) );
81*cdf0e10cSrcweir     return name;
82*cdf0e10cSrcweir }
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir OUString getPropertyFlagsAsString( sal_Int16 attributes )
85*cdf0e10cSrcweir {
86*cdf0e10cSrcweir     OUStringBuffer buf;
87*cdf0e10cSrcweir     if ((attributes & beans::PropertyAttribute::MAYBEVOID) != 0)
88*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("MAYBEVOID, ") );
89*cdf0e10cSrcweir     if ((attributes & beans::PropertyAttribute::BOUND) != 0)
90*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("BOUND, ") );
91*cdf0e10cSrcweir     if ((attributes & beans::PropertyAttribute::CONSTRAINED) != 0)
92*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("CONSTRAINED, ") );
93*cdf0e10cSrcweir     if ((attributes & beans::PropertyAttribute::TRANSIENT) != 0)
94*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("TRANSIENT, ") );
95*cdf0e10cSrcweir     if ((attributes & beans::PropertyAttribute::READONLY) != 0)
96*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("READONLY, ") );
97*cdf0e10cSrcweir     if ((attributes & beans::PropertyAttribute::MAYBEAMBIGUOUS) != 0)
98*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("MAYBEAMBIGUOUS, ") );
99*cdf0e10cSrcweir     if ((attributes & beans::PropertyAttribute::MAYBEDEFAULT) != 0)
100*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("MAYBEDEFAULT, ") );
101*cdf0e10cSrcweir     if ((attributes & beans::PropertyAttribute::REMOVEABLE) != 0)
102*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("REMOVEABLE, ") );
103*cdf0e10cSrcweir     if ((attributes & beans::PropertyAttribute::OPTIONAL) != 0)
104*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("OPTIONAL") );
105*cdf0e10cSrcweir     else if (buf.getLength() > 0)
106*cdf0e10cSrcweir         buf.setLength( buf.getLength() - 2 ); // truncate ", "
107*cdf0e10cSrcweir     return buf.makeStringAndClear();
108*cdf0e10cSrcweir }
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir void typeError( OUString const & msg, OUString const & context )
111*cdf0e10cSrcweir {
112*cdf0e10cSrcweir     OUStringBuffer buf;
113*cdf0e10cSrcweir     if (context.getLength() > 0) {
114*cdf0e10cSrcweir         buf.append( static_cast<sal_Unicode>('[') );
115*cdf0e10cSrcweir         buf.append( context );
116*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
117*cdf0e10cSrcweir     }
118*cdf0e10cSrcweir     buf.append( msg );
119*cdf0e10cSrcweir     throw IncompatibleTypeException( buf.makeStringAndClear() );
120*cdf0e10cSrcweir }
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir template<typename T>
123*cdf0e10cSrcweir void checkSeq( Sequence< Reference<T> > const & newTypes,
124*cdf0e10cSrcweir             Sequence< Reference<T> > const & existingTypes,
125*cdf0e10cSrcweir             OUString const & context,
126*cdf0e10cSrcweir             bool optionalMode = false )
127*cdf0e10cSrcweir {
128*cdf0e10cSrcweir     sal_Int32 len = newTypes.getLength();
129*cdf0e10cSrcweir     if (len != existingTypes.getLength())
130*cdf0e10cSrcweir     {
131*cdf0e10cSrcweir         if (!optionalMode || len < newTypes.getLength())
132*cdf0e10cSrcweir             typeError( OUSTR("Different number of types!"), context );
133*cdf0e10cSrcweir         len = existingTypes.getLength();
134*cdf0e10cSrcweir     }
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir     Reference<T> const * pNewTypes = newTypes.getConstArray();
137*cdf0e10cSrcweir     Reference<T> const * pExistingTypes = existingTypes.getConstArray();
138*cdf0e10cSrcweir     for ( sal_Int32 pos = 0; pos < len; ++pos )
139*cdf0e10cSrcweir     {
140*cdf0e10cSrcweir         OUStringBuffer buf;
141*cdf0e10cSrcweir         buf.append( context );
142*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", position ") );
143*cdf0e10cSrcweir         buf.append( pos );
144*cdf0e10cSrcweir         check( pNewTypes[pos].get(), pExistingTypes[pos].get(),
145*cdf0e10cSrcweir                buf.makeStringAndClear() );
146*cdf0e10cSrcweir     }
147*cdf0e10cSrcweir }
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir void checkEnum(
150*cdf0e10cSrcweir     Reference<reflection::XEnumTypeDescription> const & xNewTD,
151*cdf0e10cSrcweir     Reference<reflection::XEnumTypeDescription> const & xExistingTD )
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir     if (xNewTD->getEnumNames() != xExistingTD->getEnumNames())
154*cdf0e10cSrcweir         typeError( OUSTR("ENUM names don't match!"), xNewTD->getName() );
155*cdf0e10cSrcweir     if (xNewTD->getEnumValues() != xExistingTD->getEnumValues())
156*cdf0e10cSrcweir         typeError( OUSTR("ENUM values don't match!"), xNewTD->getName() );
157*cdf0e10cSrcweir }
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir void checkStruct(
160*cdf0e10cSrcweir     Reference<reflection::XCompoundTypeDescription> const & xNewTD,
161*cdf0e10cSrcweir     Reference<reflection::XCompoundTypeDescription> const & xExistingTD )
162*cdf0e10cSrcweir {
163*cdf0e10cSrcweir     check( xNewTD->getBaseType(), xExistingTD->getBaseType(),
164*cdf0e10cSrcweir            xNewTD->getName() + OUSTR(", base type") );
165*cdf0e10cSrcweir     checkSeq( xNewTD->getMemberTypes(), xExistingTD->getMemberTypes(),
166*cdf0e10cSrcweir               xNewTD->getName() + OUSTR(", member types") );
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir     if (xNewTD->getMemberNames() != xExistingTD->getMemberNames())
169*cdf0e10cSrcweir         typeError( OUSTR("Different member names!"), xNewTD->getName() );
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir     if (xNewTD->getTypeClass() == TypeClass_STRUCT)
172*cdf0e10cSrcweir     {
173*cdf0e10cSrcweir         Reference<reflection::XStructTypeDescription> xNewStructTD(
174*cdf0e10cSrcweir             xNewTD, UNO_QUERY );
175*cdf0e10cSrcweir         Reference<reflection::XStructTypeDescription> xExistingStructTD(
176*cdf0e10cSrcweir             xExistingTD, UNO_QUERY );
177*cdf0e10cSrcweir         if (xNewStructTD.is() && xExistingStructTD.is())
178*cdf0e10cSrcweir         {
179*cdf0e10cSrcweir             if (xNewStructTD->getTypeParameters() !=
180*cdf0e10cSrcweir                 xExistingStructTD->getTypeParameters())
181*cdf0e10cSrcweir                 typeError( OUSTR("Different type parameters of instantiated "
182*cdf0e10cSrcweir                                  "polymorphic STRUCT!"), xNewTD->getName() );
183*cdf0e10cSrcweir             checkSeq( xNewStructTD->getTypeArguments(),
184*cdf0e10cSrcweir                       xExistingStructTD->getTypeArguments(),
185*cdf0e10cSrcweir                       xNewTD->getName() + OUSTR(", argument types") );
186*cdf0e10cSrcweir         }
187*cdf0e10cSrcweir         else if (xNewStructTD.is() || xExistingStructTD.is())
188*cdf0e10cSrcweir             typeError( OUSTR("Mixing polymorphic STRUCT types "
189*cdf0e10cSrcweir                              "with non-polymorphic!"), xNewTD->getName() );
190*cdf0e10cSrcweir     }
191*cdf0e10cSrcweir }
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir void checkInterface(
194*cdf0e10cSrcweir     Reference<reflection::XInterfaceTypeDescription2> const & xNewTD,
195*cdf0e10cSrcweir     Reference<reflection::XInterfaceTypeDescription2> const & xExistingTD )
196*cdf0e10cSrcweir {
197*cdf0e10cSrcweir     checkSeq( xNewTD->getBaseTypes(), xExistingTD->getBaseTypes(),
198*cdf0e10cSrcweir               xNewTD->getName() + OUSTR(", base types") );
199*cdf0e10cSrcweir     checkSeq(xNewTD->getOptionalBaseTypes(),xExistingTD->getOptionalBaseTypes(),
200*cdf0e10cSrcweir              xNewTD->getName() + OUSTR(", optional base types") );
201*cdf0e10cSrcweir     checkSeq( xNewTD->getMembers(), xExistingTD->getMembers(),
202*cdf0e10cSrcweir               xNewTD->getName() + OUSTR(", members") );
203*cdf0e10cSrcweir }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir void checkRestParam( Reference<reflection::XParameter> const & xNewParam,
206*cdf0e10cSrcweir                      Reference<reflection::XParameter> const & xExistingParam,
207*cdf0e10cSrcweir                      OUString const & context )
208*cdf0e10cSrcweir {
209*cdf0e10cSrcweir     if (xNewParam->isRestParameter() != xExistingParam->isRestParameter())
210*cdf0e10cSrcweir         typeError( OUSTR("Different ... parameters specified!"), context );
211*cdf0e10cSrcweir }
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir void checkRestParam( Reference<reflection::XMethodParameter> const &,
214*cdf0e10cSrcweir                      Reference<reflection::XMethodParameter> const &,
215*cdf0e10cSrcweir                      OUString const & )
216*cdf0e10cSrcweir {
217*cdf0e10cSrcweir }
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir template<typename T>
220*cdf0e10cSrcweir void checkParameters( Sequence< Reference<T> > const & newParams,
221*cdf0e10cSrcweir                       Sequence< Reference<T> > const & existingParams,
222*cdf0e10cSrcweir                       OUString const & context_ )
223*cdf0e10cSrcweir {
224*cdf0e10cSrcweir     sal_Int32 len = newParams.getLength();
225*cdf0e10cSrcweir     if (len != existingParams.getLength())
226*cdf0e10cSrcweir         typeError( OUSTR("Different number of parameters!"), context_ );
227*cdf0e10cSrcweir 	Reference<T> const * pNewParams = newParams.getConstArray();
228*cdf0e10cSrcweir 	Reference<T> const * pExistingParams = existingParams.getConstArray();
229*cdf0e10cSrcweir     for ( sal_Int32 pos = 0; pos < len; ++pos )
230*cdf0e10cSrcweir     {
231*cdf0e10cSrcweir         Reference<T> const & xNewParam = pNewParams[pos];
232*cdf0e10cSrcweir         Reference<T> const & xExistingParam = pExistingParams[pos];
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir         OUStringBuffer buf;
235*cdf0e10cSrcweir         buf.append( context_ );
236*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", parameter ") );
237*cdf0e10cSrcweir         buf.append( pos );
238*cdf0e10cSrcweir         OSL_ASSERT( pos == xNewParam->getPosition() &&
239*cdf0e10cSrcweir                     pos == xExistingParam->getPosition() );
240*cdf0e10cSrcweir         OUString context( buf.makeStringAndClear() );
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir         if (xNewParam->getName() != xExistingParam->getName())
243*cdf0e10cSrcweir         {
244*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Name differs: ") );
245*cdf0e10cSrcweir             buf.append( xNewParam->getName() );
246*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
247*cdf0e10cSrcweir             buf.append( xExistingParam->getName() );
248*cdf0e10cSrcweir             typeError( buf.makeStringAndClear(), context );
249*cdf0e10cSrcweir         }
250*cdf0e10cSrcweir         check( xNewParam->getType(), xExistingParam->getType(), context );
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir         if (xNewParam->isIn() != xExistingParam->isIn())
253*cdf0e10cSrcweir             typeError( OUSTR("IN attribute differs!"), context );
254*cdf0e10cSrcweir         if (xNewParam->isOut() != xExistingParam->isOut())
255*cdf0e10cSrcweir             typeError( OUSTR("OUT attribute differs!"), context );
256*cdf0e10cSrcweir         checkRestParam( xNewParam, xExistingParam, context );
257*cdf0e10cSrcweir     }
258*cdf0e10cSrcweir }
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir static void checkMethod(
261*cdf0e10cSrcweir     Reference<reflection::XInterfaceMethodTypeDescription> const & xNewTD,
262*cdf0e10cSrcweir     Reference<reflection::XInterfaceMethodTypeDescription> const & xExistingTD )
263*cdf0e10cSrcweir {
264*cdf0e10cSrcweir 	check( xNewTD->getReturnType(), xExistingTD->getReturnType(),
265*cdf0e10cSrcweir            xNewTD->getName() );
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 	if (xNewTD->isOneway() != xExistingTD->isOneway())
268*cdf0e10cSrcweir         typeError( OUSTR("Methods have differing OneWay attribute!"),
269*cdf0e10cSrcweir                    xNewTD->getName() );
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir     checkParameters( xNewTD->getParameters(), xExistingTD->getParameters(),
272*cdf0e10cSrcweir                      xNewTD->getName() );
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir     checkSeq( xNewTD->getExceptions(), xExistingTD->getExceptions(),
275*cdf0e10cSrcweir               xNewTD->getName() + OUSTR(", declared exceptions") );
276*cdf0e10cSrcweir }
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir void checkAttribute(
279*cdf0e10cSrcweir     Reference<reflection::XInterfaceAttributeTypeDescription2> const & xNewTD,
280*cdf0e10cSrcweir     Reference<reflection::XInterfaceAttributeTypeDescription2>
281*cdf0e10cSrcweir     const & xExistingTD )
282*cdf0e10cSrcweir {
283*cdf0e10cSrcweir 	if (xNewTD->isReadOnly() != xExistingTD->isReadOnly())
284*cdf0e10cSrcweir         typeError( OUSTR("ReadOnly attribute differs!"), xNewTD->getName() );
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir     check( xNewTD->getType(), xExistingTD->getType(),
287*cdf0e10cSrcweir            xNewTD->getName() + OUSTR(", attribute type") );
288*cdf0e10cSrcweir 
289*cdf0e10cSrcweir     if (xNewTD->isBound() != xExistingTD->isBound())
290*cdf0e10cSrcweir         typeError( OUSTR("Bound attribute differs!"), xNewTD->getName() );
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir     checkSeq( xNewTD->getGetExceptions(), xExistingTD->getGetExceptions(),
293*cdf0e10cSrcweir               xNewTD->getName() + OUSTR(", getter exceptions") );
294*cdf0e10cSrcweir     checkSeq( xNewTD->getSetExceptions(), xExistingTD->getSetExceptions(),
295*cdf0e10cSrcweir               xNewTD->getName() + OUSTR(", setter exceptions") );
296*cdf0e10cSrcweir }
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir void checkProperty(
299*cdf0e10cSrcweir     Reference<reflection::XPropertyTypeDescription> const & xNewTD,
300*cdf0e10cSrcweir     Reference<reflection::XPropertyTypeDescription> const & xExistingTD )
301*cdf0e10cSrcweir {
302*cdf0e10cSrcweir     if (xNewTD->getPropertyFlags() != xExistingTD->getPropertyFlags())
303*cdf0e10cSrcweir     {
304*cdf0e10cSrcweir         OUStringBuffer buf;
305*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
306*cdf0e10cSrcweir                              "Different set of property flags: { ") );
307*cdf0e10cSrcweir         buf.append( getPropertyFlagsAsString(
308*cdf0e10cSrcweir                         xNewTD->getPropertyFlags() ) );
309*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" } (new), { ") );
310*cdf0e10cSrcweir         buf.append( getPropertyFlagsAsString(
311*cdf0e10cSrcweir                         xExistingTD->getPropertyFlags() ) );
312*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" } (existing)!") );
313*cdf0e10cSrcweir         typeError( buf.makeStringAndClear(), xNewTD->getName() );
314*cdf0e10cSrcweir     }
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir     check( xNewTD->getPropertyTypeDescription(),
317*cdf0e10cSrcweir            xExistingTD->getPropertyTypeDescription(),
318*cdf0e10cSrcweir            xNewTD->getName() );
319*cdf0e10cSrcweir }
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir void checkSingleton(
322*cdf0e10cSrcweir     Reference<reflection::XSingletonTypeDescription2> const & xNewTD,
323*cdf0e10cSrcweir     Reference<reflection::XSingletonTypeDescription2> const & xExistingTD )
324*cdf0e10cSrcweir {
325*cdf0e10cSrcweir     sal_Bool ifaceBased = xNewTD->isInterfaceBased();
326*cdf0e10cSrcweir     if (ifaceBased != xExistingTD->isInterfaceBased())
327*cdf0e10cSrcweir         typeError(
328*cdf0e10cSrcweir             OUSTR("Mixing interface and NON-interface based singletons!"),
329*cdf0e10cSrcweir             xNewTD->getName() );
330*cdf0e10cSrcweir     if (ifaceBased)
331*cdf0e10cSrcweir         check( xNewTD->getInterface(), xExistingTD->getInterface(),
332*cdf0e10cSrcweir                xNewTD->getName() );
333*cdf0e10cSrcweir     else
334*cdf0e10cSrcweir         check( xNewTD->getService().get(), xExistingTD->getService().get(),
335*cdf0e10cSrcweir                xNewTD->getName() );
336*cdf0e10cSrcweir }
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir void checkService(
339*cdf0e10cSrcweir     Reference<reflection::XServiceTypeDescription2> const & xNewTD,
340*cdf0e10cSrcweir     Reference<reflection::XServiceTypeDescription2> const & xExistingTD )
341*cdf0e10cSrcweir {
342*cdf0e10cSrcweir     sal_Bool singleIfaceBased = xNewTD->isSingleInterfaceBased();
343*cdf0e10cSrcweir     if (singleIfaceBased != xExistingTD->isSingleInterfaceBased())
344*cdf0e10cSrcweir         typeError( OUSTR("Mixing interface and NON-interface based services!"),
345*cdf0e10cSrcweir                    xNewTD->getName() );
346*cdf0e10cSrcweir     if (singleIfaceBased)
347*cdf0e10cSrcweir     {
348*cdf0e10cSrcweir         check( xNewTD->getInterface(), xExistingTD->getInterface(),
349*cdf0e10cSrcweir                xNewTD->getName() );
350*cdf0e10cSrcweir         Sequence< Reference<reflection::XServiceConstructorDescription> >
351*cdf0e10cSrcweir             newCtors( xNewTD->getConstructors() );
352*cdf0e10cSrcweir         Sequence< Reference<reflection::XServiceConstructorDescription> >
353*cdf0e10cSrcweir             existingCtors( xExistingTD->getConstructors() );
354*cdf0e10cSrcweir         sal_Int32 len = newCtors.getLength();
355*cdf0e10cSrcweir         if (len != existingCtors.getLength())
356*cdf0e10cSrcweir             typeError( OUSTR("Different number of service constructors!"),
357*cdf0e10cSrcweir                        xNewTD->getName() );
358*cdf0e10cSrcweir         Reference<reflection::XServiceConstructorDescription> const *
359*cdf0e10cSrcweir             pNewCtors = newCtors.getConstArray();
360*cdf0e10cSrcweir         Reference<reflection::XServiceConstructorDescription> const *
361*cdf0e10cSrcweir             pExistingCtors = existingCtors.getConstArray();
362*cdf0e10cSrcweir         for ( sal_Int32 pos = 0; pos < len; ++pos )
363*cdf0e10cSrcweir         {
364*cdf0e10cSrcweir             Reference<reflection::XServiceConstructorDescription> const &
365*cdf0e10cSrcweir                 xNewCtor = pNewCtors[pos];
366*cdf0e10cSrcweir             Reference<reflection::XServiceConstructorDescription> const &
367*cdf0e10cSrcweir                 xExistingCtor = pExistingCtors[pos];
368*cdf0e10cSrcweir 
369*cdf0e10cSrcweir             if (xNewCtor->getName() != xExistingCtor->getName())
370*cdf0e10cSrcweir             {
371*cdf0e10cSrcweir                 OUStringBuffer buf;
372*cdf0e10cSrcweir                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
373*cdf0e10cSrcweir                                      "Different constructor names: ") );
374*cdf0e10cSrcweir                 buf.append( xNewCtor->getName() );
375*cdf0e10cSrcweir                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (new), ") );
376*cdf0e10cSrcweir                 buf.append( xExistingCtor->getName() );
377*cdf0e10cSrcweir                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (existing)!") );
378*cdf0e10cSrcweir                 typeError( buf.makeStringAndClear(), xNewTD->getName() );
379*cdf0e10cSrcweir             }
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir             OUStringBuffer buf;
382*cdf0e10cSrcweir             buf.append( xNewTD->getName() );
383*cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", constructor ") );
384*cdf0e10cSrcweir             buf.append( xNewCtor->getName() );
385*cdf0e10cSrcweir             OUString context( buf.makeStringAndClear() );
386*cdf0e10cSrcweir             checkParameters( xNewCtor->getParameters(),
387*cdf0e10cSrcweir                              xExistingCtor->getParameters(),
388*cdf0e10cSrcweir                              context );
389*cdf0e10cSrcweir             checkSeq( xNewCtor->getExceptions(), xExistingCtor->getExceptions(),
390*cdf0e10cSrcweir                       context + OUSTR(", exceptions") );
391*cdf0e10cSrcweir         }
392*cdf0e10cSrcweir     }
393*cdf0e10cSrcweir     else // old-style service descriptions:
394*cdf0e10cSrcweir     {
395*cdf0e10cSrcweir         checkSeq( xNewTD->getMandatoryServices(),
396*cdf0e10cSrcweir                   xExistingTD->getMandatoryServices(),
397*cdf0e10cSrcweir                   xNewTD->getName() + OUSTR(", mandatory services") );
398*cdf0e10cSrcweir         checkSeq( xNewTD->getOptionalServices(),
399*cdf0e10cSrcweir                   xExistingTD->getOptionalServices(),
400*cdf0e10cSrcweir                   xNewTD->getName() + OUSTR(", optional services"),
401*cdf0e10cSrcweir                   true /* optionalMode */ );
402*cdf0e10cSrcweir         checkSeq( xNewTD->getMandatoryInterfaces(),
403*cdf0e10cSrcweir                   xExistingTD->getMandatoryInterfaces(),
404*cdf0e10cSrcweir                   xNewTD->getName() + OUSTR(", mandatory interfaces") );
405*cdf0e10cSrcweir         checkSeq( xNewTD->getOptionalInterfaces(),
406*cdf0e10cSrcweir                   xExistingTD->getOptionalInterfaces(),
407*cdf0e10cSrcweir                   xNewTD->getName() + OUSTR(", optional interfaces"),
408*cdf0e10cSrcweir                   true /* optionalMode */ );
409*cdf0e10cSrcweir 
410*cdf0e10cSrcweir         Sequence< Reference<reflection::XPropertyTypeDescription> >
411*cdf0e10cSrcweir             newProperties( xNewTD->getProperties() );
412*cdf0e10cSrcweir         Sequence< Reference<reflection::XPropertyTypeDescription> >
413*cdf0e10cSrcweir             existingProperties( xExistingTD->getProperties() );
414*cdf0e10cSrcweir         checkSeq( newProperties, existingProperties,
415*cdf0e10cSrcweir                   xNewTD->getName() + OUSTR(", properties"),
416*cdf0e10cSrcweir                   true /* optionalMode */ );
417*cdf0e10cSrcweir         if (newProperties.getLength() > existingProperties.getLength())
418*cdf0e10cSrcweir         {
419*cdf0e10cSrcweir             // check whether all added properties are OPTIONAL:
420*cdf0e10cSrcweir             Reference<reflection::XPropertyTypeDescription> const *
421*cdf0e10cSrcweir                 pNewProperties = newProperties.getConstArray();
422*cdf0e10cSrcweir             for ( sal_Int32 pos = existingProperties.getLength() + 1;
423*cdf0e10cSrcweir                   pos < newProperties.getLength(); ++pos )
424*cdf0e10cSrcweir             {
425*cdf0e10cSrcweir                 if ((pNewProperties[pos]->getPropertyFlags() &
426*cdf0e10cSrcweir                      beans::PropertyAttribute::OPTIONAL) == 0)
427*cdf0e10cSrcweir                     typeError( OUSTR("New property is not OPTIONAL!"),
428*cdf0e10cSrcweir                                pNewProperties[pos]->getName() );
429*cdf0e10cSrcweir             }
430*cdf0e10cSrcweir         }
431*cdf0e10cSrcweir     }
432*cdf0e10cSrcweir }
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir }
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir namespace stoc_tdmgr {
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir void check( Reference<reflection::XTypeDescription> const & xNewTD,
439*cdf0e10cSrcweir             Reference<reflection::XTypeDescription> const & xExistingTD,
440*cdf0e10cSrcweir             OUString const & context )
441*cdf0e10cSrcweir {
442*cdf0e10cSrcweir     if (xNewTD == xExistingTD)
443*cdf0e10cSrcweir         return;
444*cdf0e10cSrcweir     if (xNewTD->getName() != xExistingTD->getName())
445*cdf0e10cSrcweir     {
446*cdf0e10cSrcweir         OUStringBuffer buf;
447*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Different type names: ") );
448*cdf0e10cSrcweir         buf.append( xNewTD->getName() );
449*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (new), ") );
450*cdf0e10cSrcweir         buf.append( xExistingTD->getName() );
451*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (existing)!") );
452*cdf0e10cSrcweir         typeError( buf.makeStringAndClear(), context );
453*cdf0e10cSrcweir     }
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir     TypeClass tc = xNewTD->getTypeClass();
456*cdf0e10cSrcweir     if (tc != xExistingTD->getTypeClass())
457*cdf0e10cSrcweir     {
458*cdf0e10cSrcweir         OUStringBuffer buf;
459*cdf0e10cSrcweir         buf.append( xNewTD->getName() );
460*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
461*cdf0e10cSrcweir                              " has different type classes: ") );
462*cdf0e10cSrcweir         buf.append( getTypeClassName( tc ) );
463*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (new), ") );
464*cdf0e10cSrcweir         buf.append( getTypeClassName( xExistingTD->getTypeClass() ) );
465*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (existing)!") );
466*cdf0e10cSrcweir         typeError( buf.makeStringAndClear(), context );
467*cdf0e10cSrcweir     }
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir     switch (tc)
470*cdf0e10cSrcweir     {
471*cdf0e10cSrcweir     case TypeClass_ENUM:
472*cdf0e10cSrcweir         checkEnum( Reference<reflection::XEnumTypeDescription>(
473*cdf0e10cSrcweir                        xNewTD, UNO_QUERY_THROW ),
474*cdf0e10cSrcweir                    Reference<reflection::XEnumTypeDescription>(
475*cdf0e10cSrcweir                        xExistingTD, UNO_QUERY_THROW ) );
476*cdf0e10cSrcweir         break;
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir     case TypeClass_TYPEDEF:
479*cdf0e10cSrcweir     case TypeClass_SEQUENCE:
480*cdf0e10cSrcweir         check( Reference<reflection::XIndirectTypeDescription>(
481*cdf0e10cSrcweir                    xNewTD, UNO_QUERY_THROW )->getReferencedType(),
482*cdf0e10cSrcweir                Reference<reflection::XIndirectTypeDescription>(
483*cdf0e10cSrcweir                    xExistingTD, UNO_QUERY_THROW )->getReferencedType() );
484*cdf0e10cSrcweir         break;
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir     case TypeClass_STRUCT:
487*cdf0e10cSrcweir     case TypeClass_EXCEPTION:
488*cdf0e10cSrcweir         checkStruct( Reference<reflection::XCompoundTypeDescription>(
489*cdf0e10cSrcweir                          xNewTD, UNO_QUERY_THROW ),
490*cdf0e10cSrcweir                      Reference<reflection::XCompoundTypeDescription>(
491*cdf0e10cSrcweir                          xExistingTD, UNO_QUERY_THROW ) );
492*cdf0e10cSrcweir         break;
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir     case TypeClass_INTERFACE:
495*cdf0e10cSrcweir         checkInterface( Reference<reflection::XInterfaceTypeDescription2>(
496*cdf0e10cSrcweir                             xNewTD, UNO_QUERY_THROW ),
497*cdf0e10cSrcweir                         Reference<reflection::XInterfaceTypeDescription2>(
498*cdf0e10cSrcweir                             xExistingTD, UNO_QUERY_THROW ) );
499*cdf0e10cSrcweir         break;
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir     case TypeClass_SERVICE:
502*cdf0e10cSrcweir         checkService( Reference<reflection::XServiceTypeDescription2>(
503*cdf0e10cSrcweir                           xNewTD, UNO_QUERY_THROW ),
504*cdf0e10cSrcweir                       Reference<reflection::XServiceTypeDescription2>(
505*cdf0e10cSrcweir                           xExistingTD, UNO_QUERY_THROW ) );
506*cdf0e10cSrcweir         break;
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir     case TypeClass_INTERFACE_METHOD:
509*cdf0e10cSrcweir         checkMethod( Reference<reflection::XInterfaceMethodTypeDescription>(
510*cdf0e10cSrcweir                          xNewTD, UNO_QUERY_THROW ),
511*cdf0e10cSrcweir                      Reference<reflection::XInterfaceMethodTypeDescription>(
512*cdf0e10cSrcweir                          xExistingTD, UNO_QUERY_THROW ) );
513*cdf0e10cSrcweir         break;
514*cdf0e10cSrcweir     case TypeClass_INTERFACE_ATTRIBUTE:
515*cdf0e10cSrcweir         checkAttribute(
516*cdf0e10cSrcweir             Reference<reflection::XInterfaceAttributeTypeDescription2>(
517*cdf0e10cSrcweir                 xNewTD, UNO_QUERY_THROW ),
518*cdf0e10cSrcweir             Reference<reflection::XInterfaceAttributeTypeDescription2>(
519*cdf0e10cSrcweir                 xExistingTD, UNO_QUERY_THROW ) );
520*cdf0e10cSrcweir         break;
521*cdf0e10cSrcweir 
522*cdf0e10cSrcweir     case TypeClass_PROPERTY:
523*cdf0e10cSrcweir         checkProperty( Reference<reflection::XPropertyTypeDescription>(
524*cdf0e10cSrcweir                            xNewTD, UNO_QUERY_THROW ),
525*cdf0e10cSrcweir                        Reference<reflection::XPropertyTypeDescription>(
526*cdf0e10cSrcweir                            xExistingTD, UNO_QUERY_THROW ) );
527*cdf0e10cSrcweir         break;
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir     case TypeClass_CONSTANT:
530*cdf0e10cSrcweir         if (Reference<reflection::XConstantTypeDescription>(
531*cdf0e10cSrcweir                 xNewTD, UNO_QUERY_THROW )->getConstantValue() !=
532*cdf0e10cSrcweir             Reference<reflection::XConstantTypeDescription>(
533*cdf0e10cSrcweir                 xExistingTD, UNO_QUERY_THROW )->getConstantValue())
534*cdf0e10cSrcweir             typeError( OUSTR("Different constant value!"), xNewTD->getName() );
535*cdf0e10cSrcweir         break;
536*cdf0e10cSrcweir     case TypeClass_CONSTANTS:
537*cdf0e10cSrcweir         checkSeq( Reference<reflection::XConstantsTypeDescription>(
538*cdf0e10cSrcweir                       xNewTD, UNO_QUERY_THROW )->getConstants(),
539*cdf0e10cSrcweir                   Reference<reflection::XConstantsTypeDescription>(
540*cdf0e10cSrcweir                       xExistingTD, UNO_QUERY_THROW )->getConstants(),
541*cdf0e10cSrcweir                   xNewTD->getName() );
542*cdf0e10cSrcweir         break;
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir     case TypeClass_SINGLETON:
545*cdf0e10cSrcweir         checkSingleton( Reference<reflection::XSingletonTypeDescription2>(
546*cdf0e10cSrcweir                             xNewTD, UNO_QUERY_THROW ),
547*cdf0e10cSrcweir                         Reference<reflection::XSingletonTypeDescription2>(
548*cdf0e10cSrcweir                             xExistingTD, UNO_QUERY_THROW ) );
549*cdf0e10cSrcweir         break;
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir     default:
552*cdf0e10cSrcweir         break;
553*cdf0e10cSrcweir     }
554*cdf0e10cSrcweir }
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir }
557