public class CancelledDownloadException extends ServerException {
} public class CancelledUploadingException extends InterruptedIOException {
} public class ServerIOException extends ServerException {

    public ServerIOException() {
        super();
    }

    public ServerIOException(String message) {
        super(message);
    }

    public ServerIOException(Throwable e) {
        super(e);
    }
} public class WrongMethodException extends ServerException {
    public WrongMethodException(String message) {
        super(message);
    }
} public class HttpCodeException extends ServerIOException {

    protected final int code;
    protected final ApiError response;

    public HttpCodeException(int code, ApiError response) {
        super();
        this.code = code;
        this.response = response;
    }

    public HttpCodeException(int code) {
        this(code, null);
    }

    public int getCode() {
        return code;
    }

    public ApiError getResponse() {
        return response;
    }

    @Override
    public String toString() {
        return "HttpCodeException{" +
                "code=" + code +
                ", response=" + response +
                '}';
    }
} public class ApiVersion {

    @SerializedName("build")
    String build;

    @SerializedName("api_version")
    String apiVersion;

    public String getBuild() {
        return build;
    }

    public String getApiVersion() {
        return apiVersion;
    }

    @Override
    public String toString() {
        return "ApiVersion{" +
                "build='" + build + '\'' +
                ", apiVersion='" + apiVersion + '\'' +
                '}';
    }
} public class DiskInfo {

    @SerializedName("trash_size")
    long trashSize;

    @SerializedName("total_space")
    long totalSpace;

    @SerializedName("used_space")
    long usedSpace;

    @SerializedName("system_folders")
    Map<String,String> systemFolders;

    public long getTrashSize() {
        return trashSize;
    }

    public long getTotalSpace() {
        return totalSpace;
    }

    public long getUsedSpace() {
        return usedSpace;
    }

    public Map<String, String> getSystemFolders() {
        return systemFolders;
    }

    @Override
    public String toString() {
        return "DiskCapacity{" +
                "trashSize=" + trashSize +
                ", totalSpace=" + totalSpace +
                ", usedSpace=" + usedSpace +
                ", systemFolders=" + systemFolders +
                '}';
    }
} public class Link {

    public enum HttpStatus {
        done, inProgress, error
    }

    HttpStatus httpStatus;

    public final static Link DONE = new Link() {
        {
            httpStatus = HttpStatus.done;
        }
    };

    @SerializedName("href")
    String href;

    @SerializedName("method")
    String method;

    @SerializedName("templated")
    boolean templated;

    public String getHref() {
        return href;
    }

    public String getMethod() {
        return method;
    }

    public boolean isTemplated() {
        return templated;
    }

    public HttpStatus getHttpStatus() {
        return httpStatus;
    }

    public void setHttpStatus(HttpStatus httpStatus) {
        this.httpStatus = httpStatus;
    }

    @Override
    public String toString() {
        return "Link{" +
                "href='" + href + '\'' +
                ", method='" + method + '\'' +
                ", templated=" + templated +
                ", httpStatus=" + httpStatus +
                '}';
    }
} public class Operation {

    private static final String IN_PROGRESS = "in-progress";
    private static final String SUCCESS = "success";

    @SerializedName("status")
    String status;

    public String getStatus() {
        return status;
    }

    public boolean isInProgress() {
        return IN_PROGRESS.equals(status);
    }

    public boolean isSuccess() {
        return SUCCESS.equals(status);
    }

    @Override
    public String toString() {
        return "Operation{" +
                "status='" + status + '\'' +
                '}';
    }
} public class Resource {

    @SerializedName("public_key")
    String publicKey;

    @SerializedName("_embedded")
    ResourceList resourceList;

    @SerializedName("name")
    String name;

    @SerializedName("created")
    String created;

    @SerializedName("public_url")
    String publicUrl;

    @SerializedName("origin_path")
    String originPath;

    @SerializedName("modified")
    String modified;

    @SerializedName("deleted")
    String deleted;

    @SerializedName("path")
    String path;

    @SerializedName("md5")
    String md5;

    @SerializedName("type")
    String type;

    @SerializedName("mime_type")
    String mimeType;

    @SerializedName("media_type")
    String mediaType;

    @SerializedName("preview")
    String preview;

    @SerializedName("size")
    long size;

    @SerializedName("custom_properties")
    Object properties;

    public String getPublicKey() {
        return publicKey;
    }

    public ResourceList getResourceList() {
        return resourceList;
    }

    public String getName() {
        return name;
    }

    public Date getCreated() {
        return created != null ? ISO8601.parse(created) : null;
    }

    public String getPublicUrl() {
        return publicUrl;
    }

    public ResourcePath getOriginPath() {
        return originPath != null ? new ResourcePath(originPath) : null;
    }

    public Date getModified() {
        return modified != null ? ISO8601.parse(modified) : null;
    }

    public Date getDeleted() {
        return deleted != null ? ISO8601.parse(deleted) : null;
    }

    public ResourcePath getPath() {
        return path != null ? new ResourcePath(path) : null;
    }

    public String getMd5() {
        return md5;
    }

    public String getType() {
        return type;
    }

    public boolean isDir() {
        return "dir".equalsIgnoreCase(type);
    }

    public String getMimeType() {
        return mimeType;
    }

    public String getMediaType() {
        return mediaType;
    }

    public String getPreview() {
        return preview;
    }

    public long getSize() {
        return size;
    }

    public Object getProperties() {
        return properties;
    }

    @Override
    public String toString() {
        return "Resource{" +
                "publicKey='" + publicKey + '\'' +
                ", resourceList=" + resourceList +
                ", name='" + name + '\'' +
                ", created='" + getCreated() + '\'' +
                ", publicUrl='" + publicUrl + '\'' +
                ", originPath='" + getOriginPath() + '\'' +
                ", modified='" + getModified() + '\'' +
                ", deleted='" + getDeleted() + '\'' +
                ", path='" + getPath() + '\'' +
                ", md5='" + md5 + '\'' +
                ", type='" + type + '\'' +
                ", mimeType='" + mimeType + '\'' +
                ", mediaType='" + mediaType + '\'' +
                ", preview='" + preview + '\'' +
                ", size=" + size +
                ", properties=" + properties +
                '}';
    }
} public class ResourceList {

    @SerializedName("sort")
    String sort;

    @SerializedName("public_key")
    String publicKey;

    @SerializedName("items")
    List<Resource> items;

    @SerializedName("path")
    String path;

    @SerializedName("limit")
    int limit;

    @SerializedName("offset")
    int offset;

    @SerializedName("total")
    int total;

    public String getSort() {
        return sort;
    }

    public String getPublicKey() {
        return publicKey;
    }

    public List<Resource> getItems() {
        return items;
    }

    public String getPath() {
        return path;
    }

    public int getLimit() {
        return limit;
    }

    public int getOffset() {
        return offset;
    }

    public int getTotal() {
        return total;
    }

    @Override
    public String toString() {
        return "ResourceList{" +
                "sort='" + sort + '\'' +
                ", publicKey='" + publicKey + '\'' +
                ", items=" + items +
                ", path='" + path + '\'' +
                ", limit=" + limit +
                ", offset=" + offset +
                ", total=" + total +
                '}';
    }
} public class Hash {

    private enum HashType {

        MD5("MD5"), SHA256("SHA-256");

        private final String value;

        HashType(String value) {
            this.value = value;
        }

        String getValue() {
            return value;
        }
    }

    private final String md5, sha256;
    private final long size;

    public Hash(String md5, String sha256, long size) {
        this.md5 = md5;
        this.sha256 = sha256;
        this.size = size;
    }

    public static Hash getHash(File file)
            throws IOException {
        InputStream is = new FileInputStream(file);
        try {
            return getHash(is, file.length());
        } finally {
            close(is);
        }
    }

    private static Hash getHash(InputStream is, long size)
            throws IOException {
        MessageDigest md5Digest, sha256Digest;
        try {
            md5Digest = MessageDigest.getInstance(HashType.MD5.getValue());
            sha256Digest = MessageDigest.getInstance(HashType.SHA256.getValue());
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException(ex);
        }
        byte[] buf = new byte[8192];
        int count;
        while ((count = is.read(buf)) > 0) {
            md5Digest.update(buf, 0, count);
            sha256Digest.update(buf, 0, count);
        }
        return new Hash(toString(md5Digest.digest()), toString(sha256Digest.digest()), size);
    }

    private static void close(InputStream is)
            throws IOException {
        if (is != null) {
            is.close();
        }
    }

    public String getMd5() {
        return md5;
    }

    public String getSha256() {
        return sha256;
    }

    public long getSize() {
        return size;
    }

    public static String toString(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        StringBuilder out = new StringBuilder();
        for (byte b : bytes) {
            String n = Integer.toHexString(b & 0x000000FF);
            if (n.length() == 1) {
                out.append('0');
            }
            out.append(n);
        }
        return out.toString();
    }

    @Override
    public String toString() {
        return "Hash{" +
                "md5='" + md5 + '\'' +
                ", sha256='" + sha256 + '\'' +
                ", size=" + size +
                '}';
    }
} public class ResourcePath {

    private final static char SEPARATOR = ':';

    private final String prefix, path;

    public ResourcePath(String str) {
        if (str == null) {
            throw new IllegalArgumentException();
        }
        int index = str.indexOf(SEPARATOR);
        if (index == -1) {
            prefix = null;
            path = str;
        } else {
            prefix = str.substring(0, index);
            path = str.substring(index + 1);
            if (prefix.length() == 0) {
                throw new IllegalArgumentException();
            }
        }
        if (path.length() == 0) {
            throw new IllegalArgumentException();
        }
    }

    public ResourcePath(String prefix, String path) {
        if (prefix == null || path == null || prefix.length() == 0 || path.length() == 0) {
            throw new IllegalArgumentException();
        }
        this.prefix = prefix;
        this.path = path;
    }

    public String getPrefix() {
        return prefix;
    }

    public String getPath() {
        return path;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ResourcePath that = (ResourcePath) o;

        if (path != null ? !path.equals(that.path) : that.path != null) return false;
        if (prefix != null ? !prefix.equals(that.prefix) : that.prefix != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = prefix != null ? prefix.hashCode() : 0;
        result = 31 * result + (path != null ? path.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return (prefix != null ? prefix + SEPARATOR : "") + path;
    }
}
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.yandex.disk.rest.exceptions.CancelledDownloadException;
import com.yandex.disk.rest.exceptions.CancelledUploadingException;
import com.yandex.disk.rest.exceptions.ServerIOException;
import com.yandex.disk.rest.exceptions.WrongMethodException;
import com.yandex.disk.rest.exceptions.http.HttpCodeException;
import com.yandex.disk.rest.json.ApiVersion;
import com.yandex.disk.rest.json.DiskInfo;
import com.yandex.disk.rest.json.Link;
import com.yandex.disk.rest.json.Operation;
import com.yandex.disk.rest.json.Resource;
import com.yandex.disk.rest.json.ResourceList;
import com.yandex.disk.rest.util.Hash;
import com.yandex.disk.rest.util.ResourcePath;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import retrofit.converter.GsonConverter;
import retrofit.mime.TypedOutput;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.isA;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/*
* (C) 2015 Yandex LLC (https://yandex.com/)
*
* The source code of Java SDK for Yandex.Disk REST API
* is available to use under terms of Apache License,
* Version 2.0. See the file LICENSE for the details.
*/

package com.yandex.disk.rest;






@RunWith(JUnit4.class)
public class RestClientTest {

    private static final Logger logger = LoggerFactory.getLogger(RestClientTest.class);

    private RestClient client;

    @Before
    public void setUp() throws Exception {
        System.setProperty(org.slf4j.impl.SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "TRACE");

        logger.info("pwd: " + new File(".").getAbsolutePath());

        String user = null;
        String token = null;
        try {
            FileInputStream propertiesFile = new FileInputStream("local.properties");
            Properties properties = new Properties();
            properties.load(propertiesFile);
            user = properties.getProperty("test.user");
            token = properties.getProperty("test.token");
        } catch (FileNotFoundException ex) {
            logger.info("local.properties", ex);
        }
        if (user == null || token == null) {
            user = "yadiskrestapitest";
            token = "4dc977dfd8024be1bba27a5fefc1c1d0";
        }

        assertThat(user, notNullValue());
        assertThat(token, notNullValue());

        Credentials credentials = new Credentials(user, token);

        client = new RestClient(credentials);
        client.getClient().networkInterceptors().add(new LoggingInterceptor(true));
    }

    @Ignore @Test
    public void testApiVersion() throws Exception {
        ApiVersion apiVersion = client.getApiVersion();
        logger.info("apiVersion: " + apiVersion);
        assertThat(apiVersion.getBuild(), not(isEmptyOrNullString()));
        assertTrue("2.12.22".equalsIgnoreCase(apiVersion.getBuild()));
        assertTrue("v1".equalsIgnoreCase(apiVersion.getApiVersion()));
    }

    @Test
    public void testDiskInfo() throws Exception {
        DiskInfo diskInfo = client.getDiskInfo();
        logger.info("diskInfo: " + diskInfo);
        assertThat(diskInfo.getTotalSpace(), greaterThan(0L));
        assertThat(diskInfo.getTrashSize(), greaterThanOrEqualTo(0L));
        assertThat(diskInfo.getUsedSpace(), greaterThanOrEqualTo(0L));
        assertThat(diskInfo.getSystemFolders(), isA(Map.class));
        assertThat(diskInfo.getSystemFolders(), hasKey("applications"));
        assertThat(diskInfo.getSystemFolders(), hasKey("downloads"));
    }

    @Test
    public void testListResources() throws Exception {
        int limit = 50;
        Resource resource = client.getResources(new ResourcesArgs.Builder()