Introduction to the CodeCentral Web Service

By: David Clegg

Abstract: Introduces the features of the new CodeCentral Web Service, and presents an Open Tool add-in which consumes it.

    Introduction

The Borland Developer Network CodeCentral web site is an excellent repository for code snippets, demo applications and other valuable programming resources. Some of this functionality has now been exposed by a new web service, enabling developers to leverage this repository with their own custom applications.

To compliment this launch, an Open Tool has also been created to allow developers to search the CodeCentral repository and download CodeCentral snippets from within the Borland Developer Studio 2006 or Delphi 2005 IDE.

    The CodeCentral Web Service

    Web Service Location

The CodeCentral Web Service can be accessed from http://cc.borland.com/ccws/cc.asmx, and the formal specification for it can be obtained from http://cc.borland.com/ccws/cc.asmx?wsdl.

    Exposed Functionality

The CodeCentral web service currently provides a read-only view of the CodeCentral repository, but there are plans to update the functionality in future to include rating and commenting support, and the ability to add and edit submissions.

Nearly all methods exposed by the web service have two versions. One version returns a serialized System.Data.DataSet containing the results of the search operation, and the other returns a ZLib compressed array of bytes representing the XML document for the serialized DataSet. The former is slightly easier to develop clients for, but the ZLib compressed versions provide better performance as less data needs to be transferred for each method call.

Below is a summary of all the methods currently exposed by the web service :-

//Login using a valid BDN e-mail address and Password. The returned
//DataSet will contain a SessionID which must be used for subsequent 
//web service calls.
function Login(const AEmail, APassword, AUserAgent: string): DataSet;

//Login using a valid BDN e-mail address and Password. The returned
//DataSet will contain a SessionID which must be used for subsequent 
//web service calls. The result is a ZLib compressed version of the 
//XML Document representing the underlying DataSet.
function LoginZLib(const AEmail, APassword, AUserAgent: string): TByteArray;

//Perform a search against all CodeCentral submissions visible to the
//logged in user.
function Search(const ASessionID, AIDList, AProductList, ASubmitter, 
  ACategoryList: string; ALowVersion, AHighVersion : double; 
  AFromDate, AToDate : DateTime; AUseDates : Boolean;
  AKeywords: string; ACopyright: Integer): DataSet;

//Perform a search against all CodeCentral submissions visible to the
//logged in user. The result is a ZLib compressed version of the XML 
//Document represending the underlying DataSet.
function SearchZLib(const ASessionID, AIDList, AProductList, 
  ASubmitter, ACategoryList: string; ALowVersion, 
  AHighVersion : double; AFromDate, AToDate : DateTime; 
  AUseDates : Boolean; AKeywords: string; ACopyright: Integer): TByteArray;

//Return details for a specified CodeCentral entry.
function GetSnippet(const ASessionID: string; 
  const ASnippetID: Integer): DataSet;

//Return details for a specified CodeCentral entry. The result is a
//compressed version of the XML Document representing the underlying 
//DataSet.
function GetSnippetZLib(const ASessionID: string; 
  const ASnippetID: Integer): TByteArray;

//Download the attachment for a specified CodeCentral entry.
function DownloadAttachment(const ASessionID: string; 
  const ASnippetID: Integer): TByteArray;

//Retrieve details of all valid CodeCentral products which can be used
//when performing a search.
function GetProducts(const ASessionID: string): DataSet;

//Retrieve details of all valid CodeCentral products which can be used
//when performing a search. The result is a ZLib compressed version of 
//the XML Document representing the underlying DataSet.
function GetProductsZLib(const ASessionID: string): TByteArray;

//Retrieve details of all valid CodeCentral categories which can be 
//used when performing a search.
function GetCategories(const ASessionID: string): DataSet;

//Retrieve details of all valid CodeCentral categories which can be 
//used when performing a search. The result is a ZLib compressed 
//version of the XML Document representing the underlying DataSet.
function GetCategoriesZLib(const ASessionID: string): TByteArray;

//Retrieve details of all valid CodeCentral copyright details which 
//can be used when performing a search.
function GetCopyrights(const ASessionID: string): DataSet;

//Retrieve details of all valid CodeCentral copyright details which 
//can be used when performing a search. The result is a compressed 
//version of the XML Document representing the underlying DataSet.
function GetCopyrightsZLib(const ASessionID: string): TByteArray;

//Retrieve details of all valid CodeCentral terms.
function GetTerms(const ASessionID: string): DataSet;

//Retrieve details of all valid CodeCentral terms. The result is a
//compressed version of the XML Document representing the underlying 
//DataSet.
function GetTermsZLib(const ASessionID: string): TByteArray;

//Retrieve the list of all CodeCentral downloads ever performed by 
//this user.
function GetAllDownloads(const ASessionID: string): DataSet;

//Retrieve the list of all CodeCentral downloads ever performed by 
//this user. The result is a ZLib compressed version of the XML 
//Document representing the underlying DataSet.
function GetAllDownloadsZLib(const ASessionID: string): TByteArray;

//Retrieve the list of all CodeCentral submissions downloaded by this 
//user that have been updated since they were downloaded.
function GetOutdatedDownloads(const ASessionID: string): DataSet;

//Retrieve the list of all CodeCentral submissions downloaded by this 
//user that have been updated since they were downloaded. The result 
//is a compressed version of the XML Document representing the 
//underlying DataSet.
function GetOutdatedDownloadsZLib(const ASessionID: string): TByteArray;

