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