diff options
author | Michal Krysinski <mich@man.poznan.pl> | 2013-07-11 11:43:23 (GMT) |
---|---|---|
committer | Michal Krysinski <mich@man.poznan.pl> | 2013-07-11 11:43:23 (GMT) |
commit | 3762aff66844d901d5cf43133e30c02e06e06af9 (patch) | |
tree | d90762c36d8ab352de41a1917dd429275d1f31aa | |
download | QCG-Data-Serv-master.zip QCG-Data-Serv-master.tar.gz QCG-Data-Serv-master.tar.bz2 |
-rw-r--r-- | pom.xml | 111 | ||||
-rw-r--r-- | src/main/java/org/qcg/qcgdata/gdrop/DBEnabledServlet.java | 37 | ||||
-rw-r--r-- | src/main/java/org/qcg/qcgdata/gdrop/DeleteServlet.java | 47 | ||||
-rw-r--r-- | src/main/java/org/qcg/qcgdata/gdrop/ErrorHandlingServlet.java | 29 | ||||
-rw-r--r-- | src/main/java/org/qcg/qcgdata/gdrop/GetEntriesBean.java | 90 | ||||
-rw-r--r-- | src/main/java/org/qcg/qcgdata/gdrop/GetFileServlet.java | 157 | ||||
-rw-r--r-- | src/main/java/org/qcg/qcgdata/gdrop/RegisterServlet.java | 86 | ||||
-rw-r--r-- | src/main/java/org/qcg/qcgdata/gdrop/SetUpDBServlet.java | 44 | ||||
-rw-r--r-- | src/main/java/org/qcg/qcgdata/gdrop/exception/GDropException.java | 19 | ||||
-rw-r--r-- | src/main/java/org/qcg/qcgdata/gdrop/util/GDropUtil.java | 91 | ||||
-rw-r--r-- | src/main/resources/log4j.properties | 16 | ||||
-rw-r--r-- | src/main/webapp/META-INF/context.xml | 10 | ||||
-rw-r--r-- | src/main/webapp/WEB-INF/web.xml | 68 | ||||
-rw-r--r-- | src/main/webapp/entries.jsp | 34 |
14 files changed, 839 insertions, 0 deletions
@@ -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 |