xref: /trunk/main/ucb/source/ucp/expand/ucpexpand.cxx (revision 421ed02e)
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:
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 //______________________________________________________________________________
101 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 //______________________________________________________________________________
116 ExpandContentProviderImpl::~ExpandContentProviderImpl() throw ()
117 {
118 }
119 
120 //______________________________________________________________________________
121 void ExpandContentProviderImpl::disposing()
122 {
123 }
124 
125 //==============================================================================
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 //==============================================================================
135 static OUString SAL_CALL implName()
136 {
137     return OUSTR("com.sun.star.comp.ucb.ExpandContentProvider");
138 }
139 
140 //==============================================================================
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 //______________________________________________________________________________
152 OUString ExpandContentProviderImpl::getImplementationName()
153     throw (uno::RuntimeException)
154 {
155     check();
156     return implName();
157 }
158 
159 //______________________________________________________________________________
160 uno::Sequence< OUString > ExpandContentProviderImpl::getSupportedServiceNames()
161     throw (uno::RuntimeException)
162 {
163     check();
164     return supportedServices();
165 }
166 
167 //______________________________________________________________________________
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 //______________________________________________________________________________
184 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 //______________________________________________________________________________
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 //______________________________________________________________________________
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 
266 void SAL_CALL component_getImplementationEnvironment(
267 	const sal_Char ** ppEnvTypeName, uno_Environment ** )
268 {
269 	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
270 }
271 
272 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