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 virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName );
85 virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames();
86
87 // XContentProvider
88 virtual uno::Reference< ucb::XContent > SAL_CALL queryContent(
89 uno::Reference< ucb::XContentIdentifier > const & xIdentifier );
90 virtual sal_Int32 SAL_CALL compareContentIds(
91 uno::Reference< ucb::XContentIdentifier > const & xId1,
92 uno::Reference< ucb::XContentIdentifier > const & xId2 );
93 };
94
95 //______________________________________________________________________________
check() const96 inline void ExpandContentProviderImpl::check() const
97 {
98 // xxx todo guard?
99 // MutexGuard guard( m_mutex );
100 if (rBHelper.bInDispose || rBHelper.bDisposed)
101 {
102 throw lang::DisposedException(
103 OUSTR("expand content provider instance has "
104 "already been disposed!"),
105 static_cast< OWeakObject * >(
106 const_cast< ExpandContentProviderImpl * >(this) ) );
107 }
108 }
109
110 //______________________________________________________________________________
~ExpandContentProviderImpl()111 ExpandContentProviderImpl::~ExpandContentProviderImpl() throw ()
112 {
113 }
114
115 //______________________________________________________________________________
disposing()116 void ExpandContentProviderImpl::disposing()
117 {
118 }
119
120 //==============================================================================
create(uno::Reference<uno::XComponentContext> const & xComponentContext)121 static uno::Reference< uno::XInterface > SAL_CALL create(
122 uno::Reference< uno::XComponentContext > const & xComponentContext )
123 {
124 return static_cast< ::cppu::OWeakObject * >(
125 new ExpandContentProviderImpl( xComponentContext ) );
126 }
127
128 //==============================================================================
implName()129 static OUString SAL_CALL implName()
130 {
131 return OUSTR("com.sun.star.comp.ucb.ExpandContentProvider");
132 }
133
134 //==============================================================================
supportedServices()135 static uno::Sequence< OUString > SAL_CALL supportedServices()
136 {
137 OUString names [] = {
138 OUSTR("com.sun.star.ucb.ExpandContentProvider"),
139 OUSTR("com.sun.star.ucb.ContentProvider")
140 };
141 return uno::Sequence< OUString >( names, ARLEN(names) );
142 }
143
144 // XServiceInfo
145 //______________________________________________________________________________
getImplementationName()146 OUString ExpandContentProviderImpl::getImplementationName()
147 {
148 check();
149 return implName();
150 }
151
152 //______________________________________________________________________________
getSupportedServiceNames()153 uno::Sequence< OUString > ExpandContentProviderImpl::getSupportedServiceNames()
154 {
155 check();
156 return supportedServices();
157 }
158
159 //______________________________________________________________________________
supportsService(OUString const & serviceName)160 sal_Bool ExpandContentProviderImpl::supportsService(
161 OUString const & serviceName )
162 {
163 // check();
164 uno::Sequence< OUString > supported_services( getSupportedServiceNames() );
165 OUString const * ar = supported_services.getConstArray();
166 for ( sal_Int32 pos = supported_services.getLength(); pos--; )
167 {
168 if (ar[ pos ].equals( serviceName ))
169 return true;
170 }
171 return false;
172 }
173
174 //______________________________________________________________________________
expandUri(uno::Reference<ucb::XContentIdentifier> const & xIdentifier) const175 OUString ExpandContentProviderImpl::expandUri(
176 uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const
177 {
178 OUString uri( xIdentifier->getContentIdentifier() );
179 if (uri.compareToAscii(
180 RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ) != 0)
181 {
182 throw ucb::IllegalIdentifierException(
183 OUSTR("expected protocol " EXPAND_PROTOCOL "!"),
184 static_cast< OWeakObject * >(
185 const_cast< ExpandContentProviderImpl * >(this) ) );
186 }
187 // cut protocol
188 OUString str( uri.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
189 // decode uric class chars
190 str = ::rtl::Uri::decode(
191 str, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
192 // expand macro string
193 return m_xMacroExpander->expandMacros( str );
194 }
195
196 // XContentProvider
197 //______________________________________________________________________________
queryContent(uno::Reference<ucb::XContentIdentifier> const & xIdentifier)198 uno::Reference< ucb::XContent > ExpandContentProviderImpl::queryContent(
199 uno::Reference< ucb::XContentIdentifier > const & xIdentifier )
200 {
201 check();
202 OUString uri( expandUri( xIdentifier ) );
203
204 ::ucbhelper::Content ucb_content;
205 if (::ucbhelper::Content::create(
206 uri, uno::Reference< ucb::XCommandEnvironment >(), ucb_content ))
207 {
208 return ucb_content.get();
209 }
210 else
211 {
212 return uno::Reference< ucb::XContent >();
213 }
214 }
215
216 //______________________________________________________________________________
compareContentIds(uno::Reference<ucb::XContentIdentifier> const & xId1,uno::Reference<ucb::XContentIdentifier> const & xId2)217 sal_Int32 ExpandContentProviderImpl::compareContentIds(
218 uno::Reference< ucb::XContentIdentifier > const & xId1,
219 uno::Reference< ucb::XContentIdentifier > const & xId2 )
220 {
221 check();
222 try
223 {
224 OUString uri1( expandUri( xId1 ) );
225 OUString uri2( expandUri( xId2 ) );
226 return uri1.compareTo( uri2 );
227 }
228 catch (ucb::IllegalIdentifierException & exc)
229 {
230 (void) exc; // unused
231 OSL_ENSURE(
232 0, ::rtl::OUStringToOString(
233 exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
234 return -1;
235 }
236 }
237
238 static const ::cppu::ImplementationEntry s_entries [] =
239 {
240 {
241 create,
242 implName,
243 supportedServices,
244 ::cppu::createSingleComponentFactory,
245 0, 0
246 },
247 { 0, 0, 0, 0, 0, 0 }
248 };
249
250 }
251
252 extern "C"
253 {
254
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)255 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
256 const sal_Char ** ppEnvTypeName, uno_Environment ** )
257 {
258 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
259 }
260
component_getFactory(const sal_Char * pImplName,lang::XMultiServiceFactory * pServiceManager,registry::XRegistryKey * pRegistryKey)261 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
262 const sal_Char * pImplName,
263 lang::XMultiServiceFactory * pServiceManager,
264 registry::XRegistryKey * pRegistryKey )
265 {
266 return ::cppu::component_getFactoryHelper(
267 pImplName, pServiceManager, pRegistryKey, s_entries );
268 }
269
270 }
271