# Java example

> Use the Java example to build a Unity Version Control client REST API client with Retrofit.

## Overview

This Java example demonstrates how to build a Unity Version Control CM API client using Retrofit, a popular HTTP client
library for Java applications. You can use this code as a starting point for integrating Unity Version Control
functionality into your Java-based tools and applications.

The example includes a console application that allows you to do the following:

* **List repositories:** Display all repositories available on your Unity Version Control server.
* **Create repositories:** Add new repositories with specified names and server configurations.
* **Rename repositories:** Update existing repository names.
* **Delete repositories:** Remove repositories from your server.

The code uses Retrofit to handle REST API communication. The code demonstrates how to structure your Java application for Unity Version Control integration with proper separation of concerns between API interfaces, data models,
and business logic.

## Program

`/src/main/java/com/unity/versioncontrol/examples/Program.java`

```java
package com.unity.versioncontrol.examples;

import com.unity.versioncontrol.examples.actions.CreateRepositoryAction;
import com.unity.versioncontrol.examples.actions.RenameAction;
import com.unity.versioncontrol.examples.models.Repository;
import retrofit.Callback;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.Response;

import java.util.List;
import java.util.Scanner;

public class Program {

    static IApi apiClient;
    static Scanner in;
    // Menu options that correspond to Unity Version Control CM command equivalents
    static String instructions = "1 - List repositories (cm repository list)\n" +
    "2 - Create a repository (cm repository create)\n" +
    "3 - Rename a repository (cm repository rename)\n" +
    "4 - Delete a repository (cm repository delete)\n" +
    "\n"                                   +
    "Select an option (1/2/3/4): ";

    static void initApiClient() {
        // Configure Retrofit to connect to your Unity Version Control CM server
        RestAdapter adapter = new RestAdapter.Builder()
                .setEndpoint("http://localhost:9090")
                .build();

        apiClient = adapter.create(IApi.class);
    }

    static void listRepositories() {
        // Retrieve and display all repositories from the server
        List<Repository> repositories = apiClient.getRepositories();
        for(Repository repo : repositories) {
            System.out.println(String.format("%d_%d %s %s",
                    repo.getRepId().getId(),
                    repo.getRepId().getModuleId(),
                    repo.getName(),
                    repo.getServer()));
        }
    }

    static void createRepository() {
        // Collect repository details from user input
        System.out.print("Write a name for the repository: ");
        String name = in.nextLine();
        System.out.print("Write the direction of the server: ");
        String server = in.nextLine();

        // Create the repository creation request
        CreateRepositoryAction action =
                new CreateRepositoryAction(name, server);

        // Send the request and display confirmation
        Repository newRepo = apiClient.createRepository(action);
        System.out.println(String.format(
                "Repository %s successfully created!", newRepo.getName()));
    }

    static void renameRepository() {
        // Show available repositories for user selection
        listRepositories();
        System.out.print("Write the name of the repository to rename: ");
        String repository = in.nextLine();
        System.out.print(String.format("Write a new name for %s: ", repository));
        String newName = in.nextLine();

        // Execute the rename operation
        RenameAction action = new RenameAction(newName);
        Repository renamedRepo =
                apiClient.renameRepository(repository, action);
        System.out.println(
                String.format("Repository %s successfully renamed to %s.",
                        repository, renamedRepo.getName())
        );
    }

    static void deleteRepository() {
        // Display available repositories for deletion selection
        listRepositories();
        System.out.print("Write the name of the repository to delete: ");
        String repository = in.nextLine();

        // Use callback pattern for delete operation due to Retrofit limitations
        apiClient.deleteRepository(repository, new Callback<Void>() {
            @Override
            public void success(Void aVoid, Response response) {
                // Check response status code to confirm successful deletion
                System.out.println("Repository successfully deleted!");
            }

            @Override
            public void failure(RetrofitError retrofitError) {
                System.err.println("Failed to delete repository: " + retrofitError.getMessage());
            }
        });
    }

    public static void main(String[] args) {
        // Initialize the API client and display menu options
        initApiClient();

        System.out.print(instructions);
        in = new Scanner(System.in);
        String optionStr = in.nextLine();
        int option;

        // Parse user input with fallback to default option
        try {
            option = Integer.valueOf(optionStr);
        } catch (NumberFormatException e) {
            option = 1;
        }

        // Route to the appropriate repository operation
        switch (option) {
            case 1:
            default:
                listRepositories();
                break;
            case 2:
                createRepository();
                break;
            case 3:
                renameRepository();
                break;
            case 4:
                deleteRepository();
                break;
        }

    }
}
```

