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_expand.hxx"
26
27 #include "rtl/uri.hxx"
28 #include "osl/mutex.hxx"
29 #include "cppuhelper/compbase2.hxx"
30 #include "cppuhelper/factory.hxx"
31 #include "cppuhelper/implementationentry.hxx"
32 #include "ucbhelper/content.hxx"
33 #include "com/sun/star/uno/XComponentContext.hpp"
34 #include "com/sun/star/lang/DisposedException.hpp"
35 #include "com/sun/star/lang/XServiceInfo.hpp"
36 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
37 #include "com/sun/star/registry/XRegistryKey.hpp"
38 #include "com/sun/star/util/XMacroExpander.hpp"
39 #include "com/sun/star/ucb/XContentProvider.hpp"
40
41 #define EXPAND_PROTOCOL "vnd.sun.star.expand"
42 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
43 #define ARLEN(x) sizeof (x) / sizeof *(x)
44
45
46 using namespace ::com::sun::star;
47 using ::rtl::OUString;
48
49 namespace
50 {
51
52 struct MutexHolder
53 {
54 mutable ::osl::Mutex m_mutex;
55 };
56
57 typedef ::cppu::WeakComponentImplHelper2<
58 lang::XServiceInfo, ucb::XContentProvider > t_impl_helper;
59
60 //==============================================================================
61 class ExpandContentProviderImpl : protected MutexHolder, public t_impl_helper
62 {
63 uno::Reference< util::XMacroExpander > m_xMacroExpander;
64 OUString expandUri(
65 uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const;
66
67 protected:
68 inline void check() const;
69 virtual void SAL_CALL disposing();
70
71 public:
ExpandContentProviderImpl(uno::Reference<uno::XComponentContext> const & xComponentContext)72 inline ExpandContentProviderImpl(
73 uno::Reference< uno::XComponentContext > const & xComponentContext )
74 : t_impl_helper( m_mutex ),
75 m_xMacroExpander(
76 xComponentContext->getValueByName(
77 OUSTR("/singletons/com.sun.star.util.theMacroExpander") ),
78 uno::UNO_QUERY_THROW )
79 {}
80 virtual ~ExpandContentProviderImpl() throw ();
81
82 // XServiceInfo
83 virtual OUString SAL_CALL getImplementationName()
84 throw (uno::RuntimeException);
85 virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
86 throw (uno::RuntimeException);
87 virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames()
88 throw (uno::RuntimeException);
89
90 // XContentProvider
91 virtual uno::Reference< ucb::XContent > SAL_CALL queryContent(
92 uno::Reference< ucb::XContentIdentifier > const & xIdentifier )
93 throw (ucb::IllegalIdentifierException, uno::RuntimeException);
94 virtual sal_Int32 SAL_CALL compareContentIds(
95 uno::Reference< ucb::XContentIdentifier > const & xId1,
96 uno::Reference< ucb::XContentIdentifier > const & xId2 )
97 throw (uno::RuntimeException);
98 };
99
100 //______________________________________________________________________________
check() const101 inline void ExpandContentProviderImpl::check() const
102 {
103 // xxx todo guard?
104 // MutexGuard guard( m_mutex );
105 if (rBHelper.bInDispose || rBHelper.bDisposed)
106 {
107 throw lang::DisposedException(
108 OUSTR("expand content provider instance has "
109 "already been disposed!"),
110 static_cast< OWeakObject * >(
111 const_cast< ExpandContentProviderImpl * >(this) ) );
112 }
113 }
114
115 //______________________________________________________________________________
~ExpandContentProviderImpl()116 ExpandContentProviderImpl::~ExpandContentProviderImpl() throw ()
117 {
118 }
119
120 //______________________________________________________________________________
disposing()121 void ExpandContentProviderImpl::disposing()
122 {
123 }
124
125 //==============================================================================
create(uno::Reference<uno::XComponentContext> const & xComponentContext)126 static uno::Reference< uno::XInterface > SAL_CALL create(
127 uno::Reference< uno::XComponentContext > const & xComponentContext )
128 SAL_THROW( (uno::Exception) )
129 {
130 return static_cast< ::cppu::OWeakObject * >(
131 new ExpandContentProviderImpl( xComponentContext ) );
132 }
133
134 //==============================================================================
implName()135 static OUString SAL_CALL implName()
136 {
137 return OUSTR("com.sun.star.comp.ucb.ExpandContentProvider");
138 }
139
140 //==============================================================================
supportedServices()141 static uno::Sequence< OUString > SAL_CALL supportedServices()
142 {
143 OUString names [] = {
144 OUSTR("com.sun.star.ucb.ExpandContentProvider"),
145 OUSTR("com.sun.star.ucb.ContentProvider")
146 };
147 return uno::Sequence< OUString >( names, ARLEN(names) );
148 }
149
150 // XServiceInfo
151 //______________________________________________________________________________
getImplementationName()152 OUString ExpandContentProviderImpl::getImplementationName()
153 throw (uno::RuntimeException)
154 {
155 check();
156 return implName();
157 }
158
159 //______________________________________________________________________________
getSupportedServiceNames()160 uno::Sequence< OUString > ExpandContentProviderImpl::getSupportedServiceNames()
161 throw (uno::RuntimeException)
162 {
163 check();
164 return supportedServices();
165 }
166
167 //______________________________________________________________________________
supportsService(OUString const & serviceName)168 sal_Bool ExpandContentProviderImpl::supportsService(
169 OUString const & serviceName )
170 throw (uno::RuntimeException)
171 {
172 // check();
173 uno::Sequence< OUString > supported_services( getSupportedServiceNames() );
174 OUString const * ar = supported_services.getConstArray();
175 for ( sal_Int32 pos = supported_services.getLength(); pos--; )
176 {
177 if (ar[ pos ].equals( serviceName ))
178 return true;
179 }
180 return false;
181 }
182
183 //______________________________________________________________________________
expandUri(uno::Reference<ucb::XContentIdentifier> const & xIdentifier) const184 OUString ExpandContentProviderImpl::expandUri(
185 uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const
186 {
187 OUString uri( xIdentifier->getContentIdentifier() );
188 if (uri.compareToAscii(
189 RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ) != 0)
190 {
191 throw ucb::IllegalIdentifierException(
192 OUSTR("expected protocol " EXPAND_PROTOCOL "!"),
193 static_cast< OWeakObject * >(
194 const_cast< ExpandContentProviderImpl * >(this) ) );
195 }
196 // cut protocol
197 OUString str( uri.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
198 // decode uric class chars
199 str = ::rtl::Uri::decode(
200 str, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
201 // expand macro string
202 return m_xMacroExpander->expandMacros( str );
203 }
204
205 // XContentProvider
206 //______________________________________________________________________________
queryContent(uno::Reference<ucb::XContentIdentifier> const & xIdentifier)207 uno::Reference< ucb::XContent > ExpandContentProviderImpl::queryContent(
208 uno::Reference< ucb::XContentIdentifier > const & xIdentifier )
209 throw (ucb::IllegalIdentifierException, uno::RuntimeException)
210 {
211 check();
212 OUString uri( expandUri( xIdentifier ) );
213
214 ::ucbhelper::Content ucb_content;
215 if (::ucbhelper::Content::create(
216 uri, uno::Reference< ucb::XCommandEnvironment >(), ucb_content ))
217 {
218 return ucb_content.get();
219 }
220 else
221 {
222 return uno::Reference< ucb::XContent >();
223 }
224 }
225
226 //______________________________________________________________________________
compareContentIds(uno::Reference<ucb::XContentIdentifier> const & xId1,uno::Reference<ucb::XContentIdentifier> const & xId2)227 sal_Int32 ExpandContentProviderImpl::compareContentIds(
228 uno::Reference< ucb::XContentIdentifier > const & xId1,
229 uno::Reference< ucb::XContentIdentifier > const & xId2 )
230 throw (uno::RuntimeException)
231 {
232 check();
233 try
234 {
235 OUString uri1( expandUri( xId1 ) );
236 OUString uri2( expandUri( xId2 ) );
237 return uri1.compareTo( uri2 );
238 }
239 catch (ucb::IllegalIdentifierException & exc)
240 {
241 (void) exc; // unused
242 OSL_ENSURE(
243 0, ::rtl::OUStringToOString(
244 exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
245 return -1;
246 }
247 }
248
249 static const ::cppu::ImplementationEntry s_entries [] =
250 {
251 {
252 create,
253 implName,
254 supportedServices,
255 ::cppu::createSingleComponentFactory,
256 0, 0
257 },
258 { 0, 0, 0, 0, 0, 0 }
259 };
260
261 }
262
263 extern "C"
264 {
265
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)266 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
267 const sal_Char ** ppEnvTypeName, uno_Environment ** )
268 {
269 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
270 }
271
component_getFactory(const sal_Char * pImplName,lang::XMultiServiceFactory * pServiceManager,registry::XRegistryKey * pRegistryKey)272 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
273 const sal_Char * pImplName,
274 lang::XMultiServiceFactory * pServiceManager,
275 registry::XRegistryKey * pRegistryKey )
276 {
277 return ::cppu::component_getFactoryHelper(
278 pImplName, pServiceManager, pRegistryKey, s_entries );
279 }
280
281 }
282