You are on page 1of 41

Documentum Foundation Classes (DFC)

Primary Interop Assembly (PIA)


Development Guide

Version 5.3
Microsoft Windows .NET

March 2005
Copyright © 1994–2005 EMC Corporation.

2 DFC PIA Development Guide


Introduction
The DFC 5.3 Primary Interop Assembly (PIA) makes Documentum Foundation
Classes (DFC) accessible from .NET code.

The PIA integrates seamlessly into Microsoft Visual Studio .NET and supports
design-time features such as statement completion and object browser help. At
runtime, the PIA provides a thin, efficient layer through which .NET code can
access DFC via the Documentum Java–COM Bridge (DJCB).

Purpose of This Guide


ƒ Learn about the DFC 5.3 PIA
o Find out how to install it
o View the DFC 5.3 PIA documentation
ƒ Use the DFC 5.3 PIA to:
o Retrieve a repository list
o Retrieve folders, cabinets, and documents
o Retrieve content
ƒ See how to migrate existing .NET-based applications to the PIA
o Learn how to upgrade to future versions of the PIA

Who Should Read This Guide


This guide is for programmers who wish to access Documentum functionality
from the .NET environment. To get the most out of reading this document, you
should have done the following:
ƒ Gain a basic understanding of the .NET platform and are familiar with C#
or VB.NET.
ƒ Take the Technical Fundamentals of Documentum 5 training course.
ƒ Take the DFC Fundamentals training course.
ƒ Obtain access to a Microsoft Visual Studio .NET 1.1 development
environment.
ƒ Obtain access to a non-production 5.3 Content Server to experiment with
the examples.

About the DFC 5.3 PIA


What is it?
The DFC 5.3 PIA is essentially metadata that allows you to access DFC from
.NET. The DFC 5.3 PIA makes the DFC types appear as if they were
implemented in .NET, so you can access them from .NET client code.

DFC PIA Development Guide 3


Figure 1. The PIA makes DFC interfaces such as IDfSession available to .NET client code.

Behind the scenes, the PIA accesses the Documentum Java-COM Bridge
(DJCB), which accesses the DFC Java classes. This means that DFC remains in
a single source of implementation (in Java), but there are thin, efficient layers
above that implementation, increasing its accessibility (first to COM-based
clients, and second to .NET-based clients).

For a good overview of Primary Interop Assembly basics, visit The Microsoft
Developer Network (MSDN) online to read “Primary Interop Assemblies (PIAs).”

What platforms does it support?


This product supports the same Windows versions as DFC 5.3.
It does not support .NET 1.0.

Installing the DFC 5.3 PIA


When you install DFC 5.3 and choose to enable installation of the DFC 5.3 PIA,
the DFC installer copies a Windows Installer package called Documentum DFC
PIA.msi into a setup folder under the Documentum programs folder (for
example, C:\Program Files\Documentum\setup). To install the DFC PIA,
double-click Documentum DFC PIA.msi to launch Windows Installer.

To install the PIA:

1. Navigate to the setup folder on your machine.

2. Double click Documentum DFC PIA.msi to run it.

The Welcome dialog box appears.

4 DFC PIA Development Guide


3. Click Next.

The Select Installation Folder dialog box appears, displaying the default
folder path for installation.

4. (Optional) Choose a different folder path.

5. (Optional) Specify that Everyone will have access to the PIA, not just you.

6. Click Next.

The Confirm Installation dialog box appears.

7. Click Next.

The Installation Complete dialog box appears. The following items are in the
Global Assembly Cache (GAC):
• PIA
• XML documentation file
• Publisher Policy Assembly (PPA)

Private copies of these items are also in the Shared folder, along with an
HTML Help file, Documentum.Interop.DFC.chm.

The PIA installer also promotes the location of the private PIA so that adding
a reference to it in Visual Studio .NET is as straightforward as possible.

You can verify the successful installation of the PIA and the PPA by launching
Windows Explorer and navigating to %WINDIR%\assembly (that is, literally
enter this value in the address bar). You should see:
• Documentum.Interop.DFC
• policy.5.2.Documentum.Interop.DFC

Working with PIA documentation


In addition to this document, you can use Microsoft Visual Studio .NET object
browser help as you work with the PIA.

DFC PIA Development Guide 5


Figure 2. PIA help in Microsoft Visual Studio’s Object Browser.

Note: There is a known Microsoft bug in Visual Studio .NET that prevents the
object browser from displaying help for methods from no parameters. Until a fix
is available from Microsoft, you can use the Reflector utility available from
http://www.aisto.com/roeder/dotnet/

You can also view DFC PIA documentation in HTML Help format by double-
clicking the Documentum.Interop.DFC.chm file in the Shared folder. Navigating
through this documentation is similar to navigating through Microsoft’s own
platform documentation

Figure 3. PIA help in HTML Help Viewer.

6 DFC PIA Development Guide


I built my own assembly using Documentum’s COM DLL, what do I do?
We recommend that you switch to the PIA immediately. Doing so will result in
binary compatibility moving forward as subsequent versions of DFC are
released. That means you no longer have to build/maintain your own assembly
for DFC access.

To switch to the PIA:


• Change your client projects so they reference the PIA instead of your
assembly (that is, Add References dialog box Æ select
Documentum.Interop.DFC).
• Change your client code so it references the PIA (that is, use the DFC PIA
namespace; for example, using Documentum.Interop.DFC; in C# and
Imports Documentum.Interop.DFC in VB.NET).

I’ve been using the DFC 5.2 PIA from the Developer Program web site, what do
I do?
Use the new DFC 5.3 PIA.

To assist application developers and administrators in their transition to newer


versions of the DFC PIA, we provide a Publisher Policy Assembly (PPA).

The following answer provides more details on how to use the PPA to assist
your application development/deployment.

For a good overview of how to accomplish assembly version redirection using


Publisher Policy Assemblies and other means, visit The Microsoft Developer
Network (MSDN) online to read “Redirecting Assembly Versions.”

What happens when Documentum ships a new version of the PIA?


As new versions of the DFC are released, we may make additional methods and
quality improvements available through a new PIA.

If you deploy applications with private assemblies, we recommend that you


replace your current DFC PIA with the new PIA and its associated PPA.
However, if your application needs to remain fixed on an older PIA, taking no
action will maintain such an environment.

If you rely on side-by-side versioning and deployment by using the Global