## Actions

These action classes represent the data structures for API requests. They encapsulate the parameters needed for
repository operations and are serialized to JSON when sent to the Unity Version Control CM API.

`/src/main/java/com/unity/versioncontrol/examples/actions/CreateRepositoryAction.java`

```java
package com.unity.versioncontrol.examples.actions;

import com.sun.istack.internal.NotNull;

public class CreateRepositoryAction {

    private String name;
    private String server;

    public CreateRepositoryAction(@NotNull String name,
                                  @NotNull String server) {
        this.name = name;
        this.server = server;
    }
}
```

`/src/main/java/com/unity/versioncontrol/examples/actions/RenameAction.java`

```java
package com.unity.versioncontrol.examples.actions;

import com.sun.istack.internal.NotNull;

public class RenameAction {

    private String name;

    public RenameAction(@NotNull String name) {
        this.name = name;
    }
}
```

## Models

These model classes represent the data structures returned by the Unity Version Control CM API. They use standard Java
conventions with getter methods and correspond to the JSON response format from the API endpoints.

`/src/main/java/com/unity/versioncontrol/examples/models/Owner.java`

```java
package com.unity.versioncontrol.examples.models;

public class Owner {

    private String name;
    private boolean isGroup;

    public String getName() { return name; }
    public boolean isGroup() { return isGroup; }
}
```

`/src/main/java/com/unity/versioncontrol/examples/models/RepId.java`

```java
package com.unity.versioncontrol.examples.models;

public class RepId {

    private int id;
    private int moduleId;

    public int getId() { return id; }
    public int getModuleId() { return moduleId; }
}
```

`/src/main/java/com/unity/versioncontrol/examples/models/Repository.java`

```java
package com.unity.versioncontrol.examples.models;

import java.util.UUID;

public class Repository {

    private RepId repId;
    private Owner owner;
    private String name;
    private UUID guid;
    private String server;

    public RepId getRepId() { return repId; }
    public Owner getOwner() { return owner; }
    public String getName() { return name; }
    public UUID getGuid() { return guid; }
    public String getServer() { return server; }
}
```

## API Interface

This interface defines the Unity Version Control CM API endpoints using Retrofit annotations. It provides a clean,
type-safe way to interact with the REST API and automatically handles request/response serialization.

`/src/main/java/com/unity/versioncontrol/examples/IApi.java`

```java
package com.unity.versioncontrol.examples;

import com.unity.versioncontrol.examples.actions.CreateRepositoryAction;
import com.unity.versioncontrol.examples.actions.RenameAction;
import com.unity.versioncontrol.examples.models.Repository;
import retrofit.Callback;
import retrofit.http.*;

import java.util.List;

public interface IApi {

    // Retrieve all repositories from the Unity Version Control server
    @GET("/api/v1/repos")
    List<Repository> getRepositories();

    // Create a new repository with the specified parameters
    @POST("/api/v1/repos")
    Repository createRepository(@Body CreateRepositoryAction params);

    // Update an existing repository's name using its current name as identifier
    @PUT("/api/v1/repos/{repname}")
    Repository renameRepository(@Path("repname") String repositoryName,
                                @Body RenameAction params);

    // Delete a repository by name - uses callback due to Retrofit void response limitations
    @DELETE("/api/v1/repos/{repname}")
    void deleteRepository(@Path("repname") String repositoryName,
                          Callback<Void> callback);
}
```
