/// <summary> /// Non-deserializing constructor. This constructor can throw. /// </summary> public Workspace(WorkspaceManager wm, WmKas kas, UInt64 internalID, KwsCredentials creds) { Kas = kas; InternalID = internalID; CoreData.Credentials = creds; if (creds != null) Debug.Assert(Kas.KasID.CompareTo(creds.KasID) == 0); Initialize(wm); SetDirty(); }
/// <summary> /// Deserializing constructor. /// </summary> public Workspace(SerializationInfo info, StreamingContext context) { Int32 version = info.GetInt32("WorkspaceVersion"); InternalID = info.GetUInt64("m_internalID"); // This is an old workspace which needs to be rebuilt. if (version < 5) { FileKwsDeserializer dsr = (FileKwsDeserializer)KwmSpawner.Instance.KwmDsr.CurKwsDsr; // Get the folder information. try { dsr.FolderID = UInt64.Parse(info.GetString("m_parentFolderID").Substring(6)); dsr.FolderIndex = info.GetInt32("m_indexInFolder"); } catch (Exception) { } // Update the credentials. CoreData.Credentials = ((Credentials)info.GetValue("credentials", typeof(Credentials))).newCreds; // Set the rebuild information. MainStatus = KwsMainStatus.RebuildRequired; KwsRebuildInfo rebuildInfo = CoreData.RebuildInfo; rebuildInfo.DeleteCachedEventsFlag = true; rebuildInfo.DeleteLocalDataFlag = false; rebuildInfo.UpgradeFlag = true; if (version >= 3) { AppKfs appKfs = (AppKfs)info.GetValue("m_appKfs", typeof(AppKfs)); appKfs.Share.CompatLastKwsEventID = info.GetUInt64("m_lastEventID"); appKfs.Initialize(this); AppTree[KAnpType.KANP_NS_KFS] = appKfs; } } // Pre-desintermediation and later. else { MainStatus = (KwsMainStatus)info.GetValue("MainStatus", typeof(KwsMainStatus)); KAnpState = (KwsKAnpState)info.GetValue("KAnpState", typeof(KwsKAnpState)); CoreData = (KwsCoreData)info.GetValue("CoreData", typeof(KwsCoreData)); UserTask = (KwsTask)info.GetValue("UserTask", typeof(KwsTask)); // Post-desintermediation. if (version >= 6) { KasLoginHandler = (KwsKasLoginHandler)info.GetValue("KasLoginHandler", typeof(KwsKasLoginHandler)); AppException = (Exception)info.GetValue("AppException", typeof(Exception)); } } // Create a temporary KAS object. Kas = new WmKas(CoreData.Credentials.KasID); }
/// <summary> /// Unregister the WmKas object specified if there are no more references /// to it and it is disconnected. /// </summary> public void RemoveKasIfNoRef(WmKas kas) { if (kas.KwsTree.Count == 0 && kas.ConnStatus == KasConnStatus.Disconnected) { KasTree.Remove(kas.KasID); SetDirty(); } }
/// <summary> /// Create the WmKas object specified if it does not exist, /// and return a reference to the WmKas object specified. /// </summary> private WmKas GetOrCreateKas(KasIdentifier kasID) { if (!KasTree.ContainsKey(kasID)) { KasTree[kasID] = new WmKas(kasID); } return KasTree[kasID]; }
/// <summary> /// Process an ANP reply received from the KCM. /// </summary> private void ProcessKcmAnpReply(WmKas kas, AnpMsg msg) { m_wm.UiBroker.OnAnpMsgTransfer(kas, msg); // We have no knowledge of the query. Ignore the reply. if (!kas.QueryMap.ContainsKey(msg.ID)) return; // Retrieve and remove the query from the query map. WmKasQuery query = kas.QueryMap[msg.ID]; query.RemoveFromQueryMap(); // Set the reply in the query. query.Res = msg; // We don't have non-workspace-related replies yet. Debug.Assert(query.Kws != null); // Dispatch the message to the workspace. query.Kws.Sm.HandleAnpReply(query); }
public WmKasQuery(AnpMsg cmd, Object[] metaData, KasQueryDelegate callback, WmKas kas, Workspace kws, KwsApp app, bool clearOnLogoutFlag) : base(cmd, metaData, callback) { Kas = kas; Kws = kws; App = app; ClearOnLogoutFlag = clearOnLogoutFlag; }
/// <summary> /// Disconnect a KAS if it is connecting/connected. /// </summary> private void DisconnectKas(WmKas kas) { if (kas.ConnStatus == KasConnStatus.Disconnecting || kas.ConnStatus == KasConnStatus.Disconnected) return; // Send a disconnection request to the KCM. kas.ConnStatus = KasConnStatus.Disconnecting; m_wkb.RequestKasDisconnect(kas.KasID); // Notify every workspace that the KAS is disconnecting. // The workspaces will request a UI update themselves. foreach (Workspace kws in kas.KwsTree.Values) kws.Sm.HandleKasDisconnecting(); }
/// <summary> /// Process an ANP event received from the KCM. /// </summary> private void ProcessKcmAnpEvent(WmKas kas, AnpMsg msg) { m_wm.UiBroker.OnAnpMsgTransfer(kas, msg); // Get the external workspace ID referred to by the event. UInt64 externalID = msg.Elements[0].UInt64; // Locate the workspace. Workspace kws = kas.GetWorkspaceByExternalID(externalID); // No such workspace, bail out. if (kws == null) return; // Dispatch the event to its workspace. kws.Sm.HandleAnpEvent(msg); }
/// <summary> /// Connect a KAS if it is disconnected. /// </summary> private void ConnectKas(WmKas kas) { if (kas.ConnStatus != KasConnStatus.Disconnected) return; // Clear the current error, but not the failed connection count. kas.ClearError(false); // Send a connection request. kas.ConnStatus = KasConnStatus.Connecting; m_wkb.RequestKasConnect(kas.KasID); // Update the UI (workspaces are now connecting). m_wm.UiBroker.RequestBrowserUiUpdate(false); m_wm.UiBroker.RequestSelectedKwsUiUpdate(); }
/// <summary> /// Assign an error to a KAS. /// </summary> private void AssignErrorToKas(WmKas kas, Exception ex, bool connectFailureFlag) { kas.SetError(ex, DateTime.Now, connectFailureFlag); }
/// <summary> /// Clear the errors associated to the KAS specified, reset the number /// of failed connection attempts to 0 and request a run of the state /// machine, if required. This can be used to force a KAS to reconnect /// sooner than usual. /// </summary> public void ResetKasFailureState(WmKas kas) { if (kas.FailedConnectCount != 0 || kas.ErrorEx != null) { kas.ClearError(true); RequestRun("cleared KAS error"); } }
/// <summary> /// Handle non-recoverable KAS errors (aside of disconnection notices). /// This method should be called when a KAS behaves badly. /// </summary> public void HandleTroublesomeKas(WmKas kas, Exception ex) { // Assign the error to the KAS. AssignErrorToKas(kas, ex, false); // Disconnect the KAS. DisconnectKas(kas); }
/// <summary> /// This method should be called when an ANP message is transferred to /// or from a KAS. /// </summary> public void OnAnpMsgTransfer(WmKas kas, AnpMsg msg) { String text = "KAS " + kas.KasID.Host + " msg " + msg.ID + ": " + KAnpType.TypeToString(msg.Type); Logging.Log(text); }