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