LCOV - code coverage report
Current view: top level - libreoffice/ucb/source/ucp/cmis - cmis_content.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 745 0.0 %
Date: 2012-12-27 Functions: 0 44 0.0 %
Legend: Lines: hit not hit

          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/PropertyValues.hpp>
      34             : #include <com/sun/star/beans/XPropertySetInfo.hpp>
      35             : #include <com/sun/star/io/XActiveDataSink.hpp>
      36             : #include <com/sun/star/io/XActiveDataStreamer.hpp>
      37             : #include <com/sun/star/lang/IllegalAccessException.hpp>
      38             : #include <com/sun/star/task/InteractionClassification.hpp>
      39             : #include <com/sun/star/ucb/ContentInfo.hpp>
      40             : #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
      41             : #include <com/sun/star/ucb/InsertCommandArgument2.hpp>
      42             : #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
      43             : #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
      44             : #include <com/sun/star/ucb/MissingInputStreamException.hpp>
      45             : #include <com/sun/star/ucb/NameClash.hpp>
      46             : #include <com/sun/star/ucb/NameClashException.hpp>
      47             : #include <com/sun/star/ucb/OpenMode.hpp>
      48             : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
      49             : #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
      50             : #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
      51             : #include <com/sun/star/ucb/XCommandInfo.hpp>
      52             : #include <com/sun/star/ucb/XDynamicResultSet.hpp>
      53             : 
      54             : #include <libcmis/document.hxx>
      55             : 
      56             : #include <comphelper/processfactory.hxx>
      57             : #include <ucbhelper/cancelcommandexecution.hxx>
      58             : #include <ucbhelper/content.hxx>
      59             : #include <ucbhelper/contentidentifier.hxx>
      60             : #include <ucbhelper/std_inputstream.hxx>
      61             : #include <ucbhelper/std_outputstream.hxx>
      62             : #include <ucbhelper/propertyvalueset.hxx>
      63             : 
      64             : #include "auth_provider.hxx"
      65             : #include "cmis_content.hxx"
      66             : #include "cmis_provider.hxx"
      67             : #include "cmis_resultset.hxx"
      68             : 
      69             : #define OUSTR_TO_STDSTR(s) string( rtl::OUStringToOString( s, RTL_TEXTENCODING_UTF8 ).getStr() )
      70             : #define STD_TO_OUSTR( str ) rtl::OUString( str.c_str(), str.length( ), RTL_TEXTENCODING_UTF8 )
      71             : 
      72             : using namespace com::sun::star;
      73             : using namespace std;
      74             : 
      75             : namespace
      76             : {
      77           0 :     util::DateTime lcl_boostToUnoTime( boost::posix_time::ptime boostTime )
      78             :     {
      79           0 :         util::DateTime unoTime;
      80           0 :         unoTime.Year = boostTime.date().year();
      81           0 :         unoTime.Month = boostTime.date().month();
      82           0 :         unoTime.Day = boostTime.date().day();
      83           0 :         unoTime.Hours = boostTime.time_of_day().hours();
      84           0 :         unoTime.Minutes = boostTime.time_of_day().minutes();
      85           0 :         unoTime.Seconds = boostTime.time_of_day().seconds();
      86             : 
      87           0 :         long total_milli = boostTime.time_of_day().total_milliseconds( );
      88           0 :         long milli = total_milli - boostTime.time_of_day().total_seconds( );
      89           0 :         long hundredthSeconds = milli / 10;
      90             : 
      91           0 :         unoTime.HundredthSeconds = hundredthSeconds;
      92             : 
      93           0 :         return unoTime;
      94             :     }
      95             : 
      96           0 :     uno::Any lcl_cmisPropertyToUno( libcmis::PropertyPtr pProperty )
      97             :     {
      98           0 :         uno::Any aValue;
      99           0 :         bool bMultiValued = pProperty->getPropertyType( )->isMultiValued( );
     100           0 :         switch ( pProperty->getPropertyType( )->getType( ) )
     101             :         {
     102             :             default:
     103             :             case libcmis::PropertyType::String:
     104             :                 {
     105           0 :                     vector< string > aCmisStrings = pProperty->getStrings( );
     106           0 :                     if ( bMultiValued )
     107             :                     {
     108           0 :                         uno::Sequence< rtl::OUString > aStrings( aCmisStrings.size( ) );
     109           0 :                         rtl::OUString* aStringsArr = aStrings.getArray( );
     110           0 :                         sal_Int32 i = 0;
     111           0 :                         for ( vector< string >::iterator it = aCmisStrings.begin( );
     112           0 :                                 it != aCmisStrings.end( ); ++it, ++i )
     113             :                         {
     114           0 :                             string str = *it;
     115           0 :                             aStringsArr[i] = STD_TO_OUSTR( str );
     116           0 :                         }
     117           0 :                         aValue <<= aStrings;
     118             :                     }
     119           0 :                     else if ( !aCmisStrings.empty( ) )
     120             :                     {
     121           0 :                         aValue <<= STD_TO_OUSTR( aCmisStrings.front( ) );
     122           0 :                     }
     123             :                 }
     124           0 :                 break;
     125             :             case libcmis::PropertyType::Integer:
     126             :                 {
     127           0 :                     vector< long > aCmisLongs = pProperty->getLongs( );
     128           0 :                     if ( bMultiValued )
     129             :                     {
     130           0 :                         uno::Sequence< sal_Int64 > aLongs( aCmisLongs.size( ) );
     131           0 :                         sal_Int64* aLongsArr = aLongs.getArray( );
     132           0 :                         sal_Int32 i = 0;
     133           0 :                         for ( vector< long >::iterator it = aCmisLongs.begin( );
     134           0 :                                 it != aCmisLongs.end( ); ++it, ++i )
     135             :                         {
     136           0 :                             aLongsArr[i] = *it;
     137             :                         }
     138           0 :                         aValue <<= aLongs;
     139             :                     }
     140           0 :                     else if ( !aCmisLongs.empty( ) )
     141             :                     {
     142           0 :                         aValue <<= aCmisLongs.front( );
     143           0 :                     }
     144             :                 }
     145           0 :                 break;
     146             :             case libcmis::PropertyType::Decimal:
     147             :                 {
     148           0 :                     vector< double > aCmisDoubles = pProperty->getDoubles( );
     149           0 :                     if ( bMultiValued )
     150             :                     {
     151           0 :                         uno::Sequence< double > aDoubles( aCmisDoubles.size( ) );
     152           0 :                         double* aDoublesArr = aDoubles.getArray( );
     153           0 :                         sal_Int32 i = 0;
     154           0 :                         for ( vector< double >::iterator it = aCmisDoubles.begin( );
     155           0 :                                 it != aCmisDoubles.end( ); ++it, ++i )
     156             :                         {
     157           0 :                             aDoublesArr[i] = *it;
     158             :                         }
     159           0 :                         aValue <<= aDoubles;
     160             :                     }
     161           0 :                     else if ( !aCmisDoubles.empty( ) )
     162             :                     {
     163           0 :                         aValue <<= aCmisDoubles.front( );
     164           0 :                     }
     165             :                 }
     166           0 :                 break;
     167             :             case libcmis::PropertyType::Bool:
     168             :                 {
     169           0 :                     vector< bool > aCmisBools = pProperty->getBools( );
     170           0 :                     if ( bMultiValued )
     171             :                     {
     172           0 :                         uno::Sequence< sal_Bool > aBools( aCmisBools.size( ) );
     173           0 :                         sal_Bool* aBoolsArr = aBools.getArray( );
     174           0 :                         sal_Int32 i = 0;
     175           0 :                         for ( vector< bool >::iterator it = aCmisBools.begin( );
     176           0 :                                 it != aCmisBools.end( ); ++it, ++i )
     177             :                         {
     178           0 :                             aBoolsArr[i] = *it;
     179             :                         }
     180           0 :                         aValue <<= aBools;
     181             :                     }
     182           0 :                     else if ( !aCmisBools.empty( ) )
     183             :                     {
     184           0 :                         aValue <<= sal_Bool( aCmisBools.front( ) );
     185           0 :                     }
     186             :                 }
     187           0 :                 break;
     188             :             case libcmis::PropertyType::DateTime:
     189             :                 {
     190           0 :                     vector< boost::posix_time::ptime > aCmisTimes = pProperty->getDateTimes( );
     191           0 :                     if ( bMultiValued )
     192             :                     {
     193           0 :                         uno::Sequence< util::DateTime > aTimes( aCmisTimes.size( ) );
     194           0 :                         util::DateTime* aTimesArr = aTimes.getArray( );
     195           0 :                         sal_Int32 i = 0;
     196           0 :                         for ( vector< boost::posix_time::ptime >::iterator it = aCmisTimes.begin( );
     197           0 :                                 it != aCmisTimes.end( ); ++it, ++i )
     198             :                         {
     199           0 :                             aTimesArr[i] = lcl_boostToUnoTime( *it );
     200             :                         }
     201           0 :                         aValue <<= aTimes;
     202             :                     }
     203           0 :                     else if ( !aCmisTimes.empty( ) )
     204             :                     {
     205           0 :                         aValue <<= lcl_boostToUnoTime( aCmisTimes.front( ) );
     206           0 :                     }
     207             :                 }
     208           0 :                 break;
     209             :         }
     210           0 :         return aValue;
     211             :     }
     212             : }
     213             : 
     214             : namespace cmis
     215             : {
     216           0 :     Content::Content( const uno::Reference< uno::XComponentContext >& rxContext,
     217             :         ContentProvider *pProvider, const uno::Reference< ucb::XContentIdentifier >& Identifier,
     218             :         libcmis::ObjectPtr pObject )
     219             :             throw ( ucb::ContentCreationException )
     220             :         : ContentImplHelper( rxContext, pProvider, Identifier ),
     221             :         m_pProvider( pProvider ),
     222             :         m_pSession( NULL ),
     223             :         m_pObject( pObject ),
     224           0 :         m_sURL( Identifier->getContentIdentifier( ) ),
     225           0 :         m_aURL( Identifier->getContentIdentifier( ) ),
     226             :         m_bTransient( false ),
     227           0 :         m_bIsFolder( false )
     228             :     {
     229             :         SAL_INFO( "cmisucp", "Content::Content() " << m_sURL );
     230             : 
     231           0 :         m_sObjectPath = m_aURL.getObjectPath( );
     232           0 :         m_sObjectId = m_aURL.getObjectId( );
     233           0 :     }
     234             : 
     235           0 :     Content::Content( const uno::Reference< uno::XComponentContext >& rxContext, ContentProvider *pProvider,
     236             :         const uno::Reference< ucb::XContentIdentifier >& Identifier,
     237             :         sal_Bool bIsFolder )
     238             :             throw ( ucb::ContentCreationException )
     239             :         : ContentImplHelper( rxContext, pProvider, Identifier ),
     240             :         m_pProvider( pProvider ),
     241             :         m_pSession( NULL ),
     242           0 :         m_sURL( Identifier->getContentIdentifier( ) ),
     243           0 :         m_aURL( Identifier->getContentIdentifier( ) ),
     244             :         m_bTransient( true ),
     245           0 :         m_bIsFolder( bIsFolder )
     246             :     {
     247             :         SAL_INFO( "cmisucp", "Content::Content() " << m_sURL );
     248             : 
     249           0 :         m_sObjectPath = m_aURL.getObjectPath( );
     250           0 :         m_sObjectId = m_aURL.getObjectId( );
     251           0 :     }
     252             : 
     253           0 :     Content::~Content()
     254             :     {
     255           0 :     }
     256             : 
     257           0 :     libcmis::Session* Content::getSession( const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     258             :     {
     259             :         // Look for a cached session, key is binding url + repo id
     260           0 :         rtl::OUString sSessionId = m_aURL.getBindingUrl( ) + m_aURL.getRepositoryId( );
     261           0 :         if ( NULL == m_pSession )
     262           0 :             m_pSession = m_pProvider->getSession( sSessionId );
     263             : 
     264           0 :         if ( NULL == m_pSession )
     265             :         {
     266             :             // Get the auth credentials
     267           0 :             AuthProvider authProvider( xEnv, m_xIdentifier->getContentIdentifier( ), m_aURL.getBindingUrl( ) );
     268             : 
     269           0 :             string rUsername = OUSTR_TO_STDSTR( m_aURL.getUsername( ) );
     270           0 :             string rPassword = OUSTR_TO_STDSTR( m_aURL.getPassword( ) );
     271           0 :             if ( authProvider.authenticationQuery( rUsername, rPassword ) )
     272             :             {
     273             :                 // Initiate a CMIS session and register it as we found nothing
     274             :                 m_pSession = libcmis::SessionFactory::createSession(
     275           0 :                         OUSTR_TO_STDSTR( m_aURL.getBindingUrl( ) ),
     276           0 :                         rUsername, rPassword, OUSTR_TO_STDSTR( m_aURL.getRepositoryId( ) ) );
     277           0 :                 if ( m_pSession == NULL )
     278             :                     ucbhelper::cancelCommandExecution(
     279             :                                         ucb::IOErrorCode_INVALID_DEVICE,
     280             :                                         uno::Sequence< uno::Any >( 0 ),
     281             :                                         xEnv,
     282           0 :                                         rtl::OUString( ) );
     283           0 :                 m_pProvider->registerSession( sSessionId, m_pSession );
     284             :             }
     285             :             else
     286             :             {
     287             :                 // Silently fail as the user cancelled the authentication
     288           0 :                 throw uno::RuntimeException( );
     289           0 :             }
     290             :         }
     291           0 :         return m_pSession;
     292             :     }
     293             : 
     294           0 :     libcmis::ObjectTypePtr Content::getObjectType( const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     295             :     {
     296           0 :         if ( NULL == m_pObjectType.get( ) && m_bTransient )
     297             :         {
     298           0 :             string typeId = m_bIsFolder ? "cmis:folder" : "cmis:document";
     299           0 :             m_pObjectType = getSession( xEnv )->getType( typeId );
     300             :         }
     301           0 :         return m_pObjectType;
     302             :     }
     303             : 
     304             : 
     305           0 :     libcmis::ObjectPtr Content::getObject( const uno::Reference< ucb::XCommandEnvironment >& xEnv ) throw ( libcmis::Exception )
     306             :     {
     307           0 :         if ( !m_pObject.get() )
     308             :         {
     309           0 :             if ( !m_sObjectPath.isEmpty( ) )
     310           0 :                 m_pObject = getSession( xEnv )->getObjectByPath( OUSTR_TO_STDSTR( m_sObjectPath ) );
     311           0 :             else if (!m_sObjectId.isEmpty( ) )
     312           0 :                 m_pObject = getSession( xEnv )->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
     313             :             else
     314             :             {
     315           0 :                 m_pObject = getSession( xEnv )->getRootFolder( );
     316           0 :                 m_sObjectPath = "/";
     317           0 :                 m_sObjectId = rtl::OUString( );
     318             :             }
     319             :         }
     320             : 
     321           0 :         return m_pObject;
     322             :     }
     323             : 
     324           0 :     bool Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     325             :     {
     326           0 :         bool bIsFolder = false;
     327             :         try
     328             :         {
     329           0 :             bIsFolder = getObject( xEnv )->getBaseType( ) == "cmis:folder";
     330             :         }
     331           0 :         catch ( const libcmis::Exception& e )
     332             :         {
     333             :             SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
     334             :             ucbhelper::cancelCommandExecution(
     335             :                                 ucb::IOErrorCode_GENERAL,
     336             :                                 uno::Sequence< uno::Any >( 0 ),
     337             :                                 xEnv,
     338           0 :                                 rtl::OUString::createFromAscii( e.what( ) ) );
     339             :         }
     340           0 :         return bIsFolder;
     341             :     }
     342             : 
     343           0 :     uno::Any Content::getBadArgExcept()
     344             :     {
     345             :         return uno::makeAny( lang::IllegalArgumentException(
     346             :             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Wrong argument type!")),
     347           0 :             static_cast< cppu::OWeakObject * >( this ), -1) );
     348             :     }
     349             : 
     350           0 :     uno::Reference< sdbc::XRow > Content::getPropertyValues(
     351             :             const uno::Sequence< beans::Property >& rProperties,
     352             :             const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     353             :     {
     354           0 :         rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( m_xContext );
     355             : 
     356             :         sal_Int32 nProps;
     357             :         const beans::Property* pProps;
     358             : 
     359           0 :         nProps = rProperties.getLength();
     360           0 :         pProps = rProperties.getConstArray();
     361             : 
     362           0 :         for( sal_Int32 n = 0; n < nProps; ++n )
     363             :         {
     364           0 :             const beans::Property& rProp = pProps[ n ];
     365             : 
     366             :             try
     367             :             {
     368           0 :                 if ( rProp.Name == "IsDocument" )
     369             :                 {
     370             :                     try
     371             :                     {
     372           0 :                         xRow->appendBoolean( rProp, getObject( xEnv )->getBaseType( ) == "cmis:document" );
     373             :                     }
     374           0 :                     catch ( const libcmis::Exception& )
     375             :                     {
     376           0 :                         if ( m_pObjectType.get( ) )
     377           0 :                             xRow->appendBoolean( rProp, getObjectType( xEnv )->getBaseType()->getId( ) == "cmis:document" );
     378             :                         else
     379           0 :                             xRow->appendVoid( rProp );
     380             :                     }
     381             :                 }
     382           0 :                 else if ( rProp.Name == "IsFolder" )
     383             :                 {
     384             :                     try
     385             :                     {
     386           0 :                         xRow->appendBoolean( rProp, getObject( xEnv )->getBaseType( ) == "cmis:folder" );
     387             :                     }
     388           0 :                     catch ( const libcmis::Exception& )
     389             :                     {
     390           0 :                         if ( m_pObjectType.get( ) )
     391           0 :                             xRow->appendBoolean( rProp, getObjectType( xEnv )->getBaseType()->getId( ) == "cmis:folder" );
     392             :                         else
     393           0 :                             xRow->appendVoid( rProp );
     394             :                     }
     395             :                 }
     396           0 :                 else if ( rProp.Name == "Title" )
     397             :                 {
     398           0 :                     rtl::OUString sTitle;
     399             :                     try
     400             :                     {
     401           0 :                         sTitle = STD_TO_OUSTR( getObject( xEnv )->getName() );
     402             :                     }
     403           0 :                     catch ( const libcmis::Exception& )
     404             :                     {
     405           0 :                         if ( !m_pObjectProps.empty() )
     406             :                         {
     407           0 :                             map< string, libcmis::PropertyPtr >::iterator it = m_pObjectProps.find( "cmis:name" );
     408           0 :                             if ( it != m_pObjectProps.end( ) )
     409             :                             {
     410           0 :                                 vector< string > values = it->second->getStrings( );
     411           0 :                                 if ( !values.empty() )
     412           0 :                                     sTitle = STD_TO_OUSTR( values.front( ) );
     413             :                             }
     414             :                         }
     415             :                     }
     416             : 
     417             :                     // Nothing worked... get it from the path
     418           0 :                     if ( sTitle.isEmpty( ) )
     419             :                     {
     420           0 :                         rtl::OUString sPath = m_sObjectPath;
     421             : 
     422             :                         // Get rid of the trailing slash problem
     423           0 :                         if ( sPath[ sPath.getLength( ) - 1 ] == '/' )
     424           0 :                             sPath = sPath.copy( 0, sPath.getLength() - 1 );
     425             : 
     426             :                         // Get the last segment
     427           0 :                         sal_Int32 nPos = sPath.lastIndexOf( '/' );
     428           0 :                         if ( nPos >= 0 )
     429           0 :                             sTitle = sPath.copy( nPos + 1 );
     430             :                     }
     431             : 
     432           0 :                     if ( !sTitle.isEmpty( ) )
     433           0 :                         xRow->appendString( rProp, sTitle );
     434             :                     else
     435           0 :                         xRow->appendVoid( rProp );
     436             :                 }
     437           0 :                 else if ( rProp.Name == "TitleOnServer" )
     438             :                 {
     439           0 :                     string path;
     440             :                     try
     441             :                     {
     442           0 :                         vector< string > paths = getObject( xEnv )->getPaths( );
     443           0 :                         if ( !paths.empty( ) )
     444           0 :                             path = paths.front( );
     445             :                         else
     446           0 :                             path = getObject( xEnv )->getName( );
     447             : 
     448           0 :                         xRow->appendString( rProp, STD_TO_OUSTR( path ) );
     449             :                     }
     450           0 :                     catch ( const libcmis::Exception& )
     451             :                     {
     452           0 :                         xRow->appendVoid( rProp );
     453           0 :                     }
     454             :                 }
     455           0 :                 else if ( rProp.Name == "IsReadOnly" )
     456             :                 {
     457           0 :                     boost::shared_ptr< libcmis::AllowableActions > allowableActions = getObject( xEnv )->getAllowableActions( );
     458           0 :                     sal_Bool bReadOnly = sal_False;
     459           0 :                     if ( !allowableActions->isAllowed( libcmis::ObjectAction::SetContentStream ) &&
     460           0 :                          !allowableActions->isAllowed( libcmis::ObjectAction::CheckIn ) )
     461           0 :                         bReadOnly = sal_True;
     462             : 
     463           0 :                     xRow->appendBoolean( rProp, bReadOnly );
     464             :                 }
     465           0 :                 else if ( rProp.Name == "DateCreated" )
     466             :                 {
     467           0 :                     util::DateTime aTime = lcl_boostToUnoTime( getObject( xEnv )->getCreationDate( ) );
     468           0 :                     xRow->appendTimestamp( rProp, aTime );
     469             :                 }
     470           0 :                 else if ( rProp.Name == "DateModified" )
     471             :                 {
     472           0 :                     util::DateTime aTime = lcl_boostToUnoTime( getObject( xEnv )->getLastModificationDate( ) );
     473           0 :                     xRow->appendTimestamp( rProp, aTime );
     474             :                 }
     475           0 :                 else if ( rProp.Name == "Size" )
     476             :                 {
     477             :                     try
     478             :                     {
     479           0 :                         libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject( xEnv ).get( ) );
     480           0 :                         if ( NULL != document )
     481           0 :                             xRow->appendLong( rProp, document->getContentLength() );
     482             :                         else
     483           0 :                             xRow->appendVoid( rProp );
     484             :                     }
     485           0 :                     catch ( const libcmis::Exception& )
     486             :                     {
     487           0 :                         xRow->appendVoid( rProp );
     488             :                     }
     489             :                 }
     490           0 :                 else if ( rProp.Name == "CreatableContentsInfo" )
     491             :                 {
     492           0 :                     xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) );
     493             :                 }
     494           0 :                 else if ( rProp.Name == "MediaType" )
     495             :                 {
     496             :                     try
     497             :                     {
     498           0 :                         libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject( xEnv ).get( ) );
     499           0 :                         if ( NULL != document )
     500           0 :                             xRow->appendString( rProp, STD_TO_OUSTR( document->getContentType() ) );
     501             :                         else
     502           0 :                             xRow->appendVoid( rProp );
     503             :                     }
     504           0 :                     catch ( const libcmis::Exception& )
     505             :                     {
     506           0 :                         xRow->appendVoid( rProp );
     507             :                     }
     508             :                 }
     509           0 :                 else if ( rProp.Name == "CmisPropertiesValues" )
     510             :                 {
     511             :                     try
     512             :                     {
     513           0 :                         libcmis::ObjectPtr object = getObject( xEnv );
     514           0 :                         map< string, libcmis::PropertyPtr >& aProperties = object->getProperties( );
     515           0 :                         beans::PropertyValues aCmisProperties( aProperties.size( ) );
     516           0 :                         beans::PropertyValue* pCmisProps = aCmisProperties.getArray( );
     517           0 :                         sal_Int32 i = 0;
     518           0 :                         for ( map< string, libcmis::PropertyPtr >::iterator it = aProperties.begin();
     519           0 :                                 it != aProperties.end( ); ++it, ++i )
     520             :                         {
     521           0 :                             string name = it->first;
     522           0 :                             pCmisProps[i].Name = STD_TO_OUSTR( name );
     523           0 :                             pCmisProps[i].Value = lcl_cmisPropertyToUno( it->second );
     524           0 :                         }
     525           0 :                         xRow->appendObject( rProp.Name, uno::makeAny( aCmisProperties ) );
     526             :                     }
     527           0 :                     catch ( const libcmis::Exception& )
     528             :                     {
     529           0 :                         xRow->appendVoid( rProp );
     530             :                     }
     531             :                 }
     532           0 :                 else if ( rProp.Name == "CmisPropertiesDisplayNames" )
     533             :                 {
     534             :                     try
     535             :                     {
     536           0 :                         libcmis::ObjectPtr object = getObject( xEnv );
     537           0 :                         map< string, libcmis::PropertyPtr >& aProperties = object->getProperties( );
     538           0 :                         beans::PropertyValues aCmisProperties( aProperties.size( ) );
     539           0 :                         beans::PropertyValue* pCmisProps = aCmisProperties.getArray( );
     540           0 :                         sal_Int32 i = 0;
     541           0 :                         for ( map< string, libcmis::PropertyPtr >::iterator it = aProperties.begin();
     542           0 :                                 it != aProperties.end( ); ++it, ++i )
     543             :                         {
     544           0 :                             string name = it->first;
     545           0 :                             string displayName = it->second->getPropertyType()->getDisplayName( );
     546           0 :                             pCmisProps[i].Name = STD_TO_OUSTR( name );
     547           0 :                             pCmisProps[i].Value = uno::makeAny( STD_TO_OUSTR( displayName ) );
     548           0 :                         }
     549           0 :                         xRow->appendObject( rProp.Name, uno::makeAny( aCmisProperties ) );
     550             :                     }
     551           0 :                     catch ( const libcmis::Exception& )
     552             :                     {
     553           0 :                         xRow->appendVoid( rProp );
     554             :                     }
     555             :                 }
     556           0 :                 else if ( rProp.Name == "IsVersionable" )
     557             :                 {
     558             :                     try
     559             :                     {
     560           0 :                         libcmis::ObjectPtr object = getObject( xEnv );
     561           0 :                         sal_Bool bIsVersionable = object->getTypeDescription( )->isVersionable( );
     562           0 :                         xRow->appendBoolean( rProp, bIsVersionable );
     563             :                     }
     564           0 :                     catch ( const libcmis::Exception& )
     565             :                     {
     566           0 :                         xRow->appendVoid( rProp );
     567             :                     }
     568             :                 }
     569           0 :                 else if ( rProp.Name == "CanCheckOut" )
     570             :                 {
     571             :                     try
     572             :                     {
     573           0 :                         libcmis::ObjectPtr pObject = getObject( xEnv );
     574           0 :                         libcmis::AllowableActionsPtr aAllowables = pObject->getAllowableActions( );
     575           0 :                         bool bAllowed = false;
     576           0 :                         if ( aAllowables )
     577             :                         {
     578           0 :                             bAllowed = aAllowables->isAllowed( libcmis::ObjectAction::CheckOut );
     579             :                         }
     580           0 :                         xRow->appendBoolean( rProp, bAllowed );
     581             :                     }
     582           0 :                     catch ( const libcmis::Exception& )
     583             :                     {
     584           0 :                         xRow->appendVoid( rProp );
     585             :                     }
     586             :                 }
     587           0 :                 else if ( rProp.Name == "CanCancelCheckOut" )
     588             :                 {
     589             :                     try
     590             :                     {
     591           0 :                         libcmis::ObjectPtr pObject = getObject( xEnv );
     592           0 :                         libcmis::AllowableActionsPtr aAllowables = pObject->getAllowableActions( );
     593           0 :                         bool bAllowed = false;
     594           0 :                         if ( aAllowables )
     595             :                         {
     596           0 :                             bAllowed = aAllowables->isAllowed( libcmis::ObjectAction::CancelCheckOut );
     597             :                         }
     598           0 :                         xRow->appendBoolean( rProp, bAllowed );
     599             :                     }
     600           0 :                     catch ( const libcmis::Exception& )
     601             :                     {
     602           0 :                         xRow->appendVoid( rProp );
     603             :                     }
     604             :                 }
     605           0 :                 else if ( rProp.Name == "CanCheckIn" )
     606             :                 {
     607             :                     try
     608             :                     {
     609           0 :                         libcmis::ObjectPtr pObject = getObject( xEnv );
     610           0 :                         libcmis::AllowableActionsPtr aAllowables = pObject->getAllowableActions( );
     611           0 :                         bool bAllowed = false;
     612           0 :                         if ( aAllowables )
     613             :                         {
     614           0 :                             bAllowed = aAllowables->isAllowed( libcmis::ObjectAction::CheckIn );
     615             :                         }
     616           0 :                         xRow->appendBoolean( rProp, bAllowed );
     617             :                     }
     618           0 :                     catch ( const libcmis::Exception& )
     619             :                     {
     620           0 :                         xRow->appendVoid( rProp );
     621             :                     }
     622             :                 }
     623             :                 else
     624             :                     SAL_INFO( "cmisucp", "Looking for unsupported property " << rProp.Name );
     625             :             }
     626           0 :             catch (const libcmis::Exception&)
     627             :             {
     628           0 :                 xRow->appendVoid( rProp );
     629             :             }
     630             :         }
     631             : 
     632           0 :         return uno::Reference< sdbc::XRow >( xRow.get() );
     633             :     }
     634             : 
     635           0 :     bool Content::exists( const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     636             :     {
     637           0 :         bool bExists = true;
     638             :         try
     639             :         {
     640           0 :             if ( !m_sObjectPath.isEmpty( ) )
     641           0 :                 m_pSession->getObjectByPath( OUSTR_TO_STDSTR( m_sObjectPath ) );
     642           0 :             else if ( !m_sObjectId.isEmpty( ) )
     643           0 :                 getSession( xEnv )->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
     644             :             // No need to handle the root folder case... how can it not exists?
     645             :         }
     646           0 :         catch ( const libcmis::Exception& )
     647             :         {
     648           0 :             bExists = false;
     649             :         }
     650             : 
     651           0 :         return bExists;
     652             :     }
     653             : 
     654           0 :     uno::Any Content::open(const ucb::OpenCommandArgument2 & rOpenCommand,
     655             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
     656             :             throw( uno::Exception )
     657             :     {
     658           0 :         bool bIsFolder = isFolder( xEnv );
     659             : 
     660             :         // Handle the case of the non-existing file
     661           0 :         if ( !exists( xEnv ) )
     662             :         {
     663           0 :             uno::Sequence< uno::Any > aArgs( 1 );
     664           0 :             aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
     665             :             uno::Any aErr = uno::makeAny(
     666             :                 ucb::InteractiveAugmentedIOException(rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
     667             :                     task::InteractionClassification_ERROR,
     668             :                     bIsFolder ? ucb::IOErrorCode_NOT_EXISTING_PATH : ucb::IOErrorCode_NOT_EXISTING, aArgs)
     669           0 :             );
     670             : 
     671           0 :             ucbhelper::cancelCommandExecution(aErr, xEnv);
     672             :         }
     673             : 
     674           0 :         uno::Any aRet;
     675             : 
     676             :         sal_Bool bOpenFolder = (
     677             :             ( rOpenCommand.Mode == ucb::OpenMode::ALL ) ||
     678             :             ( rOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
     679             :             ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENTS )
     680           0 :          );
     681             : 
     682           0 :         if ( bOpenFolder && bIsFolder )
     683             :         {
     684             :             uno::Reference< ucb::XDynamicResultSet > xSet
     685           0 :                 = new DynamicResultSet(m_xContext, this, rOpenCommand, xEnv );
     686           0 :             aRet <<= xSet;
     687             :         }
     688           0 :         else if ( rOpenCommand.Sink.is() )
     689             :         {
     690           0 :             if (
     691             :                 ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
     692             :                 ( rOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE )
     693             :                )
     694             :             {
     695             :                 ucbhelper::cancelCommandExecution(
     696             :                     uno::makeAny ( ucb::UnsupportedOpenModeException
     697             :                         ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
     698             :                           sal_Int16( rOpenCommand.Mode ) ) ),
     699           0 :                         xEnv );
     700             :             }
     701             : 
     702           0 :             if ( !feedSink( rOpenCommand.Sink, xEnv ) )
     703             :             {
     704             :                 // Note: rOpenCommand.Sink may contain an XStream
     705             :                 //       implementation. Support for this type of
     706             :                 //       sink is optional...
     707             :                 SAL_INFO( "cmisucp", "Failed to copy data to sink" );
     708             : 
     709             :                 ucbhelper::cancelCommandExecution(
     710             :                     uno::makeAny (ucb::UnsupportedDataSinkException
     711             :                         ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
     712             :                           rOpenCommand.Sink ) ),
     713           0 :                         xEnv );
     714             :             }
     715             :         }
     716             :         else
     717             :             SAL_INFO( "cmisucp", "Open falling through ..." );
     718             : 
     719           0 :         return aRet;
     720             :     }
     721             : 
     722           0 :     rtl::OUString Content::checkIn( const ucb::CheckinArgument& rArg,
     723             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
     724             :             throw( uno::Exception )
     725             :     {
     726           0 :         ucbhelper::Content aSourceContent( rArg.SourceURL, xEnv, comphelper::getProcessComponentContext( ) );
     727           0 :         uno::Reference< io::XInputStream > xIn = aSourceContent.openStream( );
     728             : 
     729           0 :         libcmis::ObjectPtr object;
     730             :         try
     731             :         {
     732           0 :             object = getObject( xEnv );
     733             :         }
     734           0 :         catch ( const libcmis::Exception& )
     735             :         {
     736             :         }
     737             : 
     738           0 :         libcmis::Document* pPwc = dynamic_cast< libcmis::Document* >( object.get( ) );
     739           0 :         if ( !pPwc )
     740             :         {
     741             :             ucbhelper::cancelCommandExecution(
     742             :                                 ucb::IOErrorCode_GENERAL,
     743             :                                 uno::Sequence< uno::Any >( 0 ),
     744             :                                 xEnv,
     745           0 :                                 "Checkin only supported by documents" );
     746             :         }
     747             : 
     748           0 :         boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) );
     749           0 :         uno::Reference < io::XOutputStream > xOutput = new ucbhelper::StdOutputStream( pOut );
     750           0 :         copyData( xIn, xOutput );
     751             : 
     752           0 :         map< string, libcmis::PropertyPtr > newProperties;
     753             :         libcmis::DocumentPtr pDoc = pPwc->checkIn( rArg.MajorVersion, OUSTR_TO_STDSTR( rArg.VersionComment ), newProperties,
     754           0 :                            pOut, OUSTR_TO_STDSTR( rArg.MimeType ), OUSTR_TO_STDSTR( rArg.NewTitle ) );
     755             : 
     756             :         // Get the URL and send it back as a result
     757           0 :         URL aCmisUrl( m_sURL );
     758           0 :         vector< string > aPaths = pDoc->getPaths( );
     759           0 :         if ( !aPaths.empty() )
     760             :         {
     761           0 :             string sPath = aPaths.front( );
     762           0 :             aCmisUrl.setObjectPath( STD_TO_OUSTR( sPath ) );
     763             :         }
     764             :         else
     765             :         {
     766             :             // We may have unfiled document depending on the server, those
     767             :             // won't have any path, use their ID instead
     768           0 :             string sId = pDoc->getId( );
     769           0 :             aCmisUrl.setObjectId( STD_TO_OUSTR( sId ) );
     770             :         }
     771           0 :         return aCmisUrl.asString( );
     772             :     }
     773             : 
     774           0 :     rtl::OUString Content::checkOut( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
     775             :             throw( uno::Exception )
     776             :     {
     777           0 :         rtl::OUString aRet;
     778             :         try
     779             :         {
     780             :             // Checkout the document if possible
     781           0 :             libcmis::DocumentPtr pDoc = boost::dynamic_pointer_cast< libcmis::Document >( getObject( xEnv ) );
     782           0 :             if ( pDoc.get( ) == NULL )
     783             :             {
     784             :                 ucbhelper::cancelCommandExecution(
     785             :                                     ucb::IOErrorCode_GENERAL,
     786             :                                     uno::Sequence< uno::Any >( 0 ),
     787             :                                     xEnv,
     788           0 :                                     "Checkout only supported by documents" );
     789             :             }
     790           0 :             libcmis::DocumentPtr pPwc = pDoc->checkOut( );
     791             : 
     792             :             // Compute the URL of the Private Working Copy (PWC)
     793           0 :             URL aCmisUrl( m_sURL );
     794           0 :             vector< string > aPaths = pPwc->getPaths( );
     795           0 :             if ( !aPaths.empty() )
     796             :             {
     797           0 :                 string sPath = aPaths.front( );
     798           0 :                 aCmisUrl.setObjectPath( STD_TO_OUSTR( sPath ) );
     799             :             }
     800             :             else
     801             :             {
     802             :                 // We may have unfiled PWC depending on the server, those
     803             :                 // won't have any path, use their ID instead
     804           0 :                 string sId = pPwc->getId( );
     805           0 :                 aCmisUrl.setObjectId( STD_TO_OUSTR( sId ) );
     806             :             }
     807           0 :             aRet = aCmisUrl.asString( );
     808             :         }
     809           0 :         catch ( const libcmis::Exception& e )
     810             :         {
     811             :             SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
     812             :             ucbhelper::cancelCommandExecution(
     813             :                                 ucb::IOErrorCode_GENERAL,
     814             :                                 uno::Sequence< uno::Any >( 0 ),
     815             :                                 xEnv,
     816           0 :                                 rtl::OUString::createFromAscii( e.what() ) );
     817             :         }
     818           0 :         return aRet;
     819             :     }
     820             : 
     821           0 :     rtl::OUString Content::cancelCheckOut( const uno::Reference< ucb::XCommandEnvironment > & xEnv )
     822             :             throw( uno::Exception )
     823             :     {
     824           0 :         rtl::OUString aRet;
     825             :         try
     826             :         {
     827           0 :             libcmis::DocumentPtr pPwc = boost::dynamic_pointer_cast< libcmis::Document >( getObject( xEnv ) );
     828           0 :             if ( pPwc.get( ) == NULL )
     829             :             {
     830             :                 ucbhelper::cancelCommandExecution(
     831             :                                     ucb::IOErrorCode_GENERAL,
     832             :                                     uno::Sequence< uno::Any >( 0 ),
     833             :                                     xEnv,
     834           0 :                                     "CancelCheckout only supported by documents" );
     835             :             }
     836           0 :             pPwc->cancelCheckout( );
     837             : 
     838             :             // Get the Original document (latest version)
     839           0 :             vector< libcmis::DocumentPtr > aVersions = pPwc->getAllVersions( );
     840           0 :             bool bFound = false;
     841           0 :             for ( vector< libcmis::DocumentPtr >::iterator it = aVersions.begin();
     842           0 :                     it != aVersions.end( ) && !bFound; ++it )
     843             :             {
     844           0 :                 libcmis::DocumentPtr pVersion = *it;
     845           0 :                 map< string, libcmis::PropertyPtr > aProps = pVersion->getProperties( );
     846           0 :                 bool bIsLatestVersion = false;
     847           0 :                 map< string, libcmis::PropertyPtr >::iterator propIt = aProps.find( string( "cmis:isLatestVersion" ) );
     848           0 :                 if ( propIt != aProps.end( ) && !propIt->second->getBools( ).empty( ) )
     849             :                 {
     850           0 :                     bIsLatestVersion = propIt->second->getBools( ).front( );
     851             :                 }
     852             : 
     853           0 :                 if ( bIsLatestVersion )
     854             :                 {
     855           0 :                     bFound = true;
     856             :                     // Compute the URL of the Document
     857           0 :                     URL aCmisUrl( m_sURL );
     858           0 :                     vector< string > aPaths = pVersion->getPaths( );
     859           0 :                     if ( !aPaths.empty() )
     860             :                     {
     861           0 :                         string sPath = aPaths.front( );
     862           0 :                         aCmisUrl.setObjectPath( STD_TO_OUSTR( sPath ) );
     863             :                     }
     864             :                     else
     865             :                     {
     866             :                         // We may have unfiled doc depending on the server, those
     867             :                         // won't have any path, use their ID instead
     868           0 :                         string sId = pVersion->getId( );
     869           0 :                         aCmisUrl.setObjectId( STD_TO_OUSTR( sId ) );
     870             :                     }
     871           0 :                     aRet = aCmisUrl.asString( );
     872             :                 }
     873           0 :             }
     874             :         }
     875           0 :         catch ( const libcmis::Exception& e )
     876             :         {
     877             :             SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
     878             :             ucbhelper::cancelCommandExecution(
     879             :                                 ucb::IOErrorCode_GENERAL,
     880             :                                 uno::Sequence< uno::Any >( 0 ),
     881             :                                 xEnv,
     882           0 :                                 rtl::OUString::createFromAscii( e.what() ) );
     883             :         }
     884           0 :         return aRet;
     885             :     }
     886             : 
     887           0 :     void Content::transfer( const ucb::TransferInfo& rTransferInfo,
     888             :         const uno::Reference< ucb::XCommandEnvironment > & xEnv )
     889             :             throw( uno::Exception )
     890             :     {
     891             :         // If the source isn't on the same CMIS repository, then simply copy
     892           0 :         INetURLObject aSourceUrl( rTransferInfo.SourceURL );
     893           0 :         if ( aSourceUrl.GetProtocol() != INET_PROT_CMIS )
     894             :         {
     895           0 :             rtl::OUString sSrcBindingUrl = URL( rTransferInfo.SourceURL ).getBindingUrl( );
     896           0 :             if ( sSrcBindingUrl != m_aURL.getBindingUrl( ) )
     897             :             {
     898             :                 ucbhelper::cancelCommandExecution(
     899             :                     uno::makeAny(
     900             :                         ucb::InteractiveBadTransferURLException(
     901             :                             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
     902             :                                 "Unsupported URL scheme!" )),
     903             :                             static_cast< cppu::OWeakObject * >( this ) ) ),
     904           0 :                     xEnv );
     905           0 :             }
     906             :         }
     907             : 
     908           0 :         SAL_INFO( "cmisucp", "TODO - Content::transfer()" );
     909           0 :     }
     910             : 
     911           0 :     void Content::insert( const uno::Reference< io::XInputStream > & xInputStream,
     912             :         sal_Bool bReplaceExisting, const rtl::OUString& rMimeType,
     913             :         const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     914             :             throw( uno::Exception )
     915             :     {
     916           0 :         if ( !xInputStream.is() )
     917             :         {
     918             :             ucbhelper::cancelCommandExecution( uno::makeAny
     919             :                 ( ucb::MissingInputStreamException
     920             :                   ( rtl::OUString(), static_cast< cppu::OWeakObject * >( this ) ) ),
     921           0 :                 xEnv );
     922             :         }
     923             : 
     924             :         // For transient content, the URL is the one of the parent
     925           0 :         if ( m_bTransient )
     926             :         {
     927           0 :             rtl::OUString sNewPath;
     928             : 
     929             :             // Try to get the object from the server if there is any
     930           0 :             libcmis::Folder* pFolder = NULL;
     931             :             try
     932             :             {
     933           0 :                 pFolder = dynamic_cast< libcmis::Folder* >( getObject( xEnv ).get( ) );
     934             :             }
     935           0 :             catch ( const libcmis::Exception& )
     936             :             {
     937             :             }
     938             : 
     939           0 :             if ( pFolder != NULL )
     940             :             {
     941           0 :                 map< string, libcmis::PropertyPtr >::iterator it = m_pObjectProps.find( "cmis:name" );
     942           0 :                 if ( it == m_pObjectProps.end( ) )
     943             :                 {
     944             :                     ucbhelper::cancelCommandExecution( uno::makeAny
     945             :                         ( uno::RuntimeException( "Missing name property",
     946             :                             static_cast< cppu::OWeakObject * >( this ) ) ),
     947           0 :                         xEnv );
     948             :                 }
     949           0 :                 string newName = it->second->getStrings( ).front( );
     950           0 :                 string newPath = pFolder->getPath( );
     951           0 :                 if ( newPath[ newPath.size( ) - 1 ] != '/' )
     952           0 :                     newPath += "/";
     953           0 :                 newPath += newName;
     954             : 
     955           0 :                 libcmis::ObjectPtr object;
     956             :                 try
     957             :                 {
     958           0 :                     object = getSession( xEnv )->getObjectByPath( newPath );
     959           0 :                     sNewPath = STD_TO_OUSTR( newPath );
     960             :                 }
     961           0 :                 catch ( const libcmis::Exception& )
     962             :                 {
     963             :                     // Nothing matched the path
     964             :                 }
     965             : 
     966           0 :                 if ( NULL != object.get( ) )
     967             :                 {
     968             :                     // Are the base type matching?
     969           0 :                     if ( object->getBaseType( ) != m_pObjectType->getBaseType( )->getId() )
     970             :                     {
     971             :                         ucbhelper::cancelCommandExecution( uno::makeAny
     972             :                             ( uno::RuntimeException( "Can't change a folder into a document and vice-versa.",
     973             :                                 static_cast< cppu::OWeakObject * >( this ) ) ),
     974           0 :                             xEnv );
     975             :                     }
     976             : 
     977             :                     // Update the existing object if it's a document
     978           0 :                     libcmis::Document* document = dynamic_cast< libcmis::Document* >( object.get( ) );
     979           0 :                     if ( NULL != document )
     980             :                     {
     981           0 :                         boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) );
     982           0 :                         uno::Reference < io::XOutputStream > xOutput = new ucbhelper::StdOutputStream( pOut );
     983           0 :                         copyData( xInputStream, xOutput );
     984           0 :                         document->setContentStream( pOut, OUSTR_TO_STDSTR( rMimeType ), string( ), bReplaceExisting );
     985             :                     }
     986             :                 }
     987             :                 else
     988             :                 {
     989             :                     // We need to create a brand new object... either folder or document
     990           0 :                     bool bIsFolder = getObjectType( xEnv )->getBaseType( )->getId( ) == "cmis:folder";
     991           0 :                     setCmisProperty( "cmis:objectTypeId", getObjectType( xEnv )->getId( ), xEnv );
     992             : 
     993           0 :                     if ( bIsFolder )
     994             :                     {
     995           0 :                         libcmis::FolderPtr pNew = pFolder->createFolder( m_pObjectProps );
     996           0 :                         sNewPath = STD_TO_OUSTR( newPath );
     997             :                     }
     998             :                     else
     999             :                     {
    1000           0 :                         boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) );
    1001           0 :                         uno::Reference < io::XOutputStream > xOutput = new ucbhelper::StdOutputStream( pOut );
    1002           0 :                         copyData( xInputStream, xOutput );
    1003           0 :                         pFolder->createDocument( m_pObjectProps, pOut, OUSTR_TO_STDSTR( rMimeType ), string() );
    1004           0 :                         sNewPath = STD_TO_OUSTR( newPath );
    1005             :                     }
    1006             :                 }
    1007             : 
    1008           0 :                 if ( !sNewPath.isEmpty( ) )
    1009             :                 {
    1010             :                     // Update the current content: it's no longer transient
    1011           0 :                     m_sObjectPath = sNewPath;
    1012           0 :                     URL aUrl( m_sURL );
    1013           0 :                     aUrl.setObjectPath( m_sObjectPath );
    1014           0 :                     m_sURL = aUrl.asString( );
    1015           0 :                     m_pObject.reset( );
    1016           0 :                     m_pObjectType.reset( );
    1017           0 :                     m_pObjectProps.clear( );
    1018           0 :                     m_bTransient = false;
    1019             : 
    1020           0 :                     inserted();
    1021           0 :                 }
    1022           0 :             }
    1023             :         }
    1024           0 :     }
    1025             : 
    1026             :     const int TRANSFER_BUFFER_SIZE = 65536;
    1027             : 
    1028           0 :     void Content::copyData(
    1029             :         uno::Reference< io::XInputStream > xIn,
    1030             :         uno::Reference< io::XOutputStream > xOut )
    1031             :     {
    1032           0 :         uno::Sequence< sal_Int8 > theData( TRANSFER_BUFFER_SIZE );
    1033             : 
    1034           0 :         while ( xIn->readBytes( theData, TRANSFER_BUFFER_SIZE ) > 0 )
    1035           0 :             xOut->writeBytes( theData );
    1036             : 
    1037           0 :         xOut->closeOutput();
    1038           0 :     }
    1039             : 
    1040           0 :     uno::Sequence< uno::Any > Content::setPropertyValues(
    1041             :             const uno::Sequence< beans::PropertyValue >& rValues,
    1042             :             const uno::Reference< ucb::XCommandEnvironment >& xEnv )
    1043             :     {
    1044             :         try
    1045             :         {
    1046             :             // Get the already set properties if possible
    1047           0 :             if ( !m_bTransient && getObject( xEnv ).get( ) )
    1048             :             {
    1049           0 :                 m_pObjectProps.clear( );
    1050           0 :                 m_pObjectType = getObject( xEnv )->getTypeDescription();
    1051             :             }
    1052             :         }
    1053           0 :         catch ( const libcmis::Exception& e )
    1054             :         {
    1055             :             SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
    1056             :             ucbhelper::cancelCommandExecution(
    1057             :                                 ucb::IOErrorCode_GENERAL,
    1058             :                                 uno::Sequence< uno::Any >( 0 ),
    1059             :                                 xEnv,
    1060           0 :                                 rtl::OUString::createFromAscii( e.what() ) );
    1061             :         }
    1062             : 
    1063           0 :         sal_Int32 nCount = rValues.getLength();
    1064           0 :         uno::Sequence< uno::Any > aRet( nCount );
    1065             : 
    1066           0 :         bool bChanged = false;
    1067           0 :         const beans::PropertyValue* pValues = rValues.getConstArray();
    1068           0 :         for ( sal_Int32 n = 0; n < nCount; ++n )
    1069             :         {
    1070           0 :             const beans::PropertyValue& rValue = pValues[ n ];
    1071           0 :             if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) ||
    1072           0 :                  rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ||
    1073           0 :                  rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) ||
    1074           0 :                  rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) ||
    1075           0 :                  rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Size" ) ) ||
    1076           0 :                  rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CreatableContentsInfo" ) ) )
    1077             :             {
    1078             :                 lang::IllegalAccessException e ( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Property is read-only!")),
    1079           0 :                        static_cast< cppu::OWeakObject* >( this ) );
    1080           0 :                 aRet[ n ] <<= e;
    1081             :             }
    1082           0 :             else if ( rValue.Name == "Title" )
    1083             :             {
    1084           0 :                 rtl::OUString aNewTitle;
    1085           0 :                 if (!( rValue.Value >>= aNewTitle ))
    1086             :                 {
    1087           0 :                     aRet[ n ] <<= beans::IllegalTypeException
    1088             :                         ( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Property value has wrong type!")),
    1089           0 :                           static_cast< cppu::OWeakObject * >( this ) );
    1090           0 :                     continue;
    1091             :                 }
    1092             : 
    1093           0 :                 if ( aNewTitle.getLength() <= 0 )
    1094             :                 {
    1095           0 :                     aRet[ n ] <<= lang::IllegalArgumentException
    1096             :                         ( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Empty title not allowed!")),
    1097           0 :                           static_cast< cppu::OWeakObject * >( this ), -1 );
    1098           0 :                     continue;
    1099             : 
    1100             :                 }
    1101             : 
    1102           0 :                 setCmisProperty( "cmis:name", OUSTR_TO_STDSTR( aNewTitle ), xEnv );
    1103           0 :                 bChanged = true;
    1104             :             }
    1105             :             else
    1106             :             {
    1107             :                 SAL_INFO( "cmisucp", "Couln't set property: " << rValue.Name );
    1108             :                 lang::IllegalAccessException e ( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Property is read-only!")),
    1109           0 :                        static_cast< cppu::OWeakObject* >( this ) );
    1110           0 :                 aRet[ n ] <<= e;
    1111             :             }
    1112             :         }
    1113             : 
    1114             :         try
    1115             :         {
    1116           0 :             if ( !m_bTransient && bChanged )
    1117             :             {
    1118           0 :                 getObject( xEnv )->updateProperties( m_pObjectProps );
    1119             :             }
    1120             :         }
    1121           0 :         catch ( const libcmis::Exception& e )
    1122             :         {
    1123             :             SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
    1124             :             ucbhelper::cancelCommandExecution(
    1125             :                                 ucb::IOErrorCode_GENERAL,
    1126             :                                 uno::Sequence< uno::Any >( 0 ),
    1127             :                                 xEnv,
    1128           0 :                                 rtl::OUString::createFromAscii( e.what() ) );
    1129             :         }
    1130             : 
    1131           0 :         return aRet;
    1132             :     }
    1133             : 
    1134           0 :     sal_Bool Content::feedSink( uno::Reference< uno::XInterface> xSink,
    1135             :         const uno::Reference< ucb::XCommandEnvironment >& xEnv )
    1136             :     {
    1137           0 :         if ( !xSink.is() )
    1138           0 :             return sal_False;
    1139             : 
    1140           0 :         uno::Reference< io::XOutputStream > xOut = uno::Reference< io::XOutputStream >(xSink, uno::UNO_QUERY );
    1141           0 :         uno::Reference< io::XActiveDataSink > xDataSink = uno::Reference< io::XActiveDataSink >(xSink, uno::UNO_QUERY );
    1142           0 :         uno::Reference< io::XActiveDataStreamer > xDataStreamer = uno::Reference< io::XActiveDataStreamer >( xSink, uno::UNO_QUERY );
    1143             : 
    1144           0 :         if ( !xOut.is() && !xDataSink.is() && ( !xDataStreamer.is() || !xDataStreamer->getStream().is() ) )
    1145           0 :             return sal_False;
    1146             : 
    1147           0 :         if ( xDataStreamer.is() && !xOut.is() )
    1148           0 :             xOut = xDataStreamer->getStream()->getOutputStream();
    1149             : 
    1150             :         try
    1151             :         {
    1152           0 :             libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject( xEnv ).get() );
    1153           0 :             boost::shared_ptr< istream > aIn = document->getContentStream( );
    1154             : 
    1155           0 :             uno::Reference< io::XInputStream > xIn = new ucbhelper::StdInputStream( aIn );
    1156           0 :             if( !xIn.is( ) )
    1157           0 :                 return sal_False;
    1158             : 
    1159           0 :             if ( xDataSink.is() )
    1160           0 :                 xDataSink->setInputStream( xIn );
    1161           0 :             else if ( xOut.is() )
    1162           0 :                 copyData( xIn, xOut );
    1163             :         }
    1164           0 :         catch ( const libcmis::Exception& e )
    1165             :         {
    1166             :             SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
    1167             :             ucbhelper::cancelCommandExecution(
    1168             :                                 ucb::IOErrorCode_GENERAL,
    1169             :                                 uno::Sequence< uno::Any >( 0 ),
    1170             :                                 xEnv,
    1171           0 :                                 rtl::OUString::createFromAscii( e.what() ) );
    1172             :         }
    1173             : 
    1174           0 :         return sal_True;
    1175             :     }
    1176             : 
    1177           0 :     uno::Sequence< beans::Property > Content::getProperties(
    1178             :             const uno::Reference< ucb::XCommandEnvironment > & )
    1179             :     {
    1180             :         static const beans::Property aGenericProperties[] =
    1181             :         {
    1182             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ),
    1183           0 :                 -1, getCppuBooleanType(),
    1184             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1185             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ),
    1186           0 :                 -1, getCppuBooleanType(),
    1187             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1188             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),
    1189           0 :                 -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
    1190             :                 beans::PropertyAttribute::BOUND ),
    1191             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TitleOnServer" ) ),
    1192           0 :                 -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
    1193             :                 beans::PropertyAttribute::BOUND ),
    1194             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
    1195           0 :                 -1, getCppuBooleanType(),
    1196             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1197             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateCreated" ) ),
    1198           0 :                 -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
    1199             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1200             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ),
    1201           0 :                 -1, getCppuType( static_cast< const util::DateTime * >( 0 ) ),
    1202             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1203             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Size" ) ),
    1204           0 :                 -1, getCppuType( static_cast< const sal_Int64 * >( 0 ) ),
    1205             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1206             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CreatableContentsInfo" ) ),
    1207           0 :                 -1, getCppuType( static_cast< const uno::Sequence< ucb::ContentInfo > * >( 0 ) ),
    1208             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1209             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ),
    1210           0 :                 -1, getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
    1211             :                 beans::PropertyAttribute::BOUND ),
    1212             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CmisPropertiesValues" ) ),
    1213           0 :                 -1, getCppuType( static_cast< const beans::PropertyValues * >( 0 ) ),
    1214             :                 beans::PropertyAttribute::BOUND ),
    1215             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CmisPropertiesDisplayNames" ) ),
    1216           0 :                 -1, getCppuType( static_cast< const beans::PropertyValues * >( 0 ) ),
    1217             :                 beans::PropertyAttribute::BOUND ),
    1218             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsVersionable" ) ),
    1219           0 :                 -1, getCppuBooleanType(),
    1220             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1221             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CanCheckOut" ) ),
    1222           0 :                 -1, getCppuBooleanType(),
    1223             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1224             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CanCancelCheckOut" ) ),
    1225           0 :                 -1, getCppuBooleanType(),
    1226             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1227             :             beans::Property( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CanCheckIn" ) ),
    1228           0 :                 -1, getCppuBooleanType(),
    1229             :                 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY ),
    1230           0 :         };
    1231             : 
    1232           0 :         const int nProps = SAL_N_ELEMENTS(aGenericProperties);
    1233           0 :         return uno::Sequence< beans::Property > ( aGenericProperties, nProps );
    1234             :     }
    1235             : 
    1236           0 :     uno::Sequence< ucb::CommandInfo > Content::getCommands(
    1237             :             const uno::Reference< ucb::XCommandEnvironment > & xEnv )
    1238             :     {
    1239             :         static ucb::CommandInfo aCommandInfoTable[] =
    1240             :         {
    1241             :             // Required commands
    1242             :             ucb::CommandInfo
    1243             :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ),
    1244           0 :               -1, getCppuVoidType() ),
    1245             :             ucb::CommandInfo
    1246             :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ),
    1247           0 :               -1, getCppuVoidType() ),
    1248             :             ucb::CommandInfo
    1249             :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ),
    1250           0 :               -1, getCppuType( static_cast<uno::Sequence< beans::Property > * >( 0 ) ) ),
    1251             :             ucb::CommandInfo
    1252             :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
    1253           0 :               -1, getCppuType( static_cast<uno::Sequence< beans::PropertyValue > * >( 0 ) ) ),
    1254             : 
    1255             :             // Optional standard commands
    1256             :             ucb::CommandInfo
    1257             :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" ) ),
    1258           0 :               -1, getCppuBooleanType() ),
    1259             :             ucb::CommandInfo
    1260             :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert" ) ),
    1261           0 :               -1, getCppuType( static_cast<ucb::InsertCommandArgument2 * >( 0 ) ) ),
    1262             :             ucb::CommandInfo
    1263             :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ),
    1264           0 :               -1, getCppuType( static_cast<ucb::OpenCommandArgument2 * >( 0 ) ) ),
    1265             : 
    1266             :             // Mandatory CMIS-only commands
    1267           0 :             ucb::CommandInfo ( rtl::OUString( "checkout" ), -1, getCppuVoidType() ),
    1268           0 :             ucb::CommandInfo ( rtl::OUString( "cancelCheckout" ), -1, getCppuVoidType() ),
    1269             :             ucb::CommandInfo ( rtl::OUString( "checkIn" ), -1,
    1270           0 :                     getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) ),
    1271             : 
    1272             :             // Folder Only, omitted if not a folder
    1273             :             ucb::CommandInfo
    1274             :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "transfer" ) ),
    1275           0 :               -1, getCppuType( static_cast<ucb::TransferInfo * >( 0 ) ) ),
    1276             :             ucb::CommandInfo
    1277             :             ( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "createNewContent" ) ),
    1278           0 :               -1, getCppuType( static_cast<ucb::ContentInfo * >( 0 ) ) )
    1279           0 :         };
    1280             : 
    1281           0 :         const int nProps = SAL_N_ELEMENTS( aCommandInfoTable );
    1282           0 :         return uno::Sequence< ucb::CommandInfo >(aCommandInfoTable, isFolder( xEnv ) ? nProps : nProps - 2);
    1283             :     }
    1284             : 
    1285           0 :     ::rtl::OUString Content::getParentURL( )
    1286             :     {
    1287           0 :         rtl::OUString sRet;
    1288             : 
    1289             :         SAL_INFO( "cmisucp", "Content::getParentURL()" );
    1290             : 
    1291           0 :         string parentPath;
    1292             :         try
    1293             :         {
    1294           0 :             libcmis::ObjectPtr pObj = getObject( uno::Reference< ucb::XCommandEnvironment >() );
    1295           0 :             libcmis::Document* document = dynamic_cast< libcmis::Document* >( pObj.get( ) );
    1296           0 :             if ( NULL != document )
    1297             :             {
    1298           0 :                 vector< boost::shared_ptr< libcmis::Folder > > parents = document->getParents( );
    1299           0 :                 if ( !parents.empty( ) )
    1300           0 :                     parentPath = parents.front( )->getPath( );
    1301             :             }
    1302             :             else
    1303             :             {
    1304           0 :                 libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( pObj.get( ) );
    1305           0 :                 if ( NULL != folder )
    1306           0 :                     parentPath = folder->getFolderParent( )->getPath( );
    1307           0 :             }
    1308             :         }
    1309           0 :         catch ( const libcmis::Exception & )
    1310             :         {
    1311             :             // We may have an exception if we don't have the rights to
    1312             :             // get the parents
    1313             :         }
    1314             : 
    1315           0 :         if ( !parentPath.empty() )
    1316             :         {
    1317           0 :             URL aUrl( m_sURL );
    1318           0 :             aUrl.setObjectPath( STD_TO_OUSTR( parentPath ) );
    1319           0 :             sRet = aUrl.asString( );
    1320             :         }
    1321             :         else
    1322             :         {
    1323           0 :             INetURLObject aUrl( m_sURL );
    1324           0 :             if ( aUrl.getSegmentCount( ) > 0 )
    1325             :             {
    1326           0 :                 URL aCmisUrl( m_sURL );
    1327           0 :                 aUrl.removeSegment( );
    1328           0 :                 aCmisUrl.setObjectPath( aUrl.GetURLPath( INetURLObject::NO_DECODE ) );
    1329           0 :                 sRet = aCmisUrl.asString( );
    1330           0 :             }
    1331             :         }
    1332             : 
    1333           0 :         return sRet;
    1334             :     }
    1335             : 
    1336           0 :     XTYPEPROVIDER_COMMON_IMPL( Content );
    1337             : 
    1338           0 :     void SAL_CALL Content::acquire() throw()
    1339             :     {
    1340           0 :         ContentImplHelper::acquire();
    1341           0 :     }
    1342             : 
    1343           0 :     void SAL_CALL Content::release() throw()
    1344             :     {
    1345           0 :         ContentImplHelper::release();
    1346           0 :     }
    1347             : 
    1348           0 :     uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) throw ( uno::RuntimeException )
    1349             :     {
    1350           0 :         uno::Any aRet = cppu::queryInterface( rType, static_cast< ucb::XContentCreator * >( this ) );
    1351           0 :         return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface(rType);
    1352             :     }
    1353             : 
    1354           0 :     rtl::OUString SAL_CALL Content::getImplementationName() throw( uno::RuntimeException )
    1355             :     {
    1356           0 :        return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.CmisContent"));
    1357             :     }
    1358             : 
    1359           0 :     uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
    1360             :            throw( uno::RuntimeException )
    1361             :     {
    1362           0 :            uno::Sequence< rtl::OUString > aSNS( 1 );
    1363           0 :            aSNS.getArray()[ 0 ] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.CmisContent"));
    1364           0 :            return aSNS;
    1365             :     }
    1366             : 
    1367           0 :     rtl::OUString SAL_CALL Content::getContentType() throw( uno::RuntimeException )
    1368             :     {
    1369           0 :         return isFolder( uno::Reference< ucb::XCommandEnvironment >() )
    1370             :             ? rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CMIS_FOLDER_TYPE ))
    1371           0 :             : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CMIS_FILE_TYPE ));
    1372             :     }
    1373             : 
    1374           0 :     uno::Any SAL_CALL Content::execute(
    1375             :         const ucb::Command& aCommand,
    1376             :         sal_Int32 /*CommandId*/,
    1377             :         const uno::Reference< ucb::XCommandEnvironment >& xEnv )
    1378             :             throw( uno::Exception, ucb::CommandAbortedException, uno::RuntimeException )
    1379             :     {
    1380             :         SAL_INFO( "cmisucp", "Content::execute( ) - " << aCommand.Name );
    1381           0 :         uno::Any aRet;
    1382             : 
    1383           0 :         if ( aCommand.Name == "getPropertyValues" )
    1384             :         {
    1385           0 :             uno::Sequence< beans::Property > Properties;
    1386           0 :             if ( !( aCommand.Argument >>= Properties ) )
    1387           0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
    1388           0 :             aRet <<= getPropertyValues( Properties, xEnv );
    1389             :         }
    1390           0 :         else if ( aCommand.Name == "getPropertySetInfo" )
    1391           0 :             aRet <<= getPropertySetInfo( xEnv, sal_False );
    1392           0 :         else if ( aCommand.Name == "getCommandInfo" )
    1393           0 :             aRet <<= getCommandInfo( xEnv, sal_False );
    1394           0 :         else if ( aCommand.Name == "open" )
    1395             :         {
    1396           0 :             ucb::OpenCommandArgument2 aOpenCommand;
    1397           0 :             if ( !( aCommand.Argument >>= aOpenCommand ) )
    1398           0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
    1399           0 :             aRet = open( aOpenCommand, xEnv );
    1400             :         }
    1401           0 :         else if ( aCommand.Name == "transfer" )
    1402             :         {
    1403           0 :             ucb::TransferInfo transferArgs;
    1404           0 :             if ( !( aCommand.Argument >>= transferArgs ) )
    1405           0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
    1406           0 :             transfer( transferArgs, xEnv );
    1407             :         }
    1408           0 :         else if ( aCommand.Name == "setPropertyValues" )
    1409             :         {
    1410           0 :             uno::Sequence< beans::PropertyValue > aProperties;
    1411           0 :             if ( !( aCommand.Argument >>= aProperties ) || !aProperties.getLength() )
    1412           0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
    1413           0 :             aRet <<= setPropertyValues( aProperties, xEnv );
    1414             :         }
    1415           0 :         else if (aCommand.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "createNewContent" ) )
    1416           0 :                  && isFolder( xEnv ) )
    1417             :         {
    1418           0 :             ucb::ContentInfo arg;
    1419           0 :             if ( !( aCommand.Argument >>= arg ) )
    1420           0 :                     ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
    1421           0 :             aRet <<= createNewContent( arg );
    1422             :         }
    1423           0 :         else if ( aCommand.Name == "insert" )
    1424             :         {
    1425           0 :             ucb::InsertCommandArgument2 arg;
    1426           0 :             if ( !( aCommand.Argument >>= arg ) )
    1427             :             {
    1428           0 :                 ucb::InsertCommandArgument insertArg;
    1429           0 :                 if ( !( aCommand.Argument >>= insertArg ) )
    1430           0 :                     ucbhelper::cancelCommandExecution ( getBadArgExcept (), xEnv );
    1431             : 
    1432           0 :                 arg.Data = insertArg.Data;
    1433           0 :                 arg.ReplaceExisting = insertArg.ReplaceExisting;
    1434             :             }
    1435           0 :             insert( arg.Data, arg.ReplaceExisting, arg.MimeType, xEnv );
    1436             :         }
    1437           0 :         else if ( aCommand.Name == "delete" )
    1438             :         {
    1439             :             try
    1440             :             {
    1441           0 :                 if ( !isFolder( xEnv ) )
    1442             :                 {
    1443           0 :                     getObject( xEnv )->remove( );
    1444             :                 }
    1445             :                 else
    1446             :                 {
    1447           0 :                     libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( getObject( xEnv ).get() );
    1448           0 :                     folder->removeTree( );
    1449             :                 }
    1450             :             }
    1451           0 :             catch ( const libcmis::Exception& e )
    1452             :             {
    1453             :                 SAL_INFO( "cmisucp", "Unexpected libcmis exception: " << e.what( ) );
    1454             :                 ucbhelper::cancelCommandExecution(
    1455             :                                     ucb::IOErrorCode_GENERAL,
    1456             :                                     uno::Sequence< uno::Any >( 0 ),
    1457             :                                     xEnv,
    1458           0 :                                     rtl::OUString::createFromAscii( e.what() ) );
    1459             :             }
    1460             :         }
    1461           0 :         else if ( aCommand.Name == "checkout" )
    1462             :         {
    1463           0 :             aRet <<= checkOut( xEnv );
    1464             :         }
    1465           0 :         else if ( aCommand.Name == "cancelCheckout" )
    1466             :         {
    1467           0 :             aRet <<= cancelCheckOut( xEnv );
    1468             :         }
    1469           0 :         else if ( aCommand.Name == "checkin" )
    1470             :         {
    1471           0 :             ucb::CheckinArgument aArg;
    1472           0 :             if ( !( aCommand.Argument >>= aArg ) )
    1473             :             {
    1474           0 :                 ucbhelper::cancelCommandExecution ( getBadArgExcept(), xEnv );
    1475             :             }
    1476           0 :             aRet <<= checkIn( aArg, xEnv );
    1477             :         }
    1478             :         else
    1479             :         {
    1480             :             SAL_INFO( "cmisucp", "Unknown command to execute" );
    1481             : 
    1482             :             ucbhelper::cancelCommandExecution
    1483             :                 ( uno::makeAny( ucb::UnsupportedCommandException
    1484             :                   ( rtl::OUString(),
    1485             :                     static_cast< cppu::OWeakObject * >( this ) ) ),
    1486           0 :                   xEnv );
    1487             :         }
    1488             : 
    1489           0 :         return aRet;
    1490             :     }
    1491             : 
    1492           0 :     void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) throw( uno::RuntimeException )
    1493             :     {
    1494             :         SAL_INFO( "cmisucp", "TODO - Content::abort()" );
    1495             :         // TODO Implement me
    1496           0 :     }
    1497             : 
    1498           0 :     uno::Sequence< ucb::ContentInfo > SAL_CALL Content::queryCreatableContentsInfo()
    1499             :             throw( uno::RuntimeException )
    1500             :     {
    1501           0 :         return queryCreatableContentsInfo( uno::Reference< ucb::XCommandEnvironment >() );
    1502             :     }
    1503             : 
    1504           0 :     uno::Reference< ucb::XContent > SAL_CALL Content::createNewContent(
    1505             :             const ucb::ContentInfo& Info ) throw( uno::RuntimeException )
    1506             :     {
    1507             :         bool create_document;
    1508             : 
    1509           0 :         if ( Info.Type == CMIS_FILE_TYPE )
    1510           0 :             create_document = true;
    1511           0 :         else if ( Info.Type == CMIS_FOLDER_TYPE )
    1512           0 :             create_document = false;
    1513             :         else
    1514             :         {
    1515             :             SAL_INFO( "cmisucp", "Unknown type of content to create" );
    1516           0 :             return uno::Reference< ucb::XContent >();
    1517             :         }
    1518             : 
    1519           0 :         rtl::OUString sParentURL = m_xIdentifier->getContentIdentifier();
    1520           0 :         URL aParentURL( sParentURL );
    1521             : 
    1522             :         // Set the parent URL for the transient objects
    1523           0 :         uno::Reference< ucb::XContentIdentifier > xId(new ::ucbhelper::ContentIdentifier(sParentURL));
    1524             : 
    1525             :         try
    1526             :         {
    1527           0 :             return new ::cmis::Content( m_xContext, m_pProvider, xId, !create_document );
    1528             :         }
    1529           0 :         catch ( ucb::ContentCreationException & )
    1530             :         {
    1531           0 :             return uno::Reference< ucb::XContent >();
    1532           0 :         }
    1533             :     }
    1534             : 
    1535           0 :     uno::Sequence< uno::Type > SAL_CALL Content::getTypes() throw( uno::RuntimeException )
    1536             :     {
    1537           0 :         if ( isFolder( uno::Reference< ucb::XCommandEnvironment >() ) )
    1538             :         {
    1539             :             static cppu::OTypeCollection aFolderCollection
    1540           0 :                 (CPPU_TYPE_REF( lang::XTypeProvider ),
    1541           0 :                  CPPU_TYPE_REF( lang::XServiceInfo ),
    1542           0 :                  CPPU_TYPE_REF( lang::XComponent ),
    1543           0 :                  CPPU_TYPE_REF( ucb::XContent ),
    1544           0 :                  CPPU_TYPE_REF( ucb::XCommandProcessor ),
    1545           0 :                  CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
    1546           0 :                  CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
    1547           0 :                  CPPU_TYPE_REF( beans::XPropertyContainer ),
    1548           0 :                  CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
    1549           0 :                  CPPU_TYPE_REF( container::XChild ),
    1550           0 :                  CPPU_TYPE_REF( ucb::XContentCreator ) );
    1551           0 :             return aFolderCollection.getTypes();
    1552             :         }
    1553             :         else
    1554             :         {
    1555             :             static cppu::OTypeCollection aFileCollection
    1556           0 :                 (CPPU_TYPE_REF( lang::XTypeProvider ),
    1557           0 :                  CPPU_TYPE_REF( lang::XServiceInfo ),
    1558           0 :                  CPPU_TYPE_REF( lang::XComponent ),
    1559           0 :                  CPPU_TYPE_REF( ucb::XContent ),
    1560           0 :                  CPPU_TYPE_REF( ucb::XCommandProcessor ),
    1561           0 :                  CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
    1562           0 :                  CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
    1563           0 :                  CPPU_TYPE_REF( beans::XPropertyContainer ),
    1564           0 :                  CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
    1565           0 :                  CPPU_TYPE_REF( container::XChild ) );
    1566             : 
    1567           0 :             return aFileCollection.getTypes();
    1568             :         }
    1569             :     }
    1570             : 
    1571             : 
    1572           0 :     uno::Sequence< ucb::ContentInfo > Content::queryCreatableContentsInfo(
    1573             :         const uno::Reference< ucb::XCommandEnvironment >& xEnv)
    1574             :             throw( uno::RuntimeException )
    1575             :     {
    1576           0 :         if ( isFolder( xEnv ) )
    1577             :         {
    1578           0 :             uno::Sequence< ucb::ContentInfo > seq(2);
    1579             : 
    1580             :             // Minimum set of props we really need
    1581           0 :             uno::Sequence< beans::Property > props( 1 );
    1582           0 :             props[0] = beans::Property(
    1583             :                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Title")),
    1584             :                 -1,
    1585           0 :                 getCppuType( static_cast< rtl::OUString* >( 0 ) ),
    1586           0 :                 beans::PropertyAttribute::MAYBEVOID | beans::PropertyAttribute::BOUND );
    1587             : 
    1588             :             // file
    1589           0 :             seq[0].Type       = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CMIS_FILE_TYPE ));
    1590           0 :             seq[0].Attributes = ( ucb::ContentInfoAttribute::INSERT_WITH_INPUTSTREAM |
    1591           0 :                                   ucb::ContentInfoAttribute::KIND_DOCUMENT );
    1592           0 :             seq[0].Properties = props;
    1593             : 
    1594             :             // folder
    1595           0 :             seq[1].Type       = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CMIS_FOLDER_TYPE ));
    1596           0 :             seq[1].Attributes = ucb::ContentInfoAttribute::KIND_FOLDER;
    1597           0 :             seq[1].Properties = props;
    1598             : 
    1599           0 :             return seq;
    1600             :         }
    1601             :         else
    1602             :         {
    1603           0 :             return uno::Sequence< ucb::ContentInfo >();
    1604             :         }
    1605             :     }
    1606             : 
    1607           0 :     list< uno::Reference< ucb::XContent > > Content::getChildren( )
    1608             :     {
    1609           0 :         list< uno::Reference< ucb::XContent > > results;
    1610             :         SAL_INFO( "cmisucp", "Content::getChildren() " << m_sURL );
    1611             : 
    1612           0 :         libcmis::Folder* pFolder = dynamic_cast< libcmis::Folder* >( getObject( uno::Reference< ucb::XCommandEnvironment >() ).get( ) );
    1613           0 :         if ( NULL != pFolder )
    1614             :         {
    1615             :             // Get the children from pObject
    1616             :             try
    1617             :             {
    1618           0 :                 vector< libcmis::ObjectPtr > children = pFolder->getChildren( );
    1619             : 
    1620             :                 // Loop over the results
    1621           0 :                 for ( vector< libcmis::ObjectPtr >::iterator it = children.begin();
    1622           0 :                         it != children.end(); ++it )
    1623             :                 {
    1624             :                     // TODO Cache the objects
    1625             : 
    1626           0 :                     URL aUrl( m_sURL );
    1627           0 :                     rtl::OUString sPath( m_sObjectPath );
    1628           0 :                     if ( sPath[sPath.getLength( ) - 1] != '/' )
    1629           0 :                         sPath += "/";
    1630           0 :                     sPath += STD_TO_OUSTR( ( *it )->getName( ) );
    1631           0 :                     aUrl.setObjectPath( sPath );
    1632           0 :                     uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aUrl.asString( ) );
    1633           0 :                     uno::Reference< ucb::XContent > xContent = new Content( m_xContext, m_pProvider, xId, *it );
    1634             : 
    1635           0 :                     results.push_back( xContent );
    1636           0 :                 }
    1637             :             }
    1638           0 :             catch ( const libcmis::Exception& e )
    1639             :             {
    1640             :                 SAL_INFO( "cmisucp", "Exception thrown: " << e.what() );
    1641             :             }
    1642             :         }
    1643             : 
    1644           0 :         return results;
    1645             :     }
    1646             : 
    1647           0 :     void Content::setCmisProperty( std::string sName, std::string sValue, const uno::Reference< ucb::XCommandEnvironment >& xEnv )
    1648             :     {
    1649           0 :         if ( getObjectType( xEnv ).get( ) )
    1650             :         {
    1651           0 :             map< string, libcmis::PropertyPtr >::iterator propIt = m_pObjectProps.find( sName );
    1652           0 :             vector< string > values;
    1653           0 :             values.push_back( sValue );
    1654             : 
    1655           0 :             if ( propIt == m_pObjectProps.end( ) && getObjectType( xEnv ).get( ) )
    1656             :             {
    1657           0 :                 map< string, libcmis::PropertyTypePtr > propsTypes = getObjectType( xEnv )->getPropertiesTypes( );
    1658           0 :                 map< string, libcmis::PropertyTypePtr >::iterator typeIt = propsTypes.find( sName );
    1659             : 
    1660           0 :                 if ( typeIt != propsTypes.end( ) )
    1661             :                 {
    1662           0 :                     libcmis::PropertyTypePtr propType = typeIt->second;
    1663           0 :                     libcmis::PropertyPtr property( new libcmis::Property( propType, values ) );
    1664           0 :                     m_pObjectProps.insert( pair< string, libcmis::PropertyPtr >( sName, property ) );
    1665           0 :                 }
    1666             :             }
    1667           0 :             else if ( propIt != m_pObjectProps.end( ) )
    1668             :             {
    1669           0 :                 propIt->second->setValues( values );
    1670           0 :             }
    1671             :         }
    1672           0 :     }
    1673           0 : }
    1674             : 
    1675             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10