blob: f2615ac1e28e039c66c3adbfbd3fa5cf6a60722f [file] [log] [blame]
/**************************************************************
*
* 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.
*
*************************************************************/
#include "OOXMLStreamImpl.hxx"
#include "OOXMLFastTokenHandler.hxx"
#include "ooxmlLoggers.hxx"
#include <iostream>
#ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALSTORAGEACCESS_HPP_
#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
#endif
//#define DEBUG_STREAM
namespace writerfilter {
namespace ooxml
{
using namespace ::std;
OOXMLStreamImpl::OOXMLStreamImpl
(uno::Reference<uno::XComponentContext> xContext,
uno::Reference<io::XInputStream> xStorageStream, StreamType_t nType)
: mxContext(xContext), mxStorageStream(xStorageStream), mnStreamType(nType)
{
mxStorage.set
(comphelper::OStorageHelper::GetStorageOfFormatFromInputStream
(OFOPXML_STORAGE_FORMAT_STRING, mxStorageStream));
mxRelationshipAccess.set(mxStorage, uno::UNO_QUERY_THROW);
init();
}
OOXMLStreamImpl::OOXMLStreamImpl
(OOXMLStreamImpl & rOOXMLStream, StreamType_t nStreamType)
: mxContext(rOOXMLStream.mxContext),
mxStorageStream(rOOXMLStream.mxStorageStream),
mxStorage(rOOXMLStream.mxStorage),
mnStreamType(nStreamType),
msPath(rOOXMLStream.msPath)
{
mxRelationshipAccess.set(rOOXMLStream.mxDocumentStream, uno::UNO_QUERY_THROW);
init();
}
OOXMLStreamImpl::OOXMLStreamImpl
(OOXMLStreamImpl & rOOXMLStream, const rtl::OUString & rId)
: mxContext(rOOXMLStream.mxContext),
mxStorageStream(rOOXMLStream.mxStorageStream),
mxStorage(rOOXMLStream.mxStorage),
mnStreamType(UNKNOWN),
msId(rId),
msPath(rOOXMLStream.msPath)
{
mxRelationshipAccess.set(rOOXMLStream.mxDocumentStream, uno::UNO_QUERY_THROW);
init();
}
OOXMLStreamImpl::~OOXMLStreamImpl()
{
#ifdef DEBUG_STREAM
debug_logger->endElement("stream");
#endif
}
const ::rtl::OUString & OOXMLStreamImpl::getTarget() const
{
return msTarget;
}
bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
xRelationshipAccess,
StreamType_t nStreamType,
const ::rtl::OUString & rId,
::rtl::OUString & rDocumentTarget)
{
bool bFound = false;
static rtl::OUString sType(RTL_CONSTASCII_USTRINGPARAM("Type"));
static rtl::OUString sId(RTL_CONSTASCII_USTRINGPARAM("Id"));
static rtl::OUString sDocumentType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"));
static rtl::OUString sStylesType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"));
static rtl::OUString sNumberingType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"));
static rtl::OUString sFonttableType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"));
static rtl::OUString sFootnotesType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes"));
static rtl::OUString sEndnotesType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes"));
static rtl::OUString sCommentsType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"));
static rtl::OUString sThemeType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"));
static rtl::OUString sSettingsType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"));
static rtl::OUString sTarget(RTL_CONSTASCII_USTRINGPARAM("Target"));
static rtl::OUString sTargetMode(RTL_CONSTASCII_USTRINGPARAM("TargetMode"));
static rtl::OUString sExternal(RTL_CONSTASCII_USTRINGPARAM("External"));
rtl::OUString sStreamType;
switch (nStreamType)
{
case DOCUMENT:
sStreamType = sDocumentType;
break;
case STYLES:
sStreamType = sStylesType;
break;
case NUMBERING:
sStreamType = sNumberingType;
break;
case FONTTABLE:
sStreamType = sFonttableType;
break;
case FOOTNOTES:
sStreamType = sFootnotesType;
break;
case ENDNOTES:
sStreamType = sEndnotesType;
break;
case COMMENTS:
sStreamType = sCommentsType;
break;
case THEME:
sStreamType = sThemeType;
break;
case SETTINGS:
sStreamType = sSettingsType;
break;
default:
break;
}
if (xRelationshipAccess.is())
{
uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs =
xRelationshipAccess->getAllRelationships();
for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
{
uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
bool bExternalTarget = false;
::rtl::OUString sMyTarget;
for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
{
beans::StringPair aPair = aSeq[i];
if (aPair.First.compareTo(sType) == 0 &&
aPair.Second.compareTo(sStreamType) == 0)
bFound = true;
else if (aPair.First.compareTo(sId) == 0 &&
aPair.Second.compareTo(rId) == 0)
bFound = true;
else if (aPair.First.compareTo(sTarget) == 0)
sMyTarget = aPair.Second;
else if (aPair.First.compareTo(sTargetMode) == 0 &&
aPair.Second.compareTo(sExternal) == 0)
bExternalTarget = true;
}
if (bFound)
{
if (bExternalTarget)
rDocumentTarget = sMyTarget;
else
{
rDocumentTarget = msPath;
rDocumentTarget += sMyTarget;
}
break;
}
}
}
return bFound;
}
::rtl::OUString OOXMLStreamImpl::getTargetForId(const ::rtl::OUString & rId)
{
::rtl::OUString sTarget;
uno::Reference<embed::XRelationshipAccess> xRelationshipAccess
(mxDocumentStream, uno::UNO_QUERY_THROW);
if (lcl_getTarget(xRelationshipAccess, UNKNOWN, rId, sTarget))
return sTarget;
return ::rtl::OUString();
}
void OOXMLStreamImpl::init()
{
bool bFound = lcl_getTarget(mxRelationshipAccess,
mnStreamType, msId, msTarget);
#ifdef DEBUG_STREAM
debug_logger->startElement("stream");
debug_logger->attribute("target", msTarget);
#endif
if (bFound)
{
sal_Int32 nLastIndex = msTarget.lastIndexOf('/');
if (nLastIndex >= 0)
msPath = msTarget.copy(0, nLastIndex + 1);
uno::Reference<embed::XHierarchicalStorageAccess>
xHierarchicalStorageAccess(mxStorage, uno::UNO_QUERY);
if (xHierarchicalStorageAccess.is())
{
uno::Any aAny(xHierarchicalStorageAccess->
openStreamElementByHierarchicalName
(msTarget, embed::ElementModes::SEEKABLEREAD));
aAny >>= mxDocumentStream;
}
}
}
uno::Reference<io::XInputStream> OOXMLStreamImpl::getDocumentStream()
{
uno::Reference<io::XInputStream> xResult;
if (mxDocumentStream.is())
xResult = mxDocumentStream->getInputStream();
return xResult;
}
uno::Reference<io::XInputStream> OOXMLStreamImpl::getStorageStream()
{
return mxStorageStream;
}
uno::Reference<xml::sax::XParser> OOXMLStreamImpl::getParser()
{
uno::Reference<lang::XMultiComponentFactory> xFactory =
uno::Reference<lang::XMultiComponentFactory>
(mxContext->getServiceManager());
uno::Reference<xml::sax::XParser> xParser
(xFactory->createInstanceWithContext
( rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ),
mxContext ),
uno::UNO_QUERY );
return xParser;
}
uno::Reference<uno::XComponentContext> OOXMLStreamImpl::getContext()
{
return mxContext;
}
uno::Reference <xml::sax::XFastTokenHandler>
OOXMLStreamImpl::getFastTokenHandler
(uno::Reference<uno::XComponentContext> xContext)
{
if (! mxFastTokenHandler.is())
mxFastTokenHandler.set(new OOXMLFastTokenHandler(xContext));
return mxFastTokenHandler;
}
OOXMLStream::Pointer_t
OOXMLDocumentFactory::createStream
(uno::Reference<uno::XComponentContext> xContext,
uno::Reference<io::XInputStream> rStream,
OOXMLStream::StreamType_t nStreamType)
{
OOXMLStreamImpl * pStream = new OOXMLStreamImpl(xContext, rStream,
nStreamType);
return OOXMLStream::Pointer_t(pStream);
}
OOXMLStream::Pointer_t
OOXMLDocumentFactory::createStream
(OOXMLStream::Pointer_t pStream, OOXMLStream::StreamType_t nStreamType)
{
return OOXMLStream::Pointer_t
(new OOXMLStreamImpl(*dynamic_cast<OOXMLStreamImpl *>(pStream.get()),
nStreamType));
}
OOXMLStream::Pointer_t
OOXMLDocumentFactory::createStream
(OOXMLStream::Pointer_t pStream, const rtl::OUString & rId)
{
return OOXMLStream::Pointer_t
(new OOXMLStreamImpl(*dynamic_cast<OOXMLStreamImpl *>(pStream.get()),
rId));
}
}}