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_ucbhelper.hxx"
26
27 /**************************************************************************
28 TODO
29 **************************************************************************
30
31 *************************************************************************/
32
33 #include "osl/diagnose.h"
34
35 #include "com/sun/star/beans/PropertyAttribute.hpp"
36 #include "com/sun/star/beans/XPropertyAccess.hpp"
37 #include "com/sun/star/lang/IllegalAccessException.hpp"
38 #include "com/sun/star/sdbc/XRow.hpp"
39 #include "com/sun/star/ucb/XCommandInfo.hpp"
40 #include "com/sun/star/ucb/XPersistentPropertySet.hpp"
41 #include "ucbhelper/contentidentifier.hxx"
42 #include "ucbhelper/propertyvalueset.hxx"
43 #include "ucbhelper/cancelcommandexecution.hxx"
44
45 #include "myucp_content.hxx"
46 #include "myucp_provider.hxx"
47
48 #ifdef IMPLEMENT_COMMAND_INSERT
49 #include "com/sun/star/ucb/InsertCommandArgument.hpp"
50 #include "com/sun/star/ucb/MissingInputStreamException.hpp"
51 #include "com/sun/star/ucb/MissingPropertiesException.hpp"
52 #endif
53 #ifdef IMPLEMENT_COMMAND_OPEN
54 #include "com/sun/star/io/XOutputStream.hpp"
55 #include "com/sun/star/io/XActiveDataSink.hpp"
56 #include "com/sun/star/ucb/OpenCommandArgument2.hpp"
57 #include "com/sun/star/ucb/OpenMode.hpp"
58 #include "com/sun/star/ucb/UnsupportedDataSinkException.hpp"
59 #include "com/sun/star/ucb/UnsupportedOpenModeException.hpp"
60 #include "myucp_resultset.hxx"
61 #endif
62
63 using namespace com::sun::star;
64
65 // @@@ Adjust namespace name.
66 using namespace myucp;
67
68 //=========================================================================
69 //=========================================================================
70 //
71 // Content Implementation.
72 //
73 //=========================================================================
74 //=========================================================================
75
Content(const uno::Reference<lang::XMultiServiceFactory> & rxSMgr,::ucbhelper::ContentProviderImplHelper * pProvider,const uno::Reference<ucb::XContentIdentifier> & Identifier)76 Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr,
77 ::ucbhelper::ContentProviderImplHelper* pProvider,
78 const uno::Reference< ucb::XContentIdentifier >& Identifier )
79 : ContentImplHelper( rxSMgr, pProvider, Identifier )
80 {
81 // @@@ Fill m_aProps here or implement lazy evaluation logic for this.
82 // m_aProps.aTitle =
83 // m_aprops.aContentType =
84 // m_aProps.bIsDocument =
85 // m_aProps.bIsFolder =
86 }
87
88 //=========================================================================
89 // virtual
~Content()90 Content::~Content()
91 {
92 }
93
94 //=========================================================================
95 //
96 // XInterface methods.
97 //
98 //=========================================================================
99
100 // virtual
acquire()101 void SAL_CALL Content::acquire()
102 throw()
103 {
104 ContentImplHelper::acquire();
105 }
106
107 //=========================================================================
108 // virtual
release()109 void SAL_CALL Content::release()
110 throw()
111 {
112 ContentImplHelper::release();
113 }
114
115 //=========================================================================
116 // virtual
queryInterface(const uno::Type & rType)117 uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType )
118 throw ( uno::RuntimeException )
119 {
120 uno::Any aRet;
121
122 // @@@ Add support for additional interfaces.
123 #if 0
124 aRet = cppu::queryInterface( rType,
125 static_cast< yyy::Xxxxxxxxx * >( this ) );
126 #endif
127
128 return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType );
129 }
130
131 //=========================================================================
132 //
133 // XTypeProvider methods.
134 //
135 //=========================================================================
136
137 XTYPEPROVIDER_COMMON_IMPL( Content );
138
139 //=========================================================================
140 // virtual
getTypes()141 uno::Sequence< uno::Type > SAL_CALL Content::getTypes()
142 throw( uno::RuntimeException )
143 {
144 // @@@ Add own interfaces.
145
146 static cppu::OTypeCollection* pCollection = 0;
147
148 if ( !pCollection )
149 {
150 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
151 if ( !pCollection )
152 {
153 static cppu::OTypeCollection aCollection(
154 CPPU_TYPE_REF( lang::XTypeProvider ),
155 CPPU_TYPE_REF( lang::XServiceInfo ),
156 CPPU_TYPE_REF( lang::XComponent ),
157 CPPU_TYPE_REF( ucb::XContent ),
158 CPPU_TYPE_REF( ucb::XCommandProcessor ),
159 CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ),
160 CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ),
161 CPPU_TYPE_REF( beans::XPropertyContainer ),
162 CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ),
163 CPPU_TYPE_REF( container::XChild ) );
164 pCollection = &aCollection;
165 }
166 }
167
168 return (*pCollection).getTypes();
169 }
170
171 //=========================================================================
172 //
173 // XServiceInfo methods.
174 //
175 //=========================================================================
176
177 // virtual
getImplementationName()178 rtl::OUString SAL_CALL Content::getImplementationName()
179 throw( uno::RuntimeException )
180 {
181 // @@@ Adjust implementation name.
182 // Prefix with reversed company domain name.
183 return rtl::OUString::createFromAscii( "com.sun.star.comp.myucp.Content" );
184 }
185
186 //=========================================================================
187 // virtual
getSupportedServiceNames()188 uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames()
189 throw( uno::RuntimeException )
190 {
191 // @@@ Adjust macro name.
192 uno::Sequence< rtl::OUString > aSNS( 1 );
193 aSNS.getArray()[ 0 ]
194 = rtl::OUString::createFromAscii( MYUCP_CONTENT_SERVICE_NAME );
195 return aSNS;
196 }
197
198 //=========================================================================
199 //
200 // XContent methods.
201 //
202 //=========================================================================
203
204 // virtual
getContentType()205 rtl::OUString SAL_CALL Content::getContentType()
206 throw( uno::RuntimeException )
207 {
208 // @@@ Adjust macro name ( def in myucp_provider.hxx ).
209 return rtl::OUString::createFromAscii( MYUCP_CONTENT_TYPE );
210 }
211
212 //=========================================================================
213 //
214 // XCommandProcessor methods.
215 //
216 //=========================================================================
217
218 // virtual
execute(const ucb::Command & aCommand,sal_Int32,const uno::Reference<ucb::XCommandEnvironment> & Environment)219 uno::Any SAL_CALL Content::execute(
220 const ucb::Command& aCommand,
221 sal_Int32 /* CommandId */,
222 const uno::Reference< ucb::XCommandEnvironment >& Environment )
223 throw( uno::Exception,
224 ucb::CommandAbortedException,
225 uno::RuntimeException )
226 {
227 uno::Any aRet;
228
229 if ( aCommand.Name.equalsAsciiL(
230 RTL_CONSTASCII_STRINGPARAM( "getPropertyValues" ) ) )
231 {
232 //////////////////////////////////////////////////////////////////
233 // getPropertyValues
234 //////////////////////////////////////////////////////////////////
235
236 uno::Sequence< beans::Property > Properties;
237 if ( !( aCommand.Argument >>= Properties ) )
238 {
239 OSL_ENSURE( sal_False, "Wrong argument type!" );
240 ::ucbhelper::cancelCommandExecution(
241 uno::makeAny( lang::IllegalArgumentException(
242 rtl::OUString(),
243 static_cast< cppu::OWeakObject * >( this ),
244 -1 ) ),
245 Environment );
246 // Unreachable
247 }
248
249 aRet <<= getPropertyValues( Properties, Environment );
250 }
251 else if ( aCommand.Name.equalsAsciiL(
252 RTL_CONSTASCII_STRINGPARAM( "setPropertyValues" ) ) )
253 {
254 //////////////////////////////////////////////////////////////////
255 // setPropertyValues
256 //////////////////////////////////////////////////////////////////
257
258 uno::Sequence< beans::PropertyValue > aProperties;
259 if ( !( aCommand.Argument >>= aProperties ) )
260 {
261 OSL_ENSURE( sal_False, "Wrong argument type!" );
262 ::ucbhelper::cancelCommandExecution(
263 uno::makeAny( lang::IllegalArgumentException(
264 rtl::OUString(),
265 static_cast< cppu::OWeakObject * >( this ),
266 -1 ) ),
267 Environment );
268 // Unreachable
269 }
270
271 if ( !aProperties.getLength() )
272 {
273 OSL_ENSURE( sal_False, "No properties!" );
274 ::ucbhelper::cancelCommandExecution(
275 uno::makeAny( lang::IllegalArgumentException(
276 rtl::OUString(),
277 static_cast< cppu::OWeakObject * >( this ),
278 -1 ) ),
279 Environment );
280 // Unreachable
281 }
282
283 aRet <<= setPropertyValues( aProperties, Environment );
284 }
285 else if ( aCommand.Name.equalsAsciiL(
286 RTL_CONSTASCII_STRINGPARAM( "getPropertySetInfo" ) ) )
287 {
288 //////////////////////////////////////////////////////////////////
289 // getPropertySetInfo
290 //////////////////////////////////////////////////////////////////
291
292 // Note: Implemented by base class.
293 aRet <<= getPropertySetInfo( Environment );
294 }
295 else if ( aCommand.Name.equalsAsciiL(
296 RTL_CONSTASCII_STRINGPARAM( "getCommandInfo" ) ) )
297 {
298 //////////////////////////////////////////////////////////////////
299 // getCommandInfo
300 //////////////////////////////////////////////////////////////////
301
302 // Note: Implemented by base class.
303 aRet <<= getCommandInfo( Environment );
304 }
305 #ifdef IMPLEMENT_COMMAND_OPEN
306 else if ( aCommand.Name.equalsAsciiL(
307 RTL_CONSTASCII_STRINGPARAM( "open" ) ) )
308 {
309 ucb::OpenCommandArgument2 aOpenCommand;
310 if ( !( aCommand.Argument >>= aOpenCommand ) )
311 {
312 OSL_ENSURE( sal_False, "Wrong argument type!" );
313 ::ucbhelper::cancelCommandExecution(
314 uno::makeAny( lang::IllegalArgumentException(
315 rtl::OUString(),
316 static_cast< cppu::OWeakObject * >( this ),
317 -1 ) ),
318 Environment );
319 // Unreachable
320 }
321
322 sal_Bool bOpenFolder =
323 ( ( aOpenCommand.Mode == ucb::OpenMode::ALL ) ||
324 ( aOpenCommand.Mode == ucb::OpenMode::FOLDERS ) ||
325 ( aOpenCommand.Mode == ucb::OpenMode::DOCUMENTS ) );
326
327 if ( bOpenFolder /*&& isFolder( Environment )*/ )
328 {
329 // open as folder - return result set
330
331 uno::Reference< ucb::XDynamicResultSet > xSet
332 = new DynamicResultSet( m_xSMgr,
333 this,
334 aOpenCommand,
335 Environment );
336 aRet <<= xSet;
337 }
338
339 if ( aOpenCommand.Sink.is() )
340 {
341 // Open document - supply document data stream.
342
343 // Check open mode
344 if ( ( aOpenCommand.Mode
345 == ucb::OpenMode::DOCUMENT_SHARE_DENY_NONE ) ||
346 ( aOpenCommand.Mode
347 == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE ) )
348 {
349 // Unsupported.
350 ::ucbhelper::cancelCommandExecution(
351 uno::makeAny( ucb::UnsupportedOpenModeException(
352 rtl::OUString(),
353 static_cast< cppu::OWeakObject * >( this ),
354 sal_Int16( aOpenCommand.Mode ) ) ),
355 Environment );
356 // Unreachable
357 }
358
359
360 rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
361 uno::Reference< io::XOutputStream > xOut
362 = uno::Reference< io::XOutputStream >(
363 aOpenCommand.Sink, uno::UNO_QUERY );
364 if ( xOut.is() )
365 {
366 // @@@ write data into xOut
367 }
368 else
369 {
370 uno::Reference< io::XActiveDataSink > xDataSink(
371 aOpenCommand.Sink, uno::UNO_QUERY );
372 if ( xDataSink.is() )
373 {
374 uno::Reference< io::XInputStream > xIn
375 /* @@@ your XInputStream + XSeekable impl. object */;
376 xDataSink->setInputStream( xIn );
377 }
378 else
379 {
380 // Note: aOpenCommand.Sink may contain an XStream
381 // implementation. Support for this type of
382 // sink is optional...
383 ::ucbhelper::cancelCommandExecution(
384 uno::makeAny( ucb::UnsupportedDataSinkException(
385 rtl::OUString(),
386 static_cast< cppu::OWeakObject * >( this ),
387 aOpenCommand.Sink ) ),
388 Environment );
389 // Unreachable
390 }
391 }
392 }
393 }
394 #endif // IMPLEMENT_COMMAND_OPEN
395
396 #ifdef IMPLEMENT_COMMAND_INSERT
397 else if ( aCommand.Name.equalsAsciiL(
398 RTL_CONSTASCII_STRINGPARAM( "insert" ) ) )
399 {
400 //////////////////////////////////////////////////////////////////
401 // insert
402 //////////////////////////////////////////////////////////////////
403
404 ucb::InsertCommandArgument arg;
405 if ( !( aCommand.Argument >>= arg ) )
406 {
407 OSL_ENSURE( sal_False, "Wrong argument type!" );
408 ::ucbhelper::cancelCommandExecution(
409 uno::makeAny( lang::IllegalArgumentException(
410 rtl::OUString(),
411 static_cast< cppu::OWeakObject * >( this ),
412 -1 ) ),
413 Environment );
414 // Unreachable
415 }
416
417 insert( arg.Data, arg.ReplaceExisting, Environment );
418 }
419 #endif // IMPLEMENT_COMMAND_INSERT
420
421 #ifdef IMPLEMENT_COMMAND_DELETE
422 else if ( aCommand.Name.equalsAsciiL(
423 RTL_CONSTASCII_STRINGPARAM( "delete" ) ) )
424 {
425 //////////////////////////////////////////////////////////////////
426 // delete
427 //////////////////////////////////////////////////////////////////
428
429 sal_Bool bDeletePhysical = sal_False;
430 aCommand.Argument >>= bDeletePhysical;
431 destroy( bDeletePhysical );
432
433 // Remove own and all children's Additional Core Properties.
434 removeAdditionalPropertySet( sal_True );
435
436 // Remove own and all childrens(!) persistent data.
437 // removeData();
438 }
439 #endif // IMPLEMENT_COMMAND_DELETE
440 else
441 {
442 //////////////////////////////////////////////////////////////////
443 // Unsupported command
444 //////////////////////////////////////////////////////////////////
445
446 OSL_ENSURE( sal_False, "Content::execute - unsupported command!" );
447
448 ::ucbhelper::cancelCommandExecution(
449 uno::makeAny( ucb::UnsupportedCommandException(
450 rtl::OUString(),
451 static_cast< cppu::OWeakObject * >( this ) ) ),
452 Environment );
453 // Unreachable
454 }
455
456 return aRet;
457 }
458
459 //=========================================================================
460 // virtual
abort(sal_Int32)461 void SAL_CALL Content::abort( sal_Int32 )
462 throw( uno::RuntimeException )
463 {
464 // @@@ Implement logic to abort running commands, if this makes
465 // sense for your content.
466 }
467
468 //=========================================================================
469 //
470 // Non-interface methods.
471 //
472 //=========================================================================
473
474 // virtual
getParentURL()475 rtl::OUString Content::getParentURL()
476 {
477 rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
478
479 // @@@ Extract URL of parent from aURL and return it...
480
481 return rtl::OUString();
482 }
483
484 //=========================================================================
485 // static
getPropertyValues(const uno::Reference<lang::XMultiServiceFactory> & rSMgr,const uno::Sequence<beans::Property> & rProperties,const ContentProperties & rData,const rtl::Reference<::ucbhelper::ContentProviderImplHelper> & rProvider,const rtl::OUString & rContentId)486 uno::Reference< sdbc::XRow > Content::getPropertyValues(
487 const uno::Reference< lang::XMultiServiceFactory >& rSMgr,
488 const uno::Sequence< beans::Property >& rProperties,
489 const ContentProperties& rData,
490 const rtl::Reference<
491 ::ucbhelper::ContentProviderImplHelper >& rProvider,
492 const rtl::OUString& rContentId )
493 {
494 // Note: Empty sequence means "get values of all supported properties".
495
496 rtl::Reference< ::ucbhelper::PropertyValueSet > xRow
497 = new ::ucbhelper::PropertyValueSet( rSMgr );
498
499 sal_Int32 nCount = rProperties.getLength();
500 if ( nCount )
501 {
502 uno::Reference< beans::XPropertySet > xAdditionalPropSet;
503 sal_Bool bTriedToGetAdditonalPropSet = sal_False;
504
505 const beans::Property* pProps = rProperties.getConstArray();
506 for ( sal_Int32 n = 0; n < nCount; ++n )
507 {
508 const beans::Property& rProp = pProps[ n ];
509
510 // Process Core properties.
511
512 if ( rProp.Name.equalsAsciiL(
513 RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
514 {
515 xRow->appendString ( rProp, rData.aContentType );
516 }
517 else if ( rProp.Name.equalsAsciiL(
518 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
519 {
520 xRow->appendString ( rProp, rData.aTitle );
521 }
522 else if ( rProp.Name.equalsAsciiL(
523 RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
524 {
525 xRow->appendBoolean( rProp, rData.bIsDocument );
526 }
527 else if ( rProp.Name.equalsAsciiL(
528 RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
529 {
530 xRow->appendBoolean( rProp, rData.bIsFolder );
531 }
532
533 // @@@ Process other properties supported directly.
534 #if 0
535 else if ( rProp.Name.equalsAsciiL(
536 RTL_CONSTASCII_STRINGPARAM( "xxxxxx" ) ) )
537 {
538 }
539 #endif
540 else
541 {
542 // @@@ Note: If your data source supports adding/removing
543 // properties, you should implement the interface
544 // XPropertyContainer by yourself and supply your own
545 // logic here. The base class uses the service
546 // "com.sun.star.ucb.Store" to maintain Additional Core
547 // properties. But using server functionality is preferred!
548
549 // Not a Core Property! Maybe it's an Additional Core Property?!
550
551 if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
552 {
553 xAdditionalPropSet
554 = uno::Reference< beans::XPropertySet >(
555 rProvider->getAdditionalPropertySet( rContentId,
556 sal_False ),
557 uno::UNO_QUERY );
558 bTriedToGetAdditonalPropSet = sal_True;
559 }
560
561 if ( xAdditionalPropSet.is() )
562 {
563 if ( !xRow->appendPropertySetValue(
564 xAdditionalPropSet,
565 rProp ) )
566 {
567 // Append empty entry.
568 xRow->appendVoid( rProp );
569 }
570 }
571 else
572 {
573 // Append empty entry.
574 xRow->appendVoid( rProp );
575 }
576 }
577 }
578 }
579 else
580 {
581 // Append all Core Properties.
582 xRow->appendString (
583 beans::Property( rtl::OUString::createFromAscii( "ContentType" ),
584 -1,
585 getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
586 beans::PropertyAttribute::BOUND
587 | beans::PropertyAttribute::READONLY ),
588 rData.aContentType );
589 xRow->appendString (
590 beans::Property( rtl::OUString::createFromAscii( "Title" ),
591 -1,
592 getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
593 beans::PropertyAttribute::BOUND ),
594 rData.aTitle );
595 xRow->appendBoolean(
596 beans::Property( rtl::OUString::createFromAscii( "IsDocument" ),
597 -1,
598 getCppuBooleanType(),
599 beans::PropertyAttribute::BOUND
600 | beans::PropertyAttribute::READONLY ),
601 rData.bIsDocument );
602 xRow->appendBoolean(
603 beans::Property( rtl::OUString::createFromAscii( "IsFolder" ),
604 -1,
605 getCppuBooleanType(),
606 beans::PropertyAttribute::BOUND
607 | beans::PropertyAttribute::READONLY ),
608 rData.bIsFolder );
609
610 // @@@ Append other properties supported directly.
611
612 // @@@ Note: If your data source supports adding/removing
613 // properties, you should implement the interface
614 // XPropertyContainer by yourself and supply your own
615 // logic here. The base class uses the service
616 // "com.sun.star.ucb.Store" to maintain Additional Core
617 // properties. But using server functionality is preferred!
618
619 // Append all Additional Core Properties.
620
621 uno::Reference< beans::XPropertySet > xSet(
622 rProvider->getAdditionalPropertySet( rContentId, sal_False ),
623 uno::UNO_QUERY );
624 xRow->appendPropertySet( xSet );
625 }
626
627 return uno::Reference< sdbc::XRow >( xRow.get() );
628 }
629
630 //=========================================================================
getPropertyValues(const uno::Sequence<beans::Property> & rProperties,const uno::Reference<ucb::XCommandEnvironment> &)631 uno::Reference< sdbc::XRow > Content::getPropertyValues(
632 const uno::Sequence< beans::Property >& rProperties,
633 const uno::Reference< ucb::XCommandEnvironment >& /* xEnv */)
634 {
635 osl::Guard< osl::Mutex > aGuard( m_aMutex );
636 return getPropertyValues( m_xSMgr,
637 rProperties,
638 m_aProps,
639 rtl::Reference<
640 ::ucbhelper::ContentProviderImplHelper >(
641 m_xProvider.get() ),
642 m_xIdentifier->getContentIdentifier() );
643 }
644
645 //=========================================================================
setPropertyValues(const uno::Sequence<beans::PropertyValue> & rValues,const uno::Reference<ucb::XCommandEnvironment> &)646 uno::Sequence< uno::Any > Content::setPropertyValues(
647 const uno::Sequence< beans::PropertyValue >& rValues,
648 const uno::Reference< ucb::XCommandEnvironment >& /* xEnv */)
649 {
650 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
651
652 uno::Sequence< uno::Any > aRet( rValues.getLength() );
653 uno::Sequence< beans::PropertyChangeEvent > aChanges( rValues.getLength() );
654 sal_Int32 nChanged = 0;
655
656 beans::PropertyChangeEvent aEvent;
657 aEvent.Source = static_cast< cppu::OWeakObject * >( this );
658 aEvent.Further = sal_False;
659 // aEvent.PropertyName =
660 aEvent.PropertyHandle = -1;
661 // aEvent.OldValue =
662 // aEvent.NewValue =
663
664 const beans::PropertyValue* pValues = rValues.getConstArray();
665 sal_Int32 nCount = rValues.getLength();
666
667 uno::Reference< ucb::XPersistentPropertySet > xAdditionalPropSet;
668 sal_Bool bTriedToGetAdditonalPropSet = sal_False;
669
670 for ( sal_Int32 n = 0; n < nCount; ++n )
671 {
672 const beans::PropertyValue& rValue = pValues[ n ];
673
674 if ( rValue.Name.equalsAsciiL(
675 RTL_CONSTASCII_STRINGPARAM( "ContentType" ) ) )
676 {
677 // Read-only property!
678 aRet[ n ] <<= lang::IllegalAccessException(
679 rtl::OUString::createFromAscii(
680 "Property is read-only!" ),
681 static_cast< cppu::OWeakObject * >( this ) );
682 }
683 else if ( rValue.Name.equalsAsciiL(
684 RTL_CONSTASCII_STRINGPARAM( "IsDocument" ) ) )
685 {
686 // Read-only property!
687 aRet[ n ] <<= lang::IllegalAccessException(
688 rtl::OUString::createFromAscii(
689 "Property is read-only!" ),
690 static_cast< cppu::OWeakObject * >( this ) );
691 }
692 else if ( rValue.Name.equalsAsciiL(
693 RTL_CONSTASCII_STRINGPARAM( "IsFolder" ) ) )
694 {
695 // Read-only property!
696 aRet[ n ] <<= lang::IllegalAccessException(
697 rtl::OUString::createFromAscii(
698 "Property is read-only!" ),
699 static_cast< cppu::OWeakObject * >( this ) );
700 }
701 else if ( rValue.Name.equalsAsciiL(
702 RTL_CONSTASCII_STRINGPARAM( "Title" ) ) )
703 {
704 rtl::OUString aNewValue;
705 if ( rValue.Value >>= aNewValue )
706 {
707 if ( aNewValue != m_aProps.aTitle )
708 {
709 aEvent.PropertyName = rValue.Name;
710 aEvent.OldValue = uno::makeAny( m_aProps.aTitle );
711 aEvent.NewValue = uno::makeAny( aNewValue );
712
713 aChanges.getArray()[ nChanged ] = aEvent;
714
715 m_aProps.aTitle = aNewValue;
716 nChanged++;
717 }
718 else
719 {
720 // Old value equals new value. No error!
721 }
722 }
723 else
724 {
725 aRet[ n ] <<= beans::IllegalTypeException(
726 rtl::OUString::createFromAscii(
727 "Property value has wrong type!" ),
728 static_cast< cppu::OWeakObject * >( this ) );
729 }
730 }
731
732 // @@@ Process other properties supported directly.
733 #if 0
734 else if ( rValue.Name.equalsAsciiL(
735 RTL_CONSTASCII_STRINGPARAM( "xxxxxx" ) ) )
736 {
737 }
738 #endif
739 else
740 {
741 // @@@ Note: If your data source supports adding/removing
742 // properties, you should implement the interface
743 // XPropertyContainer by yourself and supply your own
744 // logic here. The base class uses the service
745 // "com.sun.star.ucb.Store" to maintain Additional Core
746 // properties. But using server functionality is preferred!
747
748 // Not a Core Property! Maybe it's an Additional Core Property?!
749
750 if ( !bTriedToGetAdditonalPropSet && !xAdditionalPropSet.is() )
751 {
752 xAdditionalPropSet = getAdditionalPropertySet( sal_False );
753 bTriedToGetAdditonalPropSet = sal_True;
754 }
755
756 if ( xAdditionalPropSet.is() )
757 {
758 try
759 {
760 uno::Any aOldValue
761 = xAdditionalPropSet->getPropertyValue( rValue.Name );
762 if ( aOldValue != rValue.Value )
763 {
764 xAdditionalPropSet->setPropertyValue(
765 rValue.Name, rValue.Value );
766
767 aEvent.PropertyName = rValue.Name;
768 aEvent.OldValue = aOldValue;
769 aEvent.NewValue = rValue.Value;
770
771 aChanges.getArray()[ nChanged ] = aEvent;
772 nChanged++;
773 }
774 else
775 {
776 // Old value equals new value. No error!
777 }
778 }
779 catch ( beans::UnknownPropertyException const & e )
780 {
781 aRet[ n ] <<= e;
782 }
783 catch ( lang::WrappedTargetException const & e )
784 {
785 aRet[ n ] <<= e;
786 }
787 catch ( beans::PropertyVetoException const & e )
788 {
789 aRet[ n ] <<= e;
790 }
791 catch ( lang::IllegalArgumentException const & e )
792 {
793 aRet[ n ] <<= e;
794 }
795 }
796 else
797 {
798 aRet[ n ] <<= uno::Exception(
799 rtl::OUString::createFromAscii(
800 "No property set for storing the value!" ),
801 static_cast< cppu::OWeakObject * >( this ) );
802 }
803 }
804 }
805
806 if ( nChanged > 0 )
807 {
808 // @@@ Save changes.
809 // storeData();
810
811 aGuard.clear();
812 aChanges.realloc( nChanged );
813 notifyPropertiesChange( aChanges );
814 }
815
816 return aRet;
817 }
818
819 #ifdef IMPLEMENT_COMMAND_INSERT
820
821 //=========================================================================
queryChildren(ContentRefList & rChildren)822 void Content::queryChildren( ContentRefList& rChildren )
823 {
824 // @@@ Adapt method to your URL scheme...
825
826 // Obtain a list with a snapshot of all currently instanciated contents
827 // from provider and extract the contents which are direct children
828 // of this content.
829
830 ::ucbhelper::ContentRefList aAllContents;
831 m_xProvider->queryExistingContents( aAllContents );
832
833 ::rtl::OUString aURL = m_xIdentifier->getContentIdentifier();
834 sal_Int32 nPos = aURL.lastIndexOf( '/' );
835
836 if ( nPos != ( aURL.getLength() - 1 ) )
837 {
838 // No trailing slash found. Append.
839 aURL += ::rtl::OUString::createFromAscii( "/" );
840 }
841
842 sal_Int32 nLen = aURL.getLength();
843
844 ::ucbhelper::ContentRefList::const_iterator it = aAllContents.begin();
845 ::ucbhelper::ContentRefList::const_iterator end = aAllContents.end();
846
847 while ( it != end )
848 {
849 ::ucbhelper::ContentImplHelperRef xChild = (*it);
850 ::rtl::OUString aChildURL
851 = xChild->getIdentifier()->getContentIdentifier();
852
853 // Is aURL a prefix of aChildURL?
854 if ( ( aChildURL.getLength() > nLen ) &&
855 ( aChildURL.compareTo( aURL, nLen ) == 0 ) )
856 {
857 nPos = aChildURL.indexOf( '/', nLen );
858
859 if ( ( nPos == -1 ) ||
860 ( nPos == ( aChildURL.getLength() - 1 ) ) )
861 {
862 // No further slashes / only a final slash. It's a child!
863 rChildren.push_back(
864 ContentRef(
865 static_cast< Content * >( xChild.get() ) ) );
866 }
867 }
868 ++it;
869 }
870 }
871
872 //=========================================================================
insert(const uno::Reference<io::XInputStream> & xInputStream,sal_Bool bReplaceExisting,const uno::Reference<ucb::XCommandEnvironment> & Environment)873 void Content::insert(
874 const uno::Reference< io::XInputStream > & xInputStream,
875 sal_Bool bReplaceExisting,
876 const uno::Reference< ucb::XCommandEnvironment >& Environment )
877 throw( uno::Exception )
878 {
879 osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
880
881 // Check, if all required properties were set.
882
883 #if 0
884 // @@@ add checks for property presence
885 if ( m_aProps.xxxx == yyyyy )
886 {
887 OSL_ENSURE( sal_False, "Content::insert - property value missing!" );
888
889 uno::Sequence< rtl::OUString > aProps( 1 );
890 aProps[ 0 ] = rtl::OUString::createFromAscii( "zzzz" );
891 ::ucbhelper::cancelCommandExecution(
892 uno::makeAny( ucb::MissingPropertiesException(
893 rtl::OUString(),
894 static_cast< cppu::OWeakObject * >( this ),
895 aProps ) ),
896 Environment );
897 // Unreachable
898 }
899 #endif
900
901 bool bNeedInputStream = true; // @@@ adjust to real requirements
902 if ( bNeedInputStream && !xInputStream.is() )
903 {
904 OSL_ENSURE( sal_False, "Content::insert - No data stream!" );
905
906 ::ucbhelper::cancelCommandExecution(
907 uno::makeAny( ucb::MissingInputStreamException(
908 rtl::OUString(),
909 static_cast< cppu::OWeakObject * >( this ) ) ),
910 Environment );
911 // Unreachable
912 }
913
914 // Assemble new content identifier...
915
916 uno::Reference< ucb::XContentIdentifier > xId /* @@@ create content identifier */;
917
918 // Fail, if a resource with given id already exists.
919 if ( !bReplaceExisting /*&& hasData( xId ) @@@ impl for hasData() */ )
920 {
921 uno::Any aProps
922 = uno::makeAny( beans::PropertyValue(
923 rtl::OUString(
924 RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ),
925 -1,
926 uno::makeAny( xId->getContentIdentifier() ),
927 beans::PropertyState_DIRECT_VALUE ) );
928 ucbhelper::cancelCommandExecution(
929 ucb::IOErrorCode_ALREADY_EXISTING,
930 uno::Sequence< uno::Any >(&aProps, 1),
931 Environment,
932 rtl::OUString::createFromAscii( "content already existing!!" ),
933 this );
934 // Unreachable
935 }
936
937 m_xIdentifier = xId;
938
939 // @@@
940 // storeData();
941
942 aGuard.clear();
943 inserted();
944 }
945
946 #endif // IMPLEMENT_COMMAND_INSERT
947
948 #ifdef IMPLEMENT_COMMAND_DELETE
949
950 //=========================================================================
destroy(sal_Bool bDeletePhysical)951 void Content::destroy( sal_Bool bDeletePhysical )
952 throw( uno::Exception )
953 {
954 // @@@ take care about bDeletePhysical -> trashcan support
955
956 uno::Reference< ucb::XContent > xThis = this;
957
958 deleted();
959
960 osl::Guard< osl::Mutex > aGuard( m_aMutex );
961
962 // Process instanciated children...
963
964 ContentRefList aChildren;
965 queryChildren( aChildren );
966
967 ContentRefList::const_iterator it = aChildren.begin();
968 ContentRefList::const_iterator end = aChildren.end();
969
970 while ( it != end )
971 {
972 (*it)->destroy( bDeletePhysical );
973 ++it;
974 }
975 }
976
977 #endif // IMPLEMENT_COMMAND_DELETE
978
979
980