LCOV - code coverage report
Current view: top level - extensions/source/abpilot - fieldmappingimpl.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 85 0.0 %
Date: 2014-04-14 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include "fieldmappingimpl.hxx"
      21             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      22             : #include <com/sun/star/beans/PropertyValue.hpp>
      23             : #include <com/sun/star/beans/XPropertySet.hpp>
      24             : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
      25             : #include <com/sun/star/ui/AddressBookSourceDialog.hpp>
      26             : #include <com/sun/star/awt/XWindow.hpp>
      27             : #include <com/sun/star/sdb/CommandType.hpp>
      28             : #include <tools/debug.hxx>
      29             : #include <toolkit/helper/vclunohelper.hxx>
      30             : #include <vcl/stdtext.hxx>
      31             : #include <com/sun/star/util/AliasProgrammaticPair.hpp>
      32             : #include "abpresid.hrc"
      33             : #include "componentmodule.hxx"
      34             : #include <unotools/confignode.hxx>
      35             : #include "sal/macros.h"
      36             : 
      37             : 
      38             : namespace abp
      39             : {
      40             : 
      41             : 
      42             :     using namespace ::utl;
      43             :     using namespace ::com::sun::star::uno;
      44             :     using namespace ::com::sun::star::awt;
      45             :     using namespace ::com::sun::star::util;
      46             :     using namespace ::com::sun::star::lang;
      47             :     using namespace ::com::sun::star::beans;
      48             :     using namespace ::com::sun::star::sdb;
      49             :     using namespace ::com::sun::star::ui;
      50             :     using namespace ::com::sun::star::ui::dialogs;
      51             : 
      52             : 
      53           0 :     static const OUString& lcl_getDriverSettingsNodeName()
      54             :     {
      55           0 :         static const OUString s_sDriverSettingsNodeName( "/org.openoffice.Office.DataAccess/DriverSettings/com.sun.star.comp.sdbc.MozabDriver" );
      56           0 :         return s_sDriverSettingsNodeName;
      57             :     }
      58             : 
      59             : 
      60           0 :     static const OUString& lcl_getAddressBookNodeName()
      61             :     {
      62           0 :         static const OUString s_sAddressBookNodeName( "/org.openoffice.Office.DataAccess/AddressBook" );
      63           0 :         return s_sAddressBookNodeName;
      64             :     }
      65             : 
      66             : 
      67             :     namespace fieldmapping
      68             :     {
      69             : 
      70             : 
      71             : 
      72           0 :         sal_Bool invokeDialog( const Reference< XComponentContext >& _rxORB, class Window* _pParent,
      73             :             const Reference< XPropertySet >& _rxDataSource, AddressSettings& _rSettings ) SAL_THROW ( ( ) )
      74             :         {
      75           0 :             _rSettings.aFieldMapping.clear();
      76             : 
      77             :             DBG_ASSERT( _rxORB.is(), "fieldmapping::invokeDialog: invalid service factory!" );
      78             :             DBG_ASSERT( _rxDataSource.is(), "fieldmapping::invokeDialog: invalid data source!" );
      79           0 :             if ( !_rxORB.is() || !_rxDataSource.is() )
      80           0 :                 return sal_False;
      81             : 
      82             :             try
      83             :             {
      84             : 
      85             :                 // create an instance of the dialog service
      86           0 :                 Reference< XWindow > xDialogParent = VCLUnoHelper::GetInterface( _pParent );
      87           0 :                 OUString sTitle(ModuleRes(RID_STR_FIELDDIALOGTITLE).toString());
      88             :                 Reference< XExecutableDialog > xDialog = AddressBookSourceDialog::createWithDataSource(_rxORB,
      89             :                                                            // the parent window
      90             :                                                            xDialogParent,
      91             :                                                            _rxDataSource,
      92             :                                                            _rSettings.bRegisterDataSource ? _rSettings.sRegisteredDataSourceName : _rSettings.sDataSourceName,
      93             :                                                            // the table to use
      94             :                                                            _rSettings.sSelectedTable,
      95           0 :                                                            sTitle);
      96             : 
      97             :                 // execute the dialog
      98           0 :                 if ( xDialog->execute() )
      99             :                 {
     100             :                     // retrieve the field mapping as set by he user
     101           0 :                     Reference< XPropertySet > xDialogProps( xDialog, UNO_QUERY );
     102             : 
     103           0 :                     Sequence< AliasProgrammaticPair > aMapping;
     104             : #ifdef DBG_UTIL
     105             :                     sal_Bool bSuccess =
     106             : #endif
     107           0 :                     xDialogProps->getPropertyValue("FieldMapping") >>= aMapping;
     108             :                     DBG_ASSERT( bSuccess, "fieldmapping::invokeDialog: invalid property type for FieldMapping!" );
     109             : 
     110             :                     // and copy it into the map
     111           0 :                     const AliasProgrammaticPair* pMapping = aMapping.getConstArray();
     112           0 :                     const AliasProgrammaticPair* pMappingEnd = pMapping + aMapping.getLength();
     113           0 :                     for (;pMapping != pMappingEnd; ++pMapping)
     114           0 :                         _rSettings.aFieldMapping[ pMapping->ProgrammaticName ] = pMapping->Alias;
     115             : 
     116           0 :                     return sal_True;
     117           0 :                 }
     118             : 
     119             :             }
     120           0 :             catch(const Exception&)
     121             :             {
     122             :                 OSL_FAIL("fieldmapping::invokeDialog: caught an exception while executing the dialog!");
     123             :             }
     124           0 :             return sal_False;
     125             :         }
     126             : 
     127             : 
     128           0 :         void defaultMapping(  const Reference< XComponentContext >& _rxContext, MapString2String& _rFieldAssignment ) SAL_THROW ( ( ) )
     129             :         {
     130           0 :             _rFieldAssignment.clear();
     131             : 
     132             :             try
     133             :             {
     134             :                 // what we have:
     135             :                 // a) For the address data source, we need a mapping from programmatic names (1) to real column names
     136             :                 // b) The SDBC driver has a fixed set of columns, which, when returned, are named according to
     137             :                 //    some configuration entries. E.g., the driver displays the field which it knows contains
     138             :                 //    the first name as "First Name" - the latter string is stored in the config.
     139             :                 //    For this, the driver uses programmatic names, too, but they differ from the programmatic names the
     140             :                 //    template documents have.
     141             :                 // So what we need first is a mapping from programmatic names (1) to programmatic names (2)
     142             :                 const sal_Char* pMappingProgrammatics[] =
     143             :                 {
     144             :                     "FirstName",            "FirstName",
     145             :                     "LastName",             "LastName",
     146             :                     "Street",               "HomeAddress",
     147             :                     "Zip",                  "HomeZipCode",
     148             :                     "City",                 "HomeCity",
     149             :                     "State",                "HomeState",
     150             :                     "Country",              "HomeCountry",
     151             :                     "PhonePriv",            "HomePhone",
     152             :                     "PhoneComp",            "WorkPhone",
     153             :                     "PhoneCell",            "CellularNumber",
     154             :                     "Pager",                "PagerNumber",
     155             :                     "Fax",                  "FaxNumber",
     156             :                     "EMail",                "PrimaryEmail",
     157             :                     "URL",                  "WebPage1",
     158             :                     "Note",                 "Notes",
     159             :                     "Altfield1",            "Custom1",
     160             :                     "Altfield2",            "Custom2",
     161             :                     "Altfield3",            "Custom3",
     162             :                     "Altfield4",            "Custom4",
     163             :                     "Title",                "JobTitle",
     164             :                     "Company",              "Company",
     165             :                     "Department",           "Department"
     166           0 :                 };
     167             :                     // (this list is not complete: both lists of programmatic names are larger in real,
     168             :                     // but this list above is the intersection)
     169             : 
     170             : 
     171             :                 // access the configuration information which the driver uses for determining it's column names
     172           0 :                 OUString sDriverAliasesNodeName = lcl_getDriverSettingsNodeName();
     173           0 :                 sDriverAliasesNodeName += OUString( "/ColumnAliases" );
     174             : 
     175             :                 // create a config node for this
     176             :                 OConfigurationTreeRoot aDriverFieldAliasing = OConfigurationTreeRoot::createWithComponentContext(
     177           0 :                     _rxContext, sDriverAliasesNodeName, -1, OConfigurationTreeRoot::CM_READONLY);
     178             : 
     179             :                 // loop through all programmatic pairs
     180             :                 DBG_ASSERT( 0 == SAL_N_ELEMENTS( pMappingProgrammatics ) % 2,
     181             :                     "fieldmapping::defaultMapping: invalid programmatic map!" );
     182             :                 // number of pairs
     183           0 :                 sal_Int32 nIntersectedProgrammatics = SAL_N_ELEMENTS( pMappingProgrammatics ) / 2;
     184             : 
     185           0 :                 const sal_Char** pProgrammatic = pMappingProgrammatics;
     186           0 :                 OUString sAddressProgrammatic;
     187           0 :                 OUString sDriverProgrammatic;
     188           0 :                 OUString sDriverUI;
     189           0 :                 for (   sal_Int32 i=0;
     190             :                         i < nIntersectedProgrammatics;
     191             :                         ++i
     192             :                     )
     193             :                 {
     194           0 :                     sAddressProgrammatic = OUString::createFromAscii( *pProgrammatic++ );
     195           0 :                     sDriverProgrammatic = OUString::createFromAscii( *pProgrammatic++ );
     196             : 
     197           0 :                     if ( aDriverFieldAliasing.hasByName( sDriverProgrammatic ) )
     198             :                     {
     199           0 :                         aDriverFieldAliasing.getNodeValue( sDriverProgrammatic ) >>= sDriverUI;
     200           0 :                         if ( 0 == sDriverUI.getLength() )
     201             :                         {
     202             :                             OSL_FAIL( "fieldmapping::defaultMapping: invalid driver UI column name!");
     203             :                         }
     204             :                         else
     205           0 :                             _rFieldAssignment[ sAddressProgrammatic ] = sDriverUI;
     206             :                     }
     207             :                     else
     208             :                     {
     209             :                         OSL_FAIL( "fieldmapping::defaultMapping: invalid driver programmatic name!" );
     210             :                     }
     211           0 :                 }
     212             :             }
     213           0 :             catch( const Exception& )
     214             :             {
     215             :                 OSL_FAIL("fieldmapping::defaultMapping: code is assumed to throw no exceptions!");
     216             :                     // the config nodes we're using herein should not do this ....
     217             :             }
     218           0 :         }
     219             : 
     220             : 
     221           0 :         void writeTemplateAddressFieldMapping( const Reference< XComponentContext >& _rxContext, const MapString2String& _rFieldAssignment ) SAL_THROW ( ( ) )
     222             :         {
     223             :             // want to have a non-const map for easier handling
     224           0 :             MapString2String aFieldAssignment( _rFieldAssignment );
     225             : 
     226             :             // access the configuration information which the driver uses for determining it's column names
     227           0 :             const OUString& sAddressBookNodeName = lcl_getAddressBookNodeName();
     228             : 
     229             :             // create a config node for this
     230             :             OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithComponentContext(
     231           0 :                 _rxContext, sAddressBookNodeName, -1, OConfigurationTreeRoot::CM_UPDATABLE);
     232             : 
     233           0 :             OConfigurationNode aFields = aAddressBookSettings.openNode( OUString( "Fields" ) );
     234             : 
     235             :             // loop through all existent fields
     236           0 :             Sequence< OUString > aExistentFields = aFields.getNodeNames();
     237           0 :             const OUString* pExistentFields = aExistentFields.getConstArray();
     238           0 :             const OUString* pExistentFieldsEnd = pExistentFields + aExistentFields.getLength();
     239             : 
     240           0 :             const OUString sProgrammaticNodeName( "ProgrammaticFieldName" );
     241           0 :             const OUString sAssignedNodeName( "AssignedFieldName" );
     242             : 
     243           0 :             for ( ; pExistentFields != pExistentFieldsEnd; ++pExistentFields )
     244             :             {
     245             : #ifdef DBG_UTIL
     246             :                 OUString sRedundantProgrammaticName;
     247             :                 aFields.openNode( *pExistentFields ).getNodeValue( sProgrammaticNodeName ) >>= sRedundantProgrammaticName;
     248             : #endif
     249             :                 DBG_ASSERT( sRedundantProgrammaticName == *pExistentFields,
     250             :                     "fieldmapping::writeTemplateAddressFieldMapping: inconsistent config data!" );
     251             :                     // there should be a redundancy in the config data .... if this asserts, there isn't anymore!
     252             : 
     253             :                 // do we have a new alias for the programmatic?
     254           0 :                 MapString2String::iterator aPos = aFieldAssignment.find( *pExistentFields );
     255           0 :                 if ( aFieldAssignment.end() != aPos )
     256             :                 {   // yes
     257             :                     // -> set a new value
     258           0 :                     OConfigurationNode aExistentField = aFields.openNode( *pExistentFields );
     259           0 :                     aExistentField.setNodeValue( sAssignedNodeName, makeAny( aPos->second ) );
     260             :                     // and remove the mapping entry
     261           0 :                     aFieldAssignment.erase( *pExistentFields );
     262             :                 }
     263             :                 else
     264             :                 {   // no
     265             :                     // -> remove it
     266           0 :                     aFields.removeNode( *pExistentFields );
     267             :                 }
     268             :             }
     269             : 
     270             :             // now everything remaining in aFieldAssignment marks a mapping entry which was not present
     271             :             // in the config before
     272           0 :             for (   MapString2String::const_iterator aNewMapping = aFieldAssignment.begin();
     273           0 :                     aNewMapping != aFieldAssignment.end();
     274             :                     ++aNewMapping
     275             :                 )
     276             :             {
     277             :                 DBG_ASSERT( !aFields.hasByName( aNewMapping->first ),
     278             :                     "fieldmapping::writeTemplateAddressFieldMapping: inconsistence!" );
     279             :                     // in case the config node for the fields already has the node named <aNewMapping->first>,
     280             :                     // the entry should have been removed from aNewMapping (in the above loop)
     281           0 :                 OConfigurationNode aNewField =  aFields.createNode( aNewMapping->first );
     282           0 :                 aNewField.setNodeValue( sProgrammaticNodeName, makeAny( aNewMapping->first ) );
     283           0 :                 aNewField.setNodeValue( sAssignedNodeName, makeAny( aNewMapping->second ) );
     284           0 :             }
     285             : 
     286             :             // commit the changes done
     287           0 :             aAddressBookSettings.commit();
     288           0 :         }
     289             : 
     290             : 
     291             :     }   // namespace fieldmapping
     292             : 
     293             : 
     294             : 
     295             :     namespace addressconfig
     296             :     {
     297             : 
     298             : 
     299             : 
     300           0 :         void writeTemplateAddressSource( const Reference< XComponentContext >& _rxContext,
     301             :             const OUString& _rDataSourceName, const OUString& _rTableName ) SAL_THROW ( ( ) )
     302             :         {
     303             :             // access the configuration information which the driver uses for determining it's column names
     304           0 :             const OUString& sAddressBookNodeName = lcl_getAddressBookNodeName();
     305             : 
     306             :             // create a config node for this
     307             :             OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithComponentContext(
     308           0 :                 _rxContext, sAddressBookNodeName, -1, OConfigurationTreeRoot::CM_UPDATABLE);
     309             : 
     310           0 :             aAddressBookSettings.setNodeValue( OUString( "DataSourceName" ), makeAny( _rDataSourceName ) );
     311           0 :             aAddressBookSettings.setNodeValue( OUString( "Command" ), makeAny( _rTableName ) );
     312           0 :             aAddressBookSettings.setNodeValue( OUString( "CommandType" ), makeAny( (sal_Int32)CommandType::TABLE ) );
     313             : 
     314             :             // commit the changes done
     315           0 :             aAddressBookSettings.commit();
     316           0 :         }
     317             : 
     318             : 
     319           0 :         void markPilotSuccess( const Reference< XComponentContext >& _rxContext ) SAL_THROW ( ( ) )
     320             :         {
     321             :             // access the configuration information which the driver uses for determining it's column names
     322           0 :             const OUString& sAddressBookNodeName = lcl_getAddressBookNodeName();
     323             : 
     324             :             // create a config node for this
     325             :             OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithComponentContext(
     326           0 :                 _rxContext, sAddressBookNodeName, -1, OConfigurationTreeRoot::CM_UPDATABLE);
     327             : 
     328             :             // set the flag
     329           0 :             aAddressBookSettings.setNodeValue( OUString( "AutoPilotCompleted" ), makeAny( (sal_Bool)sal_True ) );
     330             : 
     331             :             // commit the changes done
     332           0 :             aAddressBookSettings.commit();
     333           0 :         }
     334             : 
     335             : 
     336             :     }   // namespace addressconfig
     337             : 
     338             : 
     339             : 
     340             : }   // namespace abp
     341             : 
     342             : 
     343             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10