| /************************************************************** |
| * |
| * 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_xmlsecurity.hxx" |
| |
| #include "saxeventkeeperimpl.hxx" |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/xml/sax/XDocumentHandler.hpp> |
| #include <com/sun/star/xml/crypto/sax/ConstOfSecurityId.hpp> |
| |
| namespace cssu = com::sun::star::uno; |
| namespace cssl = com::sun::star::lang; |
| namespace cssxc = com::sun::star::xml::crypto; |
| namespace cssxcsax = com::sun::star::xml::csax; |
| namespace cssxw = com::sun::star::xml::wrapper; |
| namespace cssxs = com::sun::star::xml::sax; |
| |
| #define SERVICE_NAME "com.sun.star.xml.crypto.sax.SAXEventKeeper" |
| #define IMPLEMENTATION_NAME "com.sun.star.xml.security.framework.SAXEventKeeperImpl" |
| |
| #define _USECOMPRESSEDDOCUMENTHANDLER |
| |
| SAXEventKeeperImpl::SAXEventKeeperImpl( ) |
| :m_pRootBufferNode(NULL), |
| m_pCurrentBufferNode(NULL), |
| m_nNextElementMarkId(1), |
| m_pNewBlocker(NULL), |
| m_pCurrentBlockingBufferNode(NULL), |
| m_bIsReleasing(false), |
| m_bIsForwarding(false) |
| { |
| m_vElementMarkBuffers.reserve(2); |
| m_vNewElementCollectors.reserve(2); |
| m_vReleasedElementMarkBuffers.reserve(2); |
| } |
| |
| SAXEventKeeperImpl::~SAXEventKeeperImpl() |
| { |
| /* |
| * delete the BufferNode tree |
| */ |
| if (m_pRootBufferNode != NULL) |
| { |
| m_pRootBufferNode->freeAllChildren(); |
| delete m_pRootBufferNode; |
| } |
| |
| m_pRootBufferNode = m_pCurrentBufferNode = m_pCurrentBlockingBufferNode = NULL; |
| |
| /* |
| * delete all unfreed ElementMarks |
| */ |
| m_vNewElementCollectors.clear(); |
| m_pNewBlocker = NULL; |
| |
| std::vector< const ElementMark* >::const_iterator ii = m_vElementMarkBuffers.begin(); |
| for( ; ii != m_vElementMarkBuffers.end(); ++ii ) |
| { |
| delete (*ii); |
| } |
| m_vElementMarkBuffers.clear(); |
| } |
| |
| void SAXEventKeeperImpl::setCurrentBufferNode(BufferNode* pBufferNode) |
| /****** SAXEventKeeperImpl/setCurrentBufferNode ****************************** |
| * |
| * NAME |
| * setCurrentBufferNode -- set a new active BufferNode. |
| * |
| * SYNOPSIS |
| * setCurrentBufferNode( pBufferNode ); |
| * |
| * FUNCTION |
| * connects this BufferNode into the BufferNode tree as a child of the |
| * current active BufferNode. Then makes this BufferNode as the current |
| * active BufferNode. |
| * If the previous active BufferNode points to the root |
| * BufferNode, which means that no buffering operation was proceeding, |
| * then notifies the status change listener that buffering operation |
| * will begin at once. |
| * |
| * INPUTS |
| * pBufferNode - a BufferNode which will be the new active BufferNode |
| * |
| * RESULT |
| * empty |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| if (pBufferNode != m_pCurrentBufferNode) |
| { |
| if ( m_pCurrentBufferNode == m_pRootBufferNode && |
| m_xSAXEventKeeperStatusChangeListener.is()) |
| { |
| m_xSAXEventKeeperStatusChangeListener->collectionStatusChanged(sal_True); |
| } |
| |
| if (pBufferNode->getParent() == NULL) |
| { |
| m_pCurrentBufferNode->addChild(pBufferNode); |
| pBufferNode->setParent(m_pCurrentBufferNode); |
| } |
| |
| m_pCurrentBufferNode = pBufferNode; |
| } |
| } |
| |
| BufferNode* SAXEventKeeperImpl::addNewElementMarkBuffers() |
| /****** SAXEventKeeperImpl/addNewElementMarkBuffers ************************** |
| * |
| * NAME |
| * addNewElementMarkBuffers -- add new ElementCollectors and new Blocker. |
| * |
| * SYNOPSIS |
| * pBufferNode = addNewElementMarkBuffers( ); |
| * |
| * FUNCTION |
| * if there are new ElementCollector or new Blocker to be added, then |
| * connect all of them with the current BufferNode. In case of the |
| * current BufferNode doesn't exist, creates one. |
| * Clears up the new ElementCollector list and the new Blocker pointer. |
| * |
| * INPUTS |
| * empty |
| * |
| * RESULT |
| * pBufferNode - the BufferNode that has been connected with both new |
| * ElementCollectors and new Blocker. |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| BufferNode* pBufferNode = NULL; |
| |
| if ( (m_vNewElementCollectors.size()>0) || |
| (m_pNewBlocker != NULL)) |
| { |
| /* |
| * When the current BufferNode is right pointing to the current |
| * working element in the XMLDocumentWrapper component, then |
| * no new BufferNode is needed to create. |
| * This situation can only happen in the "Forwarding" mode. |
| */ |
| if ( (m_pCurrentBufferNode != NULL) && |
| (m_xXMLDocument->isCurrent(m_pCurrentBufferNode->getXMLElement()))) |
| { |
| pBufferNode = m_pCurrentBufferNode; |
| } |
| else |
| { |
| pBufferNode = new BufferNode(m_xXMLDocument->getCurrentElement()); |
| } |
| |
| if (m_pNewBlocker != NULL) |
| { |
| pBufferNode->setBlocker(m_pNewBlocker); |
| |
| /* |
| * If no blocking before, then notify the status change listener that |
| * the SAXEventKeeper has entered "blocking" status, during which, no |
| * SAX events will be forwarded to the next document handler. |
| */ |
| if (m_pCurrentBlockingBufferNode == NULL) |
| { |
| m_pCurrentBlockingBufferNode = pBufferNode; |
| |
| if (m_xSAXEventKeeperStatusChangeListener.is()) |
| { |
| m_xSAXEventKeeperStatusChangeListener->blockingStatusChanged(sal_True); |
| } |
| } |
| |
| m_pNewBlocker = NULL; |
| } |
| |
| if (m_vNewElementCollectors.size()>0) |
| { |
| std::vector< const ElementCollector* >::const_iterator ii = m_vNewElementCollectors.begin(); |
| |
| for( ; ii != m_vNewElementCollectors.end(); ++ii ) |
| { |
| pBufferNode->addElementCollector(*ii); |
| } |
| |
| m_vNewElementCollectors.clear(); |
| } |
| } |
| |
| return pBufferNode; |
| } |
| |
| ElementMark* SAXEventKeeperImpl::findElementMarkBuffer(sal_Int32 nId) const |
| /****** SAXEventKeeperImpl/findElementMarkBuffer ***************************** |
| * |
| * NAME |
| * findElementMarkBuffer -- finds an ElementMark. |
| * |
| * SYNOPSIS |
| * pElementMark = findElementMarkBuffer( nId ); |
| * |
| * FUNCTION |
| * searches an ElementMark with the particular Id in the ElementMark |
| * list. |
| * |
| * INPUTS |
| * nId - the Id of the ElementMark to be searched. |
| * |
| * RESULT |
| * pElementMark - the ElementMark with the particular Id, or NULL when |
| * no such Id exists. |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| ElementMark* pElementMark = NULL; |
| |
| std::vector< const ElementMark* >::const_iterator ii = m_vElementMarkBuffers.begin(); |
| |
| for( ; ii != m_vElementMarkBuffers.end(); ++ii ) |
| { |
| if ( nId == (*ii)->getBufferId()) |
| { |
| pElementMark = (ElementMark*)*ii; |
| break; |
| } |
| } |
| |
| return pElementMark; |
| } |
| |
| void SAXEventKeeperImpl::removeElementMarkBuffer(sal_Int32 nId) |
| /****** SAXEventKeeperImpl/removeElementMarkBuffer *************************** |
| * |
| * NAME |
| * removeElementMarkBuffer -- removes an ElementMark |
| * |
| * SYNOPSIS |
| * removeElementMarkBuffer( nId ); |
| * |
| * FUNCTION |
| * removes an ElementMark with the particular Id in the ElementMark list. |
| * |
| * INPUTS |
| * nId - the Id of the ElementMark to be removed. |
| * |
| * RESULT |
| * empty |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| std::vector< const ElementMark* >::iterator ii = m_vElementMarkBuffers.begin(); |
| |
| for( ; ii != m_vElementMarkBuffers.end(); ++ii ) |
| { |
| if ( nId == (*ii)->getBufferId()) |
| { |
| /* |
| * checks whether this ElementMark still in the new ElementCollect array |
| */ |
| std::vector< const ElementCollector* >::iterator jj = m_vNewElementCollectors.begin(); |
| for( ; jj != m_vNewElementCollectors.end(); ++jj ) |
| { |
| if ((*ii) == (*jj)) |
| { |
| m_vNewElementCollectors.erase(jj); |
| break; |
| } |
| } |
| |
| /* |
| * checks whether this ElementMark is the new Blocker |
| */ |
| if ((*ii) == m_pNewBlocker) |
| { |
| m_pNewBlocker = NULL; |
| } |
| |
| /* |
| * destory the ElementMark |
| */ |
| delete (*ii); |
| |
| m_vElementMarkBuffers.erase( ii ); |
| break; |
| } |
| } |
| } |
| |
| rtl::OUString SAXEventKeeperImpl::printBufferNode( |
| BufferNode* pBufferNode, sal_Int32 nIndent) const |
| /****** SAXEventKeeperImpl/printBufferNode *********************************** |
| * |
| * NAME |
| * printBufferNode -- retrieves the information of a BufferNode and its |
| * branch. |
| * |
| * SYNOPSIS |
| * info = printBufferNode( pBufferNode, nIndent ); |
| * |
| * FUNCTION |
| * all retrieved information includes: |
| * 1. whether it is the current BufferNode; |
| * 2. whether it is the current blocking BufferNode; |
| * 3. the name of the parent element; |
| * 4. the name of this element; |
| * 5. all ElementCollectors working on this BufferNode; |
| * 6. the Blocker working on this BufferNode; |
| * 7. all child BufferNodes' information. |
| * |
| * INPUTS |
| * pBufferNode - the BufferNode from where information will be retrieved. |
| * nIndent - how many space characters prefixed before the output |
| * message. |
| * |
| * RESULT |
| * info - the information string |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| rtl::OUString rc; |
| |
| for ( int i=0; i<nIndent; ++i ) |
| { |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); |
| } |
| |
| if (pBufferNode == m_pCurrentBufferNode) |
| { |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[%]" )); |
| } |
| |
| if (pBufferNode == m_pCurrentBlockingBufferNode) |
| { |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[B]" )); |
| } |
| |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); |
| rc += m_xXMLDocument->getNodeName(pBufferNode->getXMLElement()); |
| |
| BufferNode* pParent = (BufferNode*)pBufferNode->getParent(); |
| if (pParent != NULL) |
| { |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[" )); |
| rc += m_xXMLDocument->getNodeName(pParent->getXMLElement()); |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "]" )); |
| } |
| |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":EC=" )); |
| rc += pBufferNode->printChildren(); |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " BR=" )); |
| |
| ElementMark * pBlocker = pBufferNode->getBlocker(); |
| if (pBlocker != NULL) |
| { |
| rc += rtl::OUString::valueOf( pBlocker->getBufferId() ); |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "(SecId=" )); |
| rc += rtl::OUString::valueOf( pBlocker->getSecurityId() ); |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" )); |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); |
| } |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" )); |
| |
| std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren(); |
| std::vector< const BufferNode* >::const_iterator jj = vChildren->begin(); |
| for( ; jj != vChildren->end(); ++jj ) |
| { |
| rc += printBufferNode((BufferNode *)*jj, nIndent+4); |
| } |
| |
| delete vChildren; |
| |
| return rc; |
| } |
| |
| cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > > |
| SAXEventKeeperImpl::collectChildWorkingElement(BufferNode* pBufferNode) const |
| /****** SAXEventKeeperImpl/collectChildWorkingElement ************************ |
| * |
| * NAME |
| * collectChildWorkingElement -- collects a BufferNode's all child |
| * Elements. |
| * |
| * SYNOPSIS |
| * list = collectChildWorkingElement( pBufferNode ); |
| * |
| * FUNCTION |
| * see NAME. |
| * |
| * INPUTS |
| * pBufferNode - the BufferNode whose child Elements will be collected. |
| * |
| * RESULT |
| * list - the child Elements list. |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren(); |
| |
| cssu::Sequence < cssu::Reference< |
| cssxw::XXMLElementWrapper > > aChildrenCollection ( vChildren->size()); |
| |
| std::vector< const BufferNode* >::const_iterator ii = vChildren->begin(); |
| |
| sal_Int32 nIndex = 0; |
| for( ; ii != vChildren->end(); ++ii ) |
| { |
| aChildrenCollection[nIndex] = (*ii)->getXMLElement(); |
| nIndex++; |
| } |
| |
| delete vChildren; |
| |
| return aChildrenCollection; |
| } |
| |
| void SAXEventKeeperImpl::smashBufferNode( |
| BufferNode* pBufferNode, bool bClearRoot) const |
| /****** SAXEventKeeperImpl/smashBufferNode *********************************** |
| * |
| * NAME |
| * smashBufferNode -- removes a BufferNode along with its working |
| * element. |
| * |
| * SYNOPSIS |
| * smashBufferNode( pBufferNode, bClearRoot ); |
| * |
| * FUNCTION |
| * removes the BufferNode's working element from the DOM document, while |
| * reserves all ancestor paths for its child BufferNodes. |
| * when any of the BufferNode's ancestor element is useless, removes it |
| * too. |
| * removes the BufferNode from the BufferNode tree. |
| * |
| * INPUTS |
| * pBufferNode - the BufferNode to be removed |
| * bClearRoot - whether the root element also needs to be cleared up. |
| * |
| * RESULT |
| * empty |
| * |
| * NOTES |
| * when removeing a Blocker's BufferNode, the bClearRoot flag should be |
| * true. Because a Blocker can buffer many SAX events which are not used |
| * by any other ElementCollector or Blocker. |
| * When the bClearRoot is set to true, the root BufferNode will be first |
| * cleared, with a stop flag seting at the next Blocking BufferNode. This |
| * operation can delete all useless bufferred SAX events which are only |
| * needed by the Blocker to be deleted. |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| if (!pBufferNode->hasAnything()) |
| { |
| BufferNode* pParent = (BufferNode*)pBufferNode->getParent(); |
| |
| /* |
| * delete the XML data |
| */ |
| if (pParent == m_pRootBufferNode) |
| { |
| bool bIsNotBlocking = (m_pCurrentBlockingBufferNode == NULL); |
| bool bIsBlockInside = false; |
| bool bIsBlockingAfterward = false; |
| |
| /* |
| * If this is a blocker, then remove any out-element data |
| * which caused by blocking. The removal process will stop |
| * at the next blokcer to avoid removing any useful data. |
| */ |
| if (bClearRoot) |
| { |
| cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > > |
| aChildElements = collectChildWorkingElement(m_pRootBufferNode); |
| |
| /* |
| * the clearUselessData only clearup the content in the |
| * node, not the node itself. |
| */ |
| m_xXMLDocument->clearUselessData(m_pRootBufferNode->getXMLElement(), |
| aChildElements, |
| bIsNotBlocking?(NULL): |
| (m_pCurrentBlockingBufferNode->getXMLElement())); |
| |
| /* |
| * remove the node if it is empty, then if its parent is also |
| * empty, remove it, then if the next parent is also empty, |
| * remove it,..., until parent become null. |
| */ |
| m_xXMLDocument->collapse( m_pRootBufferNode->getXMLElement() ); |
| } |
| |
| /* |
| * if blocking, check the relationship between this BufferNode and |
| * the current blocking BufferNode. |
| */ |
| if ( !bIsNotBlocking ) |
| { |
| /* |
| * the current blocking BufferNode is a descendant of this BufferNode. |
| */ |
| bIsBlockInside = (NULL != pBufferNode->isAncestor(m_pCurrentBlockingBufferNode)); |
| |
| /* |
| * the current blocking BufferNode locates behind this BufferNode in tree |
| * order. |
| */ |
| bIsBlockingAfterward = pBufferNode->isPrevious(m_pCurrentBlockingBufferNode); |
| } |
| |
| /* |
| * this BufferNode's working element needs to be deleted only when |
| * 1. there is no blocking, or |
| * 2. the current blocking BufferNode is a descendant of this BufferNode, |
| * (then in the BufferNode's working element, the useless data before the blocking |
| * element should be deleted.) or |
| * 3. the current blocking BufferNode is locates behind this BufferNode in tree, |
| * (then the useless data between the blocking element and the working element |
| * should be deleted.). |
| * Otherwise, this working element should not be deleted. |
| */ |
| if ( bIsNotBlocking || bIsBlockInside || bIsBlockingAfterward ) |
| { |
| cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > > |
| aChildElements = collectChildWorkingElement(pBufferNode); |
| |
| /* |
| * the clearUselessData only clearup the content in the |
| * node, not the node itself. |
| */ |
| m_xXMLDocument->clearUselessData(pBufferNode->getXMLElement(), |
| aChildElements, |
| bIsBlockInside?(m_pCurrentBlockingBufferNode->getXMLElement()): |
| (NULL)); |
| |
| /* |
| * remove the node if it is empty, then if its parent is also |
| * empty, remove it, then if the next parent is also empty, |
| * remove it,..., until parent become null. |
| */ |
| m_xXMLDocument->collapse( pBufferNode->getXMLElement() ); |
| } |
| } |
| |
| sal_Int32 nIndex = pParent->indexOfChild(pBufferNode); |
| |
| std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren(); |
| pParent->removeChild(pBufferNode); |
| pBufferNode->setParent(NULL); |
| |
| std::vector< const BufferNode * >::const_iterator ii = vChildren->begin(); |
| for( ; ii != vChildren->end(); ++ii ) |
| { |
| ((BufferNode *)(*ii))->setParent(pParent); |
| pParent->addChild(*ii, nIndex); |
| nIndex++; |
| } |
| |
| delete vChildren; |
| |
| /* |
| * delete the BufferNode |
| */ |
| delete pBufferNode; |
| } |
| } |
| |
| BufferNode* SAXEventKeeperImpl::findNextBlockingBufferNode( |
| BufferNode* pStartBufferNode) const |
| /****** SAXEventKeeperImpl/findNextBlockingBufferNode ************************ |
| * |
| * NAME |
| * findNextBlockingBufferNode -- finds the next blocking BufferNode |
| * behind the particular BufferNode. |
| * |
| * SYNOPSIS |
| * pBufferNode = findNextBlockingBufferNode( pStartBufferNode ); |
| * |
| * FUNCTION |
| * see NAME. |
| * |
| * INPUTS |
| * pStartBufferNode - the BufferNode from where to search the next |
| * blocking BufferNode. |
| * |
| * RESULT |
| * pBufferNode - the next blocking BufferNode, or NULL if no such |
| * BufferNode exists. |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| BufferNode* pNext = NULL; |
| |
| if (pStartBufferNode != NULL) |
| { |
| pNext = pStartBufferNode; |
| |
| while (NULL != (pNext = (BufferNode*)pNext->getNextNodeByTreeOrder())) |
| { |
| if (pNext->getBlocker() != NULL) |
| { |
| break; |
| } |
| } |
| } |
| |
| return pNext; |
| } |
| |
| void SAXEventKeeperImpl::diffuse(BufferNode* pBufferNode) const |
| /****** SAXEventKeeperImpl/diffuse ******************************************* |
| * |
| * NAME |
| * diffuse -- diffuse the notification. |
| * |
| * SYNOPSIS |
| * diffuse( pBufferNode ); |
| * |
| * FUNCTION |
| * diffuse the collecting completion notification from the specific |
| * BufferNode along its parent link, until an ancestor which is not |
| * completely received is met. |
| * |
| * INPUTS |
| * pBufferNode - the BufferNode from which the notification will be |
| * diffused. |
| * |
| * RESULT |
| * empty |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| BufferNode* pParent = pBufferNode; |
| |
| while(pParent->isAllReceived()) |
| { |
| pParent->elementCollectorNotify(); |
| pParent = (BufferNode*)pParent->getParent(); |
| } |
| } |
| |
| void SAXEventKeeperImpl::releaseElementMarkBuffer() |
| /****** SAXEventKeeperImpl/releaseElementMarkBuffer ************************** |
| * |
| * NAME |
| * releaseElementMarkBuffer -- releases useless ElementMarks |
| * |
| * SYNOPSIS |
| * releaseElementMarkBuffer( ); |
| * |
| * FUNCTION |
| * releases each ElementMark in the releasing list |
| * m_vReleasedElementMarkBuffers. |
| * The operation differs between an ElementCollector and a Blocker. |
| * |
| * INPUTS |
| * empty |
| * |
| * RESULT |
| * empty |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| m_bIsReleasing = true; |
| while (m_vReleasedElementMarkBuffers.size()>0) |
| { |
| std::vector< sal_Int32 >::iterator pId = m_vReleasedElementMarkBuffers.begin(); |
| sal_Int32 nId = *pId; |
| m_vReleasedElementMarkBuffers.erase( pId ); |
| |
| ElementMark* pElementMark = findElementMarkBuffer(nId); |
| |
| if (pElementMark != NULL) |
| { |
| if (cssxc::sax::ElementMarkType_ELEMENTCOLLECTOR |
| == pElementMark->getType()) |
| /* |
| * it is a EC |
| */ |
| { |
| ElementCollector* pElementCollector = (ElementCollector*)pElementMark; |
| |
| cssxc::sax::ElementMarkPriority nPriority = pElementCollector->getPriority(); |
| bool bToModify = pElementCollector->getModify(); |
| |
| /* |
| * Delete the EC from the buffer node. |
| */ |
| BufferNode* pBufferNode = pElementCollector->getBufferNode(); |
| pBufferNode->removeElementCollector(pElementCollector); |
| |
| if ( nPriority == cssxc::sax::ElementMarkPriority_BEFOREMODIFY) |
| { |
| pBufferNode->notifyBranch(); |
| } |
| |
| if (bToModify) |
| { |
| pBufferNode->notifyAncestor(); |
| } |
| |
| /* |
| * delete the ElementMark |
| */ |
| pElementCollector = NULL; |
| pElementMark = NULL; |
| removeElementMarkBuffer(nId); |
| |
| /* |
| * delete the BufferNode |
| */ |
| diffuse(pBufferNode); |
| smashBufferNode(pBufferNode, false); |
| } |
| else |
| /* |
| * it is a Blocker |
| */ |
| { |
| /* |
| * Delete the TH from the buffer node. |
| */ |
| BufferNode *pBufferNode = pElementMark->getBufferNode(); |
| pBufferNode->setBlocker(NULL); |
| |
| /* |
| * If there is a following handler and no blocking now, then |
| * forward this event |
| */ |
| if (m_pCurrentBlockingBufferNode == pBufferNode) |
| { |
| /* |
| * Before forwarding, the next blocking point needs to be |
| * found. |
| */ |
| m_pCurrentBlockingBufferNode = findNextBlockingBufferNode(pBufferNode); |
| |
| /* |
| * Forward the blocked events between these two STHs. |
| */ |
| if (m_xNextHandler.is()) |
| { |
| BufferNode* pTempCurrentBufferNode = m_pCurrentBufferNode; |
| BufferNode* pTempCurrentBlockingBufferNode = m_pCurrentBlockingBufferNode; |
| |
| m_pCurrentBufferNode = pBufferNode; |
| m_pCurrentBlockingBufferNode = NULL; |
| |
| m_bIsForwarding = true; |
| |
| m_xXMLDocument->generateSAXEvents( |
| m_xNextHandler, |
| this, |
| pBufferNode->getXMLElement(), |
| (pTempCurrentBlockingBufferNode == NULL)?NULL:(pTempCurrentBlockingBufferNode->getXMLElement())); |
| |
| m_bIsForwarding = false; |
| |
| m_pCurrentBufferNode = pTempCurrentBufferNode; |
| if (m_pCurrentBlockingBufferNode == NULL) |
| { |
| m_pCurrentBlockingBufferNode = pTempCurrentBlockingBufferNode; |
| } |
| } |
| |
| if (m_pCurrentBlockingBufferNode == NULL && |
| m_xSAXEventKeeperStatusChangeListener.is()) |
| { |
| m_xSAXEventKeeperStatusChangeListener->blockingStatusChanged(sal_False); |
| } |
| } |
| |
| /* |
| * delete the ElementMark |
| */ |
| pElementMark = NULL; |
| removeElementMarkBuffer(nId); |
| |
| /* |
| * delete the BufferNode |
| */ |
| diffuse(pBufferNode); |
| smashBufferNode(pBufferNode, true); |
| } |
| } |
| } |
| |
| m_bIsReleasing = false; |
| |
| if (!m_pRootBufferNode->hasAnything() && |
| !m_pRootBufferNode->hasChildren() && |
| m_xSAXEventKeeperStatusChangeListener.is()) |
| { |
| m_xSAXEventKeeperStatusChangeListener->bufferStatusChanged(sal_True); |
| } |
| } |
| |
| void SAXEventKeeperImpl::markElementMarkBuffer(sal_Int32 nId) |
| /****** SAXEventKeeperImpl/markElementMarkBuffer ***************************** |
| * |
| * NAME |
| * markElementMarkBuffer -- marks an ElementMark to be released |
| * |
| * SYNOPSIS |
| * markElementMarkBuffer( nId ); |
| * |
| * FUNCTION |
| * puts the ElementMark with the particular Id into the releasing list, |
| * checks whether the releasing process is runing, if not then launch |
| * this process. |
| * |
| * INPUTS |
| * nId - the Id of the ElementMark which will be released |
| * |
| * RESULT |
| * empty |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| m_vReleasedElementMarkBuffers.push_back( nId ); |
| if ( !m_bIsReleasing ) |
| { |
| releaseElementMarkBuffer(); |
| } |
| } |
| |
| sal_Int32 SAXEventKeeperImpl::createElementCollector( |
| sal_Int32 nSecurityId, |
| cssxc::sax::ElementMarkPriority nPriority, |
| bool bModifyElement, |
| const cssu::Reference< cssxc::sax::XReferenceResolvedListener >& xReferenceResolvedListener) |
| /****** SAXEventKeeperImpl/createElementCollector **************************** |
| * |
| * NAME |
| * createElementCollector -- creates a new ElementCollector on the |
| * incoming element. |
| * |
| * SYNOPSIS |
| * nId = createElementCollector( nSecurityId, nPriority, |
| * bModifyElement, |
| * xReferenceResolvedListener ); |
| * |
| * FUNCTION |
| * allocs a new Id, then create an ElementCollector with this Id value. |
| * Add the new created ElementCollector to the new ElementCollecotor list. |
| * |
| * INPUTS |
| * nSecurityId - the security Id of the new ElementCollector |
| * nPriority - the prirority of the new ElementCollector |
| * bModifyElement -whether this BufferNode will modify the content of |
| * the corresponding element it works on |
| * xReferenceResolvedListener - the listener for the new ElementCollector. |
| * |
| * RESULT |
| * nId - the Id of the new ElementCollector |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| sal_Int32 nId = m_nNextElementMarkId; |
| m_nNextElementMarkId ++; |
| |
| ElementCollector* pElementCollector |
| = new ElementCollector( |
| nSecurityId, |
| nId, |
| nPriority, |
| bModifyElement, |
| xReferenceResolvedListener); |
| |
| m_vElementMarkBuffers.push_back( pElementCollector ); |
| |
| /* |
| * All the new EC to initial EC array. |
| */ |
| m_vNewElementCollectors.push_back( pElementCollector ); |
| |
| return nId; |
| } |
| |
| |
| sal_Int32 SAXEventKeeperImpl::createBlocker(sal_Int32 nSecurityId) |
| /****** SAXEventKeeperImpl/createBlocker ************************************* |
| * |
| * NAME |
| * createBlocker -- creates a new Blocker on the incoming element. |
| * |
| * SYNOPSIS |
| * nId = createBlocker( nSecurityId ); |
| * |
| * FUNCTION |
| * see NAME. |
| * |
| * INPUTS |
| * nSecurityId - the security Id of the new Blocker |
| * |
| * RESULT |
| * nId - the Id of the new Blocker |
| * |
| * HISTORY |
| * 05.01.2004 - implemented |
| * |
| * AUTHOR |
| * Michael Mi |
| * Email: michael.mi@sun.com |
| ******************************************************************************/ |
| { |
| sal_Int32 nId = m_nNextElementMarkId; |
| m_nNextElementMarkId ++; |
| |
| OSL_ASSERT(m_pNewBlocker == NULL); |
| |
| m_pNewBlocker = new ElementMark(nSecurityId, nId); |
| m_vElementMarkBuffers.push_back( m_pNewBlocker ); |
| |
| return nId; |
| } |
| |
| /* XSAXEventKeeper */ |
| sal_Int32 SAL_CALL SAXEventKeeperImpl::addElementCollector( ) |
| throw (cssu::RuntimeException) |
| { |
| return createElementCollector( |
| cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID, |
| cssxc::sax::ElementMarkPriority_AFTERMODIFY, |
| false, |
| NULL); |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::removeElementCollector( sal_Int32 id ) |
| throw (cssu::RuntimeException) |
| { |
| markElementMarkBuffer(id); |
| } |
| |
| sal_Int32 SAL_CALL SAXEventKeeperImpl::addBlocker( ) |
| throw (cssu::RuntimeException) |
| { |
| return createBlocker(cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID); |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::removeBlocker( sal_Int32 id ) |
| throw (cssu::RuntimeException) |
| { |
| markElementMarkBuffer(id); |
| } |
| |
| sal_Bool SAL_CALL SAXEventKeeperImpl::isBlocking( ) |
| throw (cssu::RuntimeException) |
| { |
| return (m_pCurrentBlockingBufferNode != NULL); |
| } |
| |
| cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL |
| SAXEventKeeperImpl::getElement( sal_Int32 id ) |
| throw (cssu::RuntimeException) |
| { |
| cssu::Reference< cssxw::XXMLElementWrapper > rc; |
| |
| ElementMark* pElementMark = findElementMarkBuffer(id); |
| if (pElementMark != NULL) |
| { |
| rc = pElementMark->getBufferNode()->getXMLElement(); |
| } |
| |
| return rc; |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::setElement( |
| sal_Int32 id, |
| const cssu::Reference< cssxw::XXMLElementWrapper >& aElement ) |
| throw (cssu::RuntimeException) |
| { |
| if (aElement.is()) |
| { |
| m_xXMLDocument->rebuildIDLink(aElement); |
| |
| ElementMark* pElementMark = findElementMarkBuffer(id); |
| |
| if (pElementMark != NULL) |
| { |
| BufferNode* pBufferNode = pElementMark->getBufferNode(); |
| if (pBufferNode != NULL) |
| { |
| bool bIsCurrent = m_xXMLDocument->isCurrent(pBufferNode->getXMLElement()); |
| pBufferNode->setXMLElement(aElement); |
| |
| if (bIsCurrent) |
| { |
| m_xXMLDocument->setCurrentElement(aElement); |
| } |
| } |
| } |
| } |
| else |
| { |
| removeElementCollector( id ); |
| } |
| } |
| |
| cssu::Reference< cssxs::XDocumentHandler > SAL_CALL SAXEventKeeperImpl::setNextHandler( |
| const cssu::Reference< cssxs::XDocumentHandler >& xNewHandler ) |
| throw (cssu::RuntimeException) |
| { |
| cssu::Reference< cssxs::XDocumentHandler > xOldHandler = m_xNextHandler; |
| |
| m_xNextHandler = xNewHandler; |
| return xOldHandler; |
| } |
| |
| rtl::OUString SAL_CALL SAXEventKeeperImpl::printBufferNodeTree() |
| throw (cssu::RuntimeException) |
| { |
| rtl::OUString rc; |
| |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ElementMarkBuffers: size = " )); |
| rc += rtl::OUString::valueOf((sal_Int32)m_vElementMarkBuffers.size()); |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\nCurrentBufferNode: " )); |
| rc += m_xXMLDocument->getNodeName(m_pCurrentBufferNode->getXMLElement()); |
| rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" )); |
| rc += printBufferNode(m_pRootBufferNode, 0); |
| |
| return rc; |
| } |
| |
| cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL SAXEventKeeperImpl::getCurrentBlockingNode() |
| throw (cssu::RuntimeException) |
| { |
| cssu::Reference< cssxw::XXMLElementWrapper > rc; |
| |
| if (m_pCurrentBlockingBufferNode != NULL) |
| { |
| rc = m_pCurrentBlockingBufferNode->getXMLElement(); |
| } |
| |
| return rc; |
| } |
| |
| /* XSecuritySAXEventKeeper */ |
| sal_Int32 SAL_CALL SAXEventKeeperImpl::addSecurityElementCollector( |
| cssxc::sax::ElementMarkPriority priority, |
| sal_Bool modifyElement ) |
| throw (cssu::RuntimeException) |
| { |
| return createElementCollector( |
| cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID, |
| priority, |
| modifyElement, |
| NULL); |
| } |
| |
| sal_Int32 SAL_CALL SAXEventKeeperImpl::cloneElementCollector( |
| sal_Int32 referenceId, |
| cssxc::sax::ElementMarkPriority priority ) |
| throw (cssu::RuntimeException) |
| { |
| sal_Int32 nId = -1; |
| |
| ElementCollector* pElementCollector = (ElementCollector*)findElementMarkBuffer(referenceId); |
| if (pElementCollector != NULL) |
| { |
| nId = m_nNextElementMarkId; |
| m_nNextElementMarkId ++; |
| |
| ElementCollector* pClonedOne |
| = pElementCollector->clone(nId, priority); |
| |
| /* |
| * add this EC into the security data buffer array. |
| */ |
| m_vElementMarkBuffers.push_back(pClonedOne); |
| |
| /* |
| * If the reference EC is still in initial EC array, add |
| * this cloned one into the initial EC array too. |
| */ |
| if (pElementCollector->getBufferNode() == NULL) |
| { |
| m_vNewElementCollectors.push_back(pClonedOne); |
| } |
| } |
| |
| return nId; |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::setSecurityId( sal_Int32 id, sal_Int32 securityId ) |
| throw (cssu::RuntimeException) |
| { |
| ElementMark* pElementMark = findElementMarkBuffer(id); |
| if (pElementMark != NULL) |
| { |
| pElementMark->setSecurityId(securityId); |
| } |
| } |
| |
| |
| /* XReferenceResolvedBroadcaster */ |
| void SAL_CALL SAXEventKeeperImpl::addReferenceResolvedListener( |
| sal_Int32 referenceId, |
| const cssu::Reference< cssxc::sax::XReferenceResolvedListener >& listener ) |
| throw (cssu::RuntimeException) |
| { |
| ElementCollector* pElementCollector = (ElementCollector*)findElementMarkBuffer(referenceId); |
| if (pElementCollector != NULL) |
| { |
| pElementCollector->setReferenceResolvedListener(listener); |
| } |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::removeReferenceResolvedListener( |
| sal_Int32 /*referenceId*/, |
| const cssu::Reference< cssxc::sax::XReferenceResolvedListener >&) |
| throw (cssu::RuntimeException) |
| { |
| } |
| |
| /* XSAXEventKeeperStatusChangeBroadcaster */ |
| void SAL_CALL SAXEventKeeperImpl::addSAXEventKeeperStatusChangeListener( |
| const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >& listener ) |
| throw (cssu::RuntimeException) |
| { |
| m_xSAXEventKeeperStatusChangeListener = listener; |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::removeSAXEventKeeperStatusChangeListener( |
| const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >&) |
| throw (cssu::RuntimeException) |
| { |
| } |
| |
| /* XDocumentHandler */ |
| void SAL_CALL SAXEventKeeperImpl::startDocument( ) |
| throw (cssxs::SAXException, cssu::RuntimeException) |
| { |
| if ( m_xNextHandler.is()) |
| { |
| m_xNextHandler->startDocument(); |
| } |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::endDocument( ) |
| throw (cssxs::SAXException, cssu::RuntimeException) |
| { |
| if ( m_xNextHandler.is()) |
| { |
| m_xNextHandler->endDocument(); |
| } |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::startElement( |
| const rtl::OUString& aName, |
| const cssu::Reference< cssxs::XAttributeList >& xAttribs ) |
| throw (cssxs::SAXException, cssu::RuntimeException) |
| { |
| /* |
| * If there is a following handler and no blocking now, then |
| * forward this event |
| */ |
| if ((m_pCurrentBlockingBufferNode == NULL) && |
| (m_xNextHandler.is()) && |
| (!m_bIsForwarding) && |
| (m_pNewBlocker == NULL)) |
| { |
| m_xNextHandler->startElement(aName, xAttribs); |
| } |
| |
| /* |
| * If not forwarding, buffer this startElement. |
| */ |
| if (!m_bIsForwarding) |
| { |
| #ifndef _USECOMPRESSEDDOCUMENTHANDLER |
| m_xDocumentHandler->startElement(aName, xAttribs); |
| #else |
| sal_Int32 nLength = xAttribs->getLength(); |
| cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength); |
| |
| for ( int i = 0; i<nLength; ++i ) |
| { |
| aAttributes[i].sName = xAttribs->getNameByIndex((short)i); |
| aAttributes[i].sValue =xAttribs->getValueByIndex((short)i); |
| } |
| |
| m_xCompressedDocumentHandler->_startElement(aName, aAttributes); |
| #endif |
| |
| } |
| |
| BufferNode* pBufferNode = addNewElementMarkBuffers(); |
| if (pBufferNode != NULL) |
| { |
| setCurrentBufferNode(pBufferNode); |
| } |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::endElement( const rtl::OUString& aName ) |
| throw (cssxs::SAXException, cssu::RuntimeException) |
| { |
| sal_Bool bIsCurrent = m_xXMLDocument->isCurrent(m_pCurrentBufferNode->getXMLElement()); |
| |
| /* |
| * If there is a following handler and no blocking now, then |
| * forward this event |
| */ |
| if ((m_pCurrentBlockingBufferNode == NULL) && |
| (m_xNextHandler.is()) && |
| (!m_bIsForwarding)) |
| { |
| m_xNextHandler->endElement(aName); |
| } |
| |
| if ((m_pCurrentBlockingBufferNode != NULL) || |
| (m_pCurrentBufferNode != m_pRootBufferNode) || |
| (!m_xXMLDocument->isCurrentElementEmpty())) |
| { |
| if (!m_bIsForwarding) |
| { |
| #ifndef _USECOMPRESSEDDOCUMENTHANDLER |
| m_xDocumentHandler->endElement(aName); |
| #else |
| m_xCompressedDocumentHandler->_endElement(aName); |
| #endif |
| } |
| |
| /* |
| * If the current buffer node has not notified yet, and |
| * the current buffer node is waiting for the current element, |
| * then let it notify. |
| */ |
| if (bIsCurrent && (m_pCurrentBufferNode != m_pRootBufferNode)) |
| { |
| BufferNode* pOldCurrentBufferNode = m_pCurrentBufferNode; |
| m_pCurrentBufferNode = (BufferNode*)m_pCurrentBufferNode->getParent(); |
| |
| pOldCurrentBufferNode->setReceivedAll(); |
| |
| if ((m_pCurrentBufferNode == m_pRootBufferNode) && |
| m_xSAXEventKeeperStatusChangeListener.is()) |
| { |
| m_xSAXEventKeeperStatusChangeListener->collectionStatusChanged(sal_False); |
| } |
| } |
| } |
| else |
| { |
| if (!m_bIsForwarding) |
| { |
| m_xXMLDocument->removeCurrentElement(); |
| } |
| } |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::characters( const rtl::OUString& aChars ) |
| throw (cssxs::SAXException, cssu::RuntimeException) |
| { |
| if (!m_bIsForwarding) |
| { |
| if ((m_pCurrentBlockingBufferNode == NULL) && m_xNextHandler.is()) |
| { |
| m_xNextHandler->characters(aChars); |
| } |
| |
| if ((m_pCurrentBlockingBufferNode != NULL) || |
| (m_pCurrentBufferNode != m_pRootBufferNode)) |
| { |
| #ifndef _USECOMPRESSEDDOCUMENTHANDLER |
| m_xDocumentHandler->characters(aChars); |
| #else |
| m_xCompressedDocumentHandler->_characters(aChars); |
| #endif |
| } |
| } |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::ignorableWhitespace( const rtl::OUString& aWhitespaces ) |
| throw (cssxs::SAXException, cssu::RuntimeException) |
| { |
| characters( aWhitespaces ); |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::processingInstruction( |
| const rtl::OUString& aTarget, const rtl::OUString& aData ) |
| throw (cssxs::SAXException, cssu::RuntimeException) |
| { |
| if (!m_bIsForwarding) |
| { |
| if ((m_pCurrentBlockingBufferNode == NULL) && m_xNextHandler.is()) |
| { |
| m_xNextHandler->processingInstruction(aTarget, aData); |
| } |
| |
| if ((m_pCurrentBlockingBufferNode != NULL) || |
| (m_pCurrentBufferNode != m_pRootBufferNode)) |
| { |
| #ifndef _USECOMPRESSEDDOCUMENTHANDLER |
| m_xDocumentHandler->processingInstruction(aTarget, aData); |
| #else |
| m_xCompressedDocumentHandler->_processingInstruction(aTarget, aData); |
| #endif |
| } |
| } |
| } |
| |
| void SAL_CALL SAXEventKeeperImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >&) |
| throw (cssxs::SAXException, cssu::RuntimeException) |
| { |
| } |
| |
| /* XInitialization */ |
| void SAL_CALL SAXEventKeeperImpl::initialize( const cssu::Sequence< cssu::Any >& aArguments ) |
| throw (cssu::Exception, cssu::RuntimeException) |
| { |
| OSL_ASSERT(aArguments.getLength() == 1); |
| |
| aArguments[0] >>= m_xXMLDocument; |
| m_xDocumentHandler = cssu::Reference< cssxs::XDocumentHandler >( |
| m_xXMLDocument, cssu::UNO_QUERY ); |
| m_xCompressedDocumentHandler = cssu::Reference< cssxcsax::XCompressedDocumentHandler >( |
| m_xXMLDocument, cssu::UNO_QUERY ); |
| |
| m_pRootBufferNode = new BufferNode(m_xXMLDocument->getCurrentElement()); |
| m_pCurrentBufferNode = m_pRootBufferNode; |
| } |
| |
| rtl::OUString SAXEventKeeperImpl_getImplementationName () |
| throw (cssu::RuntimeException) |
| { |
| return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) ); |
| } |
| |
| sal_Bool SAL_CALL SAXEventKeeperImpl_supportsService( const rtl::OUString& ServiceName ) |
| throw (cssu::RuntimeException) |
| { |
| return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME )); |
| } |
| |
| cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl_getSupportedServiceNames( ) |
| throw (cssu::RuntimeException) |
| { |
| cssu::Sequence < rtl::OUString > aRet(1); |
| rtl::OUString* pArray = aRet.getArray(); |
| pArray[0] = rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) ); |
| return aRet; |
| } |
| #undef SERVICE_NAME |
| |
| cssu::Reference< cssu::XInterface > SAL_CALL SAXEventKeeperImpl_createInstance( |
| const cssu::Reference< cssl::XMultiServiceFactory > &) |
| throw( cssu::Exception ) |
| { |
| return (cppu::OWeakObject*) new SAXEventKeeperImpl(); |
| } |
| |
| /* XServiceInfo */ |
| rtl::OUString SAL_CALL SAXEventKeeperImpl::getImplementationName( ) |
| throw (cssu::RuntimeException) |
| { |
| return SAXEventKeeperImpl_getImplementationName(); |
| } |
| sal_Bool SAL_CALL SAXEventKeeperImpl::supportsService( const rtl::OUString& rServiceName ) |
| throw (cssu::RuntimeException) |
| { |
| return SAXEventKeeperImpl_supportsService( rServiceName ); |
| } |
| cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl::getSupportedServiceNames( ) |
| throw (cssu::RuntimeException) |
| { |
| return SAXEventKeeperImpl_getSupportedServiceNames(); |
| } |
| |