diff options
-rw-r--r-- | offapi/UnoApi_offapi.mk | 1 | ||||
-rw-r--r-- | offapi/com/sun/star/ucb/Content.idl | 63 | ||||
-rw-r--r-- | offapi/com/sun/star/ucb/PropertyCommandArgument.idl | 43 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/DAVProperties.cxx | 40 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/DAVProperties.hxx | 2 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/webdavcontent.cxx | 216 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/webdavcontent.hxx | 16 | ||||
-rw-r--r-- | ucb/source/ucp/webdav/webdavcontentcaps.cxx | 15 |
8 files changed, 336 insertions, 60 deletions
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 747a305f1dac..26652d47c7da 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -3858,6 +3858,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,offapi/com/sun/star/ucb,\ PostCommandArgument \ PostCommandArgument2 \ Priority \ + PropertyCommandArgument \ PropertyValueInfo \ PropertyValueState \ RecipientInfo \ diff --git a/offapi/com/sun/star/ucb/Content.idl b/offapi/com/sun/star/ucb/Content.idl index cb55c0ff48e5..4b2f1437a2f5 100644 --- a/offapi/com/sun/star/ucb/Content.idl +++ b/offapi/com/sun/star/ucb/Content.idl @@ -448,6 +448,65 @@ published service Content </p> </td> </tr> + <tr> + <td>addProperty</td> + <td>void</td> + <td><type>PropertyCommandArgument</type> aCmdArg</td> + <td> + Adds a new properties to the content. + <p> + <member>PropertyCommandArgument::Property</member> + contains information about the property to be added. + <member>PropertyCommandArgument::DefaultValue</member> + may contain the default value for the property. Its type must + match the one specified in <member scope="com::sun::star::beans">Property::Type</member>. + </p> + <p>Note that the dynamic properties must be kept persistent. The + service <type>Store</type> (UCB persistence service) may be used to + implement this.</p> + <p><b>Important:</b> The implementation must at least support + adding properties of the following basic data types:</p> + <p> + <ul> + <li>boolean + <li>char + <li>byte + <li>string + <li>short + <li>long + <li>hyper + <li>float + <li>double + </ul> + </p> + <p> + Raises a <type scope="com::sun::star::beans">PropertyExistException</type> + if a property with the same name already exists; + <type scope="com::sun::star::beans">IllegalTypeException</type> + if the property has an unsupported type; + <type scope="com::sun::star::lang">IllegalArgumentException</type> + if the Name of the property is empty.</p> + <blockquote> + Note: This command replaces the deprecated interface method + <member scope="com::sun::star::beans">XPropertyContainer::addProperty</member>. + </blockquote> + </td> + </tr> + <tr> + <td>removeProperty</td> + <td>void</td> + <td>string PropertyName</td> + <td>Removes the properties from the content. + <p>Raises a <type scope="com::sun::star::beans">UnknownPropertyException</type> + if the property does not exist; + <type scope="com::sun::star::beans">NotRemoveableException</type> + if the property is not removable.</p> + <blockquote> + Note: This command replaces the deprecated interface method + <member scope="com::sun::star::beans">XPropertyContainer::removeProperty</member>. + </blockquote> + </td> + </tr> </table> <h3>Properties</h3> @@ -785,7 +844,7 @@ published service Content <td>TargetURL</td> <td>string</td> <td>for contents that are links to other contents, contains the URL of - the target content</td> + the target content</td> </tr> <tr> <td>TimeLimitStore</td> @@ -796,7 +855,7 @@ published service Content <td>UserName</td> <td>string</td> <td>contains a user name. (e.g. the user name needed to access a - POP3-Account)</td> + POP3-Account)</td> </tr> <tr> <td>VerificationMode</td> diff --git a/offapi/com/sun/star/ucb/PropertyCommandArgument.idl b/offapi/com/sun/star/ucb/PropertyCommandArgument.idl new file mode 100644 index 000000000000..f2130467925e --- /dev/null +++ b/offapi/com/sun/star/ucb/PropertyCommandArgument.idl @@ -0,0 +1,43 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +#ifndef __com_sun_star_ucb_PropertyCommandArgument_idl__ +#define __com_sun_star_ucb_PropertyCommandArgument_idl__ + +#include <com/sun/star/beans/Property.idl> + +module com { module sun { module star { module ucb { + +/** The argument for the "addProperty" command. + + @see XCommandProcessor + @since Apache OpenOffice 4.0 +*/ +struct PropertyCommandArgument +{ + /** The property that the command has to add. + */ + com::sun::star::beans::Property Property; + + /** The default value of the property. + */ + any DefaultValue; +}; + +}; }; }; }; + +#endif diff --git a/ucb/source/ucp/webdav/DAVProperties.cxx b/ucb/source/ucp/webdav/DAVProperties.cxx index 7340dbe6a35c..bbc894d728fe 100644 --- a/ucb/source/ucp/webdav/DAVProperties.cxx +++ b/ucb/source/ucp/webdav/DAVProperties.cxx @@ -19,6 +19,7 @@ #include <string.h> #include "DAVProperties.hxx" +#include <rtl/ustrbuf.hxx> using namespace http_dav_ucp; @@ -180,4 +181,43 @@ bool DAVProperties::isUCBDeadProperty( const SerfPropName & rName ) == 0 ) ); } +bool DAVProperties::isUCBSpecialProperty(const rtl::OUString& rFullName, rtl::OUString& rParsedName) +{ + sal_Int32 nLen = rFullName.getLength(); + if ( nLen <= 0 || + !rFullName.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "<prop:" ) ) || + !rFullName.endsWithAsciiL( RTL_CONSTASCII_STRINGPARAM( "\">" ) ) ) + return false; + + sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" ); + sal_Int32 nEnd = rFullName.indexOf( sal_Unicode( ' ' ), nStart ); + if ( nEnd == -1 ) + return false; + + rtl::OUString sPropName = rFullName.copy( nStart, nEnd - nStart ); + if ( !sPropName.getLength() ) + return false; + + // TODO skip whitespaces? + if ( !rFullName.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "xmlns:prop=\"" ), ++nEnd ) ) + return false; + + nStart = nEnd + RTL_CONSTASCII_LENGTH( "xmlns:prop=\"" ); + nEnd = rFullName.indexOf( sal_Unicode( '"' ), nStart ); + if ( nEnd != nLen - RTL_CONSTASCII_LENGTH( "\">" ) ) + return false; + + rtl::OUString sNamesp = rFullName.copy( nStart, nEnd - nStart ); + if ( !( nLen = sNamesp.getLength() ) ) + return false; + + rtl::OUStringBuffer aBuff( sNamesp ); + if ( sNamesp[nLen - 1] != '/' ) + aBuff.append( sal_Unicode( '/' ) ); + aBuff.append( sPropName ); + rParsedName = aBuff.makeStringAndClear(); + + return rParsedName.getLength(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/ucb/source/ucp/webdav/DAVProperties.hxx b/ucb/source/ucp/webdav/DAVProperties.hxx index 1906c7fb264d..8bf3ca37614e 100644 --- a/ucb/source/ucp/webdav/DAVProperties.hxx +++ b/ucb/source/ucp/webdav/DAVProperties.hxx @@ -48,6 +48,8 @@ struct DAVProperties OUString & rFullName ); static bool isUCBDeadProperty( const SerfPropName & rName ); + static bool isUCBSpecialProperty( const rtl::OUString & rFullName, + rtl::OUString & rParsedName ); }; } // namespace http_dav_ucp diff --git a/ucb/source/ucp/webdav/webdavcontent.cxx b/ucb/source/ucp/webdav/webdavcontent.cxx index 7ff158b4c483..f995bd098d5f 100644 --- a/ucb/source/ucp/webdav/webdavcontent.cxx +++ b/ucb/source/ucp/webdav/webdavcontent.cxx @@ -56,6 +56,7 @@ #include <com/sun/star/ucb/OpenCommandArgument2.hpp> #include <com/sun/star/ucb/OpenMode.hpp> #include <com/sun/star/ucb/PostCommandArgument2.hpp> +#include <com/sun/star/ucb/PropertyCommandArgument.hpp> #include <com/sun/star/ucb/TransferInfo.hpp> #include <com/sun/star/ucb/UnsupportedCommandException.hpp> #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> @@ -743,6 +744,68 @@ uno::Any SAL_CALL Content::execute( aRet = uno::makeAny( createNewContent( aArg ) ); } + else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "addProperty" ))) + { + ucb::PropertyCommandArgument aPropArg; + if ( !( aCommand.Argument >>= aPropArg )) + { + ucbhelper::cancelCommandExecution( + uno::makeAny( lang::IllegalArgumentException( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "Wrong argument type!" )), + static_cast< cppu::OWeakObject * >( this ), + -1 ) ), + Environment ); + } + + // TODO when/if XPropertyContainer is removed, + // the command execution can be canceled in addProperty + try + { + addProperty( aPropArg, Environment ); + } + catch ( const beans::PropertyExistException &e ) + { + ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); + } + catch ( const beans::IllegalTypeException&e ) + { + ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); + } + catch ( const lang::IllegalArgumentException&e ) + { + ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); + } + } + else if ( aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "removeProperty" ))) + { + rtl::OUString sPropName; + if ( !( aCommand.Argument >>= sPropName ) ) + { + ucbhelper::cancelCommandExecution( + uno::makeAny( lang::IllegalArgumentException( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "Wrong argument type!" )), + static_cast< cppu::OWeakObject * >( this ), + -1 ) ), + Environment ); + } + + // TODO when/if XPropertyContainer is removed, + // the command execution can be canceled in removeProperty + try + { + removeProperty( sPropName, Environment ); + } + catch( const beans::UnknownPropertyException &e ) + { + ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); + } + catch( const beans::NotRemoveableException &e ) + { + ucbhelper::cancelCommandExecution( uno::makeAny( e ), Environment ); + } + } else { ////////////////////////////////////////////////////////////////// @@ -794,42 +857,53 @@ void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) // //========================================================================= -// virtual -void SAL_CALL Content::addProperty( const OUString& Name, - sal_Int16 Attributes, - const uno::Any& DefaultValue ) - throw( beans::PropertyExistException, - beans::IllegalTypeException, - lang::IllegalArgumentException, - uno::RuntimeException ) +void Content::addProperty( const com::sun::star::ucb::PropertyCommandArgument &aCmdArg, + const uno::Reference< ucb::XCommandEnvironment >& xEnv ) +throw( beans::PropertyExistException, + beans::IllegalTypeException, + lang::IllegalArgumentException, + uno::RuntimeException ) { // if ( m_bTransient ) // @@@ ??? + const beans::Property aProperty = aCmdArg.Property; + const uno::Any aDefaultValue = aCmdArg.DefaultValue; - if ( Name.isEmpty() ) - throw lang::IllegalArgumentException(); + // check property Name + if ( !aProperty.Name.getLength() ) + throw lang::IllegalArgumentException( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "\"addProperty\" with empty Property.Name")), + static_cast< ::cppu::OWeakObject * >( this ), + -1 ); // Check property type. - if ( !UCBDeadPropertyValue::supportsType( DefaultValue.getValueType() ) ) - { - OSL_ENSURE( sal_False, - "Content::addProperty - Unsupported property type!" ); - throw beans::IllegalTypeException(); - } + if ( !UCBDeadPropertyValue::supportsType( aProperty.Type ) ) + throw beans::IllegalTypeException( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "\"addProperty\" unsupported Property.Type")), + static_cast< ::cppu::OWeakObject * >( this ) ); + + // check default value + if ( aDefaultValue.hasValue() && aDefaultValue.getValueType() != aProperty.Type ) + throw beans::IllegalTypeException( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "\"addProperty\" DefaultValue does not match Property.Type")), + static_cast< ::cppu::OWeakObject * >( this ) ); ////////////////////////////////////////////////////////////////////// // Make sure a property with the requested name does not already // exist in dynamic and static(!) properties. ////////////////////////////////////////////////////////////////////// - // @@@ Need real command environment here, but where to get it from? - // XPropertyContainer interface should be replaced by - // XCommandProcessor commands! - uno::Reference< ucb::XCommandEnvironment > xEnv; + // Take into account special properties with custom namespace + // using <prop:the_propname xmlns:prop="the_namespace"> + rtl::OUString aSpecialName; + bool bIsSpecial = DAVProperties::isUCBSpecialProperty( aProperty.Name, aSpecialName ); // Note: This requires network access! if ( getPropertySetInfo( xEnv, sal_False /* don't cache data */ ) - ->hasPropertyByName( Name ) ) + ->hasPropertyByName( bIsSpecial ? aSpecialName : aProperty.Name ) ) { // Property does already exist. throw beans::PropertyExistException(); @@ -839,7 +913,7 @@ void SAL_CALL Content::addProperty( const OUString& Name, // Add a new dynamic property. ////////////////////////////////////////////////////////////////////// - ProppatchValue aValue( PROPSET, Name, DefaultValue ); + ProppatchValue aValue( PROPSET, aProperty.Name, aDefaultValue ); std::vector< ProppatchValue > aProppatchValues; aProppatchValues.push_back( aValue ); @@ -861,7 +935,7 @@ void SAL_CALL Content::addProperty( const OUString& Name, // Notify propertyset info change listeners. beans::PropertySetInfoChangeEvent evt( static_cast< cppu::OWeakObject * >( this ), - Name, + bIsSpecial ? aSpecialName : aProperty.Name, -1, // No handle available beans::PropertySetInfoChange::PROPERTY_INSERTED ); notifyPropertySetInfoChange( evt ); @@ -873,8 +947,9 @@ void SAL_CALL Content::addProperty( const OUString& Name, // Support for setting arbitrary dead properties is optional! // Store property locally. - ContentImplHelper::addProperty( - Name, Attributes, DefaultValue ); + ContentImplHelper::addProperty( bIsSpecial ? aSpecialName : aProperty.Name, + aProperty.Attributes, + aDefaultValue ); } else { @@ -891,9 +966,9 @@ void SAL_CALL Content::addProperty( const OUString& Name, case NON_DAV: // Store property locally. - ContentImplHelper::addProperty( Name, - Attributes, - DefaultValue ); + ContentImplHelper::addProperty( bIsSpecial ? aSpecialName : aProperty.Name, + aProperty.Attributes, + aDefaultValue ); break; default: @@ -920,25 +995,19 @@ void SAL_CALL Content::addProperty( const OUString& Name, } } -//========================================================================= -// virtual -void SAL_CALL Content::removeProperty( const OUString& Name ) - throw( beans::UnknownPropertyException, - beans::NotRemoveableException, - uno::RuntimeException ) +void Content::removeProperty( const rtl::OUString& Name, + const uno::Reference< ucb::XCommandEnvironment >& xEnv ) +throw( beans::UnknownPropertyException, + beans::NotRemoveableException, + uno::RuntimeException ) { - // @@@ Need real command environment here, but where to get it from? - // XPropertyContainer interface should be replaced by - // XCommandProcessor commands! - uno::Reference< ucb::XCommandEnvironment > xEnv; - #if 0 // @@@ REMOVABLE z.Z. nicht richtig an der PropSetInfo gesetzt!!! try { beans::Property aProp - = getPropertySetInfo( xEnv, sal_False /* don't cache data */ ) - ->getPropertyByName( Name ); + = getPropertySetInfo( xEnv, sal_False /* don't cache data */ ) + ->getPropertyByName( Name ); if ( !( aProp.Attributes & beans::PropertyAttribute::REMOVABLE ) ) { @@ -1001,20 +1070,20 @@ void SAL_CALL Content::removeProperty( const OUString& Name ) const ResourceType & rType = getResourceType( xEnv ); switch ( rType ) { - case UNKNOWN: - case DAV: - throw beans::UnknownPropertyException(); - - case NON_DAV: - // Try to remove property from local store. - ContentImplHelper::removeProperty( Name ); - break; - - default: - OSL_ENSURE( sal_False, - "Content::removeProperty - " - "Unsupported resource type!" ); - break; + case UNKNOWN: + case DAV: + throw beans::UnknownPropertyException(); + + case NON_DAV: + // Try to remove property from local store. + ContentImplHelper::removeProperty( Name ); + break; + + default: + OSL_ENSURE( sal_False, + "Content::removeProperty - " + "Unsupported resource type!" ); + break; } } catch ( uno::Exception const & ) @@ -1035,6 +1104,35 @@ void SAL_CALL Content::removeProperty( const OUString& Name ) } } +// virtual +void SAL_CALL Content::addProperty( const rtl::OUString& Name, + sal_Int16 Attributes, + const uno::Any& DefaultValue ) + throw( beans::PropertyExistException, + beans::IllegalTypeException, + lang::IllegalArgumentException, + uno::RuntimeException ) +{ + beans::Property aProperty; + aProperty.Name = Name; + aProperty.Type = DefaultValue.getValueType(); + aProperty.Attributes = Attributes; + aProperty.Handle = -1; + + addProperty( ucb::PropertyCommandArgument( aProperty, DefaultValue ), + uno::Reference< ucb::XCommandEnvironment >()); +} + +// virtual +void SAL_CALL Content::removeProperty( const rtl::OUString& Name ) + throw( beans::UnknownPropertyException, + beans::NotRemoveableException, + uno::RuntimeException ) +{ + removeProperty( Name, + uno::Reference< ucb::XCommandEnvironment >() ); +} + //========================================================================= // // XContentCreator methods. @@ -1749,11 +1847,14 @@ uno::Sequence< uno::Any > Content::setPropertyValues( // Optional props. ////////////////////////////////////////////////////////////// + rtl::OUString aSpecialName; + bool bIsSpecial = DAVProperties::isUCBSpecialProperty( rName, aSpecialName ); + if ( !xInfo.is() ) xInfo = getPropertySetInfo( xEnv, sal_False /* don't cache data */ ); - if ( !xInfo->hasPropertyByName( rName ) ) + if ( !xInfo->hasPropertyByName( bIsSpecial ? aSpecialName : rName ) ) { // Check, whether property exists. Skip otherwise. // PROPPATCH::set would add the property automatically, which @@ -1798,7 +1899,8 @@ uno::Sequence< uno::Any > Content::setPropertyValues( "Property is read-only!" ), static_cast< cppu::OWeakObject * >( this ) ); } - if ( rName == "CreatableContentsInfo" ) + if ( rName.equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) ) { // Read-only property! aRet[ n ] <<= lang::IllegalAccessException( diff --git a/ucb/source/ucp/webdav/webdavcontent.hxx b/ucb/source/ucp/webdav/webdavcontent.hxx index 6ffbd222b072..10c3022dba8e 100644 --- a/ucb/source/ucp/webdav/webdavcontent.hxx +++ b/ucb/source/ucp/webdav/webdavcontent.hxx @@ -46,6 +46,7 @@ namespace com { namespace sun { namespace star { namespace sdbc { namespace com { namespace sun { namespace star { namespace ucb { struct OpenCommandArgument2; + struct PropertyCommandArgument; struct PostCommandArgument2; struct TransferInfo; } } } } @@ -190,6 +191,21 @@ private: const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment ); + // XPropertyContainer replacement + void addProperty( const com::sun::star::ucb::PropertyCommandArgument &aCmdArg, + const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment >& Environment ) + throw( com::sun::star::beans::PropertyExistException, + com::sun::star::beans::IllegalTypeException, + com::sun::star::lang::IllegalArgumentException, + com::sun::star::uno::RuntimeException ); + + void removeProperty( const rtl::OUString& Name, + const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment >& Environment ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::beans::NotRemoveableException, + com::sun::star::uno::RuntimeException ); public: Content( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, diff --git a/ucb/source/ucp/webdav/webdavcontentcaps.cxx b/ucb/source/ucp/webdav/webdavcontentcaps.cxx index f075ba0d6665..89331674f011 100644 --- a/ucb/source/ucp/webdav/webdavcontentcaps.cxx +++ b/ucb/source/ucp/webdav/webdavcontentcaps.cxx @@ -26,6 +26,7 @@ #include <com/sun/star/ucb/OpenCommandArgument2.hpp> #include <com/sun/star/ucb/InsertCommandArgument.hpp> #include <com/sun/star/ucb/PostCommandArgument2.hpp> +#include <com/sun/star/ucb/PropertyCommandArgument.hpp> #include <com/sun/star/ucb/TransferInfo.hpp> #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/util/DateTime.hpp> @@ -492,7 +493,7 @@ uno::Sequence< ucb::CommandInfo > Content::getCommands( { osl::Guard< osl::Mutex > aGuard( m_aMutex ); - uno::Sequence< ucb::CommandInfo > aCmdInfo( 8 ); + uno::Sequence< ucb::CommandInfo > aCmdInfo( 10 ); /////////////////////////////////////////////////////////////// // Mandatory commands @@ -553,6 +554,18 @@ uno::Sequence< ucb::CommandInfo > Content::getCommands( -1, getCppuType( static_cast< ucb::PostCommandArgument2 * >( 0 ) ) ); + aCmdInfo[ 8 ] = + ucb::CommandInfo( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "addProperty" ) ), + -1, + getCppuType( static_cast< + ucb::PropertyCommandArgument * >( 0 ) ) ); + aCmdInfo[ 9 ] = + ucb::CommandInfo( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "removeProperty" ) ), + -1, + getCppuType( static_cast< + rtl::OUString * >( 0 ) ) ); sal_Bool bFolder = sal_False; |