Assembly Cache (GAC), DFC PIAs are strongly named and fully support side-by-
side deployment. There is no need to uninstall older versions of the PIA. The
new PIA comes with a new PPA that is also installed into the GAC; so, your
application must override the PPA if it needs to remain fixed on an older PIA.

DFC PIA Development Guide 7


In any case, allowing automatic redirection to a new PIA via a Documentum
PPA should require no recompilation of client code unless explicitly required by
Documentum.

Examples
C# Examples

Overview
The following are simple examples in C# to help familiarize you with the
concepts required for working with the PIA.

The sample application:


- Presents collections of repositories, Cabinets, Folders, and Documents
- Checks documents both into and out of a repository

Figure 4. Sample client application

Note: These examples are intentionally basic. If you’re already familiar with
DFC, read the Setup section and skim through the remaining examples.

Setup
1. Open Microsoft Visual Studio .NET.
2. Click New Project.
3. From the tree, select Visual C# Projects.
4. Select Windows Application.
5. Enter Sample as the application name and Click OK.
6. From the Project menu, select Add Reference.
7. Select Documentum.Interop.DFC and Click OK.

8 DFC PIA Development Guide


Figure 5. Add Reference dialog box in Visual Studio .NET with Documentum.Interop.DFC selected.

8. Create controls for the form as described in the following table:

Type Property Event Value


Label Name Label1
Text User
TextBox Name UserTextBox
Text <a valid user name of your choosing>
Label Name Label2
Text Password
TextBox Name PasswordTextBox
Text <a valid password of your choosing>
Button Name GetDocbasesButton
Text Get Docbases
Click GetDocbasesButton_Click
Label Name Label3
Text Docbases
ListBox Name DocbasesListbox
SelectedIndexCh DocbasesListbox_SelectedIndexChanged
anged
Label Name Label4
Text Cabinets
ListBox Name CabinetsListbox
SelectedIndexCh CabinetsListbox_SelectedIndexChanged
anged
Label Name Label5
Text Folders
ListBox Name FoldersListbox
SelectedIndexCh FoldersListbox_SelectedIndexChanged
anged
Label Name Label6
Text Documents (with checkout status)

DFC PIA Development Guide 9


CheckedListbox Name DocumentsListbox
SelectedIndexCh DocumentsListbox_SelectedIndexChange
anged d

Figure 6. The form should look like this, but with your user name and password.

9. From the View menu, select Class View.


10. From the Class View tree, select navigate to Form1 and double-click
it.
11. The file, Form1.cs should display in the edit window. At the very top of
the file, enter the following:
using Documentum.Interop.DFC;
using System.Runtime.InteropServices;

12. Add the following member to the Form1 class:


private DfClientX m_DfClientX = null;

13. Replace the Form1() constructor with the following code:

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
m_DfClientX = new DfClientX();

if (null == m_DfClientX)
{
// TBD - add error handling here...
}
}

14. Replace the Dispose(bool disposing) method with the following code:

/// <summary>

10 DFC PIA Development Guide


/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
try
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}

Marshal.ReleaseComObject(m_DfClientX);

m_DfClientX = null;
}
}
catch(System.Exception err)
{
// TBA - add exception handling here
}
finally
{
base.Dispose( disposing );
}
}

15. Type F5 to compile and run the application to verify that things are set
up properly. The application should start successfully (with empty list
boxes, of course).

Figure 7. The list boxes appear empty for now.

16. Exit the application by clicking the Close box in the upper right hand
corner of the form.

Retrieving a List of Repositories


When the Get DocBases button is clicked, a list of repositories that are
available for access appears. So we implement a Click event handler with code
that retrieves a collection of repository names and populates the listbox.

DFC PIA Development Guide 11


1. From the Class View tree, select navigate to Form1 and double-click
it.
2. The file, Form1.cs should display in the edit window.
3. Replace the GetDocbasesButton_Click code with the code appearing
below these instructions.
4. Type F5 to compile and run the application and then click the Get
DocBases button.

Figure 8. The Docbases listbox should fill when you click the Get Docbases button.

5. Exit the application by clicking the Close box in the upper right hand
corner of the form.
private void GetDocbasesButton_Click(object sender, System.EventArgs e)
{
IDfClient client = null;
IDfDocbaseMap map = null;

try
{
//clear the list box
DocbasesListbox.Items.Clear();

//get a client
client = m_DfClientX.getLocalClient();

if (null != client)
{
//get collection of repositories (throws on failure)
map = client.getDocbaseMap();

int count = map.getDocbaseCount();

for (int i = 0; i < count; i++)


{
DocbasesListbox.Items.Add(map.getDocbaseName(i));
}
}
else
{
throw new System.Exception("Couldn't obtain client.");
}
}
catch(System.Exception err)
{
MessageBox.Show("Error: " + err.ToString());
}
finally
{
if (client != null)

12 DFC PIA Development Guide


{
System.Runtime.InteropServices.Marshal.ReleaseComObject(client);
client = null;
}
if (map != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(map);
client = null;
}
}
}

Working with Sessions


Sessions are an integral part of the DFC programming model. Sessions are
required to securely access a repository. Because sessions are a finite resource,
only create them when they’re needed and always free them when you’re done
working with them.

Interacting with sessions is a very common task and doing it wrong can create
confusion as well as bugs, so we provide a single set of procedures to call
whenever we need to use a session.

The setupSessionMgr(…) and setupSession(…) procedures retrieve a


session, and the cleanupSession(…) procedure releases a session. As the
code comments suggest, when we invoke these procedures we always do so
from a Try-Catch-Finally block, because DFC can throw exceptions.

The remaining examples illustrate this pattern. The first example adds the
procedures to Form1.

1. From the Class View tree, select navigate to Form1 and double-click
it.
2. The file, Form1.cs should display in the edit window.
3. Add the code appearing below these instructions to the Form1 class.
4. Type F5 to compile and run the application to verify that things are set
up properly.

The application should behave just as it did when you ran it in the
previous section, since we’ve added procedures, but we haven’t called
them yet.

