Contents Previous Next

Writing a Source Code Control Client

To integrate a source code control system into JDeveloper, you must write an implementation of the oracle.ide.scm.SCMClient interface. This is your source code control client and is also a JDeveloper extension. The SCMClient interface:

Hint: The class oracle.ide.scm.SCMClientAdapter provides a default implementation of SCMClient. You can subclass SCMClientAdapter and override the methods you want to use instead of implementing SCMClient directly.


Note: Remember to include JDeveloper's source code control library. Select Project | Project Settings, then select the Libraries node in Configurations | Development. You will see a list of the available and selected project libraries. Find 'JDeveloper SCM API' on the list of available libraries and move it to the list of selected libraries.

The SCMClient interface includes the following categories of methods:

Back to top

Standard Extension API Methods

The standard extension API methods are defined by the oracle.ide.addin.Addin interface:

Your client needs to register itself with JDeveloper's SCM Framework when your extension is loaded. To do this, register with the SCMManager in your client's initialize() method:

import oracle.ide.scm.SCMSystem;
...
public void initialize()
{
  SCMSystem.getRegistry().register( this );
}

For more details on implementing the other methods in the oracle.ide.addin.Addin interface, see the see the JDeveloper Extension API online help and JavaDoc. Source code control clients require no other special initialization in any of these methods.

Back to top

Identify, Activate and Deactivate

SCMClient uses two methods to identify your source code control system to users in the JDeveloper IDE:

public String getSCMName() 
{ 
  return "Acme SCM Client (Sample)"; 
} 

public String getSCMShortName() 
{ 
  return "Acme SCM"; 
}

Three methods are used to activate and deactivate your extension:

detectClient() is called when a user chooses your source code control extension from the Source Control page in Preferences. It gives your client the opportunity to prevent a user from selecting your extension if it does not meet certain prerequisites, e.g. the CVS client checks that the correct version of the cvs executable is in the user's PATH.

If you throw an oracle.ide.scm.error.SCMException from detectClient(), an alert displays containing the exception message and the user cannot activate your extension.

prepareClient() and finishClient() are called when activating and deactivating your extension from the Source Control page in Preferences. You should perform any required actions to initialize or deinitialize your client in these methods.

Hint: Hold references to other objects from your SCMClient implementation only after calling prepareClient(). You should also set any references (i.e. member variables) to null when finishClient() is called. This helps the garbage collector to manage memory usage for your extension.

Our ACME VCS sample takes no specific action in these three methods:

import oracle.ide.scm.error.SCMException;

...

public void detectClient() throws SCMException
{
}

public void prepareClient() throws SCMException
{
}

public void finishClient() throws SCMException
{
}

Hint: If your source code control system is launched using an external process and you want to verify that the correct version is installed on the user's system, you can use the SCMShellRunner utility.

Back to top

Determine Status

getStatus(SCMFile) is used when the SCM Framework needs to know the status of a file in your source code control system, e.g to determine if a specific operation is available for a file.

getStatus(SCMFile) returns an instance of SCMFileStatus, which describes information the JDeveloper IDE needs for the file status, e.g. the overlay icon used over the display icon in the System Navigator.

The concept of a file's 'status' varies between source code control systems, but the SCM Framework is flexible and manages whatever status your source code control system provides. You can implement one subclass of oracle.ide.scm.SCMFileStatusAdapter for each concept of status used.

However, many source code control systems have file states similar to the concepts of:

To implement these common states more easily and consistently, the SCM Framework provides predefined implementations of SCMFileStatus in oracle.ide.scm.util.SCMVersionFileStatus for you to use instead of implementing your own. You can simply return an instance provided by this class from getStatus(SCMFile).

Note: Do not call getStatus() on the SCMFile instance that is passed into SCMClient.getStatus(SCMFile). The implementation of SCMFile.getStatus() calls SCMClient.getStatus(SCMFile), so this would result in an unterminated recursion that would cause the JDeveloper IDE to 'hang'.

Our ACME VCS sample implements a very simple way of determining the status of a file. If the file is read-only, our sample considers the file to be checked in. Otherwise, it is considered checked out:

import oracle.ide.scm.SCMFileStatus;
import oracle.ide.scm.SCMFile;
import oracle.ide.scm.error.SCMException;
import oracle.ide.scm.util.SCMVersionFileStatus;

...
public SCMFileStatus getStatus(SCMFile f) throws SCMException
{
  if ( f.isReadOnly() )
  {
    return SCMVersionFileStatus.STATUS_CHECKED_IN;
  }
  else
  {
    return SCMVersionFileStatus.STATUS_CHECKED_OUT;
  }
}

Hint: You may not want to implement our ACME VCS exactly, as other states (especially STATUS_UNVERSIONED) are important in source code control systems. In ACME VCS, it's impossible to add a file to the source code control system because the unversioned state is not represented. Instead, you may probably run a command in your extension to determine the state of the files in your source code control system.


Hint: The performance of getStatus(SCMFile) is critical to the overall performance of your extension in the JDeveloper IDE. Avoid doing large amounts of work in this method.

From JDeveloper 9.0.4 onwards, you can determine the state of more than one file in a single query. This should improve performance, particularly for source code control clients that need to run an external command to determine this state. For more information, see the JavaDoc for SCMClient.

Back to top

Define Operation Sets

Operations performed in the SCM Framework are user actions in the JDeveloper IDE. The operations available display in the File | Source Control menu and Source Control right click context menus.

You should implement SCMClient.getOperations() in your client for the SCM Framework to determine the operations available in your client. For more details, see Implementing Operations.

getOperations() returns an instance of oracle.ide.scm.SCMOperationSet, which represents a set of operations to define the order and categories of the available operations. The operation set is used to define the contents, order and grouping of menus for your source code control extension.

In SCMClient.getOperations(), you should construct a new SCMOperationSet and add categories for your operations using addCategory().

In our ACME VCS sample, the client constructs six operations and adds them in two categories to the operation set. In JDeveloper's menus, the Add, Check Out, Check In and Undo Checkout options will appear separately to the Connect and Disconnect options:

import oracle.ide.scm.SCMOperationSet;
import oracle.ide.scm.error.SCMException;

...
public SCMOperationSet getOperations() throws SCMException
{
  SCMOperationSet ops = new SCMOperationSet();

  ops.addCategory( new Class[]
  {
    AddOperation.class,
    CheckOutOperation.class,
    CheckInOperation.class,
    UndoCheckoutOperation.class
  });
 
  ops.addCategory( new SCMOperation[]
  {
    new ConnectOperation( this ),
    new DisconnectOperation( this )
  });

  return ops;
}

Hint: You can also use addCategory(SCMOperation[]) to add instances of SCMOperation to your operation set rather than classes. This helps if you don't want to declare operations public or if you want to pass information into operations after constructing them.

Back to top

Optional Methods for Additional Features

The remaining SCMClient methods are optional methods for advanced features of the SCM Framework. They are:

For more details about these and other advanced features, see Advanced Features. If you don't want to use these features, you can safely return null (or true for isSourceControlEnabled()) from them.

Back to top

ACME VCS Sample

The sample file ACMEVCSClient.java demonstrates one way to implement SCMClient.

For more details on ACME VCS, see Introduction.

Back to top

Contents Previous Next