[Libreoffice-commits] .: 13 commits - fpicker/source libcmis/ExternalLib_libcmis.mk libcmis/libcmis-0001-virtualdtor.patch libcmis/libcmis-0.1.0-autotools.patch libcmis/libcmis-0.1.0-non-virtual-dtor.patch libcmis/libcmis-0.1.0.patch libcmis/Makefile libcmis/makefile.mk libcmis/Module_libcmis.mk officecfg/registry ooo.lst.in RepositoryExternal.mk sfx2/source svtools/inc svtools/source tools/qa tools/source ucbhelper/inc ucbhelper/Library_ucbhelper.mk ucbhelper/Package_inc.mk ucbhelper/source ucb/Library_ucpcmis1.mk ucb/source

Cédric Bosdonnat cbosdo at kemper.freedesktop.org
Mon Jun 4 04:55:39 PDT 2012


 RepositoryExternal.mk                                        |   22 
 fpicker/source/office/PlaceEditDialog.cxx                    |   25 
 fpicker/source/office/PlaceEditDialog.hrc                    |    4 
 fpicker/source/office/PlaceEditDialog.hxx                    |    5 
 fpicker/source/office/PlaceEditDialog.src                    |   25 
 fpicker/source/office/ServerDetailsControls.cxx              |   45 
 fpicker/source/office/ServerDetailsControls.hxx              |   10 
 fpicker/source/office/fpsmartcontent.cxx                     |   40 
 fpicker/source/office/fpsmartcontent.hxx                     |    9 
 fpicker/source/office/iodlg.cxx                              |   16 
 fpicker/source/office/iodlg.src                              |    2 
 libcmis/ExternalLib_libcmis.mk                               |   55 
 libcmis/Makefile                                             |    7 
 libcmis/Module_libcmis.mk                                    |   35 
 libcmis/libcmis-0.1.0-autotools.patch                        |   52 
 libcmis/libcmis-0.1.0-non-virtual-dtor.patch                 |   11 
 libcmis/libcmis-0.1.0.patch                                  |   43 
 libcmis/libcmis-0001-virtualdtor.patch                       |   22 
 libcmis/makefile.mk                                          |   16 
 officecfg/registry/data/org/openoffice/ucb/Configuration.xcu |    6 
 ooo.lst.in                                                   |    2 
 sfx2/source/doc/docfile.cxx                                  |   28 
 svtools/inc/svtools/fileview.hxx                             |    2 
 svtools/source/contnr/fileview.cxx                           |   22 
 tools/qa/cppunit/test_urlobj.cxx                             |   31 
 tools/source/fsys/urlobj.cxx                                 |   46 
 ucb/Library_ucpcmis1.mk                                      |    3 
 ucb/source/ucp/cmis/cmis_content.cxx                         |  687 ++++++++---
 ucb/source/ucp/cmis/cmis_content.hxx                         |   22 
 ucb/source/ucp/cmis/cmis_datasupplier.cxx                    |  248 +++
 ucb/source/ucp/cmis/cmis_datasupplier.hxx                    |   84 +
 ucb/source/ucp/cmis/cmis_provider.cxx                        |   31 
 ucb/source/ucp/cmis/cmis_provider.hxx                        |    7 
 ucb/source/ucp/cmis/cmis_resultset.cxx                       |   44 
 ucb/source/ucp/cmis/cmis_resultset.hxx                       |   39 
 ucb/source/ucp/cmis/cmis_url.cxx                             |   88 -
 ucb/source/ucp/cmis/cmis_url.hxx                             |   16 
 ucbhelper/Library_ucbhelper.mk                               |    2 
 ucbhelper/Package_inc.mk                                     |    2 
 ucbhelper/inc/ucbhelper/std_inputstream.hxx                  |  119 +
 ucbhelper/inc/ucbhelper/std_outputstream.hxx                 |   73 +
 ucbhelper/source/provider/std_inputstream.cxx                |  187 ++
 ucbhelper/source/provider/std_outputstream.cxx               |   98 +
 43 files changed, 1875 insertions(+), 456 deletions(-)

New commits:
commit b48db7bc94b02a3b8bb7d173454c6e67139b0739
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Mon Jun 4 10:40:29 2012 +0200

    Updated libcmis to 0.2.1
    
    Change-Id: I9ee6283a7f4a0b436ea89c7bd16af756c6aa36e4

diff --git a/libcmis/makefile.mk b/libcmis/makefile.mk
index f124df2..4657202 100644
--- a/libcmis/makefile.mk
+++ b/libcmis/makefile.mk
@@ -41,8 +41,8 @@ TARGET=cmis
     @echo "Using system libcmis..."
 .ENDIF
 
-TARFILE_NAME=libcmis-0.2.0
-TARFILE_MD5=36c168b03593dfa386fba23a0c32d11b
+TARFILE_NAME=libcmis-0.2.1
+TARFILE_MD5=aba670de3beaafac1e287a9399dcc023
 
 .IF "$(debug)" != ""
 CFLAGS+=-g
diff --git a/ooo.lst.in b/ooo.lst.in
index d344b8e..98eb1ea 100644
--- a/ooo.lst.in
+++ b/ooo.lst.in
@@ -88,7 +88,7 @@ f02578f5218f217a9f20e9c30e119c6a-boost_1_44_0.tar.bz2
 3bf481ca95109b14435125c0dd1f2217-graphite2-1.0.3.tgz
 90010e213dd25648e70f0cc12f8fed55-libvisio-0.0.17.tar.bz2
 e7a384790b13c29113e22e596ade9687-LinLibertineG-20120116.zip
-7c2549f6b0a8bb604e6c4c729ffdcfe6-libcmis-0.1.0.tar.gz
+aba670de3beaafac1e287a9399dcc023-libcmis-0.2.1.tar.gz
 c216ded0275129ccfef44fbc236ac16a-libcdr-0.0.7.tar.bz2
 327348d67c979c88c2dec59a23a17d85-lcms2-2.3.tar.gz
 @GOOGLE_DOCS_EXTENSION_PACK@
commit fd32788092fcb29526ae73ae3bae6767dbb1e490
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Mon Jun 4 10:13:17 2012 +0200

    CMIS UCP: changed URLs to have hierarchical path
    
    Hierarchical path is assumed in loads of places, changed the URLs to the
    following:
      * Binding URL is encoded in the authority part, the repository ID is
        set as a fragment of the binding URL.
      * The hierarchical path reflects one of the path to the document on
        the server
    :x
    
    Change-Id: I8214daeb1d9c9b0f6ab86bdf60875e7e4e5369f4

diff --git a/fpicker/source/office/ServerDetailsControls.cxx b/fpicker/source/office/ServerDetailsControls.cxx
index ae52de4..dc31dc5 100644
--- a/fpicker/source/office/ServerDetailsControls.cxx
+++ b/fpicker/source/office/ServerDetailsControls.cxx
@@ -26,6 +26,8 @@
  * instead of those above.
  */
 
+#include <rtl/uri.hxx>
+
 #include "PlaceEditDialog.hrc"
 
 #include "fpsofficeResMgr.hxx"
@@ -279,10 +281,13 @@ INetURLObject CmisDetailsContainer::getUrl( )
     rtl::OUString sUrl;
     if ( !sBindingUrl.isEmpty( ) && !sRepo.isEmpty() )
     {
-        sal_Int32 pos = sBindingUrl.indexOf( rtl::OUString::createFromAscii( "://" ) );
-        if ( pos > 0 )
-            sBindingUrl = sBindingUrl.copy( pos + 3 );
-        sUrl = "cmis+atom://" + sBindingUrl + "?repo-id=" + sRepo;
+        rtl::OUString sEncodedBinding = rtl::Uri::encode(
+                sBindingUrl + "#" + sRepo,
+                rtl_UriCharClassUricNoSlash,
+                rtl_UriEncodeKeepEscapes,
+                RTL_TEXTENCODING_UTF8 );
+        sUrl = "vnd.libreoffice.cmis+atom://" + sEncodedBinding;
+        INetURLObject test( sUrl );
     }
 
     return INetURLObject( sUrl );
@@ -294,38 +299,13 @@ bool CmisDetailsContainer::setUrl( const INetURLObject& rUrl )
 
     if ( bSuccess )
     {
-        rtl::OUString sBindingUrl( "http://" );
-        sBindingUrl += rUrl.GetHost( );
-        if ( rUrl.HasPort( ) )
-            sBindingUrl += rtl::OUString::valueOf( sal_Int32( rUrl.GetPort( ) ) );
-        sBindingUrl += rUrl.GetURLPath( );
-
-        // Split the query into bits and locate the repo-id key
-        rtl::OUString sQuery = rUrl.GetParam( );
+        rtl::OUString sBindingUrl;
         rtl::OUString sRepositoryId;
 
-        while ( !sQuery.isEmpty() )
-        {
-            sal_Int32 nPos = sQuery.indexOfAsciiL( "&", 1 );
-            rtl::OUString sSegment;
-            if ( nPos > 0 )
-            {
-                sSegment = sQuery.copy( 0, nPos );
-                sQuery = sQuery.copy( nPos + 1 );
-            }
-            else
-            {
-                sSegment = sQuery;
-                sQuery = rtl::OUString();
-            }
-
-            sal_Int32 nEqPos = sSegment.indexOfAsciiL( "=", 1 );
-            rtl::OUString key = sSegment.copy( 0, nEqPos );
-            rtl::OUString value = sSegment.copy( nEqPos +1 );
-
-            if ( key == "repo-id" )
-                sRepositoryId = value;
-        }
+        rtl::OUString sDecodedHost = rUrl.GetHost( INetURLObject::DECODE_WITH_CHARSET );
+        INetURLObject aHostUrl( sDecodedHost );
+        sBindingUrl = aHostUrl.GetURLNoMark( );
+        sRepositoryId = aHostUrl.GetMark( );
 
         static_cast< Edit* >( getControl( ED_ADDPLACE_CMIS_BINDING ) )->SetText( sBindingUrl );
         static_cast< Edit* >( getControl( ED_ADDPLACE_CMIS_REPOSITORY ) )->SetText( sRepositoryId );
diff --git a/officecfg/registry/data/org/openoffice/ucb/Configuration.xcu b/officecfg/registry/data/org/openoffice/ucb/Configuration.xcu
index 58d6e41..198a660 100644
--- a/officecfg/registry/data/org/openoffice/ucb/Configuration.xcu
+++ b/officecfg/registry/data/org/openoffice/ucb/Configuration.xcu
@@ -26,7 +26,7 @@
  *
  ************************************************************************ -->
 <!DOCTYPE oor:component-data SYSTEM "../../../../component-update.dtd">
-<oor:component-data oor:name="Configuration" oor:package="org.openoffice.ucb" xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" oor:name="Configuration" oor:package="org.openoffice.ucb">
   <node oor:name="ContentProviders">
     <node oor:name="Local" oor:op="replace">
       <node oor:name="SecondaryKeys">
@@ -202,14 +202,14 @@
                 <value>com.sun.star.ucb.CmisContentProvider</value>
               </prop>
               <prop oor:name="URLTemplate">
-                <value>cmis+atom</value>
+                <value>vnd.libreoffice.cmis+atom</value>
               </prop>
               <prop oor:name="Arguments">
                 <value/>
               </prop>
             </node>
             <!-- We want the Provider to be the final fallback provider -->
-            <node oor:name="Provider999" oor:op="replace" install:module="gio">
+            <node oor:name="Provider999" oor:op="replace" module="gio">
               <prop oor:name="ServiceName">
                 <value>com.sun.star.ucb.GIOContentProvider</value>
               </prop>
diff --git a/tools/qa/cppunit/test_urlobj.cxx b/tools/qa/cppunit/test_urlobj.cxx
index da11113..0a3a714 100644
--- a/tools/qa/cppunit/test_urlobj.cxx
+++ b/tools/qa/cppunit/test_urlobj.cxx
@@ -245,14 +245,29 @@ namespace tools_urlobj
 
         void urlobjCmisTest(  )
         {
-            INetURLObject aUrl( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
-                            "cmis+atom://foo.bar.com:8080/my%2Fcmis%2Fatom/path/to/content" ) ) );
-            CPPUNIT_ASSERT_EQUAL( std::string( "foo.bar.com" ),
-                    OUSTR_TO_STDSTR( aUrl.GetHost( INetURLObject::NO_DECODE ) ) );
-            CPPUNIT_ASSERT( aUrl.GetPort(  ) == 8080 );
-            CPPUNIT_ASSERT_EQUAL( std::string( "/my%2Fcmis%2Fatom/path/to/content" ),
-                    OUSTR_TO_STDSTR( aUrl.GetURLPath( INetURLObject::NO_DECODE ) ) );
-            CPPUNIT_ASSERT_EQUAL_MESSAGE( "Wrong protocol found", INET_PROT_CMIS_ATOM, aUrl.GetProtocol(  ) );
+            // Test with a username part
+            {
+                INetURLObject aUrl( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+                                "vnd.libreoffice.cmis+atom://username@http:%2F%2Ffoo.bar.com:8080%2Fmy%2Fcmis%2Fatom%23repo-id-encoded/path/to/content" ) ) );
+                CPPUNIT_ASSERT_EQUAL( std::string( "http://foo.bar.com:8080/my/cmis/atom#repo-id-encoded" ),
+                        OUSTR_TO_STDSTR( aUrl.GetHost( INetURLObject::DECODE_WITH_CHARSET ) ) );
+                CPPUNIT_ASSERT_EQUAL( std::string( "username" ), OUSTR_TO_STDSTR( aUrl.GetUser( ) ) );
+                CPPUNIT_ASSERT_EQUAL( std::string( "/path/to/content" ),
+                        OUSTR_TO_STDSTR( aUrl.GetURLPath( INetURLObject::NO_DECODE ) ) );
+                CPPUNIT_ASSERT_EQUAL_MESSAGE( "Wrong protocol found", INET_PROT_CMIS_ATOM, aUrl.GetProtocol(  ) );
+            }
+
+            // Test without a username part
+            {
+                INetURLObject aUrl( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+                                "vnd.libreoffice.cmis+atom://http:%2F%2Ffoo.bar.com:8080%2Fmy%2Fcmis%2Fatom%23repo-id-encoded/path/to/content" ) ) );
+                CPPUNIT_ASSERT_EQUAL( std::string( "http://foo.bar.com:8080/my/cmis/atom#repo-id-encoded" ),
+                        OUSTR_TO_STDSTR( aUrl.GetHost( INetURLObject::DECODE_WITH_CHARSET ) ) );
+                CPPUNIT_ASSERT( !aUrl.HasUserData() );
+                CPPUNIT_ASSERT_EQUAL( std::string( "/path/to/content" ),
+                        OUSTR_TO_STDSTR( aUrl.GetURLPath( INetURLObject::NO_DECODE ) ) );
+                CPPUNIT_ASSERT_EQUAL_MESSAGE( "Wrong protocol found", INET_PROT_CMIS_ATOM, aUrl.GetProtocol(  ) );
+            }
         }
 
         // Change the following lines only, if you add, remove or rename
diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx
index 49477eb..eb125fe 100644
--- a/tools/source/fsys/urlobj.cxx
+++ b/tools/source/fsys/urlobj.cxx
@@ -428,8 +428,8 @@ static INetURLObject::SchemeInfo const aSchemeInfoMap[INET_PROT_END]
           false, true },
         { "sftp", "sftp://", 22, true, true, false, true, true, true, true,
           true },
-        { "cmis+atom", "cmis+atom://", 0, true, true, false,
-          true, true, true, true, true } };
+        { "vnd.libreoffice.cmis+atom", "vnd.libreoffice.cmis+atom://", 0, true, true, false,
+          false, true, false, true, true } };
 
 
 // static
@@ -957,6 +957,7 @@ bool INetURLObject::setAbsURIRef(rtl::OUString const & rTheAbsURIRef,
             }
 
             case INET_PROT_VND_SUN_STAR_PKG:
+            case INET_PROT_CMIS_ATOM:
             {
                 if (pEnd - pPos < 2 || *pPos++ != '/' || *pPos++ != '/')
                 {
@@ -964,8 +965,10 @@ bool INetURLObject::setAbsURIRef(rtl::OUString const & rTheAbsURIRef,
                     return false;
                 }
                 aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
-                rtl::OUStringBuffer aSynAuthority;
-                while (pPos < pEnd
+                rtl::OUStringBuffer aSynUser;
+
+                bool bHasUser = false;
+                while (pPos < pEnd && *pPos != '@'
                        && *pPos != '/' && *pPos != '?'
                        && *pPos != nFragmentDelimiter)
                 {
@@ -973,9 +976,38 @@ bool INetURLObject::setAbsURIRef(rtl::OUString const & rTheAbsURIRef,
                     sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
                                                  cEscapePrefix, eMechanism,
                                                  eCharset, eEscapeType);
-                    appendUCS4(aSynAuthority, nUTF32, eEscapeType, bOctets,
-                               PART_AUTHORITY, cEscapePrefix, eCharset,
+                    appendUCS4(aSynUser, nUTF32, eEscapeType, bOctets,
+                               PART_USER_PASSWORD, cEscapePrefix, eCharset,
                                false);
+
+                    bHasUser = *pPos == '@';
+                }
+
+                rtl::OUStringBuffer aSynAuthority;
+                if ( !bHasUser )
+                {
+                    aSynAuthority = aSynUser;
+                }
+                else
+                {
+                    m_aUser.set(aSynAbsURIRef,
+                            aSynUser.makeStringAndClear(),
+                            aSynAbsURIRef.getLength());
+                    aSynAbsURIRef.appendAscii(RTL_CONSTASCII_STRINGPARAM("@"));
+                    ++pPos;
+
+                    while (pPos < pEnd
+                           && *pPos != '/' && *pPos != '?'
+                           && *pPos != nFragmentDelimiter)
+                    {
+                        EscapeType eEscapeType;
+                        sal_uInt32 nUTF32 = getUTF32(pPos, pEnd, bOctets,
+                                                     cEscapePrefix, eMechanism,
+                                                     eCharset, eEscapeType);
+                        appendUCS4(aSynAuthority, nUTF32, eEscapeType, bOctets,
+                                   PART_AUTHORITY, cEscapePrefix, eCharset,
+                                   false);
+                    }
                 }
                 if (aSynAuthority.getLength() == 0)
                 {
@@ -2133,7 +2165,6 @@ INetURLObject::getPrefix(sal_Unicode const *& rBegin,
             { ".uno:", "staroffice.uno:", INET_PROT_UNO,
               PrefixInfo::INTERNAL },
             { "cid:", 0, INET_PROT_CID, PrefixInfo::OFFICIAL },
-            { "cmis+atom:", 0, INET_PROT_CMIS_ATOM, PrefixInfo::INTERNAL },
             { "data:", 0, INET_PROT_DATA, PrefixInfo::OFFICIAL },
             { "db:", "staroffice.db:", INET_PROT_DB, PrefixInfo::INTERNAL },
             { "file:", 0, INET_PROT_FILE, PrefixInfo::OFFICIAL },
@@ -2203,6 +2234,7 @@ INetURLObject::getPrefix(sal_Unicode const *& rBegin,
             { "telnet:", 0, INET_PROT_TELNET, PrefixInfo::OFFICIAL },
             { "vim:", "staroffice.vim:", INET_PROT_VIM,
               PrefixInfo::INTERNAL },
+            { "vnd.libreoffice.cmis+atom:", 0, INET_PROT_CMIS_ATOM, PrefixInfo::INTERNAL },
             { "vnd.sun.star.cmd:", 0, INET_PROT_VND_SUN_STAR_CMD,
               PrefixInfo::OFFICIAL },
             { "vnd.sun.star.expand:", 0, INET_PROT_VND_SUN_STAR_EXPAND,
diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx
index d40deab..b25e1ac 100644
--- a/ucb/source/ucp/cmis/cmis_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_content.cxx
@@ -171,7 +171,7 @@ namespace cmis
             pProvider->registerSession( url.getBindingUrl( ), m_pSession );
         }
 
-        m_sObjectId = url.getObjectId( );
+        m_sObjectPath = url.getObjectPath( );
         m_sBindingUrl = url.getBindingUrl( );
     }
 
@@ -197,7 +197,7 @@ namespace cmis
             pProvider->registerSession( url.getBindingUrl( ), m_pSession );
         }
 
-        m_sObjectId = url.getObjectId( );
+        m_sObjectPath = url.getObjectPath( );
         m_sBindingUrl = url.getBindingUrl( );
 
         // Get the object type
@@ -215,12 +215,12 @@ namespace cmis
         {
             if ( !m_pObject.get() )
             {
-                if ( !m_sObjectId.isEmpty( ) )
-                    m_pObject = m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
+                if ( !m_sObjectPath.isEmpty( ) )
+                    m_pObject = m_pSession->getObjectByPath( OUSTR_TO_STDSTR( m_sObjectPath ) );
                 else
                 {
                     m_pObject = m_pSession->getRootFolder( );
-                    m_sObjectId = rtl::OUString::createFromAscii( m_pObject->getId( ).c_str( ) );
+                    m_sObjectPath = "/";
                 }
             }
         }
@@ -283,29 +283,48 @@ namespace cmis
             }
             else if ( rProp.Name == "Title" )
             {
-                string name = getObject()->getName();
-                xRow->appendString( rProp, rtl::OUString::createFromAscii( name.c_str() ) );
+                rtl::OUString sTitle;
+                if ( getObject() )
+                    sTitle = rtl::OUString::createFromAscii( getObject()->getName().c_str( ) );
+                else if ( m_pObjectProps.size() > 0 )
+                {
+                    map< string, libcmis::PropertyPtr >::iterator it = m_pObjectProps.find( "cmis:name" );
+                    if ( it != m_pObjectProps.end( ) )
+                    {
+                        vector< string > values = it->second->getStrings( );
+                        if ( values.size() > 0 )
+                            sTitle = rtl::OUString::createFromAscii( values.front( ).c_str( ) );
+                    }
+                }
+
+                // Nothing worked... get it from the path
+                if ( sTitle.isEmpty( ) )
+                {
+                    rtl::OUString sPath = m_sObjectPath;
+
+                    // Get rid of the trailing slash problem
+                    if ( sPath[ sPath.getLength( ) - 1 ] == '/' )
+                        sPath = sPath.copy( 0, sPath.getLength() - 1 );
+
+                    // Get the last segment
+                    sal_Int32 nPos = sPath.lastIndexOf( '/' );
+                    if ( nPos > 0 )
+                        sTitle = sPath.copy( nPos + 1 );
+                }
+
+                if ( !sTitle.isEmpty( ) )
+                    xRow->appendString( rProp, sTitle );
+                else
+                    xRow->appendVoid( rProp );
             }
             else if ( rProp.Name == "TitleOnServer" )
             {
                 string path;
-                libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject().get( ) );
-                if ( NULL != document )
-                {
-                    vector< boost::shared_ptr< libcmis::Folder > > parents = document->getParents( );
-                    if ( parents.size() > 0 )
-                        path = parents.front( )->getPath( );
-
-                    if ( path[ path.length() - 1 ] != '/' )
-                        path += "/";
-                    path += getObject()->getName( );
-                }
+                vector< string > paths = getObject( )->getPaths( );
+                if ( paths.size( ) > 0 )
+                    path = paths.front( );
                 else
-                {
-                    libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( getObject().get( ) );
-                    if ( NULL != folder )
-                        path = folder->getPath( );
-                }
+                    path = getObject()->getName( );
 
                 xRow->appendString( rProp, rtl::OUString::createFromAscii( path.c_str() ) );
             }
@@ -352,8 +371,8 @@ namespace cmis
         bool bExists = true;
         try
         {
-            if ( !m_sObjectId.isEmpty( ) )
-                libcmis::ObjectPtr object = m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
+            if ( !m_sObjectPath.isEmpty( ) )
+                m_pSession->getObjectByPath( OUSTR_TO_STDSTR( m_sObjectPath ) );
             // No need to handle the root folder case... how can it not exists?
         }
         catch ( const libcmis::Exception& )
@@ -479,7 +498,7 @@ namespace cmis
             // For transient content, the URL is the one of the parent
             if ( m_bTransient )
             {
-                string sNewId;
+                rtl::OUString sNewPath;
 
                 // Try to get the object from the server if there is any
                 libcmis::Folder* pFolder = dynamic_cast< libcmis::Folder* >( getObject( ).get( ) );
@@ -503,7 +522,7 @@ namespace cmis
                     try
                     {
                         object = m_pSession->getObjectByPath( newPath );
-                        sNewId = object->getId( );
+                        sNewPath = rtl::OUString::createFromAscii( newPath.c_str( ) );
                     }
                     catch ( const libcmis::Exception& )
                     {
@@ -540,7 +559,7 @@ namespace cmis
                         if ( bIsFolder )
                         {
                             libcmis::FolderPtr pNew = pFolder->createFolder( m_pObjectProps );
-                            sNewId = pNew->getId( );
+                            sNewPath = rtl::OUString::createFromAscii( newPath.c_str( ) );
                         }
                         else
                         {
@@ -548,16 +567,16 @@ namespace cmis
                             uno::Reference < io::XOutputStream > xOutput = new ucbhelper::StdOutputStream( pOut );
                             copyData( xInputStream, xOutput );
                             libcmis::DocumentPtr pNew = pFolder->createDocument( m_pObjectProps, pOut, string() );
-                            sNewId = pNew->getId( );
+                            sNewPath = rtl::OUString::createFromAscii( newPath.c_str( ) );
                         }
                     }
 
-                    if ( !sNewId.empty( ) )
+                    if ( !sNewPath.isEmpty( ) )
                     {
                         // Update the current content: it's no longer transient
-                        m_sObjectId = rtl::OUString::createFromAscii( sNewId.c_str( ) );
+                        m_sObjectPath = sNewPath;
                         URL aUrl( m_sURL );
-                        aUrl.setObjectId( m_sObjectId );
+                        aUrl.setObjectPath( m_sObjectPath );
                         m_sURL = aUrl.asString( );
                         m_pObject.reset( );
                         m_pObjectType.reset( );
@@ -790,8 +809,7 @@ namespace cmis
 
         SAL_INFO( "cmisucp", "Content::getParentURL()" );
 
-        string parentId;
-
+        string parentPath;
         try
         {
             libcmis::ObjectPtr pObj = getObject( );
@@ -800,25 +818,25 @@ namespace cmis
             {
                 vector< boost::shared_ptr< libcmis::Folder > > parents = document->getParents( );
                 if ( parents.size( ) > 0 )
-                    parentId = parents.front( )->getId( );
+                    parentPath = parents.front( )->getPath( );
             }
             else
             {
                 libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( getObject( ).get( ) );
                 if ( NULL != folder )
-                    parentId = folder->getFolderParent( )->getId( );
+                    parentPath = folder->getFolderParent( )->getPath( );
             }
         }
         catch ( const libcmis::Exception & )
         {
             // We may have an exception if we don't have the rights to
-            // get the parent ID
+            // get the parents
         }
 
-        if ( !parentId.empty() )
+        if ( !parentPath.empty() )
         {
             URL aUrl( m_sURL );
-            aUrl.setObjectId( rtl::OUString::createFromAscii( parentId.c_str( ) ) );
+            aUrl.setObjectPath( rtl::OUString::createFromAscii( parentPath.c_str( ) ) );
             sRet = aUrl.asString( );
         }
 
diff --git a/ucb/source/ucp/cmis/cmis_content.hxx b/ucb/source/ucp/cmis/cmis_content.hxx
index eafd503..21ec1d1 100644
--- a/ucb/source/ucp/cmis/cmis_content.hxx
+++ b/ucb/source/ucp/cmis/cmis_content.hxx
@@ -71,7 +71,7 @@ private:
     ContentProvider*       m_pProvider;
     libcmis::Session*      m_pSession;
     libcmis::ObjectPtr     m_pObject;
-    rtl::OUString          m_sObjectId;
+    rtl::OUString          m_sObjectPath;
     rtl::OUString          m_sURL;
     rtl::OUString          m_sBindingUrl;
 
diff --git a/ucb/source/ucp/cmis/cmis_datasupplier.cxx b/ucb/source/ucp/cmis/cmis_datasupplier.cxx
index 2a82a9b..59ffd73 100644
--- a/ucb/source/ucp/cmis/cmis_datasupplier.cxx
+++ b/ucb/source/ucp/cmis/cmis_datasupplier.cxx
@@ -90,11 +90,15 @@ namespace cmis
 
         if ( getResult( nIndex ) )
         {
-            string sObjectId = maResults[nIndex]->pObject->getId( );
+            string sObjectPath;
+            vector< string > paths = maResults[nIndex]->pObject->getPaths( );
+            if ( paths.size( ) > 0 )
+                sObjectPath = paths.front( );
+            // TODO Handle the unfiled objects with their id... but can they manage to come here?
 
-            // Get the URL from the Id
+            // Get the URL from the Path
             URL aUrl( mxContent->getIdentifier( )->getContentIdentifier( ) );
-            aUrl.setObjectId( rtl::OUString::createFromAscii( sObjectId.c_str( ) ) );
+            aUrl.setObjectPath( rtl::OUString::createFromAscii( sObjectPath.c_str( ) ) );
             rtl::OUString aId = aUrl.asString( );
 
             maResults[ nIndex ]->aId = aId;
diff --git a/ucb/source/ucp/cmis/cmis_url.cxx b/ucb/source/ucp/cmis/cmis_url.cxx
index df22501..aed136b 100644
--- a/ucb/source/ucp/cmis/cmis_url.cxx
+++ b/ucb/source/ucp/cmis/cmis_url.cxx
@@ -28,6 +28,8 @@
 
 #include <libcmis/session-factory.hxx>
 
+#include <rtl/uri.hxx>
+
 #include "cmis_url.hxx"
 
 using namespace std;
@@ -37,42 +39,24 @@ using namespace std;
 
 namespace cmis
 {
-    URL::URL( rtl::OUString const & urlStr ) :
-        m_aUrl( urlStr )
+    URL::URL( rtl::OUString const & urlStr )
     {
+        rtl::OUString sBindingUrl;
+        rtl::OUString sRepositoryId;
+
+        INetURLObject aUrl( urlStr );
+
+        // Decode the authority to get the binding URL and repository id
+        rtl::OUString sDecodedHost = aUrl.GetHost( INetURLObject::DECODE_WITH_CHARSET );
+        INetURLObject aHostUrl( sDecodedHost );
+        m_sBindingUrl = aHostUrl.GetURLNoMark( );
+        m_sRepositoryId = aHostUrl.GetMark( );
 
-        rtl::OUString bindingUrl( "http://" );
-        bindingUrl += m_aUrl.GetHostPort( );
-        bindingUrl += m_aUrl.GetURLPath( );
-        m_sBindingUrl = bindingUrl;
-
-        // Split the query into bits and locate the repo-id key
-        rtl::OUString query = m_aUrl.GetParam( );
-        while ( !query.isEmpty() )
-        {
-            sal_Int32 nPos = query.indexOfAsciiL( "&", 1 );
-            rtl::OUString segment;
-            if ( nPos > 0 )
-            {
-                segment = query.copy( 0, nPos );
-                query = query.copy( nPos + 1 );
-            }
-            else
-            {
-                segment = query;
-                query = rtl::OUString();
-            }
-
-            sal_Int32 nEqPos = segment.indexOfAsciiL( "=", 1 );
-            rtl::OUString key = segment.copy( 0, nEqPos );
-            rtl::OUString value = segment.copy( nEqPos +1 );
-
-            if ( key == "repo-id" )
-                m_sRepositoryId = value;
-            else
-                m_aQuery[key] = value;
-        }
+        m_sUser = aUrl.GetUser( );
+        m_sPass = aUrl.GetPass( );
 
+        // Store the path to the object
+        m_sPath = aUrl.GetURLPath( INetURLObject::DECODE_WITH_CHARSET );
     }
 
     map< int, string > URL::getSessionParams( )
@@ -80,19 +64,15 @@ namespace cmis
         map< int, string > params;
         params[ATOMPUB_URL] = OUSTR_TO_STDSTR( m_sBindingUrl );
         params[REPOSITORY_ID] = OUSTR_TO_STDSTR( m_sRepositoryId );
-        params[USERNAME] = OUSTR_TO_STDSTR( m_aUrl.GetUser() );
-        params[PASSWORD] = OUSTR_TO_STDSTR( m_aUrl.GetPass() );
+        params[USERNAME] = OUSTR_TO_STDSTR( m_sUser );
+        params[PASSWORD] = OUSTR_TO_STDSTR( m_sPass );
 
         return params;
     }
 
-    rtl::OUString URL::getObjectId( )
+    rtl::OUString URL::getObjectPath( )
     {
-        rtl::OUString sResult;
-        map< rtl::OUString, rtl::OUString >::iterator it = m_aQuery.find( "id" );
-        if ( it != m_aQuery.end( ) )
-            sResult = it->second;
-        return sResult;
+        return m_sPath;
     }
 
     rtl::OUString URL::getBindingUrl( )
@@ -100,21 +80,26 @@ namespace cmis
         return m_sBindingUrl;
     }
 
-    void URL::setObjectId( rtl::OUString sId )
+    void URL::setObjectPath( rtl::OUString sPath )
     {
-        m_aQuery["id"] = sId;
-        updateUrlQuery( );
+        m_sPath = sPath;
     }
 
     rtl::OUString URL::asString( )
     {
-        return m_aUrl.GetMainURL( INetURLObject::NO_DECODE );
-    }
-
-    void URL::updateUrlQuery( )
-    {
-        rtl::OUString sParam =  "repo-id=" + m_sRepositoryId + "&id=" + m_aQuery["id"];
-        m_aUrl.SetParam( sParam );
+        rtl::OUString sUrl;
+        rtl::OUString sEncodedBinding = rtl::Uri::encode(
+                m_sBindingUrl + "#" + m_sRepositoryId,
+                rtl_UriCharClassUricNoSlash,
+                rtl_UriEncodeKeepEscapes,
+                RTL_TEXTENCODING_UTF8 );
+        sUrl = "vnd.libreoffice.cmis+atom://" + sEncodedBinding;
+
+        if ( m_sPath[0] != '/' )
+            sUrl += "/";
+        sUrl += m_sPath;
+
+        return sUrl;
     }
 }
 
diff --git a/ucb/source/ucp/cmis/cmis_url.hxx b/ucb/source/ucp/cmis/cmis_url.hxx
index 18d13f1..833804b 100644
--- a/ucb/source/ucp/cmis/cmis_url.hxx
+++ b/ucb/source/ucp/cmis/cmis_url.hxx
@@ -39,25 +39,21 @@ namespace cmis
     class URL
     {
         private:
-            INetURLObject m_aUrl;
             rtl::OUString m_sBindingUrl;
             rtl::OUString m_sRepositoryId;
-
-            std::map< rtl::OUString, rtl::OUString > m_aQuery;
+            rtl::OUString m_sPath;
+            rtl::OUString m_sUser;
+            rtl::OUString m_sPass;
 
         public:
             URL( rtl::OUString const & urlStr );
 
             std::map< int, std::string > getSessionParams( );
-            rtl::OUString getObjectId( );
+            rtl::OUString getObjectPath( );
             rtl::OUString getBindingUrl( );
-            void setObjectId( rtl::OUString sId );
+            void setObjectPath( rtl::OUString sPath );
 
             rtl::OUString asString( );
-
-        private:
-
-            void updateUrlQuery( );
     };
 }
 
commit 2c4588340ee8387513dd067ecb53dc0058b12ccc
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Fri Jun 1 10:46:25 2012 +0200

    CMIS UCP: Fixed folder creation and nodes renaming
    
    Change-Id: I2c49b95279d90ebb06f38ed83061a5f1a905a555

diff --git a/fpicker/source/office/fpsmartcontent.cxx b/fpicker/source/office/fpsmartcontent.cxx
index 0e4c9fe..69bb403 100644
--- a/fpicker/source/office/fpsmartcontent.cxx
+++ b/fpicker/source/office/fpsmartcontent.cxx
@@ -310,6 +310,46 @@ namespace svt
         return bRet;
     }
 
+    rtl::OUString SmartContent::createFolder( const rtl::OUString& _rTitle )
+    {
+        rtl::OUString aCreatedUrl;
+        try
+        {
+            rtl::OUString sFolderType;
+
+            Sequence< ContentInfo > aInfo = m_pContent->queryCreatableContentsInfo();
+            const ContentInfo* pInfo = aInfo.getConstArray();
+            sal_Int32 nCount = aInfo.getLength();
+            for ( sal_Int32 i = 0; i < nCount; ++i, ++pInfo )
+            {
+                // Simply look for the first KIND_FOLDER...
+                if ( pInfo->Attributes & ContentInfoAttribute::KIND_FOLDER )
+                {
+                    sFolderType = pInfo->Type;
+                    break;
+                }
+            }
+
+            if ( !sFolderType.isEmpty() )
+            {
+                ucbhelper::Content aCreated;
+                Sequence< rtl::OUString > aNames( 1 );
+                rtl::OUString* pNames = aNames.getArray();
+                pNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
+                Sequence< Any > aValues( 1 );
+                Any* pValues = aValues.getArray();
+                pValues[0] = makeAny( _rTitle );
+                m_pContent->insertNewContent( sFolderType, aNames, aValues, aCreated );
+
+                aCreatedUrl = aCreated.getURL();
+            }
+        }
+        catch( const Exception& )
+        {
+        }
+        return aCreatedUrl;
+    }
+
 //........................................................................
 } // namespace svt
 //........................................................................
diff --git a/fpicker/source/office/fpsmartcontent.hxx b/fpicker/source/office/fpsmartcontent.hxx
index e16c288..81aff5b 100644
--- a/fpicker/source/office/fpsmartcontent.hxx
+++ b/fpicker/source/office/fpsmartcontent.hxx
@@ -61,7 +61,7 @@ namespace svt
 
     private:
         ::rtl::OUString                                                                  m_sURL;
-        ::ucbhelper::Content*                                                                  m_pContent;
+        ::ucbhelper::Content*                                                            m_pContent;
         State                                                                            m_eState;
         ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XCommandEnvironment >  m_xCmdEnv;
         ::com::sun::star::uno::Reference < ::com::sun::star::task::XInteractionHandler > m_xOwnInteraction;
@@ -174,6 +174,13 @@ namespace svt
         */
         sal_Bool    canCreateFolder( );
 
+        /** creates a new folder with the given title and return the corresponding URL.
+
+            @return
+                the URL of the created folder or an empty string
+          */
+        rtl::OUString    createFolder( const rtl::OUString& _rTitle );
+
         /** binds to the given URL, checks whether or not it refers to a folder
 
             @postcond
diff --git a/fpicker/source/office/iodlg.cxx b/fpicker/source/office/iodlg.cxx
index 258edd9..cc57c5b 100644
--- a/fpicker/source/office/iodlg.cxx
+++ b/fpicker/source/office/iodlg.cxx
@@ -819,7 +819,14 @@ IMPL_STATIC_LINK( SvtFileDialog, NewFolderHdl_Impl, PushButton*, EMPTYARG )
     while ( !bHandled )
     {
         if ( aDlg.Execute() == RET_OK )
-            bHandled = pThis->_pFileView->CreateNewFolder( aDlg.GetName() );
+        {
+            rtl::OUString aUrl = aContent.createFolder( aDlg.GetName( ) );
+            if ( !aUrl.isEmpty( ) )
+            {
+                pThis->_pFileView->CreatedFolder( aUrl, aDlg.GetName() );
+                bHandled = sal_True;
+            }
+        }
         else
             bHandled = sal_True;
     }
diff --git a/svtools/inc/svtools/fileview.hxx b/svtools/inc/svtools/fileview.hxx
index c5ec78e..4778bd9 100644
--- a/svtools/inc/svtools/fileview.hxx
+++ b/svtools/inc/svtools/fileview.hxx
@@ -98,7 +98,7 @@ public:
     String                  GetCurrentURL() const;
 
     sal_Bool                GetParentURL( String& _rParentURL ) const;
-    sal_Bool                CreateNewFolder( const String& rNewFolder );
+    void                    CreatedFolder( const String& rUrl, const String& rNewFolder );
 
     void                    SetHelpId( const rtl::OString& rHelpId );
     const rtl::OString&     GetHelpId( ) const;
diff --git a/svtools/source/contnr/fileview.cxx b/svtools/source/contnr/fileview.cxx
index 11f80bf..9f100f8 100644
--- a/svtools/source/contnr/fileview.cxx
+++ b/svtools/source/contnr/fileview.cxx
@@ -1293,23 +1293,13 @@ String SvtFileView::GetCurrentURL() const
 }
 // -----------------------------------------------------------------------------
 
-sal_Bool SvtFileView::CreateNewFolder( const String& rNewFolder )
+void SvtFileView::CreatedFolder( const String& rUrl, const String& rNewFolder )
 {
-    sal_Bool bRet = sal_False;
-    INetURLObject aObj( mpImp->maViewURL );
-    aObj.insertName( rNewFolder, false, INetURLObject::LAST_SEGMENT, true, INetURLObject::ENCODE_ALL );
-    String sURL = aObj.GetMainURL( INetURLObject::NO_DECODE );
-    if ( ::utl::UCBContentHelper::MakeFolder( sURL, sal_True ) )
-    {
-        String sTitle = aObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
-        String sEntry = mpImp->FolderInserted( sURL, sTitle );
-        SvLBoxEntry* pEntry = mpImp->mpView->InsertEntry( sEntry, mpImp->maFolderImage, mpImp->maFolderImage );
-        SvtContentEntry* pUserData = new SvtContentEntry( sURL, sal_True );
-        pEntry->SetUserData( pUserData );
-        mpImp->mpView->MakeVisible( pEntry );
-        bRet = sal_True;
-    }
-    return bRet;
+    String sEntry = mpImp->FolderInserted( rUrl, rNewFolder );
+    SvLBoxEntry* pEntry = mpImp->mpView->InsertEntry( sEntry, mpImp->maFolderImage, mpImp->maFolderImage );
+    SvtContentEntry* pUserData = new SvtContentEntry( rUrl, sal_True );
+    pEntry->SetUserData( pUserData );
+    mpImp->mpView->MakeVisible( pEntry );
 }
 
 // -----------------------------------------------------------------------
diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx
index aacfaaa..d40deab 100644
--- a/ucb/source/ucp/cmis/cmis_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_content.cxx
@@ -466,8 +466,6 @@ namespace cmis
         sal_Bool bReplaceExisting, const uno::Reference< ucb::XCommandEnvironment >& xEnv )
             throw( uno::Exception )
     {
-        SAL_INFO( "cmisucp", "TODO - Content::insert()" );
-
         if ( !xInputStream.is() )
         {
             ucbhelper::cancelCommandExecution( uno::makeAny
@@ -481,6 +479,8 @@ namespace cmis
             // For transient content, the URL is the one of the parent
             if ( m_bTransient )
             {
+                string sNewId;
+
                 // Try to get the object from the server if there is any
                 libcmis::Folder* pFolder = dynamic_cast< libcmis::Folder* >( getObject( ).get( ) );
                 if ( pFolder != NULL )
@@ -499,7 +499,16 @@ namespace cmis
                         newPath += "/";
                     newPath += newName;
 
-                    libcmis::ObjectPtr object = m_pSession->getObjectByPath( newPath );
+                    libcmis::ObjectPtr object;
+                    try
+                    {
+                        object = m_pSession->getObjectByPath( newPath );
+                        sNewId = object->getId( );
+                    }
+                    catch ( const libcmis::Exception& )
+                    {
+                        // Nothing matched the path
+                    }
 
                     if ( NULL != object.get( ) )
                     {
@@ -524,14 +533,41 @@ namespace cmis
                     }
                     else
                     {
-                        // TODO We need to create a brand new object... either folder or document
+                        // We need to create a brand new object... either folder or document
+                        bool bIsFolder = m_pObjectType->getBaseType( )->getId( ) == "cmis:folder";
+                        setCmisProperty( "cmis:objectTypeId", m_pObjectType->getId( ) );
+
+                        if ( bIsFolder )
+                        {
+                            libcmis::FolderPtr pNew = pFolder->createFolder( m_pObjectProps );
+                            sNewId = pNew->getId( );
+                        }
+                        else
+                        {
+                            boost::shared_ptr< ostream > pOut( new ostringstream ( ios_base::binary | ios_base::in | ios_base::out ) );
+                            uno::Reference < io::XOutputStream > xOutput = new ucbhelper::StdOutputStream( pOut );
+                            copyData( xInputStream, xOutput );
+                            libcmis::DocumentPtr pNew = pFolder->createDocument( m_pObjectProps, pOut, string() );
+                            sNewId = pNew->getId( );
+                        }
+                    }
+
+                    if ( !sNewId.empty( ) )
+                    {
+                        // Update the current content: it's no longer transient
+                        m_sObjectId = rtl::OUString::createFromAscii( sNewId.c_str( ) );
+                        URL aUrl( m_sURL );
+                        aUrl.setObjectId( m_sObjectId );
+                        m_sURL = aUrl.asString( );
+                        m_pObject.reset( );
+                        m_pObjectType.reset( );
+                        m_pObjectProps.clear( );
+                        m_bTransient = false;
+
+                        inserted();
                     }
                 }
             }
-            else
-            {
-                // TODO Update the current object... but I'm not sure this case can happen with UCB
-            }
         }
         catch ( const libcmis::Exception& e )
         {
@@ -559,11 +595,15 @@ namespace cmis
     {
         // Get the already set properties if possible
         if ( !m_bTransient && getObject( ).get( ) )
+        {
             m_pObjectProps = getObject()->getProperties( );
+            m_pObjectType = getObject()->getTypeDescription();
+        }
 
         sal_Int32 nCount = rValues.getLength();
         uno::Sequence< uno::Any > aRet( nCount );
 
+        bool bChanged = false;
         const beans::PropertyValue* pValues = rValues.getConstArray();
         for ( sal_Int32 n = 0; n < nCount; ++n )
         {
@@ -600,15 +640,22 @@ namespace cmis
                 }
 
                 setCmisProperty( "cmis:name", OUSTR_TO_STDSTR( aNewTitle ) );
+                bChanged = true;
             }
             else
             {
+                SAL_INFO( "cmisucp", "Couln't set property: " << rValue.Name );
                 lang::IllegalAccessException e ( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Property is read-only!")),
                        static_cast< cppu::OWeakObject* >( this ) );
                 aRet[ n ] <<= e;
             }
         }
 
+        if ( !m_bTransient && bChanged )
+        {
+            getObject()->updateProperties();
+        }
+
         return aRet;
     }
 
@@ -1030,16 +1077,25 @@ namespace cmis
     {
         if ( m_pObjectType.get( ) )
         {
-            map< string, libcmis::PropertyTypePtr > propsTypes = m_pObjectType->getPropertiesTypes( );
-            map< string, libcmis::PropertyTypePtr >::iterator typeIt = propsTypes.find( sName );
+            map< string, libcmis::PropertyPtr >::iterator propIt = m_pObjectProps.find( sName );
+            vector< string > values;
+            values.push_back( sValue );
+
+            if ( propIt == m_pObjectProps.end( ) && m_pObjectType.get( ) )
+            {
+                map< string, libcmis::PropertyTypePtr > propsTypes = m_pObjectType->getPropertiesTypes( );
+                map< string, libcmis::PropertyTypePtr >::iterator typeIt = propsTypes.find( sName );
 
-            if ( typeIt != propsTypes.end( ) )
+                if ( typeIt != propsTypes.end( ) )
+                {
+                    libcmis::PropertyTypePtr propType = typeIt->second;
+                    libcmis::PropertyPtr property( new libcmis::Property( propType, values ) );
+                    m_pObjectProps.insert( pair< string, libcmis::PropertyPtr >( sName, property ) );
+                }
+            }
+            else if ( propIt != m_pObjectProps.end( ) )
             {
-                libcmis::PropertyTypePtr propType = typeIt->second;
-                vector< string > values;
-                values.push_back( sValue );
-                libcmis::PropertyPtr property( new libcmis::Property( propType, values ) );
-                m_pObjectProps.insert( pair< string, libcmis::PropertyPtr >( sName, property ) );
+                propIt->second->setValues( values );
             }
         }
     }
commit 99465489aa24a2d9d81c0daccfcf512e4f82c841
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Thu May 31 14:59:42 2012 +0200

    fpicker: folder creation dialog fixes
    
    Change-Id: I9122de6c04561f72c633b05983590871d9ec3a73

diff --git a/fpicker/source/office/iodlg.cxx b/fpicker/source/office/iodlg.cxx
index 3209ad6..258edd9 100644
--- a/fpicker/source/office/iodlg.cxx
+++ b/fpicker/source/office/iodlg.cxx
@@ -810,9 +810,10 @@ IMPL_STATIC_LINK( SvtFileDialog, NewFolderHdl_Impl, PushButton*, EMPTYARG )
 {
     pThis->_pFileView->EndInplaceEditing( false );
 
-    INetURLObject aObj( pThis->_pFileView->GetViewURL() );
-    String sFolderName = aObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET, RTL_TEXTENCODING_UTF8 );
-    svtools::QueryFolderNameDialog aDlg( pThis, sFolderName, String( SvtResId( STR_SVT_NEW_FOLDER ) ) );
+    SmartContent aContent( pThis->_pFileView->GetViewURL( ) );
+    rtl::OUString aTitle;
+    aContent.getTitle( aTitle );
+    svtools::QueryFolderNameDialog aDlg( pThis, aTitle, String( SvtResId( STR_SVT_NEW_FOLDER ) ) );
     sal_Bool bHandled = sal_False;
 
     while ( !bHandled )
diff --git a/fpicker/source/office/iodlg.src b/fpicker/source/office/iodlg.src
index 0c78837..21aa517 100644
--- a/fpicker/source/office/iodlg.src
+++ b/fpicker/source/office/iodlg.src
@@ -266,7 +266,7 @@ ModalDialog DLG_FPICKER_QUERYFOLDERNAME
     OutputSize = TRUE ;
     SVLook = TRUE ;
     Text = "Ordner" ;
-    Size = MAP_APPFONT ( 100 , 45 ) ;
+    Size = MAP_APPFONT ( 215 , 45 ) ;
     FixedText FT_SVT_QUERYFOLDERNAME_DLG_NAME
     {
         Pos = MAP_APPFONT ( 12 , 14 ) ;
commit a57fca1bcabfbf6dae93eaafb4ab2d313a69f5a4
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Thu May 31 14:18:55 2012 +0200

    fpicker: Added CMIS protocol for Experimental features
    
    Change-Id: I Ib254cfbe2743b67bc19c2c9033908bc0bedc430c

diff --git a/fpicker/source/office/PlaceEditDialog.cxx b/fpicker/source/office/PlaceEditDialog.cxx
index 1ecdb59..d305bc4 100644
--- a/fpicker/source/office/PlaceEditDialog.cxx
+++ b/fpicker/source/office/PlaceEditDialog.cxx
@@ -33,6 +33,7 @@
 #include "PlaceEditDialog.hxx"
 #include "ServerDetailsControls.hxx"
 
+#include <officecfg/Office/Common.hxx>
 #include <vcl/msgbox.hxx>
 
 using namespace boost;
@@ -56,6 +57,10 @@ PlaceEditDialog::PlaceEditDialog(	Window* pParent ) :
     m_aEDShare( this, SvtResId( ED_ADDPLACE_SHARE ) ),
     m_aFTSmbPath( this, SvtResId( FT_ADDPLACE_SMBPATH ) ),
     m_aEDSmbPath( this, SvtResId( ED_ADDPLACE_SMBPATH ) ),
+    m_aFTCmisBinding( this, SvtResId( FT_ADDPLACE_CMIS_BINDING ) ),
+    m_aEDCmisBinding( this, SvtResId( ED_ADDPLACE_CMIS_BINDING ) ),
+    m_aFTCmisRepository( this, SvtResId( FT_ADDPLACE_CMIS_REPOSITORY ) ),
+    m_aEDCmisRepository( this, SvtResId( ED_ADDPLACE_CMIS_REPOSITORY ) ),
     m_aFTUsername( this, SvtResId( FT_ADDPLACE_USERNAME ) ),
     m_aEDUsername( this, SvtResId( ED_ADDPLACE_USERNAME ) ),
     m_aBTOk( this, SvtResId( BT_ADDPLACE_OK ) ),
@@ -95,6 +100,10 @@ PlaceEditDialog::PlaceEditDialog( Window* pParent, const PlacePtr& pPlace ) :
     m_aEDShare( this, SvtResId( ED_ADDPLACE_SHARE ) ),
     m_aFTSmbPath( this, SvtResId( FT_ADDPLACE_SMBPATH ) ),
     m_aEDSmbPath( this, SvtResId( ED_ADDPLACE_SMBPATH ) ),
+    m_aFTCmisBinding( this, SvtResId( FT_ADDPLACE_CMIS_BINDING ) ),
+    m_aEDCmisBinding( this, SvtResId( ED_ADDPLACE_CMIS_BINDING ) ),
+    m_aFTCmisRepository( this, SvtResId( FT_ADDPLACE_CMIS_REPOSITORY ) ),
+    m_aEDCmisRepository( this, SvtResId( ED_ADDPLACE_CMIS_REPOSITORY ) ),
     m_aFTUsername( this, SvtResId( FT_ADDPLACE_USERNAME ) ),
     m_aEDUsername( this, SvtResId( ED_ADDPLACE_USERNAME ) ),
     m_aBTOk( this, SvtResId( BT_ADDPLACE_OK ) ),
@@ -198,6 +207,22 @@ void PlaceEditDialog::InitDetails( )
     pSmbDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
     m_aDetailsContainers.push_back( pSmbDetails );
 
+    // Create CMIS control
+    shared_ptr< DetailsContainer > pCmisDetails( new CmisDetailsContainer( ) );
+    pCmisDetails->addControl( FT_ADDPLACE_CMIS_BINDING, &m_aFTCmisBinding );
+    pCmisDetails->addControl( ED_ADDPLACE_CMIS_BINDING, &m_aEDCmisBinding );
+    pCmisDetails->addControl( FT_ADDPLACE_CMIS_REPOSITORY, &m_aFTCmisRepository );
+    pCmisDetails->addControl( ED_ADDPLACE_CMIS_REPOSITORY, &m_aEDCmisRepository );
+    pCmisDetails->setChangeHdl( LINK( this, PlaceEditDialog, EditHdl ) );
+
+    if ( officecfg::Office::Common::Misc::ExperimentalMode::get() )
+        m_aDetailsContainers.push_back( pCmisDetails );
+    else
+    {
+        // Remove the CMIS entry, left it in src file for l10n
+        m_aLBServerType.RemoveEntry( m_aLBServerType.GetEntryCount( ) - 1 );
+    }
+
     // Set default to first value
     m_aLBServerType.SelectEntryPos( 0 );
     SelectTypeHdl( &m_aLBServerType );
diff --git a/fpicker/source/office/PlaceEditDialog.hrc b/fpicker/source/office/PlaceEditDialog.hrc
index b22f3f9..74900f7 100644
--- a/fpicker/source/office/PlaceEditDialog.hrc
+++ b/fpicker/source/office/PlaceEditDialog.hrc
@@ -53,6 +53,10 @@
 #define ED_ADDPLACE_SHARE       	 		    28
 #define FT_ADDPLACE_SMBPATH        	 		    29
 #define ED_ADDPLACE_SMBPATH        	 		    30
+#define FT_ADDPLACE_CMIS_BINDING                31
+#define ED_ADDPLACE_CMIS_BINDING                32
+#define FT_ADDPLACE_CMIS_REPOSITORY             33
+#define ED_ADDPLACE_CMIS_REPOSITORY             34
 
 #endif
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/PlaceEditDialog.hxx b/fpicker/source/office/PlaceEditDialog.hxx
index 68ee425..53526e8 100644
--- a/fpicker/source/office/PlaceEditDialog.hxx
+++ b/fpicker/source/office/PlaceEditDialog.hxx
@@ -69,6 +69,11 @@ private :
     FixedText    m_aFTSmbPath;
     Edit         m_aEDSmbPath;
 
+    FixedText    m_aFTCmisBinding;
+    Edit         m_aEDCmisBinding;
+    FixedText    m_aFTCmisRepository;
+    Edit         m_aEDCmisRepository;
+
     FixedText    m_aFTUsername;
     Edit         m_aEDUsername;
     OKButton m_aBTOk;
diff --git a/fpicker/source/office/PlaceEditDialog.src b/fpicker/source/office/PlaceEditDialog.src
index 15c614d..313f25b 100644
--- a/fpicker/source/office/PlaceEditDialog.src
+++ b/fpicker/source/office/PlaceEditDialog.src
@@ -134,6 +134,30 @@ ModalDialog DLG_FPICKER_PLACE_EDIT
         Size = MAP_APPFONT ( 137 , 12 ) ;
         Border = TRUE ;
     };
+    FixedText FT_ADDPLACE_CMIS_BINDING
+    {
+        Pos = MAP_APPFONT ( 12 , 46 ) ;
+        Size = MAP_APPFONT ( 40 , 10 ) ;
+        Text [ en-US ] = "Binding URL" ;
+    };
+    Edit ED_ADDPLACE_CMIS_BINDING
+    {
+        Pos = MAP_APPFONT ( 55, 44 ) ;
+        Size = MAP_APPFONT ( 137 , 12 ) ;
+        Border = TRUE ;
+    };
+    FixedText FT_ADDPLACE_CMIS_REPOSITORY
+    {
+        Pos = MAP_APPFONT ( 12 , 62 ) ;
+        Size = MAP_APPFONT ( 40 , 10 ) ;
+        Text [ en-US ] = "Repository" ;
+    };
+    Edit ED_ADDPLACE_CMIS_REPOSITORY
+    {
+        Pos = MAP_APPFONT ( 55, 60 ) ;
+        Size = MAP_APPFONT ( 137 , 12 ) ;
+        Border = TRUE ;
+    };
     ListBox LB_ADDPLACE_SERVERTYPE
     {
         Pos = MAP_APPFONT ( 55, 28 ) ;
@@ -146,6 +170,7 @@ ModalDialog DLG_FPICKER_PLACE_EDIT
             < "FTP" ; >;
             < "SSH" ; >;
             < "Windows Share" ; >;
+            < "CMIS (Atom Binding)" ; >;
         };
     };
     FixedText FT_ADDPLACE_USERNAME
diff --git a/fpicker/source/office/ServerDetailsControls.cxx b/fpicker/source/office/ServerDetailsControls.cxx
index ca00481..ae52de4 100644
--- a/fpicker/source/office/ServerDetailsControls.cxx
+++ b/fpicker/source/office/ServerDetailsControls.cxx
@@ -234,7 +234,6 @@ INetURLObject SmbDetailsContainer::getUrl( )
     rtl::OUString sUrl;
     if ( !sHost.isEmpty( ) )
     {
-        INetURLObject aUrl;
         sUrl = "smb://" + sHost + "/";
         if ( !sShare.isEmpty( ) )
             sUrl += sShare;
@@ -272,4 +271,68 @@ bool SmbDetailsContainer::setUrl( const INetURLObject& rUrl )
     return bSuccess;
 }
 
+INetURLObject CmisDetailsContainer::getUrl( )
+{
+    rtl::OUString sBindingUrl = rtl::OUString( static_cast< Edit* >( getControl( ED_ADDPLACE_CMIS_BINDING ) )->GetText() ).trim( );
+    rtl::OUString sRepo = rtl::OUString( static_cast< Edit* >( getControl( ED_ADDPLACE_CMIS_REPOSITORY ) )->GetText() ).trim( );
+
+    rtl::OUString sUrl;
+    if ( !sBindingUrl.isEmpty( ) && !sRepo.isEmpty() )
+    {
+        sal_Int32 pos = sBindingUrl.indexOf( rtl::OUString::createFromAscii( "://" ) );
+        if ( pos > 0 )
+            sBindingUrl = sBindingUrl.copy( pos + 3 );
+        sUrl = "cmis+atom://" + sBindingUrl + "?repo-id=" + sRepo;
+    }
+
+    return INetURLObject( sUrl );
+}
+
+bool CmisDetailsContainer::setUrl( const INetURLObject& rUrl )
+{
+    bool bSuccess =  rUrl.GetProtocol() == INET_PROT_CMIS_ATOM;
+
+    if ( bSuccess )
+    {
+        rtl::OUString sBindingUrl( "http://" );
+        sBindingUrl += rUrl.GetHost( );
+        if ( rUrl.HasPort( ) )
+            sBindingUrl += rtl::OUString::valueOf( sal_Int32( rUrl.GetPort( ) ) );
+        sBindingUrl += rUrl.GetURLPath( );
+
+        // Split the query into bits and locate the repo-id key
+        rtl::OUString sQuery = rUrl.GetParam( );
+        rtl::OUString sRepositoryId;
+
+        while ( !sQuery.isEmpty() )
+        {
+            sal_Int32 nPos = sQuery.indexOfAsciiL( "&", 1 );
+            rtl::OUString sSegment;
+            if ( nPos > 0 )
+            {
+                sSegment = sQuery.copy( 0, nPos );
+                sQuery = sQuery.copy( nPos + 1 );
+            }
+            else
+            {
+                sSegment = sQuery;
+                sQuery = rtl::OUString();
+            }
+
+            sal_Int32 nEqPos = sSegment.indexOfAsciiL( "=", 1 );
+            rtl::OUString key = sSegment.copy( 0, nEqPos );
+            rtl::OUString value = sSegment.copy( nEqPos +1 );
+
+            if ( key == "repo-id" )
+                sRepositoryId = value;
+        }
+
+        static_cast< Edit* >( getControl( ED_ADDPLACE_CMIS_BINDING ) )->SetText( sBindingUrl );
+        static_cast< Edit* >( getControl( ED_ADDPLACE_CMIS_REPOSITORY ) )->SetText( sRepositoryId );
+    }
+
+    return bSuccess;
+}
+
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/ServerDetailsControls.hxx b/fpicker/source/office/ServerDetailsControls.hxx
index aafcc0c..a31e831 100644
--- a/fpicker/source/office/ServerDetailsControls.hxx
+++ b/fpicker/source/office/ServerDetailsControls.hxx
@@ -119,5 +119,15 @@ class SmbDetailsContainer : public DetailsContainer
         virtual bool setUrl( const INetURLObject& rUrl );
 };
 
+class CmisDetailsContainer : public DetailsContainer
+{
+    public:
+        CmisDetailsContainer( ) : DetailsContainer( ) { };
+        ~CmisDetailsContainer( ) { };
+
+        virtual INetURLObject getUrl( );
+        virtual bool setUrl( const INetURLObject& rUrl );
+};
+
 #endif
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 4880c6dcee9f1ae6a895f15293727eb6a76d6c5e
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Thu May 31 14:08:58 2012 +0200

    CMIS UCP: fixed a few bugs to show repo in fpicker
    
    Change-Id: I21a38adda013b8e75bf3a6ba91d70014461ea596

diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx
index abbdb73..aacfaaa 100644
--- a/ucb/source/ucp/cmis/cmis_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_content.cxx
@@ -127,6 +127,25 @@ namespace
         }
         return false;
     }
+
+    util::DateTime lcl_boostToUnoTime( boost::posix_time::ptime boostTime )
+    {
+        util::DateTime unoTime;
+        unoTime.Year = boostTime.date().year();
+        unoTime.Month = boostTime.date().month();
+        unoTime.Day = boostTime.date().day();
+        unoTime.Hours = boostTime.time_of_day().hours();
+        unoTime.Minutes = boostTime.time_of_day().minutes();
+        unoTime.Seconds = boostTime.time_of_day().seconds();
+
+        long total_milli = boostTime.time_of_day().total_milliseconds( );
+        long milli = total_milli - boostTime.time_of_day().total_seconds( );
+        long hundredthSeconds = milli / 10;
+
+        unoTime.HundredthSeconds = hundredthSeconds;
+
+        return unoTime;
+    }
 }
 
 namespace cmis
@@ -199,7 +218,10 @@ namespace cmis
                 if ( !m_sObjectId.isEmpty( ) )
                     m_pObject = m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
                 else
+                {
                     m_pObject = m_pSession->getRootFolder( );
+                    m_sObjectId = rtl::OUString::createFromAscii( m_pObject->getId( ).c_str( ) );
+                }
             }
         }
         catch ( const libcmis::Exception& e )
@@ -256,10 +278,8 @@ namespace cmis
             }
             else if ( rProp.Name == "IsFolder" )
             {
-                if( getObject()->getBaseType( ) == "cmis:folder" )
-                    xRow->appendBoolean( rProp, true );
-                else
-                    xRow->appendVoid( rProp );
+                sal_Bool bFolder = getObject()->getBaseType( ) == "cmis:folder";
+                xRow->appendBoolean( rProp, bFolder );
             }
             else if ( rProp.Name == "Title" )
             {
@@ -300,15 +320,13 @@ namespace cmis
             }
             else if ( rProp.Name == "DateCreated" )
             {
-                // TODO Fix this value
-                SAL_INFO( "cmisucp", "TODO - Fix property value " << rProp.Name );
-                xRow->appendVoid( rProp );
+                util::DateTime aTime = lcl_boostToUnoTime( getObject( )->getCreationDate( ) );
+                xRow->appendTimestamp( rProp, aTime );
             }
             else if ( rProp.Name == "DateModified" )
             {
-                // TODO Fix this value
-                SAL_INFO( "cmisucp", "TODO - Fix property value " << rProp.Name );
-                xRow->appendVoid( rProp );
+                util::DateTime aTime = lcl_boostToUnoTime( getObject( )->getLastModificationDate( ) );
+                xRow->appendTimestamp( rProp, aTime );
             }
             else if ( rProp.Name == "Size" )
             {
@@ -334,7 +352,9 @@ namespace cmis
         bool bExists = true;
         try
         {
-            libcmis::ObjectPtr object = m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
+            if ( !m_sObjectId.isEmpty( ) )
+                libcmis::ObjectPtr object = m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
+            // No need to handle the root folder case... how can it not exists?
         }
         catch ( const libcmis::Exception& )
         {
@@ -725,19 +745,27 @@ namespace cmis
 
         string parentId;
 
-        libcmis::ObjectPtr pObj = getObject( );
-        libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject( ).get( ) );
-        if ( NULL != document )
+        try
         {
-            vector< boost::shared_ptr< libcmis::Folder > > parents = document->getParents( );
-            if ( parents.size( ) > 0 )
-                parentId = parents.front( )->getId( );
+            libcmis::ObjectPtr pObj = getObject( );
+            libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject( ).get( ) );
+            if ( NULL != document )
+            {
+                vector< boost::shared_ptr< libcmis::Folder > > parents = document->getParents( );
+                if ( parents.size( ) > 0 )
+                    parentId = parents.front( )->getId( );
+            }
+            else
+            {
+                libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( getObject( ).get( ) );
+                if ( NULL != folder )
+                    parentId = folder->getFolderParent( )->getId( );
+            }
         }
-        else
+        catch ( const libcmis::Exception & )
         {
-            libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( getObject( ).get( ) );
-            if ( NULL != folder )
-                parentId = folder->getFolderParent( )->getId( );
+            // We may have an exception if we don't have the rights to
+            // get the parent ID
         }
 
         if ( !parentId.empty() )
commit 6ad3debb05f7c6f0afdf3c9ae08210cd6b17ce0d
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Wed May 30 18:59:51 2012 +0200

    CMIS UCP: if the URL has no object id, assume we want the root folder
    
    Change-Id: I6cc330f20222d4448d2267151d49f354068f54f3

diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx
index ba025be..abbdb73 100644
--- a/ucb/source/ucp/cmis/cmis_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_content.cxx
@@ -195,7 +195,12 @@ namespace cmis
         try
         {
             if ( !m_pObject.get() )
-                m_pObject = m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
+            {
+                if ( !m_sObjectId.isEmpty( ) )
+                    m_pObject = m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
+                else
+                    m_pObject = m_pSession->getRootFolder( );
+            }
         }
         catch ( const libcmis::Exception& e )
         {
diff --git a/ucb/source/ucp/cmis/cmis_url.cxx b/ucb/source/ucp/cmis/cmis_url.cxx
index 655518d..df22501 100644
--- a/ucb/source/ucp/cmis/cmis_url.cxx
+++ b/ucb/source/ucp/cmis/cmis_url.cxx
@@ -88,7 +88,11 @@ namespace cmis
 
     rtl::OUString URL::getObjectId( )
     {
-        return m_aQuery["id"];
+        rtl::OUString sResult;
+        map< rtl::OUString, rtl::OUString >::iterator it = m_aQuery.find( "id" );
+        if ( it != m_aQuery.end( ) )
+            sResult = it->second;
+        return sResult;
     }
 
     rtl::OUString URL::getBindingUrl( )
commit 705cab9a81b81153778c09c56340c20118c00471
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Wed May 30 17:18:01 2012 +0200

    CMIS UCP: implemented delete command for folders
    
    Change-Id: Iba1c5bf10c235ebd26108be944b88096f0ee84bd

diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx
index daf16f7..ba025be 100644
--- a/ucb/source/ucp/cmis/cmis_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_content.cxx
@@ -851,8 +851,8 @@ namespace cmis
                 }
                 else
                 {
-                    // TODO Removing a folder and its children needs removeTree in libcmis
-                    // the remove() function only works for empty folders or documents
+                    libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( getObject( ).get() );
+                    folder->removeTree( );
                 }
             }
             catch ( const libcmis::Exception& e )
commit c77437672a57f53d776ae8161afeffd606cc9893
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Tue May 29 16:30:01 2012 +0200

    CMIS UCP: Implemented delete command for documents
    
    Change-Id: I34c90f4675e461f461bad7e81c23da56463f0a24

diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx
index 138eb36..daf16f7 100644
--- a/ucb/source/ucp/cmis/cmis_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_content.cxx
@@ -514,12 +514,6 @@ namespace cmis
         }
     }
 
-    void Content::destroy( sal_Bool /*bDeletePhysical*/ ) throw ( uno::Exception )
-    {
-        SAL_INFO( "cmisucp", "TODO - Content::destroy()" );
-        // TODO Implement me
-    }
-
     const int TRANSFER_BUFFER_SIZE = 65536;
 
     void Content::copyData(
@@ -849,9 +843,25 @@ namespace cmis
         }
         else if ( aCommand.Name == "delete" )
         {
-            sal_Bool bDeletePhysical = sal_False;
-            aCommand.Argument >>= bDeletePhysical;
-            destroy( bDeletePhysical );
+            try
+            {
+                if ( !isFolder( xEnv ) )
+                {
+                    getObject( )->remove( );
+                }
+                else
+                {
+                    // TODO Removing a folder and its children needs removeTree in libcmis
+                    // the remove() function only works for empty folders or documents
+                }
+            }
+            catch ( const libcmis::Exception& e )
+            {
+                ucbhelper::cancelCommandExecution( uno::makeAny
+                    ( uno::RuntimeException( rtl::OUString::createFromAscii( e.what() ),
+                        static_cast< cppu::OWeakObject * >( this ) ) ),
+                    xEnv );
+            }
         }
         else
         {
diff --git a/ucb/source/ucp/cmis/cmis_content.hxx b/ucb/source/ucp/cmis/cmis_content.hxx
index dfe8cc2..eafd503 100644
--- a/ucb/source/ucp/cmis/cmis_content.hxx
+++ b/ucb/source/ucp/cmis/cmis_content.hxx
@@ -110,7 +110,7 @@ private:
         sal_Bool bReplaceExisting, const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv )
             throw( com::sun::star::uno::Exception );
 
