Skip to content

Commit

Permalink
Added API for accessing directories and files.
Browse files Browse the repository at this point in the history
  • Loading branch information
ericbottard committed Mar 21, 2012
1 parent e9880c8 commit e6dc8a2
Show file tree
Hide file tree
Showing 8 changed files with 370 additions and 1 deletion.
@@ -0,0 +1,45 @@
package org.springframework.social.bitbucket.api;

import java.util.List;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;

/**
* Metadata about the contents of a repository directory. Contains files,
* directories and metadata about the selected directory.
*
* @author ericbottard
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class BitBucketDirectory {

@JsonProperty
private List<String> directories;

@JsonProperty
private List<BitBucketFileMetadata> files;

@JsonProperty
private String path;

@JsonProperty
private String node;

public List<String> getDirectories() {
return directories;
}

public List<BitBucketFileMetadata> getFiles() {
return files;
}

public String getPath() {
return path;
}

public String getNode() {
return node;
}

}
@@ -0,0 +1,40 @@
package org.springframework.social.bitbucket.api;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;

/**
* Content as well as metadata about a repository file.
*
* @author ebottard
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class BitBucketFile {

@JsonProperty
private String node;

@JsonProperty
private String path;

@JsonProperty
private String data;

public String getNode() {
return node;
}

/**
* Returns the file path, relative to the root of the repository.
*/
public String getPath() {
return path;
}

/**
* Returns the actual content of the file, as a String.
*/
public String getData() {
return data;
}
}
@@ -0,0 +1,46 @@
package org.springframework.social.bitbucket.api;

import java.util.Date;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.springframework.social.bitbucket.api.impl.UTCDateDeserializer;

/**
* Metadata about a file in a repository.
*
* @author ericbottard
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class BitBucketFileMetadata {

@JsonProperty
private String path;

@JsonProperty
private String revision;

@JsonProperty("utctimestamp")
@JsonDeserialize(using = UTCDateDeserializer.class)
private Date timestamp;

@JsonProperty
private int size;

public String getPath() {
return path;
}

public String getRevision() {
return revision;
}

public Date getTimestamp() {
return timestamp;
}

public int getSize() {
return size;
}
}
Expand Up @@ -64,4 +64,18 @@ public interface RepoOperations {
*/
public BitBucketChangesets getChangesets(String user, String repoSlug,
String start, int limit);

/**
* Returns information about a known directory, including children
* directories and files.
*/
public BitBucketDirectory getDirectory(String user, String repoSlug,
String revision, String path);

/**
* Returns information and actual contents (as a String) about a known file
* path.
*/
public BitBucketFile getFile(String string, String string2, String string3,
String string4);
}
Expand Up @@ -23,9 +23,11 @@

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
import org.springframework.social.bitbucket.api.BitBucketChangeset;
import org.springframework.social.bitbucket.api.BitBucketChangesets;
import org.springframework.social.bitbucket.api.BitBucketDirectory;
import org.springframework.social.bitbucket.api.BitBucketFile;
import org.springframework.social.bitbucket.api.BitBucketRepository;
import org.springframework.social.bitbucket.api.BitBucketChangeset;
import org.springframework.social.bitbucket.api.BitBucketUser;
import org.springframework.social.bitbucket.api.RepoOperations;
import org.springframework.web.client.RestTemplate;
Expand Down Expand Up @@ -92,6 +94,24 @@ public BitBucketChangesets getChangesets(String user, String repoSlug,
repoSlug, start, limit);
}

@Override
public BitBucketDirectory getDirectory(String user, String repoSlug,
String revision, String path) {
return restTemplate.getForObject(
buildUrl("/repositories/{user}/{slug}/src/{rev}/{path}/")
.toString(), BitBucketDirectory.class, user, repoSlug,
revision, path);
}

@Override
public BitBucketFile getFile(String user, String repoSlug, String revision,
String path) {
return restTemplate.getForObject(
buildUrl("/repositories/{user}/{slug}/src/{rev}/{path}")
.toString(), BitBucketFile.class, user, repoSlug,
revision, path);
}

/**
* Exists for the sole purpose of having a strongly typed Map for Jackson.
*/
Expand Down
Expand Up @@ -15,6 +15,7 @@
*/
package org.springframework.social.bitbucket.api.impl;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.springframework.http.HttpMethod.*;
import static org.springframework.test.web.client.RequestMatchers.*;
Expand All @@ -30,6 +31,9 @@
import org.springframework.social.bitbucket.api.BitBucketChangeset;
import org.springframework.social.bitbucket.api.BitBucketChangeset.FileModificationType;
import org.springframework.social.bitbucket.api.BitBucketChangesets;
import org.springframework.social.bitbucket.api.BitBucketDirectory;
import org.springframework.social.bitbucket.api.BitBucketFile;
import org.springframework.social.bitbucket.api.BitBucketFileMetadata;
import org.springframework.social.bitbucket.api.BitBucketRepository;
import org.springframework.social.bitbucket.api.BitBucketSCM;
import org.springframework.social.bitbucket.api.BitBucketUser;
Expand Down Expand Up @@ -206,4 +210,56 @@ public void testRepoChangesets() {

}

@Test
public void testRepoDirectoryListing() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);

mockServer
.expect(requestTo("https://api.bitbucket.org/1.0/repositories/jespern/django-piston/src/tip/piston/"))
.andExpect(method(GET))
.andRespond(
withResponse(jsonResource("repo-directories"),
responseHeaders));

BitBucketDirectory directory = bitBucket.repoOperations().getDirectory(
"jespern", "django-piston", "tip", "piston");

assertThat(directory.getNode(), equalTo("4fe8af1db59d"));
assertThat(directory.getPath(), equalTo("piston/"));

assertThat(directory.getDirectories().size(), equalTo(2));
assertThat(directory.getDirectories(),
hasItems("fixtures", "templates"));

BitBucketFileMetadata metadata = directory.getFiles().get(0);
assertThat(metadata.getPath(), equalTo("piston/utils.py"));
assertThat(metadata.getRevision(), equalTo("112311f7d7ce"));
assertThat(metadata.getSize(), equalTo(12275));

}

@Test
public void testRepoFile() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);

mockServer
.expect(requestTo("https://api.bitbucket.org/1.0/repositories/jespern/django-piston/src/tip/piston/utils.py"))
.andExpect(method(GET))
.andRespond(
withResponse(jsonResource("repo-file"), responseHeaders));

BitBucketFile file = bitBucket.repoOperations().getFile("jespern",
"django-piston", "tip", "piston/utils.py");

assertThat(file.getNode(), equalTo("4fe8af1db59d"));
assertThat(file.getPath(), equalTo("piston/utils.py"));
assertThat(file.getData().length(), equalTo(12275));
// The following makes sure that newline escapes are correcly handled
assertThat(
file.getData(),
startsWith("import time\nfrom django.http import HttpResponseNotAllowed,"));

}
}

0 comments on commit e6dc8a2

Please sign in to comment.