summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pom.xml111
-rw-r--r--src/main/java/org/qcg/qcgdata/gdrop/DBEnabledServlet.java37
-rw-r--r--src/main/java/org/qcg/qcgdata/gdrop/DeleteServlet.java47
-rw-r--r--src/main/java/org/qcg/qcgdata/gdrop/ErrorHandlingServlet.java29
-rw-r--r--src/main/java/org/qcg/qcgdata/gdrop/GetEntriesBean.java90
-rw-r--r--src/main/java/org/qcg/qcgdata/gdrop/GetFileServlet.java157
-rw-r--r--src/main/java/org/qcg/qcgdata/gdrop/RegisterServlet.java86
-rw-r--r--src/main/java/org/qcg/qcgdata/gdrop/SetUpDBServlet.java44
-rw-r--r--src/main/java/org/qcg/qcgdata/gdrop/exception/GDropException.java19
-rw-r--r--src/main/java/org/qcg/qcgdata/gdrop/util/GDropUtil.java91
-rw-r--r--src/main/resources/log4j.properties16
-rw-r--r--src/main/webapp/META-INF/context.xml10
-rw-r--r--src/main/webapp/WEB-INF/web.xml68
-rw-r--r--src/main/webapp/entries.jsp34
14 files changed, 839 insertions, 0 deletions
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..e0f0acb
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,111 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.qcg.qcgdata</groupId>
+ <artifactId>gdrop-web</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>war</packaging>
+
+ <name>gdrop-web</name>
+ <url>http://maven.apache.org</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <tomcat.manager.url>http://localhost:8080/manager/text</tomcat.manager.url>
+ <tomcat.server>localtomcat</tomcat.server>
+ </properties>
+
+ <dependencies>
+ <!--<dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-web-api</artifactId>
+ <version>6.0</version>
+ <scope>provided</scope>
+ </dependency>-->
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>jstl</groupId>
+ <artifactId>jstl</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.irods.jargon</groupId>
+ <artifactId>jargon-core</artifactId>
+ <version>3.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.irods.jargon</groupId>
+ <artifactId>jargon-ticket</artifactId>
+ <version>3.3.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>3.1</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>gdrop-web</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.tomcat.maven</groupId>
+ <artifactId>tomcat7-maven-plugin</artifactId>
+ <version>2.0</version>
+ <configuration>
+ <url>${tomcat.manager.url}</url>
+ <server>${tomcat.server}</server>
+ <update>true</update>
+ </configuration>
+ <executions>
+ <execution>
+ <id>e1</id>
+ <phase>package</phase>
+ <goals>
+ <goal>deploy</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <repositories>
+ <repository>
+ <id>jargon-repo</id>
+ <url>http://ci-dev.renci.org/nexus/content/repositories/releases/</url>
+ <releases/>
+ </repository>
+ </repositories>
+
+ <profiles>
+ <profile>
+ <id>elder10</id>
+ <properties>
+ <tomcat.manager.url>http://elder10.man.poznan.pl:8080/manager/text</tomcat.manager.url>
+ <tomcat.server>eldertomcat</tomcat.server>
+ </properties>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/src/main/java/org/qcg/qcgdata/gdrop/DBEnabledServlet.java b/src/main/java/org/qcg/qcgdata/gdrop/DBEnabledServlet.java
new file mode 100644
index 0000000..d190b21
--- /dev/null
+++ b/src/main/java/org/qcg/qcgdata/gdrop/DBEnabledServlet.java
@@ -0,0 +1,37 @@
+package org.qcg.qcgdata.gdrop;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.InitialContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.sql.DataSource;
+
+public class DBEnabledServlet extends HttpServlet{
+
+ private static final String DB_RESOURCE_NAME_CTX_PARAM = "db.resource.name";
+
+ private static final String DEFAULT_RESOURCE_NAME = "java:comp/env/jdbc/gdropdb";
+
+ private static Logger log = LoggerFactory.getLogger(DBEnabledServlet.class);
+
+ protected DataSource dataSource;
+
+ @Override
+ public void init() throws ServletException {
+ super.init();
+ String resourceName = getServletContext().getInitParameter(DB_RESOURCE_NAME_CTX_PARAM);
+
+ //database connection
+ try {
+ InitialContext ctx = new InitialContext();
+ resourceName = resourceName==null?DEFAULT_RESOURCE_NAME:resourceName;
+ dataSource = (DataSource) ctx.lookup(resourceName);
+ } catch (Exception e) {
+ throw new ServletException("unable to establish database connection");
+ }
+
+ }
+
+}
diff --git a/src/main/java/org/qcg/qcgdata/gdrop/DeleteServlet.java b/src/main/java/org/qcg/qcgdata/gdrop/DeleteServlet.java
new file mode 100644
index 0000000..f8fce6e
--- /dev/null
+++ b/src/main/java/org/qcg/qcgdata/gdrop/DeleteServlet.java
@@ -0,0 +1,47 @@
+package org.qcg.qcgdata.gdrop;
+
+import org.qcg.qcgdata.gdrop.exception.GDropException;
+import org.qcg.qcgdata.gdrop.util.GDropUtil;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+public class DeleteServlet extends DBEnabledServlet{
+
+ private static final String QS_TICKET_STRING = "ticket";
+
+ private static final String DELETE_TEMPLATE = "DELETE from gdrop WHERE ticket=?";
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ // by ticket
+ String queryString = request.getQueryString();
+ if(queryString == null || GDropUtil.getRequestParamSingleOptionalValue(request,QS_TICKET_STRING)==null){
+ throw new GDropException("ticket string not provided");
+ }
+
+ String ticket = GDropUtil.getRequestParamSingleValue(request,QS_TICKET_STRING);
+
+ Connection c = null;
+ PreparedStatement s = null;
+ try{
+ c = dataSource.getConnection();
+ s = c.prepareStatement(DELETE_TEMPLATE);
+ s.setString(1,ticket);
+ s.executeUpdate();
+ } catch (SQLException e){
+ throw new GDropException("error occurred while deleting entry",e);
+ } finally {
+ GDropUtil.close(s);
+ GDropUtil.close(c);
+ }
+
+ response.getWriter().println("<p>entry was successfully deleted</p>");
+ response.getWriter().println("<a href='entries.jsp'>back</a>");
+ }
+}
diff --git a/src/main/java/org/qcg/qcgdata/gdrop/ErrorHandlingServlet.java b/src/main/java/org/qcg/qcgdata/gdrop/ErrorHandlingServlet.java
new file mode 100644
index 0000000..274c500
--- /dev/null
+++ b/src/main/java/org/qcg/qcgdata/gdrop/ErrorHandlingServlet.java
@@ -0,0 +1,29 @@
+package org.qcg.qcgdata.gdrop;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class ErrorHandlingServlet extends HttpServlet{
+
+ private static Logger log = LoggerFactory.getLogger(ErrorHandlingServlet.class);
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ Throwable t = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
+ if(t!=null){
+ log.error("error occurred",t);
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ response.getWriter().println(t.getMessage()==null?"error occurred":t.getMessage());
+ }else{
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/org/qcg/qcgdata/gdrop/GetEntriesBean.java b/src/main/java/org/qcg/qcgdata/gdrop/GetEntriesBean.java
new file mode 100644
index 0000000..217fe9b
--- /dev/null
+++ b/src/main/java/org/qcg/qcgdata/gdrop/GetEntriesBean.java
@@ -0,0 +1,90 @@
+package org.qcg.qcgdata.gdrop;
+
+import org.qcg.qcgdata.gdrop.util.GDropUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+public class GetEntriesBean implements Serializable{
+
+ private static Logger log = LoggerFactory.getLogger(GetEntriesBean.class);
+
+ private static final String DEFAULT_RESOURCE_NAME = "java:comp/env/jdbc/gdropdb";
+
+ private DataSource dataSource;
+
+ private List<GDropEntry> entries;
+
+ public GetEntriesBean() {
+ Connection c = null;
+ Statement s = null;
+ ResultSet rs = null;
+ try {
+ InitialContext ctx = new InitialContext();
+ dataSource = (DataSource) ctx.lookup(DEFAULT_RESOURCE_NAME);
+ entries = new ArrayList<GDropEntry>();
+ c = dataSource.getConnection();
+ s = c.createStatement();
+ rs = s.executeQuery("SELECT * FROM gdrop;");
+ while(rs.next()){
+ String id = rs.getString("id");
+ String uri = rs.getString("uri");
+ String ticket = rs.getString("ticket");
+ entries.add(new GDropEntry(id,uri,ticket));
+ }
+ } catch (NamingException e) {
+ log.error("could not obtain the data source",e);
+ } catch (SQLException e) {
+ log.error("could not obtain data",e);
+ } finally {
+ GDropUtil.close(rs);
+ GDropUtil.close(s);
+ GDropUtil.close(c);
+ }
+ }
+
+
+
+ public List<GDropEntry> getEntries(){
+ return entries;
+ }
+
+ public class GDropEntry{
+
+ private String id;
+
+ private String uri;
+
+ private String ticket;
+
+ public GDropEntry(String id, String uri, String ticket){
+ this.id = id;
+ this.uri = uri;
+ this.ticket = ticket;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ public String getTicket() {
+ return ticket;
+ }
+
+ }
+
+}
diff --git a/src/main/java/org/qcg/qcgdata/gdrop/GetFileServlet.java b/src/main/java/org/qcg/qcgdata/gdrop/GetFileServlet.java
new file mode 100644
index 0000000..508a8c1
--- /dev/null
+++ b/src/main/java/org/qcg/qcgdata/gdrop/GetFileServlet.java
@@ -0,0 +1,157 @@
+package org.qcg.qcgdata.gdrop;
+
+import org.apache.commons.io.IOUtils;
+import org.irods.jargon.core.connection.IRODSAccount;
+import org.irods.jargon.core.exception.DataNotFoundException;
+import org.irods.jargon.core.exception.JargonException;
+import org.irods.jargon.core.pub.IRODSAccessObjectFactory;
+import org.irods.jargon.core.pub.IRODSFileSystem;
+import org.irods.jargon.core.pub.io.IRODSFile;
+import org.irods.jargon.core.pub.io.IRODSFileFactory;
+import org.irods.jargon.core.utils.MiscIRODSUtils;
+import org.irods.jargon.ticket.TicketClientOperations;
+import org.irods.jargon.ticket.TicketServiceFactory;
+import org.irods.jargon.ticket.TicketServiceFactoryImpl;
+import org.irods.jargon.ticket.io.FileStreamAndInfo;
+import org.qcg.qcgdata.gdrop.exception.GDropException;
+import org.qcg.qcgdata.gdrop.util.GDropUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class GetFileServlet extends DBEnabledServlet{
+
+ private static Logger log = LoggerFactory.getLogger(GetFileServlet.class);
+
+ private static final String TMPDIR_SYS_PROP = "java.io.tmpdir";
+
+ private static final String URI_COLUMN = "uri";
+
+ private static final String GET_TEMPLATE = "SELECT uri FROM gdrop WHERE ticket=?";
+
+ private static final String DELETE_TEMPLATE = "DELETE FROM gdrop WHERE ticket=?";
+
+ private File tempDir;
+
+ @Override
+ public void init() throws ServletException {
+ super.init();
+ String tempDirPath = System.getProperty(TMPDIR_SYS_PROP);
+ tempDir = new File(tempDirPath);
+ if (!tempDir.exists() || !tempDir.isDirectory() || !tempDir.canWrite()) {
+ throw new ServletException("temp directory is not writable");
+ }
+ }
+
+
+ /**
+ * Target iRODS server should have a default storage resource set.
+ *
+ * from IRODSAccount:
+ * defaultStorageResource
+ * <code>String</code> with optional value for the default
+ * storage resource. Note that iRODS may have defaults set by
+ * policy. In cases where no default policy exists, and none is
+ * specified here, an error can occur.
+ */
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ String pathInfo = request.getPathInfo();
+ if (pathInfo == null) {
+ response.getWriter().println("Usage: .../get/<ticket-string>");
+ response.getWriter().close();
+ }else{
+ String ticket = request.getPathInfo().substring(1);
+ GDropUtil.checkTicket(ticket);
+ String uri = getUriFromDb(ticket);
+ if(uri==null){
+ throw new GDropException("entry not found");
+ }
+ URI u;
+ try {
+ u = new URI(uri);
+ } catch (URISyntaxException e) {
+ throw new GDropException("malformed uri retrieved from database",e);
+ }
+
+ String filePath = u.getPath();
+
+ try {
+ IRODSAccount anonymousAccount = IRODSAccount.instanceForAnonymous(u.getHost(),u.getPort(),null,MiscIRODSUtils.getZoneInPath(filePath),"");
+ IRODSFileSystem fileSystem = IRODSFileSystem.instance();
+ IRODSAccessObjectFactory accessObjectFactory = fileSystem.getIRODSAccessObjectFactory();
+ TicketServiceFactory tsf = new TicketServiceFactoryImpl(accessObjectFactory);
+ TicketClientOperations ticketClientOperations = tsf.instanceTicketClientOperations(anonymousAccount);
+ IRODSFileFactory fileFactory = fileSystem.getIRODSFileFactory(anonymousAccount);
+ IRODSFile file = fileFactory.instanceIRODSFile(filePath);
+ FileStreamAndInfo fsi = ticketClientOperations.redeemTicketGetDataObjectAndStreamBack(ticket, file, tempDir);
+ response.setContentType("application/octet-stream");
+ if(fsi.getLength()<=Integer.MAX_VALUE){
+ response.setContentLength((int) fsi.getLength());
+ }
+
+ response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
+ IOUtils.copyLarge(fsi.getInputStream(), response.getOutputStream());
+ response.getOutputStream().flush();
+ response.getOutputStream().close();
+ } catch (DataNotFoundException e){
+ deleteEntry(ticket);
+ throw new GDropException("file not found");
+ } catch (JargonException e) {
+ throw new GDropException("error occurred while connecting to iRODS server",e);
+ }
+
+ }
+ }
+
+ private void deleteEntry(String ticket) {
+ Connection c = null;
+ PreparedStatement s = null;
+ try {
+ c = dataSource.getConnection();
+ s = c.prepareStatement(DELETE_TEMPLATE);
+ s.setString(1, ticket);
+ s.executeUpdate();
+ } catch (SQLException e) {
+ log.error("error occurred while deleting entry", e);
+ } finally {
+ GDropUtil.close(s);
+ GDropUtil.close(c);
+ }
+ }
+
+ private String getUriFromDb(String ticketString) throws GDropException {
+ Connection c = null;
+ PreparedStatement s = null;
+ ResultSet rs = null;
+ String uri = null;
+ try {
+ c = dataSource.getConnection();
+ s = c.prepareStatement(GET_TEMPLATE);
+ s.setString(1, ticketString);
+ rs = s.executeQuery();
+ while (rs.next()) {
+ uri = rs.getString(URI_COLUMN);
+ }
+ } catch (SQLException e) {
+ throw new GDropException("error occurred while retrieving file path", e);
+ } finally {
+ GDropUtil.close(rs);
+ GDropUtil.close(s);
+ GDropUtil.close(c);
+ }
+ return uri;
+ }
+
+}
diff --git a/src/main/java/org/qcg/qcgdata/gdrop/RegisterServlet.java b/src/main/java/org/qcg/qcgdata/gdrop/RegisterServlet.java
new file mode 100644
index 0000000..60ed950
--- /dev/null
+++ b/src/main/java/org/qcg/qcgdata/gdrop/RegisterServlet.java
@@ -0,0 +1,86 @@
+package org.qcg.qcgdata.gdrop;
+
+import org.apache.commons.httpclient.util.URIUtil;
+import org.qcg.qcgdata.gdrop.exception.GDropException;
+import org.qcg.qcgdata.gdrop.util.GDropUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+public class RegisterServlet extends DBEnabledServlet{
+
+ private static Logger log = LoggerFactory.getLogger(RegisterServlet.class);
+
+ private static final String QS_TICKET_STRING = "ticket";
+
+ private static final String QS_URI = "uri";
+
+ private static final String INSERT_TEMPLATE = "INSERT INTO gdrop(ticket,uri) VALUES (?,?)";
+
+ private static final String IRODS_SCHEME = "irods";
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ String ticket;
+ String uri;
+ ticket = GDropUtil.getRequestParamSingleValue(request, QS_TICKET_STRING);
+ GDropUtil.checkTicket(ticket);
+ uri = GDropUtil.getRequestParamSingleValue(request, QS_URI);
+ String escapedUri = URIUtil.encodePathQuery(uri);
+ checkUri(escapedUri);
+ doInsert(ticket, escapedUri);
+ String link = generatePublicLink(request,ticket);
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.getWriter().println(link);
+ response.getWriter().close();
+ }
+
+ private void doInsert(String ticket, String uri) throws GDropException {
+ Connection c = null;
+ PreparedStatement s = null;
+ try {
+ c = dataSource.getConnection();
+ s = c.prepareStatement(INSERT_TEMPLATE);
+ s.setString(1,ticket);
+ s.setString(2,uri);
+ s.executeUpdate();
+ } catch (SQLException e) {
+ throw new GDropException("error occurred while registering ticket",e);
+ } finally{
+ GDropUtil.close(s);
+ GDropUtil.close(c);
+ }
+ }
+
+ private String generatePublicLink(HttpServletRequest request, String ticket){
+ String requestURL = request.getRequestURL().toString();
+ String res = requestURL.replace("/register","/get");
+ res+="/"+ticket;
+ return res;
+ }
+
+ private void checkUri(String uri) throws GDropException{
+ URI u;
+ try {
+ u = new URI(uri);
+ } catch (URISyntaxException e) {
+ throw new GDropException("malformed uri supplied");
+ }
+ if(!IRODS_SCHEME.equals(u.getScheme())){
+ throw new GDropException("not an iRODS uri (wrong scheme) ");
+ }
+ if(u.getPath() == null){
+ throw new GDropException("uri does not contain a file path");
+ }
+ }
+
+}
diff --git a/src/main/java/org/qcg/qcgdata/gdrop/SetUpDBServlet.java b/src/main/java/org/qcg/qcgdata/gdrop/SetUpDBServlet.java
new file mode 100644
index 0000000..94efeb9
--- /dev/null
+++ b/src/main/java/org/qcg/qcgdata/gdrop/SetUpDBServlet.java
@@ -0,0 +1,44 @@
+package org.qcg.qcgdata.gdrop;
+
+
+import org.qcg.qcgdata.gdrop.exception.GDropException;
+import org.qcg.qcgdata.gdrop.util.GDropUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class SetUpDBServlet extends DBEnabledServlet{
+
+ private static Logger log = LoggerFactory.getLogger(SetUpDBServlet.class);
+
+ private static final String DROP_STATEMENT = "DROP TABLE IF EXISTS gdrop";
+
+ private static final String CREATE_STATEMENT = "CREATE TABLE gdrop(id INTEGER PRIMARY KEY AUTOINCREMENT, uri TEXT, ticket TEXT, CONSTRAINT uc_ticket UNIQUE(ticket))";
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ Connection connection = null;
+ Statement s = null;
+ try {
+ connection = dataSource.getConnection();
+ s = connection.createStatement();
+ s.executeUpdate(DROP_STATEMENT);
+ s.executeUpdate(CREATE_STATEMENT);
+ response.getWriter().println("database was reseet");
+ response.getWriter().close();
+ } catch (SQLException e) {
+ throw new GDropException("error occurred while setting up the database");
+ } finally{
+ GDropUtil.close(s);
+ GDropUtil.close(connection);
+ }
+ }
+
+}
diff --git a/src/main/java/org/qcg/qcgdata/gdrop/exception/GDropException.java b/src/main/java/org/qcg/qcgdata/gdrop/exception/GDropException.java
new file mode 100644
index 0000000..466a396
--- /dev/null
+++ b/src/main/java/org/qcg/qcgdata/gdrop/exception/GDropException.java
@@ -0,0 +1,19 @@
+package org.qcg.qcgdata.gdrop.exception;
+
+import javax.servlet.ServletException;
+
+public class GDropException extends ServletException{
+
+ public GDropException(String s) {
+ super(s);
+ }
+
+ public GDropException(String s, Throwable throwable) {
+ super(s, throwable);
+ }
+
+ public GDropException(Throwable throwable) {
+ super(throwable);
+ }
+
+}
diff --git a/src/main/java/org/qcg/qcgdata/gdrop/util/GDropUtil.java b/src/main/java/org/qcg/qcgdata/gdrop/util/GDropUtil.java
new file mode 100644
index 0000000..964e616
--- /dev/null
+++ b/src/main/java/org/qcg/qcgdata/gdrop/util/GDropUtil.java
@@ -0,0 +1,91 @@
+package org.qcg.qcgdata.gdrop.util;
+
+
+import org.qcg.qcgdata.gdrop.exception.GDropException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class GDropUtil {
+
+ private static final Pattern ticketPattern;
+
+ private static Logger log = LoggerFactory.getLogger(GDropUtil.class);
+
+ static {
+ ticketPattern = Pattern.compile("^[a-f0-9]{12}4[a-f0-9]{19}$");
+ }
+
+ // Ticket
+
+ public static void checkTicket(String ticketString) throws GDropException {
+ if(ticketString == null || ticketString.trim().length()==0){
+ throw new GDropException("empty or null ticket supplied");
+ }
+ Matcher m = ticketPattern.matcher(ticketString);
+ if(!m.find()){
+ throw new GDropException(String.format("wrong ticket format: %s",ticketString));
+ }
+ }
+
+ // Database
+
+ public static void close(Connection c){
+ if (c != null) {
+ try {
+ c.close();
+ } catch (SQLException e) {
+ log.error("error occurred while closing connection", e);
+ }
+ }
+ }
+
+ public static void close(Statement s){
+ if(s != null){
+ try{
+ s.close();
+ } catch(SQLException e){
+ log.error("error occurred while closing statement", e);
+ }
+ }
+ }
+
+ public static void close(ResultSet rs){
+ if(rs != null){
+ try{
+ rs.close();
+ } catch (SQLException e){
+ log.error("error occurred while closing result set", e);
+ }
+ }
+ }
+
+ // Request
+
+ public static String getRequestParamSingleValue(HttpServletRequest req, String parameterName) throws GDropException {
+ String[] val = req.getParameterValues(parameterName);
+ if (val != null && val.length == 1) {
+ return val[0];
+ } else {
+ throw new GDropException("unable to get unique query param value " + parameterName);
+ }
+ }
+
+ public static String getRequestParamSingleOptionalValue(HttpServletRequest req, String parameterName) throws GDropException {
+ String res;
+ try{
+ res = getRequestParamSingleValue(req,parameterName);
+ } catch (GDropException e){
+ res = null;
+ }
+ return res;
+ }
+
+}
diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties
new file mode 100644
index 0000000..da3d861
--- /dev/null
+++ b/src/main/resources/log4j.properties
@@ -0,0 +1,16 @@
+log4j.rootLogger=debug, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+
+# Pattern to output the caller's file name and line number.
+log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
+
+log4j.logger.org.qcg.qcgdata.gdrop=, F
+log4j.additivity.org.qcg.qcgdata.gdrop=false
+log4j.appender.F = org.apache.log4j.RollingFileAppender
+log4j.appender.F.file=${catalina.home}/logs/gdrop.log
+log4j.appender.F.MaxFileSize=1024KB
+log4j.appender.F.MaxBackupIndex=1
+log4j.appender.F.layout=org.apache.log4j.PatternLayout
+log4j.appender.F.layout.ConversionPattern=%p %d [%C:%L] - %m%n \ No newline at end of file
diff --git a/src/main/webapp/META-INF/context.xml b/src/main/webapp/META-INF/context.xml
new file mode 100644
index 0000000..5468a84
--- /dev/null
+++ b/src/main/webapp/META-INF/context.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Context>
+ <Resource name="jdbc/gdropdb"
+ auth="Container"
+ type="javax.sql.DataSource"
+ driverClassName="org.sqlite.JDBC"
+ url="jdbc:sqlite:${catalina.home}/gdrop.db"
+ factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
+ />
+</Context> \ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..591c7d6
--- /dev/null
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
+ http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+ <servlet>
+ <servlet-name>registerServlet</servlet-name>
+ <servlet-class>org.qcg.qcgdata.gdrop.RegisterServlet</servlet-class>
+ </servlet>
+
+ <servlet>
+ <servlet-name>getFileServlet</servlet-name>
+ <servlet-class>org.qcg.qcgdata.gdrop.GetFileServlet</servlet-class>
+ </servlet>
+
+ <servlet>
+ <servlet-name>errorHandlingServlet</servlet-name>
+ <servlet-class>org.qcg.qcgdata.gdrop.ErrorHandlingServlet</servlet-class>
+ </servlet>
+
+ <servlet>
+ <servlet-name>setUpDB</servlet-name>
+ <servlet-class>org.qcg.qcgdata.gdrop.SetUpDBServlet</servlet-class>
+ </servlet>
+
+ <servlet>
+ <servlet-name>deleteServlet</servlet-name>
+ <servlet-class>org.qcg.qcgdata.gdrop.DeleteServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>registerServlet</servlet-name>
+ <url-pattern>/register</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>getFileServlet</servlet-name>
+ <url-pattern>/get/*</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>errorHandlingServlet</servlet-name>
+ <url-pattern>/error</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>setUpDB</servlet-name>
+ <url-pattern>/setup</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>deleteServlet</servlet-name>
+ <url-pattern>/delete</url-pattern>
+ </servlet-mapping>
+
+ <error-page>
+ <exception-type>org.qcg.qcgdata.gdrop.exception.GDropException</exception-type>
+ <location>/error</location>
+ </error-page>
+
+ <resource-ref>
+ <description>GDrop database</description>
+ <res-ref-name>jdbc/gdropdb</res-ref-name>
+ <res-type>javax.sql.DataSource</res-type>
+ <res-auth>Container</res-auth>
+ </resource-ref>
+</web-app> \ No newline at end of file
diff --git a/src/main/webapp/entries.jsp b/src/main/webapp/entries.jsp
new file mode 100644
index 0000000..d0dbdd7
--- /dev/null
+++ b/src/main/webapp/entries.jsp
@@ -0,0 +1,34 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<jsp:useBean id="dbBean" class="org.qcg.qcgdata.gdrop.GetEntriesBean" scope="request" />
+<html>
+<head>
+ <title>Entries</title>
+</head>
+<body>
+ <table>
+ <tbody>
+ <c:forEach var="entry" items="${dbBean.entries}">
+ <tr>
+ <td>
+ <c:out value="${entry.id}" />
+ </td>
+ <td>
+ <c:out value="${entry.uri}" />
+ </td>
+ <td>
+ <c:out value="${entry.ticket}" />
+ </td>
+ <td>
+ <a href='get/<c:out value="${entry.ticket}"/>'>get</a>
+ </td>
+ <td>
+ <a href='delete?ticket=<c:out value="${entry.ticket}"/>'>delete</a>
+ </td>
+
+ </tr>
+ </c:forEach>
+ </tbody>
+ </table>
+</body>
+</html> \ No newline at end of file