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 :
21 : #include <vector>
22 :
23 : #include <com/sun/star/registry/XRegistryKey.hpp>
24 : #include <com/sun/star/registry/MergeConflictException.hpp>
25 :
26 : #include "mergekeys.hxx"
27 :
28 : using namespace ::rtl;
29 : using namespace ::osl;
30 : using namespace ::com::sun::star::uno;
31 : using namespace ::com::sun::star;
32 :
33 : namespace stoc_impreg
34 : {
35 :
36 0 : struct Link
37 : {
38 : OUString m_name;
39 : OUString m_target;
40 :
41 0 : inline Link( OUString const & name, OUString const & target )
42 : : m_name( name )
43 0 : , m_target( target )
44 0 : {}
45 : };
46 : typedef ::std::vector< Link > t_links;
47 :
48 :
49 0 : static void mergeKeys(
50 : Reference< registry::XRegistryKey > const & xDest,
51 : Reference< registry::XRegistryKey > const & xSource,
52 : t_links & links )
53 : // throw( registry::InvalidRegistryException, registry::MergeConflictException, RuntimeException )
54 : {
55 0 : if (!xSource.is() || !xSource->isValid()) {
56 : throw registry::InvalidRegistryException(
57 : "source key is null or invalid!",
58 0 : Reference<XInterface>() );
59 : }
60 0 : if (!xDest.is() || !xDest->isValid()) {
61 : throw registry::InvalidRegistryException(
62 : "destination key is null or invalid!",
63 0 : Reference<XInterface>() );
64 : }
65 :
66 : // write value
67 0 : switch (xSource->getValueType())
68 : {
69 : case registry::RegistryValueType_NOT_DEFINED:
70 0 : break;
71 : case registry::RegistryValueType_LONG:
72 0 : xDest->setLongValue( xSource->getLongValue() );
73 0 : break;
74 : case registry::RegistryValueType_ASCII:
75 0 : xDest->setAsciiValue( xSource->getAsciiValue() );
76 0 : break;
77 : case registry::RegistryValueType_STRING:
78 0 : xDest->setStringValue( xSource->getStringValue() );
79 0 : break;
80 : case registry::RegistryValueType_BINARY:
81 0 : xDest->setBinaryValue( xSource->getBinaryValue() );
82 0 : break;
83 : case registry::RegistryValueType_LONGLIST:
84 0 : xDest->setLongListValue( xSource->getLongListValue() );
85 0 : break;
86 : case registry::RegistryValueType_ASCIILIST:
87 0 : xDest->setAsciiListValue( xSource->getAsciiListValue() );
88 0 : break;
89 : case registry::RegistryValueType_STRINGLIST:
90 0 : xDest->setStringListValue( xSource->getStringListValue() );
91 0 : break;
92 : default:
93 : OSL_ASSERT(false);
94 0 : break;
95 : }
96 :
97 : // sub keys
98 0 : Sequence< OUString > sourceKeys( xSource->getKeyNames() );
99 0 : OUString const * pSourceKeys = sourceKeys.getConstArray();
100 0 : for ( sal_Int32 nPos = sourceKeys.getLength(); nPos--; )
101 : {
102 : // key name
103 0 : OUString name( pSourceKeys[ nPos ] );
104 0 : sal_Int32 nSlash = name.lastIndexOf( '/' );
105 0 : if (nSlash >= 0)
106 : {
107 0 : name = name.copy( nSlash +1 );
108 : }
109 :
110 0 : if (xSource->getKeyType( name ) == registry::RegistryKeyType_KEY)
111 : {
112 : // try to open exisiting dest key or create new one
113 0 : Reference< registry::XRegistryKey > xDestKey( xDest->createKey( name ) );
114 0 : Reference< registry::XRegistryKey > xSourceKey( xSource->openKey( name ) );
115 0 : mergeKeys( xDestKey, xSourceKey, links );
116 0 : xSourceKey->closeKey();
117 0 : xDestKey->closeKey();
118 : }
119 : else // link
120 : {
121 : // remove existing key
122 0 : Reference< registry::XRegistryKey > xDestKey( xDest->openKey( name ) );
123 0 : if (xDestKey.is() && xDestKey->isValid()) // something to remove
124 : {
125 0 : xDestKey->closeKey();
126 0 : if (xDest->getKeyType( name ) == registry::RegistryKeyType_LINK)
127 : {
128 0 : xDest->deleteLink( name );
129 : }
130 : else
131 : {
132 0 : xDest->deleteKey( name );
133 : }
134 : }
135 :
136 : links.push_back( Link(
137 0 : pSourceKeys[ nPos ], // abs path
138 0 : xSource->getResolvedName( name ) // abs resolved name
139 0 : ) );
140 : }
141 0 : }
142 0 : }
143 :
144 :
145 0 : void mergeKeys(
146 : Reference< registry::XRegistryKey > const & xDest,
147 : Reference< registry::XRegistryKey > const & xSource )
148 : // throw( registry::InvalidRegistryException, registry::MergeConflictException, RuntimeException )
149 : {
150 0 : if (!xDest.is() || !xDest->isValid()) {
151 : throw registry::InvalidRegistryException(
152 : "destination key is null or invalid!",
153 0 : Reference<XInterface>() );
154 : }
155 0 : if (xDest->isReadOnly())
156 : {
157 : throw registry::InvalidRegistryException(
158 : OUString(
159 : "destination registry is read-only! cannot merge!"),
160 0 : Reference< XInterface >() );
161 : }
162 :
163 0 : t_links links;
164 0 : links.reserve( 16 );
165 0 : mergeKeys( xDest, xSource, links );
166 :
167 0 : for ( size_t nPos = links.size(); nPos--; )
168 : {
169 0 : Link const & r = links[ nPos ];
170 0 : OSL_VERIFY( xDest->createLink( r.m_name, r.m_target ) );
171 0 : }
172 0 : }
173 :
174 : }
175 :
176 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|