Steven Lange

New blog..

For those of you searching for my new blog, I’ve cropped up on MSDN.  My new blog is here:  http://blogs.msdn.com/slange

 

Posted by Steven Lange on December 19th, 2005 under Uncategorized | Comment now »


Last Post!

Hi Everyone,

Today is my last day at Borland.  It’s been a terrific ride, but it’s time to move on to a new chapter in my professional life.  I’ve learned so much about this world, effectively growing up with StarTeam since 1999 (back in the Starbase days) and CaliberRM.

I used this blog to try and provide some guidance for StarTeam & Caliber, including SDK snippets and samples.  I hope some of you found this useful.  While I will no longer be living in StarTeam anymore, I know that it’s in great hands!

The people, technology, and drive here at Borland are amazing.  Keep it all going - the core of Borland.

Best Regards, and until we cross paths again,

Steven Lange

Posted by Steven Lange on September 27th, 2005 under Uncategorized | 1 Comment »


SDK Example: Creating a query in C#

Creating a Query in C#

/* Create a StarTeam query that finds all files that have a particular name
   * Inputs:
   *  server:  the StarTeam server on which to create the query
   *  QueryName:  the name of the query (if it’s to be saved)
   *  FileNameSearch:  the string of text to search for
   *  saveQueryToServer:  If true, saves the query.  If false, returns an "in memory" Query
   * Returns:
   *  A StarTeam.Query object
   */

  private Borland.StarTeam.Query createFileQuery(Server server, String QueryName, String FileNameSearch, bool saveQueryToServer)
  {
   Debug.WriteLine("Creating query ‘" + QueryName + "‘..");
   Borland.StarTeam.Type fileType = server.TypeForName(server.TypeNames.FILE);

   Debug.WriteLine("   Creating node..");
   QueryNode node = new QueryNode(QueryNode.OP_AND);

   int propID = fileType.PropertyForName(server.PropertyNames.FILE_NAME).ID;
   
   Debug.WriteLine("   Creating part..");
   QueryPart part = new QueryPart(propID,QueryPart.REL_EQUAL,FileNameSearch,true);
   
   Debug.WriteLine("   Appending part to node..");
   node.AppendQueryPart(part);

   Debug.WriteLine("   Creating query..");
   Query query = new Query(fileType,true,QueryName,node);
   if (saveQueryToServer) query.Update();

   Debug.WriteLine("Created query!");
   return query;
  }

(Viewer requested)

Posted by Steven Lange on August 26th, 2005 under SDK Snippets, StarTeam | 2 Comments »


Getting all Files by Label in VB.NET

‘———————————————————————————
‘PARAMETERS: 
‘view:  The StarTeam view to process
‘lbl:  The StarTeam label
‘GetLabeledRevisions:  True if you want the specific revision that the label is attached to.
‘GetActiveFilesOnly:  True if you only want non-deleted files (if False, GetLabeledRevisions is ignored).
‘   If lbl is a revision label, this is ignored (and defaults to True)
‘PrintListToDebug:  Optional.  True if you want to print the results to debug
‘———————————————————————————

    Public Function GetAllFilesByLabel(ByRef view As Borland.StarTeam.View, ByRef lbl As Borland.StarTeam.Label, ByRef GetLabeledRevisions As Boolean, ByRef GetActiveFilesOnly As Boolean, Optional ByRef PrintListToDebug As Boolean = True) As Borland.StarTeam.ItemCollection
        Debug.WriteLine("Gettting all files in view ‘" & view.FullName & "‘ with label ‘" & lbl.Name & "‘")

        Dim v As View

        v = view
        If lbl.IsViewLabel And Not GetActiveFilesOnly Then
            ‘ Get all files (including deleted) files with the label attached
            v = New View(view, ViewConfiguration.CreateFromLabel(lbl.ID))
        End If

        Dim flm As New FolderListManager(v)
        flm.IncludeFolders(v.RootFolder, -1)

        Dim fileType As Type = v.Server.TypeForName(v.TypeNames.FILE)
        Dim ilm As New ItemListManager(fileType, flm)

        Dim files As ItemCollection
        Dim items As ItemCollection = ilm.Items
        Dim file As File

        If (lbl.IsViewLabel And GetActiveFilesOnly) Or lbl.IsRevisionLabel Then
           
            items = ilm.SelectByLabel(lbl)
            If GetLabeledRevisions Then
                files = New ItemCollection
                For Each file In items
                    files.Add(file.GetFromHistoryByLabelID(lbl.ID))
                Next
            Else
                files = items
            End If
        Else
            files = items
        End If

        If PrintListToDebug Then
            Debug.WriteLine("Total Files: " & files.Count)
            For Each file In files
                Debug.WriteLine(file.ParentFolderHierarchy & file.Name & ", v. " & file.DotNotation)
            Next
        End If

        Return files
    End Function

