diff options
author | Kai Sommerfeld <kso@openoffice.org> | 2000-11-27 12:05:27 +0000 |
---|---|---|
committer | Kai Sommerfeld <kso@openoffice.org> | 2000-11-27 12:05:27 +0000 |
commit | 7d68f2cea2cfd5f99236a66754b02ab81f41325d (patch) | |
tree | dc69a1755e7ef915c6aae03df1d094ff1487f831 /ucb | |
parent | c918c3908d0a5a0349ad9f14ed7c18a695371d63 (diff) |
#80246# - Fixes + optimizations.
Diffstat (limited to 'ucb')
-rw-r--r-- | ucb/source/ucp/package/pkgcontent.cxx | 331 | ||||
-rw-r--r-- | ucb/source/ucp/package/pkgcontent.hxx | 17 | ||||
-rw-r--r-- | ucb/source/ucp/package/pkgcontentcaps.cxx | 7 | ||||
-rw-r--r-- | ucb/source/ucp/package/pkgdatasupplier.cxx | 9 | ||||
-rw-r--r-- | ucb/source/ucp/package/pkgprovider.cxx | 23 | ||||
-rw-r--r-- | ucb/source/ucp/package/pkguri.cxx | 26 | ||||
-rw-r--r-- | ucb/source/ucp/package/pkguri.hxx | 6 |
7 files changed, 355 insertions, 64 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; } } diff --git a/ucb/source/ucp/package/pkgcontent.hxx b/ucb/source/ucp/package/pkgcontent.hxx index 476b77f751e8..bc21741f7836 100644 --- a/ucb/source/ucp/package/pkgcontent.hxx +++ b/ucb/source/ucp/package/pkgcontent.hxx @@ -2,9 +2,9 @@ * * $RCSfile: pkgcontent.hxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: kso $ $Date: 2000-11-22 08:12:34 $ + * 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 @@ -100,8 +100,8 @@ namespace com { namespace sun { namespace star { } namespace ucb { - struct InsertCommandArgument; struct OpenCommandArgument2; + struct TransferInfo; } } } } @@ -184,9 +184,9 @@ private: ::com::sun::star::beans::PropertyValue >& rValues ); static ::com::sun::star::uno::Reference< - ::com::sun::star::container::XHierarchicalNameAccess > + ::com::sun::star::container::XHierarchicalNameAccess > getPackage( const ::com::sun::star::uno::Reference< - ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + ::com::sun::star::lang::XMultiServiceFactory > & rxSMgr, const PackageUri& rURI ); static sal_Bool loadData( const ::com::sun::star::uno::Reference< @@ -225,12 +225,17 @@ private: ::com::sun::star::ucb::XCommandEnvironment > & xEnv ) throw( ::com::sun::star::ucb::CommandAbortedException ); - void insert( const ::com::sun::star::ucb::InsertCommandArgument& rArg ) + void insert( const ::com::sun::star::uno::Reference< + ::com::sun::star::io::XInputStream >& xStream, + sal_Int32 nNameClashResolve ) throw( ::com::sun::star::ucb::CommandAbortedException ); void destroy( sal_Bool bDeletePhysical ) throw( ::com::sun::star::ucb::CommandAbortedException ); + void transfer( const ::com::sun::star::ucb::TransferInfo& rInfo ) + throw( ::com::sun::star::ucb::CommandAbortedException ); + ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > getInputStream(); diff --git a/ucb/source/ucp/package/pkgcontentcaps.cxx b/ucb/source/ucp/package/pkgcontentcaps.cxx index b2bbfbca7457..ad8d95f713bc 100644 --- a/ucb/source/ucp/package/pkgcontentcaps.cxx +++ b/ucb/source/ucp/package/pkgcontentcaps.cxx @@ -2,9 +2,9 @@ * * $RCSfile: pkgcontentcaps.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * 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 @@ -262,14 +262,11 @@ const ::ucb::CommandInfoTableEntry& Content::getCommandInfoTable() -1, &getCppuType( static_cast< OpenCommandArgument2 * >( 0 ) ) }, -#if 0 - N.Y.I. { "transfer", -1, &getCppuType( static_cast< TransferInfo * >( 0 ) ) }, -#endif /////////////////////////////////////////////////////////////// // New commands /////////////////////////////////////////////////////////////// diff --git a/ucb/source/ucp/package/pkgdatasupplier.cxx b/ucb/source/ucp/package/pkgdatasupplier.cxx index eaf275d01b5b..a6448959c89a 100644 --- a/ucb/source/ucp/package/pkgdatasupplier.cxx +++ b/ucb/source/ucp/package/pkgdatasupplier.cxx @@ -2,9 +2,9 @@ * * $RCSfile: pkgdatasupplier.cxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: sb $ $Date: 2000-11-21 17:04:47 $ + * 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 @@ -65,9 +65,8 @@ *************************************************************************/ -#ifndef __VECTOR__ -#include <stl/vector> -#endif +#include <vector> + #ifndef _COM_SUN_STAR_CONTAINER_XENUMERATION_HPP_ #include <com/sun/star/container/XEnumeration.hpp> #endif diff --git a/ucb/source/ucp/package/pkgprovider.cxx b/ucb/source/ucp/package/pkgprovider.cxx index 280ce332bb8c..061b7017a379 100644 --- a/ucb/source/ucp/package/pkgprovider.cxx +++ b/ucb/source/ucp/package/pkgprovider.cxx @@ -2,9 +2,9 @@ * * $RCSfile: pkgprovider.cxx,v $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: kso $ $Date: 2000-11-17 14:41:33 $ + * 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 @@ -82,6 +82,7 @@ #include "pkguri.hxx" #endif +using namespace com::sun::star::container; using namespace com::sun::star::lang; using namespace com::sun::star::ucb; using namespace com::sun::star::uno; @@ -172,20 +173,10 @@ Reference< XContent > SAL_CALL ContentProvider::queryContent( if ( !Identifier->getContentProviderScheme().equalsIgnoreCase( aScheme ) ) throw IllegalIdentifierException(); - // Normalize URL. Internally ids have no trailing slash. However, - // the client may append a slash to indicate that he wants a folder - // object, not a stream. Content::create below will fail, in case - // the referenced resource is a stream. - - Reference< XContentIdentifier > xId = Identifier; - OUString aURL = xId->getContentIdentifier(); - sal_Int32 nLastSlash = aURL.lastIndexOf( '/' ); - if ( ( nLastSlash + 1 ) == aURL.getLength() ) - { - // Remove trailing slash and create new identifier. - aURL = aURL.copy( 0, nLastSlash ); - xId = new ::ucb::ContentIdentifier( m_xSMgr, aURL ); - } + // Normalize URL... + PackageUri aUri( Identifier->getContentIdentifier() ); + Reference< XContentIdentifier > xId + = new ::ucb::ContentIdentifier( m_xSMgr, aUri.getUri() ); // Check, if a content with given id already exists... Reference< XContent > xContent = queryExistingContent( xId ).getBodyPtr(); diff --git a/ucb/source/ucp/package/pkguri.cxx b/ucb/source/ucp/package/pkguri.cxx index 8b8d7e8b3a93..bfb077826755 100644 --- a/ucb/source/ucp/package/pkguri.cxx +++ b/ucb/source/ucp/package/pkguri.cxx @@ -2,9 +2,9 @@ * * $RCSfile: pkguri.cxx,v $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: kso $ $Date: 2000-11-17 14:41:33 $ + * 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 @@ -111,14 +111,28 @@ void PackageUri::init() const if ( nEnd == -1 ) { // root folder. - m_aPackage = decodeSegment( m_aUri.copy( nStart ) ); + + // Note: toLowerCase needs no locale, because the string is + // escaped and does never contain special chars. + OUString aNormPackage = m_aUri.copy( nStart ).toLowerCase(); + + m_aUri = m_aUri.replaceAt( + nStart, m_aUri.getLength() - nStart, aNormPackage ); + m_aPackage = decodeSegment( aNormPackage ); m_aPath = rtl::OUString::createFromAscii( "/" ); } else { - m_aPackage = decodeSegment( - m_aUri.copy( nStart, nEnd - nStart ) ); - m_aPath = m_aUri.copy( nEnd ); + // Note: toLowerCase needs no locale, because the string is + // escaped and does never contain special chars. + OUString aNormPackage + = m_aUri.copy( nStart, nEnd - nStart ).toLowerCase(); + + m_aUri = m_aUri.replaceAt( + nStart, nEnd - nStart, aNormPackage ); + m_aPackage = decodeSegment( aNormPackage ); +// m_aPath = m_aUri.copy( nEnd ); + m_aPath = m_aUri.copy( nEnd + 1 ); sal_Int32 nLastSlash = m_aPath.lastIndexOf( '/' ); if ( nLastSlash != -1 ) diff --git a/ucb/source/ucp/package/pkguri.hxx b/ucb/source/ucp/package/pkguri.hxx index 68352d04a43b..7aa2737791a0 100644 --- a/ucb/source/ucp/package/pkguri.hxx +++ b/ucb/source/ucp/package/pkguri.hxx @@ -2,9 +2,9 @@ * * $RCSfile: pkguri.hxx,v $ * - * $Revision: 1.1 $ + * $Revision: 1.2 $ * - * last change: $Author: kso $ $Date: 2000-11-17 14:41:33 $ + * 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 @@ -71,7 +71,7 @@ namespace package_ucp { //========================================================================= #define PACKAGE_URL_SCHEME "vnd.sun.star.pkg" -#define PACKAGE_URL_SCHEME_LENGTH 20 +#define PACKAGE_URL_SCHEME_LENGTH 16 //========================================================================= |