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 #include "precompiled_ucb.hxx" 25 26 #include "ucpext_provider.hxx" 27 #include "ucpext_content.hxx" 28 29 /** === begin UNO includes === **/ 30 /** === end UNO includes === **/ 31 32 #include <ucbhelper/contentidentifier.hxx> 33 #include <osl/diagnose.h> 34 #include <osl/mutex.hxx> 35 #include <comphelper/componentcontext.hxx> 36 #include <rtl/ustrbuf.hxx> 37 38 //...................................................................................................................... 39 namespace ucb { namespace ucp { namespace ext 40 { 41 //...................................................................................................................... 42 43 /** === begin UNO using === **/ 44 using ::com::sun::star::uno::Reference; 45 using ::com::sun::star::uno::XInterface; 46 using ::com::sun::star::uno::UNO_QUERY; 47 using ::com::sun::star::uno::UNO_QUERY_THROW; 48 using ::com::sun::star::uno::UNO_SET_THROW; 49 using ::com::sun::star::uno::Exception; 50 using ::com::sun::star::uno::RuntimeException; 51 using ::com::sun::star::uno::Any; 52 using ::com::sun::star::uno::makeAny; 53 using ::com::sun::star::uno::Sequence; 54 using ::com::sun::star::uno::Type; 55 using ::com::sun::star::lang::XMultiServiceFactory; 56 using ::com::sun::star::ucb::XContentIdentifier; 57 using ::com::sun::star::ucb::IllegalIdentifierException; 58 using ::com::sun::star::ucb::XContent; 59 using ::com::sun::star::uno::XComponentContext; 60 /** === end UNO using === **/ 61 62 //================================================================================================================== 63 //= ContentProvider 64 //================================================================================================================== 65 //------------------------------------------------------------------------------------------------------------------ ContentProvider(const Reference<XMultiServiceFactory> & i_rServiceManager)66 ContentProvider::ContentProvider( const Reference< XMultiServiceFactory >& i_rServiceManager ) 67 :ContentProvider_Base( i_rServiceManager ) 68 { 69 } 70 71 //------------------------------------------------------------------------------------------------------------------ ~ContentProvider()72 ContentProvider::~ContentProvider() 73 { 74 } 75 76 //------------------------------------------------------------------------------------------------------------------ getImplementationName_static()77 ::rtl::OUString SAL_CALL ContentProvider::getImplementationName_static() throw (RuntimeException) 78 { 79 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.ucp.ext.ContentProvider" ) ); 80 } 81 82 //------------------------------------------------------------------------------------------------------------------ getImplementationName()83 ::rtl::OUString SAL_CALL ContentProvider::getImplementationName() throw (RuntimeException) 84 { 85 return getImplementationName_static(); 86 } 87 88 //------------------------------------------------------------------------------------------------------------------ getSupportedServiceNames_static()89 Sequence< ::rtl::OUString > SAL_CALL ContentProvider::getSupportedServiceNames_static( ) throw (RuntimeException) 90 { 91 Sequence< ::rtl::OUString > aServiceNames(2); 92 aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.ContentProvider" ) ); 93 aServiceNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.ExtensionContentProvider" ) ); 94 return aServiceNames; 95 } 96 97 //------------------------------------------------------------------------------------------------------------------ getSupportedServiceNames()98 Sequence< ::rtl::OUString > SAL_CALL ContentProvider::getSupportedServiceNames( ) throw (RuntimeException) 99 { 100 return getSupportedServiceNames_static(); 101 } 102 103 //------------------------------------------------------------------------------------------------------------------ Create(const Reference<XComponentContext> & i_rContext)104 Reference< XInterface > ContentProvider::Create( const Reference< XComponentContext >& i_rContext ) 105 { 106 const ::comphelper::ComponentContext aContext( i_rContext ); 107 return *( new ContentProvider( aContext.getLegacyServiceFactory() ) ); 108 } 109 110 //------------------------------------------------------------------------------------------------------------------ getRootURL()111 ::rtl::OUString ContentProvider::getRootURL() 112 { 113 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.extension://" ) ); 114 } 115 116 //------------------------------------------------------------------------------------------------------------------ getArtificialNodeContentType()117 ::rtl::OUString ContentProvider::getArtificialNodeContentType() 118 { 119 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.extension-content" ) ); 120 } 121 122 //------------------------------------------------------------------------------------------------------------------ 123 namespace 124 { lcl_ensureAndTransfer(::rtl::OUString & io_rIdentifierFragment,::rtl::OUStringBuffer & o_rNormalization,const sal_Unicode i_nLeadingChar)125 void lcl_ensureAndTransfer( ::rtl::OUString& io_rIdentifierFragment, ::rtl::OUStringBuffer& o_rNormalization, const sal_Unicode i_nLeadingChar ) 126 { 127 if ( ( io_rIdentifierFragment.getLength() == 0 ) || ( io_rIdentifierFragment[0] != i_nLeadingChar ) ) 128 throw IllegalIdentifierException(); 129 io_rIdentifierFragment = io_rIdentifierFragment.copy( 1 ); 130 o_rNormalization.append( i_nLeadingChar ); 131 } 132 } 133 134 //------------------------------------------------------------------------------------------------------------------ queryContent(const Reference<XContentIdentifier> & i_rIdentifier)135 Reference< XContent > SAL_CALL ContentProvider::queryContent( const Reference< XContentIdentifier >& i_rIdentifier ) 136 throw( IllegalIdentifierException, RuntimeException ) 137 { 138 // Check URL scheme... 139 const ::rtl::OUString sScheme( rtl::OUString::createFromAscii( "vnd.sun.star.extension" ) ); 140 if ( !i_rIdentifier->getContentProviderScheme().equalsIgnoreAsciiCase( sScheme ) ) 141 throw IllegalIdentifierException(); 142 143 // normalize the identifier 144 const ::rtl::OUString sIdentifier( i_rIdentifier->getContentIdentifier() ); 145 146 // the scheme needs to be lower-case 147 ::rtl::OUStringBuffer aComposer; 148 aComposer.append( sIdentifier.copy( 0, sScheme.getLength() ).toAsciiLowerCase() ); 149 150 // one : is required after the scheme 151 ::rtl::OUString sRemaining( sIdentifier.copy( sScheme.getLength() ) ); 152 lcl_ensureAndTransfer( sRemaining, aComposer, ':' ); 153 154 // and at least one / 155 lcl_ensureAndTransfer( sRemaining, aComposer, '/' ); 156 157 // the normalized form requires one additional /, but we also accept identifiers which don't have it 158 if ( sRemaining.getLength() == 0 ) 159 { 160 // the root content is a special case, it requires /// 161 aComposer.appendAscii( "//" ); 162 } 163 else 164 { 165 if ( sRemaining[0] != '/' ) 166 { 167 aComposer.append( sal_Unicode( '/' ) ); 168 aComposer.append( sRemaining ); 169 } 170 else 171 { 172 lcl_ensureAndTransfer( sRemaining, aComposer, '/' ); 173 // by now, we moved "vnd.sun.star.extension://" from the URL to aComposer 174 if ( sRemaining.getLength() == 0 ) 175 { 176 // again, it's the root content, but one / is missing 177 aComposer.append( sal_Unicode( '/' ) ); 178 } 179 else 180 { 181 aComposer.append( sRemaining ); 182 } 183 } 184 } 185 const Reference< XContentIdentifier > xNormalizedIdentifier( new ::ucbhelper::ContentIdentifier( m_xSMgr, aComposer.makeStringAndClear() ) ); 186 187 ::osl::MutexGuard aGuard( m_aMutex ); 188 189 // check if a content with given id already exists... 190 Reference< XContent > xContent( queryExistingContent( xNormalizedIdentifier ).get() ); 191 if ( xContent.is() ) 192 return xContent; 193 194 // create a new content 195 xContent = new Content( m_xSMgr, this, xNormalizedIdentifier ); 196 if ( !xContent->getIdentifier().is() ) 197 throw IllegalIdentifierException(); 198 199 registerNewContent( xContent ); 200 return xContent; 201 } 202 203 //...................................................................................................................... 204 } } } // namespace ucb::ucp::ext 205 //...................................................................................................................... 206