29#include <osl/diagnose.h>
31#include <rtl/ustring.hxx>
32#include <com/sun/star/beans/IllegalTypeException.hpp>
33#include <com/sun/star/beans/PropertyAttribute.hpp>
34#include <com/sun/star/beans/PropertyExistException.hpp>
35#include <com/sun/star/beans/PropertyState.hpp>
36#include <com/sun/star/container/XEnumerationAccess.hpp>
37#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
38#include <com/sun/star/container/XNameContainer.hpp>
39#include <com/sun/star/container/XNamed.hpp>
40#include <com/sun/star/io/BufferSizeExceededException.hpp>
41#include <com/sun/star/io/NotConnectedException.hpp>
42#include <com/sun/star/io/XActiveDataSink.hpp>
43#include <com/sun/star/io/XOutputStream.hpp>
44#include <com/sun/star/lang/IllegalAccessException.hpp>
45#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
46#include <com/sun/star/ucb/IllegalIdentifierException.hpp>
47#include <com/sun/star/ucb/InsertCommandArgument.hpp>
48#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
49#include <com/sun/star/ucb/MissingInputStreamException.hpp>
50#include <com/sun/star/ucb/NameClash.hpp>
51#include <com/sun/star/ucb/NameClashException.hpp>
52#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
53#include <com/sun/star/ucb/OpenMode.hpp>
54#include <com/sun/star/ucb/TransferInfo.hpp>
55#include <com/sun/star/ucb/UnsupportedCommandException.hpp>
56#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
57#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
58#include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
59#include <com/sun/star/ucb/XCommandInfo.hpp>
60#include <com/sun/star/ucb/XPersistentPropertySet.hpp>
61#include <com/sun/star/util/XChangesBatch.hpp>
62#include <com/sun/star/lang/XSingleServiceFactory.hpp>
63#include <com/sun/star/uno/Any.hxx>
64#include <com/sun/star/uno/Sequence.hxx>
76#include "../inc/urihelper.hxx"
81#define NONE_MODIFIED sal_uInt32( 0x00 )
82#define MEDIATYPE_MODIFIED sal_uInt32( 0x01 )
83#define COMPRESSED_MODIFIED sal_uInt32( 0x02 )
84#define ENCRYPTED_MODIFIED sal_uInt32( 0x04 )
85#define ENCRYPTIONKEY_MODIFIED sal_uInt32( 0x08 )
91ContentProperties::ContentProperties(
const OUString& rContentType )
92: aContentType( rContentType ),
96 bHasEncryptedEntries( false )
102 "ContentProperties::ContentProperties - Unknown type!" );
106uno::Sequence< ucb::ContentInfo >
111 uno::Sequence< beans::Property > aProps( 1 );
112 aProps.getArray()[ 0 ] = beans::Property(
116 beans::PropertyAttribute::BOUND );
118 uno::Sequence< ucb::ContentInfo >
aSeq( 2 );
121 aSeq.getArray()[ 0 ].Type
123 aSeq.getArray()[ 0 ].Attributes
124 = ucb::ContentInfoAttribute::KIND_FOLDER;
125 aSeq.getArray()[ 0 ].Properties = aProps;
128 aSeq.getArray()[ 1 ].Type
130 aSeq.getArray()[ 1 ].Attributes
131 = ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
132 | ucb::ContentInfoAttribute::KIND_DOCUMENT;
133 aSeq.getArray()[ 1 ].Properties = aProps;
139 return uno::Sequence< ucb::ContentInfo >( 0 );
149 const uno::Reference< uno::XComponentContext >& rxContext,
151 const uno::Reference< ucb::XContentIdentifier >& Identifier )
156 uno::Reference< container::XHierarchicalNameAccess > xPackage;
158 if (
loadData( pProvider, aURI, aProps, xPackage ) )
162 sal_Int32 nLastSlash =
aURL.lastIndexOf(
'/' );
163 if ( ( nLastSlash + 1 ) ==
aURL.getLength() )
170 uno::Reference< ucb::XContentIdentifier > xId
171 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
172 return new Content( rxContext, pProvider, xId, xPackage, aURI, std::move(aProps) );
178 bool bFolder =
false;
181 sal_Int32 nLastSlash =
aURL.lastIndexOf(
'/' );
182 if ( ( nLastSlash + 1 ) ==
aURL.getLength() )
185 uno::Reference< ucb::XContentIdentifier > xId
186 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
188 ucb::ContentInfo aInfo;
189 if ( bFolder || aURI.isRootFolder() )
194 return new Content( rxContext, pProvider, xId, xPackage, aURI, aInfo );
201 const uno::Reference< uno::XComponentContext >& rxContext,
203 const uno::Reference< ucb::XContentIdentifier >& Identifier,
204 const ucb::ContentInfo& Info )
206 if (
Info.Type.isEmpty() )
211 if ( !
Info.Type.equalsIgnoreAsciiCase(
213 !
Info.Type.equalsIgnoreAsciiCase(
217 uno::Reference< container::XHierarchicalNameAccess > xPackage = pProvider->
createPackage( aURI );
219 uno::Reference< ucb::XContentIdentifier > xId
220 = new ::ucbhelper::ContentIdentifier( aURI.getUri() );
221 return new Content( rxContext, pProvider, xId, xPackage, std::move(aURI), Info );
227 std::u16string_view aScheme,
bool bFolder )
229 return ( OUString::Concat(
"application/")
232 ? std::u16string_view(
u"-folder")
233 : std::u16string_view(
u"-stream") ) );
238 const uno::Reference< uno::XComponentContext >& rxContext,
240 const uno::Reference< ucb::XContentIdentifier >& Identifier,
241 uno::Reference< container::XHierarchicalNameAccess > Package,
244: ContentImplHelper( rxContext, pProvider,
Identifier ),
245 m_aUri(
std::move( aUri )),
247 m_eState( PERSISTENT ),
249 m_pProvider( pProvider ),
256 const uno::Reference< uno::XComponentContext >& rxContext,
258 const uno::Reference< ucb::XContentIdentifier >& Identifier,
259 uno::Reference< container::XHierarchicalNameAccess > Package,
261 const ucb::ContentInfo& Info )
262 : ContentImplHelper( rxContext, pProvider,
Identifier ),
263 m_aUri(
std::move( aUri )),
267 m_pProvider( pProvider ),
286 ContentImplHelper::acquire();
294 ContentImplHelper::release();
305 rType,
static_cast< ucb::XContentCreator *
>(
this ) );
307 return aRet.
hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
363 return "com.sun.star.comp.ucb.PackageContent";
370 return {
isFolder()? OUString(
"com.sun.star.ucb.PackageFolderContent"):OUString(
"com.sun.star.ucb.PackageStreamContent") } ;
389 const ucb::Command& aCommand,
391 const uno::Reference< ucb::XCommandEnvironment >& Environment )
395 if (
aCommand.Name ==
"getPropertyValues" )
402 if ( !(
aCommand.Argument >>= Properties ) )
405 uno::Any( lang::IllegalArgumentException(
406 "Wrong argument type!",
415 else if (
aCommand.Name ==
"setPropertyValues" )
422 if ( !(
aCommand.Argument >>= aProperties ) )
425 uno::Any( lang::IllegalArgumentException(
426 "Wrong argument type!",
436 uno::Any( lang::IllegalArgumentException(
446 else if (
aCommand.Name ==
"getPropertySetInfo" )
455 else if (
aCommand.Name ==
"getCommandInfo" )
470 ucb::OpenCommandArgument2 aOpenCommand;
471 if ( !(
aCommand.Argument >>= aOpenCommand ) )
474 uno::Any( lang::IllegalArgumentException(
475 "Wrong argument type!",
482 aRet =
open( aOpenCommand, Environment );
490 ucb::InsertCommandArgument aArg;
491 if ( !(
aCommand.Argument >>= aArg ) )
494 uno::Any( lang::IllegalArgumentException(
495 "Wrong argument type!",
502 sal_Int32 nNameClash = aArg.ReplaceExisting
503 ? ucb::NameClash::OVERWRITE
504 : ucb::NameClash::ERROR;
505 insert( aArg.Data, nNameClash, Environment );
513 bool bDeletePhysical =
false;
514 aCommand.Argument >>= bDeletePhysical;
515 destroy( bDeletePhysical, Environment );
525 ucb::IOErrorCode_CANT_WRITE,
528 "Cannot remove persistent data!",
536 else if (
aCommand.Name ==
"transfer" )
543 ucb::TransferInfo aInfo;
544 if ( !(
aCommand.Argument >>= aInfo ) )
547 uno::Any( lang::IllegalArgumentException(
548 "Wrong argument type!",
564 ucb::ContentInfo aInfo;
565 if ( !(
aCommand.Argument >>= aInfo ) )
567 OSL_FAIL(
"Wrong argument type!" );
569 uno::Any( lang::IllegalArgumentException(
570 "Wrong argument type!",
579 else if (
aCommand.Name ==
"flush" )
593 ucb::IOErrorCode_CANT_WRITE,
596 "Cannot write file to disk!",
608 uno::Any( ucb::UnsupportedCommandException(
631uno::Sequence< ucb::ContentInfo > SAL_CALL
639uno::Reference< ucb::XContent > SAL_CALL
644 osl::Guard< osl::Mutex > aGuard(
m_aMutex );
646 if (
Info.Type.isEmpty() )
647 return uno::Reference< ucb::XContent >();
649 if ( !
Info.Type.equalsIgnoreAsciiCase(
651 !
Info.Type.equalsIgnoreAsciiCase(
653 return uno::Reference< ucb::XContent >();
657 if (
Info.Type.equalsIgnoreAsciiCase(
659 aURL +=
"New_Folder";
661 aURL +=
"New_Stream";
663 uno::Reference< ucb::XContentIdentifier > xId(
664 new ::ucbhelper::ContentIdentifier( aURL ) );
670 OSL_FAIL(
"createNewContent called on non-folder object!" );
671 return uno::Reference< ucb::XContent >();
688 const uno::Reference< uno::XComponentContext >& rxContext,
689 const uno::Sequence< beans::Property >& rProperties,
691 const OUString& rContentId )
694 uno::Reference< container::XHierarchicalNameAccess > xPackage;
708 = new ::ucbhelper::PropertyValueSet( rxContext );
710 for (
const beans::Property& rProp : rProperties )
711 xRow->appendVoid( rProp );
720 const uno::Reference< uno::XComponentContext >& rxContext,
721 const uno::Sequence< beans::Property >& rProperties,
725 const OUString& rContentId )
730 = new ::ucbhelper::PropertyValueSet( rxContext );
732 if ( rProperties.hasElements() )
734 uno::Reference< beans::XPropertySet > xAdditionalPropSet;
735 bool bTriedToGetAdditionalPropSet =
false;
737 for (
const beans::Property& rProp : rProperties )
741 if ( rProp.Name ==
"ContentType" )
745 else if ( rProp.Name ==
"Title" )
747 xRow->appendString ( rProp, rData.
aTitle );
749 else if ( rProp.Name ==
"IsDocument" )
753 else if ( rProp.Name ==
"IsFolder" )
755 xRow->appendBoolean( rProp, rData.
bIsFolder );
757 else if ( rProp.Name ==
"CreatableContentsInfo" )
764 else if ( rProp.Name ==
"MediaType" )
766 xRow->appendString ( rProp, rData.
aMediaType );
768 else if ( rProp.Name ==
"Size" )
772 xRow->appendLong( rProp, rData.
nSize );
774 xRow->appendVoid( rProp );
776 else if ( rProp.Name ==
"Compressed" )
782 xRow->appendVoid( rProp );
784 else if ( rProp.Name ==
"Encrypted" )
788 xRow->appendBoolean( rProp, rData.
bEncrypted );
790 xRow->appendVoid( rProp );
792 else if ( rProp.Name ==
"HasEncryptedEntries" )
796 if ( aURI.isRootFolder() )
799 xRow->appendVoid( rProp );
805 if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
808 rProvider->getAdditionalPropertySet( rContentId,
810 bTriedToGetAdditionalPropSet =
true;
813 if ( xAdditionalPropSet.is() )
815 if ( !xRow->appendPropertySetValue(
820 xRow->appendVoid( rProp );
826 xRow->appendVoid( rProp );
839 beans::PropertyAttribute::BOUND
840 | beans::PropertyAttribute::READONLY ),
847 beans::PropertyAttribute::BOUND ),
854 beans::PropertyAttribute::BOUND
855 | beans::PropertyAttribute::READONLY ),
862 beans::PropertyAttribute::BOUND
863 | beans::PropertyAttribute::READONLY ),
867 "CreatableContentsInfo",
870 beans::PropertyAttribute::BOUND
871 | beans::PropertyAttribute::READONLY ),
879 beans::PropertyAttribute::BOUND ),
890 beans::PropertyAttribute::BOUND
891 | beans::PropertyAttribute::READONLY ),
899 beans::PropertyAttribute::BOUND ),
907 beans::PropertyAttribute::BOUND ),
913 if ( aURI.isRootFolder() )
917 "HasEncryptedEntries",
920 beans::PropertyAttribute::BOUND
921 | beans::PropertyAttribute::READONLY ),
927 uno::Reference< beans::XPropertySet > xSet =
928 rProvider->getAdditionalPropertySet( rContentId,
false );
929 xRow->appendPropertySet( xSet );
937 const uno::Sequence< beans::Property >& rProperties )
939 osl::Guard< osl::Mutex > aGuard(
m_aMutex );
949 const uno::Sequence< beans::PropertyValue >& rValues,
950 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
952 osl::ClearableGuard< osl::Mutex > aGuard(
m_aMutex );
954 uno::Sequence< uno::Any > aRet( rValues.getLength() );
955 auto aRetRange = asNonConstRange(aRet);
956 uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
957 sal_Int32 nChanged = 0;
959 beans::PropertyChangeEvent
aEvent;
960 aEvent.Source = getXWeak();
963 aEvent.PropertyHandle = -1;
967 const beans::PropertyValue*
pValues = rValues.getConstArray();
968 sal_Int32
nCount = rValues.getLength();
970 uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
971 bool bTriedToGetAdditionalPropSet =
false;
972 bool bExchange =
false;
975 sal_Int32 nTitlePos = -1;
977 for ( sal_Int32 n = 0;
n <
nCount; ++
n )
979 const beans::PropertyValue& rValue =
pValues[
n ];
981 if ( rValue.Name ==
"ContentType" )
984 aRetRange[
n ] <<= lang::IllegalAccessException(
985 "Property is read-only!",
988 else if ( rValue.Name ==
"IsDocument" )
991 aRetRange[
n ] <<= lang::IllegalAccessException(
992 "Property is read-only!",
995 else if ( rValue.Name ==
"IsFolder" )
998 aRetRange[
n ] <<= lang::IllegalAccessException(
999 "Property is read-only!",
1002 else if ( rValue.Name ==
"CreatableContentsInfo" )
1005 aRetRange[
n ] <<= lang::IllegalAccessException(
1006 "Property is read-only!",
1009 else if ( rValue.Name ==
"Title" )
1014 aRetRange[
n ] <<= lang::IllegalAccessException(
1015 "Property is read-only!",
1021 if ( rValue.Value >>= aNewValue )
1024 if ( !aNewValue.isEmpty() )
1033 aNewTitle = aNewValue;
1043 lang::IllegalArgumentException(
1044 "Empty title not allowed!",
1052 beans::IllegalTypeException(
1053 "Property value has wrong type!",
1058 else if ( rValue.Name ==
"MediaType" )
1061 if ( rValue.Value >>= aNewValue )
1065 aEvent.PropertyName = rValue.Name;
1067 aEvent.NewValue <<= aNewValue;
1077 aRetRange[
n ] <<= beans::IllegalTypeException(
1078 "Property value has wrong type!",
1082 else if ( rValue.Name ==
"Size" )
1085 aRetRange[
n ] <<= lang::IllegalAccessException(
1086 "Property is read-only!",
1089 else if ( rValue.Name ==
"Compressed" )
1095 if ( rValue.Value >>= bNewValue )
1099 aEvent.PropertyName = rValue.Name;
1101 aEvent.NewValue <<= bNewValue;
1111 aRetRange[
n ] <<= beans::IllegalTypeException(
1112 "Property value has wrong type!",
1118 aRetRange[
n ] <<= beans::UnknownPropertyException(
1119 "Compressed only supported by streams!",
1123 else if ( rValue.Name ==
"Encrypted" )
1129 if ( rValue.Value >>= bNewValue )
1133 aEvent.PropertyName = rValue.Name;
1135 aEvent.NewValue <<= bNewValue;
1145 aRetRange[
n ] <<= beans::IllegalTypeException(
1146 "Property value has wrong type!",
1152 aRetRange[
n ] <<= beans::UnknownPropertyException(
1153 "Encrypted only supported by streams!",
1157 else if ( rValue.Name ==
"HasEncryptedEntries" )
1160 aRetRange[
n ] <<= lang::IllegalAccessException(
1161 "Property is read-only!",
1164 else if ( rValue.Name ==
"EncryptionKey" )
1173 uno::Sequence < sal_Int8 > aNewValue;
1174 if ( rValue.Value >>= aNewValue )
1178 aEvent.PropertyName = rValue.Name;
1180 aEvent.NewValue <<= aNewValue;
1190 aRetRange[
n ] <<= beans::IllegalTypeException(
1191 "Property value has wrong type!",
1197 aRetRange[
n ] <<= beans::UnknownPropertyException(
1198 "EncryptionKey not supported by non-root folder!",
1206 if ( !bTriedToGetAdditionalPropSet && !xAdditionalPropSet.is() )
1209 bTriedToGetAdditionalPropSet =
true;
1212 if ( xAdditionalPropSet.is() )
1217 = xAdditionalPropSet->getPropertyValue( rValue.Name );
1218 if ( aOldValue != rValue.Value )
1220 xAdditionalPropSet->setPropertyValue(
1221 rValue.Name, rValue.Value );
1223 aEvent.PropertyName = rValue.Name;
1224 aEvent.OldValue = aOldValue;
1225 aEvent.NewValue = rValue.Value;
1227 aChanges.getArray()[ nChanged ] =
aEvent;
1231 catch ( beans::UnknownPropertyException
const & e )
1233 aRetRange[
n ] <<= e;
1235 catch ( lang::WrappedTargetException
const & e )
1237 aRetRange[
n ] <<= e;
1239 catch ( beans::PropertyVetoException
const & e )
1241 aRetRange[
n ] <<= e;
1243 catch ( lang::IllegalArgumentException
const & e )
1245 aRetRange[
n ] <<= e;
1250 aRetRange[
n ] <<= uno::Exception(
1251 "No property set for storing the value!",
1259 uno::Reference< ucb::XContentIdentifier > xOldId =
m_xIdentifier;
1264 uno::Reference< ucb::XContentIdentifier > xNewId
1265 = new ::ucbhelper::ContentIdentifier( aNewURL );
1275 xNewId->getContentIdentifier() );
1283 aRetRange[ nTitlePos ] <<= uno::Exception(
1289 if ( !aNewTitle.isEmpty() )
1291 aEvent.PropertyName =
"Title";
1293 aEvent.NewValue <<= aNewTitle;
1297 aChanges.getArray()[ nChanged ] =
aEvent;
1307 if ( !
storeData( uno::Reference< io::XInputStream >() ) )
1314 ucb::IOErrorCode_CANT_WRITE,
1317 "Cannot store persistent data!",
1324 aChanges.realloc( nChanged );
1333 const ucb::OpenCommandArgument2& rArg,
1334 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1336 if ( rArg.Mode == ucb::OpenMode::ALL ||
1337 rArg.Mode == ucb::OpenMode::FOLDERS ||
1338 rArg.Mode == ucb::OpenMode::DOCUMENTS )
1344 uno::Reference< ucb::XDynamicResultSet > xSet
1354 if ( ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
1355 ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
1359 uno::Any( ucb::UnsupportedOpenModeException(
1362 sal_Int16( rArg.Mode ) ) ),
1367 uno::Reference< io::XOutputStream > xOut( rArg.Sink, uno::UNO_QUERY );
1381 ucb::IOErrorCode_CANT_READ,
1385 : uno::Reference< ucb::XCommandEnvironment >(),
1386 "Got no data stream!",
1393 uno::Sequence< sal_Int8 >
aBuffer;
1396 sal_Int32 nRead = xIn->readSomeBytes( aBuffer, 65536 );
1400 xOut->writeBytes( aBuffer );
1403 xOut->closeOutput();
1405 catch ( io::NotConnectedException
const & )
1409 catch ( io::BufferSizeExceededException
const & )
1413 catch ( io::IOException
const & )
1420 uno::Reference< io::XActiveDataSink > xDataSink(
1421 rArg.Sink, uno::UNO_QUERY );
1422 if ( xDataSink.is() )
1435 ucb::IOErrorCode_CANT_READ,
1440 ucb::XCommandEnvironment >(),
1441 "Got no data stream!",
1447 xDataSink->setInputStream( xIn );
1456 ucb::UnsupportedDataSinkException(
1471 const uno::Reference< io::XInputStream >& xStream,
1472 sal_Int32 nNameClashResolve,
1473 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1475 osl::ClearableGuard< osl::Mutex > aGuard(
m_aMutex );
1492 uno::Any( ucb::MissingInputStreamException(
1506 if (1 + aNewURL.lastIndexOf(
'/') != aNewURL.getLength())
1512 switch ( nNameClashResolve )
1515 case ucb::NameClash::ERROR:
1522 task::InteractionClassification_ERROR,
1530 case ucb::NameClash::OVERWRITE:
1534 case ucb::NameClash::RENAME:
1541 OUString aNew = aNewUri.getUri() +
"_" + OUString::number( ++nTry );
1542 aNewUri.setUri( aNew );
1544 while (
hasData( aNewUri ) && ( nTry < 1000 ) );
1550 ucb::UnsupportedNameClashException(
1551 "Unable to resolve name clash!",
1553 nNameClashResolve ) ),
1565 case ucb::NameClash::KEEP:
1566 case ucb::NameClash::ASK:
1572 ucb::UnsupportedNameClashException(
1575 nNameClashResolve ) ),
1587 m_xIdentifier = new ::ucbhelper::ContentIdentifier( aNewURL );
1598 ucb::IOErrorCode_CANT_WRITE,
1601 "Cannot store persistent data!",
1611 uno::Reference< container::XHierarchicalNameAccess > xXHierarchicalNameAccess;
1615 xXHierarchicalNameAccess );
1624 bool bDeletePhysical,
1625 const uno::Reference< ucb::XCommandEnvironment >& xEnv )
1629 osl::ClearableGuard< osl::Mutex > aGuard(
m_aMutex );
1631 uno::Reference< ucb::XContent > xThis =
this;
1637 uno::Any( ucb::UnsupportedCommandException(
1656 for (
auto& rChild : aChildren )
1658 rChild->destroy( bDeletePhysical, xEnv );
1665 const ucb::TransferInfo& rInfo,
1666 const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1668 osl::ClearableGuard< osl::Mutex > aGuard(
m_aMutex );
1674 uno::Any( ucb::UnsupportedCommandException(
1682 if ( ( rInfo.SourceURL.isEmpty() ) ||
1683 ( rInfo.SourceURL.compareTo(
1687 uno::Any( ucb::InteractiveBadTransferURLException(
1697 if ( rInfo.SourceURL.getLength() <= aId.getLength() )
1699 if ( aId.startsWith( rInfo.SourceURL ) )
1706 ucb::IOErrorCode_RECURSIVE,
1709 "Target is equal to or is a child of source!",
1719 uno::Reference< ucb::XContentIdentifier > xId
1720 = new ::ucbhelper::ContentIdentifier( rInfo.SourceURL );
1728 xSource =
static_cast< Content *
>(
1731 catch ( ucb::IllegalIdentifierException
const & )
1736 if ( !xSource.is() )
1740 {
"Uri",
uno::Any(xId->getContentIdentifier())}
1743 ucb::IOErrorCode_CANT_READ,
1746 "Cannot instantiate source object!",
1755 OUString aType = xSource->isFolder()
1758 ucb::ContentInfo aContentInfo;
1759 aContentInfo.Type = aType;
1760 aContentInfo.Attributes = 0;
1773 ucb::IOErrorCode_CANT_CREATE,
1776 "XContentCreator::createNewContent failed!",
1785 uno::Sequence< beans::Property > aSourceProps
1786 = xSource->getPropertySetInfo( xEnv )->getProperties();
1787 sal_Int32
nCount = aSourceProps.getLength();
1791 bool bHadTitle = rInfo.NewTitle.isEmpty();
1794 uno::Reference< sdbc::XRow > xRow
1795 = xSource->getPropertyValues( aSourceProps );
1797 uno::Sequence< beans::PropertyValue > aValues( nCount );
1798 beans::PropertyValue*
pValues = aValues.getArray();
1800 const beans::Property* pProps = aSourceProps.getConstArray();
1801 for ( sal_Int32 n = 0;
n <
nCount; ++
n )
1803 const beans::Property& rProp = pProps[
n ];
1804 beans::PropertyValue& rValue =
pValues[
n ];
1806 rValue.Name = rProp.Name;
1807 rValue.Handle = rProp.Handle;
1809 if ( !bHadTitle && rProp.Name ==
"Title" )
1813 rValue.Value <<= rInfo.NewTitle;
1817 = xRow->getObject( n + 1,
1819 container::XNameAccess >() );
1821 rValue.State = beans::PropertyState_DIRECT_VALUE;
1823 if ( rProp.Attributes & beans::PropertyAttribute::REMOVABLE )
1828 xTarget->addProperty( rProp.Name,
1832 catch ( beans::PropertyExistException
const & )
1835 catch ( beans::IllegalTypeException
const & )
1838 catch ( lang::IllegalArgumentException
const & )
1845 xTarget->setPropertyValues( aValues, xEnv );
1852 xTarget->insert( xSource->getInputStream(), rInfo.NameClash, xEnv );
1858 if ( xSource->isFolder() )
1860 uno::Reference< container::XEnumeration > xIter
1861 = xSource->getIterator();
1864 while ( xIter->hasMoreElements() )
1868 uno::Reference< container::XNamed > xNamed;
1869 xIter->nextElement() >>= xNamed;
1873 OSL_FAIL(
"Content::transfer - Got no XNamed!" );
1877 OUString
aName = xNamed->getName();
1879 if (
aName.isEmpty() )
1881 OSL_FAIL(
"Content::transfer - Empty name!" );
1885 OUString aChildId = xId->getContentIdentifier();
1886 if ( ( aChildId.lastIndexOf(
'/' ) + 1 )
1887 != aChildId.getLength() )
1892 ucb::TransferInfo aInfo;
1893 aInfo.MoveData =
false;
1894 aInfo.NewTitle.clear();
1895 aInfo.SourceURL = aChildId;
1896 aInfo.NameClash = rInfo.NameClash;
1899 xTarget->transfer( aInfo, xEnv );
1901 catch ( container::NoSuchElementException
const & )
1904 catch ( lang::WrappedTargetException
const & )
1915 if ( !rInfo.MoveData )
1918 xSource->destroy(
true, xEnv );
1921 if ( !xSource->removeData() )
1925 {
"Uri",
uno::Any(xSource->m_xIdentifier->getContentIdentifier())}
1928 ucb::IOErrorCode_CANT_WRITE,
1931 "Cannot remove persistent data of source object!",
1937 xSource->removeAdditionalPropertySet();
1942 const uno::Reference< ucb::XContentIdentifier >& xNewId )
1947 osl::ClearableGuard< osl::Mutex > aGuard(
m_aMutex );
1949 uno::Reference< ucb::XContent > xThis =
this;
1954 OSL_FAIL(
"Content::exchangeIdentity - Not persistent!" );
1961 PackageUri aNewUri( xNewId->getContentIdentifier() );
1977 for (
const auto& rChild : aChildren )
1982 uno::Reference< ucb::XContentIdentifier > xOldChildId
1983 = xChild->getIdentifier();
1984 OUString aOldChildURL
1985 = xOldChildId->getContentIdentifier();
1986 OUString aNewChildURL
1987 = aOldChildURL.replaceAt(
1989 aOldURL.getLength(),
1990 xNewId->getContentIdentifier() );
1991 uno::Reference< ucb::XContentIdentifier > xNewChildId
1992 = new ::ucbhelper::ContentIdentifier( aNewChildURL );
1994 if ( !xChild->exchangeIdentity( xNewChildId ) )
2002 OSL_FAIL(
"Content::exchangeIdentity - Panic! Cannot exchange identity!" );
2014 m_xProvider->queryExistingContents( aAllContents );
2018 OSL_ENSURE(
aURL.lastIndexOf(
'/' ) != (
aURL.getLength() - 1 ),
2019 "Content::queryChildren - Invalid URL!" );
2023 sal_Int32 nLen =
aURL.getLength();
2025 for (
const auto& rContent : aAllContents )
2029 = xChild->getIdentifier()->getContentIdentifier();
2032 if ( ( aChildURL.getLength() > nLen ) &&
2033 ( aChildURL.startsWith(
aURL ) ) )
2035 if ( aChildURL.indexOf(
'/', nLen ) == -1 )
2038 rChildren.emplace_back(
2039 static_cast< Content *
>( xChild.get() ) );
2049 osl::Guard< osl::Mutex > aGuard(
m_aMutex );
2073 uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2076 return rxPackage->hasByHierarchicalName( rURI.
getPath() );
2082 osl::Guard< osl::Mutex > aGuard(
m_aMutex );
2084 uno::Reference< container::XHierarchicalNameAccess > xPackage;
2088 return xPackage->hasByHierarchicalName( rURI.
getPath() );
2100 uno::Reference< container::XHierarchicalNameAccess > & rxPackage )
2107 uno::Reference< beans::XPropertySet > xPackagePropSet(
2108 rxPackage, uno::UNO_QUERY );
2110 OSL_ENSURE( xPackagePropSet.is(),
2111 "Content::loadData - "
2112 "Got no XPropertySet interface from package!" );
2114 if ( xPackagePropSet.is() )
2120 = xPackagePropSet->getPropertyValue(
"HasEncryptedEntries" );
2123 OSL_FAIL(
"Content::loadData - "
2124 "Got no HasEncryptedEntries value!" );
2128 catch ( beans::UnknownPropertyException
const & )
2130 OSL_FAIL(
"Content::loadData - "
2131 "Got no HasEncryptedEntries value!" );
2134 catch ( lang::WrappedTargetException
const & )
2136 OSL_FAIL(
"Content::loadData - "
2137 "Got no HasEncryptedEntries value!" );
2143 if ( !rxPackage->hasByHierarchicalName( rURI.
getPath() ) )
2151 uno::Reference< beans::XPropertySet > xPropSet;
2152 aEntry >>= xPropSet;
2154 if ( !xPropSet.is() )
2156 OSL_FAIL(
"Content::loadData - Got no XPropertySet interface!" );
2166 uno::Any aMediaType = xPropSet->getPropertyValue(
"MediaType");
2169 OSL_FAIL(
"Content::loadData - Got no MediaType value!" );
2173 catch ( beans::UnknownPropertyException
const & )
2175 OSL_FAIL(
"Content::loadData - Got no MediaType value!" );
2178 catch ( lang::WrappedTargetException
const & )
2180 OSL_FAIL(
"Content::loadData - Got no MediaType value!" );
2184 uno::Reference< container::XEnumerationAccess > xEnumAccess;
2185 aEntry >>= xEnumAccess;
2188 if ( xEnumAccess.is() )
2208 uno::Any aSize = xPropSet->getPropertyValue(
"Size");
2209 if ( !( aSize >>= rProps.
nSize ) )
2211 OSL_FAIL(
"Content::loadData - Got no Size value!" );
2215 catch ( beans::UnknownPropertyException
const & )
2217 OSL_FAIL(
"Content::loadData - Got no Size value!" );
2220 catch ( lang::WrappedTargetException
const & )
2222 OSL_FAIL(
"Content::loadData - Got no Size value!" );
2229 uno::Any aCompressed = xPropSet->getPropertyValue(
"Compressed");
2232 OSL_FAIL(
"Content::loadData - Got no Compressed value!" );
2236 catch ( beans::UnknownPropertyException
const & )
2238 OSL_FAIL(
"Content::loadData - Got no Compressed value!" );
2241 catch ( lang::WrappedTargetException
const & )
2243 OSL_FAIL(
"Content::loadData - Got no Compressed value!" );
2250 uno::Any aEncrypted = xPropSet->getPropertyValue(
"Encrypted");
2253 OSL_FAIL(
"Content::loadData - Got no Encrypted value!" );
2257 catch ( beans::UnknownPropertyException
const & )
2259 OSL_FAIL(
"Content::loadData - Got no Encrypted value!" );
2262 catch ( lang::WrappedTargetException
const & )
2264 OSL_FAIL(
"Content::loadData - Got no Encrypted value!" );
2271 catch ( container::NoSuchElementException
const & )
2281 const uno::Reference< ucb::XContentIdentifier >& xOldId,
2282 const uno::Reference< ucb::XContentIdentifier >& xNewId )
2284 osl::Guard< osl::Mutex > aGuard(
m_aMutex );
2286 PackageUri aURI( xOldId->getContentIdentifier() );
2287 uno::Reference< container::XHierarchicalNameAccess > xNA =
getPackage(
2290 if ( !xNA->hasByHierarchicalName( aURI.getPath() ) )
2295 uno::Any aEntry = xNA->getByHierarchicalName( aURI.getPath() );
2296 uno::Reference< container::XNamed > xNamed;
2301 OSL_FAIL(
"Content::renameData - Got no XNamed interface!" );
2305 PackageUri aNewURI( xNewId->getContentIdentifier() );
2308 xNamed->setName( aNewURI.getName() );
2310 catch ( container::NoSuchElementException
const & )
2319 osl::Guard< osl::Mutex > aGuard(
m_aMutex );
2321 uno::Reference< container::XHierarchicalNameAccess > xNA =
getPackage();
2323 uno::Reference< beans::XPropertySet > xPackagePropSet(
2324 xNA, uno::UNO_QUERY );
2325 OSL_ENSURE( xPackagePropSet.is(),
2326 "Content::storeData - "
2327 "Got no XPropertySet interface from package!" );
2329 if ( !xPackagePropSet.is() )
2339 xPackagePropSet->setPropertyValue(
2344 catch ( beans::UnknownPropertyException
const & )
2348 catch ( beans::PropertyVetoException
const & )
2352 catch ( lang::IllegalArgumentException
const & )
2356 catch ( lang::WrappedTargetException
const & )
2371 uno::Reference< lang::XSingleServiceFactory > xFac(
2372 xNA, uno::UNO_QUERY );
2375 OSL_FAIL(
"Content::storeData - "
2376 "Got no XSingleServiceFactory interface!" );
2382 uno::Reference< uno::XInterface > xNew
2383 = xFac->createInstanceWithArguments( aArgs );
2387 OSL_FAIL(
"Content::storeData - createInstance failed!" );
2393 = xNA->getByHierarchicalName( aParentUri.getPath() );
2394 uno::Reference< container::XNameContainer > xParentContainer;
2395 aEntry >>= xParentContainer;
2397 if ( !xParentContainer.is() )
2399 OSL_FAIL(
"Content::storeData - "
2400 "Got no XNameContainer interface!" );
2407 catch ( lang::IllegalArgumentException
const & )
2410 OSL_FAIL(
"Content::storeData - insertByName failed!" );
2413 catch ( uno::RuntimeException
const & )
2417 catch ( container::ElementExistException
const & )
2420 OSL_FAIL(
"Content::storeData - insertByName failed!" );
2423 catch ( lang::WrappedTargetException
const & )
2426 OSL_FAIL(
"Content::storeData - insertByName failed!" );
2429 catch ( container::NoSuchElementException
const & )
2432 OSL_FAIL(
"Content::storeData - getByHierarchicalName failed!" );
2435 catch ( uno::Exception
const & )
2438 OSL_FAIL(
"Content::storeData - Error!" );
2448 uno::Reference< beans::XPropertySet > xPropSet;
2449 xNA->getByHierarchicalName(
m_aUri.
getPath() ) >>= xPropSet;
2451 if ( !xPropSet.is() )
2453 OSL_FAIL(
"Content::storeData - Got no XPropertySet interface!" );
2463 xPropSet->setPropertyValue(
2472 xPropSet->setPropertyValue(
2482 xPropSet->setPropertyValue(
2492 xPropSet->setPropertyValue(
2505 uno::Reference< io::XActiveDataSink >
xSink(
2506 xPropSet, uno::UNO_QUERY );
2510 OSL_FAIL(
"Content::storeData - "
2511 "Got no XActiveDataSink interface!" );
2515 xSink->setInputStream( xStream );
2520 catch ( container::NoSuchElementException
const & )
2524 catch ( beans::UnknownPropertyException
const & )
2528 catch ( beans::PropertyVetoException
const & )
2532 catch ( lang::IllegalArgumentException
const & )
2536 catch ( lang::WrappedTargetException
const & )
2541 OSL_FAIL(
"Content::storeData - Error!" );
2548 osl::Guard< osl::Mutex > aGuard(
m_aMutex );
2550 uno::Reference< container::XHierarchicalNameAccess > xNA =
getPackage();
2553 if ( !xNA->hasByHierarchicalName( aParentUri.
getPath() ) )
2559 uno::Reference< container::XNameContainer > xContainer;
2560 aEntry >>= xContainer;
2562 if ( !xContainer.is() )
2564 OSL_FAIL(
"Content::removeData - "
2565 "Got no XNameContainer interface!" );
2572 catch ( container::NoSuchElementException
const & )
2576 catch ( lang::WrappedTargetException
const & )
2581 OSL_FAIL(
"Content::removeData - Error!" );
2588 osl::Guard< osl::Mutex > aGuard(
m_aMutex );
2593 uno::Reference< container::XHierarchicalNameAccess > xNA =
getPackage();
2595 uno::Reference< util::XChangesBatch > xBatch( xNA, uno::UNO_QUERY );
2598 OSL_FAIL(
"Content::flushData - Got no XChangesBatch interface!" );
2604 xBatch->commitChanges();
2607 catch ( lang::WrappedTargetException
const & )
2611 OSL_FAIL(
"Content::flushData - Error!" );
2618 osl::Guard< osl::Mutex > aGuard(
m_aMutex );
2620 uno::Reference< io::XInputStream >
xStream;
2621 uno::Reference< container::XHierarchicalNameAccess > xNA =
getPackage();
2629 uno::Reference< io::XActiveDataSink >
xSink;
2634 OSL_FAIL(
"Content::getInputStream - "
2635 "Got no XActiveDataSink interface!" );
2642 "Content::getInputStream - Got no stream!" );
2644 catch ( container::NoSuchElementException
const & )
2655 osl::Guard< osl::Mutex > aGuard(
m_aMutex );
2657 uno::Reference< container::XEnumeration > xIter;
2658 uno::Reference< container::XHierarchicalNameAccess > xNA =
getPackage();
2666 uno::Reference< container::XEnumerationAccess > xIterFac;
2667 aEntry >>= xIterFac;
2669 if ( !xIterFac.is() )
2671 OSL_FAIL(
"Content::getIterator - "
2672 "Got no XEnumerationAccess interface!" );
2676 xIter = xIterFac->createEnumeration();
2678 OSL_ENSURE( xIter.is(),
2679 "Content::getIterator - Got no iterator!" );
2681 catch ( container::NoSuchElementException
const & )
const PropertyValue * pValues
PropertiesInfo aProperties
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes()
css::uno::Reference< css::container::XHierarchicalNameAccess > createPackage(const PackageUri &rParam)
bool storeData(const css::uno::Reference< css::io::XInputStream > &xStream)
rtl::Reference< Content > ContentRef
bool exchangeIdentity(const css::uno::Reference< css::ucb::XContentIdentifier > &xNewId)
css::uno::Reference< css::container::XHierarchicalNameAccess > getPackage()
static css::uno::Reference< css::sdbc::XRow > getPropertyValues(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Sequence< css::beans::Property > &rProperties, const ContentProperties &rData, const rtl::Reference< ::ucbhelper::ContentProviderImplHelper > &rProvider, const OUString &rContentId)
virtual css::uno::Sequence< css::ucb::ContentInfo > SAL_CALL queryCreatableContentsInfo() override
css::uno::Any open(const css::ucb::OpenCommandArgument2 &rArg, const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv)
static bool loadData(ContentProvider *pProvider, const PackageUri &rURI, ContentProperties &rProps, css::uno::Reference< css::container::XHierarchicalNameAccess > &rxPackage)
ContentProperties m_aProps
void destroy(bool bDeletePhysical, const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv)
Content(const css::uno::Reference< css::uno::XComponentContext > &rxContext, ContentProvider *pProvider, const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier, css::uno::Reference< css::container::XHierarchicalNameAccess > Package, PackageUri aUri, ContentProperties aProps)
css::uno::Reference< css::io::XInputStream > getInputStream()
static rtl::Reference< Content > create(const css::uno::Reference< css::uno::XComponentContext > &rxContext, ContentProvider *pProvider, const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier)
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
css::uno::Reference< css::container::XHierarchicalNameAccess > m_xPackage
virtual css::uno::Reference< css::ucb::XContent > SAL_CALL createNewContent(const css::ucb::ContentInfo &Info) override
virtual css::uno::Any SAL_CALL execute(const css::ucb::Command &aCommand, sal_Int32 CommandId, const css::uno::Reference< css::ucb::XCommandEnvironment > &Environment) override
virtual OUString SAL_CALL getImplementationName() override
std::vector< ContentRef > ContentRefList
virtual void SAL_CALL acquire() noexcept override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
ContentProvider * m_pProvider
virtual void SAL_CALL release() noexcept override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
void renameData(const css::uno::Reference< css::ucb::XContentIdentifier > &xOldId, const css::uno::Reference< css::ucb::XContentIdentifier > &xNewId)
void transfer(const css::ucb::TransferInfo &rInfo, const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv)
sal_uInt32 m_nModifiedProps
void queryChildren(ContentRefList &rChildren)
virtual OUString SAL_CALL getContentType() override
virtual void SAL_CALL abort(sal_Int32 CommandId) override
virtual OUString getParentURL() override
static bool hasData(ContentProvider *pProvider, const PackageUri &rURI, css::uno::Reference< css::container::XHierarchicalNameAccess > &rxPackage)
void insert(const css::uno::Reference< css::io::XInputStream > &xStream, sal_Int32 nNameClashResolve, const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv)
css::uno::Reference< css::container::XEnumeration > getIterator()
css::uno::Sequence< css::uno::Any > setPropertyValues(const css::uno::Sequence< css::beans::PropertyValue > &rValues, const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv)
virtual ~Content() override
bool isRootFolder() const
const OUString & getScheme() const
const OUString & getName() const
const OUString & getParentUri() const
const OUString & getPackage() const
const OUString & getPath() const
const OUString & getUri() const
css::uno::Reference< css::ucb::XPersistentPropertySet > getAdditionalPropertySet(bool bCreate)
css::uno::Reference< css::ucb::XCommandInfo > getCommandInfo(const css::uno::Reference< css::ucb::XCommandEnvironment > &xEnv, bool bCache=true)
bool renameAdditionalPropertySet(const OUString &rOldKey, const OUString &rNewKey)
rtl::Reference< ContentProviderImplHelper > m_xProvider
bool removeAdditionalPropertySet()
bool exchange(const css::uno::Reference< css::ucb::XContentIdentifier > &rNewId)
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
void notifyPropertiesChange(const css::uno::Sequence< css::beans::PropertyChangeEvent > &evt) const
uno::Reference< deployment::XPackage > m_xPackage
Reference< XInterface > xTarget
tools::SvRef< SvBaseLink > xSink
Sequence< sal_Int8 > aSeq
constexpr OUStringLiteral aData
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
OUString encodeSegment(const OUString &rSegment)
std::vector< ContentImplHelperRef > ContentRefList
void cancelCommandExecution(const uno::Any &rException, const uno::Reference< ucb::XCommandEnvironment > &xEnv)
#define ENCRYPTIONKEY_MODIFIED
#define MEDIATYPE_MODIFIED
XTYPEPROVIDER_COMMON_IMPL(Content)
#define COMPRESSED_MODIFIED
#define ENCRYPTED_MODIFIED
#define PACKAGE_ZIP_FOLDER_CONTENT_TYPE
#define PACKAGE_FOLDER_CONTENT_TYPE
#define PACKAGE_STREAM_CONTENT_TYPE
#define PACKAGE_ZIP_STREAM_CONTENT_TYPE
#define PACKAGE_URL_SCHEME_LENGTH
uno::Sequence< beans::Property > m_aProps
css::uno::Sequence< css::ucb::ContentInfo > getCreatableContentsInfo(PackageUri const &rUri) const
css::uno::Sequence< sal_Int8 > aEncryptionKey
bool bHasEncryptedEntries
std::unique_ptr< char[]> aBuffer