5. Exit the application by clicking the Close box in the upper right hand
corner of the form.
/*
Takes a user name, password, and repository name as input arguments and
returns an IDfSessionManager.
Note:
a) Only call this procedure from within a TRY-CATCH-FINALLY
block.
b) In the FINALLY block, call cleanupSession to ensure

DFC PIA Development Guide 13


that the session is properly released.
*/
private IDfSessionManager setupSessionMgr(String user, String pwd, String docBase)
{
IDfSessionManager smgr = null;
IDfClient client = null;
IDfLoginInfo loginInfo = null;

try
{
//get a client
client = m_DfClientX.getLocalClient();
if (null != client)
{
//get a session mgr
smgr = client.newSessionManager();
if (null != smgr)
{
//get a login info
loginInfo = m_DfClientX.getLoginInfo();
if (null != loginInfo)
{
//set up the login info
loginInfo.setUser(user);
loginInfo.setPassword(pwd);
//bind session mgr to login info
smgr.setIdentity(docBase, loginInfo);
return smgr;
}
else
{
throw new System.Exception("Couldn't obtain login info.");
}
}
else
{
throw new System.Exception("Couldn't obtain session mgr.");
}
}
else
{
throw new System.Exception("Couldn't obtain client.");
}
}
catch(System.Exception err)
{
throw err;
}
finally
{
if (client != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(client);
client = null;
}
if (loginInfo != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(loginInfo);
loginInfo = null;
}
}
}

/*
Takes an IDfSessionManager manager and repository name as input arguments
and returns an IDfSession.
Note:
a) Only call this procedure from within a TRY-CATCH-FINALLY
block.
b) In the FINALLY block, call cleanupSession(...) to ensure
that the session is properly released.

14 DFC PIA Development Guide


*/
private IDfSession setupSession(IDfSessionManager smgr, String docBase)
{
//Note: Notice there's no TRY-CATCH-FINALLY block here.
//Exceptions must be handled at the caller!

if (null == smgr)
{
throw new System.Exception("Session not passed.");
}
//set the session
IDfSession session = smgr.getSession(docBase);
if (null == session)
{
throw new System.Exception("Couldn't obtain session.");
}
return session;
}

/*
Takes IDfSessionManager and IDfSession object references and
frees internals, then sets them to Nothing.
Note: This procedure should always be called whenever
setupSession(...) is called.
*/
private void cleanupSession(IDfSessionManager smgr, ref IDfSession session)
{
try
{
if (null != smgr)
{
if (null != session)
{
//clean up session
smgr.release(session);
}
}
}
catch(System.Exception err)
{
// 'This should never really happen
MessageBox.Show("Error: " + err.ToString());
}
finally
{
if (smgr != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(smgr);
smgr = null;
}
if (session != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(session);
session = null;
}
}
}

Retrieving a list of Cabinets


Next, we want to enhance our application so that when the user clicks on a
particular repository, the Cabinets listbox fills with the available cabinets.

So we implement a SelectedIndexChanged event handler with code that


retrieves a collection of cabinet names and populates the listbox.

DFC PIA Development Guide 15


As you review the sample code, examine the way sessions are managed. Notice
that we call our cleanupSession(…) procedure from within a finally block.
Doing so ensures that the session will always be released safely.

Also, notice that we use a query to retrieve the list of cabinets from the
repository.

1. From the Class View tree, select navigate to Form1 and double-click it.
2. The file, Form1.cs should display in the edit window.
3. Replace the DocbasesListbox_SelectedIndexChanged code with the
code appearing below these instructions.
4. Type F5 to compile and run the application and then click the Get
DocBases button.

Selecting a repository should now result in the Cabinets listbox populating


appropriately.

Figure 9. The Cabinets listbox should fill when you select a repository.

5. Exit the application by clicking the Close box in the upper right hand corner
of the form.
private void DocbasesListbox_SelectedIndexChanged(
object sender, System.EventArgs e)
{

IDfSessionManager smgr = null;


IDfSession session = null;
IDfQuery query = null;
IDfCollection rs = null;

//clear the other list boxes


CabinetsListbox.Items.Clear();
FoldersListbox.Items.Clear();
DocumentsListbox.Items.Clear();
try
{
//get a query object
query = m_DfClientX.getQuery();
if (null != query)
{
//pass the query string to the query object
query.setDQL("Select object_name from dm_cabinet");

16 DFC PIA Development Guide


//get a session manager
smgr = setupSessionMgr(UserTextBox.Text,
PasswordTextBox.Text,
DocbasesListbox.Text);
//get a session
session = setupSession(smgr,DocbasesListbox.Text);

//Execute the query. Note the use of a constant here.


rs = query.execute(session,
(int) tagDfQueryTypes.DF_READ_QUERY);

while (true == rs.next())


{
// The following code is specific to working with Strings.
// When working with other types use a method different
// than getString(). Also, if you're making a more
// generalized solution and don't *know* the types
// ahead of time, you can use getAttr() to examine them
// and then call the appropriate methods for conversion
// as needed.
//add each document name to the listbox
CabinetsListbox.Items.Add(rs.getString("object_name"));
}
}
else
{
throw new System.Exception("Couldn't obtain query.");
}
}
catch(System.Exception err)
{
// 'This should never really happen
MessageBox.Show("Error: " + err.ToString());
}
finally
{
cleanupSession(smgr, ref session);

if (query != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(query);
query = null;
}
if (rs != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(rs);
rs = null;
}
}
}

Retrieving a list of Folders


Next, we want to enhance our application so that when a user clicks on a
particular cabinet, the Folders listbox fills with the available folders.

So, as in the previous example, we implement a SelectedIndexChanged


event handler, but this time we write code that retrieves a collection of folder
names and populates that listbox.

Unlike the previous example, where we used a Query object to query the
repository for the cabinets, the following example uses getContents(…) to
retrieve the folders within a given cabinet.

DFC PIA Development Guide 17


1. From the Class View tree, select navigate to Form1 and double-click it.
2. The file, Form1.cs should display in the edit window.
3. Replace the CabinetsListbox_SelectedIndexChanged code with the code
appearing below these instructions.
4. Type F5 to compile and run the application and then click the Get
DocBases button.

Selecting a repository and then a Cabinet should now result in the Folders
listbox populating appropriately.

Figure 10. The Folders listbox should fill when you select a Cabinet.

