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
ensureAtLeastOneInstance()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 */
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
~Model()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
lcl_getModel(const Reference<XUnoTunnel> & xTunnel)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
getModel(const Reference<XModel> & xModel)152cdf0e10cSrcweir Model* Model::getModel( const Reference<XModel>& xModel )
153cdf0e10cSrcweir {
154cdf0e10cSrcweir return lcl_getModel( Reference<XUnoTunnel>( xModel, UNO_QUERY ) );
155cdf0e10cSrcweir }
156cdf0e10cSrcweir
getEvaluationContext()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
getUnoTunnelID()181cdf0e10cSrcweir Model::IntSequence_t Model::getUnoTunnelID()
182cdf0e10cSrcweir {
183cdf0e10cSrcweir static cppu::OImplementationId aImplementationId;
184cdf0e10cSrcweir return aImplementationId.getImplementationId();
185cdf0e10cSrcweir }
186cdf0e10cSrcweir
getForeignSchema() const187cdf0e10cSrcweir Model::XDocument_t Model::getForeignSchema() const
188cdf0e10cSrcweir {
189cdf0e10cSrcweir return mxForeignSchema;
190cdf0e10cSrcweir }
191cdf0e10cSrcweir
setForeignSchema(const XDocument_t & rDocument)192cdf0e10cSrcweir void Model::setForeignSchema( const XDocument_t& rDocument )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir mxForeignSchema = rDocument;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir
getSchemaRef() const197cdf0e10cSrcweir rtl::OUString Model::getSchemaRef() const
198cdf0e10cSrcweir {
199cdf0e10cSrcweir return msSchemaRef;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir
setSchemaRef(const rtl::OUString & rSchemaRef)202cdf0e10cSrcweir void Model::setSchemaRef( const rtl::OUString& rSchemaRef )
203cdf0e10cSrcweir {
204cdf0e10cSrcweir msSchemaRef = rSchemaRef;
205cdf0e10cSrcweir }
206cdf0e10cSrcweir
getNamespaces() const207cdf0e10cSrcweir Model::XNameContainer_t Model::getNamespaces() const
208cdf0e10cSrcweir {
209cdf0e10cSrcweir return mxNamespaces;
210cdf0e10cSrcweir }
211cdf0e10cSrcweir
setNamespaces(const XNameContainer_t & rNamespaces)212cdf0e10cSrcweir void Model::setNamespaces( const XNameContainer_t& rNamespaces )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir if( rNamespaces.is() )
215cdf0e10cSrcweir mxNamespaces = rNamespaces;
216cdf0e10cSrcweir }
217cdf0e10cSrcweir
getExternalData() const218cdf0e10cSrcweir bool Model::getExternalData() const
219cdf0e10cSrcweir {
220cdf0e10cSrcweir return mbExternalData;
221cdf0e10cSrcweir }
222cdf0e10cSrcweir
setExternalData(bool _bData)223cdf0e10cSrcweir void Model::setExternalData( bool _bData )
224cdf0e10cSrcweir {
225cdf0e10cSrcweir mbExternalData = _bData;
226cdf0e10cSrcweir }
227cdf0e10cSrcweir
228cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
dbg_assertInvariant() const229cdf0e10cSrcweir 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
addMIP(void * pTag,const XNode_t & xNode,const MIP & rMIP)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
removeMIPs(void * pTag)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
queryMIP(const XNode_t & xNode) const322cdf0e10cSrcweir 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
rebind()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
deferNotifications(bool bDefer)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
setSimpleContent(const XNode_t & xConstNode,const rtl::OUString & sValue)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
loadInstance(sal_Int32 nInstance)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
loadInstances()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
isInitialized() const492cdf0e10cSrcweir bool Model::isInitialized() const
493cdf0e10cSrcweir {
494cdf0e10cSrcweir return mbInitialized;
495cdf0e10cSrcweir }
496cdf0e10cSrcweir
isValid() const497cdf0e10cSrcweir 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
getID()516cdf0e10cSrcweir rtl::OUString Model::getID()
517cdf0e10cSrcweir throw( RuntimeException )
518cdf0e10cSrcweir {
519cdf0e10cSrcweir DBG_INVARIANT();
520cdf0e10cSrcweir return msID;
521cdf0e10cSrcweir }
522cdf0e10cSrcweir
setID(const rtl::OUString & sID)523cdf0e10cSrcweir void Model::setID( const rtl::OUString& sID )
524cdf0e10cSrcweir throw( RuntimeException )
525cdf0e10cSrcweir {
526cdf0e10cSrcweir DBG_INVARIANT();
527cdf0e10cSrcweir msID = sID;
528cdf0e10cSrcweir }
529cdf0e10cSrcweir
initialize()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
rebuild()543cdf0e10cSrcweir void Model::rebuild()
544cdf0e10cSrcweir throw( RuntimeException )
545cdf0e10cSrcweir {
546cdf0e10cSrcweir if( ! mbInitialized )
547cdf0e10cSrcweir initialize();
548cdf0e10cSrcweir else
549cdf0e10cSrcweir rebind();
550cdf0e10cSrcweir }
551cdf0e10cSrcweir
recalculate()552cdf0e10cSrcweir void Model::recalculate()
553cdf0e10cSrcweir throw( RuntimeException )
554cdf0e10cSrcweir {
555cdf0e10cSrcweir rebind();
556cdf0e10cSrcweir }
557cdf0e10cSrcweir
revalidate()558cdf0e10cSrcweir void Model::revalidate()
559cdf0e10cSrcweir throw( RuntimeException )
560cdf0e10cSrcweir {
561cdf0e10cSrcweir // do nothing. We don't validate anyways!
562cdf0e10cSrcweir }
563cdf0e10cSrcweir
refresh()564cdf0e10cSrcweir void Model::refresh()
565cdf0e10cSrcweir throw( RuntimeException )
566cdf0e10cSrcweir {
567cdf0e10cSrcweir rebind();
568cdf0e10cSrcweir }
569cdf0e10cSrcweir
570cdf0e10cSrcweir
submitWithInteraction(const rtl::OUString & sID,const XInteractionHandler_t & _rxHandler)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
submit(const rtl::OUString & sID)593cdf0e10cSrcweir void Model::submit( const rtl::OUString& sID )
594cdf0e10cSrcweir throw( VetoException, WrappedTargetException, RuntimeException )
595cdf0e10cSrcweir {
596cdf0e10cSrcweir submitWithInteraction( sID, NULL );
597cdf0e10cSrcweir }
598cdf0e10cSrcweir
getDataTypeRepository()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
getInstances()612cdf0e10cSrcweir Model::XSet_t Model::getInstances()
613cdf0e10cSrcweir throw( RuntimeException )
614cdf0e10cSrcweir {
615cdf0e10cSrcweir return mxInstances;
616cdf0e10cSrcweir }
617cdf0e10cSrcweir
getInstanceDocument(const rtl::OUString & rName)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
getDefaultInstance()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
createBinding()646cdf0e10cSrcweir Model::XPropertySet_t SAL_CALL Model::createBinding()
647cdf0e10cSrcweir throw( RuntimeException )
648cdf0e10cSrcweir {
649cdf0e10cSrcweir DBG_INVARIANT();
650cdf0e10cSrcweir return new Binding();
651cdf0e10cSrcweir }
652cdf0e10cSrcweir
cloneBinding(const XPropertySet_t & xBinding)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
getBinding(const rtl::OUString & sId)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
getBindings()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
createSubmission()682cdf0e10cSrcweir Model::XSubmission_t Model::createSubmission()
683cdf0e10cSrcweir throw( RuntimeException )
684cdf0e10cSrcweir {
685cdf0e10cSrcweir DBG_INVARIANT();
686cdf0e10cSrcweir return new Submission();
687cdf0e10cSrcweir }
688cdf0e10cSrcweir
cloneSubmission(const XPropertySet_t & xSubmission)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
getSubmission(const rtl::OUString & sId)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
getSubmissions()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
initializePropertySet()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
update()758cdf0e10cSrcweir void Model::update()
759cdf0e10cSrcweir throw( RuntimeException )
760cdf0e10cSrcweir {
761cdf0e10cSrcweir rebuild();
762cdf0e10cSrcweir }
763cdf0e10cSrcweir
764cdf0e10cSrcweir
getSomething(const IntSequence_t & xId)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
getImplementationId()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
operator <<=(com::sun::star::uno::Any & rAny,xforms::Model * pModel)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
operator >>=(xforms::Model * pModel,com::sun::star::uno::Any & rAny)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