LCOV - code coverage report
Current view: top level - libreoffice/configmgr/source - writemodfile.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 286 0.0 %
Date: 2012-12-27 Functions: 0 31 0.0 %
Legend: Lines: hit not hit

          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("&#9;"));
     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("&#xA;"));
     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("&#xD;"));
     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("&quot;"));
     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("&amp;"));
     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("&lt;"));
     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("&#xD;"));
     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("&amp;"));
     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("&lt;"));
     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("&gt;"));
     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: */

Generated by: LCOV version 1.10