1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 #include "precompiled_ucb.hxx" 28 29 #include "ucpext_provider.hxx" 30 #include "ucpext_content.hxx" 31 32 /** === begin UNO includes === **/ 33 /** === end UNO includes === **/ 34 35 #include <ucbhelper/contentidentifier.hxx> 36 #include <osl/diagnose.h> 37 #include <osl/mutex.hxx> 38 #include <comphelper/componentcontext.hxx> 39 #include <rtl/ustrbuf.hxx> 40 41 //...................................................................................................................... 42 namespace ucb { namespace ucp { namespace ext 43 { 44 //...................................................................................................................... 45 46 /** === begin UNO using === **/ 47 using ::com::sun::star::uno::Reference; 48 using ::com::sun::star::uno::XInterface; 49 using ::com::sun::star::uno::UNO_QUERY; 50 using ::com::sun::star::uno::UNO_QUERY_THROW; 51 using ::com::sun::star::uno::UNO_SET_THROW; 52 using ::com::sun::star::uno::Exception; 53 using ::com::sun::star::uno::RuntimeException; 54 using ::com::sun::star::uno::Any; 55 using ::com::sun::star::uno::makeAny; 56 using ::com::sun::star::uno::Sequence; 57 using ::com::sun::star::uno::Type; 58 using ::com::sun::star::lang::XMultiServiceFactory; 59 using ::com::sun::star::ucb::XContentIdentifier; 60 using ::com::sun::star::ucb::IllegalIdentifierException; 61 using ::com::sun::star::ucb::XContent; 62 using ::com::sun::star::uno::XComponentContext; 63 /** === end UNO using === **/ 64 65 //================================================================================================================== 66 //= ContentProvider 67 //================================================================================================================== 68 //------------------------------------------------------------------------------------------------------------------ 69 ContentProvider::ContentProvider( const Reference< XMultiServiceFactory >& i_rServiceManager ) 70 :ContentProvider_Base( i_rServiceManager ) 71 { 72 } 73 74 //------------------------------------------------------------------------------------------------------------------ 75 ContentProvider::~ContentProvider() 76 { 77 } 78 79 //------------------------------------------------------------------------------------------------------------------ 80 ::rtl::OUString SAL_CALL ContentProvider::getImplementationName_static() throw (RuntimeException) 81 { 82 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.ucp.ext.ContentProvider" ) ); 83 } 84 85 //------------------------------------------------------------------------------------------------------------------ 86 ::rtl::OUString SAL_CALL ContentProvider::getImplementationName() throw (RuntimeException) 87 { 88 return getImplementationName_static(); 89 } 90 91 //------------------------------------------------------------------------------------------------------------------ 92 Sequence< ::rtl::OUString > SAL_CALL ContentProvider::getSupportedServiceNames_static( ) throw (RuntimeException) 93 { 94 Sequence< ::rtl::OUString > aServiceNames(2); 95 aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.ContentProvider" ) ); 96 aServiceNames[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ucb.ExtensionContentProvider" ) ); 97 return aServiceNames; 98 } 99 100 //------------------------------------------------------------------------------------------------------------------ 101 Sequence< ::rtl::OUString > SAL_CALL ContentProvider::getSupportedServiceNames( ) throw (RuntimeException) 102 { 103 return getSupportedServiceNames_static(); 104 } 105 106 //------------------------------------------------------------------------------------------------------------------ 107 Reference< XInterface > ContentProvider::Create( const Reference< XComponentContext >& i_rContext ) 108 { 109 const ::comphelper::ComponentContext aContext( i_rContext ); 110 return *( new ContentProvider( aContext.getLegacyServiceFactory() ) ); 111 } 112 113 //------------------------------------------------------------------------------------------------------------------ 114 ::rtl::OUString ContentProvider::getRootURL() 115 { 116 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.extension://" ) ); 117 } 118 119 //------------------------------------------------------------------------------------------------------------------ 120 ::rtl::OUString ContentProvider::getArtificialNodeContentType() 121 { 122 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.extension-content" ) ); 123 } 124 125 //------------------------------------------------------------------------------------------------------------------ 126 namespace 127 { 128 void lcl_ensureAndTransfer( ::rtl::OUString& io_rIdentifierFragment, ::rtl::OUStringBuffer& o_rNormalization, const sal_Unicode i_nLeadingChar ) 129 { 130 if ( ( io_rIdentifierFragment.getLength() == 0 ) || ( io_rIdentifierFragment[0] != i_nLeadingChar ) ) 131 throw IllegalIdentifierException(); 132 io_rIdentifierFragment = io_rIdentifierFragment.copy( 1 ); 133 o_rNormalization.append( i_nLeadingChar ); 134 } 135 } 136 137 //------------------------------------------------------------------------------------------------------------------ 138 Reference< XContent > SAL_CALL ContentProvider::queryContent( const Reference< XContentIdentifier >& i_rIdentifier ) 139 throw( IllegalIdentifierException, RuntimeException ) 140 { 141 // Check URL scheme... 142 const ::rtl::OUString sScheme( rtl::OUString::createFromAscii( "vnd.sun.star.extension" ) ); 143 if ( !i_rIdentifier->getContentProviderScheme().equalsIgnoreAsciiCase( sScheme ) ) 144 throw IllegalIdentifierException(); 145 146 // normalize the identifier 147 const ::rtl::OUString sIdentifier( i_rIdentifier->getContentIdentifier() ); 148 149 // the scheme needs to be lower-case 150 ::rtl::OUStringBuffer aComposer; 151 aComposer.append( sIdentifier.copy( 0, sScheme.getLength() ).toAsciiLowerCase() ); 152 153 // one : is required after the scheme 154 ::rtl::OUString sRemaining( sIdentifier.copy( sScheme.getLength() ) ); 155 lcl_ensureAndTransfer( sRemaining, aComposer, ':' ); 156 157 // and at least one / 158 lcl_ensureAndTransfer( sRemaining, aComposer, '/' ); 159 160 // the normalized form requires one additional /, but we also accept identifiers which don't have it 161 if ( sRemaining.getLength() == 0 ) 162 { 163 // the root content is a special case, it requires /// 164 aComposer.appendAscii( "//" ); 165 } 166 else 167 { 168 if ( sRemaining[0] != '/' ) 169 { 170 aComposer.append( sal_Unicode( '/' ) ); 171 aComposer.append( sRemaining ); 172 } 173 else 174 { 175 lcl_ensureAndTransfer( sRemaining, aComposer, '/' ); 176 // by now, we moved "vnd.sun.star.extension://" from the URL to aComposer 177 if ( sRemaining.getLength() == 0 ) 178 { 179 // again, it's the root content, but one / is missing 180 aComposer.append( sal_Unicode( '/' ) ); 181 } 182 else 183 { 184 aComposer.append( sRemaining ); 185 } 186 } 187 } 188 const Reference< XContentIdentifier > xNormalizedIdentifier( new ::ucbhelper::ContentIdentifier( m_xSMgr, aComposer.makeStringAndClear() ) ); 189 190 ::osl::MutexGuard aGuard( m_aMutex ); 191 192 // check if a content with given id already exists... 193 Reference< XContent > xContent( queryExistingContent( xNormalizedIdentifier ).get() ); 194 if ( xContent.is() ) 195 return xContent; 196 197 // create a new content 198 xContent = new Content( m_xSMgr, this, xNormalizedIdentifier ); 199 if ( !xContent->getIdentifier().is() ) 200 throw IllegalIdentifierException(); 201 202 registerNewContent( xContent ); 203 return xContent; 204 } 205 206 //...................................................................................................................... 207 } } } // namespace ucb::ucp::ext 208 //...................................................................................................................... 209