(Viewer requested)

Posted by Steven Lange on August 25th, 2005 under SDK Snippets, StarTeam | 2 Comments »


StarTeam 2005 Release 2

If you haven’t moved to R2 yet, definitely consider it.  In addition to the obligatory number of bugs addressed, there are several new bells and whistles that you may find useful:

Server

  • Support for DB2 as the underlying RBDBMS has been added
  • The Server Tools and Server Administration utilities have been combined into a more complete Server Administration utility.  This means that you can create and manage server configurations in the same dialog that you can administer server configurations, such as user/group management.
  • Borland licensing is now supported.

Clients

  • The clients have been given a much-needed facelift.  New icons
  • The Cross-Platform Client now includes charting capabilities similar to the Windows client
  • The Cross-Platform Client now has URL/HTMP support.  The client recognizes StarTeam URL’s to ease navigation to specific artifacts in the StarTeam Server.  You can easily create URL’s to items via a simple context menu item which copies the URL to the clipboard.
  • In the CP Client, you can now perform some additional operations in the Links pane, like checking out linked files.

Integrations

  • A new embedded Visual Studio .NET integration.  This integration brings the main components of StarTeam into the IDE itself, giving developers direct access to CR’s, Tasks, and Topics.
  • The Eclipse integration now supports alternate property editors (APE’s).

There are additional enhancements in the realm of MPX, LDAP QuickStart, and Import/Export Manager, too, but I won’t bore you with additional list..

Posted by Steven Lange on August 10th, 2005 under StarTeam | 3 Comments »


Requirements vs. Tasks: Which to Use?

http://blogs.msdn.com/slange/archive/2005/12/30/508229.aspx

Posted by Steven Lange on July 26th, 2005 under RM-CM-SCM Rants | Comment now »


File Lock Report

Generate an HTML report for a given project listing all files that are locked and by whom.  If audit generation is enabled on the server, then the script queries the audit entries to report when the file was locked.

You can download the report script: http://www.langewd.com/BlogFiles/GetFile.asp?FileLockReport.zip

 

Posted by Steven Lange on July 1st, 2005 under Reports, SDK Snippets, StarTeam | 2 Comments »


Article: Filters, Queries, and the StarTeam SDK

If you’ve ever used a StarTeam client, you’ve used a filter and/or a query when you look at items within a StarTeam folder. Filters and queries are great tools for organizing and managing the data that StarTeam presents to you. This article provides an overview of how to use filters and queries with the SDK.

URL: http://blogs.codegear.com/slange/articles/6674.aspx

Posted by Steven Lange on June 10th, 2005 under SDK Snippets, StarTeam | Comment now »


Filters, Queries, and the StarTeam SDK

 

Overview

If you’ve ever used a StarTeam client, you’ve used a filter and/or a query when you look at items within a StarTeam folder.  Filters and queries are great tools for organizing and managing the data that StarTeam presents to you.  You can create a virtual "inbox", showing only items for which you are responsible, only open items, items sorted by severity or priority, or files with a given set of extensions.  Many times when you look at data in StarTeam you’re looking for something - filters and queries will help you find it more easily.

With the StarTeam SDK, the same convenience applies.  When using the ItemListManager class, you can apply filters and queries just as you do within the client.  However, the API allows you to create filters and queries "in memory" for the purpose of criteria matching dynamically (i.e. the criteria for the desired data set may need to change programmatically).  Of course, a few caveats apply, but the effectiveness of using filters and queries via the SDK becomes quite obvious once put into use.

This article will show you how to create, access, and use both filters and queries with the SDK to better help you find specific StarTeam items.

ItemListManager class

Before jumping completely into filters and queries, it’s important to have a basic understanding of the ItemListManager class.  This class is great for capturing large sets of data in only a few calls to the StarTeam server.  It’s closest UI translation would be the upper-right (items) pane, which displays items based on the selected folder, all descendants, access rights, and any applied filters or queries.  The ItemListManager class is probably the most efficient way to collect data from multiple folders at once, without having to use any recursive functions in your code.

