xref: /trunk/main/xmloff/source/xforms/xformsapi.cxx (revision cdf0e10c)
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_xmloff.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "xformsapi.hxx"
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <com/sun/star/uno/Reference.hxx>
34*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/xforms/XFormsSupplier.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/xforms/XDataTypeRepository.hpp>
39*cdf0e10cSrcweir #include <com/sun/star/xforms/XModel.hpp>
40*cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp>
41*cdf0e10cSrcweir #include <com/sun/star/xsd/DataTypeClass.hpp>
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir #include <unotools/processfactory.hxx>
44*cdf0e10cSrcweir #include <tools/debug.hxx>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #include <xmloff/xmltoken.hxx>
47*cdf0e10cSrcweir #include <xmloff/nmspmap.hxx>
48*cdf0e10cSrcweir #include <xmloff/xmlnmspe.hxx>
49*cdf0e10cSrcweir #include <xmloff/xmltkmap.hxx>
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir using rtl::OUString;
52*cdf0e10cSrcweir using com::sun::star::uno::Reference;
53*cdf0e10cSrcweir using com::sun::star::uno::Sequence;
54*cdf0e10cSrcweir using com::sun::star::uno::UNO_QUERY;
55*cdf0e10cSrcweir using com::sun::star::uno::UNO_QUERY_THROW;
56*cdf0e10cSrcweir using com::sun::star::beans::XPropertySet;
57*cdf0e10cSrcweir using com::sun::star::container::XNameAccess;
58*cdf0e10cSrcweir using com::sun::star::lang::XMultiServiceFactory;
59*cdf0e10cSrcweir using com::sun::star::xforms::XFormsSupplier;
60*cdf0e10cSrcweir using com::sun::star::xforms::XDataTypeRepository;
61*cdf0e10cSrcweir using com::sun::star::container::XNameContainer;
62*cdf0e10cSrcweir using utl::getProcessServiceFactory;
63*cdf0e10cSrcweir using com::sun::star::uno::makeAny;
64*cdf0e10cSrcweir using com::sun::star::uno::Any;
65*cdf0e10cSrcweir using com::sun::star::uno::Exception;
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir using namespace com::sun::star;
68*cdf0e10cSrcweir using namespace xmloff::token;
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir Reference<XPropertySet> lcl_createPropertySet( const OUString& rServiceName )
71*cdf0e10cSrcweir {
72*cdf0e10cSrcweir     Reference<XMultiServiceFactory> xFactory = getProcessServiceFactory();
73*cdf0e10cSrcweir     DBG_ASSERT( xFactory.is(), "can't get service factory" );
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir     Reference<XPropertySet> xModel( xFactory->createInstance( rServiceName ),
76*cdf0e10cSrcweir                                     UNO_QUERY_THROW );
77*cdf0e10cSrcweir     DBG_ASSERT( xModel.is(), "can't create model" );
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir     return xModel;
80*cdf0e10cSrcweir }
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir Reference<XPropertySet> lcl_createXFormsModel()
83*cdf0e10cSrcweir {
84*cdf0e10cSrcweir     return lcl_createPropertySet( OUSTRING( "com.sun.star.xforms.Model" ) );
85*cdf0e10cSrcweir }
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir Reference<XPropertySet> lcl_createXFormsBinding()
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir     return lcl_createPropertySet( OUSTRING( "com.sun.star.xforms.Binding" ) );
90*cdf0e10cSrcweir }
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir void lcl_addXFormsModel(
93*cdf0e10cSrcweir     const Reference<frame::XModel>& xDocument,
94*cdf0e10cSrcweir     const Reference<XPropertySet>& xModel )
95*cdf0e10cSrcweir {
96*cdf0e10cSrcweir     bool bSuccess = false;
97*cdf0e10cSrcweir     try
98*cdf0e10cSrcweir     {
99*cdf0e10cSrcweir         Reference<XFormsSupplier> xSupplier( xDocument, UNO_QUERY );
100*cdf0e10cSrcweir         if( xSupplier.is() )
101*cdf0e10cSrcweir         {
102*cdf0e10cSrcweir             Reference<XNameContainer> xForms = xSupplier->getXForms();
103*cdf0e10cSrcweir             if( xForms.is() )
104*cdf0e10cSrcweir             {
105*cdf0e10cSrcweir                 OUString sName;
106*cdf0e10cSrcweir                 xModel->getPropertyValue( OUSTRING("ID")) >>= sName;
107*cdf0e10cSrcweir                 xForms->insertByName( sName, makeAny( xModel ) );
108*cdf0e10cSrcweir                 bSuccess = true;
109*cdf0e10cSrcweir             }
110*cdf0e10cSrcweir         }
111*cdf0e10cSrcweir     }
112*cdf0e10cSrcweir     catch( const Exception& )
113*cdf0e10cSrcweir     {
114*cdf0e10cSrcweir         ; // no success!
115*cdf0e10cSrcweir     }
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir     // TODO: implement proper error handling
118*cdf0e10cSrcweir     DBG_ASSERT( bSuccess, "can't import model" );
119*cdf0e10cSrcweir }
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir Reference<XPropertySet> lcl_findXFormsBindingOrSubmission(
122*cdf0e10cSrcweir     Reference<frame::XModel>& xDocument,
123*cdf0e10cSrcweir     const rtl::OUString& rBindingID,
124*cdf0e10cSrcweir     bool bBinding )
125*cdf0e10cSrcweir {
126*cdf0e10cSrcweir     // find binding by iterating over all models, and look for the
127*cdf0e10cSrcweir     // given binding ID
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir     Reference<XPropertySet> xRet;
130*cdf0e10cSrcweir     try
131*cdf0e10cSrcweir     {
132*cdf0e10cSrcweir         // get supplier
133*cdf0e10cSrcweir         Reference<XFormsSupplier> xSupplier( xDocument, UNO_QUERY );
134*cdf0e10cSrcweir         if( xSupplier.is() )
135*cdf0e10cSrcweir         {
136*cdf0e10cSrcweir             // get XForms models
137*cdf0e10cSrcweir             Reference<XNameContainer> xForms = xSupplier->getXForms();
138*cdf0e10cSrcweir             if( xForms.is() )
139*cdf0e10cSrcweir             {
140*cdf0e10cSrcweir                 // iterate over all models
141*cdf0e10cSrcweir                 Sequence<OUString> aNames = xForms->getElementNames();
142*cdf0e10cSrcweir                 const OUString* pNames = aNames.getConstArray();
143*cdf0e10cSrcweir                 sal_Int32 nNames = aNames.getLength();
144*cdf0e10cSrcweir                 for( sal_Int32 n = 0; (n < nNames) && !xRet.is(); n++ )
145*cdf0e10cSrcweir                 {
146*cdf0e10cSrcweir                     Reference<xforms::XModel> xModel(
147*cdf0e10cSrcweir                         xForms->getByName( pNames[n] ), UNO_QUERY );
148*cdf0e10cSrcweir                     if( xModel.is() )
149*cdf0e10cSrcweir                     {
150*cdf0e10cSrcweir                         // ask model for bindings
151*cdf0e10cSrcweir                         Reference<XNameAccess> xBindings(
152*cdf0e10cSrcweir                             bBinding
153*cdf0e10cSrcweir                                 ? xModel->getBindings()
154*cdf0e10cSrcweir                                 : xModel->getSubmissions(),
155*cdf0e10cSrcweir                             UNO_QUERY_THROW );
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir                         // finally, ask binding for name
158*cdf0e10cSrcweir                         if( xBindings->hasByName( rBindingID ) )
159*cdf0e10cSrcweir                             xRet.set( xBindings->getByName( rBindingID ),
160*cdf0e10cSrcweir                                       UNO_QUERY );
161*cdf0e10cSrcweir                     }
162*cdf0e10cSrcweir                 }
163*cdf0e10cSrcweir             }
164*cdf0e10cSrcweir         }
165*cdf0e10cSrcweir     }
166*cdf0e10cSrcweir     catch( const Exception& )
167*cdf0e10cSrcweir     {
168*cdf0e10cSrcweir         ; // no success!
169*cdf0e10cSrcweir     }
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir     // TODO: if (!xRet.is()) rImport.SetError(...);
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir     return xRet;
174*cdf0e10cSrcweir }
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir Reference<XPropertySet> lcl_findXFormsBinding(
177*cdf0e10cSrcweir     Reference<frame::XModel>& xDocument,
178*cdf0e10cSrcweir     const rtl::OUString& rBindingID )
179*cdf0e10cSrcweir {
180*cdf0e10cSrcweir     return lcl_findXFormsBindingOrSubmission( xDocument, rBindingID, true );
181*cdf0e10cSrcweir }
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir Reference<XPropertySet> lcl_findXFormsSubmission(
184*cdf0e10cSrcweir     Reference<frame::XModel>& xDocument,
185*cdf0e10cSrcweir     const rtl::OUString& rBindingID )
186*cdf0e10cSrcweir {
187*cdf0e10cSrcweir     return lcl_findXFormsBindingOrSubmission( xDocument, rBindingID, false );
188*cdf0e10cSrcweir }
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir void lcl_setValue( Reference<XPropertySet>& xPropertySet,
191*cdf0e10cSrcweir                    const OUString& rName,
192*cdf0e10cSrcweir                    const Any rAny )
193*cdf0e10cSrcweir {
194*cdf0e10cSrcweir     xPropertySet->setPropertyValue( rName, rAny );
195*cdf0e10cSrcweir }
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir Reference<XPropertySet> lcl_getXFormsModel( const Reference<frame::XModel>& xDoc )
199*cdf0e10cSrcweir {
200*cdf0e10cSrcweir     Reference<XPropertySet> xRet;
201*cdf0e10cSrcweir     try
202*cdf0e10cSrcweir     {
203*cdf0e10cSrcweir         Reference<XFormsSupplier> xSupplier( xDoc, UNO_QUERY );
204*cdf0e10cSrcweir         if( xSupplier.is() )
205*cdf0e10cSrcweir         {
206*cdf0e10cSrcweir             Reference<XNameContainer> xForms = xSupplier->getXForms();
207*cdf0e10cSrcweir             if( xForms.is() )
208*cdf0e10cSrcweir             {
209*cdf0e10cSrcweir                 Sequence<OUString> aNames = xForms->getElementNames();
210*cdf0e10cSrcweir                 if( aNames.getLength() > 0 )
211*cdf0e10cSrcweir                     xRet.set( xForms->getByName( aNames[0] ), UNO_QUERY );
212*cdf0e10cSrcweir             }
213*cdf0e10cSrcweir         }
214*cdf0e10cSrcweir     }
215*cdf0e10cSrcweir     catch( const Exception& )
216*cdf0e10cSrcweir     {
217*cdf0e10cSrcweir         ; // no success!
218*cdf0e10cSrcweir     }
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir     return xRet;
221*cdf0e10cSrcweir }
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir #define TOKEN_MAP_ENTRY(NAMESPACE,TOKEN) { XML_NAMESPACE_##NAMESPACE, xmloff::token::XML_##TOKEN, xmloff::token::XML_##TOKEN }
224*cdf0e10cSrcweir static SvXMLTokenMapEntry aTypes[] =
225*cdf0e10cSrcweir {
226*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, STRING  ),
227*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, DECIMAL ),
228*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, DOUBLE ),
229*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, FLOAT ),
230*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, BOOLEAN ),
231*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, ANYURI ),
232*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, DATETIME_XSD ),
233*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, DATE ),
234*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, TIME ),
235*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, YEAR ),
236*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, MONTH ),
237*cdf0e10cSrcweir     TOKEN_MAP_ENTRY( XSD, DAY ),
238*cdf0e10cSrcweir     XML_TOKEN_MAP_END
239*cdf0e10cSrcweir };
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir sal_uInt16 lcl_getTypeClass(
242*cdf0e10cSrcweir     const Reference<XDataTypeRepository>&
243*cdf0e10cSrcweir     #ifdef DBG_UTIL
244*cdf0e10cSrcweir     xRepository
245*cdf0e10cSrcweir     #endif
246*cdf0e10cSrcweir     ,
247*cdf0e10cSrcweir     const SvXMLNamespaceMap& rNamespaceMap,
248*cdf0e10cSrcweir     const OUString& rXMLName )
249*cdf0e10cSrcweir {
250*cdf0e10cSrcweir     // translate name into token for local name
251*cdf0e10cSrcweir     OUString sLocalName;
252*cdf0e10cSrcweir     sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName(rXMLName, &sLocalName);
253*cdf0e10cSrcweir     SvXMLTokenMap aMap( aTypes );
254*cdf0e10cSrcweir     sal_uInt16 mnToken = aMap.Get( nPrefix, sLocalName );
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir     sal_uInt16 nTypeClass = com::sun::star::xsd::DataTypeClass::STRING;
257*cdf0e10cSrcweir     if( mnToken != XML_TOK_UNKNOWN )
258*cdf0e10cSrcweir     {
259*cdf0e10cSrcweir         // we found an XSD name: then get the proper API name for it
260*cdf0e10cSrcweir         DBG_ASSERT( xRepository.is(), "can't find type without repository");
261*cdf0e10cSrcweir         switch( mnToken )
262*cdf0e10cSrcweir         {
263*cdf0e10cSrcweir         case XML_STRING:
264*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::STRING;
265*cdf0e10cSrcweir             break;
266*cdf0e10cSrcweir         case XML_ANYURI:
267*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::anyURI;
268*cdf0e10cSrcweir             break;
269*cdf0e10cSrcweir         case XML_DECIMAL:
270*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::DECIMAL;
271*cdf0e10cSrcweir             break;
272*cdf0e10cSrcweir         case XML_DOUBLE:
273*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::DOUBLE;
274*cdf0e10cSrcweir             break;
275*cdf0e10cSrcweir         case XML_FLOAT:
276*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::FLOAT;
277*cdf0e10cSrcweir             break;
278*cdf0e10cSrcweir         case XML_BOOLEAN:
279*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::BOOLEAN;
280*cdf0e10cSrcweir             break;
281*cdf0e10cSrcweir         case XML_DATETIME_XSD:
282*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::DATETIME;
283*cdf0e10cSrcweir             break;
284*cdf0e10cSrcweir         case XML_DATE:
285*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::DATE;
286*cdf0e10cSrcweir             break;
287*cdf0e10cSrcweir         case XML_TIME:
288*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::TIME;
289*cdf0e10cSrcweir             break;
290*cdf0e10cSrcweir         case XML_YEAR:
291*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::gYear;
292*cdf0e10cSrcweir             break;
293*cdf0e10cSrcweir         case XML_DAY:
294*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::gDay;
295*cdf0e10cSrcweir             break;
296*cdf0e10cSrcweir         case XML_MONTH:
297*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::gMonth;
298*cdf0e10cSrcweir             break;
299*cdf0e10cSrcweir 
300*cdf0e10cSrcweir             /* data types not yet supported:
301*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::DURATION;
302*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::gYearMonth;
303*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::gMonthDay;
304*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::hexBinary;
305*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::base64Binary;
306*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::QName;
307*cdf0e10cSrcweir             nTypeClass = com::sun::star::xsd::DataTypeClass::NOTATION;
308*cdf0e10cSrcweir             */
309*cdf0e10cSrcweir         }
310*cdf0e10cSrcweir     }
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir     return nTypeClass;
313*cdf0e10cSrcweir }
314*cdf0e10cSrcweir 
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir rtl::OUString lcl_getTypeName(
317*cdf0e10cSrcweir     const Reference<XDataTypeRepository>& xRepository,
318*cdf0e10cSrcweir     const SvXMLNamespaceMap& rNamespaceMap,
319*cdf0e10cSrcweir     const OUString& rXMLName )
320*cdf0e10cSrcweir {
321*cdf0e10cSrcweir     OUString sLocalName;
322*cdf0e10cSrcweir     sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName(rXMLName, &sLocalName);
323*cdf0e10cSrcweir     SvXMLTokenMap aMap( aTypes );
324*cdf0e10cSrcweir     sal_uInt16 mnToken = aMap.Get( nPrefix, sLocalName );
325*cdf0e10cSrcweir     return ( mnToken == XML_TOK_UNKNOWN )
326*cdf0e10cSrcweir         ? rXMLName
327*cdf0e10cSrcweir         : lcl_getBasicTypeName( xRepository, rNamespaceMap, rXMLName );
328*cdf0e10cSrcweir }
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir rtl::OUString lcl_getBasicTypeName(
331*cdf0e10cSrcweir     const Reference<XDataTypeRepository>& xRepository,
332*cdf0e10cSrcweir     const SvXMLNamespaceMap& rNamespaceMap,
333*cdf0e10cSrcweir     const OUString& rXMLName )
334*cdf0e10cSrcweir {
335*cdf0e10cSrcweir     OUString sTypeName = rXMLName;
336*cdf0e10cSrcweir     try
337*cdf0e10cSrcweir     {
338*cdf0e10cSrcweir         sTypeName =
339*cdf0e10cSrcweir             xRepository->getBasicDataType(
340*cdf0e10cSrcweir                 lcl_getTypeClass( xRepository, rNamespaceMap, rXMLName ) )
341*cdf0e10cSrcweir             ->getName();
342*cdf0e10cSrcweir     }
343*cdf0e10cSrcweir     catch( const Exception& )
344*cdf0e10cSrcweir     {
345*cdf0e10cSrcweir         DBG_ERROR( "exception during type creation" );
346*cdf0e10cSrcweir     }
347*cdf0e10cSrcweir     return sTypeName;
348*cdf0e10cSrcweir }
349