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