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