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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_connectivity.hxx" 26 27 #include "connectivity/sqlerror.hxx" 28 29 /** === begin UNO includes === **/ 30 #include <com/sun/star/sdbc/SQLException.hpp> 31 /** === end UNO includes === **/ 32 33 #include <comphelper/officeresourcebundle.hxx> 34 #include <cppuhelper/exc_hlp.hxx> 35 #include <rtl/ustrbuf.hxx> 36 37 #include <string.h> 38 39 //........................................................................ 40 namespace connectivity 41 { 42 //........................................................................ 43 44 /** === begin UNO using === **/ 45 using ::com::sun::star::uno::Reference; 46 using ::com::sun::star::uno::UNO_QUERY; 47 using ::com::sun::star::uno::UNO_QUERY_THROW; 48 using ::com::sun::star::uno::Exception; 49 using ::com::sun::star::uno::RuntimeException; 50 using ::com::sun::star::uno::Any; 51 using ::com::sun::star::uno::makeAny; 52 using ::com::sun::star::uno::XInterface; 53 using ::com::sun::star::sdbc::SQLException; 54 using ::com::sun::star::uno::Type; 55 /** === end UNO using === **/ 56 57 //using SQLError::ParamValue; // GCC (unxlngi6) does not like this 58 namespace 59 { 60 typedef SQLError::ParamValue ParamValue; 61 } 62 63 //==================================================================== 64 //= SQLError_Impl - declaration 65 //==================================================================== 66 class SQLError_Impl 67 { 68 public: 69 SQLError_Impl( const ::comphelper::ComponentContext& _rContext ); 70 ~SQLError_Impl(); 71 72 // versions of the public SQLError methods which are just delegated to this impl-class 73 static const ::rtl::OUString& getMessagePrefix(); 74 ::rtl::OUString getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ); 75 ::rtl::OUString getSQLState( const ErrorCondition _eCondition ); 76 static ErrorCode getErrorCode( const ErrorCondition _eCondition ); 77 void raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ); 78 void raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ); 79 void raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ); 80 SQLException getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ); 81 82 private: 83 /// returns the basic error message associated with the given error condition, without any parameter replacements 84 ::rtl::OUString 85 impl_getErrorMessage( const ErrorCondition& _eCondition ); 86 87 /// returns the SQLState associated with the given error condition 88 ::rtl::OUString 89 impl_getSQLState( const ErrorCondition& _eCondition ); 90 91 /// returns an SQLException describing the given error condition 92 SQLException 93 impl_buildSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, 94 const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ); 95 96 /// initializes our resource bundle 97 bool impl_initResources(); 98 99 private: 100 ::osl::Mutex m_aMutex; 101 ::comphelper::ComponentContext m_aContext; 102 ::std::auto_ptr< ::comphelper::OfficeResourceBundle > m_pResources; 103 bool m_bAttemptedInit; 104 }; 105 106 //==================================================================== 107 //= SQLError_Impl - implementation 108 //==================================================================== 109 //-------------------------------------------------------------------- SQLError_Impl(const::comphelper::ComponentContext & _rContext)110 SQLError_Impl::SQLError_Impl( const ::comphelper::ComponentContext& _rContext ) 111 :m_aContext( _rContext ) 112 ,m_pResources( ) 113 ,m_bAttemptedInit( false ) 114 { 115 } 116 117 //-------------------------------------------------------------------- ~SQLError_Impl()118 SQLError_Impl::~SQLError_Impl() 119 { 120 } 121 122 //-------------------------------------------------------------------- getMessagePrefix()123 const ::rtl::OUString& SQLError_Impl::getMessagePrefix() 124 { 125 static ::rtl::OUString s_sMessagePrefix( RTL_CONSTASCII_USTRINGPARAM( "[OOoBase]" ) ); 126 return s_sMessagePrefix; 127 } 128 129 //-------------------------------------------------------------------- 130 namespace 131 { 132 //................................................................ 133 /** substitutes a given placeholder in the given message with the given value 134 */ lcl_substitutePlaceholder(::rtl::OUString & _rMessage,const sal_Char * _pPlaceholder,ParamValue _rParamValue)135 void lcl_substitutePlaceholder( ::rtl::OUString& _rMessage, const sal_Char* _pPlaceholder, ParamValue _rParamValue ) 136 { 137 size_t nPlaceholderLen( strlen( _pPlaceholder ) ); 138 sal_Int32 nIndex = _rMessage.indexOfAsciiL( _pPlaceholder, nPlaceholderLen ); 139 140 bool bHasPlaceholder = ( nIndex != -1 ); 141 bool bWantsPlaceholder = _rParamValue.is(); 142 OSL_ENSURE( bHasPlaceholder == bWantsPlaceholder, "lcl_substitutePlaceholder: placeholder where none is expected, or no placeholder where one is needed!" ); 143 144 if ( bHasPlaceholder && bWantsPlaceholder ) 145 _rMessage = _rMessage.replaceAt( nIndex, nPlaceholderLen, *_rParamValue ); 146 } 147 148 //................................................................ lcl_getResourceID(const ErrorCondition _eCondition,bool _bSQLState)149 sal_Int32 lcl_getResourceID( const ErrorCondition _eCondition, bool _bSQLState ) 150 { 151 return 256 152 + 2 * ::sal::static_int_cast< sal_Int32, ErrorCondition >( _eCondition ) 153 + ( _bSQLState ? 1 : 0 ); 154 } 155 } 156 157 //-------------------------------------------------------------------- getErrorMessage(const ErrorCondition _eCondition,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3)158 ::rtl::OUString SQLError_Impl::getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) 159 { 160 ::rtl::OUString sErrorMessage( impl_getErrorMessage( _eCondition ) ); 161 162 lcl_substitutePlaceholder( sErrorMessage, "$1$", _rParamValue1 ); 163 lcl_substitutePlaceholder( sErrorMessage, "$2$", _rParamValue2 ); 164 lcl_substitutePlaceholder( sErrorMessage, "$3$", _rParamValue3 ); 165 166 return sErrorMessage; 167 } 168 169 //-------------------------------------------------------------------- getSQLState(const ErrorCondition _eCondition)170 ::rtl::OUString SQLError_Impl::getSQLState( const ErrorCondition _eCondition ) 171 { 172 return impl_getSQLState( _eCondition ); 173 } 174 175 //-------------------------------------------------------------------- getErrorCode(const ErrorCondition _eCondition)176 ErrorCode SQLError_Impl::getErrorCode( const ErrorCondition _eCondition ) 177 { 178 return 0 - ::sal::static_int_cast< ErrorCode, ErrorCondition >( _eCondition ); 179 } 180 181 //-------------------------------------------------------------------- raiseException(const ErrorCondition _eCondition,const Reference<XInterface> & _rxContext,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3)182 void SQLError_Impl::raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) 183 { 184 raiseTypedException( 185 _eCondition, 186 _rxContext, 187 ::cppu::UnoType< SQLException >::get(), 188 _rParamValue1, 189 _rParamValue2, 190 _rParamValue3 191 ); 192 } 193 194 //-------------------------------------------------------------------- raiseException(const ErrorCondition _eCondition,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3)195 void SQLError_Impl::raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) 196 { 197 raiseTypedException( 198 _eCondition, 199 NULL, 200 ::cppu::UnoType< SQLException >::get(), 201 _rParamValue1, 202 _rParamValue2, 203 _rParamValue3 204 ); 205 } 206 207 //-------------------------------------------------------------------- raiseTypedException(const ErrorCondition _eCondition,const Reference<XInterface> & _rxContext,const Type & _rExceptionType,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3)208 void SQLError_Impl::raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, 209 const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) 210 { 211 if ( !::cppu::UnoType< SQLException >::get().isAssignableFrom( _rExceptionType ) ) 212 throw ::std::bad_cast(); 213 214 // default-construct an exception of the desired type 215 Any aException( NULL, _rExceptionType ); 216 217 // fill it 218 SQLException* pException = static_cast< SQLException* >( aException.pData ); 219 *pException = impl_buildSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 ); 220 221 // throw it 222 ::cppu::throwException( aException ); 223 } 224 225 //-------------------------------------------------------------------- getSQLException(const ErrorCondition _eCondition,const Reference<XInterface> & _rxContext,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3)226 SQLException SQLError_Impl::getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, 227 const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) 228 { 229 return impl_buildSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 ); 230 } 231 232 //-------------------------------------------------------------------- impl_buildSQLException(const ErrorCondition _eCondition,const Reference<XInterface> & _rxContext,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3)233 SQLException SQLError_Impl::impl_buildSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, 234 const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) 235 { 236 return SQLException( 237 getErrorMessage( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 ), 238 _rxContext, 239 getSQLState( _eCondition ), 240 getErrorCode( _eCondition ), 241 Any() 242 ); 243 } 244 245 //-------------------------------------------------------------------- impl_getErrorMessage(const ErrorCondition & _eCondition)246 ::rtl::OUString SQLError_Impl::impl_getErrorMessage( const ErrorCondition& _eCondition ) 247 { 248 ::rtl::OUStringBuffer aMessage; 249 250 if ( impl_initResources() ) 251 { 252 ::rtl::OUString sResMessage( m_pResources->loadString( lcl_getResourceID( _eCondition, false ) ) ); 253 OSL_ENSURE( sResMessage.getLength(), "SQLError_Impl::impl_getErrorMessage: illegal error condition, or invalid resource!" ); 254 aMessage.append( getMessagePrefix() ).appendAscii( " " ).append( sResMessage ); 255 } 256 257 return aMessage.makeStringAndClear(); 258 } 259 260 //-------------------------------------------------------------------- impl_getSQLState(const ErrorCondition & _eCondition)261 ::rtl::OUString SQLError_Impl::impl_getSQLState( const ErrorCondition& _eCondition ) 262 { 263 ::rtl::OUString sState; 264 265 if ( impl_initResources() ) 266 { 267 sal_Int32 nResourceId( lcl_getResourceID( _eCondition, true ) ); 268 if ( m_pResources->hasString( nResourceId ) ) 269 sState = m_pResources->loadString( nResourceId ); 270 } 271 272 if ( !sState.getLength() ) 273 sState = ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "S1000" ) ); 274 275 return sState; 276 } 277 278 //-------------------------------------------------------------------- impl_initResources()279 bool SQLError_Impl::impl_initResources() 280 { 281 if ( m_pResources.get() ) 282 return true; 283 if ( m_bAttemptedInit ) 284 return false; 285 286 ::osl::MutexGuard aGuard( m_aMutex ); 287 m_bAttemptedInit = true; 288 289 m_pResources.reset( new ::comphelper::OfficeResourceBundle( m_aContext.getUNOContext(), "sdberr" ) ); 290 return m_pResources.get() != NULL; 291 } 292 293 //==================================================================== 294 //= SQLError 295 //==================================================================== 296 //-------------------------------------------------------------------- SQLError(const::comphelper::ComponentContext & _rContext)297 SQLError::SQLError( const ::comphelper::ComponentContext& _rContext ) 298 :m_pImpl( new SQLError_Impl( _rContext ) ) 299 { 300 } 301 302 //-------------------------------------------------------------------- ~SQLError()303 SQLError::~SQLError() 304 { 305 } 306 307 //-------------------------------------------------------------------- getMessagePrefix()308 const ::rtl::OUString& SQLError::getMessagePrefix() 309 { 310 return SQLError_Impl::getMessagePrefix(); 311 } 312 313 //-------------------------------------------------------------------- getErrorMessage(const ErrorCondition _eCondition,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3) const314 ::rtl::OUString SQLError::getErrorMessage( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const 315 { 316 return m_pImpl->getErrorMessage( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 ); 317 } 318 319 //-------------------------------------------------------------------- getSQLState(const ErrorCondition _eCondition) const320 ::rtl::OUString SQLError::getSQLState( const ErrorCondition _eCondition ) const 321 { 322 return m_pImpl->getSQLState( _eCondition ); 323 } 324 325 //-------------------------------------------------------------------- getErrorCode(const ErrorCondition _eCondition)326 ErrorCode SQLError::getErrorCode( const ErrorCondition _eCondition ) 327 { 328 return SQLError_Impl::getErrorCode( _eCondition ); 329 } 330 331 //-------------------------------------------------------------------- raiseException(const ErrorCondition _eCondition,const Reference<XInterface> & _rxContext,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3) const332 void SQLError::raiseException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const 333 { 334 m_pImpl->raiseException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 ); 335 } 336 337 //-------------------------------------------------------------------- raiseException(const ErrorCondition _eCondition,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3) const338 void SQLError::raiseException( const ErrorCondition _eCondition, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const 339 { 340 m_pImpl->raiseException( _eCondition, _rParamValue1, _rParamValue2, _rParamValue3 ); 341 } 342 343 //-------------------------------------------------------------------- raiseTypedException(const ErrorCondition _eCondition,const Reference<XInterface> & _rxContext,const Type & _rExceptionType,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3) const344 void SQLError::raiseTypedException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, 345 const Type& _rExceptionType, const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const 346 { 347 m_pImpl->raiseTypedException( _eCondition, _rxContext, _rExceptionType, _rParamValue1, _rParamValue2, _rParamValue3 ); 348 } 349 350 //-------------------------------------------------------------------- getSQLException(const ErrorCondition _eCondition,const Reference<XInterface> & _rxContext,const ParamValue & _rParamValue1,const ParamValue & _rParamValue2,const ParamValue & _rParamValue3) const351 SQLException SQLError::getSQLException( const ErrorCondition _eCondition, const Reference< XInterface >& _rxContext, 352 const ParamValue& _rParamValue1, const ParamValue& _rParamValue2, const ParamValue& _rParamValue3 ) const 353 { 354 return m_pImpl->getSQLException( _eCondition, _rxContext, _rParamValue1, _rParamValue2, _rParamValue3 ); 355 } 356 357 //........................................................................ 358 } // namespace connectivity 359 //........................................................................ 360