xref: /trunk/main/ucb/source/ucp/expand/ucpexpand.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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