LCOV - code coverage report
Current view: top level - ucb/source/ucp/cmis - cmis_content.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 520 0.0 %
Date: 2012-08-25 Functions: 0 39 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
       4                 :            :  *
       5                 :            :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :            :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :            :  * the License or as specified alternatively below. You may obtain a copy of
       8                 :            :  * the License at http://www.mozilla.org/MPL/
       9                 :            :  *
      10                 :            :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :            :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :            :  * for the specific language governing rights and limitations under the
      13                 :            :  * License.
      14                 :            :  *
      15                 :            :  * Major Contributor(s):
      16                 :            :  * [ Copyright (C) 2011 SUSE <cbosdonnat@suse.com> (initial developer) ]
      17                 :            :  *
      18                 :            :  * All Rights Reserved.
      19                 :            :  *
      20                 :            :  * For minor contributions see the git repository.
      21                 :            :  *
      22                 :            :  * Alternatively, the contents of this file may be used under the terms of
      23                 :            :  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      24                 :            :  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
      25                 :            :  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
      26                 :            :  * instead of those above.
      27                 :            :  */
      28                 :            : 
      29                 :            : #include <cstdio>
      30                 :            : 
      31                 :            : #include <com/sun/star/beans/PropertyAttribute.hpp>
      32                 :            : #include <com/sun/star/beans/PropertyValue.hpp>
      33                 :            : #include <com/sun/star/beans/XPropertySetInfo.hpp>
      34                 :            : #include <com/sun/star/io/XActiveDataSink.hpp>
      35                 :            : #include <com/sun/star/io/XActiveDataStreamer.hpp>
      36                 :            : #include <com/sun/star/lang/IllegalAccessException.hpp>
      37                 :            : #include <com/sun/star/task/InteractionClassification.hpp>
      38                 :            : #include <com/sun/star/ucb/ContentInfo.hpp>
      39                 :            : #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
      40                 :            : #include <com/sun/star/ucb/InsertCommandArgument.hpp>
      41                 :            : #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
      42                 :            : #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
      43                 :            : #include <com/sun/star/ucb/MissingInputStreamException.hpp>
      44                 :            : #include <com/sun/star/ucb/NameClash.hpp>
      45                 :            : #include <com/sun/star/ucb/NameClashException.hpp>
      46                 :            : #include <com/sun/star/ucb/OpenMode.hpp>
      47                 :            : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
      48                 :            : #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
      49                 :            : #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
      50                 :            : #include <com/sun/star/ucb/XCommandInfo.hpp>
      51                 :            : #include <com/sun/star/ucb/XDynamicResultSet.hpp>
      52                 :            : 
      53                 :            : #include <libcmis/document.hxx>
      54                 :            : 
      55                 :            : #include <ucbhelper/cancelcommandexecution.hxx>
      56                 :            : #include <ucbhelper/contentidentifier.hxx>
      57                 :            : #include <ucbhelper/std_inputstream.hxx>
      58                 :            : #include <ucbhelper/std_outputstream.hxx>
      59                 :            : #include <ucbhelper/propertyvalueset.hxx>
      60                 :            : 
      61                 :            : #include "auth_provider.hxx"
      62                 :            : #include "cmis_content.hxx"
      63                 :            : #include "cmis_provider.hxx"
      64                 :            : #include "cmis_resultset.hxx"
      65                 :            : 
      66                 :            : #define OUSTR_TO_STDSTR(s) string( rtl::OUStringToOString( s, RTL_TEXTENCODING_UTF8 ).getStr() )
      67                 :            : #define STD_TO_OUSTR( str ) rtl::OUString( str.c_str(), str.length( ), RTL_TEXTENCODING_UTF8 )
      68                 :            : 
      69                 :            : using namespace com::sun::star;
      70                 :            : using namespace std;
      71                 :            : 
      72                 :            : namespace
      73                 :            : {
      74                 :          0 :     util::DateTime lcl_boostToUnoTime( boost::posix_time::ptime boostTime )
      75                 :            :     {
      76                 :          0 :         util::DateTime unoTime;
      77                 :          0 :         unoTime.Year = boostTime.date().year();
      78                 :          0 :         unoTime.Month = boostTime.date().month();
      79                 :          0 :         unoTime.Day = boostTime.date().day();
      80                 :          0 :         unoTime.Hours = boostTime.time_of_day().hours();
      81                 :          0 :         unoTime.Minutes = boostTime.time_of_day().minutes();
      82                 :          0 :         unoTime.Seconds = boostTime.time_of_day().seconds();
      83                 :            : 
      84                 :          0 :         long total_milli = boostTime.time_of_day().total_milliseconds( );
      85                 :          0 :         long milli = total_milli - boostTime.time_of_day().total_seconds( );
      86                 :          0 :         long hundredthSeconds = milli / 10;
      87                 :            : 
      88                 :          0 :         unoTime.HundredthSeconds = hundredthSeconds;
      89                 :            : 
      90                 :          0 :         return unoTime;
      91                 :            :     }
      92                 :            : }
      93                 :            : 
      94                 :            : namespace cmis
      95                 :            : {
      96                 :          0 :     Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
      97                 :            :         ContentProvider *pProvider, const uno::Reference< ucb::XContentIdentifier >& Identifier,
      98                 :            :         libcmis::ObjectPtr pObject )
      99                 :            :             throw ( ucb::ContentCreationException )
     100                 :            :         : ContentImplHelper( rxSMgr, pProvider, Identifier ),
     101                 :            :         m_pProvider( pProvider ),
     102                 :            :         m_pSession( NULL ),
     103                 :            :         m_pObject( pObject ),
     104                 :          0 :         m_bTransient( false )
     105                 :            :     {
     106                 :            :         // Split the URL into bits
     107                 :          0 :         m_sURL = m_xIdentifier->getContentIdentifier( );
     108                 :          0 :         cmis::URL url( m_sURL );
     109                 :            :         SAL_INFO( "cmisucp", "Content::Content() " << m_sURL );
     110                 :            : 
     111                 :            :         // Look for a cached session, key is binding url + repo id
     112                 :          0 :         rtl::OUString sSessionId = url.getBindingUrl( ) + url.getRepositoryId( );
     113                 :          0 :         m_pSession = pProvider->getSession( sSessionId );
     114                 :          0 :         if ( NULL == m_pSession )
     115                 :            :         {
     116                 :            :             // Initiate a CMIS session and register it as we found nothing
     117                 :          0 :             m_pSession = libcmis::SessionFactory::createSession( url.getSessionParams( ) );
     118                 :          0 :             pProvider->registerSession( sSessionId, m_pSession );
     119                 :            :         }
     120                 :            : 
     121                 :          0 :         m_sObjectPath = url.getObjectPath( );
     122                 :          0 :         m_sObjectId = url.getObjectId( );
     123                 :          0 :         m_sBindingUrl = url.getBindingUrl( );
     124                 :          0 :     }
     125                 :            : 
     126                 :          0 :     Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, ContentProvider *pProvider,
     127                 :            :         const uno::Reference< ucb::XContentIdentifier >& Identifier,
     128                 :            :         sal_Bool bIsFolder )
     129                 :            :             throw ( ucb::ContentCreationException )
     130                 :            :         : ContentImplHelper( rxSMgr, pProvider, Identifier ),
     131                 :            :         m_pProvider( pProvider ),
     132                 :            :         m_pSession( NULL ),
     133                 :          0 :         m_bTransient( true )
     134                 :            :     {
     135                 :            :         // Split the URL into bits
     136                 :          0 :         m_sURL = m_xIdentifier->getContentIdentifier( );
     137                 :          0 :         cmis::URL url( m_sURL );
     138                 :            :         SAL_INFO( "cmisucp", "Content::Content() " << m_sURL );
     139                 :            : 
     140                 :            :         // Look for a cached session, key is binding url + repo id
     141                 :          0 :         rtl::OUString sSessionId = url.getBindingUrl( ) + url.getRepositoryId( );
     142                 :          0 :         m_pSession = pProvider->getSession( sSessionId );
     143                 :          0 :         if ( NULL == m_pSession )
     144                 :            :         {
     145                 :            :             // Initiate a CMIS session and register it as we found nothing
     146                 :          0 :             m_pSession = libcmis::SessionFactory::createSession( url.getSessionParams( ) );
     147                 :          0 :             pProvider->registerSession( sSessionId, m_pSession );
     148                 :            :         }
     149                 :            : 
     150                 :          0 :         m_sObjectPath = url.getObjectPath( );
     151                 :          0 :         m_sObjectId = url.getObjectId( );
     152                 :          0 :         m_sBindingUrl = url.getBindingUrl( );
     153                 :            : 
     154                 :            :         // Get the object type
     155                 :          0 :         string typeId = bIsFolder ? "cmis:folder" : "cmis:document";
     156                 :          0 :         m_pObjectType = m_pSession->getType( typeId );
     157                 :          0 :     }
     158                 :            : 
     159                 :          0 :     Content::~Content()
     160                 :            :     {
     161                 :          0 :     }
     162                 :            : 
     163                 :          0 :     libcmis::ObjectPtr Content::getObject( ) throw ( libcmis::Exception )
     164                 :            :     {
     165                 :          0 :         if ( !m_pObject.get() )
     166                 :            :         {
     167                 :          0 :             if ( !m_sObjectPath.isEmpty( ) )
     168                 :          0 :                 m_pObject = m_pSession->getObjectByPath( OUSTR_TO_STDSTR( m_sObjectPath ) );
     169                 :          0 :             else if (!m_sObjectId.isEmpty( ) )
     170                 :          0 :                 m_pObject = m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
     171                 :            :             else
     172                 :            :             {
     173                 :          0 :                 m_pObject = m_pSession->getRootFolder( );
     174                 :          0 :                 m_sObjectPath = "/";
     175                 :          0 :                 m_sObjectId = rtl::OUString( );
     176                 :            :             }
     177                 :            :         }
     178                 :            : 
     179                 :          0 :         return m_pObject;
     180                 :            :     }
     181                 :            : 
     182                 :          0 :     void Content::resetAuthProvider( const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     183                 :            :     {
     184                 :          0 :         libcmis::AuthProviderPtr authProvider( new AuthProvider( xEnv, m_sURL, m_sBindingUrl ) );
     185                 :          0 :         m_pSession->setAuthenticationProvider( authProvider );
     186                 :          0 :     }
     187                 :            : 
     188                 :          0 :     bool Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     189                 :            :     {
     190                 :          0 :         bool bIsFolder = false;
     191                 :            :         try
     192                 :            :         {
     193                 :          0 :             resetAuthProvider( xEnv );
     194                 :          0 :             bIsFolder = getObject( )->getBaseType( ) == "cmis:folder";
     195                 :            :         }
     196                 :          0 :         catch ( const libcmis::Exception& e )
     197                 :            :         {
     198                 :            :             SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
     199                 :            :             ucbhelper::cancelCommandExecution(
     200                 :            :                                 ucb::IOErrorCode_GENERAL,
     201                 :            :                                 uno::Sequence< uno::Any >( 0 ),
     202                 :            :                                 xEnv,
     203                 :          0 :                                 rtl::OUString::createFromAscii( e.what() ) );
     204                 :            :         }
     205                 :          0 :         return bIsFolder;
     206                 :            :     }
     207                 :            : 
     208                 :          0 :     uno::Any Content::getBadArgExcept()
     209                 :            :     {
     210                 :            :         return uno::makeAny( lang::IllegalArgumentException(
     211                 :            :             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Wrong argument type!")),
     212                 :          0 :             static_cast< cppu::OWeakObject * >( this ), -1) );
     213                 :            :     }
     214                 :            : 
     215                 :          0 :     uno::Reference< sdbc::XRow > Content::getPropertyValues(
     216                 :            :             const uno::Sequence< beans::Property >& rProperties,
     217                 :            :             const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     218                 :            :     {
     219                 :          0 :         resetAuthProvider( xEnv );
     220                 :            : 
     221                 :          0 :         rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( m_xSMgr );
     222                 :            : 
     223                 :            :         sal_Int32 nProps;
     224                 :            :         const beans::Property* pProps;
     225                 :            : 
     226                 :          0 :         nProps = rProperties.getLength();
     227                 :          0 :         pProps = rProperties.getConstArray();
     228                 :            : 
     229                 :          0 :         for( sal_Int32 n = 0; n < nProps; ++n )
     230                 :            :         {
     231                 :          0 :             const beans::Property& rProp = pProps[ n ];
     232                 :            : 
     233                 :            :             try
     234                 :            :             {
     235                 :          0 :                 if ( rProp.Name == "IsDocument" )
     236                 :            :                 {
     237                 :            :                     try
     238                 :            :                     {
     239                 :          0 :                         xRow->appendBoolean( rProp, getObject()->getBaseType( ) == "cmis:document" );
     240                 :            :                     }
     241                 :          0 :                     catch ( const libcmis::Exception& )
     242                 :            :                     {
     243                 :          0 :                         if ( m_pObjectType.get( ) )
     244                 :          0 :                             xRow->appendBoolean( rProp, m_pObjectType->getBaseType()->getId( ) == "cmis:document" );
     245                 :            :                         else
     246                 :          0 :                             xRow->appendVoid( rProp );
     247                 :            :                     }
     248                 :            :                 }
     249                 :          0 :                 else if ( rProp.Name == "IsFolder" )
     250                 :            :                 {
     251                 :            :                     try
     252                 :            :                     {
     253                 :          0 :                         xRow->appendBoolean( rProp, getObject()->getBaseType( ) == "cmis:folder" );
     254                 :            :                     }
     255                 :          0 :                     catch ( const libcmis::Exception& )
     256                 :            :                     {
     257                 :          0 :                         if ( m_pObjectType.get( ) )
     258                 :          0 :                             xRow->appendBoolean( rProp, m_pObjectType->getBaseType()->getId( ) == "cmis:folder" );
     259                 :            :                         else
     260                 :          0 :                             xRow->appendVoid( rProp );
     261                 :            :                     }
     262                 :            :                 }
     263                 :          0 :                 else if ( rProp.Name == "Title" )
     264                 :            :                 {
     265                 :          0 :                     rtl::OUString sTitle;
     266                 :            :                     try
     267                 :            :                     {
     268                 :          0 :                         sTitle = STD_TO_OUSTR( getObject()->getName() );
     269                 :            :                     }
     270                 :          0 :                     catch ( const libcmis::Exception& )
     271                 :            :                     {
     272                 :          0 :                         if ( !m_pObjectProps.empty() )
     273                 :            :                         {
     274                 :          0 :                             map< string, libcmis::PropertyPtr >::iterator it = m_pObjectProps.find( "cmis:name" );
     275                 :          0 :                             if ( it != m_pObjectProps.end( ) )
     276                 :            :                             {
     277                 :          0 :                                 vector< string > values = it->second->getStrings( );
     278                 :          0 :                                 if ( !values.empty() )
     279                 :          0 :                                     sTitle = STD_TO_OUSTR( values.front( ) );
     280                 :            :                             }
     281                 :            :                         }
     282                 :            :                     }
     283                 :            : 
     284                 :            :                     // Nothing worked... get it from the path
     285                 :          0 :                     if ( sTitle.isEmpty( ) )
     286                 :            :                     {
     287                 :          0 :                         rtl::OUString sPath = m_sObjectPath;
     288                 :            : 
     289                 :            :                         // Get rid of the trailing slash problem
     290                 :          0 :                         if ( sPath[ sPath.getLength( ) - 1 ] == '/' )
     291                 :          0 :                             sPath = sPath.copy( 0, sPath.getLength() - 1 );
     292                 :            : 
     293                 :            :                         // Get the last segment
     294                 :          0 :                         sal_Int32 nPos = sPath.lastIndexOf( '/' );
     295                 :          0 :                         if ( nPos >= 0 )
     296                 :          0 :                             sTitle = sPath.copy( nPos + 1 );
     297                 :            :                     }
     298                 :            : 
     299                 :          0 :                     if ( !sTitle.isEmpty( ) )
     300                 :          0 :                         xRow->appendString( rProp, sTitle );
     301                 :            :                     else
     302                 :          0 :                         xRow->appendVoid( rProp );
     303                 :            :                 }
     304                 :          0 :                 else if ( rProp.Name == "TitleOnServer" )
     305                 :            :                 {
     306                 :          0 :                     string path;
     307                 :            :                     try
     308                 :            :                     {
     309                 :          0 :                         vector< string > paths = getObject( )->getPaths( );
     310                 :          0 :                         if ( !paths.empty( ) )
     311                 :          0 :                             path = paths.front( );
     312                 :            :                         else
     313                 :          0 :                             path = getObject()->getName( );
     314                 :            : 
     315                 :          0 :                         xRow->appendString( rProp, STD_TO_OUSTR( path ) );
     316                 :            :                     }
     317                 :          0 :                     catch ( const libcmis::Exception& )
     318                 :            :                     {
     319                 :          0 :                         xRow->appendVoid( rProp );
     320                 :          0 :                     }
     321                 :            :                 }
     322                 :          0 :                 else if ( rProp.Name == "IsReadOnly" )
     323                 :            :                 {
     324                 :          0 :                     boost::shared_ptr< libcmis::AllowableActions > allowableActions = getObject()->getAllowableActions( );
     325                 :          0 :                     sal_Bool bReadOnly = sal_False;
     326                 :          0 :                     if ( !allowableActions->isAllowed( libcmis::ObjectAction::SetContentStream ) )
     327                 :          0 :                         bReadOnly = sal_True;
     328                 :            : 
     329                 :          0 :                     xRow->appendBoolean( rProp, bReadOnly );
     330                 :            :                 }
     331                 :          0 :                 else if ( rProp.Name == "DateCreated" )
     332                 :            :                 {
     333                 :          0 :                     util::DateTime aTime = lcl_boostToUnoTime( getObject( )->getCreationDate( ) );
     334                 :          0 :                     xRow->appendTimestamp( rProp, aTime );
     335                 :            :                 }
     336                 :          0 :                 else if ( rProp.Name == "DateModified" )
     337                 :            :                 {
     338                 :          0 :                     util::DateTime aTime = lcl_boostToUnoTime( getObject( )->getLastModificationDate( ) );
     339                 :          0 :                     xRow->appendTimestamp( rProp, aTime );
     340                 :            :                 }
     341                 :          0 :                 else if ( rProp.Name == "Size" )
     342                 :            :                 {
     343                 :            :                     try
     344                 :            :                     {
     345                 :          0 :                         libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject().get( ) );
     346                 :          0 :                         if ( NULL != document )
     347                 :          0 :                             xRow->appendLong( rProp, document->getContentLength() );
     348                 :            :                         else
     349                 :          0 :                             xRow->appendVoid( rProp );
     350                 :            :                     }
     351                 :          0 :                     catch ( const libcmis::Exception& )
     352                 :            :                     {
     353                 :          0 :                         xRow->appendVoid( rProp );
     354                 :            :                     }
     355                 :            :                 }
     356                 :          0 :                 else if ( rProp.Name == "CreatableContentsInfo" )
     357                 :            :                 {
     358                 :          0 :                     xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) );
     359                 :            :                 }
     360                 :          0 :                 else if ( rProp.Name == "MediaType" )
     361                 :            :                 {
     362                 :            :                     try
     363                 :            :                     {
     364                 :          0 :                         libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject().get( ) );
     365                 :          0 :                         if ( NULL != document )
     366                 :          0 :                             xRow->appendString( rProp, STD_TO_OUSTR( document->getContentType() ) );
     367                 :            :                         else
     368                 :          0 :                             xRow->appendVoid( rProp );
     369                 :            :                     }
     370                 :          0 :                     catch ( const libcmis::Exception& )
     371                 :            :                     {
     372                 :          0 :                         xRow->appendVoid( rProp );
     373                 :            :                     }
     374                 :            :                 }
     375                 :            :                 else
     376                 :            :                     SAL_INFO( "cmisucp", "Looking for unsupported property " << rProp.Name );
     377                 :            :             }
     378                 :          0 :             catch (const libcmis::Exception&)
     379                 :            :             {
     380                 :          0 :                 xRow->appendVoid( rProp );
     381                 :            :             }
     382                 :            :         }
     383                 :            : 
     384                 :          0 :         return uno::Reference< sdbc::XRow >( xRow.get() );
     385                 :            :     }
     386                 :            : 
     387                 :          0 :     bool Content::exists( )
     388                 :            :     {
     389                 :          0 :         bool bExists = true;
     390                 :            :         try
     391                 :            :         {
     392                 :          0 :             if ( !m_sObjectPath.isEmpty( ) )
     393                 :          0 :                 m_pSession->getObjectByPath( OUSTR_TO_STDSTR( m_sObjectPath ) );
     394                 :          0 :             else if ( !m_sObjectId.isEmpty( ) )
     395                 :          0 :                 m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
     396                 :            :             // No need to handle the root folder case... how can it not exists?
     397                 :            :         }
     398                 :          0 :         catch ( const libcmis::Exception& )
     399                 :            :         {
     400                 :          0 :             bExists = false;
     401                 :            :         }
     402                 :            : 
     403                 :          0 :         return bExists;
     404                 :            :     }
     405                 :            : 
     406                 :          0 :     uno::Any Content::open(const ucb::OpenCommandArgument2 & rOpenCommand,
     407                 :            :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
     408                 :            :             throw( uno::Exception )
     409                 :            :     {
     410                 :          0 :         bool bIsFolder = isFolder( xEnv );
     411                 :            : 
     412                 :            :         // Handle the case of the non-existing file
     413                 :          0 :         if ( !exists( ) )
     414                 :            :         {
     415                 :          0 :             uno::Sequence< uno::Any > aArgs( 1 );
     416                 :          0 :             aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
     417                 :            :             uno::Any aErr = uno::makeAny(
     418                 :            :                 ucb::InteractiveAugmentedIOException(rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
     419                 :            :                     task::InteractionClassification_ERROR,
     420                 :            :                     bIsFolder ? ucb::IOErrorCode_NOT_EXISTING_PATH : ucb::IOErrorCode_NOT_EXISTING, aArgs)
     421                 :          0 :             );
     422                 :            : 
     423                 :          0 :             ucbhelper::cancelCommandExecution(aErr, xEnv);
     424                 :            :         }
     425                 :            : 
     426                 :          0 :         uno::Any aRet;
     427                 :            : 
     428                 :            :         sal_Bool bOpenFolder = (
     429                 :            :             ( rOpenCommand.Mode == ucb::OpenMode::ALL ) ||
     430                 :            :             ( rOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
     431                 :            :             ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENTS )
     432                 :          0 :          );
     433                 :            : 
     434                 :          0 :         if ( bOpenFolder && bIsFolder )
     435                 :            :         {
     436                 :            :             uno::Reference< ucb::XDynamicResultSet > xSet
     437                 :          0 :                 = new DynamicResultSet(m_xSMgr, this, rOpenCommand, xEnv );
     438                 :          0 :             aRet <<= xSet;
     439                 :            :         }
     440                 :          0 :         else if ( rOpenCommand.Sink.is() )
     441                 :            :         {
     442                 :          0 :             if (
     443                 :            :                 ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
     444                 :            :                 ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE )
     445                 :            :                )
     446                 :            :             {
     447                 :            :                 ucbhelper::cancelCommandExecution(
     448                 :            :                     uno::makeAny ( ucb::UnsupportedOpenModeException
     449                 :            :                         ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
     450                 :            :                           sal_Int16( rOpenCommand.Mode ) ) ),
     451                 :          0 :                         xEnv );
     452                 :            :             }
     453                 :            : 
     454                 :          0 :             if ( !feedSink( rOpenCommand.Sink, xEnv ) )
     455                 :            :             {
     456                 :            :                 // Note: rOpenCommand.Sink may contain an XStream
     457                 :            :                 //       implementation. Support for this type of
     458                 :            :                 //       sink is optional...
     459                 :            :                 SAL_INFO( "cmisucp", "Failed to copy data to sink" );
     460                 :            : 
     461                 :            :                 ucbhelper::cancelCommandExecution(
     462                 :            :                     uno::makeAny (ucb::UnsupportedDataSinkException
     463                 :            :                         ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
     464                 :            :                           rOpenCommand.Sink ) ),
     465                 :          0 :                         xEnv );
     466                 :            :             }
     467                 :            :         }
     468                 :            :         else
     469                 :            :             SAL_INFO( "cmisucp", "Open falling through ..." );
     470                 :            : 
     471                 :          0 :         return aRet;
     472                 :            :     }
     473                 :            : 
     474                 :          0 :     void Content::transfer( const ucb::TransferInfo& rTransferInfo,
     475                 :            :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
     476                 :            :             throw( uno::Exception )
     477                 :            :     {
     478                 :            :         // If the source isn't on the same CMIS repository, then simply copy
     479                 :          0 :         INetURLObject aSourceUrl( rTransferInfo.SourceURL );
     480                 :          0 :         if ( aSourceUrl.GetProtocol() != INET_PROT_CMIS_ATOM )
     481                 :            :         {
     482                 :          0 :             rtl::OUString sSrcBindingUrl = URL( rTransferInfo.SourceURL ).getBindingUrl( );
     483                 :          0 :             if ( sSrcBindingUrl != m_sBindingUrl )
     484                 :            :             {
     485                 :            :                 ucbhelper::cancelCommandExecution(
     486                 :            :                     uno::makeAny(
     487                 :            :                         ucb::InteractiveBadTransferURLException(
     488                 :            :                             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
     489                 :            :                                 "Unsupported URL scheme!" )),
     490                 :            :                             static_cast< cppu::OWeakObject * >( this ) ) ),
     491                 :          0 :                     xEnv );
     492                 :          0 :             }
     493                 :            :         }
     494                 :            : 
     495                 :          0 :         SAL_INFO( "cmisucp", "TODO - Content::transfer()" );
     496                 :          0 :     }
     497                 :            : 
     498                 :          0 :     void Content::insert( const uno::Reference< io::XInputStream > & xInputStream,
     499                 :            :         sal_Bool bReplaceExisting, const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     500                 :            :             throw( uno::Exception )
     501                 :            :     {
     502                 :          0 :         if ( !xInputStream.is() )
     503                 :            :         {
     504                 :            :             ucbhelper::cancelCommandExecution( uno::makeAny
     505                 :            :                 ( ucb::MissingInputStreamException
     506                 :            :                   ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ) ) ),
     507                 :          0 :                 xEnv );
     508                 :            :         }
     509                 :            : 
     510                 :            :         // For transient content, the URL is the one of the parent
     511                 :          0 :         if ( m_bTransient )
     512                 :            :         {
     513                 :          0 :             rtl::OUString sNewPath;
     514                 :            : 
     515                 :            :             // Try to get the object from the server if there is any
     516                 :          0 :             libcmis::Folder* pFolder = NULL;
     517                 :            :             try
     518                 :            :             {
     519                 :          0 :                 pFolder = dynamic_cast< libcmis::Folder* >( getObject( ).get( ) );
     520                 :            :             }
     521                 :          0 :             catch ( const libcmis::Exception& )
     522                 :            :             {
     523                 :            :             }
     524                 :            : 
     525                 :          0 :             if ( pFolder != NULL )
     526                 :            :             {
     527                 :          0 :                 map< string, libcmis::PropertyPtr >::iterator it = m_pObjectProps.find( "cmis:name" );
     528                 :          0 :                 if ( it == m_pObjectProps.end( ) )
     529                 :            :                 {
     530                 :            :                     ucbhelper::cancelCommandExecution( uno::makeAny
     531                 :            :                         ( uno::RuntimeException( "Missing name property",
     532                 :            :                             static_cast< cppu::OWeakObject * >( this ) ) ),
     533                 :          0 :                         xEnv );
     534                 :            :                 }
     535                 :          0 :                 string newName = it->second->getStrings( ).front( );
     536                 :          0 :                 string newPath = pFolder->getPath( );
     537                 :          0 :                 if ( newPath[ newPath.size( ) - 1 ] != '/' )
     538                 :          0 :                     newPath += "/";
     539                 :          0 :                 newPath += newName;
     540                 :            : 
     541                 :          0 :                 libcmis::ObjectPtr object;
     542                 :            :                 try
     543                 :            :                 {
     544                 :          0 :                     object = m_pSession->getObjectByPath( newPath );
     545                 :          0 :                     sNewPath = STD_TO_OUSTR( newPath );
     546                 :            :                 }
     547                 :          0 :                 catch ( const libcmis::Exception& )
     548                 :            :                 {
     549                 :            :                     // Nothing matched the path
     550                 :            :                 }
     551                 :            : 
     552                 :          0 :                 if ( NULL != object.get( ) )
     553                 :            :                 {
     554                 :            :                     // Are the base type matching?
     555                 :          0 :                     if ( object->getBaseType( ) != m_pObjectType->getBaseType( )->getId() )
     556                 :            :                     {
     557                 :            :                         ucbhelper::cancelCommandExecution( uno::makeAny
     558                 :            :                             ( uno::RuntimeException( "Can't change a folder into a document and vice-versa.",
     559                 :            :                                 static_cast< cppu::OWeakObject * >( this ) ) ),
     560                 :          0 :                             xEnv );
     561                 :            :                     }
     562                 :            : 
     563                 :            :                     // Update the existing object if it's a document
     564                 :          0 :                     libcmis::Document* document = dynamic_cast< libcmis::Document* >( object.get( ) );
     565                 :          0 :                     if ( NULL != document )
     566                 :            :                     {
     567                 :          0 :                         string sMime = document->getContentType( );
     568                 :          0 :                         boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) );
     569                 :          0 :                         uno::Reference < io::XOutputStream > xOutput = new ucbhelper::StdOutputStream( pOut );
     570                 :          0 :                         copyData( xInputStream, xOutput );
     571                 :          0 :                         document->setContentStream( pOut, sMime, bReplaceExisting );
     572                 :            :                     }
     573                 :            :                 }
     574                 :            :                 else
     575                 :            :                 {
     576                 :            :                     // We need to create a brand new object... either folder or document
     577                 :          0 :                     bool bIsFolder = m_pObjectType->getBaseType( )->getId( ) == "cmis:folder";
     578                 :          0 :                     setCmisProperty( "cmis:objectTypeId", m_pObjectType->getId( ) );
     579                 :            : 
     580                 :          0 :                     if ( bIsFolder )
     581                 :            :                     {
     582                 :          0 :                         libcmis::FolderPtr pNew = pFolder->createFolder( m_pObjectProps );
     583                 :          0 :                         sNewPath = STD_TO_OUSTR( newPath );
     584                 :            :                     }
     585                 :            :                     else
     586                 :            :                     {
     587                 :          0 :                         boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) );
     588                 :          0 :                         uno::Reference < io::XOutputStream > xOutput = new ucbhelper::StdOutputStream( pOut );
     589                 :          0 :                         copyData( xInputStream, xOutput );
     590                 :          0 :                         libcmis::DocumentPtr pNew = pFolder->createDocument( m_pObjectProps, pOut, string() );
     591                 :          0 :                         sNewPath = STD_TO_OUSTR( newPath );
     592                 :            :                     }
     593                 :            :                 }
     594                 :            : 
     595                 :          0 :                 if ( !sNewPath.isEmpty( ) )
     596                 :            :                 {
     597                 :            :                     // Update the current content: it's no longer transient
     598                 :          0 :                     m_sObjectPath = sNewPath;
     599                 :          0 :                     URL aUrl( m_sURL );
     600                 :          0 :                     aUrl.setObjectPath( m_sObjectPath );
     601                 :          0 :                     m_sURL = aUrl.asString( );
     602                 :          0 :                     m_pObject.reset( );
     603                 :          0 :                     m_pObjectType.reset( );
     604                 :          0 :                     m_pObjectProps.clear( );
     605                 :          0 :                     m_bTransient = false;
     606                 :            : 
     607                 :          0 :                     inserted();
     608                 :          0 :                 }
     609                 :          0 :             }
     610                 :            :         }
     611                 :          0 :     }
     612                 :            : 
     613                 :            :     const int TRANSFER_BUFFER_SIZE = 65536;
     614                 :            : 
     615                 :          0 :     void Content::copyData(
     616                 :            :         uno::Reference< io::XInputStream > xIn,
     617                 :            :         uno::Reference< io::XOutputStream > xOut )
     618                 :            :     {
     619                 :          0 :         uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
     620                 :            : 
     621                 :          0 :         while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
     622                 :          0 :             xOut->writeBytes( theData );
     623                 :            : 
     624                 :          0 :         xOut->closeOutput();
     625                 :          0 :     }
     626                 :            : 
     627                 :          0 :     uno::Sequence< uno::Any > Content::setPropertyValues(
     628                 :            :             const uno::Sequence< beans::PropertyValue >& rValues,
     629                 :            :             const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     630                 :            :     {
     631                 :            :         try
     632                 :            :         {
     633                 :            :             // Get the already set properties if possible
     634                 :          0 :             if ( !m_bTransient && getObject( ).get( ) )
     635                 :            :             {
     636                 :          0 :                 m_pObjectProps = getObject()->getProperties( );
     637                 :          0 :                 m_pObjectType = getObject()->getTypeDescription();
     638                 :            :             }
     639                 :            :         }
     640                 :          0 :         catch ( const libcmis::Exception& e )
     641                 :            :         {
     642                 :            :             SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
     643                 :            :             ucbhelper::cancelCommandExecution(
     644                 :            :                                 ucb::IOErrorCode_GENERAL,
     645                 :            :                                 uno::Sequence< uno::Any >( 0 ),
     646                 :            :                                 xEnv,
     647                 :          0 :                                 rtl::OUString::createFromAscii( e.what() ) );
     648                 :            :         }
     649                 :            : 
     650                 :          0 :         sal_Int32 nCount = rValues.getLength();
     651                 :          0 :         uno::Sequence< uno::Any > aRet( nCount );
     652                 :            : 
     653                 :          0 :         bool bChanged = false;
     654                 :          0 :         const beans::PropertyValue* pValues = rValues.getConstArray();
     655                 :          0 :         for ( sal_Int32 n = 0; n < nCount; ++n )
     656                 :            :         {
     657                 :          0 :             const beans::PropertyValue& rValue = pValues[ n ];
     658                 :          0 :             if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ||
     659                 :          0 :                  rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ||
     660                 :          0 :                  rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ||
     661                 :          0 :                  rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ||
     662                 :          0 :                  rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ||
     663                 :          0 :                  rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
     664                 :            :             {
     665                 :            :                 lang::IllegalAccessException e ( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Property is read-only!")),
     666                 :          0 :                        static_cast< cppu::OWeakObject* >( this ) );
     667                 :          0 :                 aRet[ n ] <<= e;
     668                 :            :             }
     669                 :          0 :             else if ( rValue.Name == "Title" )
     670                 :            :             {
     671                 :          0 :                 rtl::OUString aNewTitle;
     672                 :          0 :                 if (!( rValue.Value >>= aNewTitle ))
     673                 :            :                 {
     674                 :          0 :                     aRet[ n ] <<= beans::IllegalTypeException
     675                 :            :                         ( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Property value has wrong type!")),
     676                 :          0 :                           static_cast< cppu::OWeakObject * >( this ) );
     677                 :          0 :                     continue;
     678                 :            :                 }
     679                 :            : 
     680                 :          0 :                 if ( aNewTitle.getLength() <= 0 )
     681                 :            :                 {
     682                 :          0 :                     aRet[ n ] <<= lang::IllegalArgumentException
     683                 :            :                         ( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty title not allowed!")),
     684                 :          0 :                           static_cast< cppu::OWeakObject * >( this ), -1 );
     685                 :          0 :                     continue;
     686                 :            : 
     687                 :            :                 }
     688                 :            : 
     689                 :          0 :                 setCmisProperty( "cmis:name", OUSTR_TO_STDSTR( aNewTitle ) );
     690                 :          0 :                 bChanged = true;
     691                 :            :             }
     692                 :            :             else
     693                 :            :             {
     694                 :            :                 SAL_INFO( "cmisucp", "Couln't set property: " << rValue.Name );
     695                 :            :                 lang::IllegalAccessException e ( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Property is read-only!")),
     696                 :          0 :                        static_cast< cppu::OWeakObject* >( this ) );
     697                 :          0 :                 aRet[ n ] <<= e;
     698                 :            :             }
     699                 :            :         }
     700                 :            : 
     701                 :            :         try
     702                 :            :         {
     703                 :          0 :             if ( !m_bTransient && bChanged )
     704                 :            :             {
     705                 :          0 :                 getObject()->updateProperties();
     706                 :            :             }
     707                 :            :         }
     708                 :          0 :         catch ( const libcmis::Exception& e )
     709                 :            :         {
     710                 :            :             SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
     711                 :            :             ucbhelper::cancelCommandExecution(
     712                 :            :                                 ucb::IOErrorCode_GENERAL,
     713                 :            :                                 uno::Sequence< uno::Any >( 0 ),
     714                 :            :                                 xEnv,
     715                 :          0 :                                 rtl::OUString::createFromAscii( e.what() ) );
     716                 :            :         }
     717                 :            : 
     718                 :          0 :         return aRet;
     719                 :            :     }
     720                 :            : 
     721                 :          0 :     sal_Bool Content::feedSink( uno::Reference< uno::XInterface> xSink,
     722                 :            :         const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     723                 :            :     {
     724                 :          0 :         if ( !xSink.is() )
     725                 :          0 :             return sal_False;
     726                 :            : 
     727                 :          0 :         uno::Reference< io::XOutputStream > xOut = uno::Reference< io::XOutputStream >(xSink, uno::UNO_QUERY );
     728                 :          0 :         uno::Reference< io::XActiveDataSink > xDataSink = uno::Reference< io::XActiveDataSink >(xSink, uno::UNO_QUERY );
     729                 :          0 :         uno::Reference< io::XActiveDataStreamer > xDataStreamer = uno::Reference< io::XActiveDataStreamer >( xSink, uno::UNO_QUERY );
     730                 :            : 
     731                 :          0 :         if ( !xOut.is() && !xDataSink.is() && ( !xDataStreamer.is() || !xDataStreamer->getStream().is() ) )
     732                 :          0 :             return sal_False;
     733                 :            : 
     734                 :          0 :         if ( xDataStreamer.is() && !xOut.is() )
     735                 :          0 :             xOut = xDataStreamer->getStream()->getOutputStream();
     736                 :            : 
     737                 :            :         try
     738                 :            :         {
     739                 :          0 :             libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject().get() );
     740                 :          0 :             boost::shared_ptr< istream > aIn = document->getContentStream( );
     741                 :            : 
     742                 :          0 :             uno::Reference< io::XInputStream > xIn = new ucbhelper::StdInputStream( aIn );
     743                 :          0 :             if( !xIn.is( ) )
     744                 :          0 :                 return sal_False;
     745                 :            : 
     746                 :          0 :             if ( xDataSink.is() )
     747                 :          0 :                 xDataSink->setInputStream( xIn );
     748                 :          0 :             else if ( xOut.is() )
     749                 :          0 :                 copyData( xIn, xOut );
     750                 :            :         }
     751                 :          0 :         catch ( const libcmis::Exception& e )
     752                 :            :         {
     753                 :            :             SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
     754                 :            :             ucbhelper::cancelCommandExecution(
     755                 :            :                                 ucb::IOErrorCode_GENERAL,
     756                 :            :                                 uno::Sequence< uno::Any >( 0 ),
     757                 :            :                                 xEnv,
     758                 :          0 :                                 rtl::OUString::createFromAscii( e.what() ) );
     759                 :            :         }
     760                 :            : 
     761                 :          0 :         return sal_True;
     762                 :            :     }
     763                 :            : 
     764                 :          0 :     uno::Sequence< beans::Property > Content::getProperties(
     765                 :            :             const uno::Reference< ucb::XCommandEnvironment > & xEnv )
     766                 :            :     {
     767                 :          0 :         resetAuthProvider( xEnv );
     768                 :            : 
     769                 :            :         static const beans::Property aGenericProperties[] =
     770                 :            :         {
     771                 :            :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
     772                 :          0 :                 -1, getCppuBooleanType(),
     773                 :            :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
     774                 :            :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
     775                 :          0 :                 -1, getCppuBooleanType(),
     776                 :            :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
     777                 :            :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
     778                 :          0 :                 -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
     779                 :            :                 beans::PropertyAttribute::BOUND ),
     780                 :            :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TitleOnServer" ) ),
     781                 :          0 :                 -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
     782                 :            :                 beans::PropertyAttribute::BOUND ),
     783                 :            :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
     784                 :          0 :                 -1, getCppuBooleanType(),
     785                 :            :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
     786                 :            :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
     787                 :          0 :                 -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
     788                 :            :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
     789                 :            :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
     790                 :          0 :                 -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
     791                 :            :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
     792                 :            :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
     793                 :          0 :                 -1, getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
     794                 :            :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
     795                 :            :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CreatableContentsInfo" ) ),
     796                 :          0 :                 -1, getCppuType( static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
     797                 :            :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
     798                 :            :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
     799                 :          0 :                 -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
     800                 :            :                 beans::PropertyAttribute::BOUND ),
     801                 :          0 :         };
     802                 :            : 
     803                 :          0 :         const int nProps = SAL_N_ELEMENTS(aGenericProperties);
     804                 :          0 :         return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
     805                 :            :     }
     806                 :            : 
     807                 :          0 :     uno::Sequence< ucb::CommandInfo > Content::getCommands(
     808                 :            :             const uno::Reference< ucb::XCommandEnvironment > & xEnv )
     809                 :            :     {
     810                 :          0 :         resetAuthProvider( xEnv );
     811                 :            : 
     812                 :            :         static ucb::CommandInfo aCommandInfoTable[] =
     813                 :            :         {
     814                 :            :             // Required commands
     815                 :            :             ucb::CommandInfo
     816                 :            :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
     817                 :          0 :               -1, getCppuVoidType() ),
     818                 :            :             ucb::CommandInfo
     819                 :            :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
     820                 :          0 :               -1, getCppuVoidType() ),
     821                 :            :             ucb::CommandInfo
     822                 :            :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
     823                 :          0 :               -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
     824                 :            :             ucb::CommandInfo
     825                 :            :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
     826                 :          0 :               -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
     827                 :            : 
     828                 :            :             // Optional standard commands
     829                 :            :             ucb::CommandInfo
     830                 :            :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
     831                 :          0 :               -1, getCppuBooleanType() ),
     832                 :            :             ucb::CommandInfo
     833                 :            :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
     834                 :          0 :               -1, getCppuType( static_cast<ucb::InsertCommandArgument * >( 0 ) ) ),
     835                 :            :             ucb::CommandInfo
     836                 :            :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
     837                 :          0 :               -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
     838                 :            : 
     839                 :            :             // Folder Only, omitted if not a folder
     840                 :            :             ucb::CommandInfo
     841                 :            :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
     842                 :          0 :               -1, getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) ),
     843                 :            :             ucb::CommandInfo
     844                 :            :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
     845                 :          0 :               -1, getCppuType( static_cast<ucb::ContentInfo * >( 0 ) ) )
     846                 :          0 :         };
     847                 :            : 
     848                 :          0 :         const int nProps = SAL_N_ELEMENTS(aCommandInfoTable);
     849                 :          0 :         return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, isFolder(xEnv) ? nProps : nProps - 2);
     850                 :            :     }
     851                 :            : 
     852                 :          0 :     ::rtl::OUString Content::getParentURL( )
     853                 :            :     {
     854                 :          0 :         rtl::OUString sRet;
     855                 :            : 
     856                 :            :         SAL_INFO( "cmisucp", "Content::getParentURL()" );
     857                 :            : 
     858                 :          0 :         string parentPath;
     859                 :            :         try
     860                 :            :         {
     861                 :          0 :             libcmis::ObjectPtr pObj = getObject( );
     862                 :          0 :             libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject( ).get( ) );
     863                 :          0 :             if ( NULL != document )
     864                 :            :             {
     865                 :          0 :                 vector< boost::shared_ptr< libcmis::Folder > > parents = document->getParents( );
     866                 :          0 :                 if ( !parents.empty( ) )
     867                 :          0 :                     parentPath = parents.front( )->getPath( );
     868                 :            :             }
     869                 :            :             else
     870                 :            :             {
     871                 :          0 :                 libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( getObject( ).get( ) );
     872                 :          0 :                 if ( NULL != folder )
     873                 :          0 :                     parentPath = folder->getFolderParent( )->getPath( );
     874                 :          0 :             }
     875                 :            :         }
     876                 :          0 :         catch ( const libcmis::Exception & )
     877                 :            :         {
     878                 :            :             // We may have an exception if we don't have the rights to
     879                 :            :             // get the parents
     880                 :            :         }
     881                 :            : 
     882                 :          0 :         if ( !parentPath.empty() )
     883                 :            :         {
     884                 :          0 :             URL aUrl( m_sURL );
     885                 :          0 :             aUrl.setObjectPath( STD_TO_OUSTR( parentPath ) );
     886                 :          0 :             sRet = aUrl.asString( );
     887                 :            :         }
     888                 :            :         else
     889                 :            :         {
     890                 :          0 :             INetURLObject aUrl( m_sURL );
     891                 :          0 :             if ( aUrl.getSegmentCount( ) > 0 )
     892                 :            :             {
     893                 :          0 :                 URL aCmisUrl( m_sURL );
     894                 :          0 :                 aUrl.removeSegment( );
     895                 :          0 :                 aCmisUrl.setObjectPath( aUrl.GetURLPath( INetURLObject::NO_DECODE ) );
     896                 :          0 :                 sRet = aCmisUrl.asString( );
     897                 :          0 :             }
     898                 :            :         }
     899                 :            : 
     900                 :          0 :         return sRet;
     901                 :            :     }
     902                 :            : 
     903                 :          0 :     XTYPEPROVIDER_COMMON_IMPL( Content );
     904                 :            : 
     905                 :          0 :     void SAL_CALL Content::acquire() throw()
     906                 :            :     {
     907                 :          0 :         ContentImplHelper::acquire();
     908                 :          0 :     }
     909                 :            : 
     910                 :          0 :     void SAL_CALL Content::release() throw()
     911                 :            :     {
     912                 :          0 :         ContentImplHelper::release();
     913                 :          0 :     }
     914                 :            : 
     915                 :          0 :     uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException )
     916                 :            :     {
     917                 :          0 :         uno::Any aRet = cppu::queryInterface( rType, static_cast< ucb::XContentCreator * >( this ) );
     918                 :          0 :         return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface(rType);
     919                 :            :     }
     920                 :            : 
     921                 :          0 :     rtl::OUString SAL_CALL Content::getImplementationName() throw( uno::RuntimeException )
     922                 :            :     {
     923                 :          0 :        return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.CmisContent"));
     924                 :            :     }
     925                 :            : 
     926                 :          0 :     uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
     927                 :            :            throw( uno::RuntimeException )
     928                 :            :     {
     929                 :          0 :            uno::Sequence< rtl::OUString > aSNS( 1 );
     930                 :          0 :            aSNS.getArray()[ 0 ] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.CmisContent"));
     931                 :          0 :            return aSNS;
     932                 :            :     }
     933                 :            : 
     934                 :          0 :     rtl::OUString SAL_CALL Content::getContentType() throw( uno::RuntimeException )
     935                 :            :     {
     936                 :          0 :         return isFolder(uno::Reference< ucb::XCommandEnvironment >())
     937                 :            :             ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CMIS_FOLDER_TYPE ))
     938                 :          0 :             : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CMIS_FILE_TYPE ));
     939                 :            :     }
     940                 :            : 
     941                 :          0 :     uno::Any SAL_CALL Content::execute(
     942                 :            :         const ucb::Command& aCommand,
     943                 :            :         sal_Int32 /*CommandId*/,
     944                 :            :         const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     945                 :            :             throw( uno::Exception, ucb::CommandAbortedException, uno::RuntimeException )
     946                 :            :     {
     947                 :            :         SAL_INFO( "cmisucp", "Content::execute( ) - " << aCommand.Name );
     948                 :          0 :         resetAuthProvider( xEnv );
     949                 :            : 
     950                 :          0 :         uno::Any aRet;
     951                 :            : 
     952                 :          0 :         if ( aCommand.Name == "getPropertyValues" )
     953                 :            :         {
     954                 :          0 :             uno::Sequence< beans::Property > Properties;
     955                 :          0 :             if ( !( aCommand.Argument >>= Properties ) )
     956                 :          0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     957                 :          0 :             aRet <<= getPropertyValues( Properties, xEnv );
     958                 :            :         }
     959                 :          0 :         else if ( aCommand.Name == "getPropertySetInfo" )
     960                 :          0 :             aRet <<= getPropertySetInfo( xEnv, sal_False );
     961                 :          0 :         else if ( aCommand.Name == "getCommandInfo" )
     962                 :          0 :             aRet <<= getCommandInfo( xEnv, sal_False );
     963                 :          0 :         else if ( aCommand.Name == "open" )
     964                 :            :         {
     965                 :          0 :             ucb::OpenCommandArgument2 aOpenCommand;
     966                 :          0 :             if ( !( aCommand.Argument >>= aOpenCommand ) )
     967                 :          0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     968                 :          0 :             aRet = open( aOpenCommand, xEnv );
     969                 :            :         }
     970                 :          0 :         else if ( aCommand.Name == "transfer" )
     971                 :            :         {
     972                 :          0 :             ucb::TransferInfo transferArgs;
     973                 :          0 :             if ( !( aCommand.Argument >>= transferArgs ) )
     974                 :          0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     975                 :          0 :             transfer( transferArgs, xEnv );
     976                 :            :         }
     977                 :          0 :         else if ( aCommand.Name == "setPropertyValues" )
     978                 :            :         {
     979                 :          0 :             uno::Sequence< beans::PropertyValue > aProperties;
     980                 :          0 :             if ( !( aCommand.Argument >>= aProperties ) || !aProperties.getLength() )
     981                 :          0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     982                 :          0 :             aRet <<= setPropertyValues( aProperties, xEnv );
     983                 :            :         }
     984                 :          0 :         else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) )
     985                 :          0 :                  && isFolder( xEnv ) )
     986                 :            :         {
     987                 :          0 :             ucb::ContentInfo arg;
     988                 :          0 :             if ( !( aCommand.Argument >>= arg ) )
     989                 :          0 :                     ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     990                 :          0 :             aRet <<= createNewContent( arg );
     991                 :            :         }
     992                 :          0 :         else if ( aCommand.Name == "insert" )
     993                 :            :         {
     994                 :          0 :             ucb::InsertCommandArgument arg;
     995                 :          0 :             if ( !( aCommand.Argument >>= arg ) )
     996                 :          0 :                     ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
     997                 :          0 :             insert( arg.Data, arg.ReplaceExisting, xEnv );
     998                 :            :         }
     999                 :          0 :         else if ( aCommand.Name == "delete" )
    1000                 :            :         {
    1001                 :            :             try
    1002                 :            :             {
    1003                 :          0 :                 if ( !isFolder( xEnv ) )
    1004                 :            :                 {
    1005                 :          0 :                     getObject( )->remove( );
    1006                 :            :                 }
    1007                 :            :                 else
    1008                 :            :                 {
    1009                 :          0 :                     libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( getObject( ).get() );
    1010                 :          0 :                     folder->removeTree( );
    1011                 :            :                 }
    1012                 :            :             }
    1013                 :          0 :             catch ( const libcmis::Exception& e )
    1014                 :            :             {
    1015                 :            :                 SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
    1016                 :            :                 ucbhelper::cancelCommandExecution(
    1017                 :            :                                     ucb::IOErrorCode_GENERAL,
    1018                 :            :                                     uno::Sequence< uno::Any >( 0 ),
    1019                 :            :                                     xEnv,
    1020                 :          0 :                                     rtl::OUString::createFromAscii( e.what() ) );
    1021                 :            :             }
    1022                 :            :         }
    1023                 :            :         else
    1024                 :            :         {
    1025                 :            :             SAL_INFO( "cmisucp", "Unknown command to execute" );
    1026                 :            : 
    1027                 :            :             ucbhelper::cancelCommandExecution
    1028                 :            :                 ( uno::makeAny( ucb::UnsupportedCommandException
    1029                 :            :                   ( rtl::OUString(),
    1030                 :            :                     static_cast< cppu::OWeakObject * >( this ) ) ),
    1031                 :          0 :                   xEnv );
    1032                 :            :         }
    1033                 :            : 
    1034                 :          0 :         return aRet;
    1035                 :            :     }
    1036                 :            : 
    1037                 :          0 :     void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) throw( uno::RuntimeException )
    1038                 :            :     {
    1039                 :            :         SAL_INFO( "cmisucp", "TODO - Content::abort()" );
    1040                 :            :         // TODO Implement me
    1041                 :          0 :     }
    1042                 :            : 
    1043                 :          0 :     uno::Sequence< ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo()
    1044                 :            :             throw( uno::RuntimeException )
    1045                 :            :     {
    1046                 :          0 :         return queryCreatableContentsInfo( uno::Reference< ucb::XCommandEnvironment >() );
    1047                 :            :     }
    1048                 :            : 
    1049                 :          0 :     uno::Reference< ucb::XContent > SAL_CALL Content::createNewContent(
    1050                 :            :             const ucb::ContentInfo& Info ) throw( uno::RuntimeException )
    1051                 :            :     {
    1052                 :            :         bool create_document;
    1053                 :            : 
    1054                 :          0 :         if ( Info.Type == CMIS_FILE_TYPE )
    1055                 :          0 :             create_document = true;
    1056                 :          0 :         else if ( Info.Type == CMIS_FOLDER_TYPE )
    1057                 :          0 :             create_document = false;
    1058                 :            :         else
    1059                 :            :         {
    1060                 :            :             SAL_INFO( "cmisucp", "Unknown type of content to create" );
    1061                 :          0 :             return uno::Reference< ucb::XContent >();
    1062                 :            :         }
    1063                 :            : 
    1064                 :          0 :         rtl::OUString sParentURL = m_xIdentifier->getContentIdentifier();
    1065                 :          0 :         URL aParentURL( sParentURL );
    1066                 :            : 
    1067                 :            :         // Set the parent URL for the transient objects
    1068                 :          0 :         uno::Reference< ucb::XContentIdentifier > xId(new ::ucbhelper::ContentIdentifier(m_xSMgr, sParentURL));
    1069                 :            : 
    1070                 :            :         try
    1071                 :            :         {
    1072                 :          0 :             return new ::cmis::Content( m_xSMgr, m_pProvider, xId, !create_document );
    1073                 :            :         }
    1074                 :          0 :         catch ( ucb::ContentCreationException & )
    1075                 :            :         {
    1076                 :          0 :             return uno::Reference< ucb::XContent >();
    1077                 :          0 :         }
    1078                 :            :     }
    1079                 :            : 
    1080                 :          0 :     uno::Sequence< uno::Type > SAL_CALL Content::getTypes() throw( uno::RuntimeException )
    1081                 :            :     {
    1082                 :          0 :         if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
    1083                 :            :         {
    1084                 :            :             static cppu::OTypeCollection aFolderCollection
    1085                 :          0 :                 (CPPU_TYPE_REF( lang::XTypeProvider ),
    1086                 :          0 :                  CPPU_TYPE_REF( lang::XServiceInfo ),
    1087                 :          0 :                  CPPU_TYPE_REF( lang::XComponent ),
    1088                 :          0 :                  CPPU_TYPE_REF( ucb::XContent ),
    1089                 :          0 :                  CPPU_TYPE_REF( ucb::XCommandProcessor ),
    1090                 :          0 :                  CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
    1091                 :          0 :                  CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
    1092                 :          0 :                  CPPU_TYPE_REF( beans::XPropertyContainer ),
    1093                 :          0 :                  CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
    1094                 :          0 :                  CPPU_TYPE_REF( container::XChild ),
    1095                 :          0 :                  CPPU_TYPE_REF( ucb::XContentCreator ) );
    1096                 :          0 :             return aFolderCollection.getTypes();
    1097                 :            :         }
    1098                 :            :         else
    1099                 :            :         {
    1100                 :            :             static cppu::OTypeCollection aFileCollection
    1101                 :          0 :                 (CPPU_TYPE_REF( lang::XTypeProvider ),
    1102                 :          0 :                  CPPU_TYPE_REF( lang::XServiceInfo ),
    1103                 :          0 :                  CPPU_TYPE_REF( lang::XComponent ),
    1104                 :          0 :                  CPPU_TYPE_REF( ucb::XContent ),
    1105                 :          0 :                  CPPU_TYPE_REF( ucb::XCommandProcessor ),
    1106                 :          0 :                  CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
    1107                 :          0 :                  CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
    1108                 :          0 :                  CPPU_TYPE_REF( beans::XPropertyContainer ),
    1109                 :          0 :                  CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
    1110                 :          0 :                  CPPU_TYPE_REF( container::XChild ) );
    1111                 :            : 
    1112                 :          0 :             return aFileCollection.getTypes();
    1113                 :            :         }
    1114                 :            :     }
    1115                 :            : 
    1116                 :            : 
    1117                 :          0 :     uno::Sequence< ucb::ContentInfo > Content::queryCreatableContentsInfo(
    1118                 :            :         const uno::Reference< ucb::XCommandEnvironment >& xEnv)
    1119                 :            :             throw( uno::RuntimeException )
    1120                 :            :     {
    1121                 :          0 :         resetAuthProvider( xEnv );
    1122                 :          0 :         if ( isFolder( xEnv ) )
    1123                 :            :         {
    1124                 :          0 :             uno::Sequence< ucb::ContentInfo > seq(2);
    1125                 :            : 
    1126                 :            :             // Minimum set of props we really need
    1127                 :          0 :             uno::Sequence< beans::Property > props( 1 );
    1128                 :          0 :             props[0] = beans::Property(
    1129                 :            :                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Title")),
    1130                 :            :                 -1,
    1131                 :          0 :                 getCppuType( static_cast< rtl::OUString* >( 0 ) ),
    1132                 :          0 :                 beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
    1133                 :            : 
    1134                 :            :             // file
    1135                 :          0 :             seq[0].Type       = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CMIS_FILE_TYPE ));
    1136                 :          0 :             seq[0].Attributes = ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
    1137                 :          0 :                                   ucb::ContentInfoAttribute::KIND_DOCUMENT );
    1138                 :          0 :             seq[0].Properties = props;
    1139                 :            : 
    1140                 :            :             // folder
    1141                 :          0 :             seq[1].Type       = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CMIS_FOLDER_TYPE ));
    1142                 :          0 :             seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
    1143                 :          0 :             seq[1].Properties = props;
    1144                 :            : 
    1145                 :          0 :             return seq;
    1146                 :            :         }
    1147                 :            :         else
    1148                 :            :         {
    1149                 :          0 :             return uno::Sequence< ucb::ContentInfo >();
    1150                 :            :         }
    1151                 :            :     }
    1152                 :            : 
    1153                 :          0 :     list< uno::Reference< ucb::XContent > > Content::getChildren( )
    1154                 :            :     {
    1155                 :          0 :         list< uno::Reference< ucb::XContent > > results;
    1156                 :            :         SAL_INFO( "cmisucp", "Content::getChildren() " << m_sURL );
    1157                 :            : 
    1158                 :          0 :         libcmis::Folder* pFolder = dynamic_cast< libcmis::Folder* >( getObject( ).get( ) );
    1159                 :          0 :         if ( NULL != pFolder )
    1160                 :            :         {
    1161                 :            :             // Get the children from pObject
    1162                 :            :             try
    1163                 :            :             {
    1164                 :          0 :                 vector< libcmis::ObjectPtr > children = pFolder->getChildren( );
    1165                 :            : 
    1166                 :            :                 // Loop over the results
    1167                 :          0 :                 for ( vector< libcmis::ObjectPtr >::iterator it = children.begin();
    1168                 :          0 :                         it != children.end(); ++it )
    1169                 :            :                 {
    1170                 :            :                     // TODO Cache the objects
    1171                 :            : 
    1172                 :          0 :                     URL aUrl( m_sURL );
    1173                 :          0 :                     rtl::OUString sPath( m_sObjectPath );
    1174                 :          0 :                     if ( sPath[sPath.getLength( ) - 1] != '/' )
    1175                 :          0 :                         sPath += "/";
    1176                 :          0 :                     sPath += STD_TO_OUSTR( ( *it )->getName( ) );
    1177                 :          0 :                     aUrl.setObjectPath( sPath );
    1178                 :          0 :                     uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aUrl.asString( ) );
    1179                 :          0 :                     uno::Reference< ucb::XContent > xContent = new Content( m_xSMgr, m_pProvider, xId, *it );
    1180                 :            : 
    1181                 :          0 :                     results.push_back( xContent );
    1182                 :          0 :                 }
    1183                 :            :             }
    1184                 :          0 :             catch ( const libcmis::Exception& e )
    1185                 :            :             {
    1186                 :            :                 SAL_INFO( "cmisucp", "Exception thrown: " << e.what() );
    1187                 :            :             }
    1188                 :            :         }
    1189                 :            : 
    1190                 :          0 :         return results;
    1191                 :            :     }
    1192                 :            : 
    1193                 :          0 :     void Content::setCmisProperty( std::string sName, std::string sValue )
    1194                 :            :     {
    1195                 :          0 :         if ( m_pObjectType.get( ) )
    1196                 :            :         {
    1197                 :          0 :             map< string, libcmis::PropertyPtr >::iterator propIt = m_pObjectProps.find( sName );
    1198                 :          0 :             vector< string > values;
    1199                 :          0 :             values.push_back( sValue );
    1200                 :            : 
    1201                 :          0 :             if ( propIt == m_pObjectProps.end( ) && m_pObjectType.get( ) )
    1202                 :            :             {
    1203                 :          0 :                 map< string, libcmis::PropertyTypePtr > propsTypes = m_pObjectType->getPropertiesTypes( );
    1204                 :          0 :                 map< string, libcmis::PropertyTypePtr >::iterator typeIt = propsTypes.find( sName );
    1205                 :            : 
    1206                 :          0 :                 if ( typeIt != propsTypes.end( ) )
    1207                 :            :                 {
    1208                 :          0 :                     libcmis::PropertyTypePtr propType = typeIt->second;
    1209                 :          0 :                     libcmis::PropertyPtr property( new libcmis::Property( propType, values ) );
    1210                 :          0 :                     m_pObjectProps.insert( pair< string, libcmis::PropertyPtr >( sName, property ) );
    1211                 :          0 :                 }
    1212                 :            :             }
    1213                 :          0 :             else if ( propIt != m_pObjectProps.end( ) )
    1214                 :            :             {
    1215                 :          0 :                 propIt->second->setValues( values );
    1216                 :          0 :             }
    1217                 :            :         }
    1218                 :          0 :     }
    1219                 :          0 : }
    1220                 :            : 
    1221                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10