Wednesday, August 24, 2011

P4 Java API. How to work with temporary clients.

Check new series of the articles. Review and user experience on test management systems. Functionality and usability.

There is not a lot of information about perforce Java API. However you may find the examples of how to apply the common use cases in your code. I tried to touch surrounding cases and faced the problem that had been resolved with the only decompilation help.

So assume you do not want to use the existing client and you do want to use the temporary one. How to address such the requirement. Here is the code from me.

package ar.p4apihelpers;

import java.util.List;
import java.util.UUID;

import com.perforce.p4java.client.IClient;
import com.perforce.p4java.core.IMapEntry.EntryType;
import com.perforce.p4java.core.file.FileSpecBuilder;
import com.perforce.p4java.core.file.IFileSpec;
import com.perforce.p4java.exception.P4JavaException;
import com.perforce.p4java.impl.generic.client.ClientView;
import com.perforce.p4java.impl.generic.client.ClientView.ClientViewMapping;
import com.perforce.p4java.impl.mapbased.client.Client;
import com.perforce.p4java.server.IServer;
import com.perforce.p4java.server.IServerInfo;
import com.perforce.p4java.server.ServerFactory;

public class P4APISyncUp{
 public static void main(String[] args) throws URISyntaxException, IOException, P4JavaException {
  // Generating the files to sync-up
  String[] pathsUnderDepot = new String[]{
  // Instantiating the server
  IServer p4Server = ServerFactory.getServer("p4java://", null);
  // Authorizing
  // Just check you are connected successfully
  IServerInfo serverInfo = p4Server.getServerInfo();
  // Creating new client
  IClient tempClient = new Client();
  // Setting up the name and the root folder
  tempClient.setName("tempClient" + UUID.randomUUID().toString().replace("-", ""));
  // Setting the client as the current one for the server
  // Creating Client View entry
  ClientViewMapping tempMappingEntry = new ClientViewMapping();
  // Setting up the mapping properties
  tempMappingEntry.setRight("//" + tempClient.getName() + "/...");
  // Creating Client view
  ClientView tempClientView = new ClientView();
  // Attaching client view entry to client view
  // Registering the new client on the server
  // Surrounding the underlying block with try as we want some action
  // (namely client removing) to be performed in any way 
   // Forming the FileSpec collection to be synced-up
   List<ifilespec> fileSpecsSet = FileSpecBuilder.makeFileSpecList(pathsUnderDepot);
   // Syncing up the client
   tempClient.sync(FileSpecBuilder.getValidFileSpecs(fileSpecsSet), true, false, false, false);
   // Removing the temporary client from the server
   System.out.println(p4Server.deleteClient(tempClient.getName(), false));

Please point the attention to the lines #42 and #50 of this code. Forgetting to call #42 leads to the following exception on execution #64:
Exception in thread "main" java.lang.NullPointerException
at com.perforce.p4java.impl.mapbased.client.Client.sync(
at com.perforce.p4java.impl.mapbased.client.Client.sync(
at ar.p4apihelpers.P4APISyncUp.main

If you forget to call #50 you will get the exception like this:
Exception in thread "main" com.perforce.p4java.exception.RequestException: Error in client specification.
Error detected at line 10.
Null directory (//) not allowed in 'null//depot/...'.

at com.perforce.p4java.impl.mapbased.server.Server.handleErrorStr(
at com.perforce.p4java.impl.mapbased.server.Server.createClient(
at ar.p4apihelpers.P4APISyncUp.main