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