1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xformsapi.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
34 #include "xformsapi.hxx"
36 #include <com/sun/star/uno/Reference.hxx>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/container/XNameAccess.hpp>
40 #include <com/sun/star/xforms/XFormsSupplier.hpp>
41 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
42 #include <com/sun/star/xforms/XModel.hpp>
43 #include <com/sun/star/container/XNameContainer.hpp>
44 #include <com/sun/star/xsd/DataTypeClass.hpp>
46 #include <unotools/processfactory.hxx>
47 #include <tools/debug.hxx>
49 #include <xmloff/xmltoken.hxx>
50 #include <xmloff/nmspmap.hxx>
51 #include <xmlnmspe.hxx>
52 #include <xmloff/xmltkmap.hxx>
55 using com::sun::star::uno::Reference
;
56 using com::sun::star::uno::Sequence
;
57 using com::sun::star::uno::UNO_QUERY
;
58 using com::sun::star::uno::UNO_QUERY_THROW
;
59 using com::sun::star::beans::XPropertySet
;
60 using com::sun::star::container::XNameAccess
;
61 using com::sun::star::lang::XMultiServiceFactory
;
62 using com::sun::star::xforms::XFormsSupplier
;
63 using com::sun::star::xforms::XDataTypeRepository
;
64 using com::sun::star::container::XNameContainer
;
65 using utl::getProcessServiceFactory
;
66 using com::sun::star::uno::makeAny
;
67 using com::sun::star::uno::Any
;
68 using com::sun::star::uno::Exception
;
70 using namespace com::sun::star
;
71 using namespace xmloff::token
;
73 Reference
<XPropertySet
> lcl_createPropertySet( const OUString
& rServiceName
)
75 Reference
<XMultiServiceFactory
> xFactory
= getProcessServiceFactory();
76 DBG_ASSERT( xFactory
.is(), "can't get service factory" );
78 Reference
<XPropertySet
> xModel( xFactory
->createInstance( rServiceName
),
80 DBG_ASSERT( xModel
.is(), "can't create model" );
85 Reference
<XPropertySet
> lcl_createXFormsModel()
87 return lcl_createPropertySet( OUSTRING( "com.sun.star.xforms.Model" ) );
90 Reference
<XPropertySet
> lcl_createXFormsBinding()
92 return lcl_createPropertySet( OUSTRING( "com.sun.star.xforms.Binding" ) );
95 void lcl_addXFormsModel(
96 const Reference
<frame::XModel
>& xDocument
,
97 const Reference
<XPropertySet
>& xModel
)
99 bool bSuccess
= false;
102 Reference
<XFormsSupplier
> xSupplier( xDocument
, UNO_QUERY
);
105 Reference
<XNameContainer
> xForms
= xSupplier
->getXForms();
109 xModel
->getPropertyValue( OUSTRING("ID")) >>= sName
;
110 xForms
->insertByName( sName
, makeAny( xModel
) );
115 catch( const Exception
& )
120 // TODO: implement proper error handling
121 DBG_ASSERT( bSuccess
, "can't import model" );
124 Reference
<XPropertySet
> lcl_findXFormsBindingOrSubmission(
125 Reference
<frame::XModel
>& xDocument
,
126 const rtl::OUString
& rBindingID
,
129 // find binding by iterating over all models, and look for the
132 Reference
<XPropertySet
> xRet
;
136 Reference
<XFormsSupplier
> xSupplier( xDocument
, UNO_QUERY
);
140 Reference
<XNameContainer
> xForms
= xSupplier
->getXForms();
143 // iterate over all models
144 Sequence
<OUString
> aNames
= xForms
->getElementNames();
145 const OUString
* pNames
= aNames
.getConstArray();
146 sal_Int32 nNames
= aNames
.getLength();
147 for( sal_Int32 n
= 0; (n
< nNames
) && !xRet
.is(); n
++ )
149 Reference
<xforms::XModel
> xModel(
150 xForms
->getByName( pNames
[n
] ), UNO_QUERY
);
153 // ask model for bindings
154 Reference
<XNameAccess
> xBindings(
156 ? xModel
->getBindings()
157 : xModel
->getSubmissions(),
160 // finally, ask binding for name
161 if( xBindings
->hasByName( rBindingID
) )
162 xRet
.set( xBindings
->getByName( rBindingID
),
169 catch( const Exception
& )
174 // TODO: if (!xRet.is()) rImport.SetError(...);
179 Reference
<XPropertySet
> lcl_findXFormsBinding(
180 Reference
<frame::XModel
>& xDocument
,
181 const rtl::OUString
& rBindingID
)
183 return lcl_findXFormsBindingOrSubmission( xDocument
, rBindingID
, true );
186 Reference
<XPropertySet
> lcl_findXFormsSubmission(
187 Reference
<frame::XModel
>& xDocument
,
188 const rtl::OUString
& rBindingID
)
190 return lcl_findXFormsBindingOrSubmission( xDocument
, rBindingID
, false );
193 void lcl_setValue( Reference
<XPropertySet
>& xPropertySet
,
194 const OUString
& rName
,
197 xPropertySet
->setPropertyValue( rName
, rAny
);
201 Reference
<XPropertySet
> lcl_getXFormsModel( const Reference
<frame::XModel
>& xDoc
)
203 Reference
<XPropertySet
> xRet
;
206 Reference
<XFormsSupplier
> xSupplier( xDoc
, UNO_QUERY
);
209 Reference
<XNameContainer
> xForms
= xSupplier
->getXForms();
212 Sequence
<OUString
> aNames
= xForms
->getElementNames();
213 if( aNames
.getLength() > 0 )
214 xRet
.set( xForms
->getByName( aNames
[0] ), UNO_QUERY
);
218 catch( const Exception
& )
226 #define TOKEN_MAP_ENTRY(NAMESPACE,TOKEN) { XML_NAMESPACE_##NAMESPACE, xmloff::token::XML_##TOKEN, xmloff::token::XML_##TOKEN }
227 static SvXMLTokenMapEntry aTypes
[] =
229 TOKEN_MAP_ENTRY( XSD
, STRING
),
230 TOKEN_MAP_ENTRY( XSD
, DECIMAL
),
231 TOKEN_MAP_ENTRY( XSD
, DOUBLE
),
232 TOKEN_MAP_ENTRY( XSD
, FLOAT
),
233 TOKEN_MAP_ENTRY( XSD
, BOOLEAN
),
234 TOKEN_MAP_ENTRY( XSD
, ANYURI
),
235 TOKEN_MAP_ENTRY( XSD
, DATETIME_XSD
),
236 TOKEN_MAP_ENTRY( XSD
, DATE
),
237 TOKEN_MAP_ENTRY( XSD
, TIME
),
238 TOKEN_MAP_ENTRY( XSD
, YEAR
),
239 TOKEN_MAP_ENTRY( XSD
, MONTH
),
240 TOKEN_MAP_ENTRY( XSD
, DAY
),
244 sal_uInt16
lcl_getTypeClass(
245 const Reference
<XDataTypeRepository
>&
250 const SvXMLNamespaceMap
& rNamespaceMap
,
251 const OUString
& rXMLName
)
253 // translate name into token for local name
255 sal_uInt16 nPrefix
= rNamespaceMap
.GetKeyByAttrName(rXMLName
, &sLocalName
);
256 SvXMLTokenMap
aMap( aTypes
);
257 sal_uInt16 mnToken
= aMap
.Get( nPrefix
, sLocalName
);
259 sal_uInt16 nTypeClass
= com::sun::star::xsd::DataTypeClass::STRING
;
260 if( mnToken
!= XML_TOK_UNKNOWN
)
262 // we found an XSD name: then get the proper API name for it
263 DBG_ASSERT( xRepository
.is(), "can't find type without repository");
267 nTypeClass
= com::sun::star::xsd::DataTypeClass::STRING
;
270 nTypeClass
= com::sun::star::xsd::DataTypeClass::anyURI
;
273 nTypeClass
= com::sun::star::xsd::DataTypeClass::DECIMAL
;
276 nTypeClass
= com::sun::star::xsd::DataTypeClass::DOUBLE
;
279 nTypeClass
= com::sun::star::xsd::DataTypeClass::FLOAT
;
282 nTypeClass
= com::sun::star::xsd::DataTypeClass::BOOLEAN
;
284 case XML_DATETIME_XSD
:
285 nTypeClass
= com::sun::star::xsd::DataTypeClass::DATETIME
;
288 nTypeClass
= com::sun::star::xsd::DataTypeClass::DATE
;
291 nTypeClass
= com::sun::star::xsd::DataTypeClass::TIME
;
294 nTypeClass
= com::sun::star::xsd::DataTypeClass::gYear
;
297 nTypeClass
= com::sun::star::xsd::DataTypeClass::gDay
;
300 nTypeClass
= com::sun::star::xsd::DataTypeClass::gMonth
;
303 /* data types not yet supported:
304 nTypeClass = com::sun::star::xsd::DataTypeClass::DURATION;
305 nTypeClass = com::sun::star::xsd::DataTypeClass::gYearMonth;
306 nTypeClass = com::sun::star::xsd::DataTypeClass::gMonthDay;
307 nTypeClass = com::sun::star::xsd::DataTypeClass::hexBinary;
308 nTypeClass = com::sun::star::xsd::DataTypeClass::base64Binary;
309 nTypeClass = com::sun::star::xsd::DataTypeClass::QName;
310 nTypeClass = com::sun::star::xsd::DataTypeClass::NOTATION;
319 rtl::OUString
lcl_getTypeName(
320 const Reference
<XDataTypeRepository
>& xRepository
,
321 const SvXMLNamespaceMap
& rNamespaceMap
,
322 const OUString
& rXMLName
)
325 sal_uInt16 nPrefix
= rNamespaceMap
.GetKeyByAttrName(rXMLName
, &sLocalName
);
326 SvXMLTokenMap
aMap( aTypes
);
327 sal_uInt16 mnToken
= aMap
.Get( nPrefix
, sLocalName
);
328 return ( mnToken
== XML_TOK_UNKNOWN
)
330 : lcl_getBasicTypeName( xRepository
, rNamespaceMap
, rXMLName
);
333 rtl::OUString
lcl_getBasicTypeName(
334 const Reference
<XDataTypeRepository
>& xRepository
,
335 const SvXMLNamespaceMap
& rNamespaceMap
,
336 const OUString
& rXMLName
)
338 OUString sTypeName
= rXMLName
;
342 xRepository
->getBasicDataType(
343 lcl_getTypeClass( xRepository
, rNamespaceMap
, rXMLName
) )
346 catch( const Exception
& )
348 DBG_ERROR( "exception during type creation" );