5. Exit the application by clicking the Close box in the upper right hand corner
of the form.
private void CabinetsListbox_SelectedIndexChanged(object sender, System.EventArgs e)
{
IDfSessionManager smgr = null;
IDfSession session = null;
IDfFolder cab = null;
IDfCollection rs = null;
IDfId objId = null;
IDfSysObject sysObj = null;

//clear the other list boxes


FoldersListbox.Items.Clear();
DocumentsListbox.Items.Clear();
try
{
//get a session manager
smgr = setupSessionMgr(UserTextBox.Text,
PasswordTextBox.Text,
DocbasesListbox.Text);

//get a session
session = setupSession(smgr,DocbasesListbox.Text);

//not a typo - access the cabinet through this interface


cab = session.getFolderByPath(
"/" + CabinetsListbox.Text);
if (null != cab)
{
//retrieve collection of folder names
rs = cab.getContents(
"r_object_id,object_name");
while (true == rs.next())
{
String strId = rs.getString("r_object_id");
objId = m_DfClientX.getId(strId);

18 DFC PIA Development Guide


sysObj = (IDfSysObject)
session.getObject(objId);
String objType = sysObj.getString("r_object_type");
if(objType.Equals("dm_folder"))
{
//add each folder name to the listbox
FoldersListbox.Items.Add(
rs.getString("object_name"));
}
}
}
else
{
throw new System.Exception(
"Couldn't obtain cabinet: " + CabinetsListbox.Text);
}
}
catch(System.Exception err)
{
// 'This should never really happen
MessageBox.Show("Error: " + err.ToString());
}
finally
{
cleanupSession(smgr, ref session);

if (cab != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(cab);
cab = null;
}
if (rs != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(rs);
rs = null;
}
if (objId != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(objId);
objId = null;
}
if (sysObj != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(sysObj);
sysObj = null;
}
}
}

Retrieving a list of Documents


Next, we want to enhance our application so that when the user clicks on a
particular folder, the Documents listbox fills with the available documents.

However, down the road, we’re also going to want to refresh the documents
listbox when a document is checked in or checked out. So, we put the code for
populating the documents listbox in a procedure called fillDocumentsListbox(
) and we implement a SelectedIndexChanged event handler which calls it.

Notice that the fillDocumentsListbox( ) procedure also contains logic to


determine whether each document is checked out and marks the checks in the
checked listbox as needed.

DFC PIA Development Guide 19


1. From the Class View tree, select navigate to Form1 and double-click it.
2. The file, Form1.cs should display in the edit window.
3. Replace the FoldersListbox_SelectedIndexChanged code with the code
appearing below these instructions. Be sure and add the
fillDocumentsListbox() procedure to the Form1 class as well.
4. Type F5 to compile and run the application and then click the Get
DocBases button.

Specifying a repository, Cabinet, and Folder should now result in the


Documents listbox populating appropriately. Checking a document doesn’t
yet change a given document’s checkout status – that’s coming next in the
final example.

Figure 11. The Documents listbox should fill when you select a Folder.

5. Exit the application by clicking the Close box in the upper right hand corner
of the form.

private void FoldersListbox_SelectedIndexChanged(


object sender, System.EventArgs e)
{
fillDocumentsListbox();
}

private void fillDocumentsListbox()


{
IDfSessionManager smgr = null;
IDfSession session = null;
IDfFolder folder = null;
IDfCollection rs = null;

//clear the list boxes


DocumentsListbox.Items.Clear();
try
{
//get a session manager
smgr = setupSessionMgr(UserTextBox.Text,
PasswordTextBox.Text,
DocbasesListbox.Text);
//get a session
session = setupSession(smgr,DocbasesListbox.Text);
//get the folder
folder = session.getFolderByPath(
"/"

20 DFC PIA Development Guide


+ CabinetsListbox.Text
+ "/"
+ FoldersListbox.Text);
//output list of documents
if (null != folder)
{
//retrieve collection of document names
rs = folder.getContents(
"object_name,r_lock_owner,r_object_type");
int i = 0;
//iterate list of documents
while (true == rs.next())
{
String strType = rs.getString("r_object_type");
if(strType.Equals("dm_document"))
{
//add each document name to the listbox

DocumentsListbox.Items.Add(
rs.getString("object_name"));
//if the document is checked out, check the checkbox
if (false == rs.getString("r_lock_owner").Equals(""))
{
DocumentsListbox.SetItemChecked(i, true);
}
i++;
}
}
}
else
{
throw new System.Exception(
"Couldn't obtain folder: "
+ "/"
+ CabinetsListbox.Text
+ "/"
+ FoldersListbox.Text);
}
}
catch(System.Exception err)
{
// 'This should never really happen
MessageBox.Show("Error: " + err.ToString());
}
finally
{
cleanupSession(smgr, ref session);

if (folder != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(folder);
folder = null;
}
if (rs != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(rs);
rs = null;
}
}
}

Working with Content


Finally, we want to enhance our application so that when the user checks or
unchecks an item in the Documents listbox, the corresponding document in the
repository gets checked out or in (respectively).

DFC PIA Development Guide 21


Since this sample doesn’t do anything fancy during either checkin or checkout,
both actions are accomplished through a single procedure named
toggleCheckout(…). As the code comments explain, depending on whether a
checkin or a checkout is required, a different object (that implements
IDfOperation) is passed, and the right methods are fired.

To respond to documents being checked or unchecked we implement a


SelectedValueChanged event handler on the documents list box. It calls
toggleCheckout(…) with the appropriate argument.

Note: If the use of a base interface reference to a derived object in


toggleCheckout(…) at all confuses you, consider creating two separate
procedures: one that does the checkout and one that does the checkin. We
were just trying to keep the sample brief, and you’ll probably want more
custom handling for each case anyway.

1. From the Class View tree, select navigate to Form1 and double-click it.
2. The file, Form1.cs should display in the edit window.
3. Replace the DocumentsListbox_SelectedIndexChanged code with the
code appearing below these instructions. Be sure and add the
toggleCheckout (…) procedure to the Form1 class as well.
4. Type F5 to compile and run the application and then click the Get
DocBases button.

Once you’ve specified a repository, Cabinet, and Folder, checking an item in


the Documents listbox should result in the corresponding document being
checked out of the repository. Unchecking an item should result in the
corresponding document being checked in.

Figure 12. A checked item indicates that the document is currently checked out.