//Retrieve the list of all CodeCentral submissions for this user that
//have comments associated with them.
function GetSnippetsWithComments(const ASessionID: string): DataSet;

//Retrieve the list of all CodeCentral submissions for this user that
//have comments associated with them. The result is a ZLib compressed version
//of the XML Document representing the underlying DataSet.
function GetSnippetsWithCommentsZLib(const ASessionID: string): TByteArray;

//Retrieve the list of all CodeCentral submissions which this user has
//commented on.
function GetSnippetsCommentedByUser(const ASessionID: string): DataSet;

//Retrieve the list of all CodeCentral submissions which this user has
//commented on. The result is a ZLib compressed version of the XML 
//Document representing the underlying DataSet.
function GetSnippetsCommentedByUserZLib(const ASessionID: string): TByteArray;

//Retrieve the list of all CodeCentral submissions for this user that
//have ratings associated with them.
function GetSnippetsWithRatings(const ASessionID: string): DataSet;

//Retrieve the list of all CodeCentral submissions for this user that
//have ratings associated with them. The result is a ZLib compressed 
//version of the XML Document representing the underlying DataSet.
function GetSnippetsWithRatingsZLib(const ASessionID: string): TByteArray;

//Retrieve the list of all CodeCentral submissions which this user has
//rated.
function GetSnippetsRatedByUser(const ASessionID: string): DataSet;

//Retrieve the list of all CodeCentral submissions which this user has
//rated. The result is a ZLib compressed version of the XML Document 
//representing the underlying DataSet.
function GetSnippetsRatedByUserZLib(const ASessionID: string): TByteArray;

//Return a list of recommended CodeCentral submissions based on the
//attributes of a specified submission.
function GetRecommendations(const ASessionID: string; const ASnippetID: Integer): DataSet;

//Return a list of recommended CodeCentral submissions based on the
//attributes of a specified submission. The result is a ZLib 
//compressed version of the XML Document representing the underlying 
//DataSet.
function GetRecommendationsZLib(const ASessionID: string; 
  const ASnippetID: Integer): TByteArray; 

It is important to note that the GetRecommendations and GetRecommendationsZLib searches have not yet been fully implemented, so calling these methods will currently result in an exception being thrown stating that the method has not yet been implemented.

    Consuming the Web Service

    Using the Open Tool

An Open Tool for Borland Developer Studio 2006 and Delphi 2005 has been developed in conjunction with the web service, and this surfaces all the functionality currently exposed by it. Below is a screenshot of the Open Tool in action :-

Hide image
Click to see full-sized image

The CodeCentral Open Tool for BDS 2006 can be downloaded from here, and the one for Delphi 2005 can be downloaded from here.

    Developing a .NET Client

A Delphi for .NET WinForms client demonstrating how to consume the CodeCentral web service can be downloaded from here. While it does consume every method of the web service, it was designed primarily to demonstrate how to develop .NET clients for it, and is not intended to be a fully feature rich or production ready implementation.

    Developing a Client using Delphi Win32

In order to facilitate ease of development of the CodeCentral Open Tool, which was written in Delphi Win32, a number of components descending from TCustomProvider were created. This allows the data returned from the web service methods to be used to populate a TClientDataSet, which can then be easily bound to any data aware control. It also makes consuming the web service methods very easy, as the following code snippet demonstrates. This below example is taken from the Delphi Win32 demo client, and shows how to return the details for a specified CodeCentral submission :-

procedure TMainForm.aShowSnippetExecute(Sender: TObject);
var
  lCursor: TCursor;
begin
  lCursor := Screen.Cursor;
  Screen.Cursor := crHourglass;
  try
    cdsSnippet.Active := False;
    cpSnippet.SnippetID := StrToInt(leID.Text);
    dbgResults.DataSource := dsSnippet;
    cdsSnippet.Active := True;
  finally
    Screen.Cursor := lCursor;
  end;
end;

The run-time and design-time packages for these components are installed as part of the Open Tool installer, but are not installed into the BDS IDE. In order to install these components, perform the following steps :-

- Select ‘Component->Install Packages’ from the IDE main menu

- Click the ‘Add…’ button and navigate to the ‘<BDS 2006 Directory>\CodeCentral AddIn’ directory.

- Select ‘dclCCProvPkg100.bpl’ from the list of files, and click the ‘Open’ button.

The CodeCentral provider components communicate with the web service by using the THTTPRIO component assigned to the RIO property. The TCCSessionProvider is used to login and establish a session with the CodeCentral web service, and every other CodeCentral provider component exposes a Session property which can be assigned a valid TCCSessionProvider instance. This allows them to share the information for an already established CodeCentral session. If the Session property is not set for a CodeCentral provider, it would be necessary to set the RIO, Email and Password properties, and would result in a separate web service session being established when that provider was invoked by the associated TClientDataSet instance.

A Delphi Win32 client demonstrating how to consume the CodeCentral web service can be downloaded from here. As with the Delphi for .NET demo client, it is designed to demonstrate how to consume the methods of the web service, and is not intended to be a fully feature rich or production ready implementation.

    Feedback is welcome

Feedback is welcome for the CodeCentral web service, the Open Tool, or any of the demo clients, and can be submitted to the CodeCentral area of QualityCentral.

    Acknowledgements

Thanks to Sinan Karaca of InstallAware Software, http://www.installaware.com, for providing the copy of InstallAware 6 used to create the CodeCentral Open Tool installer.

ZLib compression support for the Delphi for .NET demo client is provided by the SharpZipLib library, http://www.icsharpcode.net/OpenSource/SharpZipLib.

Server Response from: ETNASC04