1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_ucb.hxx" 30 31 #include "rtl/uri.hxx" 32 #include "osl/mutex.hxx" 33 #include "cppuhelper/compbase2.hxx" 34 #include "cppuhelper/factory.hxx" 35 #include "cppuhelper/implementationentry.hxx" 36 #include "ucbhelper/content.hxx" 37 #include "com/sun/star/uno/XComponentContext.hpp" 38 #include "com/sun/star/lang/DisposedException.hpp" 39 #include "com/sun/star/lang/XServiceInfo.hpp" 40 #include "com/sun/star/lang/XMultiServiceFactory.hpp" 41 #include "com/sun/star/registry/XRegistryKey.hpp" 42 #include "com/sun/star/util/XMacroExpander.hpp" 43 #include "com/sun/star/ucb/XContentProvider.hpp" 44 45 #define EXPAND_PROTOCOL "vnd.sun.star.expand" 46 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 47 #define ARLEN(x) sizeof (x) / sizeof *(x) 48 49 50 using namespace ::com::sun::star; 51 using ::rtl::OUString; 52 53 namespace 54 { 55 56 struct MutexHolder 57 { 58 mutable ::osl::Mutex m_mutex; 59 }; 60 61 typedef ::cppu::WeakComponentImplHelper2< 62 lang::XServiceInfo, ucb::XContentProvider > t_impl_helper; 63 64 //============================================================================== 65 class ExpandContentProviderImpl : protected MutexHolder, public t_impl_helper 66 { 67 uno::Reference< util::XMacroExpander > m_xMacroExpander; 68 OUString expandUri( 69 uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const; 70 71 protected: 72 inline void check() const; 73 virtual void SAL_CALL disposing(); 74 75 public: 76 inline ExpandContentProviderImpl( 77 uno::Reference< uno::XComponentContext > const & xComponentContext ) 78 : t_impl_helper( m_mutex ), 79 m_xMacroExpander( 80 xComponentContext->getValueByName( 81 OUSTR("/singletons/com.sun.star.util.theMacroExpander") ), 82 uno::UNO_QUERY_THROW ) 83 {} 84 virtual ~ExpandContentProviderImpl() throw (); 85 86 // XServiceInfo 87 virtual OUString SAL_CALL getImplementationName() 88 throw (uno::RuntimeException); 89 virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName ) 90 throw (uno::RuntimeException); 91 virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() 92 throw (uno::RuntimeException); 93 94 // XContentProvider 95 virtual uno::Reference< ucb::XContent > SAL_CALL queryContent( 96 uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) 97 throw (ucb::IllegalIdentifierException, uno::RuntimeException); 98 virtual sal_Int32 SAL_CALL compareContentIds( 99 uno::Reference< ucb::XContentIdentifier > const & xId1, 100 uno::Reference< ucb::XContentIdentifier > const & xId2 ) 101 throw (uno::RuntimeException); 102 }; 103 104 //______________________________________________________________________________ 105 inline void ExpandContentProviderImpl::check() const 106 { 107 // xxx todo guard? 108 // MutexGuard guard( m_mutex ); 109 if (rBHelper.bInDispose || rBHelper.bDisposed) 110 { 111 throw lang::DisposedException( 112 OUSTR("expand content provider instance has " 113 "already been disposed!"), 114 static_cast< OWeakObject * >( 115 const_cast< ExpandContentProviderImpl * >(this) ) ); 116 } 117 } 118 119 //______________________________________________________________________________ 120 ExpandContentProviderImpl::~ExpandContentProviderImpl() throw () 121 { 122 } 123 124 //______________________________________________________________________________ 125 void ExpandContentProviderImpl::disposing() 126 { 127 } 128 129 //============================================================================== 130 static uno::Reference< uno::XInterface > SAL_CALL create( 131 uno::Reference< uno::XComponentContext > const & xComponentContext ) 132 SAL_THROW( (uno::Exception) ) 133 { 134 return static_cast< ::cppu::OWeakObject * >( 135 new ExpandContentProviderImpl( xComponentContext ) ); 136 } 137 138 //============================================================================== 139 static OUString SAL_CALL implName() 140 { 141 return OUSTR("com.sun.star.comp.ucb.ExpandContentProvider"); 142 } 143 144 //============================================================================== 145 static uno::Sequence< OUString > SAL_CALL supportedServices() 146 { 147 OUString names [] = { 148 OUSTR("com.sun.star.ucb.ExpandContentProvider"), 149 OUSTR("com.sun.star.ucb.ContentProvider") 150 }; 151 return uno::Sequence< OUString >( names, ARLEN(names) ); 152 } 153 154 // XServiceInfo 155 //______________________________________________________________________________ 156 OUString ExpandContentProviderImpl::getImplementationName() 157 throw (uno::RuntimeException) 158 { 159 check(); 160 return implName(); 161 } 162 163 //______________________________________________________________________________ 164 uno::Sequence< OUString > ExpandContentProviderImpl::getSupportedServiceNames() 165 throw (uno::RuntimeException) 166 { 167 check(); 168 return supportedServices(); 169 } 170 171 //______________________________________________________________________________ 172 sal_Bool ExpandContentProviderImpl::supportsService( 173 OUString const & serviceName ) 174 throw (uno::RuntimeException) 175 { 176 // check(); 177 uno::Sequence< OUString > supported_services( getSupportedServiceNames() ); 178 OUString const * ar = supported_services.getConstArray(); 179 for ( sal_Int32 pos = supported_services.getLength(); pos--; ) 180 { 181 if (ar[ pos ].equals( serviceName )) 182 return true; 183 } 184 return false; 185 } 186 187 //______________________________________________________________________________ 188 OUString ExpandContentProviderImpl::expandUri( 189 uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const 190 { 191 OUString uri( xIdentifier->getContentIdentifier() ); 192 if (uri.compareToAscii( 193 RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ) != 0) 194 { 195 throw ucb::IllegalIdentifierException( 196 OUSTR("expected protocol " EXPAND_PROTOCOL "!"), 197 static_cast< OWeakObject * >( 198 const_cast< ExpandContentProviderImpl * >(this) ) ); 199 } 200 // cut protocol 201 OUString str( uri.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) ); 202 // decode uric class chars 203 str = ::rtl::Uri::decode( 204 str, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); 205 // expand macro string 206 return m_xMacroExpander->expandMacros( str ); 207 } 208 209 // XContentProvider 210 //______________________________________________________________________________ 211 uno::Reference< ucb::XContent > ExpandContentProviderImpl::queryContent( 212 uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) 213 throw (ucb::IllegalIdentifierException, uno::RuntimeException) 214 { 215 check(); 216 OUString uri( expandUri( xIdentifier ) ); 217 218 ::ucbhelper::Content ucb_content; 219 if (::ucbhelper::Content::create( 220 uri, uno::Reference< ucb::XCommandEnvironment >(), ucb_content )) 221 { 222 return ucb_content.get(); 223 } 224 else 225 { 226 return uno::Reference< ucb::XContent >(); 227 } 228 } 229 230 //______________________________________________________________________________ 231 sal_Int32 ExpandContentProviderImpl::compareContentIds( 232 uno::Reference< ucb::XContentIdentifier > const & xId1, 233 uno::Reference< ucb::XContentIdentifier > const & xId2 ) 234 throw (uno::RuntimeException) 235 { 236 check(); 237 try 238 { 239 OUString uri1( expandUri( xId1 ) ); 240 OUString uri2( expandUri( xId2 ) ); 241 return uri1.compareTo( uri2 ); 242 } 243 catch (ucb::IllegalIdentifierException & exc) 244 { 245 (void) exc; // unused 246 OSL_ENSURE( 247 0, ::rtl::OUStringToOString( 248 exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); 249 return -1; 250 } 251 } 252 253 static const ::cppu::ImplementationEntry s_entries [] = 254 { 255 { 256 create, 257 implName, 258 supportedServices, 259 ::cppu::createSingleComponentFactory, 260 0, 0 261 }, 262 { 0, 0, 0, 0, 0, 0 } 263 }; 264 265 } 266 267 extern "C" 268 { 269 270 void SAL_CALL component_getImplementationEnvironment( 271 const sal_Char ** ppEnvTypeName, uno_Environment ** ) 272 { 273 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 274 } 275 276 void * SAL_CALL component_getFactory( 277 const sal_Char * pImplName, 278 lang::XMultiServiceFactory * pServiceManager, 279 registry::XRegistryKey * pRegistryKey ) 280 { 281 return ::cppu::component_getFactoryHelper( 282 pImplName, pServiceManager, pRegistryKey, s_entries ); 283 } 284 285 } 286