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