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