5. Exit the application by clicking the Close box in the upper right hand corner
of the form.
private void toggleCheckout(IDfOperation operation)
{
IDfSessionManager smgr = null;

22 DFC PIA Development Guide


IDfSession session = null;
IDfSysObject sys = null;
IDfOperationNode node = null;
IDfList list = null;
IDfOperationError err = null;

// we'll retrieve a document with a path like


// "/mycabinet/myfolder/mydocument"
String path = "/" + CabinetsListbox.Text
+ "/" + FoldersListbox.Text
+ "/" + DocumentsListbox.Text;
try
{
//get a session manager
smgr = setupSessionMgr(UserTextBox.Text,
PasswordTextBox.Text,
DocbasesListbox.Text);
//get a session
session = setupSession(smgr,DocbasesListbox.Text);
sys = (IDfSysObject) session.getObjectByPath(path);
if (null != sys)
{
node = operation.add(sys);

//important: add doesn't throw so good coding practice to


//check return value
if (null == node)
{
throw new System.Exception(
"Couldn't add node during checkin/checkout: " + path);
}
//execute the operation - returns true on success
if(false == operation.execute())
{
int i = 0;
String message = null;
list = operation.getErrors();
while (i < list.getCount())
{
err = (IDfOperationError) list.get(i);
message = message + err.getMessage() + "\r\n";
i++;
}
}
}
else
{
throw new System.Exception(
"Couldn't obtain document for checkin/checkout: " + path);
}
}
catch(System.Exception error)
{
// 'This should never really happen
MessageBox.Show("Error: " + error.ToString());
}
finally
{
cleanupSession(smgr, ref session);

if (sys != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(sys);
sys = null;
}
if (node != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(node);
node = null;
}
if (list != null)

DFC PIA Development Guide 23


{
System.Runtime.InteropServices.Marshal.ReleaseComObject(list);
list = null;
}
if (err != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(err);
err = null;
}
}
}
private void DocumentsListbox_SelectedIndexChanged(object sender, System.EventArgs e)
{
IDfOperation operation = null;

try
{
// If user clicks a document that has a check, we'll
// check it in. Otherwise, we'll check it out.
if (DocumentsListbox.GetItemChecked(
DocumentsListbox.SelectedIndex))
{
operation = m_DfClientX.getCheckinOperation();
}
else
{
operation = m_DfClientX.getCheckoutOperation();
}
if (null != operation)
{
//call toggleCheckout(...) to check out the document
toggleCheckout(operation);
fillDocumentsListbox();
}
else
{
throw new System.Exception("Couldn't obtain operation");
}
}
catch(System.Exception err)
{
// 'This should never really happen
MessageBox.Show("Error: " + err.ToString());
}
finally
{
if (operation != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(operation);
operation = null;
}
}
}

VB.NET Examples
Overview
We’ve provided some of the simplest examples we could think of in VB.NET to
help familiarize you with the concepts required for working with the PIA.

Once complete our sample application:


- Presents collections of Repositories, Cabinets, Folders, and Documents
- Checks Documents both in and out of a repository

24 DFC PIA Development Guide


Figure 13. Sample client application

Note: These examples are intentionally quite basic. If you’re already very
familiar with the DFC APIs read the Setup section and then skim through the
remaining examples.

Setup
1. Open Microsoft Visual Studio .NET.
2. Click New Project.
3. From the tree, select Visual Basic Projects.
4. Select Windows Application.
5. Enter Sample as the application name and click OK.
6. From the Project menu, select Add Reference.
7. Select Documentum.Interop.DFC and click OK.

Figure 14. Add Reference dialog box in Visual Studio .NET with Documentum.Interop.DFC selected.

8. Create controls for the form as described in the table below:

Control Type Property Value

DFC PIA Development Guide 25


Label Name Label1
Text User
TextBox Name UserTextBox
Text <a valid user name of
your choosing>
Label Name Label2
Text Password
TextBox Name PasswordTextBox
Text <a valid password of your
choosing>
Button Name GetDocbasesButton
Text Get Docbases
Label Name Label3
Text Docbases
ListBox Name DocbasesListbox
Label Name Label4
Text Cabinets
ListBox Name CabinetsListbox
Label Name Label5
Text Folders
ListBox Name FoldersListbox
Label Name Label6
Text Documents (with checkout
status)
CheckedListbox Name DocumentsListbox

Figure 15. The form should look like this, but with your user name and password.

9. From the View menu, select Class View.


10. From the Class View tree, select navigate to Form1 and double-click
it.
11. The file, Form1.vb should display in the edit window. At the very top of
the file, enter the following:
Option Explicit On
Imports Documentum.Interop.DFC
Imports System.Runtime.InteropServices

12. Add the following member to the Form1 class:

26 DFC PIA Development Guide


Private m_DfClientX As DfClientX

13. Replace the Visual Studio Form Designer generated New() method with
the following:
Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.


InitializeComponent()

'Add any initialization after the InitializeComponent() call


m_DfClientX = new DfClientX()

If (Nothing Is m_DfClientX) Then


'TBD - add error handling here...
End If
End Sub

14. Replace the Visual Studio Form Designer generated Dispose(bool


disposing) method with the following code:
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If

Marshal.ReleaseComObject(m_DfClientX)
m_DfClientX = Nothing

End If
Catch err As System.Exception
'TBA - add exception handling here
Finally
MyBase.Dispose(disposing)
End Try
End Sub

15. Type F5 to compile and run the application to verify that things are set up
properly. The application should start successfully (with empty list boxes,
of course).

DFC PIA Development Guide 27


Figure 16. List boxes appear empty for now.

16. Exit the application by clicking the Close box in the upper right hand
corner of the form.

Retrieving a List of Repositories


When the Get DocBases button is clicked a list of repositories that are
available for access appears. So we implement a Click event handler with code
that retrieves a collection of repository names and populates the listbox.

1. From the Class View tree, navigate to Form1 and double-click it.
2. The file, Form1.vb should appear in the edit window.
3. Add the code appearing below these instructions to the file before the
End Class statement.
4. Type F5 to compile and run the application and then click the Get
DocBases button.

Figure 17. Docbases listbox should fill when you click the Get Docbases button.

5. Exit the application by clicking the Close box in the upper right hand
corner of the form.
Private Sub GetDocbasesButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles GetDocbasesButton.Click

Dim map As IDfDocbaseMap


Dim client As IDfClient

'First clear all listboxes


DocbasesListbox.Items.Clear()
CabinetsListbox.Items.Clear()

28 DFC PIA Development Guide


FoldersListbox.Items.Clear()
DocumentsListbox.Items.Clear()

Try
'get a client
client = m_DfClientX.getLocalClient

If (Not Nothing Is client) Then


