MCE Initial Implementation.

Points to note:
* Assumes all MCE content to be of 'Ignorable' type.
  Handling other types needs to be implemented.
* Uses the first acceptable choice and parses the
  content. Skips the others. E.g. assuming v2 and v3
  both being acceptable and v3 being newer/better, if
  the choice for v2 is stored first. v3 is skipped.
This commit is contained in:
Muthu Subramanian 2011-05-03 22:27:29 +05:30
parent 08380350f9
commit 41cc5c918e
11 changed files with 136 additions and 7 deletions

View file

@ -144,9 +144,12 @@ public:
// helpers ----------------------------------------------------------------
/** Returns the identifier of the currently processed element. */
/** Returns the identifier of the currently processed element. Ignores MCE elements in stack */
sal_Int32 getCurrentElement() const;
/** Returns the identifier of the currently processed element - Including MCE root elements */
sal_Int32 getCurrentElementWithMce() const;
/** Returns true, if nElement contains the identifier of the currently
processed element. */
inline bool isCurrentElement( sal_Int32 nElement ) const
@ -274,4 +277,4 @@ public:
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -79,6 +79,11 @@ public:
void parseStream( StorageBase& rStorage, const ::rtl::OUString& rStreamName, bool bCloseStream = false )
throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException );
::rtl::OUString getNamespaceURL( const ::rtl::OUString& rPrefix )
throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
sal_Int32 getNamespaceId( const ::rtl::OUString& aUrl );
private:
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastParser >
mxParser;

View file