Here is a quick, basic sample of how you can use the ItemListManager class to get all the Change Requests in a given view:

    private Items GetAllCRsInView(View view){
// Create a FolderListManager object
FolderListManager flm = new FolderListManager(view);

// Add all folders in the view to the FolderList Manager object
// (this is the equivalent of using "All Descendants"

flm.includeFolders(view.getRootFolder(),-1);

// Get the Change Request type object. This specifies that we want
// CR’s from the folders in the FolderListManager object.

Type crType = view.getServer().typeForName(view.getTypeNames().CHANGEREQUEST);

// Create the ItemListManager object, specifying the type of items
// we want and the FolderListManager object to use.

ItemListManager ilm = new ItemListManager(crType,flm);

return ilm.getItems();
}


If you look at the API documentation, you’ll see that there are a lot of other options you can use when performing this type of operation.  But the above should serve as a basic, functional example.


For a great write-up on how you can optimize the ItemListManager class, check out this article from CodeAlloy: http://www.codealloy.com/sdkoptimize.htm


Now that that’s taken care of, let’s move on.  The rest of this article will build off of this initial function.


Filters


Definition: A filter is a named arrangement of data that consists of a set of fields (used as column headers), sorting and grouping information, and (usually) a query. Once a filter has been created, it can be used in every project that has the same server configuration. You can filter data several different ways:



  • By applying an existing filter.
  • By arranging the data (changing displayed fields, sorting and grouping the files, etc.) and applying a query. You can then use this arrangement as the basis for a new filter.
  • By creating a new filter from scratch.

In this article we’ll cover the first and third methods.


Applying an Existing Filter


To apply an existing filter to an ItemListManager object, you’ll need to acquire the appropriate Filter object first.  Filters can be retrieved using the Type class in the StarTeam SDK.  Why?  Because filters, by definition, are global to the server (not bound to a given project or view), yet specific to a type of StarTeam item.  The method call for getting a Filter object, assuming you know the name of the filter, is Type.getFilterForName() (please note that there is also a Type.getFilterForID(), which takes the ID of the filter you want).  I also recommend using Type.hasFilterForName() to ensure that you’re specifying the correct filter (in case of a type-o, this is much easier than trying to trap an exception because StarTeam couldn’t find the filter you wanted).


Once you have the correct Filter object, you can call ItemListManager.SetFilter() to apply the filter.


So, lets expand the example function above to include what we’ve just talked about.  This time, we’ll also pass the name of the filter we want to apply as an additional parameter.

    private Items GetAllCRsInView(View view, String filtername){
FolderListManager flm = new FolderListManager(view);
flm.includeFolders(view.getRootFolder(),-1);
Type crType = view.getServer().typeForName(view.getTypeNames().CHANGEREQUEST);

ItemListManager ilm = new ItemListManager(crType,flm);

// Check to see if the named filter exists
if (crType.hasFilterForName(filtername)){
// It does exist, so let’s get it
Filter filter = crType.getFilterForName(filtername);
// Now, apply it to the ItemListManager object
ilm.setFilter(filter);
}

return ilm.getItems();
}


Creating a New Filter from Scratch


To Create a new filter, you construct a new Filter object, specify what fields you wish to include (this tells StarTeam what properties to send back from the Server in a single response), and any sorting or grouping options you want.


In the below example, we’ll create an "in memory" filter, that is, one that is not saved to the server as a permanent filter.  If you wish to create a permanent filter, you simply need to call Filter.update() prior to the function’s return statement.  By creating an "in memory" filter, you can dynamically customize how your program will retrieve data from StarTeam, without necessarily affecting the server’s filter list (and other users’ filter list, for that matter).  This allows you to take advantage of filtering multiple times in your program without pushing extra filter data to the StarTeam database.


The function below creates an "in memory" filter for Change Request items, capturing the CR number, status, and synopsis properties, and sorts them by status.

    private Filter CreateNewFilter(Server server){
// We need the Type object for Change Request items
Type crType = server.typeForName(server.getTypeNames().CHANGEREQUEST);
// Create the new filter
Filter filter = new Filter(crType,"My New Filter",Filter.CONTEXT_SERVER,false);

// Add the columns (properties) that we want to include
// Add the CR Number property

filter.appendColumn(server.getPropertyNames().CR_CHANGE_NUMBER, 1);
// Add the Status property
filter.appendColumn(server.getPropertyNames().CR_STATUS, 1);
// Add the Synopsis property
filter.appendColumn(server.getPropertyNames().CR_SYNOPSIS, 1);

// Specify that we want to sort by Status
filter.appendGroupSortInfo(false,server.getPropertyNames().CR_STATUS,true);

// If we wanted to make this filter a permanent one (saved to the
// StarTeam Server, we would uncomment the next line:
//filter.update();

return filter;
}


