xref: /trunk/main/forms/source/xforms/submission.cxx (revision 24acc546)
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_forms.hxx"
26 #include "submission.hxx"
27 
28 #include "model.hxx"
29 #include "binding.hxx"
30 #include "mip.hxx"
31 #include "evaluationcontext.hxx"
32 #include "unohelper.hxx"
33 #include "submission/submission_put.hxx"
34 #include "submission/submission_post.hxx"
35 #include "submission/submission_get.hxx"
36 
37 #include <rtl/ustring.hxx>
38 #include <rtl/ustrbuf.hxx>
39 
40 #include <com/sun/star/uno/Sequence.hxx>
41 #include <com/sun/star/uno/Reference.hxx>
42 #include <com/sun/star/xforms/XModel.hpp>
43 #include <com/sun/star/uno/RuntimeException.hpp>
44 #include <com/sun/star/xml/xpath/XXPathObject.hpp>
45 #include <com/sun/star/container/XNameAccess.hpp>
46 #include <com/sun/star/xml/xpath/XPathObjectType.hpp>
47 #include <com/sun/star/xml/dom/XNodeList.hpp>
48 #include <com/sun/star/xml/dom/XDocument.hpp>
49 #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
50 #include <com/sun/star/xml/dom/XDocumentFragment.hpp>
51 #include <com/sun/star/xml/dom/NodeType.hpp>
52 #include <com/sun/star/task/XInteractionHandler.hpp>
53 #include <com/sun/star/task/XInteractionRequest.hpp>
54 #include <com/sun/star/task/XInteractionContinuation.hpp>
55 #include <com/sun/star/xforms/InvalidDataOnSubmitException.hpp>
56 #include <com/sun/star/frame/XFrame.hpp>
57 #include <cppuhelper/typeprovider.hxx>
58 #include <comphelper/propertysetinfo.hxx>
59 #include <comphelper/interaction.hxx>
60 #include <unotools/processfactory.hxx>
61 #include <memory>
62 
63 
64 
65 
66 using rtl::OUString;
67 using rtl::OUStringBuffer;
68 using com::sun::star::beans::UnknownPropertyException;
69 using com::sun::star::beans::PropertyVetoException;
70 using com::sun::star::lang::IllegalArgumentException;
71 using com::sun::star::util::VetoException;
72 using com::sun::star::form::submission::XSubmissionVetoListener;
73 using com::sun::star::lang::WrappedTargetException;
74 using com::sun::star::lang::NoSupportException;
75 using com::sun::star::task::XInteractionHandler;
76 using com::sun::star::task::XInteractionRequest;
77 using com::sun::star::task::XInteractionContinuation;
78 using com::sun::star::xforms::XModel;
79 using com::sun::star::xforms::InvalidDataOnSubmitException;
80 using com::sun::star::container::XNameAccess;
81 using com::sun::star::xml::xpath::XXPathObject;
82 using com::sun::star::xml::xpath::XPathObjectType;
83 using com::sun::star::frame::XFrame;
84 using xforms::Submission;
85 using xforms::Model;
86 using xforms::MIP;
87 using std::auto_ptr;
88 
89 using namespace com::sun::star::uno;
90 using namespace com::sun::star::lang;
91 using namespace com::sun::star::xml::dom;
92 
Submission()93 Submission::Submission() :
94     msID(),
95     msBind(),
96     maRef(),
97     msAction(),
98     msMethod(),
99     msVersion(),
100     mbIndent(),
101     msMediaType(),
102     msEncoding(),
103     mbOmitXmlDeclaration(),
104     mbStandalone(),
105     msCDataSectionElement(),
106     msReplace( OUSTRING("none") ),
107     msSeparator(),
108     msIncludeNamespacePrefixes(),
109     m_aFactory(utl::getProcessServiceFactory())
110 {
111     initializePropertySet();
112 }
113 
~Submission()114 Submission::~Submission() throw()
115 {
116 }
117 
getModel() const118 Reference<XModel> Submission::getModel() const
119 {
120     return mxModel;
121 }
122 
setModel(const Reference<XModel> & xModel)123 void Submission::setModel( const Reference<XModel>& xModel )
124 {
125     mxModel = xModel;
126 }
127 
getID() const128 OUString Submission::getID() const
129 {
130     return msID;
131 }
132 
setID(const OUString & sID)133 void Submission::setID( const OUString& sID )
134 {
135     msID = sID;
136 }
137 
getBind() const138 OUString Submission::getBind() const
139 {
140     return msBind;
141 }
142 
setBind(const OUString & sBind)143 void Submission::setBind( const OUString& sBind )
144 {
145     msBind = sBind;
146 }
147 
getRef() const148 OUString Submission::getRef() const
149 {
150     return maRef.getExpression();
151 }
152 
setRef(const OUString & sRef)153 void Submission::setRef( const OUString& sRef )
154 {
155     maRef.setExpression( sRef );
156 }
157 
getAction() const158 OUString Submission::getAction() const
159 {
160     return msAction;
161 }
162 
setAction(const OUString & sAction)163 void Submission::setAction( const OUString& sAction )
164 {
165     msAction = sAction;
166 }
167 
getMethod() const168 OUString Submission::getMethod() const
169 {
170     return msMethod;
171 }
172 
setMethod(const OUString & sMethod)173 void Submission::setMethod( const OUString& sMethod )
174 {
175     msMethod = sMethod;
176 }
177 
getVersion() const178 OUString Submission::getVersion() const
179 {
180     return msVersion;
181 }
182 
setVersion(const OUString & sVersion)183 void Submission::setVersion( const OUString& sVersion )
184 {
185     msVersion = sVersion;
186 }
187 
getIndent() const188 bool Submission::getIndent() const
189 {
190     return mbIndent;
191 }
192 
setIndent(bool bIndent)193 void Submission::setIndent( bool bIndent )
194 {
195     mbIndent = bIndent;
196 }
197 
getMediaType() const198 OUString Submission::getMediaType() const
199 {
200     return msMediaType;
201 }
202 
setMediaType(const OUString & sMediaType)203 void Submission::setMediaType( const OUString& sMediaType )
204 {
205     msMediaType = sMediaType;
206 }
207 
getEncoding() const208 OUString Submission::getEncoding() const
209 {
210     return msEncoding;
211 }
212 
setEncoding(const OUString & sEncoding)213 void Submission::setEncoding( const OUString& sEncoding )
214 {
215     msEncoding = sEncoding;
216 }
217 
getOmitXmlDeclaration() const218 bool Submission::getOmitXmlDeclaration() const
219 {
220     return mbOmitXmlDeclaration;
221 }
222 
setOmitXmlDeclaration(bool bOmitXmlDeclaration)223 void Submission::setOmitXmlDeclaration( bool bOmitXmlDeclaration )
224 {
225     mbOmitXmlDeclaration = bOmitXmlDeclaration;
226 }
227 
getStandalone() const228 bool Submission::getStandalone() const
229 {
230     return mbStandalone;
231 }
232 
setStandalone(bool bStandalone)233 void Submission::setStandalone( bool bStandalone )
234 {
235     mbStandalone = bStandalone;
236 }
237 
getCDataSectionElement() const238 OUString Submission::getCDataSectionElement() const
239 {
240     return msCDataSectionElement;
241 }
242 
setCDataSectionElement(const OUString & sCDataSectionElement)243 void Submission::setCDataSectionElement( const OUString& sCDataSectionElement )
244 {
245     msCDataSectionElement = sCDataSectionElement;
246 }
247 
getReplace() const248 OUString Submission::getReplace() const
249 {
250     return msReplace;
251 }
252 
setReplace(const OUString & sReplace)253 void Submission::setReplace( const OUString& sReplace )
254 {
255     msReplace = sReplace;
256 }
257 
getSeparator() const258 OUString Submission::getSeparator() const
259 {
260     return msSeparator;
261 }
262 
setSeparator(const OUString & sSeparator)263 void Submission::setSeparator( const OUString& sSeparator )
264 {
265     msSeparator = sSeparator;
266 }
267 
getIncludeNamespacePrefixes() const268 Sequence< OUString > Submission::getIncludeNamespacePrefixes() const
269 {
270     return msIncludeNamespacePrefixes;
271 }
272 
setIncludeNamespacePrefixes(const Sequence<OUString> & rIncludeNamespacePrefixes)273 void Submission::setIncludeNamespacePrefixes( const Sequence< OUString >& rIncludeNamespacePrefixes )
274 {
275     msIncludeNamespacePrefixes = rIncludeNamespacePrefixes;
276 }
277 
doSubmit(const Reference<XInteractionHandler> & xHandler)278 bool Submission::doSubmit( const Reference< XInteractionHandler >& xHandler )
279 {
280     liveCheck();
281 
282     // construct XXPathObject for submission doc; use bind in preference of ref
283     EvaluationContext aEvalContext;
284     ComputedExpression aExpression;
285     if( msBind.getLength() != 0 )
286     {
287         Binding* pBinding = Binding::getBinding( mxModel->getBinding(msBind) );
288         if( pBinding != NULL )
289         {
290             aExpression.setExpression( pBinding->getBindingExpression() );
291             aEvalContext = pBinding->getEvaluationContext();
292         }
293         // TODO: else: illegal binding name -> raise error
294     }
295     else if( maRef.getExpression().getLength() != 0 )
296     {
297         aExpression.setExpression( maRef.getExpression() );
298         aEvalContext = Model::getModel( mxModel )->getEvaluationContext();
299     }
300     else
301     {
302         aExpression.setExpression( OUSTRING( "/" ) );
303         aEvalContext = Model::getModel( mxModel )->getEvaluationContext();
304     }
305     aExpression.evaluate( aEvalContext );
306     Reference<XXPathObject> xResult = aExpression.getXPath();
307     OSL_ENSURE( xResult.is(), "no result?" );
308 
309     // early out if we have not obtained any result
310     if( ! xResult.is() )
311         return false;
312 
313 
314     // Reference< XNodeList > aList = xResult->getNodeList();
315     OUString aMethod = getMethod();
316 
317     // strip whitespace-only text node for get submission
318     Reference< XDocumentFragment > aFragment = createSubmissionDocument(
319         xResult, aMethod.equalsIgnoreAsciiCaseAscii("get"));
320 
321     // submit result; set encoding, etc.
322     auto_ptr<CSubmission> xSubmission;
323     if (aMethod.equalsIgnoreAsciiCaseAscii("PUT"))
324         xSubmission = auto_ptr<CSubmission>(
325             new CSubmissionPut( getAction(), aFragment));
326     else if (aMethod.equalsIgnoreAsciiCaseAscii("post"))
327         xSubmission = auto_ptr<CSubmission>(
328             new CSubmissionPost( getAction(), aFragment));
329     else if (aMethod.equalsIgnoreAsciiCaseAscii("get"))
330         xSubmission = auto_ptr<CSubmission>(
331             new CSubmissionGet( getAction(), aFragment));
332     else
333     {
334         OSL_ENSURE(sal_False, "Unsupported xforms submission method");
335         return false;
336     }
337 
338     xSubmission->setEncoding(getEncoding());
339     CSubmission::SubmissionResult aResult = xSubmission->submit( xHandler );
340 
341     if (aResult == CSubmission::SUCCESS)
342     {
343         Reference< XDocument > aInstanceDoc = getInstanceDocument(xResult);
344         aResult = xSubmission->replace(getReplace(), aInstanceDoc, Reference< XFrame >());
345     }
346 
347     return ( aResult == CSubmission::SUCCESS );
348 }
349 
getUnoTunnelID()350 Sequence<sal_Int8> Submission::getUnoTunnelID()
351 {
352     static cppu::OImplementationId aImplementationId;
353     return aImplementationId.getImplementationId();
354 }
355 
getSubmission(const Reference<XPropertySet> & xPropertySet)356 Submission* Submission::getSubmission(
357     const Reference<XPropertySet>& xPropertySet )
358 {
359     Reference<XUnoTunnel> xTunnel( xPropertySet, UNO_QUERY );
360     return xTunnel.is()
361         ? reinterpret_cast<Submission*>(
362             xTunnel->getSomething( getUnoTunnelID() ) )
363         : NULL;
364 }
365 
366 
367 
368 
369 
370 
liveCheck()371 void Submission::liveCheck()
372     throw( RuntimeException )
373 {
374     bool bValid = mxModel.is();
375 
376     if( ! bValid )
377         throw RuntimeException();
378 }
379 
getModelImpl() const380 Model* Submission::getModelImpl() const
381 {
382     Model* pModel = NULL;
383     if( mxModel.is() )
384         pModel = Model::getModel( mxModel );
385     return pModel;
386 }
387 
388 
389 //
390 // Property-Set implementation
391 //
392 
393 #define HANDLE_ID 0
394 #define HANDLE_Bind 1
395 #define HANDLE_Ref 2
396 #define HANDLE_Action 3
397 #define HANDLE_Method 4
398 #define HANDLE_Version 5
399 #define HANDLE_Indent 6
400 #define HANDLE_MediaType 7
401 #define HANDLE_Encoding 8
402 #define HANDLE_OmitXmlDeclaration 9
403 #define HANDLE_Standalone 10
404 #define HANDLE_CDataSectionElement 11
405 #define HANDLE_Replace 12
406 #define HANDLE_Separator 13
407 #define HANDLE_IncludeNamespacePrefixes 14
408 #define HANDLE_Model 15
409 
410 #define REGISTER_PROPERTY( property, type )   \
411     registerProperty( PROPERTY( property, type ), \
412     new DirectPropertyAccessor< Submission, type >( this, &Submission::set##property, &Submission::get##property ) );
413 
414 #define REGISTER_PROPERTY_BOOL( property )   \
415     registerProperty( PROPERTY( property, bool ), \
416     new BooleanPropertyAccessor< Submission, bool >( this, &Submission::set##property, &Submission::get##property ) );
417 
initializePropertySet()418 void Submission::initializePropertySet()
419 {
420     REGISTER_PROPERTY     ( ID,                         OUString );
421     REGISTER_PROPERTY     ( Bind,                       OUString );
422     REGISTER_PROPERTY     ( Ref,                        OUString );
423     REGISTER_PROPERTY     ( Action,                     OUString );
424     REGISTER_PROPERTY     ( Method,                     OUString );
425     REGISTER_PROPERTY     ( Version,                    OUString );
426     REGISTER_PROPERTY_BOOL( Indent );
427     REGISTER_PROPERTY     ( MediaType,                  OUString );
428     REGISTER_PROPERTY     ( Encoding,                   OUString );
429     REGISTER_PROPERTY_BOOL( OmitXmlDeclaration );
430     REGISTER_PROPERTY_BOOL( Standalone );
431     REGISTER_PROPERTY     ( CDataSectionElement,        OUString );
432     REGISTER_PROPERTY     ( Replace,                    OUString );
433     REGISTER_PROPERTY     ( Separator,                  OUString );
434     REGISTER_PROPERTY     ( IncludeNamespacePrefixes,   Sequence< OUString > );
435     REGISTER_PROPERTY     ( Model,                      Reference<XModel> );
436 
437     initializePropertyValueCache( HANDLE_Indent );
438     initializePropertyValueCache( HANDLE_OmitXmlDeclaration );
439     initializePropertyValueCache( HANDLE_Standalone );
440 }
441 
convertFastPropertyValue(Any & rConvertedValue,Any & rOldValue,sal_Int32 nHandle,const Any & rValue)442 sal_Bool SAL_CALL Submission::convertFastPropertyValue(
443     Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue )
444 	throw ( IllegalArgumentException )
445 {
446     if ( nHandle == HANDLE_IncludeNamespacePrefixes )
447     {
448         // for convinience reasons (????), we accept a string which contains
449         // a comma-separated list of namespace prefixes
450         ::rtl::OUString sTokenList;
451         if ( rValue >>= sTokenList )
452         {
453             std::vector< OUString > aPrefixes;
454             sal_Int32 p = 0;
455             while ( p >= 0 )
456                 aPrefixes.push_back( sTokenList.getToken( 0, ',', p ) );
457 
458             Sequence< ::rtl::OUString > aConvertedPrefixes( &aPrefixes[0], aPrefixes.size() );
459             return PropertySetBase::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, makeAny( aConvertedPrefixes ) );
460         }
461     }
462 
463     return PropertySetBase::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
464 }
465 
getName()466 OUString SAL_CALL Submission::getName()
467     throw( RuntimeException )
468 {
469     return getID();
470 }
471 
setName(const OUString & sID)472 void SAL_CALL Submission::setName( const OUString& sID )
473     throw( RuntimeException )
474 {
475     setID( sID );
476 }
477 
478 
479 
getSomething(const Sequence<sal_Int8> & aId)480 sal_Int64 SAL_CALL Submission::getSomething(
481     const Sequence<sal_Int8>& aId )
482     throw( RuntimeException )
483 {
484     return ( aId == getUnoTunnelID() ) ? reinterpret_cast<sal_Int64>(this) : 0;
485 }
486 
487 
lcl_message(const OUString & rID,const OUString & rText)488 OUString lcl_message( const OUString& rID, const OUString& rText )
489 {
490     OUStringBuffer aMessage;
491     aMessage.append( OUSTRING("XForms submission '") );
492     aMessage.append( rID );
493     aMessage.append( OUSTRING("' failed") );
494     aMessage.append( rText );
495     aMessage.append( OUSTRING(".") );
496     return aMessage.makeStringAndClear();
497 }
498 
submitWithInteraction(const Reference<XInteractionHandler> & _rxHandler)499 void SAL_CALL Submission::submitWithInteraction(
500     const Reference<XInteractionHandler>& _rxHandler )
501     throw ( VetoException,
502             WrappedTargetException,
503             RuntimeException )
504 {
505     // as long as this class is not really threadsafe, we need to copy
506     // the members we're interested in
507     Reference< XModel > xModel( mxModel );
508     ::rtl::OUString sID( msID );
509 
510     if ( !xModel.is() || !msID.getLength() )
511         throw RuntimeException(
512                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "This is not a valid submission object." ) ),
513                 *this
514               );
515 
516     Model* pModel = Model::getModel( xModel );
517     OSL_ENSURE( pModel != NULL, "illegal model?" );
518 
519     // #i36765# #i47248# warning on submission of illegal data
520     // check for validity (and query user if invalid)
521     bool bValid = pModel->isValid();
522     if( ! bValid )
523     {
524         InvalidDataOnSubmitException aInvalidDataException(
525             lcl_message(sID, OUSTRING(" due to invalid data") ), *this );
526 
527         if( _rxHandler.is() )
528         {
529             // labouriously create interaction request
530             comphelper::OInteractionRequest* pRequest
531                 = new comphelper::OInteractionRequest(
532                     makeAny( aInvalidDataException ) );
533             Reference<XInteractionRequest> xRequest = pRequest;
534 
535             comphelper::OInteractionApprove* pContinue
536                 = new comphelper::OInteractionApprove();
537             Reference<XInteractionContinuation> xContinue = pContinue;
538             pRequest->addContinuation( xContinue );
539 
540             comphelper::OInteractionDisapprove* pCancel
541                 = new comphelper::OInteractionDisapprove();
542             Reference<XInteractionContinuation> xCancel = pCancel;
543             pRequest->addContinuation( xCancel );
544 
545             // ask the handler...
546             _rxHandler->handle( xRequest );
547             OSL_ENSURE( pContinue->wasSelected() || pCancel->wasSelected(),
548                         "handler didn't select" );
549 
550             // and continue, if user chose 'continue'
551             if( pContinue->wasSelected() )
552                 bValid = true;
553         }
554 
555         // abort if invalid (and user didn't tell us to continue)
556         if( ! bValid )
557             throw aInvalidDataException;
558     }
559 
560     // attempt submission
561     bool bResult = false;
562     try
563     {
564         bResult = doSubmit( _rxHandler );
565     }
566     catch( const VetoException& )
567     {
568         OSL_ENSURE( sal_False, "Model::submit: Hmm. How can a single submission have a veto right?" );
569         // allowed to leave
570         throw;
571     }
572     catch( const Exception& e )
573     {
574         // exception caught: re-throw as wrapped target exception
575         throw WrappedTargetException(
576             lcl_message( sID, OUSTRING(" due to exception being thrown") ),
577             *this, makeAny( e ) );
578     }
579 
580     if( bResult )
581     {
582         mxModel->rebuild();
583     }
584     else
585     {
586         // other failure: throw wrapped target exception, too.
587         throw WrappedTargetException(
588             lcl_message( sID, OUString() ), *this, Any() );
589     }
590 }
591 
submit()592 void SAL_CALL Submission::submit( ) throw ( VetoException, WrappedTargetException, RuntimeException )
593 {
594     submitWithInteraction( NULL );
595 }
596 
addSubmissionVetoListener(const Reference<XSubmissionVetoListener> &)597 void SAL_CALL Submission::addSubmissionVetoListener( const Reference< XSubmissionVetoListener >& /*listener*/ ) throw (NoSupportException, RuntimeException)
598 {
599     // TODO
600     throw NoSupportException();
601 }
602 
removeSubmissionVetoListener(const Reference<XSubmissionVetoListener> &)603 void SAL_CALL Submission::removeSubmissionVetoListener( const Reference< XSubmissionVetoListener >& /*listener*/ ) throw (NoSupportException, RuntimeException)
604 {
605     // TODO
606     throw NoSupportException();
607 }
608 
_isIgnorable(const Reference<XNode> & aNode)609 static sal_Bool _isIgnorable(const Reference< XNode >& aNode)
610 {
611     // ignore whitespace-only textnodes
612     if (aNode->getNodeType() == NodeType_TEXT_NODE)
613     {
614         OUString aTrimmedValue = aNode->getNodeValue().trim();
615         if (aTrimmedValue.getLength() == 0) return sal_True;
616     }
617 
618     return sal_False;
619 }
620 
621 // recursively copy relevant nodes from A to B
_cloneNodes(Model & aModel,const Reference<XNode> & dstParent,const Reference<XNode> & source,sal_Bool bRemoveWSNodes)622 static void _cloneNodes(Model& aModel, const Reference< XNode >& dstParent, const Reference< XNode >& source, sal_Bool bRemoveWSNodes)
623 {
624     if (!source.is()) return;
625 
626     Reference< XNode > cur = source;
627     Reference< XDocument > dstDoc = dstParent->getOwnerDocument();
628     Reference< XNode > imported;
629 
630     if (cur.is())
631     {
632         //  is this node relevant?
633         MIP mip = aModel.queryMIP(cur);
634         if(mip.isRelevant() && !(bRemoveWSNodes && _isIgnorable(cur)))
635         {
636             imported = dstDoc->importNode(cur, sal_False);
637             imported = dstParent->appendChild(imported);
638             // append source children to new imported parent
639             for( cur = cur->getFirstChild(); cur.is(); cur = cur->getNextSibling() )
640                 _cloneNodes(aModel, imported, cur, bRemoveWSNodes);
641         }
642     }
643 }
getInstanceDocument(const Reference<XXPathObject> & aObj)644 Reference< XDocument > Submission::getInstanceDocument(const Reference< XXPathObject >& aObj)
645 {
646     using namespace com::sun::star::xml::xpath;
647     // result
648     Reference< XDocument > aDocument;
649 
650     if (aObj->getObjectType() == XPathObjectType_XPATH_NODESET)
651     {
652         Reference< XNodeList > aList = aObj->getNodeList();
653         if (aList->getLength() > 0)
654             aDocument = aList->item(0)->getOwnerDocument();
655     }
656     return aDocument;
657 }
658 
createSubmissionDocument(const Reference<XXPathObject> & aObj,sal_Bool bRemoveWSNodes)659 Reference< XDocumentFragment > Submission::createSubmissionDocument(const Reference< XXPathObject >& aObj, sal_Bool bRemoveWSNodes)
660 {
661     using namespace com::sun::star::xml::xpath;
662     Reference< XDocumentBuilder > aDocBuilder(m_aFactory->createInstance(
663         OUString::createFromAscii("com.sun.star.xml.dom.DocumentBuilder")), UNO_QUERY);
664     Reference< XDocument > aDocument = aDocBuilder->newDocument();
665     Reference< XDocumentFragment > aFragment = aDocument->createDocumentFragment();
666 
667     //
668     if (aObj->getObjectType() == XPathObjectType_XPATH_NODESET)
669     {
670         Reference< XNodeList > aList = aObj->getNodeList();
671         Reference< XNode > aListItem;
672         for (sal_Int32 i=0; i < aList->getLength(); i++)
673         {
674             aListItem = aList->item(i);
675             if (aListItem->getNodeType()==NodeType_DOCUMENT_NODE)
676                 aListItem = Reference< XNode >(
677                     (Reference< XDocument >(aListItem, UNO_QUERY))->getDocumentElement(), UNO_QUERY);
678             // copy relevant nodes from instance into fragment
679             _cloneNodes(*getModelImpl(), Reference< XNode >(aFragment, UNO_QUERY), aListItem, bRemoveWSNodes);
680         }
681     }
682     return aFragment;
683 }
684 
685 // some forwarding: XPropertySet is implemented in our base class,
686 // but also available as base of XSubmission
getPropertySetInfo()687 Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL Submission::getPropertySetInfo(  ) throw(RuntimeException)
688 {
689     return PropertySetBase::getPropertySetInfo();
690 }
setPropertyValue(const::rtl::OUString & aPropertyName,const Any & aValue)691 void SAL_CALL Submission::setPropertyValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
692 {
693     PropertySetBase::setPropertyValue( aPropertyName, aValue );
694 }
getPropertyValue(const::rtl::OUString & PropertyName)695 Any SAL_CALL Submission::getPropertyValue( const ::rtl::OUString& PropertyName ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
696 {
697     return PropertySetBase::getPropertyValue( PropertyName );
698 }
addPropertyChangeListener(const::rtl::OUString & aPropertyName,const Reference<::com::sun::star::beans::XPropertyChangeListener> & xListener)699 void SAL_CALL Submission::addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
700 {
701     PropertySetBase::addPropertyChangeListener( aPropertyName, xListener );
702 }
removePropertyChangeListener(const::rtl::OUString & aPropertyName,const Reference<::com::sun::star::beans::XPropertyChangeListener> & aListener)703 void SAL_CALL Submission::removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
704 {
705     PropertySetBase::removePropertyChangeListener( aPropertyName, aListener );
706 }
addVetoableChangeListener(const::rtl::OUString & PropertyName,const Reference<::com::sun::star::beans::XVetoableChangeListener> & aListener)707 void SAL_CALL Submission::addVetoableChangeListener( const ::rtl::OUString& PropertyName, const Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
708 {
709     PropertySetBase::addVetoableChangeListener( PropertyName, aListener );
710 }
removeVetoableChangeListener(const::rtl::OUString & PropertyName,const Reference<::com::sun::star::beans::XVetoableChangeListener> & aListener)711 void SAL_CALL Submission::removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
712 {
713     PropertySetBase::removeVetoableChangeListener( PropertyName, aListener );
714 }
715 
716