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
Linkstoc_impreg::Link49 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 //==================================================================================================
mergeKeys(Reference<registry::XRegistryKey> const & xDest,Reference<registry::XRegistryKey> const & xSource,t_links & links)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 //==================================================================================================
mergeKeys(Reference<registry::XRegistryKey> const & xDest,Reference<registry::XRegistryKey> const & xSource)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