1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_stoc.hxx" 30 31 #include <vector> 32 33 #include <com/sun/star/registry/XRegistryKey.hpp> 34 #include <com/sun/star/registry/MergeConflictException.hpp> 35 36 #include "mergekeys.hxx" 37 38 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 39 40 using namespace ::rtl; 41 using namespace ::osl; 42 using namespace ::com::sun::star::uno; 43 using namespace ::com::sun::star; 44 45 namespace stoc_impreg 46 { 47 48 struct Link 49 { 50 OUString m_name; 51 OUString m_target; 52 53 inline Link( OUString const & name, OUString const & target ) 54 : m_name( name ) 55 , m_target( target ) 56 {} 57 }; 58 typedef ::std::vector< Link > t_links; 59 60 //================================================================================================== 61 static void mergeKeys( 62 Reference< registry::XRegistryKey > const & xDest, 63 Reference< registry::XRegistryKey > const & xSource, 64 t_links & links ) 65 // throw( registry::InvalidRegistryException, registry::MergeConflictException, RuntimeException ) 66 { 67 if (!xSource.is() || !xSource->isValid()) { 68 throw registry::InvalidRegistryException( 69 OUSTR("source key is null or invalid!"), 70 Reference<XInterface>() ); 71 } 72 if (!xDest.is() || !xDest->isValid()) { 73 throw registry::InvalidRegistryException( 74 OUSTR("destination key is null or invalid!"), 75 Reference<XInterface>() ); 76 } 77 78 // write value 79 switch (xSource->getValueType()) 80 { 81 case registry::RegistryValueType_NOT_DEFINED: 82 break; 83 case registry::RegistryValueType_LONG: 84 xDest->setLongValue( xSource->getLongValue() ); 85 break; 86 case registry::RegistryValueType_ASCII: 87 xDest->setAsciiValue( xSource->getAsciiValue() ); 88 break; 89 case registry::RegistryValueType_STRING: 90 xDest->setStringValue( xSource->getStringValue() ); 91 break; 92 case registry::RegistryValueType_BINARY: 93 xDest->setBinaryValue( xSource->getBinaryValue() ); 94 break; 95 case registry::RegistryValueType_LONGLIST: 96 xDest->setLongListValue( xSource->getLongListValue() ); 97 break; 98 case registry::RegistryValueType_ASCIILIST: 99 xDest->setAsciiListValue( xSource->getAsciiListValue() ); 100 break; 101 case registry::RegistryValueType_STRINGLIST: 102 xDest->setStringListValue( xSource->getStringListValue() ); 103 break; 104 default: 105 OSL_ASSERT(false); 106 break; 107 } 108 109 // sub keys 110 Sequence< OUString > sourceKeys( xSource->getKeyNames() ); 111 OUString const * pSourceKeys = sourceKeys.getConstArray(); 112 for ( sal_Int32 nPos = sourceKeys.getLength(); nPos--; ) 113 { 114 // key name 115 OUString name( pSourceKeys[ nPos ] ); 116 sal_Int32 nSlash = name.lastIndexOf( '/' ); 117 if (nSlash >= 0) 118 { 119 name = name.copy( nSlash +1 ); 120 } 121 122 if (xSource->getKeyType( name ) == registry::RegistryKeyType_KEY) 123 { 124 // try to open exisiting dest key or create new one 125 Reference< registry::XRegistryKey > xDestKey( xDest->createKey( name ) ); 126 Reference< registry::XRegistryKey > xSourceKey( xSource->openKey( name ) ); 127 mergeKeys( xDestKey, xSourceKey, links ); 128 xSourceKey->closeKey(); 129 xDestKey->closeKey(); 130 } 131 else // link 132 { 133 // remove existing key 134 Reference< registry::XRegistryKey > xDestKey( xDest->openKey( name ) ); 135 if (xDestKey.is() && xDestKey->isValid()) // something to remove 136 { 137 xDestKey->closeKey(); 138 if (xDest->getKeyType( name ) == registry::RegistryKeyType_LINK) 139 { 140 xDest->deleteLink( name ); 141 } 142 else 143 { 144 xDest->deleteKey( name ); 145 } 146 } 147 148 links.push_back( Link( 149 pSourceKeys[ nPos ], // abs path 150 xSource->getResolvedName( name ) // abs resolved name 151 ) ); 152 } 153 } 154 } 155 156 //================================================================================================== 157 void mergeKeys( 158 Reference< registry::XRegistryKey > const & xDest, 159 Reference< registry::XRegistryKey > const & xSource ) 160 // throw( registry::InvalidRegistryException, registry::MergeConflictException, RuntimeException ) 161 { 162 if (!xDest.is() || !xDest->isValid()) { 163 throw registry::InvalidRegistryException( 164 OUSTR("destination key is null or invalid!"), 165 Reference<XInterface>() ); 166 } 167 if (xDest->isReadOnly()) 168 { 169 throw registry::InvalidRegistryException( 170 OUString( RTL_CONSTASCII_USTRINGPARAM( 171 "destination registry is read-only! cannot merge!") ), 172 Reference< XInterface >() ); 173 } 174 175 t_links links; 176 links.reserve( 16 ); 177 mergeKeys( xDest, xSource, links ); 178 179 for ( size_t nPos = links.size(); nPos--; ) 180 { 181 Link const & r = links[ nPos ]; 182 OSL_VERIFY( xDest->createLink( r.m_name, r.m_target ) ); 183 } 184 } 185 186 } 187