'get collection of repositories (throws on failure)
map = client.getDocbaseMap()
Dim i, count As Integer
i = 0

count = map.getDocbaseCount()
'iterate through repositories and populate listbox

While (i < count)


DocbasesListbox.Items.Add(map.getDocbaseName(i))
i = i + 1
End While
Else
Throw New System.Exception("Couldn't obtain client.")
End If
Catch err As System.Exception
MsgBox("Error: " & err.ToString)
Finally
If (Not Nothing Is map) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(map)
map = Nothing
End If
If (Not Nothing Is client) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(client)
client = Nothing
End If
End Try
End Sub

Working with Sessions


Sessions are an integral part of the DFC programming model. Sessions are
required to securely access a repository. Because sessions are a finite resource,
only create them when they’re needed and always free them when you’re done
working with them.

Interacting with sessions is a very common task and doing it wrong can create
confusion as well as bugs, so we want to write a single set of procedures that
we can call whenever we need to use a session.

We create setupSessionMgr(…) and setupSession(…) procedures, which


we’ll use to retrieves a session and a cleanupSession(…) procedure that
releases a session. As the code comments suggest, when we invoke these
procedures we’ll always do so from a Try-Catch-Finally block, because DFC APIs
that can throw exceptions are called.

You’ll see that pattern in practice in the remaining examples – for now, let’s
add the procedures to Form1.

1. From the Class View tree, select navigate to Form1 and double-click
it.

DFC PIA Development Guide 29


2. The file, Form1.vb should display in the edit window.
3. Add the code appearing below these instructions to the file before the
End Class statement (immediately after the code we added in the
previous section).
4. Type F5 to compile and run the application to verify that things are set up
properly.

The application should behave just as it did when you ran it in the
previous section, since we’ve added procedures, but we haven’t called
them yet.

5. Exit the application by clicking the Close box in the upper right hand
corner of the form.
'Takes a user name, password, and repository name as input string arguments
'and returns an object of type IDfSessionManager.
'
'Note: a) Notice there's no TRY-CATCH-FINALLY block here. Exceptions must
' be handled at the caller.
'
' b) Call this procedure from within a TRY-CATCH-FINALLY block.
'
' c) In the FINALLY block, call cleanupSession(...) to ensure
' that the session is properly released.
'
Private Function setupSessionMgr( _
ByVal user As String, _
ByVal pwd As String, _
ByVal docBase As String) As IDfSessionManager

Dim smgr As IDfSessionManager


Dim client As IDfClient
Dim loginInfo As IDfLoginInfo

Try
'get a client
client = m_DfClientX.getLocalClient

If (Not client Is Nothing) Then


'get a session mgr
smgr = client.newSessionManager

If (Not smgr Is Nothing) Then


'get a login info
loginInfo = m_DfClientX.getLoginInfo()

If (Not loginInfo Is Nothing) Then


'set up the login info
loginInfo.setUser(user)
loginInfo.setPassword(pwd)
'bind session mgr to login info
smgr.setIdentity(docBase, loginInfo)
Else
Throw New System.Exception( _
"Couldn't obtain login info.")
End If
Else
Throw New System.Exception("Couldn't obtain session mgr.")
End If
Else
Throw New System.Exception("Couldn't obtain client.")
End If

30 DFC PIA Development Guide


'return session manager
setupSessionMgr = smgr
Catch ex As Exception
Throw ex
Finally
If (Not Nothing Is client) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(client)
client = Nothing
End If
If (Not Nothing Is loginInfo) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(loginInfo)
loginInfo = Nothing
End If
End Try
End Function

'Takes a session manager and a repository name as input string arguments


'and returns an object of type IDfSession.
'
'Note: a) Notice there's no TRY-CATCH-FINALLY block here. Exceptions must
' be handled at the caller.
'
' b) Call this procedure from within a TRY-CATCH-FINALLY block.
'
' c) In the FINALLY block, call cleanupSession(...) to ensure
' that the session is properly released.
'
Private Function setupSession(ByVal smgr As IDfSessionManager, _
ByVal docBase As String) As IDfSession

If (smgr Is Nothing) Then


Throw New System.Exception("Session not passed.")
End If

'set the session


Dim session As IDfSession
session = smgr.getSession(docBase)

If (session Is Nothing) Then


Throw New System.Exception("Couldn't obtain session.")
End If

'return session
setupSession = session
End Function

'Takes IDfSessionManager and IDfSession object references and


'frees internals, then sets them to Nothing.
'
'Note: This procedure should always be called whenever
' setupSession(...) is called.
Public Sub cleanupSession(ByRef smgr As IDfSessionManager, _
ByRef session As IDfSession)
Try
If (Not smgr Is Nothing) Then
If (Not session Is Nothing) Then
'clean up session
smgr.release(session)
End If
End If
Catch err As System.Exception
'This should never really happen
MsgBox("Error: " & err.ToString)
Finally
If (Not Nothing Is session) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(session)
session = Nothing
End If
If (Not Nothing Is smgr) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(smgr)
smgr = Nothing

DFC PIA Development Guide 31


End If
End Try
End Sub

Retrieving a list of Cabinets


Next, we want to enhance our application so that when the user clicks on a
particular repository, the Cabinets listbox fills with the available cabinets.

So we implement a SelectedIndexChanged event handler with code that


retrieves a collection of cabinet names and populates the listbox.

As you review the sample code, examine the way sessions are managed. Notice
that we call our cleanupSession(…) procedure from within a finally block.
Doing so ensures that the session will always be released safely.

Also, notice that we use a query to retrieve the list of cabinets from the
repository.

1. From the Class View tree, select navigate to Form1 and double-click
it.
2. The file, Form1.vb should display in the edit window.
3. Add the code appearing below these instructions to the file before the
End Class statement (immediately after the code we added in the
previous section).
4. Type F5 to compile and run the application and then click the Get
DocBases button.

Selecting a repository should now result in the Cabinets listbox populating


appropriately.

Figure 18. Cabinets listbox should fill when you select a repository.

