1*24acc546SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*24acc546SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*24acc546SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*24acc546SAndrew Rist * distributed with this work for additional information 6*24acc546SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*24acc546SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*24acc546SAndrew Rist * "License"); you may not use this file except in compliance 9*24acc546SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*24acc546SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*24acc546SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*24acc546SAndrew Rist * software distributed under the License is distributed on an 15*24acc546SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*24acc546SAndrew Rist * KIND, either express or implied. See the License for the 17*24acc546SAndrew Rist * specific language governing permissions and limitations 18*24acc546SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*24acc546SAndrew Rist *************************************************************/ 21*24acc546SAndrew Rist 22*24acc546SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_forms.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "model.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include "model_helper.hxx" 30cdf0e10cSrcweir #include "unohelper.hxx" 31cdf0e10cSrcweir #include "binding.hxx" 32cdf0e10cSrcweir #include "submission.hxx" 33cdf0e10cSrcweir #include "mip.hxx" 34cdf0e10cSrcweir #include "evaluationcontext.hxx" 35cdf0e10cSrcweir #include "xmlhelper.hxx" 36cdf0e10cSrcweir #include "datatyperepository.hxx" 37cdf0e10cSrcweir #include "NameContainer.hxx" 38cdf0e10cSrcweir 39cdf0e10cSrcweir #include <rtl/ustring.hxx> 40cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 41cdf0e10cSrcweir #include <tools/debug.hxx> 42cdf0e10cSrcweir 43cdf0e10cSrcweir #include <comphelper/propertysetinfo.hxx> 44cdf0e10cSrcweir #include <cppuhelper/typeprovider.hxx> 45cdf0e10cSrcweir 46cdf0e10cSrcweir #include <algorithm> 47cdf0e10cSrcweir 48cdf0e10cSrcweir // UNO classes 49cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 50cdf0e10cSrcweir #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> 51cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp> 52cdf0e10cSrcweir #include <com/sun/star/xml/dom/XDocument.hpp> 53cdf0e10cSrcweir #include <com/sun/star/xml/dom/XCharacterData.hpp> 54cdf0e10cSrcweir #include <com/sun/star/xml/dom/NodeType.hpp> 55cdf0e10cSrcweir #include <com/sun/star/xml/dom/XDocumentBuilder.hpp> 56cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx> 57cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp> 58cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp> 59cdf0e10cSrcweir #include <com/sun/star/ucb/XSimpleFileAccess.hpp> 60cdf0e10cSrcweir #include <com/sun/star/io/XInputStream.hpp> 61cdf0e10cSrcweir 62cdf0e10cSrcweir 63cdf0e10cSrcweir using com::sun::star::lang::XMultiServiceFactory; 64cdf0e10cSrcweir using com::sun::star::lang::XUnoTunnel; 65cdf0e10cSrcweir using com::sun::star::beans::XPropertySet; 66cdf0e10cSrcweir using com::sun::star::beans::PropertyValue; 67cdf0e10cSrcweir using rtl::OUString; 68cdf0e10cSrcweir using rtl::OUStringBuffer; 69cdf0e10cSrcweir using com::sun::star::beans::PropertyVetoException; 70cdf0e10cSrcweir using com::sun::star::beans::UnknownPropertyException; 71cdf0e10cSrcweir using com::sun::star::util::VetoException; 72cdf0e10cSrcweir using com::sun::star::lang::WrappedTargetException; 73cdf0e10cSrcweir using com::sun::star::lang::IllegalArgumentException; 74cdf0e10cSrcweir using com::sun::star::ucb::XSimpleFileAccess; 75cdf0e10cSrcweir using com::sun::star::io::XInputStream; 76cdf0e10cSrcweir 77cdf0e10cSrcweir using namespace com::sun::star::uno; 78cdf0e10cSrcweir using namespace com::sun::star::xml::dom; 79cdf0e10cSrcweir using namespace xforms; 80cdf0e10cSrcweir 81cdf0e10cSrcweir 82cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 83cdf0e10cSrcweir #define DBG_INVARIANT_TYPE(TYPE) class DBG_##TYPE { const TYPE* mpT; void check() { mpT->dbg_assertInvariant(); } public: DBG_##TYPE(const TYPE* pT) : mpT(pT) { check(); } ~DBG_##TYPE() { check(); } } _DBG_##TYPE(this); 84cdf0e10cSrcweir 85cdf0e10cSrcweir #define DBG_INVARIANT() DBG_INVARIANT_TYPE(Model) 86cdf0e10cSrcweir #else 87cdf0e10cSrcweir #define DBG_INVARIANT_TYPE(TYPE) 88cdf0e10cSrcweir #define DBG_INVARIANT() 89cdf0e10cSrcweir #endif 90cdf0e10cSrcweir 91cdf0e10cSrcweir 92cdf0e10cSrcweir 93cdf0e10cSrcweir // 94cdf0e10cSrcweir // The Model 95cdf0e10cSrcweir // 96cdf0e10cSrcweir 97cdf0e10cSrcweir void Model::ensureAtLeastOneInstance() 98cdf0e10cSrcweir { 99cdf0e10cSrcweir if( ! mpInstances->hasItems() ) 100cdf0e10cSrcweir { 101cdf0e10cSrcweir // create a default instance 102cdf0e10cSrcweir newInstance( OUString(), OUString(), true ); 103cdf0e10cSrcweir } 104cdf0e10cSrcweir } 105cdf0e10cSrcweir 106cdf0e10cSrcweir 107cdf0e10cSrcweir 108cdf0e10cSrcweir /** Model default constructor; create empty model */ 109cdf0e10cSrcweir Model::Model() : 110cdf0e10cSrcweir msID(), 111cdf0e10cSrcweir mpBindings( NULL ), 112cdf0e10cSrcweir mpSubmissions( NULL ), 113cdf0e10cSrcweir mpInstances( new InstanceCollection ), 114cdf0e10cSrcweir mxNamespaces( new NameContainer<OUString>() ), 115cdf0e10cSrcweir mxBindings( mpBindings ), 116cdf0e10cSrcweir mxSubmissions( mpSubmissions ), 117cdf0e10cSrcweir mxInstances( mpInstances ), 118cdf0e10cSrcweir mbInitialized( false ), 119cdf0e10cSrcweir mbExternalData( true ) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir initializePropertySet(); 122cdf0e10cSrcweir 123cdf0e10cSrcweir // initialize bindings collections 124cdf0e10cSrcweir // (not in initializer list to avoid use of incomplete 'this') 125cdf0e10cSrcweir mpBindings = new BindingCollection( this ); 126cdf0e10cSrcweir mxBindings = mpBindings; 127cdf0e10cSrcweir 128cdf0e10cSrcweir mpSubmissions = new SubmissionCollection( this ); 129cdf0e10cSrcweir mxSubmissions = mpSubmissions; 130cdf0e10cSrcweir 131cdf0e10cSrcweir // invariant only holds after construction 132cdf0e10cSrcweir DBG_INVARIANT(); 133cdf0e10cSrcweir } 134cdf0e10cSrcweir 135cdf0e10cSrcweir Model::~Model() throw() 136cdf0e10cSrcweir { 137cdf0e10cSrcweir // give up bindings & submissions; the mxBindings/mxSubmissions 138cdf0e10cSrcweir // references will then delete them 139cdf0e10cSrcweir mpBindings = NULL; 140cdf0e10cSrcweir mpSubmissions = NULL; 141cdf0e10cSrcweir } 142cdf0e10cSrcweir 143cdf0e10cSrcweir Model* lcl_getModel( const Reference<XUnoTunnel>& xTunnel ) 144cdf0e10cSrcweir { 145cdf0e10cSrcweir Model* pModel = NULL; 146cdf0e10cSrcweir if( xTunnel.is() ) 147cdf0e10cSrcweir pModel = reinterpret_cast<Model*>( 148cdf0e10cSrcweir xTunnel->getSomething( Model::getUnoTunnelID() ) ); 149cdf0e10cSrcweir return pModel; 150cdf0e10cSrcweir } 151cdf0e10cSrcweir 152cdf0e10cSrcweir Model* Model::getModel( const Reference<XModel>& xModel ) 153cdf0e10cSrcweir { 154cdf0e10cSrcweir return lcl_getModel( Reference<XUnoTunnel>( xModel, UNO_QUERY ) ); 155cdf0e10cSrcweir } 156cdf0e10cSrcweir 157cdf0e10cSrcweir EvaluationContext Model::getEvaluationContext() 158cdf0e10cSrcweir { 159cdf0e10cSrcweir // the default context is the top-level element node. A default 160cdf0e10cSrcweir // node (instanceData' is inserted when there is no default node 161cdf0e10cSrcweir Reference<XDocument> xInstance = getDefaultInstance(); 162cdf0e10cSrcweir Reference<XNode> xElement( xInstance->getDocumentElement(), UNO_QUERY ); 163cdf0e10cSrcweir 164cdf0e10cSrcweir // no element found? Then insert default element 'instanceData' 165cdf0e10cSrcweir if( ! xElement.is() ) 166cdf0e10cSrcweir { 167cdf0e10cSrcweir xElement = Reference<XNode>( 168cdf0e10cSrcweir xInstance->createElement( OUSTRING("instanceData") ), 169cdf0e10cSrcweir UNO_QUERY_THROW ); 170cdf0e10cSrcweir Reference<XNode>( xInstance, UNO_QUERY_THROW)->appendChild( xElement ); 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir OSL_ENSURE( xElement.is() && 174cdf0e10cSrcweir xElement->getNodeType() == NodeType_ELEMENT_NODE, 175cdf0e10cSrcweir "no element in evaluation context" ); 176cdf0e10cSrcweir 177cdf0e10cSrcweir return EvaluationContext( xElement, this, mxNamespaces, 0, 1 ); 178cdf0e10cSrcweir } 179cdf0e10cSrcweir 180cdf0e10cSrcweir 181cdf0e10cSrcweir Model::IntSequence_t Model::getUnoTunnelID() 182cdf0e10cSrcweir { 183cdf0e10cSrcweir static cppu::OImplementationId aImplementationId; 184cdf0e10cSrcweir return aImplementationId.getImplementationId(); 185cdf0e10cSrcweir } 186cdf0e10cSrcweir 187cdf0e10cSrcweir Model::XDocument_t Model::getForeignSchema() const 188cdf0e10cSrcweir { 189cdf0e10cSrcweir return mxForeignSchema; 190cdf0e10cSrcweir } 191cdf0e10cSrcweir 192cdf0e10cSrcweir void Model::setForeignSchema( const XDocument_t& rDocument ) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir mxForeignSchema = rDocument; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir 197cdf0e10cSrcweir rtl::OUString Model::getSchemaRef() const 198cdf0e10cSrcweir { 199cdf0e10cSrcweir return msSchemaRef; 200cdf0e10cSrcweir } 201cdf0e10cSrcweir 202cdf0e10cSrcweir void Model::setSchemaRef( const rtl::OUString& rSchemaRef ) 203cdf0e10cSrcweir { 204cdf0e10cSrcweir msSchemaRef = rSchemaRef; 205cdf0e10cSrcweir } 206cdf0e10cSrcweir 207cdf0e10cSrcweir Model::XNameContainer_t Model::getNamespaces() const 208cdf0e10cSrcweir { 209cdf0e10cSrcweir return mxNamespaces; 210cdf0e10cSrcweir } 211cdf0e10cSrcweir 212cdf0e10cSrcweir void Model::setNamespaces( const XNameContainer_t& rNamespaces ) 213cdf0e10cSrcweir { 214cdf0e10cSrcweir if( rNamespaces.is() ) 215cdf0e10cSrcweir mxNamespaces = rNamespaces; 216cdf0e10cSrcweir } 217cdf0e10cSrcweir 218cdf0e10cSrcweir bool Model::getExternalData() const 219cdf0e10cSrcweir { 220cdf0e10cSrcweir return mbExternalData; 221cdf0e10cSrcweir } 222cdf0e10cSrcweir 223cdf0e10cSrcweir void Model::setExternalData( bool _bData ) 224cdf0e10cSrcweir { 225cdf0e10cSrcweir mbExternalData = _bData; 226cdf0e10cSrcweir } 227cdf0e10cSrcweir 228cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 229cdf0e10cSrcweir void Model::dbg_assertInvariant() const 230cdf0e10cSrcweir { 231cdf0e10cSrcweir OSL_ENSURE( mpInstances != NULL, "no instances found" ); 232cdf0e10cSrcweir OSL_ENSURE( mxInstances.is(), "No instance container!" ); 233cdf0e10cSrcweir // OSL_ENSURE( mxInstances->hasElements(), "no instance!" ); 234cdf0e10cSrcweir 235cdf0e10cSrcweir OSL_ENSURE( mpBindings != NULL, "no bindings element" ); 236cdf0e10cSrcweir OSL_ENSURE( mxBindings.is(), "No Bindings container" ); 237cdf0e10cSrcweir 238cdf0e10cSrcweir OSL_ENSURE( mpSubmissions != NULL, "no submissions element" ); 239cdf0e10cSrcweir OSL_ENSURE( mxSubmissions.is(), "No Submission container" ); 240cdf0e10cSrcweir 241cdf0e10cSrcweir 242cdf0e10cSrcweir 243cdf0e10cSrcweir /* 244cdf0e10cSrcweir // check bindings, and things that have to do with our binding 245cdf0e10cSrcweir std::vector<MIP*> aAllMIPs; // check MIP map 246cdf0e10cSrcweir sal_Int32 nCount = mpBindings->countItems(); 247cdf0e10cSrcweir for( sal_Int32 i = 0; i < nCount; i++ ) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir Binding* pBind = Binding::getBinding( 250cdf0e10cSrcweir mpBindings->Collection<XPropertySet_t>::getItem( i ) ); 251cdf0e10cSrcweir 252cdf0e10cSrcweir // examine and check binding 253cdf0e10cSrcweir OSL_ENSURE( pBind != NULL, "invalid binding found" ); 254cdf0e10cSrcweir 255cdf0e10cSrcweir OSL_ENSURE( Model::getModel( pBind->getModel() ) == this, 256cdf0e10cSrcweir "our binding doesn't know us."); 257cdf0e10cSrcweir // check this binding's MIP against MIP map 258cdf0e10cSrcweir MIP* pMIP = const_cast<MIP*>( pBind->_getMIP() ); 259cdf0e10cSrcweir sal_Int32 nFound = 0; 260cdf0e10cSrcweir if( pMIP != NULL ) 261cdf0e10cSrcweir { 262cdf0e10cSrcweir aAllMIPs.push_back( pMIP ); 263cdf0e10cSrcweir for( MIPs_t::const_iterator aIter = maMIPs.begin(); 264cdf0e10cSrcweir aIter != maMIPs.end(); 265cdf0e10cSrcweir aIter++ ) 266cdf0e10cSrcweir { 267cdf0e10cSrcweir if( pMIP == aIter->second ) 268cdf0e10cSrcweir nFound++; 269cdf0e10cSrcweir } 270cdf0e10cSrcweir } 271cdf0e10cSrcweir OSL_ENSURE( ( pMIP == NULL ) == ( nFound == 0 ), "MIP-map wrong" ); 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir // check MIP map for left-over MIPs 275cdf0e10cSrcweir for( MIPs_t::const_iterator aIter = maMIPs.begin(); 276cdf0e10cSrcweir aIter != maMIPs.end(); 277cdf0e10cSrcweir aIter++ ) 278cdf0e10cSrcweir { 279cdf0e10cSrcweir MIP* pMIP = aIter->second; 280cdf0e10cSrcweir std::vector<MIP*>::iterator aFound = 281cdf0e10cSrcweir std::find( aAllMIPs.begin(), aAllMIPs.end(), pMIP ); 282cdf0e10cSrcweir if( aFound != aAllMIPs.end() ) 283cdf0e10cSrcweir aAllMIPs.erase( aFound ); 284cdf0e10cSrcweir } 285cdf0e10cSrcweir OSL_ENSURE( aAllMIPs.empty(), "lonely MIPs found!" ); 286cdf0e10cSrcweir */ 287cdf0e10cSrcweir } 288cdf0e10cSrcweir #endif 289cdf0e10cSrcweir 290cdf0e10cSrcweir 291cdf0e10cSrcweir // 292cdf0e10cSrcweir // MIP managment 293cdf0e10cSrcweir // 294cdf0e10cSrcweir 295cdf0e10cSrcweir void Model::addMIP( void* pTag, const XNode_t& xNode, const MIP& rMIP ) 296cdf0e10cSrcweir { 297cdf0e10cSrcweir OSL_ENSURE( pTag != NULL, "empty tag?" ); 298cdf0e10cSrcweir OSL_ENSURE( xNode.is(), "no node" ); 299cdf0e10cSrcweir 300cdf0e10cSrcweir MIPs_t::value_type aValue( xNode, ::std::pair<void*,MIP>( pTag, rMIP ) ); 301cdf0e10cSrcweir maMIPs.insert( aValue ); 302cdf0e10cSrcweir } 303cdf0e10cSrcweir 304cdf0e10cSrcweir void Model::removeMIPs( void* pTag ) 305cdf0e10cSrcweir { 306cdf0e10cSrcweir OSL_ENSURE( pTag != NULL, "empty tag?" ); 307cdf0e10cSrcweir 308cdf0e10cSrcweir for( MIPs_t::iterator aIter = maMIPs.begin(); 309cdf0e10cSrcweir aIter != maMIPs.end(); ) 310cdf0e10cSrcweir { 311cdf0e10cSrcweir if( aIter->second.first == pTag ) 312cdf0e10cSrcweir { 313cdf0e10cSrcweir MIPs_t::iterator next( aIter ); ++next; 314cdf0e10cSrcweir maMIPs.erase( aIter ); 315cdf0e10cSrcweir aIter = next; 316cdf0e10cSrcweir } 317cdf0e10cSrcweir else 318cdf0e10cSrcweir ++aIter; 319cdf0e10cSrcweir } 320cdf0e10cSrcweir } 321cdf0e10cSrcweir 322cdf0e10cSrcweir MIP Model::queryMIP( const XNode_t& xNode ) const 323cdf0e10cSrcweir { 324cdf0e10cSrcweir // OSL_ENSURE( xNode.is(), "no node" ); 325cdf0e10cSrcweir 326cdf0e10cSrcweir // travel up inheritance chain and inherit MIPs 327cdf0e10cSrcweir MIP aRet; 328cdf0e10cSrcweir for( XNode_t xCurrent = xNode; 329cdf0e10cSrcweir xCurrent.is(); 330cdf0e10cSrcweir xCurrent = xCurrent->getParentNode() ) 331cdf0e10cSrcweir { 332cdf0e10cSrcweir // iterate over all MIPs for this node, and join MIPs 333cdf0e10cSrcweir MIP aMIP; 334cdf0e10cSrcweir MIPs_t::const_iterator aEnd = maMIPs.upper_bound( xCurrent ); 335cdf0e10cSrcweir MIPs_t::const_iterator aIter = maMIPs.lower_bound( xCurrent ); 336cdf0e10cSrcweir for( ; aIter != aEnd; aIter++ ) 337cdf0e10cSrcweir aMIP.join( aIter->second.second ); 338cdf0e10cSrcweir 339cdf0e10cSrcweir // inherit from current node (or set if we are at the start node) 340cdf0e10cSrcweir if( xCurrent == xNode ) 341cdf0e10cSrcweir aRet = aMIP; 342cdf0e10cSrcweir else 343cdf0e10cSrcweir aRet.inherit( aMIP ); 344cdf0e10cSrcweir } 345cdf0e10cSrcweir 346cdf0e10cSrcweir return aRet; 347cdf0e10cSrcweir } 348cdf0e10cSrcweir 349cdf0e10cSrcweir 350cdf0e10cSrcweir 351cdf0e10cSrcweir void Model::rebind() 352cdf0e10cSrcweir { 353cdf0e10cSrcweir OSL_ENSURE( mpBindings != NULL, "bindings?" ); 354cdf0e10cSrcweir 355cdf0e10cSrcweir // iterate over all bindings and call update 356cdf0e10cSrcweir sal_Int32 nCount = mpBindings->countItems(); 357cdf0e10cSrcweir for( sal_Int32 i = 0; i < nCount; i++ ) 358cdf0e10cSrcweir { 359cdf0e10cSrcweir Binding* pBind = Binding::getBinding( mpBindings->Collection<XPropertySet_t>::getItem( i ) ); 360cdf0e10cSrcweir OSL_ENSURE( pBind != NULL, "binding?" ); 361cdf0e10cSrcweir pBind->update(); 362cdf0e10cSrcweir } 363cdf0e10cSrcweir } 364cdf0e10cSrcweir 365cdf0e10cSrcweir 366cdf0e10cSrcweir 367cdf0e10cSrcweir void Model::deferNotifications( bool bDefer ) 368cdf0e10cSrcweir { 369cdf0e10cSrcweir // iterate over all bindings and defer notifications 370cdf0e10cSrcweir sal_Int32 nCount = mpBindings->countItems(); 371cdf0e10cSrcweir for( sal_Int32 i = 0; i < nCount; i++ ) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir Binding* pBind = Binding::getBinding( mpBindings->Collection<XPropertySet_t>::getItem( i ) ); 374cdf0e10cSrcweir OSL_ENSURE( pBind != NULL, "binding?" ); 375cdf0e10cSrcweir pBind->deferNotifications( bDefer ); 376cdf0e10cSrcweir } 377cdf0e10cSrcweir } 378cdf0e10cSrcweir 379cdf0e10cSrcweir 380cdf0e10cSrcweir bool Model::setSimpleContent( const XNode_t& xConstNode, 381cdf0e10cSrcweir const rtl::OUString& sValue ) 382cdf0e10cSrcweir { 383cdf0e10cSrcweir OSL_ENSURE( xConstNode.is(), "need node to set data" ); 384cdf0e10cSrcweir 385cdf0e10cSrcweir bool bRet = false; 386cdf0e10cSrcweir if( xConstNode.is() ) 387cdf0e10cSrcweir { 388cdf0e10cSrcweir // non-const node reference so we can assign children (if necessary) 389cdf0e10cSrcweir XNode_t xNode( xConstNode ); 390cdf0e10cSrcweir 391cdf0e10cSrcweir switch( xNode->getNodeType() ) 392cdf0e10cSrcweir { 393cdf0e10cSrcweir case NodeType_ELEMENT_NODE: 394cdf0e10cSrcweir { 395cdf0e10cSrcweir // find first text node child 396cdf0e10cSrcweir Reference<XNode> xChild; 397cdf0e10cSrcweir for( xChild = xNode->getFirstChild(); 398cdf0e10cSrcweir xChild.is() && xChild->getNodeType() != NodeType_TEXT_NODE; 399cdf0e10cSrcweir xChild = xChild->getNextSibling() ) 400cdf0e10cSrcweir ; // empty loop; only find first text node child 401cdf0e10cSrcweir 402cdf0e10cSrcweir // create text node, if none is found 403cdf0e10cSrcweir if( ! xChild.is() ) 404cdf0e10cSrcweir { 405cdf0e10cSrcweir xChild = Reference<XNode>( 406cdf0e10cSrcweir xNode->getOwnerDocument()->createTextNode( OUString() ), 407cdf0e10cSrcweir UNO_QUERY_THROW ); 408cdf0e10cSrcweir xNode->appendChild( xChild ); 409cdf0e10cSrcweir } 410cdf0e10cSrcweir xNode = xChild; 411cdf0e10cSrcweir 412cdf0e10cSrcweir OSL_ENSURE( xNode.is() && 413cdf0e10cSrcweir xNode->getNodeType() == NodeType_TEXT_NODE, 414cdf0e10cSrcweir "text node creation failed?" ); 415cdf0e10cSrcweir } 416cdf0e10cSrcweir // no break; continue as with text node: 417cdf0e10cSrcweir 418cdf0e10cSrcweir case NodeType_TEXT_NODE: 419cdf0e10cSrcweir case NodeType_ATTRIBUTE_NODE: 420cdf0e10cSrcweir { 421cdf0e10cSrcweir // set the node value (defer notifications) 422cdf0e10cSrcweir if( xNode->getNodeValue() != sValue ) 423cdf0e10cSrcweir { 424cdf0e10cSrcweir deferNotifications( true ); 425cdf0e10cSrcweir xNode->setNodeValue( sValue ); 426cdf0e10cSrcweir deferNotifications( false ); 427cdf0e10cSrcweir } 428cdf0e10cSrcweir bRet = true; 429cdf0e10cSrcweir } 430cdf0e10cSrcweir break; 431cdf0e10cSrcweir 432cdf0e10cSrcweir default: 433cdf0e10cSrcweir { 434cdf0e10cSrcweir OSL_ENSURE( false, "bound to unknown node type?" ); 435cdf0e10cSrcweir } 436cdf0e10cSrcweir break; 437cdf0e10cSrcweir 438cdf0e10cSrcweir } 439cdf0e10cSrcweir } 440cdf0e10cSrcweir return bRet; 441cdf0e10cSrcweir } 442cdf0e10cSrcweir 443cdf0e10cSrcweir void Model::loadInstance( sal_Int32 nInstance ) 444cdf0e10cSrcweir { 445cdf0e10cSrcweir Sequence<PropertyValue> aSequence = mpInstances->getItem( nInstance ); 446cdf0e10cSrcweir 447cdf0e10cSrcweir // find URL from instance 448cdf0e10cSrcweir OUString sURL; 449cdf0e10cSrcweir bool bOnce = false; 450cdf0e10cSrcweir getInstanceData( aSequence, NULL, NULL, &sURL, &bOnce ); 451cdf0e10cSrcweir 452cdf0e10cSrcweir // if we have a URL, load the document and set it into the instance 453cdf0e10cSrcweir if( sURL.getLength() > 0 ) 454cdf0e10cSrcweir { 455cdf0e10cSrcweir try 456cdf0e10cSrcweir { 457cdf0e10cSrcweir Reference<XInputStream> xInput = 458cdf0e10cSrcweir Reference<XSimpleFileAccess>( 459cdf0e10cSrcweir createInstance( 460cdf0e10cSrcweir OUSTRING("com.sun.star.ucb.SimpleFileAccess") ), 461cdf0e10cSrcweir UNO_QUERY_THROW )->openFileRead( sURL ); 462cdf0e10cSrcweir if( xInput.is() ) 463cdf0e10cSrcweir { 464cdf0e10cSrcweir Reference<XDocument> xInstance = 465cdf0e10cSrcweir getDocumentBuilder()->parse( xInput ); 466cdf0e10cSrcweir if( xInstance.is() ) 467cdf0e10cSrcweir { 468cdf0e10cSrcweir OUString sEmpty; 469cdf0e10cSrcweir setInstanceData( aSequence, NULL, &xInstance, 470cdf0e10cSrcweir bOnce ? &sEmpty : &sURL, NULL); 471cdf0e10cSrcweir mpInstances->setItem( nInstance, aSequence ); 472cdf0e10cSrcweir } 473cdf0e10cSrcweir } 474cdf0e10cSrcweir } 475cdf0e10cSrcweir catch( const Exception& ) 476cdf0e10cSrcweir { 477cdf0e10cSrcweir // couldn't load the instance -> ignore! 478cdf0e10cSrcweir } 479cdf0e10cSrcweir } 480cdf0e10cSrcweir } 481cdf0e10cSrcweir 482cdf0e10cSrcweir void Model::loadInstances() 483cdf0e10cSrcweir { 484cdf0e10cSrcweir // iterate over instance array to get PropertyValue-Sequence 485cdf0e10cSrcweir const sal_Int32 nInstances = mpInstances->countItems(); 486cdf0e10cSrcweir for( sal_Int32 nInstance = 0; nInstance < nInstances; nInstance++ ) 487cdf0e10cSrcweir { 488cdf0e10cSrcweir loadInstance( nInstance ); 489cdf0e10cSrcweir } 490cdf0e10cSrcweir } 491cdf0e10cSrcweir 492cdf0e10cSrcweir bool Model::isInitialized() const 493cdf0e10cSrcweir { 494cdf0e10cSrcweir return mbInitialized; 495cdf0e10cSrcweir } 496cdf0e10cSrcweir 497cdf0e10cSrcweir bool Model::isValid() const 498cdf0e10cSrcweir { 499cdf0e10cSrcweir bool bValid = true; 500cdf0e10cSrcweir sal_Int32 nCount = mpBindings->countItems(); 501cdf0e10cSrcweir for( sal_Int32 i = 0; bValid && i < nCount; i++ ) 502cdf0e10cSrcweir { 503cdf0e10cSrcweir Binding* pBind = Binding::getBinding( mpBindings->Collection<XPropertySet_t>::getItem( i ) ); 504cdf0e10cSrcweir OSL_ENSURE( pBind != NULL, "binding?" ); 505cdf0e10cSrcweir bValid = pBind->isValid(); 506cdf0e10cSrcweir } 507cdf0e10cSrcweir return bValid; 508cdf0e10cSrcweir } 509cdf0e10cSrcweir 510cdf0e10cSrcweir 511cdf0e10cSrcweir 512cdf0e10cSrcweir // 513cdf0e10cSrcweir // implement xforms::XModel 514cdf0e10cSrcweir // 515cdf0e10cSrcweir 516cdf0e10cSrcweir rtl::OUString Model::getID() 517cdf0e10cSrcweir throw( RuntimeException ) 518cdf0e10cSrcweir { 519cdf0e10cSrcweir DBG_INVARIANT(); 520cdf0e10cSrcweir return msID; 521cdf0e10cSrcweir } 522cdf0e10cSrcweir 523cdf0e10cSrcweir void Model::setID( const rtl::OUString& sID ) 524cdf0e10cSrcweir throw( RuntimeException ) 525cdf0e10cSrcweir { 526cdf0e10cSrcweir DBG_INVARIANT(); 527cdf0e10cSrcweir msID = sID; 528cdf0e10cSrcweir } 529cdf0e10cSrcweir 530cdf0e10cSrcweir void Model::initialize() 531cdf0e10cSrcweir throw( RuntimeException ) 532cdf0e10cSrcweir { 533cdf0e10cSrcweir DBG_ASSERT( ! mbInitialized, "model already initialized" ); 534cdf0e10cSrcweir 535cdf0e10cSrcweir // load instances 536cdf0e10cSrcweir loadInstances(); 537cdf0e10cSrcweir 538cdf0e10cSrcweir // let's pretend we're initialized and rebind all bindings 539cdf0e10cSrcweir mbInitialized = true; 540cdf0e10cSrcweir rebind(); 541cdf0e10cSrcweir } 542cdf0e10cSrcweir 543cdf0e10cSrcweir void Model::rebuild() 544cdf0e10cSrcweir throw( RuntimeException ) 545cdf0e10cSrcweir { 546cdf0e10cSrcweir if( ! mbInitialized ) 547cdf0e10cSrcweir initialize(); 548cdf0e10cSrcweir else 549cdf0e10cSrcweir rebind(); 550cdf0e10cSrcweir } 551cdf0e10cSrcweir 552cdf0e10cSrcweir void Model::recalculate() 553cdf0e10cSrcweir throw( RuntimeException ) 554cdf0e10cSrcweir { 555cdf0e10cSrcweir rebind(); 556cdf0e10cSrcweir } 557cdf0e10cSrcweir 558cdf0e10cSrcweir void Model::revalidate() 559cdf0e10cSrcweir throw( RuntimeException ) 560cdf0e10cSrcweir { 561cdf0e10cSrcweir // do nothing. We don't validate anyways! 562cdf0e10cSrcweir } 563cdf0e10cSrcweir 564cdf0e10cSrcweir void Model::refresh() 565cdf0e10cSrcweir throw( RuntimeException ) 566cdf0e10cSrcweir { 567cdf0e10cSrcweir rebind(); 568cdf0e10cSrcweir } 569cdf0e10cSrcweir 570cdf0e10cSrcweir 571cdf0e10cSrcweir void SAL_CALL Model::submitWithInteraction( 572cdf0e10cSrcweir const rtl::OUString& sID, 573cdf0e10cSrcweir const XInteractionHandler_t& _rxHandler ) 574cdf0e10cSrcweir throw( VetoException, 575cdf0e10cSrcweir WrappedTargetException, 576cdf0e10cSrcweir RuntimeException ) 577cdf0e10cSrcweir { 578cdf0e10cSrcweir DBG_INVARIANT(); 579cdf0e10cSrcweir 580cdf0e10cSrcweir if( mpSubmissions->hasItem( sID ) ) 581cdf0e10cSrcweir { 582cdf0e10cSrcweir Submission* pSubmission = 583cdf0e10cSrcweir Submission::getSubmission( mpSubmissions->getItem( sID ) ); 584cdf0e10cSrcweir OSL_ENSURE( pSubmission != NULL, "no submission?" ); 585cdf0e10cSrcweir OSL_ENSURE( pSubmission->getModel() == Reference<XModel>( this ), 586cdf0e10cSrcweir "wrong model" ); 587cdf0e10cSrcweir 588cdf0e10cSrcweir // submit. All exceptions are allowed to leave. 589cdf0e10cSrcweir pSubmission->submitWithInteraction( _rxHandler ); 590cdf0e10cSrcweir } 591cdf0e10cSrcweir } 592cdf0e10cSrcweir 593cdf0e10cSrcweir void Model::submit( const rtl::OUString& sID ) 594cdf0e10cSrcweir throw( VetoException, WrappedTargetException, RuntimeException ) 595cdf0e10cSrcweir { 596cdf0e10cSrcweir submitWithInteraction( sID, NULL ); 597cdf0e10cSrcweir } 598cdf0e10cSrcweir 599cdf0e10cSrcweir Model::XDataTypeRepository_t SAL_CALL Model::getDataTypeRepository( ) 600cdf0e10cSrcweir throw( RuntimeException ) 601cdf0e10cSrcweir { 602cdf0e10cSrcweir if ( !mxDataTypes.is() ) 603cdf0e10cSrcweir mxDataTypes = new ODataTypeRepository; 604cdf0e10cSrcweir 605cdf0e10cSrcweir return mxDataTypes; 606cdf0e10cSrcweir } 607cdf0e10cSrcweir 608cdf0e10cSrcweir // 609cdf0e10cSrcweir // instance management 610cdf0e10cSrcweir // 611cdf0e10cSrcweir 612cdf0e10cSrcweir Model::XSet_t Model::getInstances() 613cdf0e10cSrcweir throw( RuntimeException ) 614cdf0e10cSrcweir { 615cdf0e10cSrcweir return mxInstances; 616cdf0e10cSrcweir } 617cdf0e10cSrcweir 618cdf0e10cSrcweir Model::XDocument_t Model::getInstanceDocument( const rtl::OUString& rName ) 619cdf0e10cSrcweir throw( RuntimeException ) 620cdf0e10cSrcweir { 621cdf0e10cSrcweir ensureAtLeastOneInstance(); 622cdf0e10cSrcweir Reference<XDocument> aInstance; 623cdf0e10cSrcweir sal_Int32 nInstance = lcl_findInstance( mpInstances, rName ); 624cdf0e10cSrcweir if( nInstance != -1 ) 625cdf0e10cSrcweir getInstanceData( mpInstances->getItem( nInstance ), 626cdf0e10cSrcweir NULL, &aInstance, NULL, NULL ); 627cdf0e10cSrcweir return aInstance; 628cdf0e10cSrcweir } 629cdf0e10cSrcweir 630cdf0e10cSrcweir Model::XDocument_t SAL_CALL Model::getDefaultInstance() 631cdf0e10cSrcweir throw( RuntimeException ) 632cdf0e10cSrcweir { 633cdf0e10cSrcweir ensureAtLeastOneInstance(); 634cdf0e10cSrcweir DBG_ASSERT( mpInstances->countItems() > 0, "no instance?" ); 635cdf0e10cSrcweir Reference<XDocument> aInstance; 636cdf0e10cSrcweir getInstanceData( mpInstances->getItem( 0 ), NULL, &aInstance, NULL, NULL ); 637cdf0e10cSrcweir return aInstance; 638cdf0e10cSrcweir } 639cdf0e10cSrcweir 640cdf0e10cSrcweir 641cdf0e10cSrcweir 642cdf0e10cSrcweir // 643cdf0e10cSrcweir // bindings management 644cdf0e10cSrcweir // 645cdf0e10cSrcweir 646cdf0e10cSrcweir Model::XPropertySet_t SAL_CALL Model::createBinding() 647cdf0e10cSrcweir throw( RuntimeException ) 648cdf0e10cSrcweir { 649cdf0e10cSrcweir DBG_INVARIANT(); 650cdf0e10cSrcweir return new Binding(); 651cdf0e10cSrcweir } 652cdf0e10cSrcweir 653cdf0e10cSrcweir Model::XPropertySet_t Model::cloneBinding( const XPropertySet_t& xBinding ) 654cdf0e10cSrcweir throw( RuntimeException ) 655cdf0e10cSrcweir { 656cdf0e10cSrcweir DBG_INVARIANT(); 657cdf0e10cSrcweir XPropertySet_t xNewBinding = createBinding(); 658cdf0e10cSrcweir copy( xBinding, xNewBinding ); 659cdf0e10cSrcweir return xNewBinding; 660cdf0e10cSrcweir } 661cdf0e10cSrcweir 662cdf0e10cSrcweir Model::XPropertySet_t Model::getBinding( const rtl::OUString& sId ) 663cdf0e10cSrcweir throw( RuntimeException ) 664cdf0e10cSrcweir { 665cdf0e10cSrcweir DBG_INVARIANT(); 666cdf0e10cSrcweir return mpBindings->hasItem( sId ) ? mpBindings->getItem( sId ) : NULL; 667cdf0e10cSrcweir } 668cdf0e10cSrcweir 669cdf0e10cSrcweir Model::XSet_t Model::getBindings() 670cdf0e10cSrcweir throw( RuntimeException ) 671cdf0e10cSrcweir { 672cdf0e10cSrcweir DBG_INVARIANT(); 673cdf0e10cSrcweir return mxBindings; 674cdf0e10cSrcweir } 675cdf0e10cSrcweir 676cdf0e10cSrcweir 677cdf0e10cSrcweir 678cdf0e10cSrcweir // 679cdf0e10cSrcweir // submission management 680cdf0e10cSrcweir // 681cdf0e10cSrcweir 682cdf0e10cSrcweir Model::XSubmission_t Model::createSubmission() 683cdf0e10cSrcweir throw( RuntimeException ) 684cdf0e10cSrcweir { 685cdf0e10cSrcweir DBG_INVARIANT(); 686cdf0e10cSrcweir return new Submission(); 687cdf0e10cSrcweir } 688cdf0e10cSrcweir 689cdf0e10cSrcweir Model::XSubmission_t Model::cloneSubmission(const XPropertySet_t& xSubmission) 690cdf0e10cSrcweir throw( RuntimeException ) 691cdf0e10cSrcweir { 692cdf0e10cSrcweir DBG_INVARIANT(); 693cdf0e10cSrcweir XSubmission_t xNewSubmission = createSubmission(); 694cdf0e10cSrcweir XPropertySet_t xAsPropertySet( xNewSubmission.get() ); 695cdf0e10cSrcweir copy( xSubmission.get(), xAsPropertySet ); 696cdf0e10cSrcweir return xNewSubmission; 697cdf0e10cSrcweir } 698cdf0e10cSrcweir 699cdf0e10cSrcweir Model::XSubmission_t Model::getSubmission( const rtl::OUString& sId ) 700cdf0e10cSrcweir throw( RuntimeException ) 701cdf0e10cSrcweir { 702cdf0e10cSrcweir DBG_INVARIANT(); 703cdf0e10cSrcweir XSubmission_t xSubmission; 704cdf0e10cSrcweir if ( mpSubmissions->hasItem( sId ) ) 705cdf0e10cSrcweir xSubmission = xSubmission.query( mpSubmissions->getItem( sId ) ); 706cdf0e10cSrcweir return xSubmission; 707cdf0e10cSrcweir } 708cdf0e10cSrcweir 709cdf0e10cSrcweir Model::XSet_t Model::getSubmissions() 710cdf0e10cSrcweir throw( RuntimeException ) 711cdf0e10cSrcweir { 712cdf0e10cSrcweir DBG_INVARIANT(); 713cdf0e10cSrcweir return mxSubmissions; 714cdf0e10cSrcweir } 715cdf0e10cSrcweir 716cdf0e10cSrcweir 717cdf0e10cSrcweir 718cdf0e10cSrcweir // 719cdf0e10cSrcweir // implementation of XFormsUIHelper1 interface 720cdf0e10cSrcweir // can be found in file model_ui.cxx 721cdf0e10cSrcweir // 722cdf0e10cSrcweir 723cdf0e10cSrcweir 724cdf0e10cSrcweir 725cdf0e10cSrcweir // 726cdf0e10cSrcweir // implement XPropertySet & friends 727cdf0e10cSrcweir // 728cdf0e10cSrcweir 729cdf0e10cSrcweir #define HANDLE_ID 0 730cdf0e10cSrcweir #define HANDLE_Instance 1 731cdf0e10cSrcweir #define HANDLE_InstanceURL 2 732cdf0e10cSrcweir #define HANDLE_ForeignSchema 3 733cdf0e10cSrcweir #define HANDLE_SchemaRef 4 734cdf0e10cSrcweir #define HANDLE_Namespaces 5 735cdf0e10cSrcweir #define HANDLE_ExternalData 6 736cdf0e10cSrcweir 737cdf0e10cSrcweir #define REGISTER_PROPERTY( property, type ) \ 738cdf0e10cSrcweir registerProperty( PROPERTY( property, type ), \ 739cdf0e10cSrcweir new DirectPropertyAccessor< Model, type >( this, &Model::set##property, &Model::get##property ) ); 740cdf0e10cSrcweir 741cdf0e10cSrcweir #define REGISTER_PROPERTY_API( property, type ) \ 742cdf0e10cSrcweir registerProperty( PROPERTY( property, type ), \ 743cdf0e10cSrcweir new APIPropertyAccessor< Model, type >( this, &Model::set##property, &Model::get##property ) ); 744cdf0e10cSrcweir 745cdf0e10cSrcweir #define REGISTER_BOOL_PROPERTY( property ) \ 746cdf0e10cSrcweir registerProperty( PROPERTY( property, sal_Bool ), \ 747cdf0e10cSrcweir new BooleanPropertyAccessor< Model, bool >( this, &Model::set##property, &Model::get##property ) ); 748cdf0e10cSrcweir 749cdf0e10cSrcweir void Model::initializePropertySet() 750cdf0e10cSrcweir { 751cdf0e10cSrcweir REGISTER_PROPERTY_API ( ID, OUString ); 752cdf0e10cSrcweir REGISTER_PROPERTY ( ForeignSchema, XDocument_t ); 753cdf0e10cSrcweir REGISTER_PROPERTY ( SchemaRef, OUString ); 754cdf0e10cSrcweir REGISTER_PROPERTY ( Namespaces, XNameContainer_t ); 755cdf0e10cSrcweir REGISTER_BOOL_PROPERTY( ExternalData ); 756cdf0e10cSrcweir } 757cdf0e10cSrcweir 758cdf0e10cSrcweir void Model::update() 759cdf0e10cSrcweir throw( RuntimeException ) 760cdf0e10cSrcweir { 761cdf0e10cSrcweir rebuild(); 762cdf0e10cSrcweir } 763cdf0e10cSrcweir 764cdf0e10cSrcweir 765cdf0e10cSrcweir sal_Int64 Model::getSomething( const IntSequence_t& xId ) 766cdf0e10cSrcweir throw( RuntimeException ) 767cdf0e10cSrcweir { 768cdf0e10cSrcweir return reinterpret_cast<sal_Int64>( ( xId == getUnoTunnelID() ) ? this : NULL ); 769cdf0e10cSrcweir } 770cdf0e10cSrcweir 771cdf0e10cSrcweir Sequence<sal_Int8> Model::getImplementationId() 772cdf0e10cSrcweir throw( RuntimeException ) 773cdf0e10cSrcweir { 774cdf0e10cSrcweir return getUnoTunnelID(); 775cdf0e10cSrcweir } 776cdf0e10cSrcweir 777cdf0e10cSrcweir 778cdf0e10cSrcweir // 779cdf0e10cSrcweir // 'shift' operators for getting data into and out of Anys 780cdf0e10cSrcweir // 781cdf0e10cSrcweir 782cdf0e10cSrcweir void operator <<= ( com::sun::star::uno::Any& rAny, 783cdf0e10cSrcweir xforms::Model* pModel) 784cdf0e10cSrcweir { 785cdf0e10cSrcweir Reference<XPropertySet> xPropSet( static_cast<XPropertySet*>( pModel ) ); 786cdf0e10cSrcweir rAny <<= xPropSet; 787cdf0e10cSrcweir } 788cdf0e10cSrcweir 789cdf0e10cSrcweir bool operator >>= ( xforms::Model* pModel, 790cdf0e10cSrcweir com::sun::star::uno::Any& rAny ) 791cdf0e10cSrcweir { 792cdf0e10cSrcweir bool bRet = false; 793cdf0e10cSrcweir 794cdf0e10cSrcweir // acquire model pointer through XUnoTunnel 795cdf0e10cSrcweir Reference<XUnoTunnel> xTunnel( rAny, UNO_QUERY ); 796cdf0e10cSrcweir if( xTunnel.is() ) 797cdf0e10cSrcweir { 798cdf0e10cSrcweir pModel = reinterpret_cast<xforms::Model*>( 799cdf0e10cSrcweir xTunnel->getSomething( xforms::Model::getUnoTunnelID() ) ); 800cdf0e10cSrcweir bRet = true; 801cdf0e10cSrcweir } 802cdf0e10cSrcweir 803cdf0e10cSrcweir return bRet; 804cdf0e10cSrcweir } 805