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_dbaccess.hxx"
26 #ifndef DBA_CONTENTHELPER_HXX
27 #include "ContentHelper.hxx"
28 #endif
29 #ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX_
30 #include <ucbhelper/cancelcommandexecution.hxx>
31 #endif
32 #ifndef _COMPHELPER_PROPERTY_HXX_
33 #include <comphelper/property.hxx>
34 #endif
35 #ifndef _COM_SUN_STAR_UCB_UNSUPPORTEDCOMMANDEXCEPTION_HPP_
36 #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
37 #endif
38 #ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_
39 #include <com/sun/star/lang/IllegalArgumentException.hpp>
40 #endif
41 #ifndef _COM_SUN_STAR_LANG_ILLEGALACCESSEXCEPTION_HPP_
42 #include <com/sun/star/lang/IllegalAccessException.hpp>
43 #endif
44 #ifndef _COM_SUN_STAR_IO_XOUTPUTSTREAM_HPP_
45 #include <com/sun/star/io/XOutputStream.hpp>
46 #endif
47 #ifndef _COM_SUN_STAR_IO_XACTIVEDATASINK_HPP_
48 #include <com/sun/star/io/XActiveDataSink.hpp>
49 #endif
50 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
51 #include <com/sun/star/beans/PropertyAttribute.hpp>
52 #endif
53 #ifndef _UCBHELPER_PROPERTYVALUESET_HXX
54 #include <ucbhelper/propertyvalueset.hxx>
55 #endif
56 #ifndef _UCBHELPER_CONTENTIDENTIFIER_HXX
57 #include <ucbhelper/contentidentifier.hxx>
58 #endif
59 #ifndef DBA_UCPRESULTSET_HXX
60 #include "myucp_resultset.hxx"
61 #endif
62 #ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_
63 #include <com/sun/star/container/XNameContainer.hpp>
64 #endif
65 #ifndef DBACORE_SDBCORETOOLS_HXX
66 #include "sdbcoretools.hxx"
67 #endif
68 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
69 #include "dbastrings.hrc"
70 #endif
71 #ifndef _TOOLS_DEBUG_HXX
72 #include <tools/debug.hxx>
73 #endif
74 
75 
76 namespace dbaccess
77 {
78 using namespace ::com::sun::star::uno;
79 using namespace ::com::sun::star::ucb;
80 using namespace ::com::sun::star::beans;
81 using namespace ::com::sun::star::lang;
82 using namespace ::com::sun::star::sdbc;
83 using namespace ::com::sun::star::io;
84 using namespace ::com::sun::star::util;
85 using namespace ::com::sun::star::embed;
86 using namespace ::com::sun::star::container;
87 using namespace ::comphelper;
88 using namespace ::cppu;
89 
90 // -----------------------------------------------------------------------------
DBG_NAME(OContentHelper_Impl)91 DBG_NAME(OContentHelper_Impl)
92 OContentHelper_Impl::OContentHelper_Impl()
93 {
94 	DBG_CTOR(OContentHelper_Impl,NULL);
95 }
96 // -----------------------------------------------------------------------------
~OContentHelper_Impl()97 OContentHelper_Impl::~OContentHelper_Impl()
98 {
99 	DBG_DTOR(OContentHelper_Impl,NULL);
100 }
101 // -----------------------------------------------------------------------------
102 
OContentHelper(const Reference<XMultiServiceFactory> & _xORB,const Reference<XInterface> & _xParentContainer,const TContentPtr & _pImpl)103 OContentHelper::OContentHelper(const Reference< XMultiServiceFactory >& _xORB
104 							   ,const Reference< XInterface >&	_xParentContainer
105 							   ,const TContentPtr& _pImpl)
106 	: OContentHelper_COMPBASE(m_aMutex)
107 	,m_aContentListeners(m_aMutex)
108 	,m_aPropertyChangeListeners(m_aMutex)
109 	,m_xParentContainer(_xParentContainer)
110 	,m_aContext( _xORB )
111     ,m_aErrorHelper( m_aContext )
112 	,m_pImpl(_pImpl)
113 	,m_nCommandId(0)
114 {
115 }
116 //--------------------------------------------------------------------------
disposing()117 void SAL_CALL OContentHelper::disposing()
118 {
119 	::osl::MutexGuard aGuard(m_aMutex);
120 
121 	// say our listeners goobye
122 	EventObject aEvt(*this);
123 	m_aContentListeners.disposeAndClear(aEvt);
124 
125 	m_xParentContainer = NULL;
126 }
127 // -----------------------------------------------------------------------------
128 IMPLEMENT_SERVICE_INFO1(OContentHelper,"com.sun.star.comp.sdb.Content","com.sun.star.ucb.Content");
IMPLEMENT_IMPLEMENTATION_ID(OContentHelper)129 IMPLEMENT_IMPLEMENTATION_ID(OContentHelper)
130 // -----------------------------------------------------------------------------
131 // XContent
132 Reference< XContentIdentifier > SAL_CALL OContentHelper::getIdentifier(  ) throw (RuntimeException)
133 {
134 	::osl::MutexGuard aGuard(m_aMutex);
135     ::rtl::OUStringBuffer aIdentifier;
136     aIdentifier.appendAscii( "private:" );
137     aIdentifier.append( impl_getHierarchicalName( true ) );
138     return new ::ucbhelper::ContentIdentifier( m_aContext.getLegacyServiceFactory(), aIdentifier.makeStringAndClear() );
139 }
140 // -----------------------------------------------------------------------------
impl_getHierarchicalName(bool _includingRootContainer) const141 ::rtl::OUString OContentHelper::impl_getHierarchicalName( bool _includingRootContainer ) const
142 {
143     ::rtl::OUStringBuffer aHierarchicalName( m_pImpl->m_aProps.aTitle );
144 	Reference< XInterface > xParent = m_xParentContainer;
145 	while( xParent.is() )
146 	{
147 		Reference<XPropertySet> xProp( xParent, UNO_QUERY );
148 		Reference< XChild > xChild( xParent, UNO_QUERY );
149 		xParent.set( xChild.is() ? xChild->getParent() : Reference< XInterface >(), UNO_QUERY );
150 		if ( xProp.is() && xParent.is() )
151 		{
152 			::rtl::OUString sName;
153 			xProp->getPropertyValue( PROPERTY_NAME ) >>= sName;
154 
155             ::rtl::OUString sPrevious = aHierarchicalName.makeStringAndClear();
156             aHierarchicalName.append( sName );
157             aHierarchicalName.append( sal_Unicode( '/' ) );
158             aHierarchicalName.append( sPrevious );
159 		}
160 	}
161     ::rtl::OUString sHierarchicalName( aHierarchicalName.makeStringAndClear() );
162     if ( !_includingRootContainer )
163         sHierarchicalName = sHierarchicalName.copy( sHierarchicalName.indexOf( '/' ) + 1 );
164     return sHierarchicalName;
165 }
166 
167 // -----------------------------------------------------------------------------
getContentType()168 ::rtl::OUString SAL_CALL OContentHelper::getContentType() throw (RuntimeException)
169 {
170 	::osl::MutexGuard aGuard(m_aMutex);
171 
172     if ( !m_pImpl->m_aProps.aContentType )
173     {   // content type not yet retrieved
174         m_pImpl->m_aProps.aContentType.reset( determineContentType() );
175     }
176 
177 	return *m_pImpl->m_aProps.aContentType;
178 }
179 // -----------------------------------------------------------------------------
addContentEventListener(const Reference<XContentEventListener> & _rxListener)180 void SAL_CALL OContentHelper::addContentEventListener( const Reference< XContentEventListener >& _rxListener ) throw (RuntimeException)
181 {
182 	::osl::MutexGuard aGuard(m_aMutex);
183 	if ( _rxListener.is() )
184 		m_aContentListeners.addInterface(_rxListener);
185 }
186 // -----------------------------------------------------------------------------
removeContentEventListener(const Reference<XContentEventListener> & _rxListener)187 void SAL_CALL OContentHelper::removeContentEventListener( const Reference< XContentEventListener >& _rxListener ) throw (RuntimeException)
188 {
189 	::osl::MutexGuard aGuard(m_aMutex);
190 	if (_rxListener.is())
191 		m_aContentListeners.removeInterface(_rxListener);
192 }
193 // -----------------------------------------------------------------------------
194 
195 // XCommandProcessor
createCommandIdentifier()196 sal_Int32 SAL_CALL OContentHelper::createCommandIdentifier(  ) throw (RuntimeException)
197 {
198 	::osl::MutexGuard aGuard(m_aMutex);
199 	// Just increase counter on every call to generate an identifier.
200 	return ++m_nCommandId;
201 }
202 // -----------------------------------------------------------------------------
execute(const Command & aCommand,sal_Int32,const Reference<XCommandEnvironment> & Environment)203 Any SAL_CALL OContentHelper::execute( const Command& aCommand, sal_Int32 /*CommandId*/, const Reference< XCommandEnvironment >& Environment ) throw (Exception, CommandAbortedException, RuntimeException)
204 {
205 	Any aRet;
206 	if ( aCommand.Name.compareToAscii( "getPropertyValues" ) == 0 )
207 	{
208 		//////////////////////////////////////////////////////////////////
209 		// getPropertyValues
210 		//////////////////////////////////////////////////////////////////
211 
212 		Sequence< Property > Properties;
213 		if ( !( aCommand.Argument >>= Properties ) )
214 		{
215 			OSL_ENSURE( sal_False, "Wrong argument type!" );
216             ucbhelper::cancelCommandExecution(
217                 makeAny( IllegalArgumentException(
218                                     rtl::OUString(),
219                                     static_cast< cppu::OWeakObject * >( this ),
220                                     -1 ) ),
221                 Environment );
222             // Unreachable
223 		}
224 		aRet <<= getPropertyValues( Properties);
225 	}
226 	else if ( aCommand.Name.compareToAscii( "setPropertyValues" ) == 0 )
227 	{
228 		//////////////////////////////////////////////////////////////////
229 		// setPropertyValues
230 		//////////////////////////////////////////////////////////////////
231 
232 		Sequence< PropertyValue > aProperties;
233 		if ( !( aCommand.Argument >>= aProperties ) )
234 		{
235             OSL_ENSURE( sal_False, "Wrong argument type!" );
236             ucbhelper::cancelCommandExecution(
237                 makeAny( IllegalArgumentException(
238                                     rtl::OUString(),
239                                     static_cast< cppu::OWeakObject * >( this ),
240                                     -1 ) ),
241                 Environment );
242             // Unreachable
243         }
244 
245 		if ( !aProperties.getLength() )
246 		{
247             OSL_ENSURE( sal_False, "No properties!" );
248             ucbhelper::cancelCommandExecution(
249                 makeAny( IllegalArgumentException(
250                                     rtl::OUString(),
251                                     static_cast< cppu::OWeakObject * >( this ),
252                                     -1 ) ),
253                 Environment );
254             // Unreachable
255         }
256 
257         aRet <<= setPropertyValues( aProperties, Environment );
258 	}
259 	else if ( aCommand.Name.compareToAscii( "getPropertySetInfo" ) == 0 )
260 	{
261 		//////////////////////////////////////////////////////////////////
262 		// getPropertySetInfo
263 		//////////////////////////////////////////////////////////////////
264 
265 		Reference<XPropertySet> xProp(*this,UNO_QUERY);
266 		if ( xProp.is() )
267 			aRet <<= xProp->getPropertySetInfo();
268 		//	aRet <<= getPropertySetInfo(); // TODO
269 	}
270 	else
271 	{
272 		//////////////////////////////////////////////////////////////////
273 		// Unsupported command
274 		//////////////////////////////////////////////////////////////////
275 
276         OSL_ENSURE( sal_False, "Content::execute - unsupported command!" );
277 
278         ucbhelper::cancelCommandExecution(
279             makeAny( UnsupportedCommandException(
280                             rtl::OUString(),
281                             static_cast< cppu::OWeakObject * >( this ) ) ),
282             Environment );
283         // Unreachable
284     }
285 
286 	return aRet;
287 }
288 // -----------------------------------------------------------------------------
abort(sal_Int32)289 void SAL_CALL OContentHelper::abort( sal_Int32 /*CommandId*/ ) throw (RuntimeException)
290 {
291 }
292 // -----------------------------------------------------------------------------
293 
294 // XPropertiesChangeNotifier
addPropertiesChangeListener(const Sequence<::rtl::OUString> & PropertyNames,const Reference<XPropertiesChangeListener> & Listener)295 void SAL_CALL OContentHelper::addPropertiesChangeListener( const Sequence< ::rtl::OUString >& PropertyNames, const Reference< XPropertiesChangeListener >& Listener ) throw (RuntimeException)
296 {
297 	::osl::MutexGuard aGuard(m_aMutex);
298 	sal_Int32 nCount = PropertyNames.getLength();
299 	if ( !nCount )
300 	{
301 		// Note: An empty sequence means a listener for "all" properties.
302 		m_aPropertyChangeListeners.addInterface(::rtl::OUString(), Listener );
303 	}
304 	else
305 	{
306 		const ::rtl::OUString* pSeq = PropertyNames.getConstArray();
307 
308 		for ( sal_Int32 n = 0; n < nCount; ++n )
309 		{
310 			const ::rtl::OUString& rName = pSeq[ n ];
311 			if ( rName.getLength() )
312 				m_aPropertyChangeListeners.addInterface(rName, Listener );
313 		}
314 	}
315 }
316 // -----------------------------------------------------------------------------
removePropertiesChangeListener(const Sequence<::rtl::OUString> & PropertyNames,const Reference<XPropertiesChangeListener> & Listener)317 void SAL_CALL OContentHelper::removePropertiesChangeListener( const Sequence< ::rtl::OUString >& PropertyNames, const Reference< XPropertiesChangeListener >& Listener ) throw (RuntimeException)
318 {
319 	::osl::MutexGuard aGuard(m_aMutex);
320 	sal_Int32 nCount = PropertyNames.getLength();
321 	if ( !nCount )
322 	{
323 		// Note: An empty sequence means a listener for "all" properties.
324 		m_aPropertyChangeListeners.removeInterface( ::rtl::OUString(), Listener );
325 	}
326 	else
327 	{
328 		const ::rtl::OUString* pSeq = PropertyNames.getConstArray();
329 
330 		for ( sal_Int32 n = 0; n < nCount; ++n )
331 		{
332 			const ::rtl::OUString& rName = pSeq[ n ];
333 			if ( rName.getLength() )
334 				m_aPropertyChangeListeners.removeInterface( rName, Listener );
335 		}
336 	}
337 }
338 // -----------------------------------------------------------------------------
339 
340 // XPropertyContainer
addProperty(const::rtl::OUString &,sal_Int16,const Any &)341 void SAL_CALL OContentHelper::addProperty( const ::rtl::OUString& /*Name*/, sal_Int16 /*Attributes*/, const Any& /*DefaultValue*/ ) throw (PropertyExistException, IllegalTypeException, IllegalArgumentException, RuntimeException)
342 {
343     DBG_ERROR( "OContentHelper::addProperty: not implemented!" );
344 }
345 // -----------------------------------------------------------------------------
removeProperty(const::rtl::OUString &)346 void SAL_CALL OContentHelper::removeProperty( const ::rtl::OUString& /*Name*/ ) throw (UnknownPropertyException, NotRemoveableException, RuntimeException)
347 {
348     DBG_ERROR( "OContentHelper::removeProperty: not implemented!" );
349 }
350 // -----------------------------------------------------------------------------
351 // XInitialization
initialize(const Sequence<Any> & _aArguments)352 void SAL_CALL OContentHelper::initialize( const Sequence< Any >& _aArguments ) throw(Exception, RuntimeException)
353 {
354 	const Any* pBegin = _aArguments.getConstArray();
355 	const Any* pEnd = pBegin + _aArguments.getLength();
356 	PropertyValue aValue;;
357 	for(;pBegin != pEnd;++pBegin)
358 	{
359 		*pBegin >>= aValue;
360 		if ( aValue.Name.equalsAscii("Parent") )
361 		{
362 			m_xParentContainer.set(aValue.Value,UNO_QUERY);
363 		}
364 		else if ( aValue.Name.equalsAscii(PROPERTY_NAME) )
365 		{
366 			aValue.Value >>= m_pImpl->m_aProps.aTitle;
367 		}
368 		else if ( aValue.Name.equalsAscii(PROPERTY_PERSISTENT_NAME) )
369 		{
370 			aValue.Value >>= m_pImpl->m_aProps.sPersistentName;
371 		}
372 	}
373 }
374 // -----------------------------------------------------------------------------
setPropertyValues(const Sequence<PropertyValue> & rValues,const Reference<XCommandEnvironment> &)375 Sequence< Any > OContentHelper::setPropertyValues(const Sequence< PropertyValue >& rValues,const Reference< XCommandEnvironment >& /*xEnv*/ )
376 {
377 	osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
378 
379     Sequence< Any > aRet( rValues.getLength() );
380     Sequence< PropertyChangeEvent > aChanges( rValues.getLength() );
381 	sal_Int32 nChanged = 0;
382 
383     PropertyChangeEvent aEvent;
384     aEvent.Source         = static_cast< cppu::OWeakObject * >( this );
385 	aEvent.Further 		  = sal_False;
386 	aEvent.PropertyHandle = -1;
387 
388     const PropertyValue* pValues = rValues.getConstArray();
389 	sal_Int32 nCount = rValues.getLength();
390 
391 	for ( sal_Int32 n = 0; n < nCount; ++n )
392 	{
393         const PropertyValue& rValue = pValues[ n ];
394 
395         if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
396         {
397 			// Read-only property!
398             aRet[ n ] <<= IllegalAccessException(
399                             rtl::OUString::createFromAscii(
400                                 "Property is read-only!" ),
401                             static_cast< cppu::OWeakObject * >( this ) );
402 		}
403         else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
404 		{
405 			// Read-only property!
406             aRet[ n ] <<= IllegalAccessException(
407                             rtl::OUString::createFromAscii(
408                                 "Property is read-only!" ),
409                             static_cast< cppu::OWeakObject * >( this ) );
410 		}
411         else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
412 		{
413 			// Read-only property!
414             aRet[ n ] <<= IllegalAccessException(
415                             rtl::OUString::createFromAscii(
416                                 "Property is read-only!" ),
417                             static_cast< cppu::OWeakObject * >( this ) );
418 		}
419         else if ( rValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
420 		{
421             rtl::OUString aNewValue;
422 			if ( rValue.Value >>= aNewValue )
423 			{
424 				if ( aNewValue != m_pImpl->m_aProps.aTitle )
425 				{
426 					aEvent.PropertyName = rValue.Name;
427                     aEvent.OldValue     = makeAny( m_pImpl->m_aProps.aTitle );
428 
429                     try
430                     {
431                         impl_rename_throw( aNewValue ,false);
432                         OSL_ENSURE( m_pImpl->m_aProps.aTitle == aNewValue, "OContentHelper::setPropertyValues('Title'): rename did not work!" );
433 
434                         aEvent.NewValue     = makeAny( aNewValue );
435 					    aChanges.getArray()[ nChanged ] = aEvent;
436 					    nChanged++;
437                     }
438                     catch( const Exception& )
439                     {
440                     	OSL_ENSURE( sal_False, "OContentHelper::setPropertyValues('Title'): caught an exception while renaming!" );
441                     }
442 				}
443                 else
444                 {
445                     // Old value equals new value. No error!
446                 }
447 			}
448             else
449             {
450                 aRet[ n ] <<= IllegalTypeException(
451                                 rtl::OUString::createFromAscii(
452                                     "Property value has wrong type!" ),
453                                 static_cast< cppu::OWeakObject * >( this ) );
454             }
455 		}
456 
457 		// @@@ Process other properties supported directly.
458 #if 0
459         else if ( rValue.Name.equalsAsciiL(
460                         RTL_CONSTASCII_STRINGPARAM( "xxxxxx" ) ) )
461 		{
462 		}
463 #endif
464 		else
465 		{
466             aRet[ n ] <<= Exception(
467                             rtl::OUString::createFromAscii(
468                                 "No property set for storing the value!" ),
469                             static_cast< cppu::OWeakObject * >( this ) );
470 		}
471 	}
472 
473 	if ( nChanged > 0 )
474 	{
475 		// @@@ Save changes.
476 //		storeData();
477 
478 		notifyDataSourceModified();
479 		aGuard.clear();
480 		aChanges.realloc( nChanged );
481 		notifyPropertiesChange( aChanges );
482 	}
483 
484     return aRet;
485 }
486 // -----------------------------------------------------------------------------
487 //=========================================================================
488 // static
getPropertyValues(const Sequence<Property> & rProperties)489 Reference< XRow > OContentHelper::getPropertyValues( const Sequence< Property >& rProperties)
490 {
491 	// Note: Empty sequence means "get values of all supported properties".
492 
493     rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = new ::ucbhelper::PropertyValueSet( m_aContext.getLegacyServiceFactory() );
494 
495 	sal_Int32 nCount = rProperties.getLength();
496 	if ( nCount )
497 	{
498         const Property* pProps = rProperties.getConstArray();
499 		for ( sal_Int32 n = 0; n < nCount; ++n )
500 		{
501             const Property& rProp = pProps[ n ];
502 
503 			// Process Core properties.
504 
505             if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
506             {
507 				xRow->appendString ( rProp, getContentType() );
508 			}
509             else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
510 			{
511 				xRow->appendString ( rProp, m_pImpl->m_aProps.aTitle );
512 			}
513             else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
514 			{
515 				xRow->appendBoolean( rProp, m_pImpl->m_aProps.bIsDocument );
516 			}
517             else if ( rProp.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
518 			{
519 				xRow->appendBoolean( rProp, m_pImpl->m_aProps.bIsFolder );
520 			}
521 			else
522 				xRow->appendVoid(rProp);
523 
524 			// @@@ Process other properties supported directly.
525 #if 0
526             else if ( rProp.Name.equalsAsciiL(
527                     RTL_CONSTASCII_STRINGPARAM( "xxxxxx" ) ) )
528 			{
529 			}
530 #endif
531 		}
532 	}
533 	else
534 	{
535 		// Append all Core Properties.
536 		xRow->appendString (
537             Property( rtl::OUString::createFromAscii( "ContentType" ),
538 					  -1,
539                       getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
540                       PropertyAttribute::BOUND
541                         | PropertyAttribute::READONLY ),
542 			getContentType() );
543 		xRow->appendString (
544             Property( rtl::OUString::createFromAscii( "Title" ),
545 					  -1,
546                       getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
547                       PropertyAttribute::BOUND ),
548 			m_pImpl->m_aProps.aTitle );
549 		xRow->appendBoolean(
550             Property( rtl::OUString::createFromAscii( "IsDocument" ),
551 					  -1,
552 					  getCppuBooleanType(),
553                       PropertyAttribute::BOUND
554                         | PropertyAttribute::READONLY ),
555 			m_pImpl->m_aProps.bIsDocument );
556 		xRow->appendBoolean(
557             Property( rtl::OUString::createFromAscii( "IsFolder" ),
558 					  -1,
559 					  getCppuBooleanType(),
560                       PropertyAttribute::BOUND
561                         | PropertyAttribute::READONLY ),
562 			m_pImpl->m_aProps.bIsFolder );
563 
564 		// @@@ Append other properties supported directly.
565 	}
566 
567     return Reference< XRow >( xRow.get() );
568 }
569 // -----------------------------------------------------------------------------
570 // -----------------------------------------------------------------------------
notifyPropertiesChange(const Sequence<PropertyChangeEvent> & evt) const571 void OContentHelper::notifyPropertiesChange( const Sequence< PropertyChangeEvent >& evt ) const
572 {
573 
574 	sal_Int32 nCount = evt.getLength();
575 	if ( nCount )
576 	{
577 		// First, notify listeners interested in changes of every property.
578 		OInterfaceContainerHelper* pAllPropsContainer = m_aPropertyChangeListeners.getContainer( ::rtl::OUString() );
579 		if ( pAllPropsContainer )
580 		{
581 			OInterfaceIteratorHelper aIter( *pAllPropsContainer );
582 			while ( aIter.hasMoreElements() )
583 			{
584 				// Propagate event.
585 				Reference< XPropertiesChangeListener > xListener( aIter.next(), UNO_QUERY );
586 				if ( xListener.is() )
587 					xListener->propertiesChange( evt );
588 			}
589 		}
590 
591 		typedef Sequence< PropertyChangeEvent > PropertyEventSequence;
592 		typedef ::std::map< XPropertiesChangeListener*, PropertyEventSequence* > PropertiesEventListenerMap;
593 		PropertiesEventListenerMap aListeners;
594 
595 
596 		const PropertyChangeEvent* propertyChangeEvent = evt.getConstArray();
597 
598 		for ( sal_Int32 n = 0; n < nCount; ++n, ++propertyChangeEvent )
599 		{
600 			const PropertyChangeEvent& rEvent = *propertyChangeEvent;
601 			const ::rtl::OUString& rName = rEvent.PropertyName;
602 
603 			OInterfaceContainerHelper* pPropsContainer = m_aPropertyChangeListeners.getContainer( rName );
604 			if ( pPropsContainer )
605 			{
606 				OInterfaceIteratorHelper aIter( *pPropsContainer );
607 				while ( aIter.hasMoreElements() )
608 				{
609 					PropertyEventSequence* propertyEvents = NULL;
610 
611 					XPropertiesChangeListener* pListener = static_cast< XPropertiesChangeListener * >( aIter.next() );
612 					PropertiesEventListenerMap::iterator it = aListeners.find( pListener );
613 					if ( it == aListeners.end() )
614 					{
615 						// Not in map - create and insert new entry.
616 						propertyEvents = new PropertyEventSequence( nCount );
617 						aListeners[ pListener ] = propertyEvents;
618 					}
619 					else
620 						propertyEvents = (*it).second;
621 
622 					if ( propertyEvents )
623 						(*propertyEvents)[n] = rEvent;
624 				}
625 			}
626 		}
627 
628 		// Notify listeners.
629 		PropertiesEventListenerMap::iterator it = aListeners.begin();
630 		while ( !aListeners.empty() )
631 		{
632 			XPropertiesChangeListener* pListener =
633 					static_cast< XPropertiesChangeListener * >( (*it).first );
634 			PropertyEventSequence* pSeq = (*it).second;
635 
636 			// Remove current element.
637 			aListeners.erase( it );
638 
639 			// Propagate event.
640 			pListener->propertiesChange( *pSeq );
641 
642 			delete pSeq;
643 
644 			it = aListeners.begin();
645 		}
646 	}
647 }
648 // -----------------------------------------------------------------------------
649 // com::sun::star::lang::XUnoTunnel
650 //------------------------------------------------------------------
getSomething(const Sequence<sal_Int8> & rId)651 sal_Int64 OContentHelper::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
652 {
653 	if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
654 		return reinterpret_cast<sal_Int64>(this);
655 
656 	return 0;
657 }
658 
659 // -----------------------------------------------------------------------------
getImplementation(const Reference<XInterface> & _rxComponent)660 OContentHelper* OContentHelper::getImplementation( const Reference< XInterface >& _rxComponent )
661 {
662 	OContentHelper* pContent( NULL );
663 
664     Reference< XUnoTunnel > xUnoTunnel( _rxComponent, UNO_QUERY );
665 	if ( xUnoTunnel.is() )
666 		pContent = reinterpret_cast< OContentHelper* >( xUnoTunnel->getSomething( getUnoTunnelImplementationId() ) );
667 
668     return pContent;
669 }
670 
671 // -----------------------------------------------------------------------------
getParent()672 Reference< XInterface > SAL_CALL OContentHelper::getParent(  ) throw (RuntimeException)
673 {
674 	::osl::MutexGuard aGuard(m_aMutex);
675 	return m_xParentContainer;
676 }
677 // -----------------------------------------------------------------------------
setParent(const Reference<XInterface> & _xParent)678 void SAL_CALL OContentHelper::setParent( const Reference< XInterface >& _xParent ) throw (NoSupportException, RuntimeException)
679 {
680 	::osl::MutexGuard aGuard(m_aMutex);
681 	m_xParentContainer = _xParent;
682 }
683 
684 // -----------------------------------------------------------------------------
impl_rename_throw(const::rtl::OUString & _sNewName,bool _bNotify)685 void OContentHelper::impl_rename_throw(const ::rtl::OUString& _sNewName,bool _bNotify )
686 {
687 	osl::ClearableGuard< osl::Mutex > aGuard(m_aMutex);
688     if ( _sNewName.equals( m_pImpl->m_aProps.aTitle ) )
689         return;
690     try
691 	{
692         Sequence< PropertyChangeEvent > aChanges( 1 );
693 
694         aChanges[0].Source          = static_cast< cppu::OWeakObject * >( this );
695 	    aChanges[0].Further 	    = sal_False;
696         aChanges[0].PropertyName    = PROPERTY_NAME;
697 	    aChanges[0].PropertyHandle  = PROPERTY_ID_NAME;
698         aChanges[0].OldValue        <<= m_pImpl->m_aProps.aTitle;
699         aChanges[0].NewValue        <<= _sNewName;
700 
701 		aGuard.clear();
702 
703 		m_pImpl->m_aProps.aTitle = _sNewName;
704         if ( _bNotify )
705             notifyPropertiesChange( aChanges );
706         notifyDataSourceModified();
707 	}
708 	catch(const PropertyVetoException&)
709 	{
710 		throw ElementExistException(_sNewName,*this);
711 	}
712 }
713 // -----------------------------------------------------------------------------
rename(const::rtl::OUString & newName)714 void SAL_CALL OContentHelper::rename( const ::rtl::OUString& newName ) throw (SQLException, ElementExistException, RuntimeException)
715 {
716 
717     impl_rename_throw(newName);
718 	//Reference<XNameContainer> xNameCont(m_xParentContainer,UNO_QUERY);
719 	//if ( xNameCont.is() )
720 	//{
721 	//	if ( xNameCont->hasByName(newName) )
722 	//		throw ElementExistException(newName,*this);
723 
724 	//	try
725 	//	{
726 	//		if ( xNameCont->hasByName(m_pImpl->m_aProps.aTitle) )
727 	//			xNameCont->removeByName(m_pImpl->m_aProps.aTitle);
728 
729 	//		m_pImpl->m_aProps.aTitle = newName;
730 	//		xNameCont->insertByName(m_pImpl->m_aProps.aTitle,makeAny(Reference<XContent>(*this,UNO_QUERY)));
731 	//		notifyDataSourceModified();
732 	//	}
733 	//	catch(IllegalArgumentException)
734 	//	{
735 	//		throw SQLException();
736 	//	}
737 	//	catch(NoSuchElementException)
738 	//	{
739 	//		throw SQLException();
740 	//	}
741 	//	catch(WrappedTargetException)
742 	//	{
743 	//		throw SQLException();
744 	//	}
745 	//}
746 	//else
747 	//	m_pImpl->m_aProps.aTitle = newName;
748 
749 }
750 // -----------------------------------------------------------------------------
notifyDataSourceModified()751 void OContentHelper::notifyDataSourceModified()
752 {
753 	::dbaccess::notifyDataSourceModified(m_xParentContainer,sal_True);
754 }
755 //........................................................................
756 }	// namespace dbaccess
757 //........................................................................
758 
759