5. Exit the application by clicking the Close box in the upper right hand
corner of the form.
Private Sub DocBasesListbox_SelectedIndexChanged( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _

32 DFC PIA Development Guide


Handles DocbasesListbox.SelectedIndexChanged

Dim smgr As IDfSessionManager


Dim session As IDfSession
Dim query As IDfQuery
Dim rs As IDfCollection

CabinetsListbox.Items.Clear()
FoldersListbox.Items.Clear()
DocumentsListbox.Items.Clear()

Try
'get a query object
query = m_DfClientX.getQuery()

If (Not query Is Nothing) Then


'pass the query string to the query object
query.setDQL("Select object_name from dm_cabinet")

'get a session manager (throws on failure)


smgr = setupSessionMgr(UserTextBox.Text, _
PasswordTextBox.Text, _
DocbasesListbox.Text)

'get a session (throws on failure)


session = setupSession(smgr, DocbasesListbox.Text)

'execute the query


rs = query.execute(session, _
tagDfQueryTypes.DF_READ_QUERY)

While (True = rs.next())


'The following code is specific to working with Strings.
'When working with other types use a method different
'than getString(). Also, if you're making a more
'generalized solution and don't know the types
'ahead of time, you can use getAttr() to examine them
'and then call the appropriate methods for conversion
'as needed.
'add each document name to the listbox
CabinetsListbox.Items.Add(rs.getString("object_name"))
End While
Else
Throw New System.Exception("Couldn't obtain query.")
End If
Catch err As System.Exception
MsgBox("Error: " & err.ToString)
Finally
cleanupSession(smgr, session)

If (Not Nothing Is query) Then


System.Runtime.InteropServices.Marshal.ReleaseComObject(query)
query = Nothing
End If
If (Not Nothing Is rs) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(rs)
rs = Nothing
End If
End Try
End Sub

Retrieving a list of Folders


Next, we want to enhance our application so that when the user clicks on a
particular cabinet, the Folders listbox fills with the available folders.

DFC PIA Development Guide 33


So, as in the previous example, we implement a SelectedIndexChanged
event handler, but this time we write code that retrieves a collection of folder
names and populates that listbox.

Unlike the previous example, where we used a Query object to query the
repository for the cabinets, the following example uses getContents(…) to
retrieve the folders within a given cabinet.

1. From the Class View tree, select navigate to Form1 and double-click
it.
2. The file, Form1.vb should display in the edit window.
3. Add the code appearing below these instructions to the file before the
End Class statement (immediately after the code we added in the
previous section).
4. Type F5 to compile and run the application and then click the Get
DocBases button.

Selecting a repository and then a Cabinet should now result in the Folders
listbox populating appropriately.

Figure 19. Folders listbox should fill when you select a Cabinet.

5. Exit the application by clicking the Close box in the upper right hand
corner of the form.
Private Sub CabinetsListBox_SelectedIndexChanged( _
ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles CabinetsListbox.SelectedIndexChanged
Dim smgr As IDfSessionManager
Dim session As IDfSession
Dim rs As IDfCollection
Dim cab As IDfFolder 'access the cabinet through this interface

FoldersListbox.Items.Clear()
DocumentsListbox.Items.Clear()

Try
'get a session manager (throws on failure)
smgr = setupSessionMgr(UserTextBox.Text, _
PasswordTextBox.Text, _
DocbasesListbox.Text)

34 DFC PIA Development Guide


'get a session (throws on failure)
session = setupSession(smgr, DocbasesListbox.Text)
cab = session.getFolderByPath("/" & CabinetsListbox.Text)

If (Not cab Is Nothing) Then


'retrieve collection of folder names
rs = cab.getContents("object_name,r_object_type")

Dim i As Integer
i = 0
'iterate list of folders
While (True = rs.next())
Dim strType As String = rs.getString("r_object_type")
Dim res As Int16 = String.Compare(strType, "dm_folder")

If (res = 0) Then
FoldersListbox.Items.Add(rs.getString("object_name"))
End If

i = i + 1
End While
Else
Throw New System.Exception( _
"Couldn't obtain cabinet: " & CabinetsListbox.Text)
End If
Catch err As System.Exception
MsgBox("Error: " & err.ToString)
Finally
cleanupSession(smgr, session)
If (Not Nothing Is rs) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(rs)
rs = Nothing
End If
If (Not Nothing Is cab) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(cab)
cab = Nothing
End If
End Try
End Sub

Retrieving a list of Documents


Next, we want to enhance our application so that when the user clicks on a
particular folder, the Documents listbox fills with the available documents.

However, down the road, we’re also going to want to refresh the documents
listbox when a document is checked in or checked out. So, we put the code for
populating the documents listbox in a procedure called fillDocumentsListbox(
) and we implement a SelectedIndexChanged event handler which calls it.

Notice that the fillDocumentsListbox( ) procedure also contains logic to


determine whether each document is checked out and marks the checks in the
checked listbox as needed.

1. From the Class View tree, select navigate to Form1 and double-click
it.
2. The file, Form1.vb should display in the edit window.

DFC PIA Development Guide 35


3. Add the code appearing below these instructions to the file before the
End Class statement (immediately after the code we added in the
previous section).
4. Type F5 to compile and run the application and then click the Get
DocBases button.

Specifying a repository, Cabinet, and Folder should now result in the


Documents listbox populating appropriately. Checking a document doesn’t
yet change a given document’s checkout status – that’s coming next in
the final example.

Figure 20. Documents listbox should fill when you select a Folder.

5. Exit the application by clicking the Close box in the upper right hand
corner of the form.
Private Sub FoldersListBox_SelectedIndexChanged( _
ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles FoldersListbox.SelectedIndexChanged

fillDocumentsListbox()
End Sub

Private Sub fillDocumentsListbox()


Dim smgr As IDfSessionManager
Dim session As IDfSession
Dim folder As IDfFolder
Dim rs As IDfCollection

DocumentsListbox.Items.Clear()

Try
'get a session manager (throws on failure)
smgr = setupSessionMgr(UserTextBox.Text, _
PasswordTextBox.Text, _
DocbasesListbox.Text)

'get a session (throws on failure)


session = setupSession(smgr, DocbasesListbox.Text)

'retrieve folder with a path like "/mycabinet/myfolder"


folder = session.getFolderByPath( _
"/" & CabinetsListbox.Text _
& "/" & FoldersListbox.Text)

36 DFC PIA Development Guide


If (Not folder Is Nothing) Then
'retrieve collection of folder names
rs = folder.getContents("object_name,r_lock_owner,r_object_type")

Dim i As Integer
i = 0
'output list of folders
While (True = rs.next())
Dim objType As String = rs.getString("r_object_type")
Dim res As Int16 = String.Compare(objType, "dm_document")
If (res = 0) Then
'add each document name to the listbox
DocumentsListbox.Items.Add(rs.getString("object_name"))

'if the document is checked out, check the checkbox


If (Not "" = rs.getString("r_lock_owner")) Then
DocumentsListbox.SetItemChecked(i, True)
End If
End If
i = i + 1
End While
Else
Throw New System.Exception( _
"Couldn't find" & "/" & CabinetsListbox.Text _
& "/" & FoldersListbox.Text)
End If
Catch err As System.Exception
MsgBox("Error: " & err.ToString)
Finally
cleanupSession(smgr, session)
If (Not Nothing Is folder) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(folder)
folder = Nothing
End If
If (Not Nothing Is rs) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(rs)
rs = Nothing
End If
End Try
End Sub

Working with Content


Finally, we want to enhance our application so that when the user checks or
unchecks an item in the Documents listbox, the corresponding document in the
repository gets checked out or in (respectively).

Since this sample doesn’t do anything fancy during either checkin or checkout,
both actions are accomplished through a single procedure named
toggleCheckout(…). As the code comments explain, depending on whether a
checkin or a checkout is required, a different object (that implements
IDfOperation) is passed, and the right methods are fired.

To respond to documents being checked or unchecked we implement a


SelectedValueChanged event handler on the documents list box. It calls
toggleCheckout(…) with the appropriate argument.

Note: If the use of a base interface reference to a derived object in


toggleCheckout(…) at all confuses you, consider creating two separate
procedures: one that does the checkout and one that does the checkin. We

DFC PIA Development Guide 37


were just trying to keep the sample brief, and you’ll probably want more
custom handling for each case anyway.

1. From the Class View tree, select navigate to Form1 and double-click
it.
2. The file, Form1.vb should display in the edit window.
3. Add the code appearing below these instructions to the file before the
End Class statement (immediately after the code we added in the
previous section).
4. Type F5 to compile and run the application and then click the Get
DocBases button.

Once you’ve specified a repository, Cabinet, and Folder, checking an item


in the Documents listbox should result in the corresponding document
being checked out of the repository. Unchecking an item should result in
the corresponding document being checked in.

Figure 21. Checked item indicates that the document is currently checked out.

5. Exit the application by clicking the Close box in the upper right hand
corner of the form.
Private Sub DocumentsListbox_SelectedValueChanged( _
ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles DocumentsListbox.SelectedValueChanged
Dim operation As IDfOperation

Try
'If user clicks a document that has a check, we'll
'check it in. Otherwise, we'll check it out.

If (DocumentsListbox.GetItemChecked( _
DocumentsListbox.SelectedIndex)) Then
operation = m_DfClientX.getCheckinOperation()
Else
operation = m_DfClientX.getCheckoutOperation()
End If

If (Not operation Is Nothing) Then


'call toggleCheckout(...) to check out the document
toggleCheckout(operation)
Else
Throw New System.Exception( _
"Couldn't obtain operation")

38 DFC PIA Development Guide


End If
Catch err As System.Exception
MsgBox("Error: " & err.ToString)
Finally
If (Not Nothing Is operation) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(operation)
operation = Nothing
End If
End Try
fillDocumentsListbox()
End Sub

'This procedure demonstrates some very *basic* interaction with


'content.
'
'When an object of type IDfCheckoutOperation is passed as
'the operation argument, the document specified in the UI gets checked
'out.
'
'Similarly, when an object of type IDfCheckinOperation is passed
'as the operation argument, the document specified in the UI gets
'checked in.
'
Private Sub toggleCheckout(ByRef operation As IDfOperation)

Dim smgr As IDfSessionManager


Dim session As IDfSession
Dim sys As IDfSysObject
Dim node As IDfOperationNode
Dim list As IDfList
Dim err As IDfOperationError

'we'll retrieve a document with a path like


' /mycabinet/myfolder/mydocument
Dim path As String

path = "/" & CabinetsListbox.Text _


& "/" & FoldersListbox.Text _
& "/" & DocumentsListbox.Text
Try
'get a session manager (throws on failure)
smgr = setupSessionMgr(UserTextBox.Text, _
PasswordTextBox.Text, _
DocbasesListbox.Text)

'get a session (throws on failure)


session = setupSession(smgr, DocbasesListbox.Text)

sys = session.getObjectByPath(path)

If (Not sys Is Nothing) Then


node = operation.add(sys)

'important: add() doesn't throw so good coding practice to


'check return value
If (node Is Nothing) Then
Throw New System.Exception( _
"Couldn't add node during checkin/checkout: " & path)
End If

'execute the operation - returns true on success


If (False = operation.execute()) Then
' there were errors - we'll just display them
' all in a single message...
Dim i As Integer
Dim message As String
list = operation.getErrors()
i = 0

While (i < list.getCount())


err = list.get(i)

DFC PIA Development Guide 39


message = message & err.getMessage() & vbCrLf
i = i + 1
End While
Throw New System.Exception( _
"Checkin/checkout failed: " & path & vbCrLf & message)
End If
Else
Throw New System.Exception( _
"Couldn't obtain document for checkin/checkout: " & path)
End If
Catch e As System.Exception
MsgBox("Error: " & e.ToString)
Finally
cleanupSession(smgr, session)

If (Not Nothing Is sys) Then


System.Runtime.InteropServices.Marshal.ReleaseComObject(sys)
sys = Nothing
End If
If (Not Nothing Is node) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(node)
node = Nothing
End If
If (Not Nothing Is list) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(list)
list = Nothing
End If
If (Not Nothing Is err) Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(err)
err = Nothing
End If
End Try
End Sub

40 DFC PIA Development Guide


© 2011 - 2013 EMC Corporation. All Rights Reserved.
EMC believes the information in this publication is accurate as of its publication date. The information is subject to change
without
notice.
THE INFORMATION IN THIS PUBLICATION IS PROVIDED “AS IS.” EMC CORPORATION MAKES NO
REPRESENTATIONS OR
WARRANTIES OF ANY KIND WITH RESPECT TO THE INFORMATION IN THIS PUBLICATION, AND
SPECIFICALLY
DISCLAIMS IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Use, copying, and distribution of any EMC software described in this publication requires an applicable software license.
EMC2, EMC, and the EMC logo are registered trademarks or trademarks of EMC Corporation in the United State and other
countries.
All other trademarks used herein are the property of their respective owners.

You might also like