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 <badesca.h>
+
+#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<MXIMPItemParent*>(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<MXIMPItemParent*>(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<CPresentityGroupInfoImp>
+ 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<CPresentityGroupInfoImp>
+ 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<CPresentityGroupInfoImp>
+ 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