kde-playground/kdepim-runtime/migration/kres/kresmigratorbase.cpp
2015-04-14 22:08:21 +00:00

177 lines
6.1 KiB
C++

/*
Copyright (c) 2008 Volker Krause <vkrause@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "kresmigratorbase.h"
#include <akonadi/agentinstancecreatejob.h>
#include <akonadi/agentmanager.h>
#include <kresources/manager.h>
#include <kresources/resource.h>
#include <KConfigGroup>
#include <KGlobal>
#include <KStandardDirs>
#include <KJob>
using namespace Akonadi;
KResMigratorBase::KResMigratorBase(const QString & type, const QString &bridgeType) :
KMigratorBase(),
mType( type ),
mBridgeType( bridgeType ),
mCurrentKResource( 0 ),
mBridgingInProgress( false )
{
KConfigGroup cfg( KGlobal::config(), "Bridged" );
mPendingBridgedResources = cfg.readEntry( mType + QLatin1String("Resources"), QStringList() );
}
void KResMigratorBase::migrateToBridge( KRES::Resource *res, const QString & typeId)
{
kDebug() << res->type() << res->identifier() << typeId;
if ( migrationState( res->identifier() ) != None ) {
migrateNext();
return;
}
emit message( Info, i18n( "Trying to migrate '%1' to compatibility bridge...", res->resourceName() ) );
mBridgingInProgress = true;
createAgentInstance( typeId, this, SLOT(resourceBridgeCreated(KJob*)) );
}
void KResMigratorBase::resourceBridgeCreated(KJob * job)
{
kDebug();
if ( job->error() ) {
migrationFailed( i18n( "Unable to create compatibility bridge: %1", job->errorText() ) );
return;
}
KRES::Resource *res = mCurrentKResource;
Q_ASSERT( res );
AgentInstance instance = static_cast<AgentInstanceCreateJob*>( job )->instance();
const KConfigGroup kresCfg = kresConfig( res );
instance.setName( kresCfg.readEntry( "ResourceName", "Bridged KResource" ) );
const QString akoResCfgFile = KStandardDirs::locateLocal( "config", QString::fromLatin1( "%1rc" ).arg( instance.identifier() ) );
KConfig *akoResConfig = new KConfig( akoResCfgFile );
KConfigGroup bridgeResCfg( akoResConfig, kresCfg.name() );
kresCfg.copyTo( &bridgeResCfg );
bridgeResCfg.writeEntry( "ResourceIsActive", true );
bridgeResCfg.sync();
KConfigGroup generalCfg( akoResConfig, "General" );
generalCfg.writeEntry( "ResourceKeys", res->identifier() );
generalCfg.writeEntry( "Standard", res->identifier() );
generalCfg.sync();
akoResConfig->sync();
delete akoResConfig;
instance.reconfigure();
migratedToBridge( instance );
}
void KResMigratorBase::setBridgingOnly(bool b)
{
mBridgeOnly = b;
}
void KResMigratorBase::migrationFailed(const QString & errorMsg, const Akonadi::AgentInstance & instance)
{
if ( mBridgingInProgress ) {
emit message( Error, i18n( "Migration of '%1' to compatibility bridge failed: %2",
mCurrentKResource->resourceName(), errorMsg ) );
} else {
emit message( Error, i18n( "Migration of '%1' to native backend failed: %2",
mCurrentKResource->resourceName(), errorMsg ) );
}
if ( instance.isValid() ) {
AgentManager::self()->removeInstance( instance );
}
// native backend failed, try the bridge instead
if ( !mBridgingInProgress && mCurrentKResource && !mBridgeType.isEmpty() ) {
migrateToBridge( mCurrentKResource, mBridgeType );
return;
}
mBridgingInProgress = false;
mCurrentKResource = 0;
migrateNext();
}
void KResMigratorBase::setOmitClientBridge(bool b)
{
mOmitClientBridge = b;
}
void KResMigratorBase::migrationCompleted( const Akonadi::AgentInstance &instance, const QString &kresId, const QString &kresName )
{
// do an initial sync so the resource shows up in the folder tree at least
AgentInstance nonConstInstance = instance;
nonConstInstance.synchronize();
// check if this one was previously bridged and remove the bridge
KConfigGroup cfg( KGlobal::config(), QLatin1String("Resource ") + kresId );
const QString bridgeId = cfg.readEntry( "ResourceIdentifier", "" );
if ( bridgeId != instance.identifier() ) {
const AgentInstance bridge = AgentManager::self()->instance( bridgeId );
AgentManager::self()->removeInstance( bridge );
}
setMigrationState( kresId, Complete, instance.identifier(), mType );
emit message( Success, i18n( "Migration of '%1' succeeded.", kresName ) );
}
void KResMigratorBase::createKolabResource( const QString &kresId, const QString &kresName )
{
// check if kolab resource exists. If not, create one.
Akonadi::AgentInstance kolabAgent = Akonadi::AgentManager::self()->instance( QLatin1String("akonadi_kolabproxy_resource") );
if ( !kolabAgent.isValid() ) {
emit message( Info, i18n( "Attempting to create kolab resource" ) );
KJob * job = createAgentInstance(QLatin1String( "akonadi_kolabproxy_resource"), this, SLOT(kolabResourceCreated(KJob*)) );
job->setProperty( "kresId", kresId );
job->setProperty( "kresName", kresName );
} else {
migrationCompleted( kolabAgent, kresId, kresName );
migrateNext();
}
}
void KResMigratorBase::kolabResourceCreated( KJob *job )
{
const QString kresId = job->property( "kresId" ).value<QString>();
const QString kresName = job->property( "kresName" ).value<QString>();
if ( job->error() != 0 ) {
kError() << "Failed to create Kolab resource for" << kresName << "(id=" << kresId << "):" << job->errorString();
emit message( Error, i18n( "Failed to create kolab proxy resource." ) );
} else {
AgentInstanceCreateJob *createJob = qobject_cast<AgentInstanceCreateJob*>( job );
Q_ASSERT( createJob != 0 );
migrationCompleted( createJob->instance(), kresId, kresName );
}
migrateNext();
}