So to use this new function with our base example, we would change the initial function to use the temporary filter created by the above function:

    private Items GetAllCRsInView(View view){
FolderListManager flm = new FolderListManager(view);
flm.includeFolders(view.getRootFolder(),-1);
Type crType = view.getServer().typeForName(view.getTypeNames().CHANGEREQUEST);

ItemListManager ilm = new ItemListManager(crType,flm);

// Get the new temporary filter
Filter filter = CreateNewFilter(view.getServer());
ilm.setFilter(filter);

return ilm.getItems();
}


Now we’ll move on to queries.  At the end of the next section, you’ll see how you can use both a filter and a query with the ItemListManager object.



Queries


Definition:  A query is a feature that you can use a query to limit the items displayed in the upper pane. Each query is performed on all items in the StarTeam folder and component you have selected. Once a query has been created, it can be used in every project in the same server configuration.


StarTeam queries have the following attributes:



  • A unique name that easily identifies the query. Query names are not case-sensitive.
  • Public or private status. Public queries can be used by anyone with the appropriate access rights, while private queries are available only to your user ID. Once a query has been saved with a specific status, its status cannot be changed. However, you can copy a query and change the state of the new query.
  • A logical expression appropriate for items of a particular type. These expressions include one or more conditions. A condition consists of a field (not necessarily a current column header), a relational operator, and a value to be compared to the value of the field. For example, a condition used to locate change requests might be: Responsibility Equals Rhonda Thurman.

With the SDK, queries can be used with the ItemListManager class a few ways:



  • Applying a query to a populated ItemListManager object to get a subset of results (a "populated" ItemListManager object is one that has already retrieved data from the server by calling methods like .getItems() and .getItemsArray()).
  • Applying an existing query to a Filter, which is then in turn applied to an ItemListManager object.
  • Creating a new query, and utilizing it with one of the first two methods above.

Applying a Query to a Populated ItemListManager Object


To apply an existing query to an ItemListManager object, you’ll need to acquire the appropriate QueryInfo object first.  QueryInfo objects can be retrieved using the Type class in the StarTeam SDK for the same reason described above for filters.  The method call for getting a QueryInfo object, assuming you know the name of the query, is Type.getQueryForName() (please note that, like filters, there is also a Type.getQueryForID(), which takes the ID of the query you want).  I again recommend using Type.hasQueryForName() to ensure that you’re referring to the correct query.


Once you have the correct QueryInfo object, you can call ItemListManager.selectByQuery() to apply the query and get a subset of results matching the query’s criteria.


Now let’s see a basic example of this, again building from the base example:

    private Items GetAllCRsInView(View view, String queryname){
FolderListManager flm = new FolderListManager(view);
flm.includeFolders(view.getRootFolder(),-1);
Type crType = view.getServer().typeForName(view.getTypeNames().CHANGEREQUEST);

ItemListManager ilm = new ItemListManager(crType,flm);

// Check to see if the named query exists
if (crType.hasQueryForName(queryname)){
// It does exist, so let’s get it
QueryInfo query = crType.getQueryForName(queryname);

// "Populate" the ItemListManager object
ilm.getItems();
// Now, apply the query and return the subset
return ilm.selectByQuery(query);
}
else {
return ilm.getItems();
}
}


Note that ilm.getItems() is called prior to ilm.selectByQuery().  This is necessary for the second call to have an initial result set to which it can apply the query.  If you don’t "populate" the ItemListManager object first, you will receive no results.


Applying an Existing Query to a Filter


If you’ve ever looked at the Filter dialog in the StarTeam client, you’ve probably see that a filter can have a query associated with it.  This is convenient in that you can specify both what items to display (query) and how they are displayed (filter) in a single operation.


With the SDK, applying a query to a filter is effectively the same thing.  You can apply an existing (not "in memory") QueryInfo object to a Filter object and save your changes (so the filter permanently uses the specified query), or programmatically use the filter/query combination with an ItemListManager object and dispose of it when done.


