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