summaryrefslogtreecommitdiffstats
path: root/forms/source/xforms/submission
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--forms/source/xforms/submission.cxx609
-rw-r--r--forms/source/xforms/submission.hxx232
-rw-r--r--forms/source/xforms/submission/replace.cxx131
-rw-r--r--forms/source/xforms/submission/serialization.hxx60
-rw-r--r--forms/source/xforms/submission/serialization_app_xml.cxx126
-rw-r--r--forms/source/xforms/submission/serialization_app_xml.hxx40
-rw-r--r--forms/source/xforms/submission/serialization_urlencoded.cxx181
-rw-r--r--forms/source/xforms/submission/serialization_urlencoded.hxx47
-rw-r--r--forms/source/xforms/submission/submission.hxx137
-rw-r--r--forms/source/xforms/submission/submission_get.cxx103
-rw-r--r--forms/source/xforms/submission/submission_get.hxx33
-rw-r--r--forms/source/xforms/submission/submission_post.cxx78
-rw-r--r--forms/source/xforms/submission/submission_post.hxx32
-rw-r--r--forms/source/xforms/submission/submission_put.cxx67
-rw-r--r--forms/source/xforms/submission/submission_put.hxx33
15 files changed, 1909 insertions, 0 deletions
diff --git a/forms/source/xforms/submission.cxx b/forms/source/xforms/submission.cxx
new file mode 100644
index 000000000..d8d81abd5
--- /dev/null
+++ b/forms/source/xforms/submission.cxx
@@ -0,0 +1,609 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "submission.hxx"
+
+#include "model.hxx"
+#include "binding.hxx"
+#include "mip.hxx"
+#include "evaluationcontext.hxx"
+#include "submission/submission_put.hxx"
+#include "submission/submission_post.hxx"
+#include "submission/submission_get.hxx"
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/lang/NoSupportException.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/xforms/XModel.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/xml/dom/XNodeList.hpp>
+#include <com/sun/star/xml/dom/XDocument.hpp>
+#include <com/sun/star/xml/dom/DocumentBuilder.hpp>
+#include <com/sun/star/xml/dom/XDocumentFragment.hpp>
+#include <com/sun/star/xml/dom/NodeType.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+#include <com/sun/star/task/XInteractionRequest.hpp>
+#include <com/sun/star/task/XInteractionContinuation.hpp>
+#include <com/sun/star/xforms/InvalidDataOnSubmitException.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <cppuhelper/exc_hlp.hxx>
+#include <comphelper/interaction.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <memory>
+#include <string_view>
+
+using com::sun::star::util::VetoException;
+using com::sun::star::form::submission::XSubmissionVetoListener;
+using com::sun::star::lang::WrappedTargetException;
+using com::sun::star::lang::NoSupportException;
+using com::sun::star::task::XInteractionHandler;
+using com::sun::star::task::XInteractionRequest;
+using com::sun::star::task::XInteractionContinuation;
+using com::sun::star::xforms::XModel;
+using com::sun::star::xforms::InvalidDataOnSubmitException;
+using com::sun::star::xml::xpath::XXPathObject;
+using com::sun::star::frame::XFrame;
+using xforms::Submission;
+using xforms::Model;
+using xforms::MIP;
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::xml::dom;
+
+Submission::Submission() :
+ mbIndent(),
+ mbOmitXmlDeclaration(),
+ mbStandalone(),
+ msReplace( "none" )
+{
+ initializePropertySet();
+}
+
+Submission::~Submission() noexcept
+{
+}
+
+
+void Submission::setModel( const Reference<XModel>& xModel )
+{
+ mxModel = xModel;
+}
+
+
+void Submission::setID( const OUString& sID )
+{
+ msID = sID;
+}
+
+
+void Submission::setBind( const OUString& sBind )
+{
+ msBind = sBind;
+}
+
+OUString Submission::getRef() const
+{
+ return maRef.getExpression();
+}
+
+void Submission::setRef( const OUString& sRef )
+{
+ maRef.setExpression( sRef );
+}
+
+
+void Submission::setAction( const OUString& sAction )
+{
+ msAction = sAction;
+}
+
+
+void Submission::setMethod( const OUString& sMethod )
+{
+ msMethod = sMethod;
+}
+
+
+void Submission::setVersion( const OUString& sVersion )
+{
+ msVersion = sVersion;
+}
+
+
+void Submission::setIndent( bool bIndent )
+{
+ mbIndent = bIndent;
+}
+
+
+void Submission::setMediaType( const OUString& sMediaType )
+{
+ msMediaType = sMediaType;
+}
+
+
+void Submission::setEncoding( const OUString& sEncoding )
+{
+ msEncoding = sEncoding;
+}
+
+
+void Submission::setOmitXmlDeclaration( bool bOmitXmlDeclaration )
+{
+ mbOmitXmlDeclaration = bOmitXmlDeclaration;
+}
+
+
+void Submission::setStandalone( bool bStandalone )
+{
+ mbStandalone = bStandalone;
+}
+
+
+void Submission::setCDataSectionElement( const OUString& sCDataSectionElement )
+{
+ msCDataSectionElement = sCDataSectionElement;
+}
+
+
+void Submission::setReplace( const OUString& sReplace )
+{
+ msReplace = sReplace;
+}
+
+
+void Submission::setSeparator( const OUString& sSeparator )
+{
+ msSeparator = sSeparator;
+}
+
+
+void Submission::setIncludeNamespacePrefixes( const Sequence< OUString >& rIncludeNamespacePrefixes )
+{
+ msIncludeNamespacePrefixes = rIncludeNamespacePrefixes;
+}
+
+bool Submission::doSubmit( const Reference< XInteractionHandler >& xHandler )
+{
+ liveCheck();
+
+ // construct XXPathObject for submission doc; use bind in preference of ref
+ EvaluationContext aEvalContext;
+ ComputedExpression aExpression;
+ if( !msBind.isEmpty() )
+ {
+ Binding* pBinding = comphelper::getFromUnoTunnel<Binding>( mxModel->getBinding(msBind) );
+ if( pBinding != nullptr )
+ {
+ aExpression.setExpression( pBinding->getBindingExpression() );
+ aEvalContext = pBinding->getEvaluationContext();
+ }
+ // TODO: else: illegal binding name -> raise error
+ }
+ else if( !maRef.getExpression().isEmpty() )
+ {
+ aExpression.setExpression( maRef.getExpression() );
+ aEvalContext = comphelper::getFromUnoTunnel<Model>( mxModel )->getEvaluationContext();
+ }
+ else
+ {
+ aExpression.setExpression( "/" );
+ aEvalContext = comphelper::getFromUnoTunnel<Model>( mxModel )->getEvaluationContext();
+ }
+ aExpression.evaluate( aEvalContext );
+ Reference<XXPathObject> xResult = aExpression.getXPath();
+ OSL_ENSURE( xResult.is(), "no result?" );
+
+ // early out if we have not obtained any result
+ if( ! xResult.is() )
+ return false;
+
+
+ // Reference< XNodeList > aList = xResult->getNodeList();
+ OUString aMethod = getMethod();
+
+ // strip whitespace-only text node for get submission
+ Reference< XDocumentFragment > aFragment = createSubmissionDocument(
+ xResult, aMethod.equalsIgnoreAsciiCase("get"));
+
+ // submit result; set encoding, etc.
+ std::unique_ptr<CSubmission> xSubmission;
+ if (aMethod.equalsIgnoreAsciiCase("PUT"))
+ xSubmission.reset(new CSubmissionPut( getAction(), aFragment));
+ else if (aMethod.equalsIgnoreAsciiCase("post"))
+ xSubmission.reset(new CSubmissionPost( getAction(), aFragment));
+ else if (aMethod.equalsIgnoreAsciiCase("get"))
+ xSubmission.reset(new CSubmissionGet( getAction(), aFragment));
+ else
+ {
+ OSL_FAIL("Unsupported xforms submission method");
+ return false;
+ }
+
+ if (!xSubmission->IsWebProtocol())
+ return false;
+
+ CSubmission::SubmissionResult aResult = xSubmission->submit( xHandler );
+
+ if (aResult == CSubmission::SUCCESS)
+ {
+ Reference< XDocument > aInstanceDoc = getInstanceDocument(xResult);
+ aResult = xSubmission->replace(getReplace(), aInstanceDoc, Reference< XFrame >());
+ }
+
+ return ( aResult == CSubmission::SUCCESS );
+}
+
+Sequence<sal_Int8> Submission::getUnoTunnelId()
+{
+ static const comphelper::UnoIdInit aImplementationId;
+ return aImplementationId.getSeq();
+}
+
+
+void Submission::liveCheck()
+{
+ bool bValid = mxModel.is();
+
+ if( ! bValid )
+ throw RuntimeException();
+}
+
+Model* Submission::getModelImpl() const
+{
+ Model* pModel = nullptr;
+ if( mxModel.is() )
+ pModel = comphelper::getFromUnoTunnel<Model>( mxModel );
+ return pModel;
+}
+
+
+// Property-Set implementation
+
+
+#define HANDLE_ID 0
+#define HANDLE_Bind 1
+#define HANDLE_Ref 2
+#define HANDLE_Action 3
+#define HANDLE_Method 4
+#define HANDLE_Version 5
+#define HANDLE_Indent 6
+#define HANDLE_MediaType 7
+#define HANDLE_Encoding 8
+#define HANDLE_OmitXmlDeclaration 9
+#define HANDLE_Standalone 10
+#define HANDLE_CDataSectionElement 11
+#define HANDLE_Replace 12
+#define HANDLE_Separator 13
+#define HANDLE_IncludeNamespacePrefixes 14
+#define HANDLE_Model 15
+
+void Submission::initializePropertySet()
+{
+ registerProperty( css::beans::Property("ID", HANDLE_ID, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setID, &Submission::getID) );
+
+ registerProperty( css::beans::Property("Bind", HANDLE_Bind, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setBind, &Submission::getBind) );
+
+ registerProperty( css::beans::Property("Ref", HANDLE_Ref, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setRef, &Submission::getRef) );
+
+ registerProperty( css::beans::Property("Action", HANDLE_Action, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setAction, &Submission::getAction) );
+
+ registerProperty( css::beans::Property("Method", HANDLE_Method, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setMethod, &Submission::getMethod) );
+
+ registerProperty( css::beans::Property("Version", HANDLE_Version, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setVersion, &Submission::getVersion) );
+
+ registerProperty( css::beans::Property("Indent", HANDLE_Indent, cppu::UnoType<bool>::get(), css::beans::PropertyAttribute::BOUND ),
+ new BooleanPropertyAccessor< Submission >(this, &Submission::setIndent, &Submission::getIndent));
+
+ registerProperty( css::beans::Property("MediaType", HANDLE_MediaType, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setMediaType, &Submission::getMediaType) );
+
+ registerProperty( css::beans::Property("Encoding", HANDLE_Encoding, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setEncoding, &Submission::getEncoding) );
+
+ registerProperty( css::beans::Property("OmitXmlDeclaration", HANDLE_OmitXmlDeclaration, cppu::UnoType<bool>::get(), css::beans::PropertyAttribute::BOUND ),
+ new BooleanPropertyAccessor< Submission >(this, &Submission::setOmitXmlDeclaration, &Submission::getOmitXmlDeclaration));
+
+ registerProperty( css::beans::Property("Standalone", HANDLE_Standalone, cppu::UnoType<bool>::get(), css::beans::PropertyAttribute::BOUND ),
+ new BooleanPropertyAccessor< Submission >(this, &Submission::setStandalone, &Submission::getStandalone));
+
+ registerProperty( css::beans::Property("CDataSectionElement", HANDLE_CDataSectionElement, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setCDataSectionElement, &Submission::getCDataSectionElement) );
+
+ registerProperty( css::beans::Property("Replace", HANDLE_Replace, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setReplace, &Submission::getReplace) );
+
+ registerProperty( css::beans::Property("Separator", HANDLE_Separator, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, OUString >(this, &Submission::setSeparator, &Submission::getSeparator) );
+
+ registerProperty( css::beans::Property("IncludeNamespacePrefixes", HANDLE_IncludeNamespacePrefixes, cppu::UnoType<Sequence<OUString>>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, Sequence<OUString> >(this, &Submission::setIncludeNamespacePrefixes, &Submission::getIncludeNamespacePrefixes) );
+
+ registerProperty( css::beans::Property("Model", HANDLE_Model, cppu::UnoType<Reference<XModel>>::get(), css::beans::PropertyAttribute::BOUND ),
+ new DirectPropertyAccessor< Submission, Reference<XModel> >(this, &Submission::setModel, &Submission::getModel) );
+
+ initializePropertyValueCache( HANDLE_Indent );
+ initializePropertyValueCache( HANDLE_OmitXmlDeclaration );
+ initializePropertyValueCache( HANDLE_Standalone );
+}
+
+sal_Bool SAL_CALL Submission::convertFastPropertyValue(
+ Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue )
+{
+ if ( nHandle == HANDLE_IncludeNamespacePrefixes )
+ {
+ // for convenience reasons (????), we accept a string which contains
+ // a comma-separated list of namespace prefixes
+ OUString sTokenList;
+ if ( rValue >>= sTokenList )
+ {
+ std::vector< OUString > aPrefixes;
+ sal_Int32 p = 0;
+ while ( p >= 0 )
+ aPrefixes.push_back( sTokenList.getToken( 0, ',', p ) );
+
+ Sequence< OUString > aConvertedPrefixes( aPrefixes.data(), aPrefixes.size() );
+ return PropertySetBase::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, Any( aConvertedPrefixes ) );
+ }
+ }
+
+ return PropertySetBase::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
+}
+
+OUString SAL_CALL Submission::getName()
+{
+ return getID();
+}
+
+void SAL_CALL Submission::setName( const OUString& sID )
+{
+ setID( sID );
+}
+
+
+sal_Int64 SAL_CALL Submission::getSomething(
+ const Sequence<sal_Int8>& aId )
+{
+ return comphelper::getSomethingImpl(aId, this);
+}
+
+
+static OUString lcl_message( std::u16string_view rID, std::u16string_view rText )
+{
+ OUString aMessage = OUString::Concat("XForms submission '") + rID + "' failed" + rText + ".";
+ return aMessage;
+}
+
+void SAL_CALL Submission::submitWithInteraction(
+ const Reference<XInteractionHandler>& _rxHandler )
+{
+ // as long as this class is not really threadsafe, we need to copy
+ // the members we're interested in
+ Reference< XModel > xModel( mxModel );
+ OUString sID( msID );
+
+ if ( !xModel.is() || msID.isEmpty() )
+ throw RuntimeException(
+ "This is not a valid submission object.",
+ *this
+ );
+
+ Model* pModel = comphelper::getFromUnoTunnel<Model>( xModel );
+ OSL_ENSURE( pModel != nullptr, "illegal model?" );
+
+ // #i36765# #i47248# warning on submission of illegal data
+ // check for validity (and query user if invalid)
+ bool bValid = pModel->isValid();
+ if( ! bValid )
+ {
+ InvalidDataOnSubmitException aInvalidDataException(
+ lcl_message(sID, u" due to invalid data" ), *this );
+
+ if( _rxHandler.is() )
+ {
+ // laboriously create interaction request
+ rtl::Reference<comphelper::OInteractionRequest> pRequest
+ = new comphelper::OInteractionRequest(
+ Any( aInvalidDataException ) );
+
+ rtl::Reference<comphelper::OInteractionApprove> pContinue
+ = new comphelper::OInteractionApprove();
+ pRequest->addContinuation( pContinue );
+
+ rtl::Reference<comphelper::OInteractionDisapprove> pCancel
+ = new comphelper::OInteractionDisapprove();
+ pRequest->addContinuation( pCancel );
+
+ // ask the handler...
+ _rxHandler->handle( pRequest );
+ OSL_ENSURE( pContinue->wasSelected() || pCancel->wasSelected(),
+ "handler didn't select" );
+
+ // and continue, if user chose 'continue'
+ if( pContinue->wasSelected() )
+ bValid = true;
+ }
+
+ // abort if invalid (and user didn't tell us to continue)
+ if( ! bValid )
+ throw aInvalidDataException;
+ }
+
+ // attempt submission
+ bool bResult = false;
+ try
+ {
+ bResult = doSubmit( _rxHandler );
+ }
+ catch( const VetoException& )
+ {
+ OSL_FAIL( "Model::submit: Hmm. How can a single submission have a veto right?" );
+ // allowed to leave
+ throw;
+ }
+ catch( const Exception& )
+ {
+ css::uno::Any anyEx = cppu::getCaughtException();
+ // exception caught: re-throw as wrapped target exception
+ throw WrappedTargetException(
+ lcl_message( sID, u" due to exception being thrown" ),
+ *this, anyEx );
+ }
+
+ if( !bResult )
+ {
+ // other failure: throw wrapped target exception, too.
+ throw WrappedTargetException(
+ lcl_message( sID, std::u16string_view() ), *this, Any() );
+ }
+ mxModel->rebuild();
+}
+
+void SAL_CALL Submission::submit( )
+{
+ submitWithInteraction( nullptr );
+}
+
+void SAL_CALL Submission::addSubmissionVetoListener( const Reference< XSubmissionVetoListener >& /*listener*/ )
+{
+ // TODO
+ throw NoSupportException();
+}
+
+void SAL_CALL Submission::removeSubmissionVetoListener( const Reference< XSubmissionVetoListener >& /*listener*/ )
+{
+ // TODO
+ throw NoSupportException();
+}
+
+static bool isIgnorable(const Reference< XNode >& aNode)
+{
+ // ignore whitespace-only textnodes
+ if (aNode->getNodeType() == NodeType_TEXT_NODE)
+ {
+ OUString aTrimmedValue = aNode->getNodeValue().trim();
+ if (aTrimmedValue.isEmpty()) return true;
+ }
+
+ return false;
+}
+
+// recursively copy relevant nodes from A to B
+static void cloneNodes(Model& aModel, const Reference< XNode >& dstParent, const Reference< XNode >& source, bool bRemoveWSNodes)
+{
+ if (!source.is()) return;
+
+ Reference< XNode > cur = source;
+ Reference< XDocument > dstDoc = dstParent->getOwnerDocument();
+ Reference< XNode > imported;
+
+ if (!cur.is())
+ return;
+
+ // is this node relevant?
+ MIP mip = aModel.queryMIP(cur);
+ if(mip.isRelevant() && !(bRemoveWSNodes && isIgnorable(cur)))
+ {
+ imported = dstDoc->importNode(cur, false);
+ imported = dstParent->appendChild(imported);
+ // append source children to new imported parent
+ for( cur = cur->getFirstChild(); cur.is(); cur = cur->getNextSibling() )
+ cloneNodes(aModel, imported, cur, bRemoveWSNodes);
+ }
+}
+Reference< XDocument > Submission::getInstanceDocument(const Reference< XXPathObject >& aObj)
+{
+ using namespace css::xml::xpath;
+ // result
+ Reference< XDocument > aDocument;
+
+ if (aObj->getObjectType() == XPathObjectType_XPATH_NODESET)
+ {
+ Reference< XNodeList > aList = aObj->getNodeList();
+ if (aList->getLength() > 0)
+ aDocument = aList->item(0)->getOwnerDocument();
+ }
+ return aDocument;
+}
+
+Reference< XDocumentFragment > Submission::createSubmissionDocument(const Reference< XXPathObject >& aObj, bool bRemoveWSNodes)
+{
+ using namespace css::xml::xpath;
+ Reference< XDocumentBuilder > aDocBuilder = DocumentBuilder::create(comphelper::getProcessComponentContext());
+ Reference< XDocument > aDocument = aDocBuilder->newDocument();
+ Reference< XDocumentFragment > aFragment = aDocument->createDocumentFragment();
+
+
+ if (aObj->getObjectType() == XPathObjectType_XPATH_NODESET)
+ {
+ Reference< XNodeList > aList = aObj->getNodeList();
+ Reference< XNode > aListItem;
+ for (sal_Int32 i=0; i < aList->getLength(); i++)
+ {
+ aListItem = aList->item(i);
+ if (aListItem->getNodeType()==NodeType_DOCUMENT_NODE)
+ aListItem = (Reference< XDocument >(aListItem, UNO_QUERY))->getDocumentElement();
+ // copy relevant nodes from instance into fragment
+ cloneNodes(*getModelImpl(), aFragment, aListItem, bRemoveWSNodes);
+ }
+ }
+ return aFragment;
+}
+
+// some forwarding: XPropertySet is implemented in our base class,
+// but also available as base of XSubmission
+Reference< css::beans::XPropertySetInfo > SAL_CALL Submission::getPropertySetInfo( )
+{
+ return PropertySetBase::getPropertySetInfo();
+}
+void SAL_CALL Submission::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
+{
+ PropertySetBase::setPropertyValue( aPropertyName, aValue );
+}
+Any SAL_CALL Submission::getPropertyValue( const OUString& PropertyName )
+{
+ return PropertySetBase::getPropertyValue( PropertyName );
+}
+void SAL_CALL Submission::addPropertyChangeListener( const OUString& aPropertyName, const Reference< css::beans::XPropertyChangeListener >& xListener )
+{
+ PropertySetBase::addPropertyChangeListener( aPropertyName, xListener );
+}
+void SAL_CALL Submission::removePropertyChangeListener( const OUString& aPropertyName, const Reference< css::beans::XPropertyChangeListener >& aListener )
+{
+ PropertySetBase::removePropertyChangeListener( aPropertyName, aListener );
+}
+void SAL_CALL Submission::addVetoableChangeListener( const OUString& PropertyName, const Reference< css::beans::XVetoableChangeListener >& aListener )
+{
+ PropertySetBase::addVetoableChangeListener( PropertyName, aListener );
+}
+void SAL_CALL Submission::removeVetoableChangeListener( const OUString& PropertyName, const Reference< css::beans::XVetoableChangeListener >& aListener )
+{
+ PropertySetBase::removeVetoableChangeListener( PropertyName, aListener );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission.hxx b/forms/source/xforms/submission.hxx
new file mode 100644
index 000000000..1e7f17e4c
--- /dev/null
+++ b/forms/source/xforms/submission.hxx
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <cppuhelper/implbase.hxx>
+#include "propertysetbase.hxx"
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/xml/dom/XDocument.hpp>
+#include <com/sun/star/xml/dom/XDocumentFragment.hpp>
+#include <com/sun/star/xml/xpath/XXPathObject.hpp>
+#include <com/sun/star/xforms/XSubmission.hpp>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include "computedexpression.hxx"
+
+// forward declaractions
+namespace com::sun::star {
+ namespace xforms { class XModel; }
+ namespace uno { class Any; }
+ namespace beans { class UnknownPropertyException;
+ class PropertyVetoException; }
+ namespace lang { class IllegalArgumentException;
+ class WrappedTargetException; }
+}
+namespace xforms { class Model; }
+
+
+namespace xforms
+{
+
+/** An XForms submission.
+ *
+ * See http://www.w3.org/TR/xforms/ for more information.
+ */
+typedef cppu::ImplInheritanceHelper<
+ PropertySetBase,
+ css::lang::XUnoTunnel,
+ css::xforms::XSubmission
+> Submission_t;
+
+class Submission : public Submission_t
+{
+ // submission properties
+ OUString msID;
+ OUString msBind;
+ ComputedExpression maRef;
+ OUString msAction;
+ OUString msMethod;
+ OUString msVersion;
+ bool mbIndent;
+ OUString msMediaType;
+ OUString msEncoding;
+ bool mbOmitXmlDeclaration;
+ bool mbStandalone;
+ OUString msCDataSectionElement;
+ OUString msReplace;
+ OUString msSeparator;
+ css::uno::Sequence< OUString > msIncludeNamespacePrefixes;
+
+private:
+
+ /// the Model to which this Submission belongs; may be NULL
+ css::uno::Reference<css::xforms::XModel> mxModel;
+
+ // this will extract the document from the model that will be submitted
+ css::uno::Reference< css::xml::dom::XDocumentFragment >
+ createSubmissionDocument(const css::uno::Reference< css::xml::xpath::XXPathObject >& aObject,
+ bool bRemoveWSNodes);
+ static css::uno::Reference< css::xml::dom::XDocument >
+ getInstanceDocument(const css::uno::Reference< css::xml::xpath::XXPathObject >& aObject);
+
+public:
+ Submission();
+ virtual ~Submission() noexcept override;
+
+
+ // property methods: get/set value
+
+
+ /// get XForms model
+ css::uno::Reference<css::xforms::XModel>
+ getModel() const { return mxModel;}
+
+ /// set XForms model
+ void setModel(
+ const css::uno::Reference<css::xforms::XModel>& );
+
+ OUString getID() const { return msID;} /// get ID for this submission
+ void setID( const OUString& ); /// set ID for this submission
+
+ OUString getBind() const { return msBind;}
+ void setBind( const OUString& );
+
+ OUString getRef() const;
+ void setRef( const OUString& );
+
+ OUString getAction() const { return msAction;}
+ void setAction( const OUString& );
+
+ OUString getMethod() const { return msMethod;}
+ void setMethod( const OUString& );
+
+ OUString getVersion() const { return msVersion;}
+ void setVersion( const OUString& );
+
+ bool getIndent() const { return mbIndent;}
+ void setIndent( bool );
+
+ OUString getMediaType() const { return msMediaType;}
+ void setMediaType( const OUString& );
+
+ OUString getEncoding() const { return msEncoding;}
+ void setEncoding( const OUString& );
+
+ bool getOmitXmlDeclaration() const { return mbOmitXmlDeclaration;}
+ void setOmitXmlDeclaration( bool );
+
+ bool getStandalone() const { return mbStandalone;}
+ void setStandalone( bool );
+
+ OUString getCDataSectionElement() const { return msCDataSectionElement;}
+ void setCDataSectionElement( const OUString& );
+
+ OUString getReplace() const { return msReplace;}
+ void setReplace( const OUString& );
+
+ OUString getSeparator() const { return msSeparator;}
+ void setSeparator( const OUString& );
+
+ css::uno::Sequence< OUString > getIncludeNamespacePrefixes() const { return msIncludeNamespacePrefixes;}
+ void setIncludeNamespacePrefixes( const css::uno::Sequence< OUString >& );
+
+ /** perform the submission
+ * @returns if submission was successful */
+ bool doSubmit( const css::uno::Reference< css::task::XInteractionHandler >& aHandler );
+
+ // helpers for UNO tunnel
+ static css::uno::Sequence<sal_Int8> getUnoTunnelId();
+
+private:
+
+ /// check whether object is live, and throw suitable exception if not
+ /// (to be used be API methods before acting on the object)
+ ///
+ /// @throws css::uno::RuntimeException
+ void liveCheck();
+
+ /// get the model implementation
+ xforms::Model* getModelImpl() const;
+
+protected:
+
+
+ // XPropertySet & friends:
+ // implement abstract methods from PropertySetHelper
+
+
+ virtual sal_Bool SAL_CALL convertFastPropertyValue(
+ css::uno::Any& rConvertedValue,
+ css::uno::Any& rOldValue,
+ sal_Int32 nHandle,
+ const css::uno::Any& rValue ) override;
+
+private:
+ void initializePropertySet();
+
+
+public:
+
+
+ // XNamed:
+ // get/set name
+
+
+ virtual OUString SAL_CALL getName() override;
+
+ virtual void SAL_CALL setName( const OUString& ) override;
+
+
+ // XUnoTunnel
+
+
+ virtual sal_Int64 SAL_CALL getSomething(
+ const css::uno::Sequence<sal_Int8>& ) override;
+
+
+ // XSubmission
+
+
+ virtual void SAL_CALL submit( ) override;
+ virtual void SAL_CALL submitWithInteraction(
+ const css::uno::Reference< css::task::XInteractionHandler >& aHandler ) override;
+ virtual void SAL_CALL addSubmissionVetoListener(
+ const css::uno::Reference< css::form::submission::XSubmissionVetoListener >& listener ) override;
+ virtual void SAL_CALL removeSubmissionVetoListener(
+ const css::uno::Reference< css::form::submission::XSubmissionVetoListener >& listener ) override;
+
+
+ // XPropertySet
+ // (need to disambiguate this)
+
+ virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override;
+ virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
+ virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
+ virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override;
+ virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override;
+ virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
+ virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override;
+};
+
+
+} // namespace xforms
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/replace.cxx b/forms/source/xforms/submission/replace.cxx
new file mode 100644
index 000000000..e6154ef61
--- /dev/null
+++ b/forms/source/xforms/submission/replace.cxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include "submission.hxx"
+#include "serialization_app_xml.hxx"
+
+#include <rtl/ustring.hxx>
+#include <rtl/ref.hxx>
+#include <tools/diagnose_ex.h>
+#include <o3tl/string_view.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/xml/dom/XDocument.hpp>
+#include <com/sun/star/xml/dom/DocumentBuilder.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::ucb;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::task;
+using namespace com::sun::star::xml::dom;
+
+CSubmission::SubmissionResult CSubmission::replace(std::u16string_view aReplace, const Reference<XDocument>& aDocument, const Reference<XFrame>& aFrame)
+{
+ if (!m_aResultStream.is())
+ return CSubmission::UNKNOWN_ERROR;
+
+ try {
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ if (o3tl::equalsIgnoreAsciiCase(aReplace, u"all")
+ || o3tl::equalsIgnoreAsciiCase(aReplace, u"document")) {
+ Reference< XComponentLoader > xLoader;
+ if (aFrame.is())
+ xLoader.set(aFrame, UNO_QUERY);
+
+ if (!xLoader.is())
+ xLoader.set( Desktop::create(xContext), UNO_QUERY_THROW);
+
+ // open the stream from the result...
+ // build media descriptor
+ Sequence< PropertyValue > descriptor{
+ PropertyValue("InputStream",
+ -1, Any(m_aResultStream), PropertyState_DIRECT_VALUE),
+ PropertyValue("ReadOnly",
+ -1, Any(true), PropertyState_DIRECT_VALUE)
+ };
+
+ OUString aURL = m_aURLObj.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+ xLoader->loadComponentFromURL(aURL, "_default", FrameSearchFlag::ALL, descriptor);
+
+ return CSubmission::SUCCESS;
+
+ } else if (o3tl::equalsIgnoreAsciiCase(aReplace, u"instance")) {
+ if (aDocument.is()) {
+ // parse the result stream into a new document
+ Reference< XDocumentBuilder > xBuilder(DocumentBuilder::create(xContext));
+ Reference< XDocument > aNewDocument = xBuilder->parse(m_aResultStream);
+
+ if (aNewDocument.is()) {
+ // and replace the content of the current instance
+ Reference< XElement > oldRoot = aDocument->getDocumentElement();
+ Reference< XElement > newRoot = aNewDocument->getDocumentElement();
+
+ Reference< XNode > aImportedNode = aDocument->importNode(newRoot, true);
+ aDocument->replaceChild(aImportedNode, oldRoot);
+ return CSubmission::SUCCESS;
+ } else {
+ return CSubmission::UNKNOWN_ERROR;
+ }
+ } else {
+ // nothing to replace
+ return CSubmission::UNKNOWN_ERROR;
+ }
+ } else if (o3tl::equalsIgnoreAsciiCase(aReplace, u"none")) {
+ // do nothing \o/
+ return CSubmission::SUCCESS;
+ }
+ } catch (const Exception&) {
+ TOOLS_WARN_EXCEPTION( "forms.xforms", "Exception during replace");
+ }
+ return CSubmission::UNKNOWN_ERROR;
+}
+
+::std::unique_ptr< CSerialization > CSubmission::createSerialization(const Reference< XInteractionHandler >& _xHandler,Reference<XCommandEnvironment>& _rOutEnv)
+{
+ // PUT always uses application/xml
+ ::std::unique_ptr< CSerialization > apSerialization(new CSerializationAppXML());
+ apSerialization->setSource(m_aFragment);
+ apSerialization->serialize();
+
+ // create a commandEnvironment and use the default interaction handler
+ rtl::Reference<CCommandEnvironmentHelper> pHelper = new CCommandEnvironmentHelper;
+ if( _xHandler.is() )
+ pHelper->m_aInteractionHandler = _xHandler;
+ else
+ pHelper->m_aInteractionHandler.set(
+ InteractionHandler::createWithParent(m_xContext, nullptr), UNO_QUERY_THROW);
+
+ rtl::Reference<CProgressHandlerHelper> pProgressHelper = new CProgressHandlerHelper;
+ pHelper->m_aProgressHandler.set(pProgressHelper);
+
+ // UCB has ownership of environment...
+ _rOutEnv = pHelper;
+ return apSerialization;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/serialization.hxx b/forms/source/xforms/submission/serialization.hxx
new file mode 100644
index 000000000..19f072b0b
--- /dev/null
+++ b/forms/source/xforms/submission/serialization.hxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/xml/dom/XDocumentFragment.hpp>
+
+/**
+Serialize an XObject
+*/
+
+class CSerialization
+{
+protected:
+ css::uno::Reference<css::xml::dom::XDocumentFragment> m_aFragment;
+
+public:
+ virtual ~CSerialization() {}
+
+ /**
+ sets the XObject that is to serialized
+ */
+ void setSource(const css::uno::Reference<css::xml::dom::XDocumentFragment>& aFragment)
+ {
+ m_aFragment = aFragment;
+ }
+
+ /**
+ start the serialization process
+ */
+ virtual void serialize() = 0;
+
+ /**
+ get the serialized bytes.
+ reads up to buffer->getLength() bytes and returns the number of
+ bytes read.
+ returns -1 on error
+ */
+ virtual css::uno::Reference<css::io::XInputStream> getInputStream() = 0;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/serialization_app_xml.cxx b/forms/source/xforms/submission/serialization_app_xml.cxx
new file mode 100644
index 000000000..61729d027
--- /dev/null
+++ b/forms/source/xforms/submission/serialization_app_xml.cxx
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include "serialization_app_xml.hxx"
+
+#include <com/sun/star/io/Pipe.hpp>
+#include <com/sun/star/xml/dom/DocumentBuilder.hpp>
+#include <com/sun/star/xml/dom/XNode.hpp>
+#include <com/sun/star/xml/dom/XDocument.hpp>
+#include <com/sun/star/xml/dom/NodeType.hpp>
+#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
+#include <com/sun/star/xml/sax/Writer.hpp>
+#include <com/sun/star/beans/StringPair.hpp>
+#include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
+
+#include <tools/diagnose_ex.h>
+#include <comphelper/processfactory.hxx>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::uno::UNO_SET_THROW;
+using ::com::sun::star::xml::dom::DocumentBuilder;
+using ::com::sun::star::xml::dom::XNode;
+using ::com::sun::star::xml::dom::XDocument;
+using ::com::sun::star::xml::sax::XSAXSerializable;
+using ::com::sun::star::beans::StringPair;
+using ::com::sun::star::xml::dom::NodeType_DOCUMENT_NODE;
+using ::com::sun::star::xml::dom::NodeType_ELEMENT_NODE;
+using ::com::sun::star::xml::dom::XDocumentBuilder;
+using ::com::sun::star::xml::sax::Writer;
+using ::com::sun::star::xml::sax::XDocumentHandler;
+
+CSerializationAppXML::CSerializationAppXML()
+ : m_xBuffer(css::io::Pipe::create(comphelper::getProcessComponentContext()))
+{
+}
+
+Reference< css::io::XInputStream >
+CSerializationAppXML::getInputStream()
+{
+ // The pipes output is provided through it's
+ // XOutputStream interface aspect
+ return m_xBuffer;
+}
+
+void
+CSerializationAppXML::serialize_node(const Reference< XNode >& rNode)
+{
+ try
+ {
+ Reference< XSAXSerializable > xSerializer( rNode, UNO_QUERY );
+ if ( !xSerializer.is() )
+ {
+ // ensure we have a "real" node
+ Reference< XNode > xNode = rNode;
+ if ( xNode->getNodeType() == NodeType_DOCUMENT_NODE )
+ {
+ Reference< XDocument > const xDoc( xNode, UNO_QUERY_THROW );
+ xNode.set( xDoc->getDocumentElement(), UNO_QUERY_THROW );
+ }
+ ENSURE_OR_RETURN_VOID( xNode->getNodeType() == NodeType_ELEMENT_NODE,
+ "CSerializationAppXML::serialize_node: invalid node type!" );
+
+ // create a new document
+ Reference< XDocumentBuilder > const xDocBuilder = DocumentBuilder::create( comphelper::getProcessComponentContext() );
+ Reference< XDocument > const xDocument( xDocBuilder->newDocument(), UNO_SET_THROW );
+
+ // copy the to-be-serialized node
+ Reference< XNode > const xImportedNode( xDocument->importNode( xNode, true ), UNO_SET_THROW );
+ xDocument->appendChild( xImportedNode );
+
+ // ask the doc for the serializer
+ xSerializer.set( xDocument, UNO_QUERY );
+ }
+
+ ENSURE_OR_RETURN_VOID( xSerializer.is(),
+ "CSerializationAppXML::serialize_node: no serialization access to the node/document!" );
+
+ // create a SAXWriter to take the serialization events, and connect it to our pipe
+ Reference< css::xml::sax::XWriter > const xSaxWriter = Writer::create( comphelper::getProcessComponentContext() );
+ xSaxWriter->setOutputStream( Reference< css::io::XOutputStream >( m_xBuffer, UNO_QUERY_THROW) );
+
+ // do the serialization
+ xSerializer->serialize( Reference< XDocumentHandler >(xSaxWriter, UNO_QUERY_THROW), Sequence< StringPair >() );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("forms.xforms");
+ }
+}
+
+void
+CSerializationAppXML::serialize()
+{
+ if (!m_aFragment.is()) return;
+
+ Reference< XNode > cur = m_aFragment->getFirstChild();
+ while (cur.is())
+ {
+ serialize_node(cur);
+ cur = cur->getNextSibling();
+ }
+ m_xBuffer->closeOutput();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/serialization_app_xml.hxx b/forms/source/xforms/submission/serialization_app_xml.hxx
new file mode 100644
index 000000000..51fb1eb54
--- /dev/null
+++ b/forms/source/xforms/submission/serialization_app_xml.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/io/XPipe.hpp>
+
+#include "serialization.hxx"
+
+class CSerializationAppXML : public CSerialization
+{
+private:
+ css::uno::Reference<css::io::XPipe> m_xBuffer;
+
+ void serialize_node(const css::uno::Reference<css::xml::dom::XNode>& aNode);
+
+public:
+ CSerializationAppXML();
+
+ virtual void serialize() override;
+ virtual css::uno::Reference<css::io::XInputStream> getInputStream() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/serialization_urlencoded.cxx b/forms/source/xforms/submission/serialization_urlencoded.cxx
new file mode 100644
index 000000000..22a625ccb
--- /dev/null
+++ b/forms/source/xforms/submission/serialization_urlencoded.cxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <com/sun/star/io/Pipe.hpp>
+#include <com/sun/star/xml/xpath/XPathObjectType.hpp>
+#include <com/sun/star/xml/dom/XNode.hpp>
+#include <com/sun/star/xml/dom/XText.hpp>
+#include <com/sun/star/xml/dom/XNodeList.hpp>
+#include <com/sun/star/xml/dom/NodeType.hpp>
+#include <rtl/character.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <stdio.h>
+
+#include "serialization_urlencoded.hxx"
+
+using namespace css::uno;
+using namespace css::io;
+using namespace css::xml::xpath;
+using namespace css::xml::dom;
+
+CSerializationURLEncoded::CSerializationURLEncoded()
+ : m_aPipe(Pipe::create(comphelper::getProcessComponentContext()))
+{
+}
+
+
+/*
+ rfc2396
+ reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+ "$" | ","
+ mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
+ unreserved = alphanum | mark
+*/
+bool CSerializationURLEncoded::is_unreserved(char c)
+{
+ if (rtl::isAsciiAlphanumeric(static_cast<unsigned char>(c)))
+ return true;
+ switch (c) {
+ case '-':
+ case '_':
+ case '.':
+ case '!':
+ case '~':
+ case '*':
+ case '\'':
+ case '(':
+ case ')':
+ return true;
+ }
+ return false;
+}
+void CSerializationURLEncoded::encode_and_append(
+ std::u16string_view aString, OStringBuffer& aBuffer)
+{
+ OString utf8String = OUStringToOString(aString, RTL_TEXTENCODING_UTF8);
+ const sal_uInt8 *pString = reinterpret_cast< const sal_uInt8 * >( utf8String.getStr() );
+ char tmpChar[4];
+
+ while( *pString != 0)
+ {
+ if( *pString < 0x80 )
+ {
+ if ( is_unreserved(*pString) ) {
+ aBuffer.append(char(*pString));
+ } else if (*pString == 0x20) {
+ aBuffer.append('+');
+ } else if (*pString == 0x0d && *(pString+1) == 0x0a) {
+ aBuffer.append("%0D%0A");
+ pString++;
+ } else if (*pString == 0x0a) {
+ aBuffer.append("%0D%0A");
+ } else {
+ snprintf(tmpChar, 4, "%%%X", *pString % 0x100);
+ aBuffer.append(tmpChar);
+ }
+ } else {
+ snprintf(tmpChar, 4, "%%%X", *pString % 0x100);
+ aBuffer.append(tmpChar);
+ while (*pString >= 0x80) {
+ // continuation...
+ pString++;
+ snprintf(tmpChar, 4, "%%%X", *pString % 0x100);
+ aBuffer.append(tmpChar);
+ }
+ }
+ pString++;
+ }
+}
+
+void CSerializationURLEncoded::serialize_node(const Reference< XNode >& aNode)
+{
+ // serialize recursive
+ // every element node E that has a text child T will be serialized in document order
+ // <E1>T1<E2>T2</E2></E1><E3>T3</E3> -> E1=T2&E2=T2&E3=T3 (En := local name)
+
+ // this node
+ Reference< XNodeList > aChildList = aNode->getChildNodes();
+ Reference< XNode > aChild;
+ // is this an element node?
+ if (aNode->getNodeType() == NodeType_ELEMENT_NODE)
+ {
+ OUString aName = aNode->getNodeName();
+ // find any text children
+ OUStringBuffer aValue;
+ Reference< XText > aText;
+ for(sal_Int32 i=0; i < aChildList->getLength(); i++)
+ {
+ aChild = aChildList->item(i);
+ if (aChild->getNodeType() == NodeType_TEXT_NODE)
+ {
+ aText.set(aChild, UNO_QUERY);
+ aValue.append(aText->getData());
+ }
+ }
+
+ // found anything?
+ if (!aValue.isEmpty())
+ {
+ OUString aUnencValue = aValue.makeStringAndClear();
+ OStringBuffer aEncodedBuffer;
+ encode_and_append(aName, aEncodedBuffer);
+ aEncodedBuffer.append("=");
+ encode_and_append(aUnencValue, aEncodedBuffer);
+ aEncodedBuffer.append("&");
+ sal_Int8 const *pData = reinterpret_cast<sal_Int8 const *>(aEncodedBuffer.getStr());
+ Sequence< sal_Int8 > sData(pData, aEncodedBuffer.getLength());
+ m_aPipe->writeBytes(sData);
+ }
+ }
+
+ // element children...
+ for(sal_Int32 i=0; i < aChildList->getLength(); i++)
+ {
+ aChild = aChildList->item(i);
+ // if this is an element node, it might be a candidate for serialization
+ if (aChild.is() && aChild->getNodeType() == NodeType_ELEMENT_NODE)
+ serialize_node(aChild);
+ }
+}
+
+void CSerializationURLEncoded::serialize()
+{
+
+ // output stream to the pipe buffer
+
+ css::uno::Reference< css::xml::dom::XNode > cur = m_aFragment->getFirstChild();
+ while (cur.is())
+ {
+ serialize_node(cur);
+ cur = cur->getNextSibling();
+ }
+ m_aPipe->closeOutput();
+}
+
+Reference< XInputStream > CSerializationURLEncoded::getInputStream()
+{
+ return m_aPipe;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/serialization_urlencoded.hxx b/forms/source/xforms/submission/serialization_urlencoded.hxx
new file mode 100644
index 000000000..2ae91c1f1
--- /dev/null
+++ b/forms/source/xforms/submission/serialization_urlencoded.hxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <com/sun/star/io/XPipe.hpp>
+
+#include <rtl/strbuf.hxx>
+
+#include "serialization.hxx"
+
+class CSerializationURLEncoded : public CSerialization
+{
+private:
+ css::uno::Reference<css::io::XPipe> m_aPipe;
+
+ static bool is_unreserved(char);
+ static void encode_and_append(std::u16string_view aString, OStringBuffer& aBuffer);
+ void serialize_node(const css::uno::Reference<css::xml::dom::XNode>& aNode);
+
+public:
+ CSerializationURLEncoded();
+ virtual void serialize() override;
+ virtual css::uno::Reference<css::io::XInputStream> getInputStream() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/submission.hxx b/forms/source/xforms/submission/submission.hxx
new file mode 100644
index 000000000..ac80947aa
--- /dev/null
+++ b/forms/source/xforms/submission/submission.hxx
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <tools/urlobj.hxx>
+#include <osl/conditn.hxx>
+#include <osl/mutex.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/xml/dom/XDocumentFragment.hpp>
+
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+
+#include <com/sun/star/task/XInteractionHandler.hpp>
+
+#include <com/sun/star/frame/XFrame.hpp>
+
+#include <cppuhelper/implbase.hxx>
+
+#include "serialization.hxx"
+
+#include <memory>
+
+class CSubmissionPut;
+class CSubmissionPost;
+class CSubmissionGet;
+
+class CCommandEnvironmentHelper final : public cppu::WeakImplHelper< css::ucb::XCommandEnvironment >
+{
+ friend class CSubmissionPut;
+ friend class CSubmissionPost;
+ friend class CSubmissionGet;
+ friend class CSubmission;
+
+ css::uno::Reference< css::task::XInteractionHandler > m_aInteractionHandler;
+ css::uno::Reference< css::ucb::XProgressHandler > m_aProgressHandler;
+
+public:
+ virtual css::uno::Reference< css::task::XInteractionHandler > SAL_CALL getInteractionHandler() override
+ {
+ return m_aInteractionHandler;
+ }
+ virtual css::uno::Reference< css::ucb::XProgressHandler > SAL_CALL getProgressHandler() override
+ {
+ return m_aProgressHandler;
+ }
+};
+
+class CProgressHandlerHelper final : public cppu::WeakImplHelper< css::ucb::XProgressHandler >
+{
+ friend class CSubmissionPut;
+ friend class CSubmissionPost;
+ friend class CSubmissionGet;
+ osl::Condition m_cFinished;
+ osl::Mutex m_mLock;
+ sal_Int32 m_count;
+public:
+ CProgressHandlerHelper()
+ : m_count(0)
+ {}
+ virtual void SAL_CALL push( const css::uno::Any& /*aStatus*/) override
+ {
+ m_mLock.acquire();
+ m_count++;
+ m_mLock.release();
+ }
+ virtual void SAL_CALL update(const css::uno::Any& /*aStatus*/) override
+ {
+ }
+ virtual void SAL_CALL pop() override
+ {
+ m_mLock.acquire();
+ m_count--;
+ if (m_count == 0)
+ m_cFinished.set();
+ m_mLock.release();
+ }
+};
+
+class CSubmission
+{
+
+protected:
+ INetURLObject m_aURLObj;
+ css::uno::Reference< css::xml::dom::XDocumentFragment > m_aFragment;
+ css::uno::Reference< css::io::XInputStream > m_aResultStream;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+
+ ::std::unique_ptr< CSerialization > createSerialization(const css::uno::Reference< css::task::XInteractionHandler >& aHandler
+ ,css::uno::Reference<css::ucb::XCommandEnvironment>& _rOutEnv);
+
+public:
+ enum SubmissionResult {
+ SUCCESS,
+ UNKNOWN_ERROR
+ };
+
+ CSubmission(std::u16string_view aURL, const css::uno::Reference< css::xml::dom::XDocumentFragment >& aFragment)
+ : m_aURLObj(aURL)
+ , m_aFragment(aFragment)
+ , m_xContext(::comphelper::getProcessComponentContext())
+ {}
+
+ bool IsWebProtocol() const
+ {
+ INetProtocol eProtocol = m_aURLObj.GetProtocol();
+ return eProtocol == INetProtocol::Http || eProtocol == INetProtocol::Https;
+ }
+
+ virtual ~CSubmission() {}
+
+ virtual SubmissionResult submit(const css::uno::Reference< css::task::XInteractionHandler >& ) = 0;
+
+ SubmissionResult replace(std::u16string_view, const css::uno::Reference< css::xml::dom::XDocument >&, const css::uno::Reference< css::frame::XFrame>&);
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/submission_get.cxx b/forms/source/xforms/submission/submission_get.cxx
new file mode 100644
index 000000000..5a82aeae0
--- /dev/null
+++ b/forms/source/xforms/submission/submission_get.cxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include "submission_get.hxx"
+#include "serialization_urlencoded.hxx"
+
+#include <rtl/strbuf.hxx>
+#include <osl/diagnose.h>
+#include <ucbhelper/content.hxx>
+#include <com/sun/star/io/Pipe.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <tools/diagnose_ex.h>
+
+using namespace css::uno;
+using namespace css::ucb;
+using namespace css::task;
+using namespace css::io;
+using namespace osl;
+using namespace ucbhelper;
+
+
+CSubmissionGet::CSubmissionGet(std::u16string_view aURL, const css::uno::Reference< css::xml::dom::XDocumentFragment >& aFragment)
+ : CSubmission(aURL, aFragment)
+{
+}
+
+CSubmission::SubmissionResult CSubmissionGet::submit(const css::uno::Reference< css::task::XInteractionHandler >& aInteractionHandler)
+{
+ // GET always uses application/x-www-formurlencoded
+ CSerializationURLEncoded aSerialization;
+ aSerialization.setSource(m_aFragment);
+ aSerialization.serialize();
+
+ css::uno::Reference< XInputStream > aInStream = aSerialization.getInputStream();
+
+ // create a commandEnvironment and use the default interaction handler
+ rtl::Reference<CCommandEnvironmentHelper> pHelper = new CCommandEnvironmentHelper;
+ if( aInteractionHandler.is() )
+ pHelper->m_aInteractionHandler = aInteractionHandler;
+ else
+ pHelper->m_aInteractionHandler.set(
+ css::task::InteractionHandler::createWithParent(m_xContext, nullptr), UNO_QUERY_THROW);
+ rtl::Reference<CProgressHandlerHelper> pProgressHelper = new CProgressHandlerHelper;
+ pHelper->m_aProgressHandler.set(pProgressHelper);
+
+ // UCB has ownership of environment...
+ css::uno::Reference< XCommandEnvironment > aEnvironment(pHelper);
+
+ // append query string to the URL
+ try {
+ OStringBuffer aUTF8QueryURL(OUStringToOString(m_aURLObj.GetMainURL(INetURLObject::DecodeMechanism::NONE),
+ RTL_TEXTENCODING_UTF8));
+ OStringBuffer aQueryString;
+
+ const sal_Int32 size = 1024;
+ sal_Int32 n = 0;
+ Sequence< sal_Int8 > aByteBuffer(size);
+ while ((n = aInStream->readSomeBytes(aByteBuffer, size-1)) != 0)
+ aQueryString.append(reinterpret_cast<char const *>(aByteBuffer.getConstArray()), n);
+ if (!aQueryString.isEmpty() && m_aURLObj.GetProtocol() != INetProtocol::File)
+ {
+ aUTF8QueryURL.append('?');
+ aUTF8QueryURL.append(aQueryString);
+ }
+ OUString aQueryURL = OStringToOUString(aUTF8QueryURL.makeStringAndClear(), RTL_TEXTENCODING_UTF8);
+ ucbhelper::Content aContent(aQueryURL, aEnvironment, m_xContext);
+ css::uno::Reference< XOutputStream > aPipe( css::io::Pipe::create(m_xContext), UNO_QUERY_THROW );
+ if (!aContent.openStream(aPipe))
+ return UNKNOWN_ERROR;
+ // get reply
+ try {
+ m_aResultStream = aContent.openStream();
+ } catch (const Exception&) {
+ OSL_FAIL("Cannot open reply stream from content");
+ }
+ } catch (const Exception&)
+ {
+ // XXX
+ TOOLS_WARN_EXCEPTION( "forms.misc", "Exception during UCB operation.");
+ return UNKNOWN_ERROR;
+ }
+
+ return SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/submission_get.hxx b/forms/source/xforms/submission/submission_get.hxx
new file mode 100644
index 000000000..086fab25b
--- /dev/null
+++ b/forms/source/xforms/submission/submission_get.hxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "submission.hxx"
+
+class CSubmissionGet : public CSubmission
+{
+public:
+ CSubmissionGet(std::u16string_view aURL,
+ const css::uno::Reference<css::xml::dom::XDocumentFragment>& aFragment);
+ virtual SubmissionResult
+ submit(const css::uno::Reference<css::task::XInteractionHandler>& aInteractionHandler) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/submission_post.cxx b/forms/source/xforms/submission/submission_post.cxx
new file mode 100644
index 000000000..89ffd2323
--- /dev/null
+++ b/forms/source/xforms/submission/submission_post.cxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <memory>
+
+#include "submission_post.hxx"
+
+#include <osl/diagnose.h>
+#include <ucbhelper/content.hxx>
+#include <ucbhelper/activedatasink.hxx>
+#include <com/sun/star/ucb/PostCommandArgument2.hpp>
+#include <tools/diagnose_ex.h>
+
+using namespace css::uno;
+using namespace css::ucb;
+using namespace css::task;
+using namespace css::io;
+using namespace osl;
+using namespace ucbhelper;
+
+
+CSubmissionPost::CSubmissionPost(std::u16string_view aURL, const css::uno::Reference< css::xml::dom::XDocumentFragment >& aFragment)
+ : CSubmission(aURL, aFragment)
+{
+}
+
+CSubmission::SubmissionResult CSubmissionPost::submit(const css::uno::Reference< css::task::XInteractionHandler >& aInteractionHandler)
+{
+ // PUT always uses application/xml
+ css::uno::Reference< XCommandEnvironment > aEnvironment;
+ std::unique_ptr< CSerialization > apSerialization(createSerialization(aInteractionHandler,aEnvironment));
+
+ try {
+ ucbhelper::Content aContent(m_aURLObj.GetMainURL(INetURLObject::DecodeMechanism::NONE), aEnvironment, comphelper::getProcessComponentContext());
+
+ // use post command
+ PostCommandArgument2 aPostArgument;
+ aPostArgument.Source = apSerialization->getInputStream();
+ css::uno::Reference< XActiveDataSink > aSink(new ucbhelper::ActiveDataSink);
+ aPostArgument.Sink = aSink;
+ aPostArgument.MediaType = "application/xml";
+ aPostArgument.Referer.clear();
+ Any aCommandArgument;
+ aCommandArgument <<= aPostArgument;
+ aContent.executeCommand( "post", aCommandArgument);
+
+ try {
+ m_aResultStream = aSink->getInputStream();
+ } catch (const Exception&) {
+ OSL_FAIL("Cannot open reply stream from content");
+ }
+ } catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "forms.misc", "Exception during UCB operation.");
+ return UNKNOWN_ERROR;
+ }
+
+ return SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/submission_post.hxx b/forms/source/xforms/submission/submission_post.hxx
new file mode 100644
index 000000000..0fb63472b
--- /dev/null
+++ b/forms/source/xforms/submission/submission_post.hxx
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "submission.hxx"
+
+class CSubmissionPost : public CSubmission
+{
+public:
+ CSubmissionPost(std::u16string_view aURL, const css::uno::Reference< css::xml::dom::XDocumentFragment >& aFragment);
+ virtual SubmissionResult submit(const css::uno::Reference< css::task::XInteractionHandler >& aInteractionHandler) override;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/submission_put.cxx b/forms/source/xforms/submission/submission_put.cxx
new file mode 100644
index 000000000..678cd7921
--- /dev/null
+++ b/forms/source/xforms/submission/submission_put.cxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <memory>
+
+#include "submission_put.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <ucbhelper/content.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace css::uno;
+using namespace css::ucb;
+using namespace css::task;
+using namespace css::io;
+using namespace osl;
+using namespace ucbhelper;
+
+
+CSubmissionPut::CSubmissionPut(std::u16string_view aURL, const css::uno::Reference< css::xml::dom::XDocumentFragment >& aFragment)
+ : CSubmission(aURL, aFragment)
+{
+}
+
+CSubmission::SubmissionResult CSubmissionPut::submit(const css::uno::Reference< css::task::XInteractionHandler >& aInteractionHandler)
+{
+ css::uno::Reference< XCommandEnvironment > aEnvironment;
+ std::unique_ptr< CSerialization > apSerialization(createSerialization(aInteractionHandler,aEnvironment));
+
+ try {
+ ucbhelper::Content aContent(m_aURLObj.GetMainURL(INetURLObject::DecodeMechanism::NONE), aEnvironment, comphelper::getProcessComponentContext());
+
+ // insert serialized data to content -> PUT
+ css::uno::Reference< XInputStream > aInStream = apSerialization->getInputStream();
+ aContent.writeStream(aInStream, true);
+ //aContent.closeStream();
+
+ // no content as a result of put...
+ }
+ catch ( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "forms.misc", "Exception during UCB operation." );
+ return UNKNOWN_ERROR;
+ }
+
+
+ return SUCCESS;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/forms/source/xforms/submission/submission_put.hxx b/forms/source/xforms/submission/submission_put.hxx
new file mode 100644
index 000000000..2dce84307
--- /dev/null
+++ b/forms/source/xforms/submission/submission_put.hxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "submission.hxx"
+
+class CSubmissionPut : public CSubmission
+{
+public:
+ CSubmissionPut(std::u16string_view aURL,
+ const css::uno::Reference<css::xml::dom::XDocumentFragment>& aFragment);
+ virtual SubmissionResult
+ submit(const css::uno::Reference<css::task::XInteractionHandler>& aInteractionHandler) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */