public virtual void AddConnection(Connection newConnection)
        {
            // Deriving classes are required to update their backing store)

            //Add to isolated storage
            AddNewUserConnection(newConnection);
        }
 public void DeleteUserConnection(Connection connection)
 {
     List<Connection> userConnections = GetUserConnections();
     foreach (Connection item in userConnections)
     {
         if (item.Url == connection.Url)
         {
             userConnections.Remove(item);
             SaveUserConnections(userConnections);
             break;
         }
     }
 }
 public void AddNewUserConnection(Connection newConnection)
 {
     List<Connection> userConnections = GetUserConnections();
     bool found = false;
     foreach (Connection item in userConnections)
     {
         if (item.Url == newConnection.Url)
         {
             found = true;
             break;
         }
     }
     if (!found)
     {
         userConnections.Add(newConnection);
         SaveUserConnections(userConnections);
     }
 }
        public virtual void DeleteConnection(Connection oldConnection)
        {
            // NO-OP (Derieving classes are required to update their backing store)

            //Delete from isolated storage
            DeleteUserConnection(oldConnection);
        }
        private async void GetResourceFromNextDataSourceInQueue(Queue<IDataSourceWithResources> dataSources, Connection connection, bool isNewConnection)
        {
            IDataSourceWithResources dataSource = dataSources.Dequeue();
            connection.ConnectionType = DataSourceProvider.MapDataSourceToConnectionType(dataSource);
            currentActiveConnectionDataSource = dataSource;

            // Analyze the connection string and try to determine if this is a server or a more specific endpoint such as an
            // individual map service, layer, gp service, gp tool, etc.
            Resource res = dataSource.GetResource(connection.Url, connection.ProxyUrl);
            if (res.ResourceType == ResourceType.Server)
            {
                // Get the URL to use for token authentication
                _currentRestUrl = 
                    await ArcGISServerDataSource.GetServicesDirectoryURL(connection.Url, connection.ProxyUrl);
                // Initialize the command allowing users to sign-in
                await initializeSignInCommand(_currentRestUrl, connection.ProxyUrl);

                dataSource.GetCatalogCompleted += (o, e) =>
                {
                    dataSource_GetCatalogCompleted(o, e);
                };
                dataSource.GetCatalogFailed += (o, e) =>
                {
                    // Try the next datasource                
                    tryGetResourceFromNextDataSourceInQueue(dataSources, connection, isNewConnection);
                };
                dataSource.GetCatalog(connection.Url, connection.ProxyUrl, filter, new object[] { connection, isNewConnection });
            }
            else
            {
                // If the filter permits this kind of resource, then obtain child information
                if (ApplyFilterToResourceType(res, filter))
                {
                    dataSource.GetChildResourcesCompleted += (o, e) =>
                    {
                        resource_GetChildResourcesCompleted(o, e);
                    };
                    dataSource.GetChildResourcesFailed += (o, e) =>
                    {
                        // Code 499 == token authentication failed.  So the endpoint exists, but the 
                        // token was not retrieved.  In this case, don't try other data source types.
                        if (e.StatusCode == 499) 
                            connectionFailed(connection, false);
                        else // Try the next datasource                
                            tryGetResourceFromNextDataSourceInQueue(dataSources, connection, isNewConnection);
                    };

                    // Before connecting to the server to get its list of services, try authenticating
                    // with the existing set of credentials in the application.  This makes it so that
                    // if a user has signed in to another server with a username and password that is
                    // valid for this server, it will authenticate using those credentials automatically
                    IdentityManager.Credential newCred = await ApplicationHelper.TryExistingCredentials(connection.Url, connection.ProxyUrl);
                    if (newCred != null)
                    {
                        // If authentication is successful and the URL belong to the current ArcGIS Portal,
                        // use the credentials to also sign into the application environment's current 
                        // Portal instance
                        if (await connection.Url.IsFederatedWithPortal())
                            await ApplicationHelper.SignInToPortal(newCred);

                        // If a credential for the URL has not already be saved into the application 
                        // environment, do so now
                        if (!UserManagement.Current.Credentials.Any(c => c.Url != null 
                        && c.Url.Equals(newCred.Url, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(c.Token)))
                            UserManagement.Current.Credentials.Add(newCred);
                    }
                    dataSource.GetChildResourcesAsync(res, filter, new object[] { treeResources, dataSource, res, connection });
                }
                else
                {
                    // If filtering prevents this kind of item in this context then create a tree node to indicate the error.
                    showHideProgressIndicator(true);
                    enableDisableUrlEntryUI(false);

                    TreeViewItem tvi = CreateTreeNodeWhenNoItems();
                    treeResources.Items.Add(tvi);
                }
            }
        }
 private void connectionFailed(Connection connection, bool showErrorMessage = true)
 {
     enableDisableUrlEntryUI(false);
     string message = string.Format(LocalizableStrings.ServiceConnectionErrorDuringInit, connection.Url);
     if (showErrorMessage)
         MessageBoxDialog.Show(message, LocalizableStrings.ServiceConnectionErrorCaption, MessageBoxButton.OK);
     OnConnectionRemoved(new ConnectionRemovedEventArgs() { Connection = connection });
     OnGetCatalogFailed(new core.ExceptionEventArgs(new Exception(message), null));
 }
 private void tryGetResourceFromNextDataSourceInQueue(Queue<IDataSourceWithResources> dataSources, Connection connection, bool isNewConnection)
 {
     if (dataSources == null || dataSources.Count < 1)
     {
         connectionFailed(connection);
         return;
     }
     GetResourceFromNextDataSourceInQueue(dataSources, connection, isNewConnection);
 }
        private async void getDataFromConnection(Connection connection, bool isNewConnection)
        {
            if (connection == null)
                return;

            if (DataSourceProvider == null)
                throw new InvalidOperationException("Must specify DataSourceProvider");

            // Reset whether endpoint needs credentials to access sevices
            NeedsServerCredentials = false;

            if (connection.ConnectionType == ConnectionType.Unknown)
            {
                // Try datasources 1, by 1
                Queue<IDataSourceWithResources> dataSources = new Queue<IDataSourceWithResources>();
                foreach (IDataSourceWithResources dataSource in DataSourceProvider.GetAllDataSourcesWhichSupportResources())
                {
                    dataSources.Enqueue(dataSource);
                }
                tryGetResourceFromNextDataSourceInQueue(dataSources, connection, isNewConnection);
            }
            else
            {
                ESRI.ArcGIS.Mapping.Core.DataSources.DataSource dataSource = DataSourceProvider.CreateNewDataSourceForConnectionType(connection.ConnectionType);
                if (dataSource == null)
                    throw new Exception("Unable to retrieve datasource for connection type " + connection.ConnectionType);

                IDataSourceWithResources dataSourceWithResource = dataSource as IDataSourceWithResources;
                if (dataSourceWithResource == null)
                    throw new Exception("The connection type " + connection.ConnectionType + " does not correspond to a datasource (" + dataSource.ID + ") which has resources");

                currentActiveConnectionDataSource = dataSourceWithResource;

                // Analyze the connection string and try to determine if this is a server or a more specific endpoint such as an
                // individual map service, layer, gp service, gp tool, etc.
                Resource res = dataSourceWithResource.GetResource(connection.Url, connection.ProxyUrl);
                if (res.ResourceType == ResourceType.Server)
                {
                    // Get the URL to use for token authentication
                    _currentRestUrl = 
                        await ArcGISServerDataSource.GetServicesDirectoryURL(connection.Url, connection.ProxyUrl);
                    // Initialize the command allowing users to sign-in
                    await initializeSignInCommand(_currentRestUrl, connection.ProxyUrl);

                    dataSourceWithResource.GetCatalogCompleted += (o, e) =>
                    {
                        dataSource_GetCatalogCompleted(o, e);
                    };
                    dataSourceWithResource.GetCatalogFailed += (o, e) =>
                    {
                        enableDisableUrlEntryUI(false);
                        Logger.Instance.LogError(e.Exception);

                        bool displayErrorMessage = e is GetCatalogFailedEventArgs && !((GetCatalogFailedEventArgs)e).DisplayErrorMessage;
                        if (!displayErrorMessage)
                        {
                            string message = string.Format(LocalizableStrings.ServiceConnectionErrorDuringInit, connection.Url);
                            MessageBoxDialog.Show(message, LocalizableStrings.ServiceConnectionErrorCaption, MessageBoxButton.OK);
                        }
                        OnConnectionRemoved(new ConnectionRemovedEventArgs() { Connection = connection });
                    };
                    dataSourceWithResource.GetCatalog(connection.Url, connection.ProxyUrl, filter, new object[] { connection, isNewConnection, Dispatcher });
                }
                else
                {
                    // If the filter permits this kind of resource, then obtain child information
                    if (ApplyFilterToResourceType(res, filter))
                    {
                        dataSourceWithResource.GetChildResourcesCompleted += (o, e) =>
                        {
                            resource_GetChildResourcesCompleted(o, e);
                        };
                        dataSourceWithResource.GetChildResourcesFailed += (o, e) =>
                        {
                            Logger.Instance.LogError(e.Exception);
                            MessageBoxDialog.Show("Unable to retrieve resources." + Environment.NewLine + e.Exception != null ? e.Exception.Message : "");
                        };
                        
                        // Before connecting to the server to get its list of services, try authenticating
                        // with the existing set of credentials in the application.  This makes it so that
                        // if a user has signed in to another server with a username and password that is
                        // valid for this server, it will authenticate using those credentials automatically
                        IdentityManager.Credential newCred = 
                            await ApplicationHelper.TryExistingCredentials(connection.Url, connection.ProxyUrl);
                        if (newCred != null)
                        {
                            // If authentication is successful and the URL belong to the current ArcGIS Portal,
                            // use the credentials to also sign into the application environment's current 
                            // Portal instance
                            if (await connection.Url.IsFederatedWithPortal())
                                await ApplicationHelper.SignInToPortal(newCred);

                            // If a credential for the URL has not already be saved into the application 
                            // environment, do so now
                            if (!!UserManagement.Current.Credentials.Any(c => c.Url != null 
                            && c.Url.Equals(newCred.Url, StringComparison.OrdinalIgnoreCase) 
                            && !string.IsNullOrEmpty(c.Token)))
                                UserManagement.Current.Credentials.Add(newCred);
                        }
                        dataSourceWithResource.GetChildResourcesAsync(res, filter, new object[] { treeResources, dataSourceWithResource, res, connection });
                    }
                    else
                    {
                        // If filtering prevents this kind of item in this context then create a tree node to indicate the error.
                        showHideProgressIndicator(true);
                        enableDisableUrlEntryUI(false);

                        TreeViewItem tvi = CreateTreeNodeWhenNoItems();
                        treeResources.Items.Add(tvi);
                    }
                }
            }
        }
        private void deleteConnection(Connection connection)
        {
            if (connection == null)
                return;

            MessageBoxDialog.Show(LocalizableStrings.DeleteConnectionPrompt, LocalizableStrings.DeleteConnectionCaption, MessageBoxButton.OKCancel,
                            new MessageBoxClosedEventHandler(delegate(object obj, MessageBoxClosedArgs args1)
                            {
                                if (args1.Result == MessageBoxResult.OK)
                                {
                                    if (Connections != null)
                                        Connections.Remove(connection);
                                    if (ConnectionsProvider != null)
                                        ConnectionsProvider.DeleteConnection(connection); // inform the provider about the deleted connection
                                    if (ConnectionRemoved != null)
                                        ConnectionRemoved(this, new ConnectionRemovedEventArgs() { Connection = connection });
                                }
                            }));
        }
        private void getResourcesForUrl(string url)
        {
            // Remove any leading or trailing spaces as this will cause an exception when parsing this
            // or trying to convert it into a URI
            url = url.Trim();

            _currentInputUrl = url;

            if (currentActiveConnectionDataSource != null)
                currentActiveConnectionDataSource.CancelAllCurrentRequests();

            if (treeResources != null)
                treeResources.Items.Clear();

            if (DropDownToggle != null)
                DropDownToggle.IsChecked = false;

            if (string.IsNullOrEmpty(url)) return;

            bool connectionExists = false;
            if (Connections != null)
                connectionExists = Connections.FirstOrDefault<Connection>(c => c != null && (string.Compare(c.Url, url, StringComparison.InvariantCultureIgnoreCase) == 0)) != null;

            enableDisableUrlEntryUI(true);
            Connection newConnection = new Connection()
            {
                ConnectionType = ConnectionType.Unknown,
                Name = url,
                Url = url,
            };
            if (ShowRestrictedServices)
                newConnection.ProxyUrl = getProxyUrl();

            getDataFromConnection(newConnection, !connectionExists);
        }