private void GetConnections() { if (IsCancelRequested()) return; SetMessage(ResourceStrings.Loading, ResourceStrings.Connections, 0, 0); string values = ""; string names = ""; foreach (string key in this.idIndexConnectionLoad.Keys) { values += "<value>" + ((Entity)idIndexConnectionLoad[key].SourceData).Id + "</value>"; names += idIndexConnectionLoad[key].Name + " , "; } this.idIndexConnectionLoad.Clear(); if (values != "") { // Clear out the parties so we don't load again string fetchXml = string.Format(Config.ConnectionFetchXml, values); OrganizationServiceProxy.BeginRetrieveMultiple(fetchXml, delegate(object state2) { if (IsCancelRequested()) return; EntityCollection rootResults2 = null; int total = 0; try { rootResults2 = OrganizationServiceProxy.EndRetrieveMultiple(state2, typeof(Connection)); total = rootResults2.Entities.Count; } catch (Exception ex) { ReportError(ex); return; } DelegateItterator.CallbackItterate(delegate(int index, Action nextCallBack, ErrorCallBack errorCallBack) { if (IsCancelRequested()) return; ProcessConnection(rootResults2, index, total); nextCallBack(); }, total, delegate() { _currentLoad = null; CallNextProcessQueue(); return; }, delegate(Exception ex) { }); }); } else { _currentLoad = null; CallNextProcessQueue(); return; } }
private void GetActivities() { if (IsCancelRequested()) return; SetMessage(ResourceStrings.Loading, ResourceStrings.Activities, 0, 0); string parties = ""; foreach (string key in this.idIndexActivityLoad.Keys) { parties += "<value>" + ((Entity)idIndexActivityLoad[key].SourceData).Id + "</value>"; } this.idIndexActivityLoad.Clear(); if (parties != "") { string fetchXml = string.Format(Config.AcitvityFetchXml, parties); OrganizationServiceProxy.BeginRetrieveMultiple(fetchXml, delegate(object state2) { if (IsCancelRequested()) return; EntityCollection rootResults2; int total = 0; try { rootResults2 = OrganizationServiceProxy.EndRetrieveMultiple(state2, typeof(Entity)); total = rootResults2.Entities.Count; } catch (Exception ex) { ReportError(ex); return; } DelegateItterator.CallbackItterate(delegate(int index, Action nextCallBack, ErrorCallBack errorCallBack) { if (IsCancelRequested()) return; ProcessActivity(rootResults2, index, total); nextCallBack(); }, total, delegate() { // Add in pending links // Load the accounts referenced by activity parties - both directly and directly via other contacts // For each account - provide a link to exapand further LoadUsers(delegate() { _currentLoad = null; CallNextProcessQueue(); return; }); }, delegate(Exception ex) { }); }); } else { _currentLoad = null; CallNextProcessQueue(); return; } }
private void ProcessQueryResults(QueuedLoad load, EntityCollection rootResults) { int total = rootResults.Entities.Count; int index = 0; List<string> ids = new List<string>(); foreach (Entity record in rootResults.Entities) { if (IsCancelRequested()) return; SetMessage(ResourceStrings.Processing, load.Entity.DisplayName, index, total); // Check if this is a pending load - and remove it RemovePendingID(record.LogicalName, record.Id); index++; ids.Add(record.Id); string name = record.GetAttributeValueString(load.Entity.NameAttribute == null ? "name" : load.Entity.NameAttribute); // If this is the root entity then set the window title bool rootNode = (RootEntityId.Value.ToLowerCase().Substr(1, 36) == record.Id.ToLowerCase()); if (rootNode) { Window.Document.Title = name; } if (!IsAlsoAUser(record) && !IndexContainsEntity(record)) { EntityNode newNode = new EntityNode(name, 100); newNode.Root = rootNode; newNode.X = _startX; newNode.Y = _startY; newNode.SourceData = record; if (!AddEntity(record, newNode, load.Entity, false)) return; // Add User reference for owner EntityReference owner = record.GetAttributeValueEntityReference("ownerid"); if (owner != null) { UserOrTeam user = GetUserOrTeamReference(owner); user.Parties[record.Id.ToString()] = record.ToEntityReference(); } } } Trace("Linking to Parents {0} {1} records", new object[] { load.Entity.LogicalName, rootResults.Entities.Count }); index = 0; // Add the parent links foreach (Entity record in rootResults.Entities) { if (IsCancelRequested()) return; SetMessage(ResourceStrings.Linking, load.Entity.DisplayName, index, total); EntityNode thisNode = GetEntity(record); if (thisNode == null) continue; // Add the heiarchical links EntityNode parentNode = GetParentEntity(record, load.Entity.ParentAttributeId, load.Entity.LogicalName); if (parentNode != null) { // Create Link AddLink(thisNode, parentNode, false); } // Add the backlinks // e.g. if this is a contact then back link via the parentcustomerid field if (load.Join != null) { Trace("Adding backlinks {0}->{1}", new object[] { load.Entity.LogicalName, load.Join.RightEntity }); EntityNode joinedNode = GetParentEntity(record, load.Join.RightAttribute, load.Join.RightEntity); if (joinedNode != null) { AddLink(thisNode, joinedNode, false); } else { // Add pending link } } } if (ids.Count > 0) { // add links if (load.Entity.Joins != null) { Trace("Adding Joins to {0}", new object[] { ids.Count }); foreach (JoinSetting join in load.Entity.Joins) { EntitySetting joinedTo = Config.Entities[join.RightEntity]; if (joinedTo != null) { Trace("Queing Join {0}.{1} -> {2}.{3} {4}", new object[] { join.LeftEntity, join.LeftAttribute, join.RightEntity, join.RightAttribute, join.Name }); Queue.Enqueue(new QueuedLoad(ids, joinedTo, join)); } } } if (load.Entity.LoadActivities) { Queue.Enqueue(new QueuedLoad(ids, load.Entity, NewJoinSetting(load.Entity.LogicalName, "activity"))); } if (load.Entity.LoadConnections) { Queue.Enqueue(new QueuedLoad(ids, load.Entity, NewJoinSetting(load.Entity.LogicalName, "connection"))); } } _currentLoad = null; CallNextProcessQueue(); }
public void ProcessQueue() { if (IsCancelRequested()) return; if (!IsBusy.GetValue()) IsBusy.SetValue(true); QueueIterations++; Trace("--------------------{0}", new object[] { QueueIterations }); string queueString = ""; foreach (QueuedLoad load in (QueuedLoad[])(object)Queue) { queueString += load.Entity.LogicalName; if (load.Join != null) { if (load.Join.RightEntity == "connection" || load.Join.RightEntity == "activity") { queueString += ("[" + load.Join.RightEntity + "]"); } else { queueString += ("[" + load.Join.LeftEntity + "." + load.Join.LeftAttribute + " = " + load.Join.RightEntity + "." + load.Join.RightAttribute + "]"); } } queueString += " | "; } Trace("Queue = {0}", new object[] { queueString }); Trace("--------------------{0}", new object[] { QueueIterations }); if (QueueIterations > MaxQueueItems) { PauseLoadWithMessage(ResourceStrings.PossibleInfiniteLoop); QueueIterations = 0; return; } // Pop settings from queue if (_currentLoad == null) { _currentLoad = Queue.Dequeue(); if (_currentLoad == null) { AddPendingQueuedLoads(); // End of load queue RaiseOnNodesChanged(); _currentLoad = Queue.Dequeue(); if (_currentLoad == null) { IsBusy.SetValue(false); Trace("End of Queue", null); return; } } } // Check if we can merge the following load TryToShrinkQueue(); if (_currentLoad.Join == null) { if (!NextIteration()) return; Trace("Entity Query {0} ", new object[] { _currentLoad.Entity.LogicalName }); SetMessage("Loading", _currentLoad.Entity.DisplayName, 0, 0); List<string> correctedIds = new List<string>(); foreach (string id in _currentLoad.Ids) { string key = GetIdIndexString(_currentLoad.Entity.LogicalName, id); if (idIndexQueried.ContainsKey(key)) { // This ID has already been loaded - so remove it from pending and don't query RemovePendingID(_currentLoad.Entity.LogicalName, id); continue; } else idIndexQueried[key] = key; correctedIds.Add(id); } if (correctedIds.Count > 0) { string op = _currentLoad.Entity.Hierarchical ? "eq-above-under" : "eq"; string idValues = GetValues(_currentLoad.Entity.LogicalName, _currentLoad.Entity.IdAttribute, op, correctedIds); string rootQuery = String.Format("\n\n<!-- " + IsBusyMessage.GetValue() + "-->\n\n" + _currentLoad.Entity.FetchXml, idValues); LoadFetchXml(_currentLoad, rootQuery); } else { _currentLoad = null; CallNextProcessQueue(); return; } } else if (_currentLoad.Join.RightEntity == "activity") { _currentLoad = null; GetActivities(); return; } else if (_currentLoad.Join.RightEntity == "connection") { _currentLoad = null; GetConnections(); return; } else if (_currentLoad.Join != null) { Trace("Join Query {0}->{1}", new object[] { _currentLoad.Join.LeftEntity, _currentLoad.Join.RightEntity }); // Load join SetMessage("Joining", _currentLoad.Entity.DisplayName, 0, 0); if (_currentLoad.Ids.Count > 0) { List<string> joinIds = new List<string>(); foreach (string id in _currentLoad.Ids) { // Is the id already loaded? EntityNode record = idIndex[GetIdIndexKeyEntityRef(new EntityReference(new Guid(id), _currentLoad.Join.LeftEntity, null))]; if (record != null) { object idValue = ((Entity)record.SourceData).GetAttributeValue(_currentLoad.Join.LeftAttribute); if (idValue != null) { if (idValue.GetType() == typeof(Guid)) { joinIds.Add(((Guid)idValue).Value); } else if (idValue.GetType() == typeof(EntityReference)) { joinIds.Add(((EntityReference)idValue).Id.Value); } } } } if (joinIds.Count > 0) { Trace("Found {0} Join IDs", new object[] { joinIds.Count }); JoinSetting join = _currentLoad.Join; // Check if the key is the primary key - if so we can use the hierarchical query string op = (_currentLoad.Entity.Hierarchical && join.RightAttribute == _currentLoad.Entity.IdAttribute) ? "eq-above-under" : "eq"; // Remove any ids already joined or exlcuded - this removes infinite loops in joins List<string> joinIdsCorrected = new List<string>(); if (join.ExcludeIds == null) { join.ExcludeIds = new Dictionary<string, string>(); } foreach (string id in joinIds) { if (!join.ExcludeIds.ContainsKey("ID" + id)) { joinIdsCorrected.Add(id); join.ExcludeIds["ID" + id] = id; } } if (joinIdsCorrected.Count > 0) { Trace("Correted Join IDS {0}", new object[] { joinIdsCorrected.Count }); string joinXml = string.Format( "\n\n<!-- " + IsBusyMessage.GetValue() + "-->\n\n" + _currentLoad.Entity.FetchXml, GetValues(_currentLoad.Entity.LogicalName, _currentLoad.Join.RightAttribute, op, joinIdsCorrected)); LoadFetchXml(_currentLoad, joinXml); } else { Trace("Join supressed due to infinite loop possibility", null); _currentLoad = null; CallNextProcessQueue(); } return; } else { Trace("Nothing to Load", null); // Nothing to load _currentLoad = null; CallNextProcessQueue(); return; } } else { CallNextProcessQueue(); return; } } }
private void LoadFetchXml(QueuedLoad load, string rootQuery) { // Get all the related records to the root SetMessage(ResourceStrings.Querying, load.Entity.DisplayName, 0, 0); OrganizationServiceProxy.BeginRetrieveMultiple(rootQuery, delegate(object state) { try { EntityCollection rootResults = OrganizationServiceProxy.EndRetrieveMultiple(state, typeof(Entity)); Trace("Query for {0} returned {1} records", new object[] { load.Entity.LogicalName, rootResults.Entities.Count }); ProcessQueryResults(load, rootResults); } catch (Exception ex) { ReportError(ex); return; } }); }