1 |
From d7cc1b57990e1ebc2e1f2a4380dd8e66b0eff158 Mon Sep 17 00:00:00 2001 |
2 |
From: David Tardon <dtardon@redhat.com> |
3 |
Date: Thu, 10 Feb 2011 13:54:19 +0100 |
4 |
Subject: [PATCH] rhbz#649310 don't crash deregistering diff. platform ext. |
5 |
|
6 |
This happens, for example, if one switches between, lets say, x86 and |
7 |
x86_64 systems and has the same /home mounted from both. Then |
8 |
platform-dependent extensions from one system does not exist on the |
9 |
other one, but must still be deregistered correctly. |
10 |
--- |
11 |
.../deployment/registry/component/dp_component.cxx | 164 +++++++++++++++++++- |
12 |
1 files changed, 159 insertions(+), 5 deletions(-) |
13 |
|
14 |
diff --git a/desktop/source/deployment/registry/component/dp_component.cxx b/desktop/source/deployment/registry/component/dp_component.cxx |
15 |
index b7fe0b1..d4cb5dd 100644 |
16 |
--- a/desktop/source/deployment/registry/component/dp_component.cxx |
17 |
+++ b/desktop/source/deployment/registry/component/dp_component.cxx |
18 |
@@ -192,6 +192,42 @@ class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend |
19 |
OUString const & identifier); |
20 |
}; |
21 |
friend class TypelibraryPackageImpl; |
22 |
+ |
23 |
+ /** Serves for unregistering packages that were registered on a |
24 |
+ different platform. This can happen if one has remotely mounted |
25 |
+ /home, for example. |
26 |
+ */ |
27 |
+ class OtherPlatformPackageImpl : public ::dp_registry::backend::Package |
28 |
+ { |
29 |
+ public: |
30 |
+ OtherPlatformPackageImpl( |
31 |
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend, |
32 |
+ OUString const & url, OUString const & name, |
33 |
+ Reference<deployment::XPackageTypeInfo> const & xPackageType, |
34 |
+ bool bRemoved, OUString const & identifier, OUString const& rPlatform); |
35 |
+ |
36 |
+ private: |
37 |
+ BackendImpl * getMyBackend() const; |
38 |
+ |
39 |
+ const Reference<registry::XSimpleRegistry> impl_openRDB() const; |
40 |
+ const Reference<XInterface> impl_createInstance(OUString const& rService) const; |
41 |
+ |
42 |
+ // Package |
43 |
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_( |
44 |
+ ::osl::ResettableMutexGuard & guard, |
45 |
+ ::rtl::Reference<AbortChannel> const & abortChannel, |
46 |
+ Reference<XCommandEnvironment> const & xCmdEnv ); |
47 |
+ virtual void processPackage_( |
48 |
+ ::osl::ResettableMutexGuard & guard, |
49 |
+ bool registerPackage, |
50 |
+ bool startup, |
51 |
+ ::rtl::Reference<AbortChannel> const & abortChannel, |
52 |
+ Reference<XCommandEnvironment> const & xCmdEnv ); |
53 |
+ |
54 |
+ private: |
55 |
+ OUString const m_aPlatform; |
56 |
+ }; |
57 |
+ friend class OtherPlatformPackageImpl; |
58 |
|
59 |
t_stringlist m_jar_typelibs; |
60 |
t_stringlist m_rdb_typelibs; |
61 |
@@ -694,16 +730,30 @@ Reference<deployment::XPackage> BackendImpl::bindPackage_( |
62 |
|
63 |
INetContentTypeParameter const * param = params.find( |
64 |
ByteString("platform") ); |
65 |
- if (param == 0 || platform_fits( param->m_sValue )) { |
66 |
+ bool bPlatformFits(param == 0); |
67 |
+ String aPlatform; |
68 |
+ if (!bPlatformFits) // platform is specified, we have to check |
69 |
+ { |
70 |
+ aPlatform = param->m_sValue; |
71 |
+ bPlatformFits = platform_fits(aPlatform); |
72 |
+ } |
73 |
+ // If the package is being removed, do not care whether |
74 |
+ // platform fits. We won't be using it anyway. |
75 |
+ if (bPlatformFits || bRemoved) { |
76 |
param = params.find( ByteString("type") ); |
77 |
if (param != 0) |
78 |
{ |
79 |
String const & value = param->m_sValue; |
80 |
if (value.EqualsIgnoreCaseAscii("native")) { |
81 |
- return new BackendImpl::ComponentPackageImpl( |
82 |
- this, url, name, m_xDynComponentTypeInfo, |
83 |
- OUSTR("com.sun.star.loader.SharedLibrary"), |
84 |
- bRemoved, identifier); |
85 |
+ if (bPlatformFits) |
86 |
+ return new BackendImpl::ComponentPackageImpl( |
87 |
+ this, url, name, m_xDynComponentTypeInfo, |
88 |
+ OUSTR("com.sun.star.loader.SharedLibrary"), |
89 |
+ bRemoved, identifier); |
90 |
+ else |
91 |
+ return new BackendImpl::OtherPlatformPackageImpl( |
92 |
+ this, url, name, m_xDynComponentTypeInfo, |
93 |
+ bRemoved, identifier, aPlatform); |
94 |
} |
95 |
if (value.EqualsIgnoreCaseAscii("Java")) { |
96 |
return new BackendImpl::ComponentPackageImpl( |
97 |
@@ -1567,6 +1617,110 @@ void BackendImpl::TypelibraryPackageImpl::processPackage_( |
98 |
} |
99 |
} |
100 |
|
101 |
+BackendImpl::OtherPlatformPackageImpl::OtherPlatformPackageImpl( |
102 |
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend, |
103 |
+ OUString const & url, OUString const & name, |
104 |
+ Reference<deployment::XPackageTypeInfo> const & xPackageType, |
105 |
+ bool bRemoved, OUString const & identifier, OUString const& rPlatform) |
106 |
+ : Package(myBackend, url, name, name, xPackageType, bRemoved, identifier) |
107 |
+ , m_aPlatform(rPlatform) |
108 |
+{ |
109 |
+ OSL_PRECOND(bRemoved, "this class can only be used for removing packages!"); |
110 |
+} |
111 |
+ |
112 |
+BackendImpl * |
113 |
+BackendImpl::OtherPlatformPackageImpl::getMyBackend() const |
114 |
+{ |
115 |
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get()); |
116 |
+ if (NULL == pBackend) |
117 |
+ { |
118 |
+ //Throws a DisposedException |
119 |
+ check(); |
120 |
+ //We should never get here... |
121 |
+ throw RuntimeException( |
122 |
+ OUSTR("Failed to get the BackendImpl"), |
123 |
+ static_cast<OWeakObject*>(const_cast<OtherPlatformPackageImpl*>(this))); |
124 |
+ } |
125 |
+ return pBackend; |
126 |
+} |
127 |
+ |
128 |
+Reference<registry::XSimpleRegistry> const |
129 |
+BackendImpl::OtherPlatformPackageImpl::impl_openRDB() const |
130 |
+{ |
131 |
+ OUString const aRDB(m_aPlatform + OUString(RTL_CONSTASCII_USTRINGPARAM(".rdb"))); |
132 |
+ OUString const aRDBPath(makeURL(getMyBackend()->getCachePath(), aRDB)); |
133 |
+ |
134 |
+ Reference<registry::XSimpleRegistry> xRegistry; |
135 |
+ |
136 |
+ try |
137 |
+ { |
138 |
+ xRegistry.set( |
139 |
+ impl_createInstance( |
140 |
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry"))), |
141 |
+ UNO_QUERY) |
142 |
+ ; |
143 |
+ if (xRegistry.is()) |
144 |
+ xRegistry->open(expandUnoRcUrl(aRDBPath), false, false); |
145 |
+ } |
146 |
+ catch (registry::InvalidRegistryException const&) |
147 |
+ { |
148 |
+ // If the registry does not exist, we do not need to bother at all |
149 |
+ xRegistry.set(0); |
150 |
+ } |
151 |
+ |
152 |
+ OSL_POSTCOND(xRegistry.is(), "could not create registry for the package's platform"); |
153 |
+ return xRegistry; |
154 |
+} |
155 |
+ |
156 |
+Reference<XInterface> const |
157 |
+BackendImpl::OtherPlatformPackageImpl::impl_createInstance(OUString const& rService) |
158 |
+const |
159 |
+{ |
160 |
+ Reference<XComponentContext> const xContext(getMyBackend()->getComponentContext()); |
161 |
+ OSL_ASSERT(xContext.is()); |
162 |
+ Reference<XInterface> xService; |
163 |
+ if (xContext.is()) |
164 |
+ xService.set(xContext->getServiceManager()->createInstanceWithContext(rService, xContext)); |
165 |
+ return xService; |
166 |
+} |
167 |
+ |
168 |
+beans::Optional<beans::Ambiguous<sal_Bool> > |
169 |
+BackendImpl::OtherPlatformPackageImpl::isRegistered_( |
170 |
+ ::osl::ResettableMutexGuard& /* guard */, |
171 |
+ ::rtl::Reference<AbortChannel> const& /* abortChannel */, |
172 |
+ Reference<XCommandEnvironment> const& /* xCmdEnv */ ) |
173 |
+{ |
174 |
+ return beans::Optional<beans::Ambiguous<sal_Bool> >(sal_True, |
175 |
+ beans::Ambiguous<sal_Bool>(sal_True, sal_False)); |
176 |
+} |
177 |
+ |
178 |
+void |
179 |
+BackendImpl::OtherPlatformPackageImpl::processPackage_( |
180 |
+ ::osl::ResettableMutexGuard& /* guard */, |
181 |
+ bool bRegisterPackage, |
182 |
+ bool /* bStartup */, |
183 |
+ ::rtl::Reference<AbortChannel> const& /* abortChannel */, |
184 |
+ Reference<XCommandEnvironment> const& /* xCmdEnv */) |
185 |
+{ |
186 |
+ OSL_PRECOND(!bRegisterPackage, "this class can only be used for removing packages!"); |
187 |
+ (void) bRegisterPackage; |
188 |
+ |
189 |
+ OUString const aURL(getURL()); |
190 |
+ |
191 |
+ Reference<registry::XSimpleRegistry> const xServicesRDB(impl_openRDB()); |
192 |
+ Reference<registry::XImplementationRegistration> const xImplReg( |
193 |
+ impl_createInstance( |
194 |
+ OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.ImplementationRegistration"))), |
195 |
+ UNO_QUERY) |
196 |
+ ; |
197 |
+ if (xImplReg.is() && xServicesRDB.is()) |
198 |
+ xImplReg->revokeImplementation(aURL, xServicesRDB); |
199 |
+ if (xServicesRDB.is()) |
200 |
+ xServicesRDB->close(); |
201 |
+ |
202 |
+ getMyBackend()->deleteDataFromDb(aURL); |
203 |
+} |
204 |
+ |
205 |
} // anon namespace |
206 |
|
207 |
namespace sdecl = comphelper::service_decl; |
208 |
-- |
209 |
1.7.4 |