import freenet.keys.FreenetURI;
import freenet.support.api.Bucket;
+import com.google.common.base.Optional;
+
/**
* The Sone downloader is responsible for download Sones as they are updated.
*
* @return The downloaded Sone, or {@code null} if the Sone could not be
* downloaded
*/
- public Sone fetchSone(Sone sone, FreenetURI soneUri, boolean fetchOnly) {
+ public Optional<Sone> fetchSone(Sone sone, FreenetURI soneUri, boolean fetchOnly) {
logger.log(Level.FINE, String.format("Starting fetch for Sone “%s” from %s…", sone, soneUri));
FreenetURI requestUri = soneUri.setMetaString(new String[] { "sone.xml" });
sone.setStatus(SoneStatus.downloading);
return null;
}
logger.log(Level.FINEST, String.format("Got %d bytes back.", fetchResults.getFetchResult().size()));
- Sone parsedSone = parseSone(sone, fetchResults.getFetchResult(), fetchResults.getFreenetUri());
- if (parsedSone != null) {
+ Optional<Sone> parsedSone = parseSone(sone, fetchResults.getFetchResult(), fetchResults.getFreenetUri());
+ if (parsedSone.isPresent()) {
if (!fetchOnly) {
- parsedSone.setStatus((parsedSone.getTime() == 0) ? SoneStatus.unknown : SoneStatus.idle);
- core.updateSone(parsedSone);
- addSone(parsedSone);
+ parsedSone.get().setStatus((parsedSone.get().getTime() == 0) ? SoneStatus.unknown : SoneStatus.idle);
+ core.updateSone(parsedSone.get());
+ addSone(parsedSone.get());
}
}
return parsedSone;
* The requested URI
* @return The parsed Sone, or {@code null} if the Sone could not be parsed
*/
- public Sone parseSone(Sone originalSone, FetchResult fetchResult, FreenetURI requestUri) {
+ public Optional<Sone> parseSone(Sone originalSone, FetchResult fetchResult, FreenetURI requestUri) {
logger.log(Level.FINEST, String.format("Parsing FetchResult (%d bytes, %s) for %s…", fetchResult.size(), fetchResult.getMimeType(), originalSone));
Bucket soneBucket = fetchResult.asBucket();
InputStream soneInputStream = null;
try {
soneInputStream = soneBucket.getInputStream();
- Sone parsedSone = parseSone(originalSone, soneInputStream);
- if (parsedSone != null) {
- parsedSone.modify().setLatestEdition(requestUri.getEdition()).update();
+ Optional<Sone> parsedSone = parseSone(originalSone, soneInputStream);
+ if (parsedSone.isPresent()) {
+ parsedSone.get().modify().setLatestEdition(requestUri.getEdition()).update();
}
return parsedSone;
} catch (Exception e1) {
* The input stream to parse the Sone from
* @return The parsed Sone
*/
- public Sone parseSone(Sone originalSone, InputStream soneInputStream) {
+ public Optional<Sone> parseSone(Sone originalSone, InputStream soneInputStream) {
return new SoneParser().parseSone(core.getDatabase(), originalSone, soneInputStream);
}
* The input stream to parse the Sone from
* @return The parsed Sone
*/
- public Sone parseSone(Database database, Sone originalSone, InputStream soneInputStream) {
+ public Optional<Sone> parseSone(Database database, Sone originalSone, InputStream soneInputStream) {
/* TODO - impose a size limit? */
Document document;
if (document == null) {
/* TODO - mark Sone as bad. */
logger.log(Level.WARNING, String.format("Could not parse XML for Sone %s!", originalSone.getId()));
- return null;
+ return absent();
}
Optional<SimpleXML> soneXml = parseXml(originalSone, document);
if (!soneXml.isPresent()) {
logger.log(Level.WARNING, String.format("XML for Sone %s can not be parsed!", originalSone.getId()));
- return null;
+ return absent();
}
Optional<Client> parsedClient = parseClient(originalSone, soneXml.get());
if (protocolVersion.isPresent()) {
if (protocolVersion.get() < 0) {
logger.log(Level.WARNING, String.format("Invalid protocol version: %d! Not parsing Sone.", protocolVersion.get()));
- return null;
+ return absent();
}
if (protocolVersion.get() > MAX_PROTOCOL_VERSION) {
logger.log(Level.WARNING, String.format("Unknown protocol version: %d! Not parsing Sone.", protocolVersion.get()));
- return null;
+ return absent();
}
}
if (soneTime == null) {
/* TODO - mark Sone as bad. */
logger.log(Level.WARNING, String.format("Downloaded time for Sone %s was null!", sone));
- return null;
+ return absent();
}
try {
sone.setTime(Long.parseLong(soneTime));
} catch (NumberFormatException nfe1) {
/* TODO - mark Sone as bad. */
logger.log(Level.WARNING, String.format("Downloaded Sone %s with invalid time: %s", sone, soneTime));
- return null;
+ return absent();
}
SimpleXML profileXml = soneXml.get().getNode("profile");
if (profileXml == null) {
/* TODO - mark Sone as bad. */
logger.log(Level.WARNING, String.format("Downloaded Sone %s has no profile!", sone));
- return null;
+ return absent();
}
/* parse profile. */
String fieldValue = fieldXml.getValue("field-value", "");
if (fieldName == null) {
logger.log(Level.WARNING, String.format("Downloaded profile field for Sone %s with missing data! Name: %s, Value: %s", sone, fieldName, fieldValue));
- return null;
+ return absent();
}
try {
profile.addField(fieldName).setValue(fieldValue);
} catch (IllegalArgumentException iae1) {
logger.log(Level.WARNING, String.format("Duplicate field: %s", fieldName), iae1);
- return null;
+ return absent();
}
}
}
if ((postId == null) || (postTime == null) || (postText == null)) {
/* TODO - mark Sone as bad. */
logger.log(Level.WARNING, String.format("Downloaded post for Sone %s with missing data! ID: %s, Time: %s, Text: %s", sone, postId, postTime, postText));
- return null;
+ return absent();
}
try {
PostBuilder postBuilder = sone.newPostBuilder();
} catch (NumberFormatException nfe1) {
/* TODO - mark Sone as bad. */
logger.log(Level.WARNING, String.format("Downloaded post for Sone %s with invalid time: %s", sone, postTime));
- return null;
+ return absent();
}
}
}
if ((replyId == null) || (replyPostId == null) || (replyTime == null) || (replyText == null)) {
/* TODO - mark Sone as bad. */
logger.log(Level.WARNING, String.format("Downloaded reply for Sone %s with missing data! ID: %s, Post: %s, Time: %s, Text: %s", sone, replyId, replyPostId, replyTime, replyText));
- return null;
+ return absent();
}
try {
/* TODO - parse time correctly. */
} catch (NumberFormatException nfe1) {
/* TODO - mark Sone as bad. */
logger.log(Level.WARNING, String.format("Downloaded reply for Sone %s with invalid time: %s", sone, replyTime));
- return null;
+ return absent();
}
}
}
String albumImageId = albumXml.getValue("album-image", null);
if ((id == null) || (title == null) || (description == null)) {
logger.log(Level.WARNING, String.format("Downloaded Sone %s contains invalid album!", sone));
- return null;
+ return absent();
}
Album parent = sone.getRootAlbum();
if (parentId != null) {
parent = albums.get(parentId);
if (parent == null) {
logger.log(Level.WARNING, String.format("Downloaded Sone %s has album with invalid parent!", sone));
- return null;
+ return absent();
}
}
Album album = parent.newAlbumBuilder().withId(id).build().modify().setTitle(title).setDescription(description).update();
String imageHeightString = imageXml.getValue("height", null);
if ((imageId == null) || (imageCreationTimeString == null) || (imageKey == null) || (imageTitle == null) || (imageWidthString == null) || (imageHeightString == null)) {
logger.log(Level.WARNING, String.format("Downloaded Sone %s contains invalid images!", sone));
- return null;
+ return absent();
}
long creationTime = Numbers.safeParseLong(imageCreationTimeString, 0L);
int imageWidth = Numbers.safeParseInteger(imageWidthString, 0);
int imageHeight = Numbers.safeParseInteger(imageHeightString, 0);
if ((imageWidth < 1) || (imageHeight < 1)) {
logger.log(Level.WARNING, String.format("Downloaded Sone %s contains image %s with invalid dimensions (%s, %s)!", sone, imageId, imageWidthString, imageHeightString));
- return null;
+ return absent();
}
Image image = album.newImageBuilder().withId(imageId).at(imageKey).created(creationTime).sized(imageWidth, imageHeight).build(Optional.<ImageCreated>absent());
image = image.modify().setTitle(imageTitle).setDescription(imageDescription).update();
sone.setLikePostIds(likedPostIds);
sone.setLikeReplyIds(likedReplyIds);
- return sone;
+ return of(sone);
}
private Optional<Integer> parseProtocolVersion(SimpleXML soneXml) {
import net.pterodactylus.sone.data.Sone;
import net.pterodactylus.util.service.AbstractService;
+
import freenet.keys.FreenetURI;
+import com.google.common.base.Optional;
+
/**
* The Sone rescuer downloads older editions of a Sone and updates the currently
* stored Sone with it.
core.lockSone(sone);
FreenetURI soneUri = TO_FREENET_URI.apply(sone).setKeyType("SSK").setDocName("Sone-" + currentEdition).setMetaString(new String[] { "sone.xml" });
System.out.println("URI: " + soneUri);
- Sone fetchedSone = soneDownloader.fetchSone(sone, soneUri, true);
+ Optional<Sone> fetchedSone = soneDownloader.fetchSone(sone, soneUri, true);
System.out.println("Sone: " + fetchedSone);
- lastFetchSuccessful = (fetchedSone != null);
+ lastFetchSuccessful = fetchedSone.isPresent();
if (lastFetchSuccessful) {
- core.updateSone(fetchedSone, true);
+ core.updateSone(fetchedSone.get(), true);
}
fetching = false;
}
import static java.lang.String.format;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
@Test
public void verifyThatAnInvalidXmlDocumentIsNotParsed() throws UnsupportedEncodingException {
- assertThat(soneParser.parseSone(database, originalSone, getInputStream("<xml>This is not valid XML.</invalid>")), nullValue());
+ Optional<Sone> sone = soneParser.parseSone(database, originalSone, getInputStream("<xml>This is not valid XML.</invalid>"));
+ assertThat(sone, notNullValue());
+ assertThat(sone.isPresent(), is(false));
}
@Test
public void verifyThatANegativeProtocolVersionCausesAnError() {
- assertThat(soneParser.parseSone(database, originalSone, soneXmlBuilder.setProtocolVersion("-1").get()), nullValue());
+ Optional<Sone> sone = soneParser.parseSone(database, originalSone, soneXmlBuilder.setProtocolVersion("-1").get());
+ assertThat(sone, notNullValue());
+ assertThat(sone.isPresent(), is(false));
}
@Test
public void verifyThatATooLargeProtocolVersionCausesAnError() {
- assertThat(soneParser.parseSone(database, originalSone, soneXmlBuilder.setProtocolVersion("1").get()), nullValue());
+ Optional<Sone> sone = soneParser.parseSone(database, originalSone, soneXmlBuilder.setProtocolVersion("1").get());
+ assertThat(sone, notNullValue());
+ assertThat(sone.isPresent(), is(false));
}
@Test
public void verifyThatAMissingClientCausesTheOriginalClientToBeUsed() {
- Sone sone = soneParser.parseSone(database, originalSone, soneXmlBuilder.removeClientInformation().get());
+ Optional<Sone> sone = soneParser.parseSone(database, originalSone, soneXmlBuilder.removeClientInformation().get());
assertThat(sone, notNullValue());
- assertThat(sone.getClient(), notNullValue());
- assertThat(sone.getClient(), is(originalSone.getClient()));
+ assertThat(sone.isPresent(), is(true));
+ assertThat(sone.get().getClient(), notNullValue());
+ assertThat(sone.get().getClient(), is(originalSone.getClient()));
}
@Test
public void verifyThatTheCreatedSoneMeetsAllExpectations() {
- Sone sone = soneParser.parseSone(database, originalSone, soneXmlBuilder.get());
+ Optional<Sone> sone = soneParser.parseSone(database, originalSone, soneXmlBuilder.get());
assertThat(sone, notNullValue());
- assertThat(sone.getTime(), is(1000L));
- assertThat(sone.getClient(), notNullValue());
- assertThat(sone.getClient().getName(), is("Test-Client"));
- assertThat(sone.getClient().getVersion(), is("1.0"));
- assertThat(sone.getProfile(), notNullValue());
- assertThat(sone.getProfile().getFirstName(), is("First"));
- assertThat(sone.getProfile().getMiddleName(), is("M."));
- assertThat(sone.getProfile().getLastName(), is("Last"));
- assertThat(sone.getProfile().getBirthYear(), is(2000));
- assertThat(sone.getProfile().getBirthMonth(), is(9));
- assertThat(sone.getProfile().getBirthDay(), is(13));
- assertThat(sone.getProfile().getAvatar(), is("avatar-id"));
+ assertThat(sone.isPresent(), is(true));
+ assertThat(sone.get().getTime(), is(1000L));
+ assertThat(sone.get().getClient(), notNullValue());
+ assertThat(sone.get().getClient().getName(), is("Test-Client"));
+ assertThat(sone.get().getClient().getVersion(), is("1.0"));
+ assertThat(sone.get().getProfile(), notNullValue());
+ assertThat(sone.get().getProfile().getFirstName(), is("First"));
+ assertThat(sone.get().getProfile().getMiddleName(), is("M."));
+ assertThat(sone.get().getProfile().getLastName(), is("Last"));
+ assertThat(sone.get().getProfile().getBirthYear(), is(2000));
+ assertThat(sone.get().getProfile().getBirthMonth(), is(9));
+ assertThat(sone.get().getProfile().getBirthDay(), is(13));
+ assertThat(sone.get().getProfile().getAvatar(), is("avatar-id"));
}
public InputStream getInputStream(String content) throws UnsupportedEncodingException {