24#include <com/sun/star/beans/PropertyAttribute.hpp>
25#include <com/sun/star/beans/XPropertySetInfo.hpp>
26#include <com/sun/star/lang/IllegalAccessException.hpp>
27#include <com/sun/star/sdbc/XRow.hpp>
28#include <com/sun/star/ucb/XCommandInfo.hpp>
29#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
30#include <com/sun/star/ucb/OpenMode.hpp>
31#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
32#include <com/sun/star/ucb/XDynamicResultSet.hpp>
33#include <com/sun/star/deployment/PackageInformationProvider.hpp>
40#include <rtl/ustrbuf.hxx>
53 using ::com::sun::star::uno::Reference;
54 using ::com::sun::star::uno::UNO_SET_THROW;
55 using ::com::sun::star::uno::Exception;
56 using ::com::sun::star::uno::Any;
57 using ::com::sun::star::uno::Sequence;
58 using ::com::sun::star::uno::XComponentContext;
59 using ::com::sun::star::ucb::XContentIdentifier;
60 using ::com::sun::star::ucb::XCommandEnvironment;
61 using ::com::sun::star::ucb::Command;
62 using ::com::sun::star::beans::Property;
63 using ::com::sun::star::lang::IllegalArgumentException;
64 using ::com::sun::star::beans::PropertyValue;
65 using ::com::sun::star::ucb::OpenCommandArgument2;
66 using ::com::sun::star::ucb::XDynamicResultSet;
67 using ::com::sun::star::ucb::UnsupportedCommandException;
68 using ::com::sun::star::sdbc::XRow;
69 using ::com::sun::star::beans::PropertyChangeEvent;
70 using ::com::sun::star::lang::IllegalAccessException;
71 using ::com::sun::star::ucb::CommandInfo;
72 using ::com::sun::star::deployment::PackageInformationProvider;
73 using ::com::sun::star::deployment::XPackageInformationProvider;
75 namespace OpenMode = ::com::sun::star::ucb::OpenMode;
76 namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
84 OUString lcl_compose( std::u16string_view i_rBaseURL,
const OUString& i_rRelativeURL )
88 OUStringBuffer aComposer( i_rBaseURL );
90 aComposer.append(
'/' );
91 aComposer.append( i_rRelativeURL );
92 return aComposer.makeStringAndClear();
96 struct SelectPropertyName
98 const OUString& operator()(
const Property& i_rProperty )
const
100 return i_rProperty.Name;
110 const Reference< XContentIdentifier >& i_rIdentifier )
114 const OUString sURL(
getIdentifier()->getContentIdentifier() );
115 if ( denotesRootContent( sURL ) )
117 m_eExtContentType =
E_ROOT;
122 const size_t nSepPos = sRelativeURL.find(
'/' );
123 if ( ( nSepPos == std::u16string_view::npos ) || ( nSepPos == sRelativeURL.size() - 1 ) )
133 if ( m_eExtContentType ==
E_ROOT )
137 m_sExtensionId = sURL.copy( sRootURL.getLength() );
139 const sal_Int32 nNextSep = m_sExtensionId.indexOf(
'/' );
142 m_sPathIntoExtension = m_sExtensionId.copy( nNextSep + 1 );
143 m_sExtensionId = m_sExtensionId.copy( 0, nNextSep );
156 return "org.openoffice.comp.ucp.ext.Content";
162 return {
"com.sun.star.ucb.Content",
"com.sun.star.ucb.ExtensionContent" };
173 Any SAL_CALL
Content::execute(
const Command& aCommand, sal_Int32 ,
const Reference< XCommandEnvironment >& i_rEnvironment )
177 if (
aCommand.Name ==
"getPropertyValues" )
180 if ( !(
aCommand.Argument >>= Properties ) )
182 ::ucbhelper::cancelCommandExecution(
Any( IllegalArgumentException(
183 OUString(), *
this, -1 ) ),
190 else if (
aCommand.Name ==
"setPropertyValues" )
193 if ( !(
aCommand.Argument >>= aProperties ) )
195 ::ucbhelper::cancelCommandExecution(
Any( IllegalArgumentException(
196 OUString(), *
this, -1 ) ),
203 ::ucbhelper::cancelCommandExecution(
Any( IllegalArgumentException(
204 OUString(), *
this, -1 ) ),
211 else if (
aCommand.Name ==
"getPropertySetInfo" )
216 else if (
aCommand.Name ==
"getCommandInfo" )
223 OpenCommandArgument2 aOpenCommand;
224 if ( !(
aCommand.Argument >>= aOpenCommand ) )
226 ::ucbhelper::cancelCommandExecution(
Any( IllegalArgumentException(
227 OUString(), *
this, -1 ) ),
233 ( ( aOpenCommand.Mode == OpenMode::ALL ) ||
234 ( aOpenCommand.Mode == OpenMode::FOLDERS ) ||
235 ( aOpenCommand.Mode == OpenMode::DOCUMENTS ) );
240 Reference< XDynamicResultSet > xSet =
new ResultSet(
m_xContext,
this, aOpenCommand, i_rEnvironment );
244 if ( aOpenCommand.Sink.is() )
248 aRet = aRequestedContent.executeCommand(
"open",
Any( aOpenCommand ) );
254 ::ucbhelper::cancelCommandExecution(
Any( UnsupportedCommandException(
255 OUString(), *
this ) ),
271 return ::rtl::Uri::encode( i_rIdentifier, rtl_UriCharClassRegName, rtl_UriEncodeIgnoreEscapes,
272 RTL_TEXTENCODING_UTF8 );
278 return ::rtl::Uri::decode( i_rIdentifier, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
285 if ( i_rContentIdentifier == sRootURL )
290 && ( sal_Int32(i_rContentIdentifier.size()) == sRootURL.getLength() + 1 )
291 && ( i_rContentIdentifier[ i_rContentIdentifier.size() - 1 ] ==
'/' )
318 if ( !sURL.match( sRootURL ) )
320 SAL_INFO(
"ucb.ucp.ext",
"illegal URL structure - no root" );
324 OUString sRelativeURL( sURL.copy( sRootURL.getLength() ) );
328 if ( !sRelativeURL.match( sSeparatedExtensionId ) )
330 SAL_INFO(
"ucb.ucp.ext",
"illegal URL structure - no extension ID" );
334 sRelativeURL = sRelativeURL.copy( sSeparatedExtensionId.getLength() );
337 if ( sRelativeURL.isEmpty() )
339 SAL_INFO(
"ucb.ucp.ext",
"illegal URL structure - ExtensionContent should have a level below the extension ID" );
343 if ( sRelativeURL.endsWith(
"/") )
344 sRelativeURL = sRelativeURL.copy( 0, sRelativeURL.getLength() - 1 );
347 const sal_Int32 nLastSep = sRelativeURL.lastIndexOf(
'/' );
348 sRelativeURL = sRelativeURL.copy( 0, nLastSep != -1 ? nLastSep : 0 );
350 return sRootURL + sSeparatedExtensionId + sRelativeURL;
354 OSL_FAIL(
"Content::getParentURL: unhandled case!" );
362 const Sequence< Property >& i_rProperties,
const OUString& i_rTitle )
367 if ( i_rProperties.hasElements() )
369 for (
const Property& rProp : i_rProperties )
372 if ( rProp.Name ==
"ContentType" )
376 else if ( rProp.Name ==
"Title" )
378 xRow->appendString ( rProp, i_rTitle );
380 else if ( rProp.Name ==
"IsDocument" )
382 xRow->appendBoolean( rProp,
false );
384 else if ( rProp.Name ==
"IsFolder" )
386 xRow->appendBoolean( rProp,
true );
391 xRow->appendVoid( rProp );
398 xRow->appendString (
Property(
"ContentType",
401 PropertyAttribute::BOUND | PropertyAttribute::READONLY ),
403 xRow->appendString (
Property(
"Title",
406 PropertyAttribute::BOUND | PropertyAttribute::READONLY ),
408 xRow->appendBoolean(
Property(
"IsDocument",
411 PropertyAttribute::BOUND | PropertyAttribute::READONLY ),
413 xRow->appendBoolean(
Property(
"IsFolder",
416 PropertyAttribute::BOUND | PropertyAttribute::READONLY ),
429 const Reference< XPackageInformationProvider > xPackageInfo = PackageInformationProvider::get(
m_xContext);
430 const OUString sPackageLocation( xPackageInfo->getPackageLocation(
m_sExtensionId ) );
433 return sPackageLocation;
438 Reference< XRow >
Content::getPropertyValues(
const Sequence< Property >& i_rProperties,
const Reference< XCommandEnvironment >& i_rEnv )
440 ::osl::Guard< ::osl::Mutex > aGuard(
m_aMutex );
454 Sequence< OUString > aPropertyNames( i_rProperties.getLength() );
456 i_rProperties.begin(),
458 aPropertyNames.getArray(),
461 const Sequence< Any >
aPropertyValues = aRequestedContent.getPropertyValues( aPropertyNames );
462 const ::rtl::Reference< ::ucbhelper::PropertyValueSet > xValueRow = new ::ucbhelper::PropertyValueSet(
m_xContext );
469 xValueRow->appendObject( aPropertyNames[i], *value );
475 OSL_FAIL(
"Content::getPropertyValues: unhandled case!" );
479 OSL_FAIL(
"Content::getPropertyValues: unreachable!" );
486 ::osl::ClearableGuard< osl::Mutex > aGuard(
m_aMutex );
488 Sequence< Any > aRet( i_rValues.getLength() );
490 PropertyChangeEvent
aEvent;
491 aEvent.Source = getXWeak();
493 aEvent.PropertyHandle = -1;
495 for (
auto& rRet : asNonConstRange(aRet) )
498 rRet <<= IllegalAccessException(
"property is read-only.", *
this );
507 static const CommandInfo aCommandInfoTable[] =
517 "getPropertySetInfo",
541 return Sequence< CommandInfo >( aCommandInfoTable,
SAL_N_ELEMENTS(aCommandInfoTable) );
553 PropertyAttribute::BOUND | PropertyAttribute::READONLY
559 PropertyAttribute::BOUND | PropertyAttribute::READONLY
565 PropertyAttribute::BOUND | PropertyAttribute::READONLY
571 PropertyAttribute::BOUND | PropertyAttribute::READONLY
574 return Sequence< Property >( aProperties,
SAL_N_ELEMENTS( aProperties ) );
583 bool bIsFolder =
false;
586 Sequence< Property > aProps{ {
"IsFolder", {}, {}, {} } };
588 bIsFolder = xRow->getBoolean(1);
610 Sequence< Property > aProps{ {
"ContentType", {}, {}, {} } };
PropertyValueVector_t aPropertyValues
PropertiesInfo aProperties
static OUString getRootURL()
static OUString getArtificialNodeContentType()
css::uno::Sequence< css::uno::Any > setPropertyValues(const css::uno::Sequence< css::beans::PropertyValue > &rValues)
ExtensionContentType m_eExtContentType
virtual OUString SAL_CALL getContentType() override
void impl_determineContentType()
::std::optional< OUString > m_aContentType
virtual css::uno::Any SAL_CALL execute(const css::ucb::Command &aCommand, sal_Int32 CommandId, const css::uno::Reference< css::ucb::XCommandEnvironment > &Environment) override
css::uno::Reference< css::sdbc::XRow > getPropertyValues(const css::uno::Sequence< css::beans::Property > &rProperties, const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv)
Content(const css::uno::Reference< css::uno::XComponentContext > &rxContext, ::ucbhelper::ContentProviderImplHelper *pProvider, const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier)
static OUString encodeIdentifier(const OUString &i_rIdentifier)
virtual css::uno::Sequence< css::ucb::CommandInfo > getCommands(const css::uno::Reference< css::ucb::XCommandEnvironment > &i_rEnv) override
static css::uno::Reference< css::sdbc::XRow > getArtificialNodePropertyValues(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Sequence< css::beans::Property > &rProperties, const OUString &rTitle)
virtual OUString getParentURL() override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
static bool denotesRootContent(std::u16string_view i_rContentIdentifier)
virtual ~Content() override
::std::optional< bool > m_aIsFolder
OUString m_sPathIntoExtension
static OUString decodeIdentifier(const OUString &i_rIdentifier)
virtual OUString SAL_CALL getImplementationName() override
virtual css::uno::Sequence< css::beans::Property > getProperties(const css::uno::Reference< css::ucb::XCommandEnvironment > &i_rEnv) override
OUString getPhysicalURL() const
retrieves the URL of the underlying physical content.
virtual void SAL_CALL abort(sal_Int32 CommandId) override
css::uno::Reference< css::ucb::XCommandInfo > getCommandInfo(const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv, bool bCache=true)
css::uno::Reference< css::beans::XPropertySetInfo > getPropertySetInfo(const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv, bool bCache=true)
css::uno::Reference< css::ucb::XContentIdentifier > m_xIdentifier
css::uno::Reference< css::uno::XComponentContext > m_xContext
#define ENSURE_OR_RETURN(c, m, r)
#define DBG_UNHANDLED_EXCEPTION(...)
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString getIdentifier(css::uno::Reference< css::deployment::XPackage > const &package)
constexpr bool ends_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
::ucbhelper::ContentImplHelper Content_Base