package com.transmem.action;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.ServletContext;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import com.transmem.data.db.Databases;
import com.transmem.data.db.Users;
import com.transmem.data.db.Corpora;
import com.transmem.data.db.CorpusTally;
import com.transmem.data.db.Sources;
import com.transmem.data.db.Transunit;
/**
* Action class for Corpus-related operations.
*
* @version 0.1
* @author Ted Wen
* @date May. 2007
*/
public class CorpusAction extends BaseAction
{
private Logger log_ = Logger.getLogger(CorpusAction.class.getName());
public CorpusAction()
{
super();
}
public void execute(ServletParams param) throws ServletException, IOException
{
log_.entering("CorpusAction","execute");
Session session = param.getSession();
Users user = session.getUser();
if (user == null) {
log_.severe("session.getAttribute('user') returned null");
param.sendError(MessageCode.ERR_NOT_LOGIN);
return;
}
String langpair = param.getParameter("arg1");
if (langpair == null || langpair.length()<4) {
langpair = session.getLangPair();
if (langpair == null || langpair.length()<4) {
langpair = "ENZH"; //TODO: make this depend on user's
}
}
String op = param.getParameter("operation");
if (op == null || op.length()<1)
{
//param.sendError("Form operation not specified");
op = session.getCorpusOp();
if (op == null)
{
op = "tally";
}
}
if (op.equals("tally"))
{
if (session.getCorpusTally()!=null)
{
setNextPage(PageLinks.CORPUS_TALLY_PAGE);
session.setCorpusOp(op);
return;
}
}
else if (op.equals("sources"))
{
if (session.getCorpusSourceList()!=null)
{
setNextPage(PageLinks.MYCORPUS_PAGE);
session.setCorpusOp(op);
return;
}
}
else if (op.equals("units"))
{
if (session.getCorpusUnitList()!=null)
{
setNextPage(PageLinks.MYSENTENCES_PAGE);
session.setCorpusOp(op);
return;
}
}
else
{
op = "tally";
}
log_.info("Operation="+op+", langpair="+langpair);
String srcid = null;
Connection conn = null;
try
{
conn = getConnection(param,Databases.CATEGORY_USER);
conn.setAutoCommit(false);
if (op.equals("delsources"))
{
if (param.getParameter("arg2")!=null)
{
deleteSources(conn, langpair, param.getParameter("arg2"));
}
op = "sources";
}
else if (op.equals("delunits"))
{
if (param.getParameter("arg2")!=null)
{
deleteUnits(conn, langpair, param.getParameter("arg2"));
}
op = "units";
srcid = session.getSourceID();
}
if (op.equals("tally"))
{
Corpora c = new Corpora(conn);
ArrayList<CorpusTally> cts = c.queryCorpusStats(langpair);
log_.info("queryCorpusStats return "+cts.size());
session.setCorpusTally(cts);
setNextPage(PageLinks.CORPUS_TALLY_PAGE);
log_.info("Redirecting to "+PageLinks.CORPUS_TALLY_PAGE);
}
else if (op.equals("sources"))
{
Sources s = new Sources(conn);
log_.info("loading sources for user "+user.getUserID());
ArrayList<Sources> srcs = s.queryByOwner(user.getUserID());
log_.info(srcs.size()+" sources loaded for user "+user.getUserID());
session.setCorpusSourceList(srcs);
setNextPage(PageLinks.MYCORPUS_PAGE);
}
else if (op.equals("units"))
{
String tablename = getCorpusTableName(conn, langpair);
if (srcid == null) srcid = param.getParameter("arg2");
if (srcid == null) srcid = session.getSourceID(); else session.setSourceID(srcid);
int srcidn = Integer.parseInt(srcid);
//TODO: retrieve page by page!
String sql = "SELECT * FROM "+tablename+" WHERE F_From=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, srcidn);
ResultSet rs = ps.executeQuery();
ArrayList<Transunit> sents = new ArrayList<Transunit>();
while (rs.next())
{
Transunit tu = new Transunit();
tu.setSid(rs.getLong(1)); //F_SID
tu.setSource(rs.getString(2)); //F_Source
tu.setTarget(rs.getString(3)); //F_Target
sents.add(tu);
/*sent[0] = rs.getLong(1); //F_SID
sent[1] = rs.getString(2); //F_Source
sent[2] = rs.getString(3); //F_Target
sent[3] = rs.getString(4); //F_Domain
sent[4] = rs.getInt(5); //F_Owner
sent[5] = rs.getInt(6); //F_Permit
sent[6] = rs.getInt(7); //F_From
sents.add(sent);*/
}
rs.close();
ps.close();
session.setCorpusUnitList(sents);
setNextPage(PageLinks.MYSENTENCES_PAGE);
}
//finally, remember the display page
conn.commit();
session.setCorpusOp(op);
//log_.info("Corpus Op="+op);
}
catch (NumberFormatException nfe)
{
try {conn.rollback();} catch (SQLException xe) {}
log_.warning(nfe.getMessage());
param.sendError(999,nfe.toString());
}
catch (SQLException e)
{
try {conn.rollback();} catch (SQLException xe) {}
log_.severe(e.getMessage());
param.sendError(999,e.toString());
}
finally
{
if (conn != null)
try { conn.close(); } catch (SQLException x) {}
}
}
/**
* Delete some source records.
* These records may be referenced by some translation units in different tables such as T_ENZH.
* To delete these source records, the referencing units must be deleted first.
* Another note is that this feature might be abused by hackers. therefore, it must be strictly
* checked for user credibility and it is necessary to backup the deleted records into some
* other tables in order to recover if the records are deleted by accident or hacking.
* @param conn - Connection
* @param langpair - ENZH
* @param sids - Source IDs as a string separated by commas
*/
protected void deleteSources(Connection conn, String langpair, String sids) throws SQLException
{
//1.remove leading or trailing commas if any
if (sids.startsWith(",")) sids = sids.substring(1);
if (sids.endsWith(",")) sids = sids.substring(0,sids.length()-1);
//2. delete units first (assuming no Cascaded delete on DBMS)
String tablename = getCorpusTableName(conn,langpair);
//2.1 backup these units
//TODO:
//2.2 delete these units
String sql = "DELETE FROM "+tablename+" WHERE F_From IN ("+sids+")";
java.sql.Statement st = conn.createStatement();
try {
st.executeUpdate(sql);
} catch (SQLException se) {
throw new SQLException(se.getMessage());
} finally {
st.close();
}
//3. delete the list from t_sources
//3.1 backup the source first
//TODO:
//3.2 delete the sources
sql = "DELETE FROM T_Sources WHERE F_SourceID IN ("+sids+")";
st = conn.createStatement();
try {
st.executeUpdate(sql);
} catch (SQLException se) {
throw new SQLException(se.getMessage());
} finally {
st.close();
}
}
/**
* Delete some translation units from example table.
* @param conn - Connection
* @param langpair - ENZH
* @param sids - Sentence IDs as a string separated by commas
*/
protected void deleteUnits(Connection conn, String langpair, String sids) throws SQLException
{
//1.remove leading or trailing commas if any
if (sids.startsWith(",")) sids = sids.substring(1);
if (sids.endsWith(",")) sids = sids.substring(0,sids.length()-1);
//2.determine table name from langpair
String tablename = getCorpusTableName(conn,langpair);
//3.backup these deleted records to another table
//TODO:
//4.delete from corpus
String sql = "DELETE FROM "+tablename+" WHERE F_SID IN ("+sids+")";
java.sql.Statement st = conn.createStatement();
try {
st.executeUpdate(sql);
} catch (SQLException se) {
throw new SQLException(se.getMessage());
} finally {
st.close();
}
}
}