@ -31,6 +31,7 @@
#include "oox/core/contexthandler2.hxx"
#include "oox/core/fragmenthandler.hxx"
#include <vector>
namespace oox {
namespace core {
@ -39,6 +40,19 @@ namespace core {
class FragmentHandler2 : public FragmentHandler, public ContextHandler2Helper
{
private:
enum MCE_STATE
{
MCE_UNUSED,
MCE_STARTED,
MCE_FOUND_CHOICE
};
::std::vector<MCE_STATE> aMceState;
private:
bool prepareMceContext( sal_Int32 nElement, const AttributeList& rAttribs );
public:
explicit FragmentHandler2(
XmlFilterBase& rFilter,
@ -113,4 +127,4 @@ public:
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -204,6 +204,10 @@ public:
*/
XmlFilterBase& exportDocumentProperties( ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentProperties > xProperties );
::rtl::OUString getNamespaceURL( const ::rtl::OUString& rPrefix );
sal_Int32 getNamespaceId( const ::rtl::OUString& rUrl );
void importDocumentProperties() throw();
protected:

View file

@ -74,11 +74,20 @@ ContextHandler2Helper::~ContextHandler2Helper()
{
}
sal_Int32 ContextHandler2Helper::getCurrentElement() const
sal_Int32 ContextHandler2Helper::getCurrentElementWithMce() const
{
return mxContextStack->empty() ? XML_ROOT_CONTEXT : mxContextStack->back().mnElement;
}
sal_Int32 ContextHandler2Helper::getCurrentElement() const
{
for ( ContextStack::const_reverse_iterator It = mxContextStack->rbegin();
It != mxContextStack->rend(); It++ )
if( getNamespace( It->mnElement ) != NMSP_mce )
return It->mnElement;
return XML_ROOT_CONTEXT;
}
sal_Int32 ContextHandler2Helper::getParentElement( sal_Int32 nCountBack ) const
{
if( (nCountBack < 0) || (mxContextStack->size() < static_cast< size_t >( nCountBack )) )
@ -118,7 +127,7 @@ void ContextHandler2Helper::implCharacters( const OUString& rChars )
void ContextHandler2Helper::implEndElement( sal_Int32 nElement )
{
(void)nElement; // prevent "unused parameter" warning in product build
OSL_ENSURE( getCurrentElement() == nElement, "ContextHandler2Helper::implEndElement - context stack broken" );
OSL_ENSURE( getCurrentElementWithMce() == nElement, "ContextHandler2Helper::implEndElement - context stack broken" );
if( !mxContextStack->empty() )
{
// #i76091# process collected characters (calls onCharacters() if needed)
@ -142,7 +151,7 @@ void ContextHandler2Helper::implStartRecord( sal_Int32 nRecId, SequenceInputStre
void ContextHandler2Helper::implEndRecord( sal_Int32 nRecId )
{
(void)nRecId; // prevent "unused parameter" warning in product build
OSL_ENSURE( getCurrentElement() == nRecId, "ContextHandler2Helper::implEndRecord - context stack broken" );
OSL_ENSURE( getCurrentElementWithMce() == nRecId, "ContextHandler2Helper::implEndRecord - context stack broken" );
if( !mxContextStack->empty() )
{
onEndRecord();

15
oox/source/core/fastparser.cxx Normal file → Executable file
View file

@ -130,6 +130,21 @@ void FastParser::parseStream( StorageBase& rStorage, const OUString& rStreamName
parseStream( rStorage.openInputStream( rStreamName ), rStreamName, bCloseStream );
}
OUString FastParser::getNamespaceURL( const OUString& rPrefix ) throw( IllegalArgumentException, RuntimeException )
{
if( !mxParser.is() )
throw RuntimeException();
return mxParser->getNamespaceURL( rPrefix );
}
sal_Int32 FastParser::getNamespaceId( const OUString& rUrl )
{
for( NamespaceMap::const_iterator aIt = mrNamespaceMap.begin(), aEnd = mrNamespaceMap.end(); aIt != aEnd; ++aIt )
if( rUrl == aIt->second )
return aIt->first;
return 0;
}
// ============================================================================
} // namespace core

View file

@ -27,6 +27,7 @@
************************************************************************/
#include "oox/core/fragmenthandler2.hxx"
#include "oox/core/xmlfilterbase.hxx"
namespace oox {
namespace core {
@ -38,6 +39,9 @@ using namespace ::com::sun::star::xml::sax;
using ::rtl::OUString;
using ::com::sun::star::uno::Sequence;
// ============================================================================
FragmentHandler2::FragmentHandler2( XmlFilterBase& rFilter, const OUString& rFragmentPath, bool bEnableTrimSpace ) :
@ -62,11 +66,58 @@ void SAL_CALL FragmentHandler2::endDocument() throw( SAXException, RuntimeExcept
finalizeImport();
}
bool FragmentHandler2::prepareMceContext( sal_Int32 nElement, const AttributeList& rAttribs )
{
switch( nElement )
{
case MCE_TOKEN( AlternateContent ):
aMceState.push_back( MCE_STARTED );
break;
case MCE_TOKEN( Choice ):
{
OUString aRequires = rAttribs.getString( ( XML_Requires ), OUString::createFromAscii("none") );
aRequires = getFilter().getNamespaceURL( aRequires );
if( getFilter().getNamespaceId( aRequires ) > 0 && !aMceState.empty() && aMceState.back() == MCE_STARTED )
aMceState.back() = MCE_FOUND_CHOICE;
else
return false;
}
break;
case MCE_TOKEN( Fallback ):
if( !aMceState.empty() && aMceState.back() == MCE_STARTED )
break;
return false;
default:
{
OUString str = rAttribs.getString( MCE_TOKEN( Ignorable ), OUString() );
if( !str.isEmpty() )
{
Sequence< ::com::sun::star::xml::FastAttribute > attrs = rAttribs.getFastAttributeList()->getFastAttributes();
// printf("MCE: %s\n", ::rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
// TODO: Check & Get the namespaces in "Ignorable"
// printf("NS: %d : %s\n", attrs.getLength(), ::rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
}
}
return false;
}
return true;
}
// com.sun.star.xml.sax.XFastContextHandler interface -------------------------
Reference< XFastContextHandler > SAL_CALL FragmentHandler2::createFastChildContext(
sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw( SAXException, RuntimeException )
{
if( getNamespace( nElement ) == NMSP_mce ) // TODO for checking 'Ignorable'
{
if( prepareMceContext( nElement, AttributeList( rxAttribs ) ) )
return getFastContextHandler();
return NULL;
}
return implCreateChildContext( nElement, rxAttribs );
}
@ -83,6 +134,14 @@ void SAL_CALL FragmentHandler2::characters( const OUString& rChars ) throw( SAXE
void SAL_CALL FragmentHandler2::endFastElement( sal_Int32 nElement ) throw( SAXException, RuntimeException )
{
/* If MCE */
switch( nElement )
{
case MCE_TOKEN( AlternateContent ):
aMceState.pop_back();
break;
}
implEndElement( nElement );
}
@ -150,4 +209,4 @@ void FragmentHandler2::finalizeImport()
} // namespace core
} // namespace oox
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -141,6 +141,8 @@ XmlFilterBaseImpl::XmlFilterBaseImpl( const Reference< XComponentContext >& rxCo
maFastParser.registerNamespace( NMSP_ax );
maFastParser.registerNamespace( NMSP_xm );
maFastParser.registerNamespace( NMSP_mce );
maFastParser.registerNamespace( NMSP_mceTest );
}
@ -272,6 +274,16 @@ bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& r
return false;
}
OUString XmlFilterBase::getNamespaceURL( const OUString& rPrefix )
{
return mxImpl->maFastParser.getNamespaceURL( rPrefix );
}
sal_Int32 XmlFilterBase::getNamespaceId( const OUString& rUrl )
{
return mxImpl->maFastParser.getNamespaceId( rUrl );
}
RelationsRef XmlFilterBase::importRelations( const OUString& rFragmentPath )
{
// try to find cached relations

1
oox/source/token/namespaces.hxx.tail Normal file → Executable file
View file

@ -27,6 +27,7 @@ inline sal_Int32 getNamespace( sal_Int32 nToken ) { return nToken & NMSP_MASK; }
#define XLS_TOKEN( token ) (::oox::NMSP_xls | XML_##token)
#define XM_TOKEN( token ) (::oox::NMSP_xm | XML_##token)
#define XML_TOKEN( token ) (::oox::NMSP_xml | XML_##token)
#define MCE_TOKEN( token ) (::oox::NMSP_mce | XML_##token)
// ============================================================================

View file

@ -50,3 +50,5 @@ dc http://purl.org/dc/elements/1.1/
dcTerms http://purl.org/dc/terms/
xm http://schemas.microsoft.com/office/excel/2006/main
sprm http://sprm
mce http://schemas.openxmlformats.org/markup-compatibility/2006
mceTest http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2

View file

@ -37,6 +37,7 @@ AbbreviatedCaseNumber
Accel
Accel2
AlbumTitle
AlternateContent
Always
Anchor
AppVersion
@ -79,6 +80,7 @@ Characters
CharactersWithSpaces
Checkbox
Checked
Choice
City
ClientData
ColHidden
@ -142,6 +144,7 @@ EnhancedMetaFile
Extend
Extension
External
Fallback
False
FieldCodes
FileBinding
@ -183,6 +186,7 @@ IDREF
IDREFS
Icon
Id
Ignorable
Inc
Institution
Internal
@ -324,6 +328,7 @@ Relationships
RelationshipsGroupReference
Report
Reporter
Requires
Right
RootElement
Row