package org.activityinfo.server.endpoint.odk;
import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import org.activityinfo.model.auth.AuthenticatedUser;
import org.activityinfo.model.form.FormClass;
import org.activityinfo.model.legacy.CuidAdapter;
import org.activityinfo.server.command.ResourceLocatorSyncImpl;
import org.activityinfo.io.xform.manifest.MediaFile;
import org.activityinfo.io.xform.form.XForm;
import org.activityinfo.server.endpoint.odk.build.XFormBuilder;
import org.activityinfo.io.xform.manifest.XFormManifest;
import org.activityinfo.service.store.ResourceNotFound;
import javax.inject.Provider;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import java.io.IOException;
import java.util.logging.Logger;
@Path("/forms")
public class FormResource {
private static final Logger LOGGER = Logger.getLogger(FormResource.class.getName());
/**
* This is the filename expected by ODK
*/
private static final String ITEMSETS_CSV = "itemsets.csv";
private ResourceLocatorSyncImpl locator;
private OdkFormFieldBuilderFactory factory;
private Provider<AuthenticatedUser> authProvider;
private AuthenticationTokenService authenticationTokenService;
private ItemSetBuilder itemSetBuilder;
@Inject
public FormResource(ResourceLocatorSyncImpl locator, OdkAuthProvider authProvider, OdkFormFieldBuilderFactory factory,
AuthenticationTokenService authenticationTokenService, ItemSetBuilder itemSetBuilder) {
this.locator = locator;
this.authProvider = authProvider;
this.factory = factory;
this.authenticationTokenService = authenticationTokenService;
this.itemSetBuilder = itemSetBuilder;
}
@VisibleForTesting
FormResource(ResourceLocatorSyncImpl locator, Provider<AuthenticatedUser> authProvider, OdkFormFieldBuilderFactory factory,
AuthenticationTokenService authenticationTokenService) {
this.locator = locator;
this.authProvider = authProvider;
this.factory = factory;
this.authenticationTokenService = authenticationTokenService;
}
private FormClass fetchFormClass(int id) {
FormClass formClass;
try {
formClass = locator.getFormClass(CuidAdapter.activityFormClass(id));
} catch (ResourceNotFound resourceNotFound) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return formClass;
}
@GET
@Path("{id}/xform")
@Produces(MediaType.TEXT_XML)
public Response form(@PathParam("id") int id) {
AuthenticatedUser user = authProvider.get();
LOGGER.finer("ODK activity form " + id + " requested by " +
user.getEmail() + " (" + user.getId() + ")");
FormClass formClass = fetchFormClass(id);
String authenticationToken = authenticationTokenService
.createAuthenticationToken(user.getId(), formClass.getId());
XForm xForm = new XFormBuilder(factory)
.setUserId(authenticationToken)
.build(formClass);
return Response.ok(xForm).build();
}
@GET
@Path("{id}/manifest")
@Produces(MediaType.TEXT_XML)
public Response manifest(@Context UriInfo uri, @PathParam("id") int id) {
AuthenticatedUser user = authProvider.get();
LOGGER.finer("ODK manifest for " + id + " requested by " +
user.getEmail() + " (" + user.getId() + ")");
MediaFile itemSet = new MediaFile();
itemSet.setFilename("itemsets.csv");
itemSet.setHash("md5:00000000000000000000000000000000");
itemSet.setDownloadUrl(uri.getBaseUriBuilder()
.path(FormResource.class)
.path(Integer.toString(id))
.path("itemsets.csv")
.build());
XFormManifest manifest = new XFormManifest();
return OpenRosaResponse.build(manifest);
}
@GET
@Path("{id}/itemsets.csv")
@Produces(MediaType.TEXT_PLAIN)
public Response itemSet(@PathParam("id") int id) throws IOException {
authProvider.get();
return Response.ok(itemSetBuilder.build(CuidAdapter.activityFormClass(id)))
.type("text/plain; charset=utf-8")
.build();
}
}