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 #include "precompiled_configmgr.hxx" 29 #include "sal/config.h" 30 31 #include "boost/noncopyable.hpp" 32 #include "com/sun/star/uno/Any.hxx" 33 #include "com/sun/star/uno/Reference.hxx" 34 #include "com/sun/star/uno/RuntimeException.hpp" 35 #include "com/sun/star/uno/Sequence.hxx" 36 #include "com/sun/star/uno/XInterface.hpp" 37 #include "osl/diagnose.h" 38 #include "osl/file.h" 39 #include "osl/file.hxx" 40 #include "rtl/string.h" 41 #include "rtl/string.hxx" 42 #include "rtl/textcvt.h" 43 #include "rtl/textenc.h" 44 #include "rtl/ustrbuf.hxx" 45 #include "rtl/ustring.h" 46 #include "rtl/ustring.hxx" 47 #include "sal/types.h" 48 #include "xmlreader/span.hxx" 49 50 #include "data.hxx" 51 #include "groupnode.hxx" 52 #include "localizedpropertynode.hxx" 53 #include "localizedvaluenode.hxx" 54 #include "modifications.hxx" 55 #include "node.hxx" 56 #include "nodemap.hxx" 57 #include "propertynode.hxx" 58 #include "type.hxx" 59 #include "writemodfile.hxx" 60 61 namespace configmgr { 62 63 class Components; 64 65 namespace { 66 67 namespace css = com::sun::star; 68 69 rtl::OString convertToUtf8( 70 rtl::OUString const & text, sal_Int32 offset, sal_Int32 length) 71 { 72 OSL_ASSERT( 73 offset <= text.getLength() && text.getLength() - offset >= length); 74 rtl::OString s; 75 if (!rtl_convertUStringToString( 76 &s.pData, text.pData->buffer + offset, length, 77 RTL_TEXTENCODING_UTF8, 78 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | 79 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) 80 { 81 throw css::uno::RuntimeException( 82 rtl::OUString( 83 RTL_CONSTASCII_USTRINGPARAM("cannot convert to UTF-8")), 84 css::uno::Reference< css::uno::XInterface >()); 85 } 86 return s; 87 } 88 89 struct TempFile: public boost::noncopyable { 90 rtl::OUString url; 91 oslFileHandle handle; 92 bool closed; 93 94 TempFile(): handle(0), closed(false) {} 95 96 ~TempFile(); 97 }; 98 99 TempFile::~TempFile() { 100 if (handle != 0) { 101 if (!closed) { 102 oslFileError e = osl_closeFile(handle); 103 if (e != osl_File_E_None) { 104 OSL_TRACE( 105 "osl_closeFile failed with %ld", static_cast< long >(e)); 106 } 107 } 108 osl::FileBase::RC e = osl::File::remove(url); 109 if (e != osl::FileBase::E_None) { 110 OSL_TRACE("osl_removeFile failed with %ld", static_cast< long >(e)); 111 } 112 } 113 } 114 115 void writeData(oslFileHandle handle, char const * begin, sal_Int32 length) { 116 OSL_ASSERT(length >= 0); 117 sal_uInt64 n; 118 if ((osl_writeFile(handle, begin, static_cast< sal_uInt32 >(length), &n) != 119 osl_File_E_None) || 120 n != static_cast< sal_uInt32 >(length)) 121 { 122 throw css::uno::RuntimeException( 123 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("write failure")), 124 css::uno::Reference< css::uno::XInterface >()); 125 } 126 } 127 128 void writeData(oslFileHandle handle, rtl::OString const & text) { 129 writeData(handle, text.getStr(), text.getLength()); 130 } 131 132 void writeAttributeValue(oslFileHandle handle, rtl::OUString const & value) { 133 sal_Int32 i = 0; 134 sal_Int32 j = i; 135 for (; j < value.getLength(); ++j) { 136 OSL_ASSERT( 137 value[j] == 0x0009 || value[j] == 0x000A || value[j] == 0x000D || 138 (value[j] >= 0x0020 && value[j] != 0xFFFE && value[j] != 0xFFFF)); 139 switch(value[j]) { 140 case '\x09': 141 writeData(handle, convertToUtf8(value, i, j - i)); 142 writeData(handle, RTL_CONSTASCII_STRINGPARAM("	")); 143 i = j + 1; 144 break; 145 case '\x0A': 146 writeData(handle, convertToUtf8(value, i, j - i)); 147 writeData(handle, RTL_CONSTASCII_STRINGPARAM("
")); 148 i = j + 1; 149 break; 150 case '\x0D': 151 writeData(handle, convertToUtf8(value, i, j - i)); 152 writeData(handle, RTL_CONSTASCII_STRINGPARAM("
")); 153 i = j + 1; 154 break; 155 case '"': 156 writeData(handle, convertToUtf8(value, i, j - i)); 157 writeData(handle, RTL_CONSTASCII_STRINGPARAM(""")); 158 i = j + 1; 159 break; 160 case '&': 161 writeData(handle, convertToUtf8(value, i, j - i)); 162 writeData(handle, RTL_CONSTASCII_STRINGPARAM("&")); 163 i = j + 1; 164 break; 165 case '<': 166 writeData(handle, convertToUtf8(value, i, j - i)); 167 writeData(handle, RTL_CONSTASCII_STRINGPARAM("<")); 168 i = j + 1; 169 break; 170 default: 171 break; 172 } 173 } 174 writeData(handle, convertToUtf8(value, i, j - i)); 175 } 176 177 void writeValueContent(oslFileHandle handle, sal_Bool value) { 178 if (value) { 179 writeData(handle, RTL_CONSTASCII_STRINGPARAM("true")); 180 } else { 181 writeData(handle, RTL_CONSTASCII_STRINGPARAM("false")); 182 } 183 } 184 185 void writeValueContent(oslFileHandle handle, sal_Int16 value) { 186 writeData(handle, rtl::OString::valueOf(static_cast< sal_Int32 >(value))); 187 } 188 189 void writeValueContent(oslFileHandle handle, sal_Int32 value) { 190 writeData(handle, rtl::OString::valueOf(value)); 191 } 192 193 void writeValueContent(oslFileHandle handle, sal_Int64 value) { 194 writeData(handle, rtl::OString::valueOf(value)); 195 } 196 197 void writeValueContent(oslFileHandle handle, double value) { 198 writeData(handle, rtl::OString::valueOf(value)); 199 } 200 201 void writeValueContent(oslFileHandle handle, rtl::OUString const & value) { 202 sal_Int32 i = 0; 203 sal_Int32 j = i; 204 for (; j < value.getLength(); ++j) { 205 sal_Unicode c = value[j]; 206 if ((c < 0x0020 && c != 0x0009 && c != 0x000A && c != 0x000D) || 207 c == 0xFFFE || c == 0xFFFF) 208 { 209 writeData(handle, convertToUtf8(value, i, j - i)); 210 writeData( 211 handle, RTL_CONSTASCII_STRINGPARAM("<unicode oor:scalar=\"")); 212 writeData( 213 handle, rtl::OString::valueOf(static_cast< sal_Int32 >(c))); 214 writeData(handle, RTL_CONSTASCII_STRINGPARAM("\"/>")); 215 i = j + 1; 216 } else if (c == '\x0D') { 217 writeData(handle, convertToUtf8(value, i, j - i)); 218 writeData(handle, RTL_CONSTASCII_STRINGPARAM("
")); 219 i = j + 1; 220 } else if (c == '&') { 221 writeData(handle, convertToUtf8(value, i, j - i)); 222 writeData(handle, RTL_CONSTASCII_STRINGPARAM("&")); 223 i = j + 1; 224 } else if (c == '<') { 225 writeData(handle, convertToUtf8(value, i, j - i)); 226 writeData(handle, RTL_CONSTASCII_STRINGPARAM("<")); 227 i = j + 1; 228 } else if (c == '>') { 229 // "MUST, for compatibility, be escaped [...] when it appears in the 230 // string ']]>'": 231 writeData(handle, convertToUtf8(value, i, j - i)); 232 writeData(handle, RTL_CONSTASCII_STRINGPARAM(">")); 233 i = j + 1; 234 } 235 } 236 writeData(handle, convertToUtf8(value, i, j - i)); 237 } 238 239 void writeValueContent( 240 oslFileHandle handle, css::uno::Sequence< sal_Int8 > const & value) 241 { 242 for (sal_Int32 i = 0; i < value.getLength(); ++i) { 243 static char const hexDigit[16] = { 244 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 245 'D', 'E', 'F' }; 246 writeData(handle, hexDigit + ((value[i] >> 4) & 0xF), 1); 247 writeData(handle, hexDigit + (value[i] & 0xF), 1); 248 } 249 } 250 251 template< typename T > void writeSingleValue( 252 oslFileHandle handle, css::uno::Any const & value) 253 { 254 writeData(handle, RTL_CONSTASCII_STRINGPARAM(">")); 255 T val = T(); 256 value >>= val; 257 writeValueContent(handle, val); 258 writeData(handle, RTL_CONSTASCII_STRINGPARAM("</value>")); 259 } 260 261 template< typename T > void writeListValue( 262 oslFileHandle handle, css::uno::Any const & value) 263 { 264 writeData(handle, RTL_CONSTASCII_STRINGPARAM(">")); 265 css::uno::Sequence< T > val; 266 value >>= val; 267 for (sal_Int32 i = 0; i < val.getLength(); ++i) { 268 if (i != 0) { 269 writeData(handle, RTL_CONSTASCII_STRINGPARAM(" ")); 270 } 271 writeValueContent(handle, val[i]); 272 } 273 writeData(handle, RTL_CONSTASCII_STRINGPARAM("</value>")); 274 } 275 276 template< typename T > void writeItemListValue( 277 oslFileHandle handle, css::uno::Any const & value) 278 { 279 writeData(handle, RTL_CONSTASCII_STRINGPARAM(">")); 280 css::uno::Sequence< T > val; 281 value >>= val; 282 for (sal_Int32 i = 0; i < val.getLength(); ++i) { 283 writeData(handle, RTL_CONSTASCII_STRINGPARAM("<it>")); 284 writeValueContent(handle, val[i]); 285 writeData(handle, RTL_CONSTASCII_STRINGPARAM("</it>")); 286 } 287 writeData(handle, RTL_CONSTASCII_STRINGPARAM("</value>")); 288 } 289 290 void writeValue(oslFileHandle handle, Type type, css::uno::Any const & value) { 291 switch (type) { 292 case TYPE_BOOLEAN: 293 writeSingleValue< sal_Bool >(handle, value); 294 break; 295 case TYPE_SHORT: 296 writeSingleValue< sal_Int16 >(handle, value); 297 break; 298 case TYPE_INT: 299 writeSingleValue< sal_Int32 >(handle, value); 300 break; 301 case TYPE_LONG: 302 writeSingleValue< sal_Int64 >(handle, value); 303 break; 304 case TYPE_DOUBLE: 305 writeSingleValue< double >(handle, value); 306 break; 307 case TYPE_STRING: 308 writeSingleValue< rtl::OUString >(handle, value); 309 break; 310 case TYPE_HEXBINARY: 311 writeSingleValue< css::uno::Sequence< sal_Int8 > >(handle, value); 312 break; 313 case TYPE_BOOLEAN_LIST: 314 writeListValue< sal_Bool >(handle, value); 315 break; 316 case TYPE_SHORT_LIST: 317 writeListValue< sal_Int16 >(handle, value); 318 break; 319 case TYPE_INT_LIST: 320 writeListValue< sal_Int32 >(handle, value); 321 break; 322 case TYPE_LONG_LIST: 323 writeListValue< sal_Int64 >(handle, value); 324 break; 325 case TYPE_DOUBLE_LIST: 326 writeListValue< double >(handle, value); 327 break; 328 case TYPE_STRING_LIST: 329 writeItemListValue< rtl::OUString >(handle, value); 330 break; 331 case TYPE_HEXBINARY_LIST: 332 writeItemListValue< css::uno::Sequence< sal_Int8 > >(handle, value); 333 break; 334 default: // TYPE_ERROR, TYPE_NIL, TYPE_ANY 335 OSL_ASSERT(false); // this cannot happen 336 } 337 } 338 339 void writeNode( 340 Components & components, oslFileHandle handle, 341 rtl::Reference< Node > const & parent, rtl::OUString const & name, 342 rtl::Reference< Node > const & node) 343 { 344 static xmlreader::Span const typeNames[] = { 345 xmlreader::Span(), xmlreader::Span(), xmlreader::Span(), 346 // TYPE_ERROR, TYPE_NIL, TYPE_ANY 347 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:boolean")), 348 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:short")), 349 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:int")), 350 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:long")), 351 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:double")), 352 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:string")), 353 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("xs:hexBinary")), 354 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:boolean-list")), 355 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:short-list")), 356 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:int-list")), 357 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:long-list")), 358 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:double-list")), 359 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:string-list")), 360 xmlreader::Span(RTL_CONSTASCII_STRINGPARAM("oor:hexBinary-list")) }; 361 switch (node->kind()) { 362 case Node::KIND_PROPERTY: 363 { 364 PropertyNode * prop = dynamic_cast< PropertyNode * >(node.get()); 365 writeData(handle, RTL_CONSTASCII_STRINGPARAM("<prop oor:name=\"")); 366 writeAttributeValue(handle, name); 367 writeData(handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\"")); 368 Type type = prop->getStaticType(); 369 Type dynType = getDynamicType(prop->getValue(components)); 370 OSL_ASSERT(dynType != TYPE_ERROR); 371 if (type == TYPE_ANY) { 372 type = dynType; 373 if (type != TYPE_NIL) { 374 writeData( 375 handle, RTL_CONSTASCII_STRINGPARAM(" oor:type=\"")); 376 writeData( 377 handle, typeNames[type].begin, typeNames[type].length); 378 writeData(handle, RTL_CONSTASCII_STRINGPARAM("\"")); 379 } 380 } 381 writeData(handle, "><value"); 382 if (dynType == TYPE_NIL) { 383 writeData( 384 handle, RTL_CONSTASCII_STRINGPARAM(" xsi:nil=\"true\"/>")); 385 } else { 386 writeValue(handle, type, prop->getValue(components)); 387 } 388 writeData(handle, "</prop>"); 389 } 390 break; 391 case Node::KIND_LOCALIZED_PROPERTY: 392 writeData(handle, RTL_CONSTASCII_STRINGPARAM("<prop oor:name=\"")); 393 writeAttributeValue(handle, name); 394 writeData(handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"fuse\">")); 395 for (NodeMap::iterator i(node->getMembers().begin()); 396 i != node->getMembers().end(); ++i) 397 { 398 writeNode(components, handle, node, i->first, i->second); 399 } 400 writeData(handle, RTL_CONSTASCII_STRINGPARAM("</prop>")); 401 break; 402 case Node::KIND_LOCALIZED_VALUE: 403 { 404 writeData(handle, RTL_CONSTASCII_STRINGPARAM("<value")); 405 if (name.getLength() != 0) { 406 writeData(handle, RTL_CONSTASCII_STRINGPARAM(" xml:lang=\"")); 407 writeAttributeValue(handle, name); 408 writeData(handle, RTL_CONSTASCII_STRINGPARAM("\"")); 409 } 410 Type type = dynamic_cast< LocalizedPropertyNode * >(parent.get())-> 411 getStaticType(); 412 css::uno::Any value( 413 dynamic_cast< LocalizedValueNode * >(node.get())->getValue()); 414 Type dynType = getDynamicType(value); 415 OSL_ASSERT(dynType != TYPE_ERROR); 416 if (type == TYPE_ANY) { 417 type = dynType; 418 if (type != TYPE_NIL) { 419 writeData( 420 handle, RTL_CONSTASCII_STRINGPARAM(" oor:type=\"")); 421 writeData( 422 handle, typeNames[type].begin, typeNames[type].length); 423 writeData(handle, RTL_CONSTASCII_STRINGPARAM("\"")); 424 } 425 } 426 if (dynType == TYPE_NIL) { 427 writeData( 428 handle, RTL_CONSTASCII_STRINGPARAM(" xsi:nil=\"true\"/>")); 429 } else { 430 writeValue(handle, type, value); 431 } 432 } 433 break; 434 case Node::KIND_GROUP: 435 case Node::KIND_SET: 436 writeData(handle, RTL_CONSTASCII_STRINGPARAM("<node oor:name=\"")); 437 writeAttributeValue(handle, name); 438 if (node->getTemplateName().getLength() != 0) { // set member 439 writeData( 440 handle, RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"replace")); 441 } 442 writeData(handle, RTL_CONSTASCII_STRINGPARAM("\">")); 443 for (NodeMap::iterator i(node->getMembers().begin()); 444 i != node->getMembers().end(); ++i) 445 { 446 writeNode(components, handle, node, i->first, i->second); 447 } 448 writeData(handle, RTL_CONSTASCII_STRINGPARAM("</node>")); 449 break; 450 } 451 } 452 453 void writeModifications( 454 Components & components, oslFileHandle handle, 455 rtl::OUString const & parentPathRepresentation, 456 rtl::Reference< Node > const & parent, rtl::OUString const & nodeName, 457 rtl::Reference< Node > const & node, 458 Modifications::Node const & modifications) 459 { 460 // It is never necessary to write oor:finalized or oor:mandatory attributes, 461 // as they cannot be set via the UNO API. 462 if (modifications.children.empty()) { 463 OSL_ASSERT(parent.is()); 464 // components themselves have no parent but must have children 465 writeData(handle, RTL_CONSTASCII_STRINGPARAM("<item oor:path=\"")); 466 writeAttributeValue(handle, parentPathRepresentation); 467 writeData(handle, RTL_CONSTASCII_STRINGPARAM("\">")); 468 if (node.is()) { 469 writeNode(components, handle, parent, nodeName, node); 470 } else { 471 switch (parent->kind()) { 472 case Node::KIND_LOCALIZED_PROPERTY: 473 writeData(handle, RTL_CONSTASCII_STRINGPARAM("<value")); 474 if (nodeName.getLength() != 0) { 475 writeData( 476 handle, RTL_CONSTASCII_STRINGPARAM(" xml:lang=\"")); 477 writeAttributeValue(handle, nodeName); 478 writeData(handle, RTL_CONSTASCII_STRINGPARAM("\"")); 479 } 480 writeData( 481 handle, RTL_CONSTASCII_STRINGPARAM(" oor:op=\"remove\"/>")); 482 break; 483 case Node::KIND_GROUP: 484 OSL_ASSERT( 485 dynamic_cast< GroupNode * >(parent.get())->isExtensible()); 486 writeData( 487 handle, RTL_CONSTASCII_STRINGPARAM("<prop oor:name=\"")); 488 writeAttributeValue(handle, nodeName); 489 writeData( 490 handle, 491 RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"remove\"/>")); 492 break; 493 case Node::KIND_SET: 494 writeData( 495 handle, RTL_CONSTASCII_STRINGPARAM("<node oor:name=\"")); 496 writeAttributeValue(handle, nodeName); 497 writeData( 498 handle, 499 RTL_CONSTASCII_STRINGPARAM("\" oor:op=\"remove\"/>")); 500 break; 501 default: 502 OSL_ASSERT(false); // this cannot happen 503 break; 504 } 505 } 506 writeData(handle, RTL_CONSTASCII_STRINGPARAM("</item>")); 507 } else { 508 OSL_ASSERT(node.is()); 509 rtl::OUString pathRep( 510 parentPathRepresentation + 511 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) + 512 Data::createSegment(node->getTemplateName(), nodeName)); 513 for (Modifications::Node::Children::const_iterator i( 514 modifications.children.begin()); 515 i != modifications.children.end(); ++i) 516 { 517 writeModifications( 518 components, handle, pathRep, node, i->first, 519 node->getMember(i->first), i->second); 520 } 521 } 522 } 523 524 } 525 526 void writeModFile( 527 Components & components, rtl::OUString const & url, Data const & data) 528 { 529 sal_Int32 i = url.lastIndexOf('/'); 530 OSL_ASSERT(i != -1); 531 rtl::OUString dir(url.copy(0, i)); 532 switch (osl::Directory::createPath(dir)) { 533 case osl::FileBase::E_None: 534 case osl::FileBase::E_EXIST: 535 break; 536 case osl::FileBase::E_ACCES: 537 OSL_TRACE( 538 "cannot create registrymodifications.xcu path (E_ACCES); changes" 539 " will be lost"); 540 return; 541 default: 542 throw css::uno::RuntimeException( 543 (rtl::OUString( 544 RTL_CONSTASCII_USTRINGPARAM("cannot create directory ")) + 545 dir), 546 css::uno::Reference< css::uno::XInterface >()); 547 } 548 TempFile tmp; 549 switch (osl::FileBase::createTempFile(&dir, &tmp.handle, &tmp.url)) { 550 case osl::FileBase::E_None: 551 break; 552 case osl::FileBase::E_ACCES: 553 OSL_TRACE( 554 "cannot create temp registrymodifications.xcu (E_ACCES); changes" 555 " will be lost"); 556 return; 557 default: 558 throw css::uno::RuntimeException( 559 (rtl::OUString( 560 RTL_CONSTASCII_USTRINGPARAM( 561 "cannot create temporary file in ")) + 562 dir), 563 css::uno::Reference< css::uno::XInterface >()); 564 } 565 writeData( 566 tmp.handle, 567 RTL_CONSTASCII_STRINGPARAM( 568 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><oor:items" 569 " xmlns:oor=\"http://openoffice.org/2001/registry\"" 570 " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"" 571 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">")); 572 //TODO: Do not write back information about those removed items that did not 573 // come from the .xcs/.xcu files, anyway (but had been added dynamically 574 // instead): 575 for (Modifications::Node::Children::const_iterator j( 576 data.modifications.getRoot().children.begin()); 577 j != data.modifications.getRoot().children.end(); ++j) 578 { 579 writeModifications( 580 components, tmp.handle, rtl::OUString(), rtl::Reference< Node >(), 581 j->first, Data::findNode(Data::NO_LAYER, data.components, j->first), 582 j->second); 583 } 584 writeData(tmp.handle, RTL_CONSTASCII_STRINGPARAM("</oor:items>")); 585 oslFileError e = osl_closeFile(tmp.handle); 586 tmp.closed = true; 587 if (e != osl_File_E_None) { 588 throw css::uno::RuntimeException( 589 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cannot close ")) + 590 tmp.url), 591 css::uno::Reference< css::uno::XInterface >()); 592 } 593 if (osl::File::move(tmp.url, url) != osl::FileBase::E_None) { 594 throw css::uno::RuntimeException( 595 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cannot move ")) + 596 tmp.url), 597 css::uno::Reference< css::uno::XInterface >()); 598 } 599 tmp.handle = 0; 600 } 601 602 } 603