To show this, let’s expand on the "CreateNewFilter()" function above, and apply a named query as well.

    private Filter CreateNewFilter(Server server, String queryname){
Type crType = server.typeForName(server.getTypeNames().CHANGEREQUEST);

Filter filter = new Filter(crType,"My New Filter",Filter.CONTEXT_SERVER,false);

filter.appendColumn(server.getPropertyNames().CR_CHANGE_NUMBER, 1);
filter.appendColumn(server.getPropertyNames().CR_STATUS, 1);
filter.appendColumn(server.getPropertyNames().CR_SYNOPSIS, 1);

filter.appendGroupSortInfo(false,server.getPropertyNames().CR_STATUS,true);

// Look for and apply the named query, if it exists
if (crType.hasQueryForName(queryname)){
// It does exist, so let’s get it
QueryInfo query = crType.getQueryForName(queryname);
// Associate the existing query with the new filter
filter.setQueryID(query.getID());
}

// If we wanted to make this filter a permanent one (saved to the
// StarTeam Server, we would uncomment the next line:
//filter.update();

return filter;
}


Now, if we were to apply this filter to an ItemListManager object as described above, both the filter and the associated query would be applied.  This is more efficient than calling .selectByQuery() because you are not forced to fetch the entire superset of items from the server before applying a query.  It is applied "on the fly" because it is included with the filter (which is applied on the server side during the initial fetch of items).


Here’s the caveat:  To associate a query with a filter, the query must be an existing or permanent filter on the server - it cannot reside solely in memory.  This is because since the filter is applied on the server side, the server needs to know about the associated query to use (which is impossible if the query exists only in client-side memory).  If you try to apply an "in memory" query to a filter (Filter.setQueryID()), you’ll effectively be passing -1 as the query’s ID, which will ultimately be ignored by the Filter and ItemListManager.


Creating a New Query


Creating queries can be very useful for creating multi-conditional searches within your application.  Queries can have multiple logical operators containing multiple logical expressions, basically forming a query tree.  To create a new query, you need to first understand the implications of where you set query "nodes" and their expressions to get the expected result.


The below example is relatively simple, but should provide a good framework to allow you to build more complex, specific queries.  This example will create a query for Change Requests that finds CR’s with a "New" status and whose synopsis contains the word "StarDraw":

    private QueryInfo CreateNewQuery(Server server){
Type crType = server.typeForName(server.getTypeNames().CHANGEREQUEST);

// Create a QueryNode
QueryNode node = new QueryNode(QueryNode.OP_AND);

// Create a QueryPart for: Status = "New"
int propertyID = crType.propertyForName(server.getPropertyNames().CR_STATUS).getID();
int statusNew = server.getPropertyEnums().CR_STATUS_NEW;
QueryPart part = new QueryPart(propertyID,QueryPart.REL_EQUAL,statusNew);
// Add the QueryPart to the QueryNode
node.appendQueryPart(part);

// Create a QueryPart for: Synopsis contains "StarDraw" (ignore case)
propertyID = crType.propertyForName(server.getPropertyNames().CR_SYNOPSIS).getID();
part = new QueryPart(propertyID,QueryPart.REL_TEXTSEARCH,"StarDraw",false);
// Add the QueryPart to the QueryNode
node.appendQueryPart(part);

// Create the QueryInfo object
QueryInfo query = new QueryInfo(crType,false,"My Temporary Query",node);

// If we wanted to make this query a permanent one (saved to the
// StarTeam Server), we would uncomment the next line:
//query.update();

return query;
}


I recommend that you play around with adding additional QueryNode objects at different hierarchies, and different types of QueryPart objects (data types, operators, etc.).



Well, I hope this helps some of you become more familiar with how you can use both filters and queries with the SDK in your applications.  There are several additional layers of detail that you can get into with the ItemListManager, Filter, and Query* classes, and the best way to tap those layers is to take a test drive.


Good luck, and happy programming!

Posted by Steven Lange on June 10th, 2005 under Source Code, StarTeam | 2 Comments »


New category: Reports

I’m gradually building a collection of StarTeam and CaliberRM reports (SDK-based, Datamart, other..) which I want to start sharing as I find the time.  So I’ve created a new blog category (aptly-named Reports) to capture these as they become available.

Stay tuned!

Posted by Steven Lange on March 30th, 2005 under CaliberRM, Reports, StarTeam | Comment now »




Server Response from: blog2.codegear.com