blob: 4b1410684d2072577b2206c90ace8c3cf4ce25d5 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_ucb.hxx"
#include "rtl/uri.hxx"
#include "osl/mutex.hxx"
#include "cppuhelper/compbase2.hxx"
#include "cppuhelper/factory.hxx"
#include "cppuhelper/implementationentry.hxx"
#include "ucbhelper/content.hxx"
#include "com/sun/star/uno/XComponentContext.hpp"
#include "com/sun/star/lang/DisposedException.hpp"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/lang/XMultiServiceFactory.hpp"
#include "com/sun/star/registry/XRegistryKey.hpp"
#include "com/sun/star/util/XMacroExpander.hpp"
#include "com/sun/star/ucb/XContentProvider.hpp"
#define EXPAND_PROTOCOL "vnd.sun.star.expand"
#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
#define ARLEN(x) sizeof (x) / sizeof *(x)
using namespace ::com::sun::star;
using ::rtl::OUString;
namespace
{
struct MutexHolder
{
mutable ::osl::Mutex m_mutex;
};
typedef ::cppu::WeakComponentImplHelper2<
lang::XServiceInfo, ucb::XContentProvider > t_impl_helper;
//==============================================================================
class ExpandContentProviderImpl : protected MutexHolder, public t_impl_helper
{
uno::Reference< util::XMacroExpander > m_xMacroExpander;
OUString expandUri(
uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const;
protected:
inline void check() const;
virtual void SAL_CALL disposing();
public:
inline ExpandContentProviderImpl(
uno::Reference< uno::XComponentContext > const & xComponentContext )
: t_impl_helper( m_mutex ),
m_xMacroExpander(
xComponentContext->getValueByName(
OUSTR("/singletons/com.sun.star.util.theMacroExpander") ),
uno::UNO_QUERY_THROW )
{}
virtual ~ExpandContentProviderImpl() throw ();
// XServiceInfo
virtual OUString SAL_CALL getImplementationName()
throw (uno::RuntimeException);
virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
throw (uno::RuntimeException);
virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames()
throw (uno::RuntimeException);
// XContentProvider
virtual uno::Reference< ucb::XContent > SAL_CALL queryContent(
uno::Reference< ucb::XContentIdentifier > const & xIdentifier )
throw (ucb::IllegalIdentifierException, uno::RuntimeException);
virtual sal_Int32 SAL_CALL compareContentIds(
uno::Reference< ucb::XContentIdentifier > const & xId1,
uno::Reference< ucb::XContentIdentifier > const & xId2 )
throw (uno::RuntimeException);
};
//______________________________________________________________________________
inline void ExpandContentProviderImpl::check() const
{
// xxx todo guard?
// MutexGuard guard( m_mutex );
if (rBHelper.bInDispose || rBHelper.bDisposed)
{
throw lang::DisposedException(
OUSTR("expand content provider instance has "
"already been disposed!"),
static_cast< OWeakObject * >(
const_cast< ExpandContentProviderImpl * >(this) ) );
}
}
//______________________________________________________________________________
ExpandContentProviderImpl::~ExpandContentProviderImpl() throw ()
{
}
//______________________________________________________________________________
void ExpandContentProviderImpl::disposing()
{
}
//==============================================================================
static uno::Reference< uno::XInterface > SAL_CALL create(
uno::Reference< uno::XComponentContext > const & xComponentContext )
SAL_THROW( (uno::Exception) )
{
return static_cast< ::cppu::OWeakObject * >(
new ExpandContentProviderImpl( xComponentContext ) );
}
//==============================================================================
static OUString SAL_CALL implName()
{
return OUSTR("com.sun.star.comp.ucb.ExpandContentProvider");
}
//==============================================================================
static uno::Sequence< OUString > SAL_CALL supportedServices()
{
OUString names [] = {
OUSTR("com.sun.star.ucb.ExpandContentProvider"),
OUSTR("com.sun.star.ucb.ContentProvider")
};
return uno::Sequence< OUString >( names, ARLEN(names) );
}
// XServiceInfo
//______________________________________________________________________________
OUString ExpandContentProviderImpl::getImplementationName()
throw (uno::RuntimeException)
{
check();
return implName();
}
//______________________________________________________________________________
uno::Sequence< OUString > ExpandContentProviderImpl::getSupportedServiceNames()
throw (uno::RuntimeException)
{
check();
return supportedServices();
}
//______________________________________________________________________________
sal_Bool ExpandContentProviderImpl::supportsService(
OUString const & serviceName )
throw (uno::RuntimeException)
{
// check();
uno::Sequence< OUString > supported_services( getSupportedServiceNames() );
OUString const * ar = supported_services.getConstArray();
for ( sal_Int32 pos = supported_services.getLength(); pos--; )
{
if (ar[ pos ].equals( serviceName ))
return true;
}
return false;
}
//______________________________________________________________________________
OUString ExpandContentProviderImpl::expandUri(
uno::Reference< ucb::XContentIdentifier > const & xIdentifier ) const
{
OUString uri( xIdentifier->getContentIdentifier() );
if (uri.compareToAscii(
RTL_CONSTASCII_STRINGPARAM(EXPAND_PROTOCOL ":") ) != 0)
{
throw ucb::IllegalIdentifierException(
OUSTR("expected protocol " EXPAND_PROTOCOL "!"),
static_cast< OWeakObject * >(
const_cast< ExpandContentProviderImpl * >(this) ) );
}
// cut protocol
OUString str( uri.copy( sizeof (EXPAND_PROTOCOL ":") -1 ) );
// decode uric class chars
str = ::rtl::Uri::decode(
str, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
// expand macro string
return m_xMacroExpander->expandMacros( str );
}
// XContentProvider
//______________________________________________________________________________
uno::Reference< ucb::XContent > ExpandContentProviderImpl::queryContent(
uno::Reference< ucb::XContentIdentifier > const & xIdentifier )
throw (ucb::IllegalIdentifierException, uno::RuntimeException)
{
check();
OUString uri( expandUri( xIdentifier ) );
::ucbhelper::Content ucb_content;
if (::ucbhelper::Content::create(
uri, uno::Reference< ucb::XCommandEnvironment >(), ucb_content ))
{
return ucb_content.get();
}
else
{
return uno::Reference< ucb::XContent >();
}
}
//______________________________________________________________________________
sal_Int32 ExpandContentProviderImpl::compareContentIds(
uno::Reference< ucb::XContentIdentifier > const & xId1,
uno::Reference< ucb::XContentIdentifier > const & xId2 )
throw (uno::RuntimeException)
{
check();
try
{
OUString uri1( expandUri( xId1 ) );
OUString uri2( expandUri( xId2 ) );
return uri1.compareTo( uri2 );
}
catch (ucb::IllegalIdentifierException & exc)
{
(void) exc; // unused
OSL_ENSURE(
0, ::rtl::OUStringToOString(
exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
return -1;
}
}
static const ::cppu::ImplementationEntry s_entries [] =
{
{
create,
implName,
supportedServices,
::cppu::createSingleComponentFactory,
0, 0
},
{ 0, 0, 0, 0, 0, 0 }
};
}
extern "C"
{
void SAL_CALL component_getImplementationEnvironment(
const sal_Char ** ppEnvTypeName, uno_Environment ** )
{
*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
void * SAL_CALL component_getFactory(
const sal_Char * pImplName,
lang::XMultiServiceFactory * pServiceManager,
registry::XRegistryKey * pRegistryKey )
{
return ::cppu::component_getFactoryHelper(
pImplName, pServiceManager, pRegistryKey, s_entries );
}
}