-    void destroy( sal_Bool bDeletePhysical ) throw( com::sun::star::uno::Exception );
+    void destroy( ) throw( com::sun::star::uno::Exception );
 
     void copyData( com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xIn,
         com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > xOut );
commit 6f34fd25cbd8d9ed43ae9c2b074f7c6fa6968b31
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Tue May 29 16:17:21 2012 +0200

    CMIS UCP: implemented folder case for open command
    
    Change-Id: Id0997cd99d7d80c975de3d46670a1fa8b3d602a3

diff --git a/ucb/Library_ucpcmis1.mk b/ucb/Library_ucpcmis1.mk
index 077d595..8237f6c 100644
--- a/ucb/Library_ucpcmis1.mk
+++ b/ucb/Library_ucpcmis1.mk
@@ -53,7 +53,9 @@ $(eval $(call gb_Library_use_externals,ucpcmis1,\
 
 $(eval $(call gb_Library_add_exception_objects,ucpcmis1,\
 	ucb/source/ucp/cmis/cmis_content \
+	ucb/source/ucp/cmis/cmis_datasupplier \
 	ucb/source/ucp/cmis/cmis_provider \
+	ucb/source/ucp/cmis/cmis_resultset \
 	ucb/source/ucp/cmis/cmis_url \
 ))
 
diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx
index ead9f2d..138eb36 100644
--- a/ucb/source/ucp/cmis/cmis_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_content.cxx
@@ -39,6 +39,7 @@
 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
 #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
 #include <com/sun/star/ucb/NameClash.hpp>
 #include <com/sun/star/ucb/NameClashException.hpp>
@@ -60,6 +61,7 @@
 
 #include "cmis_content.hxx"
 #include "cmis_provider.hxx"
+#include "cmis_resultset.hxx"
 
 #define OUSTR_TO_STDSTR(s) string( rtl::OUStringToOString( s, RTL_TEXTENCODING_UTF8 ).getStr() )
 
@@ -322,6 +324,21 @@ namespace cmis
         return uno::Reference< sdbc::XRow >( xRow.get() );
     }
 
+    bool Content::exists( )
+    {
+        bool bExists = true;
+        try
+        {
+            libcmis::ObjectPtr object = m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
+        }
+        catch ( const libcmis::Exception& )
+        {
+            bExists = false;
+        }
+
+        return bExists;
+    }
+
     void Content::queryChildren( ContentRefList& /*rChildren*/ )
     {
         SAL_INFO( "cmisucp", "TODO - Content::queryChildren()" );
@@ -334,7 +351,19 @@ namespace cmis
     {
         bool bIsFolder = isFolder( xEnv );
 
-        // TODO Handle the case of the non-existing file
+        // Handle the case of the non-existing file
+        if ( !exists( ) )
+        {
+            uno::Sequence< uno::Any > aArgs( 1 );
+            aArgs[ 0 ] <<= m_xIdentifier->getContentIdentifier();
+            uno::Any aErr = uno::makeAny(
+                ucb::InteractiveAugmentedIOException(rtl::OUString(), static_cast< cppu::OWeakObject * >( this ),
+                    task::InteractionClassification_ERROR,
+                    bIsFolder ? ucb::IOErrorCode_NOT_EXISTING_PATH : ucb::IOErrorCode_NOT_EXISTING, aArgs)
+            );
+
+            ucbhelper::cancelCommandExecution(aErr, xEnv);
+        }
 
         uno::Any aRet;
 
@@ -346,8 +375,9 @@ namespace cmis
 
         if ( bOpenFolder && bIsFolder )
         {
-            SAL_INFO( "cmisucp", "TODO - Content::open() - Folder case" );
-            // TODO Handle the folder case
+            uno::Reference< ucb::XDynamicResultSet > xSet
+                = new DynamicResultSet(m_xSMgr, this, rOpenCommand, xEnv );
+            aRet <<= xSet;
         }
         else if ( rOpenCommand.Sink.is() )
         {
diff --git a/ucb/source/ucp/cmis/cmis_content.hxx b/ucb/source/ucp/cmis/cmis_content.hxx
index e80a6d2..dfe8cc2 100644
--- a/ucb/source/ucp/cmis/cmis_content.hxx
+++ b/ucb/source/ucp/cmis/cmis_content.hxx
@@ -89,6 +89,9 @@ private:
         getPropertyValues(
             const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& rProperties,
             const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv );
+
+    bool exists( );
+
 private:
     typedef rtl::Reference< Content > ContentRef;
     typedef std::list< ContentRef > ContentRefList;
@@ -124,7 +127,6 @@ private:
     sal_Bool exchangeIdentity(const com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >&  xNewId);
 
     void resetAuthProvider( const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv );
-    libcmis::ObjectPtr getObject( );
 
 public:
     Content( const com::sun::star::uno::Reference<
@@ -186,6 +188,8 @@ public:
     com::sun::star::uno::Sequence< com::sun::star::ucb::ContentInfo >
         queryCreatableContentsInfo( const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& xEnv )
                 throw( com::sun::star::uno::RuntimeException );
+
+    libcmis::ObjectPtr getObject( );
 };
 
 }
diff --git a/ucb/source/ucp/cmis/cmis_datasupplier.cxx b/ucb/source/ucp/cmis/cmis_datasupplier.cxx
new file mode 100644
index 0000000..2a82a9b
--- /dev/null
+++ b/ucb/source/ucp/cmis/cmis_datasupplier.cxx
@@ -0,0 +1,244 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright 2012 LibreOffice contributors.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <vector>
+
+#include <ucbhelper/contentidentifier.hxx>
+#include <ucbhelper/providerhelper.hxx>
+
+#include <com/sun/star/ucb/OpenMode.hpp>
+
+#include "cmis_datasupplier.hxx"
+#include "cmis_content.hxx"
+#include "cmis_provider.hxx"
+
+using namespace com::sun::star;
+using namespace std;
+
+namespace cmis
+{
+
+    typedef std::vector< ResultListEntry* > ResultList;
+
+    DataSupplier::DataSupplier( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
+        const uno::Reference< ::cmis::Content >& rContent, sal_Int32 nOpenMode )
+        : mxContent(rContent), m_xSMgr(rxSMgr), mnOpenMode(nOpenMode), mbCountFinal(false)
+    {
+    }
+
+    bool DataSupplier::getData()
+    {
+        if ( mbCountFinal )
+            return true;
+
+        libcmis::ObjectPtr pObject = mxContent->getObject();
+        libcmis::Folder* pFolder = dynamic_cast< libcmis::Folder* >( pObject.get( ) );
+        if ( NULL != pFolder )
+        {
+            // Get the children from pObject
+            try
+            {
+                vector< libcmis::ObjectPtr > children = pFolder->getChildren( );
+
+                // Loop over the results and filter them
+                for ( vector< libcmis::ObjectPtr >::iterator it = children.begin();
+                        it != children.end(); ++it )
+                {
+                    bool bIsFolder = ( *it )->getBaseType( ) == "cmis:folder";
+                    if ( ( mnOpenMode == ucb::OpenMode::FOLDERS && bIsFolder ) ||
+                         ( mnOpenMode == ucb::OpenMode::DOCUMENTS && !bIsFolder ) ||
+                         ( mnOpenMode == ucb::OpenMode::ALL ) )
+                    {
+                        maResults.push_back( new ResultListEntry( *it ) );
+                    }
+                }
+                mbCountFinal = sal_True;
+
+                return true;
+            }
+            catch ( const libcmis::Exception& e )
+            {
+                SAL_INFO( "cmisucp", "Exception thrown: " << e.what() );
+                return false;
+            }
+        }
+
+        return false;
+    }
+
+    DataSupplier::~DataSupplier()
+    {
+    }
+
+    ::rtl::OUString DataSupplier::queryContentIdentifierString( sal_uInt32 nIndex )
+    {
+        if ( nIndex < maResults.size() )
+        {
+            ::rtl::OUString aId = maResults[ nIndex ]->aId;
+            if ( aId.getLength() )
+            {
+                // Already cached.
+                return aId;
+            }
+        }
+
+        if ( getResult( nIndex ) )
+        {
+            string sObjectId = maResults[nIndex]->pObject->getId( );
+
+            // Get the URL from the Id
+            URL aUrl( mxContent->getIdentifier( )->getContentIdentifier( ) );
+            aUrl.setObjectId( rtl::OUString::createFromAscii( sObjectId.c_str( ) ) );
+            rtl::OUString aId = aUrl.asString( );
+
+            maResults[ nIndex ]->aId = aId;
+            return aId;
+        }
+
+        return ::rtl::OUString();
+    }
+
+    uno::Reference< ucb::XContentIdentifier > DataSupplier::queryContentIdentifier( sal_uInt32 nIndex )
+    {
+        if ( nIndex < maResults.size() )
+        {
+            uno::Reference< ucb::XContentIdentifier > xId = maResults[ nIndex ]->xId;
+            if ( xId.is() )
+            {
+                // Already cached.
+                return xId;
+            }
+        }
+
+        ::rtl::OUString aId = queryContentIdentifierString( nIndex );
+        if ( aId.getLength() )
+        {
+            uno::Reference< ucb::XContentIdentifier > xId = new ucbhelper::ContentIdentifier( aId );
+            maResults[ nIndex ]->xId = xId;
+            return xId;
+        }
+
+        return uno::Reference< ucb::XContentIdentifier >();
+    }
+
+    uno::Reference< ucb::XContent > DataSupplier::queryContent( sal_uInt32 nIndex )
+    {
+        if ( nIndex < maResults.size() )
+        {
+            uno::Reference< ucb::XContent > xContent = maResults[ nIndex ]->xContent;
+            if ( xContent.is() )
+            {
+                // Already cached.
+                return xContent;
+            }
+        }
+
+        uno::Reference< ucb::XContentIdentifier > xId = queryContentIdentifier( nIndex );
+        if ( xId.is() )
+        {
+            try
+            {
+                uno::Reference< ucb::XContent > xContent = mxContent->getProvider()->queryContent( xId );
+                maResults[ nIndex ]->xContent = xContent;
+                return xContent;
+            }
+            catch ( ucb::IllegalIdentifierException& )
+            {
+            }
+        }
+        return uno::Reference< ucb::XContent >();
+    }
+
+    sal_Bool DataSupplier::getResult( sal_uInt32 nIndex )
+    {
+        if ( maResults.size() > nIndex ) // Result already present.
+            return sal_True;
+
+        if ( getData() && maResults.size() > nIndex )
+            return sal_True;
+
+        return sal_False;
+    }
+
+    sal_uInt32 DataSupplier::totalCount()
+    {
+        getData();
+        return maResults.size();
+    }
+
+    sal_uInt32 DataSupplier::currentCount()
+    {
+        return maResults.size();
+    }
+
+    sal_Bool DataSupplier::isCountFinal()
+    {
+        return mbCountFinal;
+    }
+
+    uno::Reference< sdbc::XRow > DataSupplier::queryPropertyValues( sal_uInt32 nIndex  )
+    {
+        if ( nIndex < maResults.size() )
+        {
+            uno::Reference< sdbc::XRow > xRow = maResults[ nIndex ]->xRow;
+            if ( xRow.is() )
+            {
+                // Already cached.
+                return xRow;
+            }
+        }
+
+        if ( getResult( nIndex ) )
+        {
+            uno::Reference< ucb::XContent > xContent( queryContent( nIndex ) );
+            if ( xContent.is() )
+            {
+                try
+                {
+                    uno::Reference< ucb::XCommandProcessor > xCmdProc(
+                        xContent, uno::UNO_QUERY_THROW );
+                    sal_Int32 nCmdId( xCmdProc->createCommandIdentifier() );
+                    ucb::Command aCmd;
+                    aCmd.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("getPropertyValues"));
+                    aCmd.Handle = -1;
+                    aCmd.Argument <<= getResultSet()->getProperties();
+                    uno::Any aResult( xCmdProc->execute(
+                        aCmd, nCmdId, getResultSet()->getEnvironment() ) );
+                    uno::Reference< sdbc::XRow > xRow;
+                    if ( aResult >>= xRow )
+                    {
+                        maResults[ nIndex ]->xRow = xRow;
+                        return xRow;
+                    }
+                }
+                catch ( uno::Exception const & )
+                {
+                }
+            }
+        }
+        return uno::Reference< sdbc::XRow >();
+    }
+
+    void DataSupplier::releasePropertyValues( sal_uInt32 nIndex )
+    {
+        if ( nIndex < maResults.size() )
+            maResults[ nIndex ]->xRow = uno::Reference< sdbc::XRow >();
+    }
+
+    void DataSupplier::close()
+    {
+    }
+
+    void DataSupplier::validate() throw( ucb::ResultSetException )
+    {
+    }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ucb/source/ucp/cmis/cmis_datasupplier.hxx b/ucb/source/ucp/cmis/cmis_datasupplier.hxx
new file mode 100644
index 0000000..14ad404
--- /dev/null
+++ b/ucb/source/ucp/cmis/cmis_datasupplier.hxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright 2012 LibreOffice contributors.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef CMIS_DATASUPPLIER_HXX
+#define CMIS_DATASUPPLIER_HXX
+
+#include <vector>
+
+#include <ucbhelper/resultset.hxx>
+
+#include "cmis_content.hxx"
+
+namespace cmis
+{
+
+    class Content;
+
+    struct ResultListEntry
+    {
+        ::rtl::OUString aId;
+        com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > xId;
+        com::sun::star::uno::Reference< com::sun::star::ucb::XContent > xContent;
+        com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > xRow;
+        libcmis::ObjectPtr pObject;
+
+        ResultListEntry( libcmis::ObjectPtr pObj ) : pObject( pObj )
+        {
+        }
+
+        ~ResultListEntry()
+        {
+        }
+    };
+
+    typedef std::vector< ResultListEntry* > ResultList;
+
+    class DataSupplier : public ucbhelper::ResultSetDataSupplier
+    {
+        private:
+            com::sun::star::uno::Reference< ::cmis::Content > mxContent;
+            com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xSMgr;
+            sal_Int32 mnOpenMode;
+            bool mbCountFinal;
+            bool getData();
+            ResultList maResults;
+
+        public:
+            DataSupplier( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+                const com::sun::star::uno::Reference< Content >& rContent, sal_Int32 nOpenMode );
+            virtual ~DataSupplier();
+
+            virtual rtl::OUString queryContentIdentifierString( sal_uInt32 nIndex );
+            virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier >
+                queryContentIdentifier( sal_uInt32 nIndex );
+            virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent >
+                queryContent( sal_uInt32 nIndex );
+
+            virtual sal_Bool getResult( sal_uInt32 nIndex );
+
+            virtual sal_uInt32 totalCount();
+            virtual sal_uInt32 currentCount();
+            virtual sal_Bool isCountFinal();
+
+            virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRow >
+                queryPropertyValues( sal_uInt32 nIndex  );
+            virtual void releasePropertyValues( sal_uInt32 nIndex );
+
+            virtual void close();
+
+            virtual void validate()
+                throw( com::sun::star::ucb::ResultSetException );
+    };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ucb/source/ucp/cmis/cmis_resultset.cxx b/ucb/source/ucp/cmis/cmis_resultset.cxx
new file mode 100644
index 0000000..b79b5f1
--- /dev/null
+++ b/ucb/source/ucp/cmis/cmis_resultset.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright 2012 LibreOffice contributors.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "cmis_datasupplier.hxx"
+#include "cmis_resultset.hxx"
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::uno;
+
+namespace cmis
+{
+    DynamicResultSet::DynamicResultSet(
+        const Reference< XMultiServiceFactory >& rxSMgr,
+        const Reference< Content >& rxContent,
+        const OpenCommandArgument2& rCommand,
+        const Reference< XCommandEnvironment >& rxEnv ) :
+            ResultSetImplHelper( rxSMgr, rCommand ),
+            m_xContent( rxContent ),
+            m_xEnv( rxEnv )
+    {
+    }
+
+    void DynamicResultSet::initStatic()
+    {
+        m_xResultSet1 = new ::ucbhelper::ResultSet(
+            m_xSMgr, m_aCommand.Properties,
+            new DataSupplier( m_xSMgr, m_xContent, m_aCommand.Mode ), m_xEnv );
+    }
+
+    void DynamicResultSet::initDynamic()
+    {
+        initStatic();
+        m_xResultSet2 = m_xResultSet1;
+    }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ucb/source/ucp/cmis/cmis_resultset.hxx b/ucb/source/ucp/cmis/cmis_resultset.hxx
new file mode 100644
index 0000000..bd40a8c
--- /dev/null
+++ b/ucb/source/ucp/cmis/cmis_resultset.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright 2012 LibreOffice contributors.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef CMIS_RESULTSET_HXX
+#define CMIS_RESULTSET_HXX
+
+#include <ucbhelper/resultsethelper.hxx>
+
+namespace cmis
+{
+
+    class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper
+    {
+        com::sun::star::uno::Reference< Content > m_xContent;
+        com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+
+        private:
+            virtual void initStatic();
+            virtual void initDynamic();
+
+        public:
+            DynamicResultSet(
+                    const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+                    const com::sun::star::uno::Reference< Content >& rxContent,
+                    const com::sun::star::ucb::OpenCommandArgument2& rCommand,
+                    const com::sun::star::uno::Reference<
+                    com::sun::star::ucb::XCommandEnvironment >& rxEnv );
+    };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 966d20e35d5a2be2fce6c204af5c156c3ead7063
Author: Cédric Bosdonnat <cedric.bosdonnat at free.fr>
Date:   Tue May 29 15:18:29 2012 +0200

    CMIS ucp: write documents back to CMIS server
    
    This change needs a git repo build of libcmis.
    
    Change-Id: I I740d18dbf3c36d9387b867e750fcbe8e114e5362

diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx
index 27d4398..6271acd 100644
--- a/sfx2/source/doc/docfile.cxx
+++ b/sfx2/source/doc/docfile.cxx
@@ -33,6 +33,7 @@
 #include <com/sun/star/task/XInteractionHandler.hpp>
 #include <com/sun/star/uno/Reference.h>
 #include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/container/XChild.hpp>
 #include <com/sun/star/document/XDocumentRevisionListPersistence.hpp>
 #include <com/sun/star/document/LockedDocumentRequest.hpp>
 #include <com/sun/star/document/OwnLockOnDocumentRequest.hpp>
@@ -1918,6 +1919,7 @@ void SfxMedium::Transfer_Impl()
                                                       Reference< ::com::sun::star::ucb::XProgressHandler >() );
 
         rtl::OUString aDestURL( aDest.GetMainURL( INetURLObject::NO_DECODE ) );
+
         if ( ::utl::LocalFileHelper::IsLocalFile( aDestURL ) || !aDest.removeSegment() )
         {
             TransactedTransferForFS_Impl( aSource, aDest, xComEnv );
@@ -1939,8 +1941,30 @@ void SfxMedium::Transfer_Impl()
             ::ucbhelper::Content aSourceContent;
             ::ucbhelper::Content aTransferContent;
 
-            String aFileName = GetLongName();
-            if ( !aFileName.Len() )
+            // Get the parent URL from the XChild if possible: why would the URL necessarily have
+            // a hierarchical path? It's not the case for CMIS.
+            ::ucbhelper::Content aDestContent;
+            ::ucbhelper::Content::create( aDestURL, xComEnv, aDestContent );
+            Reference< ::com::sun::star::container::XChild> xChild( aDestContent.get(), uno::UNO_QUERY );
+            rtl::OUString sParentUrl;
+            if ( xChild.is( ) )
+            {
+                Reference< ::com::sun::star::ucb::XContent > xParent( xChild->getParent( ), uno::UNO_QUERY );
+                if ( xParent.is( ) )
+                {
+                    sParentUrl = xParent->getIdentifier( )->getContentIdentifier();
+                }
+            }
+
+            if ( !sParentUrl.isEmpty() )
+                aDest = INetURLObject( sParentUrl );
+
+            // LongName wasn't defined anywhere, only used here... get the Title instead
+            // as it's less probably empty
+            rtl::OUString aFileName;
+            Any aAny = aDestContent.getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Title" )) );
+            aAny >>= aFileName;
+            if ( aFileName.isEmpty() )
                 aFileName = GetURLObject().getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
 
             try
diff --git a/ucb/source/ucp/cmis/cmis_content.cxx b/ucb/source/ucp/cmis/cmis_content.cxx
index 8c12f93..ead9f2d 100644
--- a/ucb/source/ucp/cmis/cmis_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_content.cxx
@@ -32,10 +32,19 @@
 #include <com/sun/star/beans/PropertyValue.hpp>
 #include <com/sun/star/beans/XPropertySetInfo.hpp>
 #include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XActiveDataStreamer.hpp>
+#include <com/sun/star/lang/IllegalAccessException.hpp>
+#include <com/sun/star/task/InteractionClassification.hpp>
+#include <com/sun/star/ucb/ContentInfo.hpp>
 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+#include <com/sun/star/ucb/MissingInputStreamException.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/NameClashException.hpp>
 #include <com/sun/star/ucb/OpenMode.hpp>
 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
+#include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
 #include <com/sun/star/ucb/XCommandInfo.hpp>
 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
@@ -44,17 +53,80 @@
 
 #include <ucbhelper/cancelcommandexecution.hxx>
 #include <ucbhelper/contentidentifier.hxx>
-#include <ucbhelper/fd_inputstream.hxx>
+#include <ucbhelper/std_inputstream.hxx>
+#include <ucbhelper/std_outputstream.hxx>
 #include <ucbhelper/propertyvalueset.hxx>
+#include <ucbhelper/simpleauthenticationrequest.hxx>
 
 #include "cmis_content.hxx"
 #include "cmis_provider.hxx"
-#include "cmis_url.hxx"
 
+#define OUSTR_TO_STDSTR(s) string( rtl::OUStringToOString( s, RTL_TEXTENCODING_UTF8 ).getStr() )
 
 using namespace com::sun::star;
 using namespace std;
 
+namespace
+{
+    class AuthProvider : public libcmis::AuthProvider
+    {
+        const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment>& m_xEnv;
+        rtl::OUString m_sUrl;
+        rtl::OUString m_sBindingUrl;
+
+        public:
+            AuthProvider ( const com::sun::star::uno::Reference<
+                                   com::sun::star::ucb::XCommandEnvironment>& xEnv,
+                           rtl::OUString sUrl,
+                           rtl::OUString sBindingUrl ):
+                m_xEnv( xEnv ), m_sUrl( sUrl ), m_sBindingUrl( sBindingUrl ) { }
+
+            bool authenticationQuery( string& username, string& password );
+    };
+
+    bool AuthProvider::authenticationQuery( string& username, string& password )
+    {
+        if ( m_xEnv.is() )
+        {
+            uno::Reference< task::XInteractionHandler > xIH
+                = m_xEnv->getInteractionHandler();
+
+            if ( xIH.is() )
+            {
+                rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest
+                    = new ucbhelper::SimpleAuthenticationRequest(
+                        m_sUrl, m_sBindingUrl, ::rtl::OUString(),
+                        rtl::OUString::createFromAscii( username.c_str( ) ),
+                        rtl::OUString::createFromAscii( password.c_str( ) ),
+                        ::rtl::OUString(), true, false );
+                xIH->handle( xRequest.get() );
+
+                rtl::Reference< ucbhelper::InteractionContinuation > xSelection
+                    = xRequest->getSelection();
+
+                if ( xSelection.is() )
+                {
+                    // Handler handled the request.
+                    uno::Reference< task::XInteractionAbort > xAbort(
+                        xSelection.get(), uno::UNO_QUERY );
+                    if ( !xAbort.is() )
+                    {
+                        const rtl::Reference<
+                            ucbhelper::InteractionSupplyAuthentication > & xSupp
+                            = xRequest->getAuthenticationSupplier();
+
+                        username = OUSTR_TO_STDSTR( xSupp->getUserName() );
+                        password = OUSTR_TO_STDSTR( xSupp->getPassword() );
+
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+}
+
 namespace cmis
 {
     Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
@@ -62,43 +134,85 @@ namespace cmis
             throw ( ucb::ContentCreationException )
         : ContentImplHelper( rxSMgr, pProvider, Identifier ),
         m_pProvider( pProvider ),
-        m_pSession( NULL )
+        m_pSession( NULL ),
+        m_bTransient( false )
     {
-#if OSL_DEBUG_LEVEL > 1
-    fprintf(stderr, "New Content ('%s')\n", rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
-#endif
         // Split the URL into bits
-        cmis::URL url( m_xIdentifier->getContentIdentifier() );
+        m_sURL = m_xIdentifier->getContentIdentifier( );
+        cmis::URL url( m_sURL );
 
-        // Initiate a CMIS session
-        m_pSession = libcmis::SessionFactory::createSession( url.getSessionParams( ) );
+        // Look for a cached session
+        m_pSession = pProvider->getSession( url.getBindingUrl( ) );
+        if ( NULL == m_pSession )
+        {
+            // Initiate a CMIS session and register it as we found nothing
+            m_pSession = libcmis::SessionFactory::createSession( url.getSessionParams( ) );
+            pProvider->registerSession( url.getBindingUrl( ), m_pSession );
+        }
 
-        // Get the content Object
-        m_pObject = m_pSession->getObject( url.getObjectId() );
+        m_sObjectId = url.getObjectId( );
+        m_sBindingUrl = url.getBindingUrl( );
     }
 
     Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, ContentProvider *pProvider,
         const uno::Reference< ucb::XContentIdentifier >& Identifier,
-        sal_Bool /*bIsFolder*/)
+        sal_Bool bIsFolder )
             throw ( ucb::ContentCreationException )
         : ContentImplHelper( rxSMgr, pProvider, Identifier ),
         m_pProvider( pProvider ),
-        m_pSession( NULL )
+        m_pSession( NULL ),
+        m_bTransient( true )
     {
-#if OSL_DEBUG_LEVEL > 1
-    fprintf(stderr, "TODO - Create Content ('%s')\n", rtl::OUStringToOString(m_xIdentifier->getContentIdentifier(), RTL_TEXTENCODING_UTF8).getStr());
-#endif
-        // TODO Implement me
+        // Split the URL into bits
+        m_sURL = m_xIdentifier->getContentIdentifier( );
+        cmis::URL url( m_sURL );
+
+        // Look for a cached session
+        m_pSession = pProvider->getSession( url.getBindingUrl( ) );
+        if ( NULL == m_pSession )
+        {
+            // Initiate a CMIS session and register it as we found nothing
+            m_pSession = libcmis::SessionFactory::createSession( url.getSessionParams( ) );
+            pProvider->registerSession( url.getBindingUrl( ), m_pSession );
+        }
+
+        m_sObjectId = url.getObjectId( );
+        m_sBindingUrl = url.getBindingUrl( );
+
+        // Get the object type
+        string typeId = bIsFolder ? "cmis:folder" : "cmis:document";
+        m_pObjectType = m_pSession->getType( typeId );
     }
 
     Content::~Content()
     {
-        delete m_pSession;
     }
 
-    bool Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/)
+    libcmis::ObjectPtr Content::getObject( )
     {
-        return m_pObject->getBaseType( ) == "cmis::folder";
+        try
+        {
+            if ( !m_pObject.get() )
+                m_pObject = m_pSession->getObject( OUSTR_TO_STDSTR( m_sObjectId ) );
+        }
+        catch ( const libcmis::Exception& e )
+        {
+            SAL_INFO( "cmisucp", "Unexpected exception: " << e.what() );
+        }
+
+        return m_pObject;
+    }
+
+    void Content::resetAuthProvider( const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+    {
+        libcmis::AuthProviderPtr authProvider( new AuthProvider( xEnv, m_sURL, m_sBindingUrl ) );
+        m_pSession->setAuthenticationProvider( authProvider );
+    }
+
+    bool Content::isFolder(const uno::Reference< ucb::XCommandEnvironment >& xEnv )
+    {
+        resetAuthProvider( xEnv );
+        return getObject( )->getBaseType( ) == "cmis:folder";
     }
 
     uno::Any Content::getBadArgExcept()
@@ -110,11 +224,10 @@ namespace cmis
 
     uno::Reference< sdbc::XRow > Content::getPropertyValues(
             const uno::Sequence< beans::Property >& rProperties,
-            const uno::Reference< ucb::XCommandEnvironment >& /*xEnv*/ )
+            const uno::Reference< ucb::XCommandEnvironment >& xEnv )
     {
-#if OSL_DEBUG_LEVEL > 1
-        fprintf( stderr, "TODO - cmis::Content::getPropertyValues()\n" );
-#endif
+        resetAuthProvider( xEnv );
+
         rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( m_xSMgr );
 
         sal_Int32 nProps;
@@ -126,59 +239,84 @@ namespace cmis
         for( sal_Int32 n = 0; n < nProps; ++n )
         {
             const beans::Property& rProp = pProps[ n ];
-#if OSL_DEBUG_LEVEL > 1
-            fprintf( stderr, "Property: %s\n", rtl::OUStringToOString( rProp.Name, RTL_TEXTENCODING_UTF8 ).getStr() );
-#endif
 
             if ( rProp.Name == "IsDocument" )
             {
-                if ( m_pObject->getBaseType( ) == "cmis:document" )
+                if ( getObject()->getBaseType( ) == "cmis:document" )
                     xRow->appendBoolean( rProp, true );
                 else
                     xRow->appendVoid( rProp );
             }
             else if ( rProp.Name == "IsFolder" )
             {
-                if( m_pObject->getBaseType( ) == "cmis:folder" )
+                if( getObject()->getBaseType( ) == "cmis:folder" )
                     xRow->appendBoolean( rProp, true );
                 else
                     xRow->appendVoid( rProp );
             }
+            else if ( rProp.Name == "Title" )
+            {
+                string name = getObject()->getName();
+                xRow->appendString( rProp, rtl::OUString::createFromAscii( name.c_str() ) );
+            }
             else if ( rProp.Name == "TitleOnServer" )
             {
-                // TODO Set the path instead of the name
-                xRow->appendString( rProp, rtl::OUString::createFromAscii( m_pObject->getName().c_str() ) );
+                string path;
+                libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject().get( ) );
+                if ( NULL != document )
+                {
+                    vector< boost::shared_ptr< libcmis::Folder > > parents = document->getParents( );
+                    if ( parents.size() > 0 )
+                        path = parents.front( )->getPath( );
+
+                    if ( path[ path.length() - 1 ] != '/' )
+                        path += "/";
+                    path += getObject()->getName( );
+                }
+                else
+                {
+                    libcmis::Folder* folder = dynamic_cast< libcmis::Folder* >( getObject().get( ) );
+                    if ( NULL != folder )
+                        path = folder->getPath( );
+                }
+
+                xRow->appendString( rProp, rtl::OUString::createFromAscii( path.c_str() ) );
             }
             else if ( rProp.Name == "IsReadOnly" )
             {
-                // TODO Fix this value
-                xRow->appendBoolean( rProp, sal_True );
+                boost::shared_ptr< libcmis::AllowableActions > allowableActions = getObject()->getAllowableActions( );
+                sal_Bool bReadOnly = sal_False;
+                if ( allowableActions->isAllowed( libcmis::ObjectAction::SetContentStream ) )
+                    bReadOnly = sal_True;
+
+                xRow->appendBoolean( rProp, bReadOnly );
             }
             else if ( rProp.Name == "DateCreated" )
             {
                 // TODO Fix this value
+                SAL_INFO( "cmisucp", "TODO - Fix property value " << rProp.Name );
                 xRow->appendVoid( rProp );
             }
             else if ( rProp.Name == "DateModified" )
             {
                 // TODO Fix this value
+                SAL_INFO( "cmisucp", "TODO - Fix property value " << rProp.Name );
                 xRow->appendVoid( rProp );
             }
             else if ( rProp.Name == "Size" )
             {
-                libcmis::Document* document = dynamic_cast< libcmis::Document* >( m_pObject.get( ) );
+                libcmis::Document* document = dynamic_cast< libcmis::Document* >( getObject().get( ) );
                 if ( NULL != document )
                     xRow->appendLong( rProp, document->getContentLength() );
                 else
                     xRow->appendVoid( rProp );
             }
-#if OSL_DEBUG_LEVEL > 1
-            else
+            else if ( rProp.Name == "CreatableContentsInfo" )
             {
-                fprintf( stderr, "Looking for unsupported property %s\n",
-                    rtl::OUStringToOString( rProp.Name, RTL_TEXTENCODING_UTF8 ).getStr( ) );
+                xRow->appendObject( rProp, uno::makeAny( queryCreatableContentsInfo( xEnv ) ) );
             }
-#endif
+            else
+                SAL_INFO( "cmisucp", "Looking for unsupported property " << rProp.Name );
         }
 
         return uno::Reference< sdbc::XRow >( xRow.get() );
@@ -186,9 +324,7 @@ namespace cmis
 
     void Content::queryChildren( ContentRefList& /*rChildren*/ )
     {
-#if OSL_DEBUG_LEVEL > 1
-        fprintf( stderr, "TODO - cmis::Content::queryChildren()\n" );
-#endif
+        SAL_INFO( "cmisucp", "TODO - Content::queryChildren()" );
         // TODO Implement me
     }
 
@@ -210,10 +346,8 @@ namespace cmis
 
         if ( bOpenFolder && bIsFolder )
         {
-#if OSL_DEBUG_LEVEL > 1
-        fprintf( stderr, "TODO - cmis::Content::open() - Folder case\n" );
-#endif

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list