1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_stoc.hxx" 26 27 #include <vector> 28 29 #include <com/sun/star/registry/XRegistryKey.hpp> 30 #include <com/sun/star/registry/MergeConflictException.hpp> 31 32 #include "mergekeys.hxx" 33 34 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 35 36 using namespace ::rtl; 37 using namespace ::osl; 38 using namespace ::com::sun::star::uno; 39 using namespace ::com::sun::star; 40 41 namespace stoc_impreg 42 { 43 44 struct Link 45 { 46 OUString m_name; 47 OUString m_target; 48 49 inline Link( OUString const & name, OUString const & target ) 50 : m_name( name ) 51 , m_target( target ) 52 {} 53 }; 54 typedef ::std::vector< Link > t_links; 55 56 //================================================================================================== 57 static void mergeKeys( 58 Reference< registry::XRegistryKey > const & xDest, 59 Reference< registry::XRegistryKey > const & xSource, 60 t_links & links ) 61 // throw( registry::InvalidRegistryException, registry::MergeConflictException, RuntimeException ) 62 { 63 if (!xSource.is() || !xSource->isValid()) { 64 throw registry::InvalidRegistryException( 65 OUSTR("source key is null or invalid!"), 66 Reference<XInterface>() ); 67 } 68 if (!xDest.is() || !xDest->isValid()) { 69 throw registry::InvalidRegistryException( 70 OUSTR("destination key is null or invalid!"), 71 Reference<XInterface>() ); 72 } 73 74 // write value 75 switch (xSource->getValueType()) 76 { 77 case registry::RegistryValueType_NOT_DEFINED: 78 break; 79 case registry::RegistryValueType_LONG: 80 xDest->setLongValue( xSource->getLongValue() ); 81 break; 82 case registry::RegistryValueType_ASCII: 83 xDest->setAsciiValue( xSource->getAsciiValue() ); 84 break; 85 case registry::RegistryValueType_STRING: 86 xDest->setStringValue( xSource->getStringValue() ); 87 break; 88 case registry::RegistryValueType_BINARY: 89 xDest->setBinaryValue( xSource->getBinaryValue() ); 90 break; 91 case registry::RegistryValueType_LONGLIST: 92 xDest->setLongListValue( xSource->getLongListValue() ); 93 break; 94 case registry::RegistryValueType_ASCIILIST: 95 xDest->setAsciiListValue( xSource->getAsciiListValue() ); 96 break; 97 case registry::RegistryValueType_STRINGLIST: 98 xDest->setStringListValue( xSource->getStringListValue() ); 99 break; 100 default: 101 OSL_ASSERT(false); 102 break; 103 } 104 105 // sub keys 106 Sequence< OUString > sourceKeys( xSource->getKeyNames() ); 107 OUString const * pSourceKeys = sourceKeys.getConstArray(); 108 for ( sal_Int32 nPos = sourceKeys.getLength(); nPos--; ) 109 { 110 // key name 111 OUString name( pSourceKeys[ nPos ] ); 112 sal_Int32 nSlash = name.lastIndexOf( '/' ); 113 if (nSlash >= 0) 114 { 115 name = name.copy( nSlash +1 ); 116 } 117 118 if (xSource->getKeyType( name ) == registry::RegistryKeyType_KEY) 119 { 120 // try to open exisiting dest key or create new one 121 Reference< registry::XRegistryKey > xDestKey( xDest->createKey( name ) ); 122 Reference< registry::XRegistryKey > xSourceKey( xSource->openKey( name ) ); 123 mergeKeys( xDestKey, xSourceKey, links ); 124 xSourceKey->closeKey(); 125 xDestKey->closeKey(); 126 } 127 else // link 128 { 129 // remove existing key 130 Reference< registry::XRegistryKey > xDestKey( xDest->openKey( name ) ); 131 if (xDestKey.is() && xDestKey->isValid()) // something to remove 132 { 133 xDestKey->closeKey(); 134 if (xDest->getKeyType( name ) == registry::RegistryKeyType_LINK) 135 { 136 xDest->deleteLink( name ); 137 } 138 else 139 { 140 xDest->deleteKey( name ); 141 } 142 } 143 144 links.push_back( Link( 145 pSourceKeys[ nPos ], // abs path 146 xSource->getResolvedName( name ) // abs resolved name 147 ) ); 148 } 149 } 150 } 151 152 //================================================================================================== 153 void mergeKeys( 154 Reference< registry::XRegistryKey > const & xDest, 155 Reference< registry::XRegistryKey > const & xSource ) 156 // throw( registry::InvalidRegistryException, registry::MergeConflictException, RuntimeException ) 157 { 158 if (!xDest.is() || !xDest->isValid()) { 159 throw registry::InvalidRegistryException( 160 OUSTR("destination key is null or invalid!"), 161 Reference<XInterface>() ); 162 } 163 if (xDest->isReadOnly()) 164 { 165 throw registry::InvalidRegistryException( 166 OUString( RTL_CONSTASCII_USTRINGPARAM( 167 "destination registry is read-only! cannot merge!") ), 168 Reference< XInterface >() ); 169 } 170 171 t_links links; 172 links.reserve( 16 ); 173 mergeKeys( xDest, xSource, links ); 174 175 for ( size_t nPos = links.size(); nPos--; ) 176 { 177 Link const & r = links[ nPos ]; 178 OSL_VERIFY( xDest->createLink( r.m_name, r.m_target ) ); 179 } 180 } 181 182 } 183