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