1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <connectionsbuffer.hxx>
21 #include <biffhelper.hxx>
23 #include <osl/diagnose.h>
24 #include <oox/helper/attributelist.hxx>
25 #include <oox/token/namespaces.hxx>
26 #include <oox/token/tokens.hxx>
27 #include <oox/helper/binaryinputstream.hxx>
28 #include <sax/fastattribs.hxx>
29 #include <documentimport.hxx>
30 #include <document.hxx>
31 #include <sax/fshelper.hxx>
35 using namespace ::com::sun::star::uno
;
39 const sal_Int32 BIFF12_RECONNECT_AS_REQUIRED
= 1;
41 const sal_uInt8 BIFF12_CONNECTION_SAVEPASSWORD_ON
= 1;
43 const sal_uInt16 BIFF12_CONNECTION_KEEPALIVE
= 0x0001;
44 const sal_uInt16 BIFF12_CONNECTION_NEW
= 0x0002;
45 const sal_uInt16 BIFF12_CONNECTION_DELETED
= 0x0004;
46 const sal_uInt16 BIFF12_CONNECTION_ONLYUSECONNFILE
= 0x0008;
47 const sal_uInt16 BIFF12_CONNECTION_BACKGROUND
= 0x0010;
48 const sal_uInt16 BIFF12_CONNECTION_REFRESHONLOAD
= 0x0020;
49 const sal_uInt16 BIFF12_CONNECTION_SAVEDATA
= 0x0040;
51 const sal_uInt16 BIFF12_CONNECTION_HAS_SOURCEFILE
= 0x0001;
52 const sal_uInt16 BIFF12_CONNECTION_HAS_SOURCECONNFILE
= 0x0002;
53 const sal_uInt16 BIFF12_CONNECTION_HAS_DESCRIPTION
= 0x0004;
54 const sal_uInt16 BIFF12_CONNECTION_HAS_NAME
= 0x0008;
55 const sal_uInt16 BIFF12_CONNECTION_HAS_SSOID
= 0x0010;
57 const sal_uInt32 BIFF12_WEBPR_XML
= 0x00000100;
58 const sal_uInt32 BIFF12_WEBPR_SOURCEDATA
= 0x00000200;
59 const sal_uInt32 BIFF12_WEBPR_PARSEPRE
= 0x00000400;
60 const sal_uInt32 BIFF12_WEBPR_CONSECUTIVE
= 0x00000800;
61 const sal_uInt32 BIFF12_WEBPR_FIRSTROW
= 0x00001000;
62 const sal_uInt32 BIFF12_WEBPR_XL97CREATED
= 0x00002000;
63 const sal_uInt32 BIFF12_WEBPR_TEXTDATES
= 0x00004000;
64 const sal_uInt32 BIFF12_WEBPR_XL2000REFRESHED
= 0x00008000;
65 const sal_uInt32 BIFF12_WEBPR_HTMLTABLES
= 0x00010000;
67 const sal_uInt8 BIFF12_WEBPR_HAS_POSTMETHOD
= 0x01;
68 const sal_uInt8 BIFF12_WEBPR_HAS_EDITPAGE
= 0x02;
69 const sal_uInt8 BIFF12_WEBPR_HAS_URL
= 0x04;
73 WebPrModel::WebPrModel() :
77 mbSourceData( false ),
79 mbConsecutive( false ),
81 mbXl97Created( false ),
83 mbXl2000Refreshed( false ),
88 ConnectionModel::ConnectionModel() :
90 mnType( BIFF12_CONNECTION_UNKNOWN
),
91 mnReconnectMethod( BIFF12_RECONNECT_AS_REQUIRED
),
94 mnRefreshedVersion(-1),
95 mnMinRefreshableVersion(0),
99 mbOnlyUseConnFile( false ),
100 mbBackground( false ),
101 mbRefreshOnLoad( false ),
103 mbSavePassword( false )
107 WebPrModel
& ConnectionModel::createWebPr()
109 OSL_ENSURE( !mxWebPr
, "ConnectionModel::createWebPr - multiple call" );
110 mxWebPr
.reset( new WebPrModel
);
114 TextPrModel
& ConnectionModel::createTextPr()
116 OSL_ENSURE(!mxTextPr
, "ConnectionModel::createTextPr - multiple call");
117 mxTextPr
.reset(new TextPrModel
);
121 ParametersModel
& ConnectionModel::createParameters()
123 OSL_ENSURE(!mxParameters
, "ConnectionModel::createParameters - multiple call");
124 mxParameters
.reset(new ParametersModel
);
125 return *mxParameters
;
128 ExtensionListModel
& ConnectionModel::createExtensionList()
130 OSL_ENSURE(!mxExtensionList
, "ConnectionModel::createExtensionList - multiple call");
131 mxExtensionList
.reset(new ExtensionListModel
);
132 return *mxExtensionList
;
135 Connection::Connection( const WorkbookHelper
& rHelper
) :
136 WorkbookHelper( rHelper
)
138 maModel
.mnId
= -1; // use="required"
139 maModel
.mnRefreshedVersion
= -1; // use="required"
142 void Connection::importConnection( const AttributeList
& rAttribs
)
144 maModel
.maName
= rAttribs
.getXString( XML_name
, OUString() );
145 maModel
.maDescription
= rAttribs
.getXString( XML_description
, OUString() );
146 maModel
.maSourceFile
= rAttribs
.getXString( XML_sourceFile
, OUString() );
147 maModel
.maSourceConnFile
= rAttribs
.getXString( XML_odcFile
, OUString() );
148 maModel
.maSsoId
= rAttribs
.getXString( XML_singleSignOnId
, OUString() );
149 maModel
.mnId
= rAttribs
.getInteger( XML_id
, -1 );
150 maModel
.mnRefreshedVersion
= rAttribs
.getInteger(XML_refreshedVersion
, -1);
151 maModel
.mnMinRefreshableVersion
= rAttribs
.getInteger(XML_minRefreshableVersion
, 0);
152 // type and reconnectionMethod are using the BIFF12 constants instead of XML tokens
153 maModel
.mnType
= rAttribs
.getInteger( XML_type
, BIFF12_CONNECTION_UNKNOWN
);
154 maModel
.mnReconnectMethod
= rAttribs
.getInteger( XML_reconnectionMethod
, BIFF12_RECONNECT_AS_REQUIRED
);
155 maModel
.mnCredentials
= rAttribs
.getToken( XML_credentials
, -1 );
156 maModel
.mnInterval
= rAttribs
.getInteger( XML_interval
, 0 );
157 maModel
.mbKeepAlive
= rAttribs
.getBool( XML_keepAlive
, false );
158 maModel
.mbNew
= rAttribs
.getBool( XML_new
, false );
159 maModel
.mbDeleted
= rAttribs
.getBool( XML_deleted
, false );
160 maModel
.mbOnlyUseConnFile
= rAttribs
.getBool( XML_onlyUseConnectionFile
, false );
161 maModel
.mbBackground
= rAttribs
.getBool( XML_background
, false );
162 maModel
.mbRefreshOnLoad
= rAttribs
.getBool( XML_refreshOnLoad
, false );
163 maModel
.mbSaveData
= rAttribs
.getBool( XML_saveData
, false );
164 maModel
.mbSavePassword
= rAttribs
.getBool( XML_savePassword
, false );
165 // FIXME: FSNS(XML_xr16, XML_uid) gets wrong(?) id of xr16:uid
166 // maModel.maXr16Uid = rAttribs.getXString( FSNS(XML_xr16, XML_uid), OUString() );
168 // workaround for finding correct XML id of xr16:uid
169 if (auto xFastAttributeList
= rAttribs
.getFastAttributeList())
171 css::uno::Sequence
<css::xml::FastAttribute
> aFast
= xFastAttributeList
->getFastAttributes();
173 for (auto& attr
: aFast
)
175 // xr16:uid="{...}" // tokenId = 3347856
176 if (attr
.Value
.startsWith("{"))
178 maModel
.maXr16Uid
= attr
.Value
;
185 void Connection::importWebPr( const AttributeList
& rAttribs
)
187 WebPrModel
& rWebPr
= maModel
.createWebPr();
189 rWebPr
.maUrl
= rAttribs
.getXString( XML_url
, OUString() );
190 rWebPr
.maPostMethod
= rAttribs
.getXString( XML_post
, OUString() );
191 rWebPr
.maEditPage
= rAttribs
.getXString( XML_editPage
, OUString() );
192 rWebPr
.mnHtmlFormat
= rAttribs
.getToken( XML_htmlFormat
, -1 );
193 rWebPr
.mbXml
= rAttribs
.getBool( XML_xml
, false );
194 rWebPr
.mbSourceData
= rAttribs
.getBool( XML_sourceData
, false );
195 rWebPr
.mbParsePre
= rAttribs
.getBool( XML_parsePre
, false );
196 rWebPr
.mbConsecutive
= rAttribs
.getBool( XML_consecutive
, false );
197 rWebPr
.mbFirstRow
= rAttribs
.getBool( XML_firstRow
, false );
198 rWebPr
.mbXl97Created
= rAttribs
.getBool( XML_xl97
, false );
199 rWebPr
.mbTextDates
= rAttribs
.getBool( XML_textDates
, false );
200 rWebPr
.mbXl2000Refreshed
= rAttribs
.getBool( XML_xl2000
, false );
201 rWebPr
.mbHtmlTables
= rAttribs
.getBool( XML_htmlTables
, false );
204 void Connection::importDbPr(const AttributeList
& rAttribs
)
206 if (auto xFastAttributeList
= rAttribs
.getFastAttributeList())
208 maModel
.maDbPrSequenceAny
= getSequenceOfAny(xFastAttributeList
);
212 void Connection::importOlapPr(const AttributeList
& rAttribs
)
214 if (auto xFastAttributeList
= rAttribs
.getFastAttributeList())
216 maModel
.maOlapPrSequenceAny
= getSequenceOfAny(xFastAttributeList
);
220 void Connection::importTables(const AttributeList
& rAttribs
)
222 if( maModel
.mxWebPr
)
224 OSL_ENSURE( maModel
.mxWebPr
->maTables
.empty(), "Connection::importTables - multiple calls" );
225 maModel
.mxWebPr
->maTables
.clear();
227 maModel
.mxWebPr
->mnCount
= rAttribs
.getInteger(XML_count
, 0);
231 void Connection::importTable( const AttributeList
& rAttribs
, sal_Int32 nElement
)
233 if( !maModel
.mxWebPr
)
239 case XLS_TOKEN(m
): // no value
241 case XLS_TOKEN(s
): // character value
242 aTableAny
<<= "s," + rAttribs
.getXString(XML_v
, OUString());
244 case XLS_TOKEN(x
): // shared items index
245 aTableAny
<<= "x," + OUString::number(rAttribs
.getInteger(XML_v
, -1));
248 OSL_ENSURE( false, "Connection::importTable - unexpected element" );
251 maModel
.mxWebPr
->maTables
.push_back( aTableAny
);
254 void Connection::importTextPr(const AttributeList
& rAttribs
)
256 TextPrModel
& rTextPr
= maModel
.createTextPr();
258 if (auto xFastAttributeList
= rAttribs
.getFastAttributeList())
260 rTextPr
.maTextPrSequenceAny
= getSequenceOfAny(xFastAttributeList
);
264 void Connection::importTextFields(const AttributeList
& rAttribs
)
266 if (maModel
.mxTextPr
)
268 OSL_ENSURE(maModel
.mxTextPr
->vTextField
.empty(),
269 "Connection::importTextFields - multiple calls");
270 maModel
.mxTextPr
->vTextField
.clear();
272 if (auto xFastAttributeList
= rAttribs
.getFastAttributeList())
274 maModel
.mxTextPr
->maTextFieldsSequenceAny
= getSequenceOfAny(xFastAttributeList
);
279 void Connection::importTextField(const AttributeList
& rAttribs
)
281 if (!maModel
.mxTextPr
)
284 if (auto xFastAttributeList
= rAttribs
.getFastAttributeList())
286 maModel
.mxTextPr
->vTextField
.push_back(getSequenceOfAny(xFastAttributeList
));
290 void Connection::importParameters(const AttributeList
& rAttribs
)
292 ParametersModel
& rParameters
= maModel
.createParameters();
293 maModel
.mxParameters
->vParameter
.clear();
294 rParameters
.mnCount
= rAttribs
.getInteger(XML_count
, -1);
297 void Connection::importParameter(const AttributeList
& rAttribs
)
299 if (!maModel
.mxParameters
)
302 if (auto xFastAttributeList
= rAttribs
.getFastAttributeList())
304 maModel
.mxParameters
->vParameter
.push_back(getSequenceOfAny(xFastAttributeList
));
308 void Connection::importExtensionList()
310 maModel
.createExtensionList();
311 maModel
.mxExtensionList
->vExtension
.clear();
314 void Connection::importExtension(const AttributeList
& rAttribs
)
316 if (!maModel
.mxExtensionList
)
319 // store uri attributes of <ext> element
320 OUString sUri
= rAttribs
.getXString(XML_uri
, OUString());
321 maModel
.mxExtensionList
->vExtension
.push_back(sUri
);
324 css::uno::Sequence
<css::uno::Any
> Connection::getSequenceOfAny(
325 css::uno::Reference
<css::xml::sax::XFastAttributeList
>& xFastAttributeList
)
327 css::uno::Sequence
<css::xml::FastAttribute
> aFast
= xFastAttributeList
->getFastAttributes();
328 css::uno::Sequence
<css::xml::Attribute
> aUnk
= xFastAttributeList
->getUnknownAttributes();
329 return { css::uno::Any(aFast
), css::uno::Any(aUnk
) };
332 void Connection::importConnection( SequenceInputStream
& rStrm
)
334 // TODO: update import&export of Microsoft Excel Binary (XLSB) File Format
335 sal_uInt16 nFlags
, nStrFlags
;
336 sal_uInt8 nSavePassword
, nCredentials
;
338 nSavePassword
= rStrm
.readuChar();
340 maModel
.mnInterval
= rStrm
.readuInt16();
341 nFlags
= rStrm
.readuInt16();
342 nStrFlags
= rStrm
.readuInt16();
343 maModel
.mnType
= rStrm
.readInt32();
344 maModel
.mnReconnectMethod
= rStrm
.readInt32();
345 maModel
.mnId
= rStrm
.readInt32();
346 nCredentials
= rStrm
.readuChar();
348 if( getFlag( nStrFlags
, BIFF12_CONNECTION_HAS_SOURCEFILE
) )
349 rStrm
>> maModel
.maSourceFile
;
350 if( getFlag( nStrFlags
, BIFF12_CONNECTION_HAS_SOURCECONNFILE
) )
351 rStrm
>> maModel
.maSourceConnFile
;
352 if( getFlag( nStrFlags
, BIFF12_CONNECTION_HAS_DESCRIPTION
) )
353 rStrm
>> maModel
.maDescription
;
354 if( getFlag( nStrFlags
, BIFF12_CONNECTION_HAS_NAME
) )
355 rStrm
>> maModel
.maName
;
356 if( getFlag( nStrFlags
, BIFF12_CONNECTION_HAS_SSOID
) )
357 rStrm
>> maModel
.maSsoId
;
359 static const sal_Int32 spnCredentials
[] = { XML_integrated
, XML_none
, XML_stored
, XML_prompt
};
360 maModel
.mnCredentials
= STATIC_ARRAY_SELECT( spnCredentials
, nCredentials
, XML_integrated
);
362 maModel
.mbKeepAlive
= getFlag( nFlags
, BIFF12_CONNECTION_KEEPALIVE
);
363 maModel
.mbNew
= getFlag( nFlags
, BIFF12_CONNECTION_NEW
);
364 maModel
.mbDeleted
= getFlag( nFlags
, BIFF12_CONNECTION_DELETED
);
365 maModel
.mbOnlyUseConnFile
= getFlag( nFlags
, BIFF12_CONNECTION_ONLYUSECONNFILE
);
366 maModel
.mbBackground
= getFlag( nFlags
, BIFF12_CONNECTION_BACKGROUND
);
367 maModel
.mbRefreshOnLoad
= getFlag( nFlags
, BIFF12_CONNECTION_REFRESHONLOAD
);
368 maModel
.mbSaveData
= getFlag( nFlags
, BIFF12_CONNECTION_SAVEDATA
);
369 maModel
.mbSavePassword
= nSavePassword
== BIFF12_CONNECTION_SAVEPASSWORD_ON
;
372 void Connection::importWebPr( SequenceInputStream
& rStrm
)
374 WebPrModel
& rWebPr
= maModel
.createWebPr();
378 nFlags
= rStrm
.readuInt32();
379 nStrFlags
= rStrm
.readuChar();
381 if( getFlag( nStrFlags
, BIFF12_WEBPR_HAS_URL
) )
382 rStrm
>> rWebPr
.maUrl
;
383 if( getFlag( nStrFlags
, BIFF12_WEBPR_HAS_POSTMETHOD
) )
384 rStrm
>> rWebPr
.maPostMethod
;
385 if( getFlag( nStrFlags
, BIFF12_WEBPR_HAS_EDITPAGE
) )
386 rStrm
>> rWebPr
.maEditPage
;
388 static const sal_Int32 spnHmlFormats
[] = { XML_none
, XML_rtf
, XML_all
};
389 rWebPr
.mnHtmlFormat
= STATIC_ARRAY_SELECT( spnHmlFormats
, extractValue
< sal_uInt8
>( nFlags
, 0, 8 ), XML_none
);
391 rWebPr
.mbXml
= getFlag( nFlags
, BIFF12_WEBPR_XML
);
392 rWebPr
.mbSourceData
= getFlag( nFlags
, BIFF12_WEBPR_SOURCEDATA
);
393 rWebPr
.mbParsePre
= getFlag( nFlags
, BIFF12_WEBPR_PARSEPRE
);
394 rWebPr
.mbConsecutive
= getFlag( nFlags
, BIFF12_WEBPR_CONSECUTIVE
);
395 rWebPr
.mbFirstRow
= getFlag( nFlags
, BIFF12_WEBPR_FIRSTROW
);
396 rWebPr
.mbXl97Created
= getFlag( nFlags
, BIFF12_WEBPR_XL97CREATED
);
397 rWebPr
.mbTextDates
= getFlag( nFlags
, BIFF12_WEBPR_TEXTDATES
);
398 rWebPr
.mbXl2000Refreshed
= getFlag( nFlags
, BIFF12_WEBPR_XL2000REFRESHED
);
399 rWebPr
.mbHtmlTables
= getFlag( nFlags
, BIFF12_WEBPR_HTMLTABLES
);
402 void Connection::importWebPrTables( SequenceInputStream
& /*rStrm*/ )
404 if( maModel
.mxWebPr
)
406 OSL_ENSURE( maModel
.mxWebPr
->maTables
.empty(), "Connection::importWebPrTables - multiple calls" );
407 maModel
.mxWebPr
->maTables
.clear();
411 void Connection::importWebPrTable( SequenceInputStream
& rStrm
, sal_Int32 nRecId
)
413 if( !maModel
.mxWebPr
)
419 case BIFF12_ID_PCITEM_MISSING
: break;
420 case BIFF12_ID_PCITEM_STRING
: aTableAny
<<= BiffHelper::readString( rStrm
); break;
421 case BIFF12_ID_PCITEM_INDEX
: aTableAny
<<= rStrm
.readInt32(); break;
423 OSL_ENSURE( false, "Connection::importWebPrTable - unexpected record" );
426 maModel
.mxWebPr
->maTables
.push_back( aTableAny
);
429 ConnectionsBuffer::ConnectionsBuffer( const WorkbookHelper
& rHelper
) :
430 WorkbookHelper( rHelper
),
435 Connection
& ConnectionsBuffer::createConnection()
437 ConnectionRef xConnection
= std::make_shared
<Connection
>( *this );
438 maConnections
.push_back( xConnection
);
442 void ConnectionsBuffer::finalizeImport()
444 for( const auto& rxConnection
: maConnections
)
445 insertConnectionToMap( rxConnection
);
447 ScDocument
& rDoc
= getDocImport().getDoc();
448 rDoc
.setConnectionVector(maConnections
);
451 ConnectionRef
ConnectionsBuffer::getConnection( sal_Int32 nConnId
) const
453 return maConnectionsById
.get( nConnId
);
456 void ConnectionsBuffer::insertConnectionToMap( const ConnectionRef
& rxConnection
)
458 sal_Int32 nConnId
= rxConnection
->getConnectionId();
461 OSL_ENSURE( !maConnectionsById
.has( nConnId
), "ConnectionsBuffer::insertConnectionToMap - multiple connection identifier" );
462 maConnectionsById
[ nConnId
] = rxConnection
;
463 mnUnusedId
= ::std::max
< sal_Int32
>( mnUnusedId
, nConnId
+ 1 );
467 } // namespace oox::xls
469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */