summaryrefslogtreecommitdiff
path: root/ucb/source/ucp/package/pkgcontent.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'ucb/source/ucp/package/pkgcontent.cxx')
-rw-r--r--ucb/source/ucp/package/pkgcontent.cxx331
1 files changed, 308 insertions, 23 deletions
diff --git a/ucb/source/ucp/package/pkgcontent.cxx b/ucb/source/ucp/package/pkgcontent.cxx
index 86dbb4869f1a..579488c6e73d 100644
--- a/ucb/source/ucp/package/pkgcontent.cxx
+++ b/ucb/source/ucp/package/pkgcontent.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: pkgcontent.cxx,v $
*
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
- * last change: $Author: kso $ $Date: 2000-11-20 12:25:04 $
+ * last change: $Author: kso $ $Date: 2000-11-27 13:05:27 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -62,9 +62,6 @@
/**************************************************************************
TODO
**************************************************************************
-
- - transfer command
-
*************************************************************************/
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
@@ -100,6 +97,9 @@
#ifndef _COM_SUN_STAR_UCB_CONTENTINFOATTRIBUTE_HPP_
#include <com/sun/star/ucb/ContentInfoAttribute.hpp>
#endif
+#ifndef _COM_SUN_STAR_UCB_NAMECLASH_HPP_
+#include <com/sun/star/ucb/NameClash.hpp>
+#endif
#ifndef _COM_SUN_STAR_UCB_OPENCOMMANDARGUMENT2_HPP_
#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
#endif
@@ -495,7 +495,10 @@ Any SAL_CALL Content::execute( const Command& aCommand,
InsertCommandArgument aArg;
if ( aCommand.Argument >>= aArg )
{
- insert( aArg );
+ sal_Int32 nNameClash = aArg.ReplaceExisting
+ ? NameClash::OVERWRITE
+ : NameClash::ERROR;
+ insert( aArg.Data, nNameClash );
}
else
{
@@ -520,9 +523,6 @@ Any SAL_CALL Content::execute( const Command& aCommand,
// Remove own and all children's Additional Core Properties.
removeAdditionalPropertySet( sal_True );
}
-#if 0
- N.Y.I.
-
else if ( aCommand.Name.compareToAscii( "transfer" ) == 0 )
{
//////////////////////////////////////////////////////////////////
@@ -533,8 +533,7 @@ Any SAL_CALL Content::execute( const Command& aCommand,
TransferInfo aInfo;
if ( aCommand.Argument >>= aInfo )
{
-// @@@
-// transfer( aInfo );
+ transfer( aInfo );
}
else
{
@@ -543,7 +542,6 @@ Any SAL_CALL Content::execute( const Command& aCommand,
throw CommandAbortedException();
}
}
-#endif
else if ( aCommand.Name.compareToAscii( "flush" ) == 0 )
{
//////////////////////////////////////////////////////////////////
@@ -551,8 +549,7 @@ Any SAL_CALL Content::execute( const Command& aCommand,
// ( Not available at stream objects )
//////////////////////////////////////////////////////////////////
-// @@@
-
+ flushData();
}
else
{
@@ -1121,7 +1118,8 @@ Any Content::open( const OpenCommandArgument2& rArg,
}
//=========================================================================
-void Content::insert( const InsertCommandArgument& rArg )
+void Content::insert(
+ const Reference< XInputStream >& xStream, sal_Int32 nNameClashResolve )
throw( CommandAbortedException )
{
osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
@@ -1142,7 +1140,7 @@ void Content::insert( const InsertCommandArgument& rArg )
{
// Required: rArg.Data
- if ( !rArg.Data.is() )
+ if ( !xStream.is() )
{
VOS_ENSURE( sal_False,
"Content::insert - input stream missing!" );
@@ -1163,16 +1161,62 @@ void Content::insert( const InsertCommandArgument& rArg )
aNewURL += m_aProps.aTitle;
PackageUri aNewUri( aNewURL );
- if ( !rArg.ReplaceExisting )
+ // Handle possible name clash...
+ switch ( nNameClashResolve )
{
- if ( hasData( m_xSMgr, aNewUri ) )
+ // fail.
+ case NameClash::ERROR:
+ if ( hasData( m_xSMgr, aNewUri ) )
+ throw CommandAbortedException();
+
+ break;
+
+ // replace (possibly) existing object.
+ case NameClash::OVERWRITE:
+ break;
+
+ // "invent" a new valid title.
+ case NameClash::RENAME:
+ if ( hasData( m_xSMgr, aNewUri ) )
+ {
+ sal_Int32 nTry = 0;
+
+ do
+ {
+ OUString aNew = aNewUri.getUri();
+ aNew += OUString::createFromAscii( "_" );
+ aNew += OUString::valueOf( ++nTry );
+ aNewUri.setUri( aNew );
+ }
+ while ( hasData( m_xSMgr, aNewUri ) && ( nTry < 100000 ) );
+
+ if ( nTry == 100000 )
+ {
+ VOS_ENSURE( sal_False,
+ "Content::insert - "
+ "Unable to resolve name clash" );
+ throw CommandAbortedException();
+ }
+ else
+ {
+ m_aProps.aTitle += OUString::createFromAscii( "_" );
+ m_aProps.aTitle += OUString::valueOf( nTry );
+ }
+ }
+ break;
+
+ // keep existing sub-objects, transfer non-clashing sub-objects.
+ case NameClash::KEEP:
+ // @@@
+
+ default:
throw CommandAbortedException();
}
m_xIdentifier = new ::ucb::ContentIdentifier( m_xSMgr, aNewURL );
m_aUri = aNewUri;
- storeData( rArg.Data );
+ storeData( xStream );
if ( m_eState == TRANSIENT )
{
@@ -1224,6 +1268,247 @@ void Content::destroy( sal_Bool bDeletePhysical )
}
//=========================================================================
+void Content::transfer( const TransferInfo& rInfo )
+ throw( CommandAbortedException )
+{
+ // targeturl->XNamed::setParent( this )
+
+ // setParent hat weder returnwert noch wirft es exceptions
+ // --> nach setparent checken, ob neues elem existiert und
+ // by move checken, ob altes elem weg ist.
+
+ // dynamische props nicht vergessen!
+
+ osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
+
+ // Persistent?
+ if ( m_eState != PERSISTENT )
+ {
+ VOS_ENSURE( sal_False, "Content::transfer - Not persistent!" );
+ throw CommandAbortedException();
+ }
+
+ if ( rInfo.SourceURL.getLength() == 0 )
+ throw CommandAbortedException();
+
+ // Is source a hierarchy content?
+ if ( rInfo.SourceURL.compareToAscii(
+ PACKAGE_URL_SCHEME "://", PACKAGE_URL_SCHEME_LENGTH + 3 ) != 0 )
+ throw CommandAbortedException();
+
+ // Is source not a parent of me / not me?
+ OUString aId = m_xIdentifier->getContentIdentifier();
+ sal_Int32 nPos = aId.lastIndexOf( '/' );
+ if ( nPos != ( aId.getLength() - 1 ) )
+ {
+ // No trailing slash found. Append.
+ aId += OUString::createFromAscii( "/" );
+ }
+
+ if ( rInfo.SourceURL.getLength() <= aId.getLength() )
+ {
+ if ( aId.compareTo(
+ rInfo.SourceURL, rInfo.SourceURL.getLength() ) == 0 )
+ throw CommandAbortedException();
+ }
+
+ try
+ {
+ //////////////////////////////////////////////////////////////////
+ // 0) Obtain content object for source.
+ //////////////////////////////////////////////////////////////////
+
+ Reference< XContentIdentifier > xId =
+ new ::ucb::ContentIdentifier( m_xSMgr, rInfo.SourceURL );
+
+ // Note: The static cast is okay here, because its sure that
+ // m_xProvider is always the PackageContentProvider.
+ vos::ORef< Content > xSource
+ = static_cast< Content * >(
+ m_xProvider->queryContent( xId ).get() );
+ if ( !xSource.isValid() )
+ throw CommandAbortedException();
+
+ //////////////////////////////////////////////////////////////////
+ // 1) Create new child content.
+ //////////////////////////////////////////////////////////////////
+
+ OUString aType = xSource->isFolder()
+ ? OUString::createFromAscii(
+ PACKAGE_FOLDER_CONTENT_SERVICE_NAME )
+ : OUString::createFromAscii(
+ PACKAGE_STREAM_CONTENT_SERVICE_NAME );
+ ContentInfo aInfo;
+ aInfo.Type = aType;
+ aInfo.Attributes = 0;
+
+ // Note: The static cast is okay here, because its sure that
+ // createNewContent always creates a Content.
+ vos::ORef< Content > xTarget = static_cast< Content * >(
+ createNewContent( aInfo ).get() );
+ if ( !xTarget.isValid() )
+ throw CommandAbortedException();
+
+ //////////////////////////////////////////////////////////////////
+ // 2) Copy data from source content to child content.
+ //////////////////////////////////////////////////////////////////
+
+ Sequence< Property > aProps
+ = xSource->getPropertySetInfo()->getProperties();
+ sal_Int32 nCount = aProps.getLength();
+
+ if ( nCount )
+ {
+ sal_Bool bHadTitle = ( rInfo.NewTitle.getLength() == 0 );
+
+ // Get all source values.
+ Reference< XRow > xRow = xSource->getPropertyValues( aProps );
+
+ Sequence< PropertyValue > aValues( nCount );
+ PropertyValue* pValues = aValues.getArray();
+
+ const Property* pProps = aProps.getConstArray();
+ for ( sal_Int32 n = 0; n < nCount; ++n )
+ {
+ const Property& rProp = pProps[ n ];
+ PropertyValue& rValue = pValues[ n ];
+
+ rValue.Name = rProp.Name;
+ rValue.Handle = rProp.Handle;
+
+ if ( !bHadTitle && rProp.Name.compareToAscii( "Title" ) == 0 )
+ {
+ // Set new title instead of original.
+ bHadTitle = sal_True;
+ rValue.Value <<= rInfo.NewTitle;
+ }
+ else
+ rValue.Value
+ = xRow->getObject( n + 1, Reference< XNameAccess >() );
+
+ rValue.State = PropertyState_DIRECT_VALUE;
+
+ if ( rProp.Attributes & PropertyAttribute::REMOVABLE )
+ {
+ // Add Additional Core Property.
+ try
+ {
+ xTarget->addProperty( rProp.Name,
+ rProp.Attributes,
+ rValue.Value );
+ }
+ catch ( PropertyExistException & )
+ {
+ }
+ catch ( IllegalTypeException & )
+ {
+ }
+ catch ( IllegalArgumentException & )
+ {
+ }
+ }
+ }
+
+ // Set target values.
+ xTarget->setPropertyValues( aValues );
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // 3) Commit (insert) child.
+ //////////////////////////////////////////////////////////////////
+
+ xTarget->insert( xSource->getInputStream(), rInfo.NameClash );
+
+ //////////////////////////////////////////////////////////////////
+ // 4) Transfer (copy) children of source.
+ //////////////////////////////////////////////////////////////////
+
+ if ( xSource->isFolder() )
+ {
+ Reference< XEnumeration > xIter = xSource->getIterator();
+ if ( xIter.is() )
+ {
+ while ( xIter->hasMoreElements() )
+ {
+ try
+ {
+ Reference< XNamed > xNamed;
+ xIter->nextElement() >>= xNamed;
+
+ if ( !xNamed.is() )
+ {
+ VOS_ENSURE( sal_False,
+ "Content::transfer - Got no XNamed!" );
+ break;
+ }
+
+ OUString aName = xNamed->getName();
+
+ if ( !aName.getLength() )
+ {
+ VOS_ENSURE( sal_False,
+ "Content::transfer - Empty name!" );
+ break;
+ }
+
+ OUString aChildId = xId->getContentIdentifier();
+ if ( ( aChildId.lastIndexOf( '/' ) + 1 )
+ != aChildId.getLength() )
+ aChildId += OUString::createFromAscii( "/" );
+
+ aChildId += aName;
+
+ Reference< XContentIdentifier > xChildId
+ = new ::ucb::ContentIdentifier( m_xSMgr, aChildId );
+
+ vos::ORef< Content > xChild
+ = static_cast< Content * >(
+ m_xProvider->queryContent( xChildId ).get() );
+
+ TransferInfo aInfo;
+ aInfo.MoveData = sal_False;
+ aInfo.NewTitle = OUString();
+ aInfo.SourceURL = aChildId;
+ aInfo.NameClash = rInfo.NameClash;
+
+ // Transfer child to target.
+ xTarget->transfer( aInfo );
+ }
+ catch ( NoSuchElementException & )
+ {
+ }
+ catch ( WrappedTargetException & )
+ {
+ }
+ }
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // 5) Destroy source ( when moving only ) .
+ //////////////////////////////////////////////////////////////////
+
+ if ( rInfo.MoveData )
+ {
+ xSource->destroy( sal_True );
+
+ // Remove all persistent data of source and its children.
+ xSource->removeData();
+
+ // Remove own and all children's Additional Core Properties.
+ xSource->removeAdditionalPropertySet( sal_True );
+ }
+ }
+ catch ( IllegalIdentifierException & )
+ {
+ // queryContent
+ VOS_ENSURE( sal_False, "Content::transfer - "
+ "Caught IllegalIdentifierException!" );
+ throw CommandAbortedException();
+ }
+}
+
+//=========================================================================
sal_Bool Content::exchangeIdentity(
const Reference< XContentIdentifier >& xNewId )
{
@@ -1343,8 +1628,8 @@ void Content::queryChildren( ContentRefList& rChildren )
//=========================================================================
// static
Reference< XHierarchicalNameAccess > Content::getPackage(
- const Reference< XMultiServiceFactory >& rxSMgr,
- const PackageUri& rURI )
+ const Reference< XMultiServiceFactory > & rxSMgr,
+ const PackageUri& rURI )
{
Reference< XHierarchicalNameAccess > xNameAccess;
@@ -1371,7 +1656,8 @@ Reference< XHierarchicalNameAccess > Content::getPackage(
= Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY );
VOS_ENSURE( xNameAccess.is(),
- "Content::getPackage - Got no hierarchical name access!" );
+ "Content::getPackage - "
+ "Got no hierarchical name access!" );
}
}
catch ( RuntimeException & )
@@ -1499,7 +1785,6 @@ sal_Bool Content::loadData( const Reference< XMultiServiceFactory >& rxSMgr,
rProps.bIsFolder = sal_False;
}
-
return sal_True;
}
}