diff options
author | Oliver Bolte <obo@openoffice.org> | 2006-10-13 10:41:33 +0000 |
---|---|---|
committer | Oliver Bolte <obo@openoffice.org> | 2006-10-13 10:41:33 +0000 |
commit | 34e853cc6a3e3c5468c7a73424c833461e45a96f (patch) | |
tree | d20f5338e7c2138d384e68eb4898bdc9c47d34e5 /comphelper | |
parent | 222ac425d1c710945286f34a67fe82b42400b5ed (diff) |
INTEGRATION: CWS opofxmlstorage (1.1.2); FILE ADDED
2006/06/30 10:22:29 mav 1.1.2.2: resync to m173: fix warnings
2006/04/21 11:32:18 mav 1.1.2.1: #i64612# xml parsing helper
Diffstat (limited to 'comphelper')
-rw-r--r-- | comphelper/source/xml/ofopxmlhelper.cxx | 472 |
1 files changed, 472 insertions, 0 deletions
diff --git a/comphelper/source/xml/ofopxmlhelper.cxx b/comphelper/source/xml/ofopxmlhelper.cxx new file mode 100644 index 000000000000..fa1447d136ce --- /dev/null +++ b/comphelper/source/xml/ofopxmlhelper.cxx @@ -0,0 +1,472 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ofopxmlhelper.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: obo $ $Date: 2006-10-13 11:41:33 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_ +#include <com/sun/star/beans/StringPair.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif +#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP +#include <com/sun/star/io/XActiveDataSource.hpp> +#endif +#ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP +#include <com/sun/star/xml/sax/XParser.hpp> +#endif +#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#endif + +#include <comphelper/ofopxmlhelper.hxx> +#include <comphelper/attributelist.hxx> + +#define RELATIONINFO_FORMAT 0 +#define CONTENTTYPE_FORMAT 1 +#define FORMAT_MAX_ID CONTENTTYPE_FORMAT + +using namespace ::com::sun::star; + +namespace comphelper { + +// ----------------------------------- +uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OFOPXMLHelper::ReadRelationsInfoSequence( const uno::Reference< io::XInputStream >& xInStream, const ::rtl::OUString aStreamName, const uno::Reference< lang::XMultiServiceFactory > xFactory ) + throw( uno::Exception ) +{ + ::rtl::OUString aStringID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_rels/" ) ); + aStringID += aStreamName; + return ReadSequence_Impl( xInStream, aStringID, RELATIONINFO_FORMAT, xFactory ); +} + +// ----------------------------------- +uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OFOPXMLHelper::ReadContentTypeSequence( const uno::Reference< io::XInputStream >& xInStream, const uno::Reference< lang::XMultiServiceFactory > xFactory ) + throw( uno::Exception ) +{ + ::rtl::OUString aStringID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[Content_Types].xml" ) ); + return ReadSequence_Impl( xInStream, aStringID, CONTENTTYPE_FORMAT, xFactory ); +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::WriteRelationsInfoSequence( const uno::Reference< io::XOutputStream >& xOutStream, const uno::Sequence< uno::Sequence< beans::StringPair > >& aSequence, const uno::Reference< lang::XMultiServiceFactory > xFactory ) + throw( uno::Exception ) +{ + if ( !xOutStream.is() ) + throw uno::RuntimeException(); + + uno::Reference< io::XActiveDataSource > xWriterSource( + xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< xml::sax::XDocumentHandler > xWriterHandler( xWriterSource, uno::UNO_QUERY_THROW ); + + xWriterSource->setOutputStream( xOutStream ); + + ::rtl::OUString aRelListElement( RTL_CONSTASCII_USTRINGPARAM( "Relationships" ) ); + ::rtl::OUString aRelElement( RTL_CONSTASCII_USTRINGPARAM( "Relationship" ) ); + ::rtl::OUString aIDAttr( RTL_CONSTASCII_USTRINGPARAM( "Id" ) ); + ::rtl::OUString aTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ); + ::rtl::OUString aTargetTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "TargetType" ) ); + ::rtl::OUString aTargetAttr( RTL_CONSTASCII_USTRINGPARAM( "Target" ) ); + ::rtl::OUString aCDATAString( RTL_CONSTASCII_USTRINGPARAM ( "CDATA" ) ); + ::rtl::OUString aWhiteSpace( RTL_CONSTASCII_USTRINGPARAM ( " " ) ); + + // write the namespace + AttributeList* pRootAttrList = new AttributeList; + uno::Reference< xml::sax::XAttributeList > xRootAttrList( pRootAttrList ); + pRootAttrList->AddAttribute( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "xmlns" ) ), + aCDATAString, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "http://schemas.openxmlformats.org/package/2006/relationsships" ) ) ); + + xWriterHandler->startDocument(); + xWriterHandler->startElement( aRelListElement, xRootAttrList ); + + for ( sal_Int32 nInd = 0; nInd < aSequence.getLength(); nInd++ ) + { + AttributeList *pAttrList = new AttributeList; + uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList ); + for( sal_Int32 nSecInd = 0; nSecInd < aSequence[nInd].getLength(); nSecInd++ ) + { + if ( aSequence[nInd][nSecInd].First.equals( aIDAttr ) + || aSequence[nInd][nSecInd].First.equals( aTypeAttr ) + || aSequence[nInd][nSecInd].First.equals( aTargetTypeAttr ) + || aSequence[nInd][nSecInd].First.equals( aTargetAttr ) ) + { + pAttrList->AddAttribute( aSequence[nInd][nSecInd].First, aCDATAString, aSequence[nInd][nSecInd].Second ); + } + else + { + // TODO/LATER: should the extensions be allowed? + throw lang::IllegalArgumentException(); + } + } + + xWriterHandler->startElement( aRelElement, xAttrList ); + xWriterHandler->ignorableWhitespace( aWhiteSpace ); + xWriterHandler->endElement( aRelElement ); + } + + xWriterHandler->ignorableWhitespace( aWhiteSpace ); + xWriterHandler->endElement( aRelListElement ); + xWriterHandler->endDocument(); +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::WriteContentSequence( const uno::Reference< io::XOutputStream >& xOutStream, const uno::Sequence< beans::StringPair >& aDefaultsSequence, const uno::Sequence< beans::StringPair >& aOverridesSequence, const uno::Reference< lang::XMultiServiceFactory > xFactory ) + throw( uno::Exception ) +{ + if ( !xOutStream.is() ) + throw uno::RuntimeException(); + + uno::Reference< io::XActiveDataSource > xWriterSource( + xFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" ) ) ), + uno::UNO_QUERY_THROW ); + uno::Reference< xml::sax::XDocumentHandler > xWriterHandler( xWriterSource, uno::UNO_QUERY_THROW ); + + xWriterSource->setOutputStream( xOutStream ); + + ::rtl::OUString aTypesElement( RTL_CONSTASCII_USTRINGPARAM( "Types" ) ); + ::rtl::OUString aDefaultElement( RTL_CONSTASCII_USTRINGPARAM( "Default" ) ); + ::rtl::OUString aOverrideElement( RTL_CONSTASCII_USTRINGPARAM( "Override" ) ); + ::rtl::OUString aExtensionAttr( RTL_CONSTASCII_USTRINGPARAM( "Extension" ) ); + ::rtl::OUString aPartNameAttr( RTL_CONSTASCII_USTRINGPARAM( "PartName" ) ); + ::rtl::OUString aContentTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ); + ::rtl::OUString aCDATAString( RTL_CONSTASCII_USTRINGPARAM ( "CDATA" ) ); + ::rtl::OUString aWhiteSpace( RTL_CONSTASCII_USTRINGPARAM ( " " ) ); + + // write the namespace + AttributeList* pRootAttrList = new AttributeList; + uno::Reference< xml::sax::XAttributeList > xRootAttrList( pRootAttrList ); + pRootAttrList->AddAttribute( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "xmlns" ) ), + aCDATAString, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "http://schemas.openxmlformats.org/package/2006/content-types" ) ) ); + + xWriterHandler->startDocument(); + xWriterHandler->startElement( aTypesElement, xRootAttrList ); + + for ( sal_Int32 nInd = 0; nInd < aDefaultsSequence.getLength(); nInd++ ) + { + AttributeList *pAttrList = new AttributeList; + uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList ); + pAttrList->AddAttribute( aExtensionAttr, aCDATAString, aDefaultsSequence[nInd].First ); + pAttrList->AddAttribute( aContentTypeAttr, aCDATAString, aDefaultsSequence[nInd].Second ); + + xWriterHandler->startElement( aDefaultElement, xAttrList ); + xWriterHandler->ignorableWhitespace( aWhiteSpace ); + xWriterHandler->endElement( aDefaultElement ); + } + + for ( sal_Int32 nInd = 0; nInd < aOverridesSequence.getLength(); nInd++ ) + { + AttributeList *pAttrList = new AttributeList; + uno::Reference< xml::sax::XAttributeList > xAttrList( pAttrList ); + pAttrList->AddAttribute( aPartNameAttr, aCDATAString, aOverridesSequence[nInd].First ); + pAttrList->AddAttribute( aContentTypeAttr, aCDATAString, aOverridesSequence[nInd].Second ); + + xWriterHandler->startElement( aOverrideElement, xAttrList ); + xWriterHandler->ignorableWhitespace( aWhiteSpace ); + xWriterHandler->endElement( aOverrideElement ); + } + + xWriterHandler->ignorableWhitespace( aWhiteSpace ); + xWriterHandler->endElement( aTypesElement ); + xWriterHandler->endDocument(); + +} + +// ================================================================================== + +// ----------------------------------- +uno::Sequence< uno::Sequence< beans::StringPair > > SAL_CALL OFOPXMLHelper::ReadSequence_Impl( const uno::Reference< io::XInputStream >& xInStream, const ::rtl::OUString& aStringID, sal_uInt16 nFormat, const uno::Reference< lang::XMultiServiceFactory > xFactory ) + throw( uno::Exception ) +{ + if ( !xFactory.is() || !xInStream.is() || nFormat > FORMAT_MAX_ID ) + throw uno::RuntimeException(); + + uno::Sequence< uno::Sequence< beans::StringPair > > aResult; + + uno::Reference< xml::sax::XParser > xParser( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" ) ) ), uno::UNO_QUERY_THROW ); + + OFOPXMLHelper* pHelper = new OFOPXMLHelper( nFormat ); + uno::Reference< xml::sax::XDocumentHandler > xHelper( static_cast< xml::sax::XDocumentHandler* >( pHelper ) ); + xml::sax::InputSource aParserInput; + aParserInput.aInputStream = xInStream; + aParserInput.sSystemId = aStringID; + xParser->setDocumentHandler( xHelper ); + xParser->parseStream( aParserInput ); + xParser->setDocumentHandler( uno::Reference < xml::sax::XDocumentHandler > () ); + + return pHelper->GetParsingResult(); +} + +// ----------------------------------- +OFOPXMLHelper::OFOPXMLHelper( sal_uInt16 nFormat ) +: m_nFormat( nFormat ) +, m_aRelListElement( RTL_CONSTASCII_USTRINGPARAM( "Relationships" ) ) +, m_aRelElement( RTL_CONSTASCII_USTRINGPARAM( "Relationship" ) ) +, m_aIDAttr( RTL_CONSTASCII_USTRINGPARAM( "Id" ) ) +, m_aTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) +, m_aTargetTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "TargetType" ) ) +, m_aTargetAttr( RTL_CONSTASCII_USTRINGPARAM( "Target" ) ) +, m_aTypesElement( RTL_CONSTASCII_USTRINGPARAM( "Types" ) ) +, m_aDefaultElement( RTL_CONSTASCII_USTRINGPARAM( "Default" ) ) +, m_aOverrideElement( RTL_CONSTASCII_USTRINGPARAM( "Override" ) ) +, m_aExtensionAttr( RTL_CONSTASCII_USTRINGPARAM( "Extension" ) ) +, m_aPartNameAttr( RTL_CONSTASCII_USTRINGPARAM( "PartName" ) ) +, m_aContentTypeAttr( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ) +{ +} + +// ----------------------------------- +OFOPXMLHelper::~OFOPXMLHelper() +{ +} + +// ----------------------------------- +uno::Sequence< uno::Sequence< beans::StringPair > > OFOPXMLHelper::GetParsingResult() +{ + if ( m_aElementsSeq.getLength() ) + throw uno::RuntimeException(); // the parsing has still not finished! + + return m_aResultSeq; +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::startDocument() + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::endDocument() + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) + throw( xml::sax::SAXException, uno::RuntimeException ) +{ + if ( m_nFormat == RELATIONINFO_FORMAT ) + { + if ( aName == m_aRelListElement ) + { + sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1; + + if ( nNewLength != 1 ) + throw xml::sax::SAXException(); // TODO: this element must be the first level element + + m_aElementsSeq.realloc( nNewLength ); + m_aElementsSeq[nNewLength-1] = aName; + + return; // nothing to do + } + else if ( aName == m_aRelElement ) + { + sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1; + if ( nNewLength != 2 ) + throw xml::sax::SAXException(); // TODO: this element must be the second level element + + m_aElementsSeq.realloc( nNewLength ); + m_aElementsSeq[nNewLength-1] = aName; + + sal_Int32 nNewEntryNum = m_aResultSeq.getLength() + 1; + m_aResultSeq.realloc( nNewEntryNum ); + sal_Int32 nAttrNum = 0; + m_aResultSeq[nNewEntryNum-1].realloc( 4 ); // the maximal expected number of arguments is 4 + + ::rtl::OUString aIDValue = xAttribs->getValueByName( m_aIDAttr ); + if ( !aIDValue.getLength() ) + throw xml::sax::SAXException(); // TODO: the ID value must present + + ::rtl::OUString aTypeValue = xAttribs->getValueByName( m_aTypeAttr ); + ::rtl::OUString aTargetValue = xAttribs->getValueByName( m_aTargetAttr ); + ::rtl::OUString aTargetTypeValue = xAttribs->getValueByName( m_aTargetTypeAttr ); + + m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aIDAttr; + m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aIDValue; + + if ( aTypeValue.getLength() ) + { + m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aTypeAttr; + m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aTypeValue; + } + + if ( aTargetValue.getLength() ) + { + m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aTargetAttr; + m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aTargetValue; + } + + if ( aTargetTypeValue.getLength() ) + { + m_aResultSeq[nNewEntryNum-1][++nAttrNum - 1].First = m_aTargetTypeAttr; + m_aResultSeq[nNewEntryNum-1][nAttrNum - 1].Second = aTargetTypeValue; + } + + m_aResultSeq[nNewEntryNum-1].realloc( nAttrNum ); + } + else + throw xml::sax::SAXException(); // TODO: no other elements expected! + } + else if ( m_nFormat == CONTENTTYPE_FORMAT ) + { + if ( aName == m_aTypesElement ) + { + sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1; + + if ( nNewLength != 1 ) + throw xml::sax::SAXException(); // TODO: this element must be the first level element + + m_aElementsSeq.realloc( nNewLength ); + m_aElementsSeq[nNewLength-1] = aName; + + if ( !m_aResultSeq.getLength() ) + m_aResultSeq.realloc( 2 ); + + return; // nothing to do + } + else if ( aName == m_aDefaultElement ) + { + sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1; + if ( nNewLength != 2 ) + throw xml::sax::SAXException(); // TODO: this element must be the second level element + + m_aElementsSeq.realloc( nNewLength ); + m_aElementsSeq[nNewLength-1] = aName; + + if ( !m_aResultSeq.getLength() ) + m_aResultSeq.realloc( 2 ); + + if ( m_aResultSeq.getLength() != 2 ) + throw uno::RuntimeException(); + + ::rtl::OUString aExtensionValue = xAttribs->getValueByName( m_aExtensionAttr ); + if ( !aExtensionValue.getLength() ) + throw xml::sax::SAXException(); // TODO: the Extension value must present + + ::rtl::OUString aContentTypeValue = xAttribs->getValueByName( m_aContentTypeAttr ); + if ( !aContentTypeValue.getLength() ) + throw xml::sax::SAXException(); // TODO: the ContentType value must present + + sal_Int32 nNewResultLen = m_aResultSeq[0].getLength() + 1; + m_aResultSeq[0].realloc( nNewResultLen ); + + m_aResultSeq[0][nNewResultLen-1].First = aExtensionValue; + m_aResultSeq[0][nNewResultLen-1].Second = aContentTypeValue; + } + else if ( aName == m_aOverrideElement ) + { + sal_Int32 nNewLength = m_aElementsSeq.getLength() + 1; + if ( nNewLength != 2 ) + throw xml::sax::SAXException(); // TODO: this element must be the second level element + + m_aElementsSeq.realloc( nNewLength ); + m_aElementsSeq[nNewLength-1] = aName; + + if ( !m_aResultSeq.getLength() ) + m_aResultSeq.realloc( 2 ); + + if ( m_aResultSeq.getLength() != 2 ) + throw uno::RuntimeException(); + + ::rtl::OUString aPartNameValue = xAttribs->getValueByName( m_aPartNameAttr ); + if ( !aPartNameValue.getLength() ) + throw xml::sax::SAXException(); // TODO: the PartName value must present + + ::rtl::OUString aContentTypeValue = xAttribs->getValueByName( m_aContentTypeAttr ); + if ( !aContentTypeValue.getLength() ) + throw xml::sax::SAXException(); // TODO: the ContentType value must present + + sal_Int32 nNewResultLen = m_aResultSeq[1].getLength() + 1; + m_aResultSeq[1].realloc( nNewResultLen ); + + m_aResultSeq[1][nNewResultLen-1].First = aPartNameValue; + m_aResultSeq[1][nNewResultLen-1].Second = aContentTypeValue; + } + else + throw xml::sax::SAXException(); // TODO: no other elements expected! + } + else + throw xml::sax::SAXException(); // TODO: no other elements expected! +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::endElement( const ::rtl::OUString& aName ) + throw( xml::sax::SAXException, uno::RuntimeException ) +{ + if ( m_nFormat == RELATIONINFO_FORMAT || m_nFormat == CONTENTTYPE_FORMAT ) + { + sal_Int32 nLength = m_aElementsSeq.getLength(); + if ( nLength <= 0 ) + throw xml::sax::SAXException(); // TODO: no other end elements expected! + + if ( !m_aElementsSeq[nLength-1].equals( aName ) ) + throw xml::sax::SAXException(); // TODO: unexpected element ended + + m_aElementsSeq.realloc( nLength - 1 ); + } +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::characters( const ::rtl::OUString& /*aChars*/ ) + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::ignorableWhitespace( const ::rtl::OUString& /*aWhitespaces*/ ) + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::processingInstruction( const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +// ----------------------------------- +void SAL_CALL OFOPXMLHelper::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& /*xLocator*/ ) + throw(xml::sax::SAXException, uno::RuntimeException) +{ +} + +} // namespace comphelper + |