merge the formfield patch from ooo-build
[ooovba.git] / xmloff / source / xforms / xformsapi.cxx
blobb7df90967976108a5c9cf1baa9b051642d2796dd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xformsapi.cxx,v $
10 * $Revision: 1.9 $
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>
54 using rtl::OUString;
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 ),
79 UNO_QUERY_THROW );
80 DBG_ASSERT( xModel.is(), "can't create model" );
82 return xModel;
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 );
103 if( xSupplier.is() )
105 Reference<XNameContainer> xForms = xSupplier->getXForms();
106 if( xForms.is() )
108 OUString sName;
109 xModel->getPropertyValue( OUSTRING("ID")) >>= sName;
110 xForms->insertByName( sName, makeAny( xModel ) );
111 bSuccess = true;
115 catch( const Exception& )
117 ; // no success!
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,
127 bool bBinding )
129 // find binding by iterating over all models, and look for the
130 // given binding ID
132 Reference<XPropertySet> xRet;
135 // get supplier
136 Reference<XFormsSupplier> xSupplier( xDocument, UNO_QUERY );
137 if( xSupplier.is() )
139 // get XForms models
140 Reference<XNameContainer> xForms = xSupplier->getXForms();
141 if( xForms.is() )
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 );
151 if( xModel.is() )
153 // ask model for bindings
154 Reference<XNameAccess> xBindings(
155 bBinding
156 ? xModel->getBindings()
157 : xModel->getSubmissions(),
158 UNO_QUERY_THROW );
160 // finally, ask binding for name
161 if( xBindings->hasByName( rBindingID ) )
162 xRet.set( xBindings->getByName( rBindingID ),
163 UNO_QUERY );
169 catch( const Exception& )
171 ; // no success!
174 // TODO: if (!xRet.is()) rImport.SetError(...);
176 return xRet;
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,
195 const Any rAny )
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 );
207 if( xSupplier.is() )
209 Reference<XNameContainer> xForms = xSupplier->getXForms();
210 if( xForms.is() )
212 Sequence<OUString> aNames = xForms->getElementNames();
213 if( aNames.getLength() > 0 )
214 xRet.set( xForms->getByName( aNames[0] ), UNO_QUERY );
218 catch( const Exception& )
220 ; // no success!
223 return xRet;
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 ),
241 XML_TOKEN_MAP_END
244 sal_uInt16 lcl_getTypeClass(
245 const Reference<XDataTypeRepository>&
246 #ifdef DBG_UTIL
247 xRepository
248 #endif
250 const SvXMLNamespaceMap& rNamespaceMap,
251 const OUString& rXMLName )
253 // translate name into token for local name
254 OUString sLocalName;
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");
264 switch( mnToken )
266 case XML_STRING:
267 nTypeClass = com::sun::star::xsd::DataTypeClass::STRING;
268 break;
269 case XML_ANYURI:
270 nTypeClass = com::sun::star::xsd::DataTypeClass::anyURI;
271 break;
272 case XML_DECIMAL:
273 nTypeClass = com::sun::star::xsd::DataTypeClass::DECIMAL;
274 break;
275 case XML_DOUBLE:
276 nTypeClass = com::sun::star::xsd::DataTypeClass::DOUBLE;
277 break;
278 case XML_FLOAT:
279 nTypeClass = com::sun::star::xsd::DataTypeClass::FLOAT;
280 break;
281 case XML_BOOLEAN:
282 nTypeClass = com::sun::star::xsd::DataTypeClass::BOOLEAN;
283 break;
284 case XML_DATETIME_XSD:
285 nTypeClass = com::sun::star::xsd::DataTypeClass::DATETIME;
286 break;
287 case XML_DATE:
288 nTypeClass = com::sun::star::xsd::DataTypeClass::DATE;
289 break;
290 case XML_TIME:
291 nTypeClass = com::sun::star::xsd::DataTypeClass::TIME;
292 break;
293 case XML_YEAR:
294 nTypeClass = com::sun::star::xsd::DataTypeClass::gYear;
295 break;
296 case XML_DAY:
297 nTypeClass = com::sun::star::xsd::DataTypeClass::gDay;
298 break;
299 case XML_MONTH:
300 nTypeClass = com::sun::star::xsd::DataTypeClass::gMonth;
301 break;
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;
315 return nTypeClass;
319 rtl::OUString lcl_getTypeName(
320 const Reference<XDataTypeRepository>& xRepository,
321 const SvXMLNamespaceMap& rNamespaceMap,
322 const OUString& rXMLName )
324 OUString sLocalName;
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 )
329 ? rXMLName
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;
341 sTypeName =
342 xRepository->getBasicDataType(
343 lcl_getTypeClass( xRepository, rNamespaceMap, rXMLName ) )
344 ->getName();
346 catch( const Exception& )
348 DBG_ERROR( "exception during type creation" );
350 return sTypeName;