xref: /trunk/main/ucb/source/ucp/odma/odma_provider.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_ucb.hxx"
26 
27 /**************************************************************************
28                                 TODO
29  **************************************************************************
30 
31  *************************************************************************/
32 #include <ucbhelper/contentidentifier.hxx>
33 #include "odma_provider.hxx"
34 #include "odma_content.hxx"
35 #include "odma_contentprops.hxx"
36 #include <com/sun/star/util/Date.hpp>
37 #include <com/sun/star/util/Time.hpp>
38 #include <rtl/uri.hxx>
39 #include <algorithm>
40 #include <osl/file.hxx>
41 
42 using namespace com::sun::star;
43 using namespace odma;
44 
45 //=========================================================================
46 //=========================================================================
47 //
48 // ContentProvider Implementation.
49 //
50 //=========================================================================
51 //=========================================================================
52 ODMHANDLE ContentProvider::m_aOdmHandle = NULL;
53 
ContentProvider(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)54 ContentProvider::ContentProvider(
55                 const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
56 : ::ucbhelper::ContentProviderImplHelper( rSMgr )
57 {
58 
59 }
60 
61 //=========================================================================
62 // virtual
~ContentProvider()63 ContentProvider::~ContentProvider()
64 {
65     ContentsMap::iterator aIter = m_aContents.begin();
66     for (;aIter != m_aContents.end() ;++aIter )
67     {
68         if(aIter->second->m_bIsOpen)
69             closeDocument(aIter->first);
70     }
71     if(m_aOdmHandle)
72     {
73         NODMUnRegisterApp(m_aOdmHandle);
74         m_aOdmHandle = NULL;
75     }
76 }
77 // -----------------------------------------------------------------------------
getHandle()78 ODMHANDLE ContentProvider::getHandle()
79 {
80     if(!m_aOdmHandle)
81     {
82         ODMSTATUS odm = NODMRegisterApp(&m_aOdmHandle,ODM_API_VERSION,ODMA_ODMA_REGNAME,NULL,NULL);
83         switch(odm)
84         {
85         case ODM_SUCCESS:
86             break;
87         case ODM_E_NODMS:
88             break;
89         case ODM_E_CANTINIT:
90             break;
91         case ODM_E_VERSION:
92             break;
93         default:
94             break;
95         }
96     }
97     return m_aOdmHandle;
98 }
99 // -----------------------------------------------------------------------------
100 
101 //=========================================================================
102 //
103 // XInterface methods.
104 //
105 //=========================================================================
106 
107 // @@@ Add own interfaces.
108 XINTERFACE_IMPL_3( ContentProvider,
109                    lang::XTypeProvider,
110                    lang::XServiceInfo,
111                    ucb::XContentProvider );
112 
113 //=========================================================================
114 //
115 // XTypeProvider methods.
116 //
117 //=========================================================================
118 
119 // @@@ Add own interfaces.
120 XTYPEPROVIDER_IMPL_3( ContentProvider,
121                       lang::XTypeProvider,
122                       lang::XServiceInfo,
123                       ucb::XContentProvider );
124 
125 //=========================================================================
126 //
127 // XServiceInfo methods.
128 //
129 //=========================================================================
130 
131 // @@@ Adjust implementation name. Keep the prefix "com.sun.star.comp."!
132 // @@@ Adjust service name.
133 XSERVICEINFO_IMPL_1( ContentProvider,
134                      rtl::OUString::createFromAscii(
135                             "com.sun.star.comp.odma.ContentProvider" ),
136                      rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODMA_CONTENT_PROVIDER_SERVICE_NAME) ) );
137 
138 //=========================================================================
139 //
140 // Service factory implementation.
141 //
142 //=========================================================================
143 
144 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider );
145 
146 //=========================================================================
147 //
148 // XContentProvider methods.
149 //
150 //=========================================================================
151 
152 // virtual
queryContent(const uno::Reference<ucb::XContentIdentifier> & Identifier)153 uno::Reference< ucb::XContent > SAL_CALL ContentProvider::queryContent(
154         const uno::Reference< ucb::XContentIdentifier >& Identifier )
155 {
156     // Check URL scheme...
157     if(!getHandle())
158         throw ucb::IllegalIdentifierException();
159 
160     rtl::OUString aScheme( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(ODMA_URL_SCHEME) ) );
161     sal_Int32 nIndex = 0;
162     rtl::OUString sOdma = aScheme.getToken(3,'.',nIndex);
163     rtl::OUString sCanonicURL = Identifier->getContentIdentifier();
164     // check if url starts with odma
165     if ( !(Identifier->getContentProviderScheme().equalsIgnoreAsciiCase( aScheme ) ||
166            Identifier->getContentProviderScheme().equalsIgnoreAsciiCase( sOdma )) )
167         throw ucb::IllegalIdentifierException();
168 
169     if(!(   sCanonicURL.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(ODMA_URL_SCHEME_SHORT ODMA_URL_SHORT)) ||
170             sCanonicURL.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(ODMA_URL_SCHEME ODMA_URL_SHORT))))
171         throw ucb::IllegalIdentifierException();
172 
173     // @@@ Further id checks may go here...
174 #if 0
175     if ( id-check-failes )
176         throw ucb::IllegalIdentifierException();
177 #endif
178 
179     // @@@ Id normalization may go here...
180 #if 0
181     // Normalize URL and create new Id.
182     rtl::OUString aCanonicURL = ( Identifier->getContentIdentifier() );
183     uno::Reference< ucb::XContentIdentifier > xCanonicId
184         = new ::ucb::ContentIdentifier( m_xSMgr, aCanonicURL );
185 #else
186     uno::Reference< ucb::XContentIdentifier > xCanonicId = Identifier;
187 #endif
188 
189     osl::MutexGuard aGuard( m_aMutex );
190 
191     // Check, if a content with given id already exists...
192     uno::Reference< ucb::XContent > xContent
193         = queryExistingContent( xCanonicId ).get();
194     if ( xContent.is() )
195         return xContent;
196 
197     // @@@ Decision, which content implementation to instantiate may be
198     //     made here ( in case you have different content classes ).
199 
200     // Create a new content.
201 
202     sCanonicURL = convertURL(sCanonicURL);
203 
204     ::rtl::Reference<ContentProperties> aProp;
205     // first check if we got an ODMA ID from outside
206     if( sCanonicURL.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(ODMA_URL_ODMAID)))
207     {// we get an original ODMA id so we have to look for the name
208         ::rtl::OString sDocId = ::rtl::OUStringToOString(sCanonicURL,RTL_TEXTENCODING_MS_1252);
209         sal_Char* lpszDocName = new sal_Char[ODM_NAME_MAX];
210 
211         ODMSTATUS odm = NODMGetDocInfo( getHandle(),
212                                         const_cast<sal_Char*>(sDocId.getStr()),
213                                         ODM_NAME,
214                                         lpszDocName,
215                                         ODM_NAME_MAX
216                                     );
217         if(odm == ODM_SUCCESS)
218         {
219             aProp = new ContentProperties();
220             aProp->m_sDocumentName = ::rtl::OStringToOUString(rtl::OString(lpszDocName),RTL_TEXTENCODING_ASCII_US);
221             aProp->m_sDocumentId   = sDocId;
222             aProp->m_sContentType  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ODMA_CONTENT_TYPE));
223             append(aProp);
224         }
225         delete [] lpszDocName;
226     }
227     else // we got an already fetched name here so look for it
228     {
229         // we have a valid document name
230         aProp = getContentPropertyWithTitle(sCanonicURL);
231         if(!aProp.is())
232             aProp = getContentPropertyWithSavedAsName(sCanonicURL);
233         if(!aProp.is())
234         {
235             if(sCanonicURL.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("/")))
236             { // found only the scheme
237                 aProp = new ContentProperties();
238                 aProp->m_sDocumentId = "/";
239                 aProp->m_sTitle = sCanonicURL;
240                 aProp->m_bIsFolder = sal_True;
241                 aProp->m_bIsDocument = !aProp->m_bIsFolder;
242                 m_aContents.insert(ContentsMap::value_type(aProp->m_sDocumentId,aProp));
243             }
244             else
245                 aProp = queryContentProperty(sCanonicURL);
246         }
247     }
248     if(!aProp.is())
249         throw ucb::IllegalIdentifierException();
250 
251     xContent = new Content( m_xSMgr, this, xCanonicId ,aProp);
252     registerNewContent( xContent );
253 
254     if ( !xContent->getIdentifier().is() )
255         throw ucb::IllegalIdentifierException();
256 
257     return xContent;
258 }
259 // -----------------------------------------------------------------------------
closeDocument(const::rtl::OString & _sDocumentId)260 void ContentProvider::closeDocument(const ::rtl::OString& _sDocumentId)
261 {
262     ContentsMap::iterator aIter = m_aContents.find(_sDocumentId);
263     if(aIter != m_aContents.end())
264     {
265         DWORD dwFlags = ODM_SILENT;
266         ODMSTATUS odm = NODMCloseDocEx( ContentProvider::getHandle(),
267                                         const_cast<sal_Char*>(_sDocumentId.getStr()),
268                                         &dwFlags,
269                                         0xFFFFFFFF,
270                                         0xFFFFFFFF,
271                                         NULL,
272                                         0);
273         OSL_ENSURE(odm == ODM_SUCCESS,"Error while closing a document!");
274         if(odm == ODM_SUCCESS)
275             aIter->second->m_bIsOpen = sal_False;
276     }
277 }
278 // -----------------------------------------------------------------------------
saveDocument(const::rtl::OString & _sDocumentId)279 void ContentProvider::saveDocument(const ::rtl::OString& _sDocumentId)
280 {
281     ContentsMap::iterator aIter = m_aContents.find(_sDocumentId);
282     if(aIter != m_aContents.end())
283     {
284         sal_Char* lpszDocId = new sal_Char[ODM_DOCID_MAX];
285         DWORD dwFlags = ODM_SILENT;
286         ODMSTATUS odm = NODMSaveDocEx(getHandle(),
287                                     const_cast<sal_Char*>(_sDocumentId.getStr()),
288                                     lpszDocId,
289                                     &dwFlags);
290         OSL_ENSURE(odm == ODM_SUCCESS,"Could not save document!");
291         if(odm != ODM_SUCCESS)
292         {
293             delete [] lpszDocId;
294             throw uno::Exception();
295         }
296         aIter->second->m_sDocumentId = rtl::OString(lpszDocId);
297         delete [] lpszDocId;
298     }
299 }
300 // -----------------------------------------------------------------------------
toDate(const::rtl::OString & _sSQLString)301 util::Date toDate(const ::rtl::OString& _sSQLString)
302 {
303     sal_uInt16  nYear   = 0,
304                 nMonth  = 0,
305                 nDay    = 0;
306     nYear   = (sal_uInt16)_sSQLString.copy(0,4).toInt32();
307     nMonth  = (sal_uInt16)_sSQLString.copy(4,2).toInt32();
308     nDay    = (sal_uInt16)_sSQLString.copy(6,2).toInt32();
309 
310     return util::Date(nDay,nMonth,nYear);
311 }
312 //-----------------------------------------------------------------------------
toTime(const::rtl::OString & _sSQLString)313 util::Time toTime(const ::rtl::OString& _sSQLString)
314 {
315     sal_uInt16  nHour   = 0,
316                 nMinute = 0,
317                 nSecond = 0;
318     nHour   = (sal_uInt16)_sSQLString.copy(8,2).toInt32();
319     nMinute = (sal_uInt16)_sSQLString.copy(10,2).toInt32();
320     nSecond = (sal_uInt16)_sSQLString.copy(12,2).toInt32();
321 
322     return util::Time(0,nHour,nMinute,nSecond);
323 }
324 //-----------------------------------------------------------------------------
toDateTime(const::rtl::OString & _sSQLString)325 util::DateTime toDateTime(const ::rtl::OString& _sSQLString)
326 {
327     util::Date aDate = toDate(_sSQLString);
328     util::Time aTime = toTime(_sSQLString);
329 
330     return util::DateTime(0,aTime.Seconds,aTime.Minutes,aTime.Hours,aDate.Day,aDate.Month,aDate.Year);
331 }
332 // -----------------------------------------------------------------------------
fillDocumentProperties(const::rtl::Reference<ContentProperties> & _rProp)333 void ContentProvider::fillDocumentProperties(const ::rtl::Reference<ContentProperties>& _rProp)
334 {
335     // read some properties from the DMS
336     sal_Char* lpszDocInfo = new sal_Char[ODM_DOCID_MAX];
337     sal_Char* pDocId = const_cast<sal_Char*>(_rProp->m_sDocumentId.getStr());
338 
339     // read the create date of the document
340     ODMSTATUS odm = NODMGetDocInfo( getHandle(),
341                                     pDocId,
342                                     ODM_CREATEDDATE,
343                                     lpszDocInfo,
344                                     ODM_DOCID_MAX);
345     if(odm == ODM_SUCCESS)
346         _rProp->m_aDateCreated = toDateTime(::rtl::OString(lpszDocInfo));
347 
348     // read the modified date of the document
349     odm = NODMGetDocInfo(   getHandle(),
350                             pDocId,
351                             ODM_MODIFYDATE,
352                             lpszDocInfo,
353                             ODM_DOCID_MAX);
354     if(odm == ODM_SUCCESS)
355         _rProp->m_aDateModified = toDateTime(::rtl::OString(lpszDocInfo));
356 
357     // read the title of the document
358     odm = NODMGetDocInfo(   getHandle(),
359                             pDocId,
360                             ODM_TITLETEXT,
361                             lpszDocInfo,
362                             ODM_DOCID_MAX);
363     if(odm == ODM_SUCCESS)
364         _rProp->m_sTitle = ::rtl::OStringToOUString(rtl::OString(lpszDocInfo),RTL_TEXTENCODING_ASCII_US);
365 
366     // read the name of the document
367     odm = NODMGetDocInfo(   getHandle(),
368                             pDocId,
369                             ODM_NAME,
370                             lpszDocInfo,
371                             ODM_DOCID_MAX);
372     if(odm == ODM_SUCCESS)
373         _rProp->m_sDocumentName = ::rtl::OStringToOUString(rtl::OString(lpszDocInfo),RTL_TEXTENCODING_ASCII_US);
374 
375     // read the author of the document
376     odm = NODMGetDocInfo(   getHandle(),
377                             pDocId,
378                             ODM_AUTHOR,
379                             lpszDocInfo,
380                             ODM_DOCID_MAX);
381     if(odm == ODM_SUCCESS)
382         _rProp->m_sAuthor = ::rtl::OStringToOUString(rtl::OString(lpszDocInfo),RTL_TEXTENCODING_ASCII_US);
383 
384     // read the subject of the document
385     odm = NODMGetDocInfo(   getHandle(),
386                             pDocId,
387                             ODM_SUBJECT,
388                             lpszDocInfo,
389                             ODM_DOCID_MAX);
390     if(odm == ODM_SUCCESS)
391         _rProp->m_sSubject = ::rtl::OStringToOUString(rtl::OString(lpszDocInfo),RTL_TEXTENCODING_ASCII_US);
392 
393     // read the keywords of the document
394     odm = NODMGetDocInfo(   getHandle(),
395                             pDocId,
396                             ODM_KEYWORDS,
397                             lpszDocInfo,
398                             ODM_DOCID_MAX);
399     if(odm == ODM_SUCCESS)
400         _rProp->m_sKeywords = ::rtl::OStringToOUString(rtl::OString(lpszDocInfo),RTL_TEXTENCODING_ASCII_US);
401 
402 /*
403     odm = NODMGetDocInfo(   getHandle(),
404                                     const_cast<sal_Char*>(_rProp->m_sDocumentId.getStr()),
405                                     ODM_URL,
406                                     lpszDocInfo,
407                                     ODM_DOCID_MAX);
408 */
409     delete [] lpszDocInfo;
410 }
411 // -----------------------------------------------------------------------------
append(const::rtl::Reference<ContentProperties> & _rProp)412 void ContentProvider::append(const ::rtl::Reference<ContentProperties>& _rProp)
413 {
414     // now fill some more properties
415     fillDocumentProperties(_rProp);
416     // and append them
417     m_aContents.insert(ContentsMap::value_type(_rProp->m_sDocumentId,_rProp));
418 }
419 // -----------------------------------------------------------------------------
queryContentProperty(const::rtl::OUString & _sDocumentName)420 ::rtl::Reference<ContentProperties> ContentProvider::queryContentProperty(const ::rtl::OUString& _sDocumentName)
421 {
422     ::rtl::Reference<ContentProperties> aReturn;
423     sal_Char* lpszDMSList   = new sal_Char[ODM_DMSID_MAX];
424 
425     ODMSTATUS odm = NODMGetDMS(ODMA_ODMA_REGNAME, lpszDMSList);
426     if(odm == ODM_SUCCESS)
427     {
428         sal_Char* pQueryId = new sal_Char[ODM_QUERYID_MAX];
429         lpszDMSList[strlen(lpszDMSList)+1] = '\0';
430 
431         ::rtl::OString sTitleText(::rtl::OUStringToOString(_sDocumentName,RTL_TEXTENCODING_ASCII_US));
432         ::rtl::OString sQuery("SELECT ODM_DOCID, ODM_NAME WHERE ODM_TITLETEXT = '");
433         sQuery += sTitleText;
434         sQuery += "'";
435 
436         DWORD dwFlags = ODM_SPECIFIC;
437         odm = NODMQueryExecute(getHandle(), sQuery,dwFlags, lpszDMSList, pQueryId );
438         if(odm == ODM_SUCCESS)
439         {
440             sal_uInt16 nCount       = 10;
441             sal_uInt16 nMaxCount    = 10;
442             sal_Char* lpszDocId     = new sal_Char[ODM_DOCID_MAX * nMaxCount];
443             sal_Char* lpszDocName   = new sal_Char[ODM_NAME_MAX * nMaxCount];
444             sal_Char* lpszDocInfo   = new sal_Char[ODM_DOCID_MAX];
445 
446             ::rtl::OUString sContentType(RTL_CONSTASCII_USTRINGPARAM(ODMA_CONTENT_TYPE));
447             do
448             {
449                 if(nCount >= nMaxCount)
450                 {
451                     // get the result
452                     nCount = nMaxCount;
453                     odm = NODMQueryGetResults(getHandle(), pQueryId,lpszDocId, lpszDocName, ODM_NAME_MAX, (WORD*)&nCount);
454                 }
455                 if(odm == ODM_SUCCESS)
456                     for(sal_uInt16 i = 0; i < nCount; ++i)
457                     {
458                         odm = NODMGetDocInfo(   getHandle(),
459                                                 &lpszDocId[ODM_DOCID_MAX*i],
460                                                 ODM_TITLETEXT,
461                                                 lpszDocInfo,
462                                                 ODM_DOCID_MAX);
463                         if( odm == ODM_SUCCESS && sTitleText == ::rtl::OString(lpszDocInfo))
464                         {
465                             aReturn = new ContentProperties();
466                             aReturn->m_sDocumentName    = ::rtl::OStringToOUString(rtl::OString(&lpszDocName[ODM_NAME_MAX*i]),RTL_TEXTENCODING_ASCII_US);
467                             aReturn->m_sDocumentId  = ::rtl::OString(&lpszDocId[ODM_DOCID_MAX*i]);
468                             aReturn->m_sContentType = sContentType;
469                             append(aReturn);
470                             nCount = 0; // break condition from outer loop
471                             break;
472                         }
473                     }
474             }
475             while(nCount > nMaxCount);
476 
477             delete [] lpszDocInfo;
478             delete [] lpszDocId;
479             delete [] lpszDocName;
480         }
481 
482         // now close the query
483         odm = NODMQueryClose(ContentProvider::getHandle(), pQueryId);
484         delete [] pQueryId;
485     }
486     delete [] lpszDMSList;
487 
488 
489     return aReturn;
490 }
491 // -----------------------------------------------------------------------------
getContentProperty(const::rtl::OUString & _sName,const ContentPropertiesMemberFunctor & _aFunctor) const492 ::rtl::Reference<ContentProperties> ContentProvider::getContentProperty(const ::rtl::OUString& _sName,
493                                                                    const ContentPropertiesMemberFunctor& _aFunctor) const
494 {
495     ::rtl::Reference<ContentProperties> aReturn;
496     ContentsMap::const_iterator aFind = ::std::find_if( m_aContents.begin(),
497                                                         m_aContents.end(),
498                                                         ::std::compose1(
499                                                             ::std::bind2nd(_aFunctor,_sName),
500                                                             ::std::select2nd<ContentsMap::value_type>()
501                                                         )
502                                                     );
503     if(aFind != m_aContents.end())
504         aReturn = aFind->second;
505     return aReturn;
506 }
507 // -----------------------------------------------------------------------------
getContentPropertyWithSavedAsName(const::rtl::OUString & _sSaveAsName) const508 ::rtl::Reference<ContentProperties> ContentProvider::getContentPropertyWithSavedAsName(const ::rtl::OUString& _sSaveAsName) const
509 {
510     ContentPropertiesMemberFunctor aFunc(::std::mem_fun(&ContentProperties::getSavedAsName));
511     return getContentProperty(_sSaveAsName,aFunc);
512 }
513 // -----------------------------------------------------------------------------
getContentPropertyWithTitle(const::rtl::OUString & _sTitle) const514 ::rtl::Reference<ContentProperties> ContentProvider::getContentPropertyWithTitle(const ::rtl::OUString& _sTitle) const
515 {
516     ContentPropertiesMemberFunctor aFunc(::std::mem_fun(&ContentProperties::getTitle));
517     return getContentProperty(_sTitle,aFunc);
518 }
519 // -----------------------------------------------------------------------------
openDoc(const::rtl::Reference<ContentProperties> & _rProp)520 ::rtl::OUString ContentProvider::openDoc(const ::rtl::Reference<ContentProperties>& _rProp)
521 {
522     OSL_ENSURE(_rProp.is(),"No valid content properties!");
523     if(!_rProp->m_bIsOpen)
524     {
525         sal_Char *pFileName = new sal_Char[ODM_FILENAME_MAX];
526 
527         DWORD dwFlag = ODM_MODIFYMODE | ODM_SILENT;
528         ODMSTATUS odm = NODMOpenDoc(getHandle(), dwFlag, const_cast<sal_Char*>(_rProp->m_sDocumentId.getStr()), pFileName);
529         switch(odm)
530         {
531             case ODM_E_INUSE:
532                 dwFlag = ODM_VIEWMODE;
533                 if( NODMOpenDoc(getHandle(), dwFlag, const_cast<sal_Char*>(_rProp->m_sDocumentId.getStr()), pFileName) != ODM_SUCCESS)
534                     break;
535                 // else run through
536             case ODM_SUCCESS:
537                 ::osl::FileBase::getFileURLFromSystemPath(::rtl::OStringToOUString(rtl::OString(pFileName),RTL_TEXTENCODING_ASCII_US)
538                                                             ,_rProp->m_sFileURL);
539                 _rProp->m_bIsOpen = sal_True;
540                 break;
541             default:
542                 delete [] pFileName;
543                 throw uno::Exception();  // TODO give a more precise error message here
544         }
545 
546         delete [] pFileName;
547     }
548     return _rProp->m_sFileURL;
549 }
550 // -----------------------------------------------------------------------------
convertURL(const::rtl::OUString & _sCanonicURL)551 ::rtl::OUString ContentProvider::convertURL(const ::rtl::OUString& _sCanonicURL)
552 {
553     sal_Int32 nPos = 0;
554     // check if url starts with odma
555     if(_sCanonicURL.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(ODMA_URL_SCHEME_SHORT ODMA_URL_SHORT)))
556     { // URL starts with odma:// so we have to remove this
557         nPos = ODMA_URL_SHORT_LGTH;
558     }
559     else if(_sCanonicURL.matchIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM(ODMA_URL_SCHEME ODMA_URL_SHORT)))
560     { // URL starts with vnd.sun.star.odma:/// so we have to remove this
561         nPos = ODMA_URL_LGTH;
562     }
563 
564     ::rtl::OUString sCanonicURL = _sCanonicURL;
565     // now check what formats we allow
566     if(nPos == _sCanonicURL.getLength()) // only ask for root entry
567         sCanonicURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
568 
569     if(nPos < sCanonicURL.getLength())
570     {
571         sCanonicURL = sCanonicURL.copy(nPos);
572         sCanonicURL = rtl::Uri::decode(sCanonicURL,rtl_UriDecodeWithCharset,RTL_TEXTENCODING_UTF8);
573     }
574     if(sCanonicURL.getLength() > 1 && sCanonicURL.getStr()[0] == sal_Unicode('/'))
575     {
576         sCanonicURL = sCanonicURL.copy(1);
577         if(sCanonicURL.getLength() == 1 && sCanonicURL.getStr()[0] == sal_Unicode('.'))
578             sCanonicURL = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
579     }
580     return sCanonicURL;
581 }
582 // -----------------------------------------------------------------------------
deleteDocument(const::rtl::Reference<ContentProperties> & _rProp)583 sal_Bool ContentProvider::deleteDocument(const ::rtl::Reference<ContentProperties>& _rProp)
584 {
585     closeDocument(_rProp->m_sDocumentId);
586     ODMSTATUS odm = NODMActivate(ContentProvider::getHandle(),
587                                  ODM_DELETE,
588                                  const_cast< sal_Char*>(_rProp->m_sDocumentId.getStr()));
589     if(odm == ODM_SUCCESS)
590         m_aContents.erase(_rProp->m_sDocumentId);
591 
592     return odm == ODM_SUCCESS;
593 }
594 // -----------------------------------------------------------------------------
595