Add a means to check if a namespace exists.

Useful when we just need to check if the stream has a certain namespace
defined. Calling getNamespaceURL() may throw SAXException in such case.

Change-Id: Ib2b7b202492390158270d87bab95d1793c9d8a70
This commit is contained in:
Kohei Yoshida
2013-12-02 19:20:59 -05:00
parent 2130fd9d61
commit 532b2f4818
8 changed files with 60 additions and 3 deletions

View File

@@ -75,10 +75,12 @@ public:
void parseStream( StorageBase& rStorage, const OUString& rStreamName, bool bCloseStream = false )
throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException );
OUString getNamespaceURL( const OUString& rPrefix )
OUString getNamespaceURL( const OUString& rPrefix )
throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
sal_Int32 getNamespaceId( const OUString& aUrl );
bool hasNamespaceURL( const OUString& rPrefix ) const;
sal_Int32 getNamespaceId( const OUString& aUrl );
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastTokenHandler >
getTokenHandler() const { return mxTokenHandler; }

View File

@@ -227,6 +227,8 @@ public:
OUString getNamespaceURL( const OUString& rPrefix );
bool hasNamespaceURL( const OUString& rPrefix ) const;
sal_Int32 getNamespaceId( const OUString& rUrl );
void importDocumentProperties();

View File

@@ -140,9 +140,12 @@ public:
void pushEntity( const Entity& rEntity );
void popEntity();
Entity& getEntity();
const Entity& getEntity() const;
void parse();
void produce( CallbackType aType );
bool hasNamespaceURL( const OUString& rPrefix ) const;
private:
bool consume(EventList *);
void deleteUsedEvents();

View File

@@ -40,6 +40,7 @@ $(eval $(call gb_Library_use_libraries,oox,\
cppuhelper \
editeng \
drawinglayer \
fastsax \
msfilter \
sal \
i18nlangtag \

View File

@@ -25,6 +25,8 @@
#include "oox/helper/storagebase.hxx"
#include "oox/token/namespacemap.hxx"
#include "sax/fastparser.hxx"
namespace oox {
namespace core {
@@ -66,11 +68,13 @@ InputStreamCloseGuard::~InputStreamCloseGuard()
// ============================================================================
FastParser::FastParser( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
mrNamespaceMap( StaticNamespaceMap::get() )
mrNamespaceMap( StaticNamespaceMap::get() ),
mpParser(NULL)
{
// create a fast parser instance
Reference< XMultiComponentFactory > xFactory( rxContext->getServiceManager(), UNO_SET_THROW );
mxParser.set( xFactory->createInstanceWithContext( "com.sun.star.xml.sax.FastParser", rxContext ), UNO_QUERY_THROW );
mpParser = dynamic_cast<sax_fastparser::FastSaxParser*>(mxParser.get());
// create the fast tokenhandler
mxTokenHandler.set( new FastTokenHandler );
@@ -131,6 +135,17 @@ OUString FastParser::getNamespaceURL( const OUString& rPrefix ) throw( IllegalAr
return mxParser->getNamespaceURL( rPrefix );
}
bool FastParser::hasNamespaceURL( const OUString& rPrefix ) const
{
if (!mxParser.is())
throw RuntimeException();
if (!mpParser)
return false;
return mpParser->hasNamespaceURL(rPrefix);
}
sal_Int32 FastParser::getNamespaceId( const OUString& rUrl )
{
for( NamespaceMap::const_iterator aIt = mrNamespaceMap.begin(), aEnd = mrNamespaceMap.end(); aIt != aEnd; ++aIt )

View File

@@ -67,6 +67,12 @@ bool FragmentHandler2::prepareMceContext( sal_Int32 nElement, const AttributeLis
case MCE_TOKEN( Choice ):
{
OUString aRequires = rAttribs.getString( ( XML_Requires ), OUString("none") );
if (!getFilter().hasNamespaceURL(aRequires))
// Check to see if we have this namespace defined first,
// because calling getNamespaceURL() would throw if the
// namespace doesn't exist.
return false;
aRequires = getFilter().getNamespaceURL( aRequires );
if( getFilter().getNamespaceId( aRequires ) > 0 && !aMceState.empty() && aMceState.back() == MCE_STARTED )
aMceState.back() = MCE_FOUND_CHOICE;

View File

@@ -300,6 +300,11 @@ OUString XmlFilterBase::getNamespaceURL( const OUString& rPrefix )
return mxImpl->maFastParser.getNamespaceURL( rPrefix );
}
bool XmlFilterBase::hasNamespaceURL( const OUString& rPrefix ) const
{
return mxImpl->maFastParser.hasNamespaceURL(rPrefix);
}
sal_Int32 XmlFilterBase::getNamespaceId( const OUString& rUrl )
{
return mxImpl->maFastParser.getNamespaceId( rUrl );

View File

@@ -859,6 +859,24 @@ void FastSaxParser::produce( CallbackType aType )
}
}
bool FastSaxParser::hasNamespaceURL( const OUString& rPrefix ) const
{
const Entity& rEntity = getEntity();
if (rEntity.maNamespaceCount.empty())
return false;
OString aPrefix = OUStringToOString(rPrefix, RTL_TEXTENCODING_UTF8);
sal_uInt32 nNamespace = rEntity.maNamespaceCount.top();
while (nNamespace--)
{
if (rEntity.maNamespaceDefines[nNamespace]->maPrefix == aPrefix)
return true;
}
return false;
}
bool FastSaxParser::consume(EventList *pEventList)
{
Entity& rEntity = getEntity();
@@ -924,6 +942,11 @@ Entity& FastSaxParser::getEntity()
return maEntities.top();
}
const Entity& FastSaxParser::getEntity() const
{
return maEntities.top();
}
// starts parsing with actual parser !
void FastSaxParser::parse()
{