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