/**
*------------------------* * ClarescoExperienceAPI
* Copyright
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* Please contact Claresco, www.claresco.com, if you have any questions.
**/
package com.claresco.tinman.sql;
import java.io.BufferedReader;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import com.claresco.tinman.json.JsonUtility;
import com.claresco.tinman.lrs.XapiActivity;
import com.claresco.tinman.lrs.XapiActivityDefinition;
import com.claresco.tinman.lrs.XapiInteraction;
import com.claresco.tinman.lrs.XapiInteractionComponent;
import com.claresco.tinman.lrs.XapiStatement;
import com.google.gson.Gson;
/**
* XapiActivitySqlWriter.java
*
*
*
*
*
* @author rheza
* on Feb 24, 2014
*
*/
class XapiActivitySQLWriter extends SQLWriter {
private PreparedStatement myInsertStatement;
private PreparedStatement myCorrectResponseInsertStatement;
private PreparedStatement myInteractionCompInsertStatement;
private PreparedStatement myActivityTypeInsertStatement;
private PreparedStatement myUpdateStatement;
private PreparedStatement myCorrectResponseUpdateStatement;
private PreparedStatement myInteractionCompUpdateStatement;
private XapiLanguageMapSQLWriter myLanguageMapWriter;
private XapiExtensionSQLWriter myExtensionWriter;
private XapiActivitySQLReader myActivityReader;
private String[] myFieldNames = {"activityid", "actviri", "namelanguagemapid", "desclanguagemapid",
"activitytypecode", "interactiontypecode", "xextensionid"};
private String[] correctResponseFieldNames = {"correctresponseid", "activityid", "crpattern"};
private String[] interactionComponentFieldNames = {"interactioncomponentid", "activityid",
"icompkey", "languagemapid", "interactioncomponenttypecode"};
/**
* Description:
*
* Params:
*
*/
public XapiActivitySQLWriter(Connection conn, XapiLanguageMapSQLWriter theLanguageMapWriter,
XapiExtensionSQLWriter theExtWriter, XapiActivitySQLReader theActivityReader) throws SQLException{
this.myConn = conn;
this.myInsertStatement = SQLUtility.createInsertStatement(super.myConn, "activity", myFieldNames);
this.myCorrectResponseInsertStatement = SQLUtility.createInsertStatement(myConn, "correctresponse",
correctResponseFieldNames);
this.myInteractionCompInsertStatement = SQLUtility.createInsertStatement(myConn, "interaction" +
"component", interactionComponentFieldNames);
this.myInteractionCompUpdateStatement = SQLUtility.createUpdateStatement(myConn, "interactioncomponent",
new String[]{"icompkey", "interactioncomponenttypecode"}, new String[]{"interactioncomponentid"});
this.myActivityTypeInsertStatement = SQLUtility.createInsertStatement(myConn, "activitytype",
new String[]{"activitytypecode", "atypiri"});
this.myUpdateStatement = SQLUtility.createUpdateStatement(myConn, "activity", new String[]{
"activitytypecode", "interactiontypecode", "namelanguagemapid", "desclanguagemapid",
"xextensionid"}, new String[]{"activityid"});
this.myCorrectResponseUpdateStatement = SQLUtility.createUpdateStatement(myConn, "correctresponse",
new String[]{"crpattern"}, new String[]{"correctresponseid"});
this.myLanguageMapWriter = theLanguageMapWriter;
this.myExtensionWriter = theExtWriter;
this.myActivityReader = theActivityReader;
}
protected int insertActivity(XapiActivity theActivity, boolean isNewActivityAllowed)
throws SQLException, XapiDataIntegrityException{
synchronized (this) {
int activityID = myActivityReader.retrieveIDByValue(theActivity.getId().toString());
// Checking if the activity is already in the database
if (activityID != -1) {
// Update the activity if it is necessary
updateActivityIfNecessary(activityID, theActivity, isNewActivityAllowed);
}
else{
if(!isNewActivityAllowed){
throw new XapiActivityInvalidException("Not allowed to define new activity");
}else{
activityID = insertNewActivity(theActivity);
}
}
return activityID;
}
}
protected int insertNewActivity(XapiActivity theActivity) throws SQLException,
XapiDataIntegrityException{
int theId = super.fetchId();
XapiInteraction theInteraction = null;
this.myInsertStatement.setInt(1, theId);
this.myInsertStatement.setString(2, theActivity.getId().toString());
this.myInsertStatement.setNull(3, Types.NUMERIC);
this.myInsertStatement.setNull(4, Types.NUMERIC);
this.myInsertStatement.setNull(5, Types.CHAR);
this.myInsertStatement.setNull(6, Types.CHAR);
this.myInsertStatement.setNull(7, Types.NUMERIC);
if(theActivity.hasDefinition()){
XapiActivityDefinition theDefinition = theActivity.getDefinition();
if(theDefinition.hasName()){
this.myInsertStatement.setInt(3, myLanguageMapWriter.insertNewLanguageMap
(theDefinition.getName()));
}
if(theDefinition.hasDescription()){
this.myInsertStatement.setInt(4, myLanguageMapWriter.insertNewLanguageMap
(theDefinition.getDescription()));
}
if(theDefinition.hasType()){
String theTypeCode = insertActivityType(theDefinition.getType().toString());
myInsertStatement.setString(5, theTypeCode);
}
if(theDefinition.hasInteractionProperties()){
theInteraction = theDefinition.getInteractionProperties();
myInsertStatement.setString(6, getInteractionTypeCode(theInteraction.getType()));
}
if(theDefinition.hasExtension()){
myInsertStatement.setInt(7, myExtensionWriter.insertNewExtension
(theDefinition.getExtension()));
}
}
this.myInsertStatement.executeUpdate();
if(theInteraction != null){
if(theInteraction.hasCorrectReponse()){
insertCorrectResponse(theInteraction.getCorrectResponse(), theId);
}
if(theInteraction.hasChoices()){
insertInteractionComponent("CHOICES", theInteraction.getChoices(), theId);
}
if(theInteraction.hasScale()){
insertInteractionComponent("SCALE", theInteraction.getScale(), theId);
}
if(theInteraction.hasSource()){
insertInteractionComponent("SOURCE", theInteraction.getSource(), theId);
}
if(theInteraction.hasTarget()){
insertInteractionComponent("TARGET", theInteraction.getTarget(), theId);
}
if(theInteraction.hasSteps()){
insertInteractionComponent("STEPS", theInteraction.getSteps(), theId);
}
}
return theId;
}
private String getInteractionTypeCode(String interactionType) throws XapiDataIntegrityException{
if(interactionType.equalsIgnoreCase("choice")){
return "CHO";
}else if(interactionType.equalsIgnoreCase("sequencing")){
return "SEQ";
}else if(interactionType.equalsIgnoreCase("likert")){
return "LIKE";
}else if(interactionType.equalsIgnoreCase("matching")){
return "MAT";
}else if(interactionType.equalsIgnoreCase("performance")){
return "PERF";
}else if(interactionType.equalsIgnoreCase("true-false")){
return "TF";
}else if(interactionType.equalsIgnoreCase("fill-in")){
return "FILL";
}else if(interactionType.equalsIgnoreCase("numeric")){
return "NUM";
}else if(interactionType.equalsIgnoreCase("other")){
return "OTH";
}else{
throw new XapiActivityInvalidException("Bad interaction");
}
}
private String insertActivityType(String theType) throws SQLException{
String theDatabaseID = myActivityReader.retrieveActivityTypeCode(theType);
if(theDatabaseID != null){
return theDatabaseID;
}
int theID = super.fetchId();
String theActivityTypeCode = String.valueOf(theID);
myActivityTypeInsertStatement.setString(1, theActivityTypeCode);
myActivityTypeInsertStatement.setString(2, theType);
myActivityTypeInsertStatement.executeUpdate();
return theActivityTypeCode;
}
private void insertCorrectResponse(ArrayList<String> theCorrectResponses, int theActID) throws SQLException{
for (String s : theCorrectResponses){
insertOneCorrectResponse(s, theActID);
}
}
private void insertOneCorrectResponse(String theResponse, int theActID) throws SQLException{
int theID = super.fetchId();
myCorrectResponseInsertStatement.setInt(1, theID);
myCorrectResponseInsertStatement.setInt(2, theActID);
myCorrectResponseInsertStatement.setString(3, theResponse);
myCorrectResponseInsertStatement.executeUpdate();
}
private void insertInteractionComponent(String iCompType, ArrayList<XapiInteractionComponent> theComponents,
int theActivityID) throws SQLException{
for(XapiInteractionComponent iComp : theComponents){
insertOneInteractionComponent(iCompType, iComp, theActivityID);
}
}
private void insertOneInteractionComponent(String iCompType, XapiInteractionComponent iComp, int theActivityID)
throws SQLException{
myInteractionCompInsertStatement.setInt(1, super.fetchId());
myInteractionCompInsertStatement.setInt(2, theActivityID);
myInteractionCompInsertStatement.setString(3, iComp.getID());
if(iComp.getDescription() != null){
myInteractionCompInsertStatement.setInt(4, myLanguageMapWriter.insertNewLanguageMap
(iComp.getDescription()));
}else{
myInteractionCompInsertStatement.setNull(4, Types.NUMERIC);
}
myInteractionCompInsertStatement.setString(5, iCompType);
myInteractionCompInsertStatement.executeUpdate();
}
protected void updateActivityIfNecessary(int theActvID, XapiActivity theActivity, boolean isDefiningActivityAllowed)
throws SQLException, XapiDataIntegrityException{
XapiActivity theExistingActivity = myActivityReader.retrieveByID(theActvID);
// Somehow the activity is not found in the database
if(theExistingActivity == null){
throw new XapiActivityInvalidException("Trying to update not existing activity");
}
// Determine if activity needs to be updated
if(!theActivity.equals(theExistingActivity)){
if(isDefiningActivityAllowed){
updateActivity(theActvID, theActivity);
}else{
throw new XapiActivityInvalidException("Not allowed to redefine the activity");
}
}
}
private void updateActivity(int theActvID, XapiActivity theActivity) throws SQLException,
XapiDataIntegrityException{
myUpdateStatement.setNull(1, Types.CHAR);
myUpdateStatement.setNull(2, Types.CHAR);
myUpdateStatement.setNull(3, Types.INTEGER);
myUpdateStatement.setNull(4, Types.INTEGER);
myUpdateStatement.setNull(5, Types.INTEGER);
// If activity does not have a definition, throw an error
if(!theActivity.hasDefinition()){
throw new XapiInvalidActivityException("Activity Definition has to exists to update activity");
}
ResultSet myRS = myActivityReader.getActivityResultSet(theActvID);
myRS.next();
XapiActivityDefinition theDefinition = theActivity.getDefinition();
XapiInteraction theInteraction = theDefinition.getInteractionProperties();
// Update Activty Type
if(theDefinition.hasType()){
String theType = myActivityReader.retrieveActivityTypeCode(theDefinition.getType().toString());
if(theType != null){
myUpdateStatement.setString(1, theType);
}else{
myUpdateStatement.setString(1, insertActivityType(theDefinition.getType().toString()));
}
}
// Update interaction type
if(theDefinition.hasInteractionProperties()){
theInteraction = theDefinition.getInteractionProperties();
myUpdateStatement.setString(2, getInteractionTypeCode(theInteraction.getType()));
}
// Update the Name
if(theDefinition.hasName()){
int theNameID = myRS.getInt("namelanguagemapid");
if(myRS.wasNull()){
theNameID = myLanguageMapWriter.insertNewLanguageMap(theDefinition.getName());
}else{
myLanguageMapWriter.updateLanguageMap(theDefinition.getName(), theNameID);
}
myUpdateStatement.setInt(3, theNameID);
}
// Update the Description
if(theDefinition.hasDescription()){
int theDescID = myRS.getInt("desclanguagemapid");
if(myRS.wasNull()){
theDescID = myLanguageMapWriter.insertNewLanguageMap(theDefinition.getDescription());
}else{
myLanguageMapWriter.updateLanguageMap(theDefinition.getDescription(), theDescID);
}
myUpdateStatement.setInt(4, theDescID);
}
// Update the extension
if(theDefinition.hasExtension()){
int theExtID = myRS.getInt("xextensionid");
if(myRS.wasNull()){
theExtID = myExtensionWriter.insertNewExtension(theDefinition.getExtension());
}else{
myExtensionWriter.updateExtension(theDefinition.getExtension(), theExtID);
}
myUpdateStatement.setInt(5, theExtID);
}
// Set the activityID
myUpdateStatement.setInt(6, theActvID);
myUpdateStatement.executeUpdate();
// Update the interaction properties
if(theDefinition.hasInteractionProperties()){
if(theInteraction.hasCorrectReponse()){
updateCorrectResponse(theInteraction.getCorrectResponse(), theActvID);
}
ResultSet theResultSet = myActivityReader.getInteractionResultSet(theActvID);
if(theInteraction.hasChoices()){
updateInteractionComponent("CHOICES", theInteraction.getChoices(), theActvID,
theResultSet);
}
if(theInteraction.hasScale()){
updateInteractionComponent("SCALE", theInteraction.getScale(), theActvID,
theResultSet);
}
if(theInteraction.hasSource()){
updateInteractionComponent("SOURCE", theInteraction.getSource(), theActvID,
theResultSet);
}
if(theInteraction.hasTarget()){
updateInteractionComponent("TARGET", theInteraction.getTarget(), theActvID,
theResultSet);
}
if(theInteraction.hasSteps()){
updateInteractionComponent("STEPS", theInteraction.getSteps(), theActvID,
theResultSet);
}
}
}
private void updateCorrectResponse(ArrayList<String> theCorrectResponses, int theActID)
throws SQLException{
ResultSet myRS = myActivityReader.getCorrectResponseResultSet(theActID);
for (String s : theCorrectResponses){
if(myRS.next()){
updateOneCorrectResponse(s, myRS.getInt("correctresponseid"));
}else{
insertOneCorrectResponse(s, theActID);
}
}
}
private void updateOneCorrectResponse(String theResponse, int theID) throws SQLException{
myCorrectResponseUpdateStatement.setString(1, theResponse);
myCorrectResponseUpdateStatement.setInt(2, theID);
myCorrectResponseUpdateStatement.executeUpdate();
}
private void updateInteractionComponent(String iCompType, ArrayList<XapiInteractionComponent> theComponents,
int theActivityID, ResultSet theResultSet) throws SQLException{
for(XapiInteractionComponent iComp : theComponents){
if(theResultSet.next()){
updateOneInteractionComponent(iCompType, iComp, theResultSet.getInt("interactioncomponentid"));
}else{
insertOneInteractionComponent(iCompType, iComp, theActivityID);
}
}
}
private void updateOneInteractionComponent(String iCompType, XapiInteractionComponent iComp,
int theICompID) throws SQLException{
myInteractionCompUpdateStatement.setString(1, iComp.getID());
myInteractionCompUpdateStatement.setString(2, iCompType);
myInteractionCompUpdateStatement.setInt(3, theICompID);
myInteractionCompUpdateStatement.executeUpdate();
}
/* (non-Javadoc)
* @see com.claresco.tinman.sql.SQLWriter#close()
*/
@Override
protected void close() throws SQLException {
super.close();
SQLUtility.closeStatement(myInsertStatement);
SQLUtility.closeStatement(myCorrectResponseInsertStatement);
SQLUtility.closeStatement(myInteractionCompInsertStatement);
SQLUtility.closeStatement(myUpdateStatement);
SQLUtility.closeStatement(myCorrectResponseUpdateStatement);
SQLUtility.closeStatement(myInteractionCompUpdateStatement);
}
public static void main(String[] args) {
try {
Connection conn = SQLUtility.establishDefaultConnection();
XapiExtensionSQLReader theExtR = new XapiExtensionSQLReader(conn);
XapiExtensionSQLWriter theExtW = new XapiExtensionSQLWriter(conn, theExtR);
XapiLanguageMapSQLReader theLReader = new XapiLanguageMapSQLReader(conn);
XapiLanguageMapSQLWriter theLWriter = new XapiLanguageMapSQLWriter(conn, theLReader);
XapiLanguageMapSQLReader theLMapReader = new XapiLanguageMapSQLReader(conn);
XapiExtensionSQLReader theExtReader = new XapiExtensionSQLReader(conn);
XapiActivitySQLReader theActReader = new XapiActivitySQLReader(conn, theLMapReader, theExtReader);
XapiActivitySQLWriter theActWriter = new XapiActivitySQLWriter(conn, theLWriter, theExtW, theActReader);
} catch (Exception e) {
}
}
}