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 "precompiled_dbaccess.hxx"
25 
26 #include "settingsimport.hxx"
27 
28 /** === begin UNO includes === **/
29 /** === end UNO includes === **/
30 
31 #include <tools/diagnose_ex.h>
32 #include <xmloff/xmltoken.hxx>
33 #include <xmloff/xmluconv.hxx>
34 
35 //........................................................................
36 namespace dbaccess
37 {
38 //........................................................................
39 
40 	/** === begin UNO using === **/
41 	using ::com::sun::star::uno::Reference;
42 	using ::com::sun::star::uno::XInterface;
43 	using ::com::sun::star::uno::UNO_QUERY;
44 	using ::com::sun::star::uno::UNO_QUERY_THROW;
45 	using ::com::sun::star::uno::UNO_SET_THROW;
46 	using ::com::sun::star::uno::Exception;
47 	using ::com::sun::star::uno::RuntimeException;
48 	using ::com::sun::star::uno::Any;
49 	using ::com::sun::star::uno::makeAny;
50 	using ::com::sun::star::uno::Sequence;
51 	using ::com::sun::star::uno::Type;
52     using ::com::sun::star::xml::sax::XAttributeList;
53 	/** === end UNO using === **/
54 
55 	//====================================================================
56 	//= SettingsImport
57 	//====================================================================
58 	//--------------------------------------------------------------------
SettingsImport()59     SettingsImport::SettingsImport()
60         :m_refCount( 0 )
61     {
62     }
63 
64 	//--------------------------------------------------------------------
~SettingsImport()65     SettingsImport::~SettingsImport()
66     {
67     }
68 
69 	//--------------------------------------------------------------------
acquire()70     oslInterlockedCount SAL_CALL SettingsImport::acquire()
71     {
72         return osl_incrementInterlockedCount( &m_refCount );
73     }
74 
75 	//--------------------------------------------------------------------
release()76     oslInterlockedCount SAL_CALL SettingsImport::release()
77     {
78         oslInterlockedCount newCount = osl_decrementInterlockedCount( &m_refCount );
79         if ( newCount == 0 )
80             delete this;
81         return newCount;
82     }
83 
84 	//--------------------------------------------------------------------
startElement(const Reference<XAttributeList> & i_rAttributes)85     void SettingsImport::startElement( const Reference< XAttributeList >& i_rAttributes )
86     {
87         // find the name of the setting
88         if ( i_rAttributes.is() )
89         {
90             m_sItemName = i_rAttributes->getValueByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "config:name" ) ) );
91             m_sItemType = i_rAttributes->getValueByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "config:type" ) ) );
92         }
93     }
94 
95 	//--------------------------------------------------------------------
endElement()96     void SettingsImport::endElement()
97     {
98     }
99 
100 	//--------------------------------------------------------------------
characters(const::rtl::OUString & i_rCharacters)101     void SettingsImport::characters( const ::rtl::OUString& i_rCharacters )
102     {
103         m_aCharacters.append( i_rCharacters );
104     }
105 
106 	//--------------------------------------------------------------------
split(const::rtl::OUString & i_rElementName,::rtl::OUString & o_rNamespace,::rtl::OUString & o_rLocalName)107     void SettingsImport::split( const ::rtl::OUString& i_rElementName, ::rtl::OUString& o_rNamespace, ::rtl::OUString& o_rLocalName )
108     {
109         o_rNamespace = ::rtl::OUString();
110         o_rLocalName = i_rElementName;
111         const sal_Int32 nSeparatorPos = i_rElementName.indexOf( ':' );
112         if ( nSeparatorPos > -1 )
113         {
114             o_rNamespace = i_rElementName.copy( 0, nSeparatorPos );
115             o_rLocalName = i_rElementName.copy( nSeparatorPos + 1 );
116         }
117 
118         OSL_ENSURE( o_rNamespace.equalsAscii( "config" ), "SettingsImport::split: unexpected namespace!" );
119             // our recovery file is kind of hand-made, so there shouldn't be anything else than "config".
120             // If there is, then just ignore it ...
121     }
122 
123 	//====================================================================
124 	//= IgnoringSettingsImport
125 	//====================================================================
126 	//--------------------------------------------------------------------
nextState(const::rtl::OUString & i_rElementName)127     ::rtl::Reference< SettingsImport > IgnoringSettingsImport::nextState( const ::rtl::OUString& i_rElementName )
128     {
129         (void)i_rElementName;
130         return this;
131     }
132 
133 	//====================================================================
134 	//= OfficeSettingsImport
135 	//====================================================================
136 	//--------------------------------------------------------------------
OfficeSettingsImport(::comphelper::NamedValueCollection & o_rSettings)137     OfficeSettingsImport::OfficeSettingsImport( ::comphelper::NamedValueCollection& o_rSettings )
138         :m_rSettings( o_rSettings )
139     {
140     }
141 
142 	//--------------------------------------------------------------------
~OfficeSettingsImport()143     OfficeSettingsImport::~OfficeSettingsImport()
144     {
145     }
146 
147 	//--------------------------------------------------------------------
nextState(const::rtl::OUString & i_rElementName)148     ::rtl::Reference< SettingsImport > OfficeSettingsImport::nextState( const ::rtl::OUString& i_rElementName )
149     {
150         // separate the namespace part from the element name
151         ::rtl::OUString sNamespace;
152         ::rtl::OUString sLocalName;
153         split( i_rElementName, sNamespace, sLocalName );
154 
155         if ( sLocalName.equalsAscii( "config-item-set" ) )
156             return new ConfigItemSetImport( m_rSettings );
157 
158 #if OSL_DEBUG_LEVEL > 0
159         ::rtl::OString sMessage( "unknown (or unsupported at this place) element name '" );
160         sMessage += ::rtl::OUStringToOString( i_rElementName, RTL_TEXTENCODING_UTF8 );
161         sMessage += "', ignoring";
162         OSL_ENSURE( false, sMessage.getStr() );
163 #endif
164         return new IgnoringSettingsImport;
165     }
166 
167 	//====================================================================
168 	//= ConfigItemImport
169 	//====================================================================
170 	//--------------------------------------------------------------------
ConfigItemImport(::comphelper::NamedValueCollection & o_rSettings)171     ConfigItemImport::ConfigItemImport( ::comphelper::NamedValueCollection& o_rSettings )
172         :m_rSettings( o_rSettings )
173     {
174     }
175 
176 	//--------------------------------------------------------------------
~ConfigItemImport()177     ConfigItemImport::~ConfigItemImport()
178     {
179     }
180 
181 	//--------------------------------------------------------------------
nextState(const::rtl::OUString & i_rElementName)182     ::rtl::Reference< SettingsImport > ConfigItemImport::nextState( const ::rtl::OUString& i_rElementName )
183     {
184         OSL_ENSURE( false, "ConfigItemImport::nextState: unexpected: this class is responsible for child-less items only!" );
185         (void)i_rElementName;
186         return new IgnoringSettingsImport;
187     }
188 
189 	//--------------------------------------------------------------------
endElement()190     void ConfigItemImport::endElement()
191     {
192         SettingsImport::endElement();
193 
194         const ::rtl::OUString sItemName( getItemName() );
195         ENSURE_OR_RETURN_VOID( sItemName.getLength(), "no item name -> no item value" );
196         Any aValue;
197         getItemValue( aValue );
198         m_rSettings.put( sItemName, aValue );
199     }
200 
201 	//--------------------------------------------------------------------
getItemValue(::com::sun::star::uno::Any & o_rValue) const202     void ConfigItemImport::getItemValue( ::com::sun::star::uno::Any& o_rValue ) const
203     {
204         o_rValue.clear();
205 
206         // the characters building up th evalue
207         ::rtl::OUStringBuffer aCharacters( getAccumulatedCharacters() );
208         const ::rtl::OUString sValue = aCharacters.makeStringAndClear();
209 
210         const ::rtl::OUString& rItemType( getItemType() );
211         ENSURE_OR_RETURN_VOID( rItemType.getLength(), "no item type -> no item value" );
212 
213         if ( ::xmloff::token::IsXMLToken( rItemType, ::xmloff::token::XML_INT ) )
214         {
215             sal_Int32 nValue(0);
216             if ( SvXMLUnitConverter::convertNumber( nValue, sValue ) )
217                 o_rValue <<= nValue;
218             else
219             {
220                 OSL_ENSURE( false, "ConfigItemImport::getItemValue: could not convert an int value!" );
221             }
222         }
223         else if ( ::xmloff::token::IsXMLToken( rItemType, ::xmloff::token::XML_BOOLEAN ) )
224         {
225             sal_Bool nValue( sal_False );
226             if ( SvXMLUnitConverter::convertBool( nValue, sValue ) )
227                 o_rValue <<= nValue;
228             else
229             {
230                 OSL_ENSURE( false, "ConfigItemImport::getItemValue: could not convert a boolean value!" );
231             }
232         }
233         else if ( ::xmloff::token::IsXMLToken( rItemType, ::xmloff::token::XML_STRING ) )
234         {
235             o_rValue <<= sValue;
236         }
237 #if OSL_DEBUG_LEVEL > 0
238         else
239         {
240             ::rtl::OString sMessage( "ConfigItemImport::getItemValue: unsupported item type '" );
241             sMessage += ::rtl::OUStringToOString( rItemType, RTL_TEXTENCODING_UTF8 );
242             sMessage += "', ignoring";
243             OSL_ENSURE( false, sMessage.getStr() );
244         }
245 #endif
246     }
247 
248 	//====================================================================
249 	//= ConfigItemSetImport
250 	//====================================================================
251 	//--------------------------------------------------------------------
ConfigItemSetImport(::comphelper::NamedValueCollection & o_rSettings)252     ConfigItemSetImport::ConfigItemSetImport( ::comphelper::NamedValueCollection& o_rSettings )
253         :ConfigItemImport( o_rSettings )
254     {
255     }
256 
257 	//--------------------------------------------------------------------
~ConfigItemSetImport()258     ConfigItemSetImport::~ConfigItemSetImport()
259     {
260     }
261 
262 	//--------------------------------------------------------------------
nextState(const::rtl::OUString & i_rElementName)263     ::rtl::Reference< SettingsImport > ConfigItemSetImport::nextState( const ::rtl::OUString& i_rElementName )
264     {
265         // separate the namespace part from the element name
266         ::rtl::OUString sNamespace;
267         ::rtl::OUString sLocalName;
268         split( i_rElementName, sNamespace, sLocalName );
269 
270         if ( sLocalName.equalsAscii( "config-item-set" ) )
271             return new ConfigItemSetImport( m_aChildSettings );
272         if ( sLocalName.equalsAscii( "config-item" ) )
273             return new ConfigItemImport( m_aChildSettings );
274 
275 #if OSL_DEBUG_LEVEL > 0
276         ::rtl::OString sMessage( "unknown element name '" );
277         sMessage += ::rtl::OUStringToOString( i_rElementName, RTL_TEXTENCODING_UTF8 );
278         sMessage += "', ignoring";
279         OSL_ENSURE( false, sMessage.getStr() );
280 #endif
281         return new IgnoringSettingsImport;
282     }
283 
284 	//--------------------------------------------------------------------
getItemValue(Any & o_rValue) const285     void ConfigItemSetImport::getItemValue( Any& o_rValue ) const
286     {
287         o_rValue <<= m_aChildSettings.getPropertyValues();
288     }
289 
290 //........................................................................
291 } // namespace dbaccess
292 //........................................................................
293