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