The following example demonstrates how to establish a connection. The connection is contained within one class, which has the following four public methods:
This class also has the following three private data members:
The registry and connectionManager variables are initialized during object creation. The connection variable is given a value by the connection operation.
//get the display names for all of the providers in the registry
//and build a connection menu
void
ExerciseFdoUtilities::PopulateConnectionMenu(Menu * connectMenu) {
const FdoProviderCollection * providers;
GisPtr<FdoProvider> provider;
try {
providers = registry->GetProviders ();
GisInt32 providerCount = providers->GetCount();
GisString * providerDisplayName = NULL;
for (int i = 0; i < providerCount; i++) {
provider = providers->GetItem (i);
providerDisplayName = provider->GetDisplayName();
// add providerDisplayName to menu
connectMenu->Add(providerDisplayName);
}
}
catch (GisException* ex) {
// exception handling
ex->Release();
}
}
// user selects a provider from the connection menu
// loop through the registry to match the provider name selected
// by the user with the display names in the registry
// once you get a match, get the provider internal name
GisString *
ExerciseFdoUtilities::MapProviderMenuNameToInternalName(
GisString * menuName) {
try {
const FdoProviderCollection * providers =
registry->GetProviders();
GisPtr<FdoProvider> provider;
GisString * providerInternalName = NULL;
GisInt32 providerCount = providers->GetCount();
for(int i = 0; i < providerCount; i++) {
provider = providers->GetItem(i);
if (wcsicmp(menuName,
provider->GetDisplayName()) == 0) {
providerInternalName = provider->GetName();
break;
}
}
if (providerInternalName == NULL) {
// error handling
return NULL;
} else {
return providerInternalName;
}
}
catch (GisException* ex) {
// exception handling
ex->Release();
return NULL;
}
}
// map the provider menu name to an internal name
// use the connection manager to make a connection object using
// the provider internal name
// get the connection property dictionary from the connection
// object use the dictionary to construct a dialog, which asks
// the user to input values for connection properties specific
// to the provider (see the comments in the
// GetConnectionProperties method)
// use the values given by the user to set the properties in the
// dictionary
// open the connection
// if the connection state returned by the open operation is
// pending, then ask the user for additional connection property
// values and call open again
int
ExerciseFdoUtilities::ConnectToProvider(GisString * providerMenuName) {
GisString * providerInternalName = MapProviderMenuNameToInternalName(providerMenuName);
if (providerInternalName == NULL) {
return 1;
}
GisPtr<FdoIConnectionInfo> connectionInfo;
GisPtr<FdoIConnectionPropertyDictionary> connectionPropertyDictionary;
Dialog * connectDialog = new Dialog();
FdoConnectionState connectState;
int retval = 0;
try {
connection = connectionManager->CreateConnection(providerInternalName);
connectionInfo = connection->GetConnectionInfo();
connectionPropertyDictionary = connectionInfo->GetConnectionProperties();
retval = GetConnectionPropertyValues(connectionPropertyDictionary, connectDialog);
if (retval == 0) {
connectState = connection->Open();
switch (connectState) {
case FdoConnectionState_Busy: break;
case FdoConnectionState_Closed: break;
case FdoConnectionState_Open : break;
case FdoConnectionState_Pending :
retval = GetConnectionPropertyValues(connectionPropertyDictionary, connectDialog);
if (retval == 0) {
connectState = connection->Open();
}
break;
default :
GisException * ex = GisException::Create(L"connection->Open() returned unknown connection state");
throw ex;
}
}
}
catch (GisException * ex){
// error handling
ex->Release();
if (connection) {
connection->Close();
}
return 1;
}
if (connectState != FdoConnectionState_Open) {
// error handling
return 1;
}
return 0;
}
// this method constructs the dialog the user fills in with
// values for the connection properties
// if the user fills in all the required fields and does not
// cancel, the method sets the property values in the property
// dictionary once that is done, the connection can be opened
int
ExerciseFdoUtilities::GetConnectionPropertyValues(
FdoIConnectionPropertyDictionary
*dictionary, Dialog * dialog) {
int retval = 0;
// get the list of property names in the dictionary
GisString ** propertyNames = NULL;
GisInt32 nameCount = 0;
propertyNames = dictionary->GetPropertyNames(nameCount);
GisString * propertyName = NULL;
// loop through the property names adding each property to the
// dialog
for(int i = 0; i < nameCount; i++) {
// get the property name
propertyName = propertyNames[i];
// get the label to be used for the property input line
// in the dialog
GisString * propertyLabel = dictionary->
GetLocalizedName(propertyName);
// determine whether to make the entry line required
// or optional
bool IsRequired = dictionary->
IsPropertyRequired(propertyName);
// determine whether the user input has to be handled in a
// secure way
bool IsProtected = dictionary->
IsPropertyProtected(propertyName);
// get the actual and default values for the property
// these could be the empty string, that is, (GisString *)””
GisString * actualValue = dictionary->
GetProperty(propertyName);
GisString * defaultValue = dictionary->
GetPropertyDefault(propertyName);
// determine whether the property values are enumerable
bool IsEnumerable = dictionary->
IsPropertyEnumerable(propertyName);
GisString ** EnumeratedValues = NULL;
GisInt32 numValues = 0;
if (IsEnumerable) {
// get the list of valid values
EnumeratedValues = dictionary->EnumeratePropertyValues
(propertyName, numValues);
}
// the dictionary entry for this property could possibly be
// populatetd by a subsequent call to the Open() method
bool greyOut = false;
if (IsEnumerable && numValues == 0) {
greyOut = true;
}
// the values are enumerable and there is only one
else if (IsEnumerable && numValues == 1) {
// add the line to the dialog,
// setting the spin box value to EnumeratedValues[0]
}
// the values are enumerable and there is more than one
else if (IsEnumerable && numValues > 1) {
// add the line to the dialog,
// setting the spin box value to the actualValue if
// not empty, or setting it to the defaultValue if
// valid and not empty, or setting it to one of the
// enumerated values
}
// set the field to the actual value if not empty
else if ( wcscmp(actualValue, L"") != 0) {
// add line to dialog
}
// set the field to whatever is the default value
else {
// add line to dialog
}
}
// blocks until user clicks ok or cancel in dialog
// returns 0 if user clicks ok and all required input is
// there and valid if user doesn't fill in required fields,
// dialog persists until user does so or presses cancel
// returns positive if user cancels
retval = dialog->expose();
if (retval == 0) {
GisString * value = NULL;
for(int i = 0; i < nameCount; i++) {
// get the property name
propertyName = propertyNames[i];
// get the value input by the user for this property
value = dialog->GetValue(propertyName);
dictionary->SetProperty(propertyName, value);
}
}
return retval;
}