com.redhat.victims.VictimsService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of victims-lib Show documentation
Show all versions of victims-lib Show documentation
A java library providing fingerprinting and service interaction for the Victims Project.
package com.redhat.victims;
/*
* #%L
* This file is part of victims-lib.
* %%
* Copyright (C) 2013 The Victims Project
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
* #L%
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
/**
*
* This implements a basic wrapper for the victims web service. Provides basic
* interactions with the REST interface.
*
* @author gcmurphy
* @author abn
*
*/
public class VictimsService {
protected String baseURI;
protected String serviceEntry;
/**
* Create a VictimsService instance with the default uri and entry point.
*
* @throws MalformedURLException
*/
public VictimsService() throws MalformedURLException {
this.baseURI = VictimsConfig.uri();
this.serviceEntry = VictimsConfig.entry();
}
/**
*
* Get all new records after a given date.
*
* @param since
* The date from when updates are required for.
* @return
* @throws IOException
*/
public RecordStream updates(Date since) throws IOException {
return fetch(since, "update");
}
/**
*
* Get all records removed after a given date.
*
* @param since
* The date from when removed records are required for.
* @return
* @throws IOException
*/
public RecordStream removed(Date since) throws IOException {
return fetch(since, "remove");
}
/**
*
* Work horse method that provides a {@link RecordStream} wraped from a
* response received from the server.
*
* @param since
* The date from when removed records are required for.
* @param type
* The service type. To be used as ${base-uri}/${service}/%{type}
* @return
* @throws IOException
*/
protected RecordStream fetch(Date since, String type) throws IOException {
SimpleDateFormat fmt = new SimpleDateFormat(VictimsRecord.DATE_FORMAT);
String spec = FileUtils.getFile(serviceEntry, type, fmt.format(since))
.toString();
spec = FilenameUtils.normalize(spec, true);
URL merged = new URL(new URL(baseURI), spec);
return new RecordStream(merged.toString());
}
/**
* This provides a simple ObjectStream like implementation for wrapping
* streamed responses from the server.
*
* @author abn
*
*/
public static class RecordStream {
protected JsonReader json;
protected InputStream in;
protected Gson gson;
/**
* Create a record stream from a given URI.
*
* @param uri
* @throws IOException
*/
public RecordStream(String uri) throws IOException {
this(new URL(uri).openStream());
}
/**
* Create a record stream from a given input stream. we expect the
* stream to contain a json response of the for [{"fields" : {
* {@link VictimsRecord} String}}]
*
* @param in
* @throws IOException
*/
public RecordStream(InputStream in) throws IOException {
this.in = in;
this.gson = new GsonBuilder().setDateFormat(
VictimsRecord.DATE_FORMAT).create();
this.json = new JsonReader(new InputStreamReader(in, "UTF-8"));
this.json.beginArray();
}
/**
*
* @return The next available {@link VictimsRecord}. If none available
* returns null.
* @throws IOException
*/
public VictimsRecord getNext() throws IOException {
if (hasNext()) {
json.beginObject();
json.nextName(); // discard fields
VictimsRecord v = gson.fromJson(json, VictimsRecord.class);
json.endObject();
return v;
}
return null;
}
/**
* Checks if the internal {@link JsonReader} has any more json strings
* available. If not we end the json array and close the response
* stream.
*
* @return true
if more records can be read, else returns
* false
.
* @throws IOException
*/
public boolean hasNext() throws IOException {
if (!json.hasNext()) {
json.endArray();
IOUtils.closeQuietly(in);
return false;
}
return true;
}
}
}