1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "OOXMLStreamImpl.hxx"
25 #include "OOXMLFastTokenHandler.hxx"
26 #include "ooxmlLoggers.hxx"
27 #include <iostream>
28
29 #ifndef _COM_SUN_STAR_CONTAINER_XHIERARCHICALSTORAGEACCESS_HPP_
30 #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
31 #endif
32
33 //#define DEBUG_STREAM
34
35 namespace writerfilter {
36 namespace ooxml
37 {
38
39 using namespace ::std;
40
OOXMLStreamImpl(uno::Reference<uno::XComponentContext> xContext,uno::Reference<io::XInputStream> xStorageStream,StreamType_t nType)41 OOXMLStreamImpl::OOXMLStreamImpl
42 (uno::Reference<uno::XComponentContext> xContext,
43 uno::Reference<io::XInputStream> xStorageStream, StreamType_t nType)
44 : mxContext(xContext), mxStorageStream(xStorageStream), mnStreamType(nType)
45 {
46 mxStorage.set
47 (comphelper::OStorageHelper::GetStorageOfFormatFromInputStream
48 (OFOPXML_STORAGE_FORMAT_STRING, mxStorageStream));
49 mxRelationshipAccess.set(mxStorage, uno::UNO_QUERY_THROW);
50
51 init();
52 }
53
OOXMLStreamImpl(OOXMLStreamImpl & rOOXMLStream,StreamType_t nStreamType)54 OOXMLStreamImpl::OOXMLStreamImpl
55 (OOXMLStreamImpl & rOOXMLStream, StreamType_t nStreamType)
56 : mxContext(rOOXMLStream.mxContext),
57 mxStorageStream(rOOXMLStream.mxStorageStream),
58 mxStorage(rOOXMLStream.mxStorage),
59 mnStreamType(nStreamType),
60 msPath(rOOXMLStream.msPath)
61 {
62 mxRelationshipAccess.set(rOOXMLStream.mxDocumentStream, uno::UNO_QUERY_THROW);
63
64 init();
65 }
66
OOXMLStreamImpl(OOXMLStreamImpl & rOOXMLStream,const rtl::OUString & rId)67 OOXMLStreamImpl::OOXMLStreamImpl
68 (OOXMLStreamImpl & rOOXMLStream, const rtl::OUString & rId)
69 : mxContext(rOOXMLStream.mxContext),
70 mxStorageStream(rOOXMLStream.mxStorageStream),
71 mxStorage(rOOXMLStream.mxStorage),
72 mnStreamType(UNKNOWN),
73 msId(rId),
74 msPath(rOOXMLStream.msPath)
75 {
76 mxRelationshipAccess.set(rOOXMLStream.mxDocumentStream, uno::UNO_QUERY_THROW);
77
78 init();
79 }
80
~OOXMLStreamImpl()81 OOXMLStreamImpl::~OOXMLStreamImpl()
82 {
83 #ifdef DEBUG_STREAM
84 debug_logger->endElement("stream");
85 #endif
86 }
87
getTarget() const88 const ::rtl::OUString & OOXMLStreamImpl::getTarget() const
89 {
90 return msTarget;
91 }
92
lcl_getTarget(uno::Reference<embed::XRelationshipAccess> xRelationshipAccess,StreamType_t nStreamType,const::rtl::OUString & rId,::rtl::OUString & rDocumentTarget)93 bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
94 xRelationshipAccess,
95 StreamType_t nStreamType,
96 const ::rtl::OUString & rId,
97 ::rtl::OUString & rDocumentTarget)
98 {
99 bool bFound = false;
100
101 static rtl::OUString sType(RTL_CONSTASCII_USTRINGPARAM("Type"));
102 static rtl::OUString sId(RTL_CONSTASCII_USTRINGPARAM("Id"));
103 static rtl::OUString sDocumentType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"));
104 static rtl::OUString sStylesType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"));
105 static rtl::OUString sNumberingType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"));
106 static rtl::OUString sFonttableType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"));
107 static rtl::OUString sFootnotesType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes"));
108 static rtl::OUString sEndnotesType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes"));
109 static rtl::OUString sCommentsType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"));
110 static rtl::OUString sThemeType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"));
111 static rtl::OUString sSettingsType(RTL_CONSTASCII_USTRINGPARAM("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"));
112 static rtl::OUString sTarget(RTL_CONSTASCII_USTRINGPARAM("Target"));
113 static rtl::OUString sTargetMode(RTL_CONSTASCII_USTRINGPARAM("TargetMode"));
114 static rtl::OUString sExternal(RTL_CONSTASCII_USTRINGPARAM("External"));
115
116 rtl::OUString sStreamType;
117
118 switch (nStreamType)
119 {
120 case DOCUMENT:
121 sStreamType = sDocumentType;
122 break;
123 case STYLES:
124 sStreamType = sStylesType;
125 break;
126 case NUMBERING:
127 sStreamType = sNumberingType;
128 break;
129 case FONTTABLE:
130 sStreamType = sFonttableType;
131 break;
132 case FOOTNOTES:
133 sStreamType = sFootnotesType;
134 break;
135 case ENDNOTES:
136 sStreamType = sEndnotesType;
137 break;
138 case COMMENTS:
139 sStreamType = sCommentsType;
140 break;
141 case THEME:
142 sStreamType = sThemeType;
143 break;
144 case SETTINGS:
145 sStreamType = sSettingsType;
146 break;
147 default:
148 break;
149 }
150
151 if (xRelationshipAccess.is())
152 {
153 uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs =
154 xRelationshipAccess->getAllRelationships();
155
156 for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
157 {
158 uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
159
160 bool bExternalTarget = false;
161 ::rtl::OUString sMyTarget;
162 for (sal_Int32 i = 0; i < aSeq.getLength(); i++)
163 {
164 beans::StringPair aPair = aSeq[i];
165
166 if (aPair.First.compareTo(sType) == 0 &&
167 aPair.Second.compareTo(sStreamType) == 0)
168 bFound = true;
169 else if (aPair.First.compareTo(sId) == 0 &&
170 aPair.Second.compareTo(rId) == 0)
171 bFound = true;
172 else if (aPair.First.compareTo(sTarget) == 0)
173 sMyTarget = aPair.Second;
174 else if (aPair.First.compareTo(sTargetMode) == 0 &&
175 aPair.Second.compareTo(sExternal) == 0)
176 bExternalTarget = true;
177
178 }
179
180 if (bFound)
181 {
182 if (bExternalTarget)
183 rDocumentTarget = sMyTarget;
184 else
185 {
186 rDocumentTarget = msPath;
187 rDocumentTarget += sMyTarget;
188 }
189
190 break;
191 }
192 }
193 }
194
195 return bFound;
196 }
197
getTargetForId(const::rtl::OUString & rId)198 ::rtl::OUString OOXMLStreamImpl::getTargetForId(const ::rtl::OUString & rId)
199 {
200 ::rtl::OUString sTarget;
201
202 uno::Reference<embed::XRelationshipAccess> xRelationshipAccess
203 (mxDocumentStream, uno::UNO_QUERY_THROW);
204
205 if (lcl_getTarget(xRelationshipAccess, UNKNOWN, rId, sTarget))
206 return sTarget;
207
208 return ::rtl::OUString();
209 }
210
init()211 void OOXMLStreamImpl::init()
212 {
213 bool bFound = lcl_getTarget(mxRelationshipAccess,
214 mnStreamType, msId, msTarget);
215 #ifdef DEBUG_STREAM
216 debug_logger->startElement("stream");
217 debug_logger->attribute("target", msTarget);
218 #endif
219
220 if (bFound)
221 {
222 sal_Int32 nLastIndex = msTarget.lastIndexOf('/');
223 if (nLastIndex >= 0)
224 msPath = msTarget.copy(0, nLastIndex + 1);
225
226 uno::Reference<embed::XHierarchicalStorageAccess>
227 xHierarchicalStorageAccess(mxStorage, uno::UNO_QUERY);
228
229 if (xHierarchicalStorageAccess.is())
230 {
231 uno::Any aAny(xHierarchicalStorageAccess->
232 openStreamElementByHierarchicalName
233 (msTarget, embed::ElementModes::SEEKABLEREAD));
234 aAny >>= mxDocumentStream;
235 }
236 }
237 }
238
getDocumentStream()239 uno::Reference<io::XInputStream> OOXMLStreamImpl::getDocumentStream()
240 {
241 uno::Reference<io::XInputStream> xResult;
242
243 if (mxDocumentStream.is())
244 xResult = mxDocumentStream->getInputStream();
245
246 return xResult;
247 }
248
getStorageStream()249 uno::Reference<io::XInputStream> OOXMLStreamImpl::getStorageStream()
250 {
251 return mxStorageStream;
252 }
253
getParser()254 uno::Reference<xml::sax::XParser> OOXMLStreamImpl::getParser()
255 {
256 uno::Reference<lang::XMultiComponentFactory> xFactory =
257 uno::Reference<lang::XMultiComponentFactory>
258 (mxContext->getServiceManager());
259
260 uno::Reference<xml::sax::XParser> xParser
261 (xFactory->createInstanceWithContext
262 ( rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ),
263 mxContext ),
264 uno::UNO_QUERY );
265
266 return xParser;
267 }
268
getContext()269 uno::Reference<uno::XComponentContext> OOXMLStreamImpl::getContext()
270 {
271 return mxContext;
272 }
273
274 uno::Reference <xml::sax::XFastTokenHandler>
getFastTokenHandler(uno::Reference<uno::XComponentContext> xContext)275 OOXMLStreamImpl::getFastTokenHandler
276 (uno::Reference<uno::XComponentContext> xContext)
277 {
278 if (! mxFastTokenHandler.is())
279 mxFastTokenHandler.set(new OOXMLFastTokenHandler(xContext));
280
281 return mxFastTokenHandler;
282 }
283
284 OOXMLStream::Pointer_t
createStream(uno::Reference<uno::XComponentContext> xContext,uno::Reference<io::XInputStream> rStream,OOXMLStream::StreamType_t nStreamType)285 OOXMLDocumentFactory::createStream
286 (uno::Reference<uno::XComponentContext> xContext,
287 uno::Reference<io::XInputStream> rStream,
288 OOXMLStream::StreamType_t nStreamType)
289 {
290 OOXMLStreamImpl * pStream = new OOXMLStreamImpl(xContext, rStream,
291 nStreamType);
292 return OOXMLStream::Pointer_t(pStream);
293 }
294
295 OOXMLStream::Pointer_t
createStream(OOXMLStream::Pointer_t pStream,OOXMLStream::StreamType_t nStreamType)296 OOXMLDocumentFactory::createStream
297 (OOXMLStream::Pointer_t pStream, OOXMLStream::StreamType_t nStreamType)
298 {
299 return OOXMLStream::Pointer_t
300 (new OOXMLStreamImpl(*dynamic_cast<OOXMLStreamImpl *>(pStream.get()),
301 nStreamType));
302 }
303
304 OOXMLStream::Pointer_t
createStream(OOXMLStream::Pointer_t pStream,const rtl::OUString & rId)305 OOXMLDocumentFactory::createStream
306 (OOXMLStream::Pointer_t pStream, const rtl::OUString & rId)
307 {
308 return OOXMLStream::Pointer_t
309 (new OOXMLStreamImpl(*dynamic_cast<OOXMLStreamImpl *>(pStream.get()),
310 rId));
311 }
312
313 }}
314