| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_forms.hxx" |
| |
| #include "model.hxx" |
| |
| #include "model_helper.hxx" |
| #include "unohelper.hxx" |
| #include "binding.hxx" |
| #include "submission.hxx" |
| #include "mip.hxx" |
| #include "evaluationcontext.hxx" |
| #include "xmlhelper.hxx" |
| #include "datatyperepository.hxx" |
| #include "NameContainer.hxx" |
| |
| #include <rtl/ustring.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include <tools/debug.hxx> |
| |
| #include <comphelper/propertysetinfo.hxx> |
| #include <cppuhelper/typeprovider.hxx> |
| |
| #include <algorithm> |
| |
| // UNO classes |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> |
| #include <com/sun/star/lang/IllegalArgumentException.hpp> |
| #include <com/sun/star/xml/dom/XDocument.hpp> |
| #include <com/sun/star/xml/dom/XCharacterData.hpp> |
| #include <com/sun/star/xml/dom/NodeType.hpp> |
| #include <com/sun/star/xml/dom/XDocumentBuilder.hpp> |
| #include <com/sun/star/uno/Sequence.hxx> |
| #include <com/sun/star/ucb/XSimpleFileAccess.hpp> |
| #include <com/sun/star/beans/PropertyValue.hpp> |
| #include <com/sun/star/ucb/XSimpleFileAccess.hpp> |
| #include <com/sun/star/io/XInputStream.hpp> |
| |
| |
| using com::sun::star::lang::XMultiServiceFactory; |
| using com::sun::star::lang::XUnoTunnel; |
| using com::sun::star::beans::XPropertySet; |
| using com::sun::star::beans::PropertyValue; |
| using rtl::OUString; |
| using rtl::OUStringBuffer; |
| using com::sun::star::beans::PropertyVetoException; |
| using com::sun::star::beans::UnknownPropertyException; |
| using com::sun::star::util::VetoException; |
| using com::sun::star::lang::WrappedTargetException; |
| using com::sun::star::lang::IllegalArgumentException; |
| using com::sun::star::ucb::XSimpleFileAccess; |
| using com::sun::star::io::XInputStream; |
| |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::xml::dom; |
| using namespace xforms; |
| |
| |
| #if OSL_DEBUG_LEVEL > 1 |
| #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); |
| |
| #define DBG_INVARIANT() DBG_INVARIANT_TYPE(Model) |
| #else |
| #define DBG_INVARIANT_TYPE(TYPE) |
| #define DBG_INVARIANT() |
| #endif |
| |
| |
| |
| // |
| // The Model |
| // |
| |
| void Model::ensureAtLeastOneInstance() |
| { |
| if( ! mpInstances->hasItems() ) |
| { |
| // create a default instance |
| newInstance( OUString(), OUString(), true ); |
| } |
| } |
| |
| |
| |
| /** Model default constructor; create empty model */ |
| Model::Model() : |
| msID(), |
| mpBindings( NULL ), |
| mpSubmissions( NULL ), |
| mpInstances( new InstanceCollection ), |
| mxNamespaces( new NameContainer<OUString>() ), |
| mxBindings( mpBindings ), |
| mxSubmissions( mpSubmissions ), |
| mxInstances( mpInstances ), |
| mbInitialized( false ), |
| mbExternalData( true ) |
| { |
| initializePropertySet(); |
| |
| // initialize bindings collections |
| // (not in initializer list to avoid use of incomplete 'this') |
| mpBindings = new BindingCollection( this ); |
| mxBindings = mpBindings; |
| |
| mpSubmissions = new SubmissionCollection( this ); |
| mxSubmissions = mpSubmissions; |
| |
| // invariant only holds after construction |
| DBG_INVARIANT(); |
| } |
| |
| Model::~Model() throw() |
| { |
| // give up bindings & submissions; the mxBindings/mxSubmissions |
| // references will then delete them |
| mpBindings = NULL; |
| mpSubmissions = NULL; |
| } |
| |
| Model* lcl_getModel( const Reference<XUnoTunnel>& xTunnel ) |
| { |
| Model* pModel = NULL; |
| if( xTunnel.is() ) |
| pModel = reinterpret_cast<Model*>( |
| xTunnel->getSomething( Model::getUnoTunnelID() ) ); |
| return pModel; |
| } |
| |
| Model* Model::getModel( const Reference<XModel>& xModel ) |
| { |
| return lcl_getModel( Reference<XUnoTunnel>( xModel, UNO_QUERY ) ); |
| } |
| |
| EvaluationContext Model::getEvaluationContext() |
| { |
| // the default context is the top-level element node. A default |
| // node (instanceData' is inserted when there is no default node |
| Reference<XDocument> xInstance = getDefaultInstance(); |
| Reference<XNode> xElement( xInstance->getDocumentElement(), UNO_QUERY ); |
| |
| // no element found? Then insert default element 'instanceData' |
| if( ! xElement.is() ) |
| { |
| xElement = Reference<XNode>( |
| xInstance->createElement( OUSTRING("instanceData") ), |
| UNO_QUERY_THROW ); |
| Reference<XNode>( xInstance, UNO_QUERY_THROW)->appendChild( xElement ); |
| } |
| |
| OSL_ENSURE( xElement.is() && |
| xElement->getNodeType() == NodeType_ELEMENT_NODE, |
| "no element in evaluation context" ); |
| |
| return EvaluationContext( xElement, this, mxNamespaces, 0, 1 ); |
| } |
| |
| |
| Model::IntSequence_t Model::getUnoTunnelID() |
| { |
| static cppu::OImplementationId aImplementationId; |
| return aImplementationId.getImplementationId(); |
| } |
| |
| Model::XDocument_t Model::getForeignSchema() const |
| { |
| return mxForeignSchema; |
| } |
| |
| void Model::setForeignSchema( const XDocument_t& rDocument ) |
| { |
| mxForeignSchema = rDocument; |
| } |
| |
| rtl::OUString Model::getSchemaRef() const |
| { |
| return msSchemaRef; |
| } |
| |
| void Model::setSchemaRef( const rtl::OUString& rSchemaRef ) |
| { |
| msSchemaRef = rSchemaRef; |
| } |
| |
| Model::XNameContainer_t Model::getNamespaces() const |
| { |
| return mxNamespaces; |
| } |
| |
| void Model::setNamespaces( const XNameContainer_t& rNamespaces ) |
| { |
| if( rNamespaces.is() ) |
| mxNamespaces = rNamespaces; |
| } |
| |
| bool Model::getExternalData() const |
| { |
| return mbExternalData; |
| } |
| |
| void Model::setExternalData( bool _bData ) |
| { |
| mbExternalData = _bData; |
| } |
| |
| #if OSL_DEBUG_LEVEL > 1 |
| void Model::dbg_assertInvariant() const |
| { |
| OSL_ENSURE( mpInstances != NULL, "no instances found" ); |
| OSL_ENSURE( mxInstances.is(), "No instance container!" ); |
| // OSL_ENSURE( mxInstances->hasElements(), "no instance!" ); |
| |
| OSL_ENSURE( mpBindings != NULL, "no bindings element" ); |
| OSL_ENSURE( mxBindings.is(), "No Bindings container" ); |
| |
| OSL_ENSURE( mpSubmissions != NULL, "no submissions element" ); |
| OSL_ENSURE( mxSubmissions.is(), "No Submission container" ); |
| |
| |
| |
| /* |
| // check bindings, and things that have to do with our binding |
| std::vector<MIP*> aAllMIPs; // check MIP map |
| sal_Int32 nCount = mpBindings->countItems(); |
| for( sal_Int32 i = 0; i < nCount; i++ ) |
| { |
| Binding* pBind = Binding::getBinding( |
| mpBindings->Collection<XPropertySet_t>::getItem( i ) ); |
| |
| // examine and check binding |
| OSL_ENSURE( pBind != NULL, "invalid binding found" ); |
| |
| OSL_ENSURE( Model::getModel( pBind->getModel() ) == this, |
| "our binding doesn't know us."); |
| // check this binding's MIP against MIP map |
| MIP* pMIP = const_cast<MIP*>( pBind->_getMIP() ); |
| sal_Int32 nFound = 0; |
| if( pMIP != NULL ) |
| { |
| aAllMIPs.push_back( pMIP ); |
| for( MIPs_t::const_iterator aIter = maMIPs.begin(); |
| aIter != maMIPs.end(); |
| aIter++ ) |
| { |
| if( pMIP == aIter->second ) |
| nFound++; |
| } |
| } |
| OSL_ENSURE( ( pMIP == NULL ) == ( nFound == 0 ), "MIP-map wrong" ); |
| } |
| |
| // check MIP map for left-over MIPs |
| for( MIPs_t::const_iterator aIter = maMIPs.begin(); |
| aIter != maMIPs.end(); |
| aIter++ ) |
| { |
| MIP* pMIP = aIter->second; |
| std::vector<MIP*>::iterator aFound = |
| std::find( aAllMIPs.begin(), aAllMIPs.end(), pMIP ); |
| if( aFound != aAllMIPs.end() ) |
| aAllMIPs.erase( aFound ); |
| } |
| OSL_ENSURE( aAllMIPs.empty(), "lonely MIPs found!" ); |
| */ |
| } |
| #endif |
| |
| |
| // |
| // MIP managment |
| // |
| |
| void Model::addMIP( void* pTag, const XNode_t& xNode, const MIP& rMIP ) |
| { |
| OSL_ENSURE( pTag != NULL, "empty tag?" ); |
| OSL_ENSURE( xNode.is(), "no node" ); |
| |
| MIPs_t::value_type aValue( xNode, ::std::pair<void*,MIP>( pTag, rMIP ) ); |
| maMIPs.insert( aValue ); |
| } |
| |
| void Model::removeMIPs( void* pTag ) |
| { |
| OSL_ENSURE( pTag != NULL, "empty tag?" ); |
| |
| for( MIPs_t::iterator aIter = maMIPs.begin(); |
| aIter != maMIPs.end(); ) |
| { |
| if( aIter->second.first == pTag ) |
| { |
| MIPs_t::iterator next( aIter ); ++next; |
| maMIPs.erase( aIter ); |
| aIter = next; |
| } |
| else |
| ++aIter; |
| } |
| } |
| |
| MIP Model::queryMIP( const XNode_t& xNode ) const |
| { |
| // OSL_ENSURE( xNode.is(), "no node" ); |
| |
| // travel up inheritance chain and inherit MIPs |
| MIP aRet; |
| for( XNode_t xCurrent = xNode; |
| xCurrent.is(); |
| xCurrent = xCurrent->getParentNode() ) |
| { |
| // iterate over all MIPs for this node, and join MIPs |
| MIP aMIP; |
| MIPs_t::const_iterator aEnd = maMIPs.upper_bound( xCurrent ); |
| MIPs_t::const_iterator aIter = maMIPs.lower_bound( xCurrent ); |
| for( ; aIter != aEnd; aIter++ ) |
| aMIP.join( aIter->second.second ); |
| |
| // inherit from current node (or set if we are at the start node) |
| if( xCurrent == xNode ) |
| aRet = aMIP; |
| else |
| aRet.inherit( aMIP ); |
| } |
| |
| return aRet; |
| } |
| |
| |
| |
| void Model::rebind() |
| { |
| OSL_ENSURE( mpBindings != NULL, "bindings?" ); |
| |
| // iterate over all bindings and call update |
| sal_Int32 nCount = mpBindings->countItems(); |
| for( sal_Int32 i = 0; i < nCount; i++ ) |
| { |
| Binding* pBind = Binding::getBinding( mpBindings->Collection<XPropertySet_t>::getItem( i ) ); |
| OSL_ENSURE( pBind != NULL, "binding?" ); |
| pBind->update(); |
| } |
| } |
| |
| |
| |
| void Model::deferNotifications( bool bDefer ) |
| { |
| // iterate over all bindings and defer notifications |
| sal_Int32 nCount = mpBindings->countItems(); |
| for( sal_Int32 i = 0; i < nCount; i++ ) |
| { |
| Binding* pBind = Binding::getBinding( mpBindings->Collection<XPropertySet_t>::getItem( i ) ); |
| OSL_ENSURE( pBind != NULL, "binding?" ); |
| pBind->deferNotifications( bDefer ); |
| } |
| } |
| |
| |
| bool Model::setSimpleContent( const XNode_t& xConstNode, |
| const rtl::OUString& sValue ) |
| { |
| OSL_ENSURE( xConstNode.is(), "need node to set data" ); |
| |
| bool bRet = false; |
| if( xConstNode.is() ) |
| { |
| // non-const node reference so we can assign children (if necessary) |
| XNode_t xNode( xConstNode ); |
| |
| switch( xNode->getNodeType() ) |
| { |
| case NodeType_ELEMENT_NODE: |
| { |
| // find first text node child |
| Reference<XNode> xChild; |
| for( xChild = xNode->getFirstChild(); |
| xChild.is() && xChild->getNodeType() != NodeType_TEXT_NODE; |
| xChild = xChild->getNextSibling() ) |
| ; // empty loop; only find first text node child |
| |
| // create text node, if none is found |
| if( ! xChild.is() ) |
| { |
| xChild = Reference<XNode>( |
| xNode->getOwnerDocument()->createTextNode( OUString() ), |
| UNO_QUERY_THROW ); |
| xNode->appendChild( xChild ); |
| } |
| xNode = xChild; |
| |
| OSL_ENSURE( xNode.is() && |
| xNode->getNodeType() == NodeType_TEXT_NODE, |
| "text node creation failed?" ); |
| } |
| // no break; continue as with text node: |
| |
| case NodeType_TEXT_NODE: |
| case NodeType_ATTRIBUTE_NODE: |
| { |
| // set the node value (defer notifications) |
| if( xNode->getNodeValue() != sValue ) |
| { |
| deferNotifications( true ); |
| xNode->setNodeValue( sValue ); |
| deferNotifications( false ); |
| } |
| bRet = true; |
| } |
| break; |
| |
| default: |
| { |
| OSL_ENSURE( false, "bound to unknown node type?" ); |
| } |
| break; |
| |
| } |
| } |
| return bRet; |
| } |
| |
| void Model::loadInstance( sal_Int32 nInstance ) |
| { |
| Sequence<PropertyValue> aSequence = mpInstances->getItem( nInstance ); |
| |
| // find URL from instance |
| OUString sURL; |
| bool bOnce = false; |
| getInstanceData( aSequence, NULL, NULL, &sURL, &bOnce ); |
| |
| // if we have a URL, load the document and set it into the instance |
| if( sURL.getLength() > 0 ) |
| { |
| try |
| { |
| Reference<XInputStream> xInput = |
| Reference<XSimpleFileAccess>( |
| createInstance( |
| OUSTRING("com.sun.star.ucb.SimpleFileAccess") ), |
| UNO_QUERY_THROW )->openFileRead( sURL ); |
| if( xInput.is() ) |
| { |
| Reference<XDocument> xInstance = |
| getDocumentBuilder()->parse( xInput ); |
| if( xInstance.is() ) |
| { |
| OUString sEmpty; |
| setInstanceData( aSequence, NULL, &xInstance, |
| bOnce ? &sEmpty : &sURL, NULL); |
| mpInstances->setItem( nInstance, aSequence ); |
| } |
| } |
| } |
| catch( const Exception& ) |
| { |
| // couldn't load the instance -> ignore! |
| } |
| } |
| } |
| |
| void Model::loadInstances() |
| { |
| // iterate over instance array to get PropertyValue-Sequence |
| const sal_Int32 nInstances = mpInstances->countItems(); |
| for( sal_Int32 nInstance = 0; nInstance < nInstances; nInstance++ ) |
| { |
| loadInstance( nInstance ); |
| } |
| } |
| |
| bool Model::isInitialized() const |
| { |
| return mbInitialized; |
| } |
| |
| bool Model::isValid() const |
| { |
| bool bValid = true; |
| sal_Int32 nCount = mpBindings->countItems(); |
| for( sal_Int32 i = 0; bValid && i < nCount; i++ ) |
| { |
| Binding* pBind = Binding::getBinding( mpBindings->Collection<XPropertySet_t>::getItem( i ) ); |
| OSL_ENSURE( pBind != NULL, "binding?" ); |
| bValid = pBind->isValid(); |
| } |
| return bValid; |
| } |
| |
| |
| |
| // |
| // implement xforms::XModel |
| // |
| |
| rtl::OUString Model::getID() |
| throw( RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| return msID; |
| } |
| |
| void Model::setID( const rtl::OUString& sID ) |
| throw( RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| msID = sID; |
| } |
| |
| void Model::initialize() |
| throw( RuntimeException ) |
| { |
| DBG_ASSERT( ! mbInitialized, "model already initialized" ); |
| |
| // load instances |
| loadInstances(); |
| |
| // let's pretend we're initialized and rebind all bindings |
| mbInitialized = true; |
| rebind(); |
| } |
| |
| void Model::rebuild() |
| throw( RuntimeException ) |
| { |
| if( ! mbInitialized ) |
| initialize(); |
| else |
| rebind(); |
| } |
| |
| void Model::recalculate() |
| throw( RuntimeException ) |
| { |
| rebind(); |
| } |
| |
| void Model::revalidate() |
| throw( RuntimeException ) |
| { |
| // do nothing. We don't validate anyways! |
| } |
| |
| void Model::refresh() |
| throw( RuntimeException ) |
| { |
| rebind(); |
| } |
| |
| |
| void SAL_CALL Model::submitWithInteraction( |
| const rtl::OUString& sID, |
| const XInteractionHandler_t& _rxHandler ) |
| throw( VetoException, |
| WrappedTargetException, |
| RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| |
| if( mpSubmissions->hasItem( sID ) ) |
| { |
| Submission* pSubmission = |
| Submission::getSubmission( mpSubmissions->getItem( sID ) ); |
| OSL_ENSURE( pSubmission != NULL, "no submission?" ); |
| OSL_ENSURE( pSubmission->getModel() == Reference<XModel>( this ), |
| "wrong model" ); |
| |
| // submit. All exceptions are allowed to leave. |
| pSubmission->submitWithInteraction( _rxHandler ); |
| } |
| } |
| |
| void Model::submit( const rtl::OUString& sID ) |
| throw( VetoException, WrappedTargetException, RuntimeException ) |
| { |
| submitWithInteraction( sID, NULL ); |
| } |
| |
| Model::XDataTypeRepository_t SAL_CALL Model::getDataTypeRepository( ) |
| throw( RuntimeException ) |
| { |
| if ( !mxDataTypes.is() ) |
| mxDataTypes = new ODataTypeRepository; |
| |
| return mxDataTypes; |
| } |
| |
| // |
| // instance management |
| // |
| |
| Model::XSet_t Model::getInstances() |
| throw( RuntimeException ) |
| { |
| return mxInstances; |
| } |
| |
| Model::XDocument_t Model::getInstanceDocument( const rtl::OUString& rName ) |
| throw( RuntimeException ) |
| { |
| ensureAtLeastOneInstance(); |
| Reference<XDocument> aInstance; |
| sal_Int32 nInstance = lcl_findInstance( mpInstances, rName ); |
| if( nInstance != -1 ) |
| getInstanceData( mpInstances->getItem( nInstance ), |
| NULL, &aInstance, NULL, NULL ); |
| return aInstance; |
| } |
| |
| Model::XDocument_t SAL_CALL Model::getDefaultInstance() |
| throw( RuntimeException ) |
| { |
| ensureAtLeastOneInstance(); |
| DBG_ASSERT( mpInstances->countItems() > 0, "no instance?" ); |
| Reference<XDocument> aInstance; |
| getInstanceData( mpInstances->getItem( 0 ), NULL, &aInstance, NULL, NULL ); |
| return aInstance; |
| } |
| |
| |
| |
| // |
| // bindings management |
| // |
| |
| Model::XPropertySet_t SAL_CALL Model::createBinding() |
| throw( RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| return new Binding(); |
| } |
| |
| Model::XPropertySet_t Model::cloneBinding( const XPropertySet_t& xBinding ) |
| throw( RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| XPropertySet_t xNewBinding = createBinding(); |
| copy( xBinding, xNewBinding ); |
| return xNewBinding; |
| } |
| |
| Model::XPropertySet_t Model::getBinding( const rtl::OUString& sId ) |
| throw( RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| return mpBindings->hasItem( sId ) ? mpBindings->getItem( sId ) : NULL; |
| } |
| |
| Model::XSet_t Model::getBindings() |
| throw( RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| return mxBindings; |
| } |
| |
| |
| |
| // |
| // submission management |
| // |
| |
| Model::XSubmission_t Model::createSubmission() |
| throw( RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| return new Submission(); |
| } |
| |
| Model::XSubmission_t Model::cloneSubmission(const XPropertySet_t& xSubmission) |
| throw( RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| XSubmission_t xNewSubmission = createSubmission(); |
| XPropertySet_t xAsPropertySet( xNewSubmission.get() ); |
| copy( xSubmission.get(), xAsPropertySet ); |
| return xNewSubmission; |
| } |
| |
| Model::XSubmission_t Model::getSubmission( const rtl::OUString& sId ) |
| throw( RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| XSubmission_t xSubmission; |
| if ( mpSubmissions->hasItem( sId ) ) |
| xSubmission = xSubmission.query( mpSubmissions->getItem( sId ) ); |
| return xSubmission; |
| } |
| |
| Model::XSet_t Model::getSubmissions() |
| throw( RuntimeException ) |
| { |
| DBG_INVARIANT(); |
| return mxSubmissions; |
| } |
| |
| |
| |
| // |
| // implementation of XFormsUIHelper1 interface |
| // can be found in file model_ui.cxx |
| // |
| |
| |
| |
| // |
| // implement XPropertySet & friends |
| // |
| |
| #define HANDLE_ID 0 |
| #define HANDLE_Instance 1 |
| #define HANDLE_InstanceURL 2 |
| #define HANDLE_ForeignSchema 3 |
| #define HANDLE_SchemaRef 4 |
| #define HANDLE_Namespaces 5 |
| #define HANDLE_ExternalData 6 |
| |
| #define REGISTER_PROPERTY( property, type ) \ |
| registerProperty( PROPERTY( property, type ), \ |
| new DirectPropertyAccessor< Model, type >( this, &Model::set##property, &Model::get##property ) ); |
| |
| #define REGISTER_PROPERTY_API( property, type ) \ |
| registerProperty( PROPERTY( property, type ), \ |
| new APIPropertyAccessor< Model, type >( this, &Model::set##property, &Model::get##property ) ); |
| |
| #define REGISTER_BOOL_PROPERTY( property ) \ |
| registerProperty( PROPERTY( property, sal_Bool ), \ |
| new BooleanPropertyAccessor< Model, bool >( this, &Model::set##property, &Model::get##property ) ); |
| |
| void Model::initializePropertySet() |
| { |
| REGISTER_PROPERTY_API ( ID, OUString ); |
| REGISTER_PROPERTY ( ForeignSchema, XDocument_t ); |
| REGISTER_PROPERTY ( SchemaRef, OUString ); |
| REGISTER_PROPERTY ( Namespaces, XNameContainer_t ); |
| REGISTER_BOOL_PROPERTY( ExternalData ); |
| } |
| |
| void Model::update() |
| throw( RuntimeException ) |
| { |
| rebuild(); |
| } |
| |
| |
| sal_Int64 Model::getSomething( const IntSequence_t& xId ) |
| throw( RuntimeException ) |
| { |
| return reinterpret_cast<sal_Int64>( ( xId == getUnoTunnelID() ) ? this : NULL ); |
| } |
| |
| Sequence<sal_Int8> Model::getImplementationId() |
| throw( RuntimeException ) |
| { |
| return getUnoTunnelID(); |
| } |
| |
| |
| // |
| // 'shift' operators for getting data into and out of Anys |
| // |
| |
| void operator <<= ( com::sun::star::uno::Any& rAny, |
| xforms::Model* pModel) |
| { |
| Reference<XPropertySet> xPropSet( static_cast<XPropertySet*>( pModel ) ); |
| rAny <<= xPropSet; |
| } |
| |
| bool operator >>= ( xforms::Model* pModel, |
| com::sun::star::uno::Any& rAny ) |
| { |
| bool bRet = false; |
| |
| // acquire model pointer through XUnoTunnel |
| Reference<XUnoTunnel> xTunnel( rAny, UNO_QUERY ); |
| if( xTunnel.is() ) |
| { |
| pModel = reinterpret_cast<xforms::Model*>( |
| xTunnel->getSomething( xforms::Model::getUnoTunnelID() ) ); |
| bRet = true; |
| } |
| |
| return bRet; |
| } |