diff -r 000000000000 -r e6b17d312c8b ximpfw/presence/srcpresencedatamodel/presentitygroups/grouplistsubscriptionitem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ximpfw/presence/srcpresencedatamodel/presentitygroups/grouplistsubscriptionitem.cpp Thu Dec 17 08:54:49 2009 +0200 @@ -0,0 +1,320 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Presence Service Connection group list subscription implementation. +* +*/ + + +#include + +#include "grouplistsubscriptionitem.h" +#include "presenceinfofilterimp.h" +#include "ximpitemparent.h" +#include "ximppanics.h" +#include "ximppsccontext.h" +#include "documentutils.h" +#include "presentitygrouplisteventimp.h" +#include "presencetypehelpers.h" +#include "presentitygroupinfoimp.h" +//#include "ximpapieventbase.h" + +#include "ximptrace.h" +// --------------------------------------------------------------------------- +// CGroupListSubscriptionItem::CGroupListSubscriptionItem() +// --------------------------------------------------------------------------- +// +CGroupListSubscriptionItem::CGroupListSubscriptionItem( MXIMPItemParentBase& aParent ) +: CXIMPSubscriptionItemBase( aParent ) + { + } + + +// --------------------------------------------------------------------------- +// CGroupListSubscriptionItem::ConstructL() +// --------------------------------------------------------------------------- +// +void CGroupListSubscriptionItem::ConstructL() + { + BaseConstructL(); + // empty lists must always exist + iCurrentList = new ( ELeave) RPrGrpInfoImpArray; + + iCreated = new ( ELeave ) RPrGrpInfoImpArray; + iUpdated = new ( ELeave ) RPrGrpInfoImpArray; + iDeleted = new ( ELeave ) RPrGrpInfoImpArray; + } + + +// --------------------------------------------------------------------------- +// CGroupListSubscriptionItem::NewL() +// --------------------------------------------------------------------------- +// +CGroupListSubscriptionItem* CGroupListSubscriptionItem::NewLC( MXIMPItemParentBase& aParent ) + { + CGroupListSubscriptionItem* self = new( ELeave ) CGroupListSubscriptionItem( aParent ); + CleanupClosePushL( *self ); + self->ConstructL(); + return self; + } + + +// --------------------------------------------------------------------------- +// CGroupListSubscriptionItem::~CGroupListSubscriptionItem() +// --------------------------------------------------------------------------- +// +CGroupListSubscriptionItem::~CGroupListSubscriptionItem() + { + MXIMPItemParent* presCache = static_cast(iParent.GetInterface(PRESENCE_ITEM_PARENT)); + presCache->RemoveMe( this ); + + if( iCurrentList ) + { + iCurrentList->Close(); + } + delete iCurrentList; + + Clean(); + // just in case + delete iCreated; + delete iDeleted; + delete iUpdated; + } + +// --------------------------------------------------------------------------- +// CGroupListSubscriptionItem::SynthesiseSubscriptionEventTo() +// --------------------------------------------------------------------------- +// +void CGroupListSubscriptionItem::SynthesiseSubscriptionEventToL( + MXIMPPscContext* aContext, TBool aForceEvent ) + { + TRACE_1( _L("CGroupListSubscriptionItem::SynthesiseSubscriptionEventTo() aForce=%d"), aForceEvent ); + CXIMPDataSubscriptionStateImp* status = StatusLC( aContext ); + + if( status->DataState() == MXIMPDataSubscriptionState::EDataAvailable || aForceEvent ) + { + CPresentityGroupListEventImp* newEvent = CPresentityGroupListEventImp::NewL( + iCreated, + iUpdated, + iDeleted, + aForceEvent ? iCurrentList : NULL, + status + ); + CleanupStack::Pop( status ); + CleanupStack::PushL( newEvent ); + + MXIMPItemParent* presCache = static_cast(iParent.GetInterface(PRESENCE_ITEM_PARENT)); + presCache->AddEventL( *newEvent, aContext ); + + } + CleanupStack::PopAndDestroy(); //status || newEvent. Depending on branch. + } + + +// --------------------------------------------------------------------------- +// CGroupListSubscriptionItem::SetNewListL +// --------------------------------------------------------------------------- +// +EXPORT_C void CGroupListSubscriptionItem::SetNewListL( + RPrGrpInfoImpArray* aGroupList ) + { + TRACE_1( _L("CGroupListSubscriptionItem::SetNewListL() aGroupList Count=%d"), aGroupList->Count() ); + // we will eventually take ownership to this + RPrGrpInfoImpArray* tmp = aGroupList; + CleanupDeletePushL( tmp ); + + // the list is already sorted. when a copy was made in datacacheimp, the + // InsertInOrder method was used + + // The below algorithm has complexity of (roughly): + // - aGroupList length M + // - iCurrentList final length N + // + // Final complexity: + // M*( 1 // indexed accessor + // + logN // find (ordered) + // + logN // insert in order (find+insert) + // + O(1) // delete + // + O(1) // remove + // ) + O(1) // updating iDeleted and iCurrentList + // = M(2logN+3) + 2MlogN+3M = O(cMlogM). + // + // Should be fast enough. The complexity is not fully accurate because + // array size grows as we insert into it. + // + TLinearOrder + linearOrder( CPresentityGroupInfoImp::GroupIdLinearOrder ); + + for ( TInt i = 0; i < tmp->Count(); i++ ) + { + // compare against current list + CPresentityGroupInfoImp* info = (*tmp)[ i ]; + TInt pos = iCurrentList->FindInOrder( info, linearOrder ); + + if ( pos == KErrNotFound ) + { + // not found in current list + // so must be a fresh created list name + iCreated->InsertInOrderL( info, linearOrder ); + } + else + { + // found in current list, so it must be an updated list name + iUpdated->InsertInOrderL( info, linearOrder ); + + delete (*iCurrentList)[ pos ]; + iCurrentList->Remove( pos ); + + // we must remove the found ones from iCurrentList, + // otherwise we will not know what was left. and finding out + // the deleted items will be difficult. + } + } + + // what's left in iCurrentList contains the deleted ones. + delete iDeleted; + iDeleted = iCurrentList; + + // the given list becomes the new list + iCurrentList = tmp; + CleanupStack::Pop( tmp ); + iSubscriptionState->SetDataStateL( MXIMPDataSubscriptionState::EDataAvailable ); + } + +// --------------------------------------------------------------------------- +// CGroupListSubscriptionItem::SetCreatedListL +// --------------------------------------------------------------------------- +// +EXPORT_C void CGroupListSubscriptionItem::SetCreatedListL( + RPrGrpInfoImpArray* aGroupList ) + { + TRACE_1( _L("CGroupListSubscriptionItem::SetCreatedListL() aGroupList Count=%d"), aGroupList->Count() ); + // we took ownership to the given list + RPrGrpInfoImpArray* tmp = aGroupList; + CleanupDeletePushL( tmp ); + + // see also SetNewListL. + + // the list is already sorted. when a copy was made in datacacheimp, the + // InsertInOrder method was used + TLinearOrder + linearOrder( CPresentityGroupInfoImp::GroupIdLinearOrder ); + + // update the list of created and updated groups + for ( TInt i = 0; i < tmp->Count(); i++ ) + { + // compare against current list + CPresentityGroupInfoImp* info = (*tmp)[ i ]; + TInt pos = iCurrentList->FindInOrder( info, linearOrder ); + + if ( pos == KErrNotFound ) + { + // not found in current list + // so must be a fresh created list name. + // this cannot come when the HandleDisplayNameUpdatedListL method + // is called. + iCurrentList->InsertInOrderL( info, linearOrder ); + ( *tmp )[ i ] = NULL; + iCreated->InsertInOrderL( info, linearOrder ); + } + else + { + // This can be checked if really had changed if needed. Now + // we trust server that changes are reasonable. + + // change the display name of the updated group in the current list + (*iCurrentList)[ pos ]->SetGroupDisplayNameL( info->GroupDisplayName() ); + + // found in current list, so it must be an updated list name + iUpdated->InsertInOrderL( (*iCurrentList)[ pos ], linearOrder ); + } + } + + // current list may get updated display name to the existing elements, + // otherwise the list is unchanged. list of deleted groups stays empty. + // updated and created lists were updated. the input parameter list can be + // deleted + CleanupStack::PopAndDestroy( tmp ); + iSubscriptionState->SetDataStateL( MXIMPDataSubscriptionState::EDataAvailable ); + } + +// --------------------------------------------------------------------------- +// CGroupListSubscriptionItem::SetDeletedListL +// --------------------------------------------------------------------------- +// +EXPORT_C void CGroupListSubscriptionItem::SetDeletedListL( + RPrGrpInfoImpArray* aGroupList ) + { + TRACE_1( _L("CGroupListSubscriptionItem::SetDeletedListL() aGroupList Count=%d"), aGroupList->Count() ); + // we will eventually take ownership to this + RPrGrpInfoImpArray* tmp = aGroupList; + CleanupDeletePushL( tmp ); + + // see also SetNewListL. + + // the list is already sorted. when a copy was made in datacacheimp, the + // InsertInOrder method was used + TLinearOrder + linearOrder( CPresentityGroupInfoImp::GroupIdLinearOrder ); + + // remove the deleted ones from the current list + for ( TInt i = 0; i < tmp->Count(); i++ ) + { + // compare against current list + CPresentityGroupInfoImp* info = (*tmp)[ i ]; + TInt pos = iCurrentList->FindInOrder( info, linearOrder ); + + // found in current list, so it must be a deleted list name + if ( pos != KErrNotFound ) + { + // remove from current list + delete (*iCurrentList)[ pos ]; + iCurrentList->Remove( pos ); + } + } + + // the given list becomes the new list of + // deleted ones + delete iDeleted; + iDeleted = tmp; + CleanupStack::Pop( tmp ); + iSubscriptionState->SetDataStateL( MXIMPDataSubscriptionState::EDataAvailable ); + } + +// --------------------------------------------------------------------------- +// CGroupListSubscriptionItem::Clean +// --------------------------------------------------------------------------- +// +EXPORT_C void CGroupListSubscriptionItem::Clean() + { + TRACE( _L("CGroupListSubscriptionItem::Clean()") ); + // empty the lists. + // the lists must stay valid for use + + // iCreated and iUpdated are collection from currentlist. Do not delete items. + // iDeleted is only place for items. Delete those. + + iCreated->Reset(); + iUpdated->Reset(); + iDeleted->Close(); + } + +// --------------------------------------------------------------------------- +// CGroupListSubscriptionItem::CleanExpired() +// --------------------------------------------------------------------------- +// +void CGroupListSubscriptionItem::CleanExpired() + { + + } +// End of file