package org.ariadne_eu.content.insert;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Writer;
import java.math.BigInteger;
import java.rmi.dgc.VMID;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Random;
import javax.activation.DataHandler;
import oracle.sql.CLOB;
import org.apache.log4j.Logger;
import org.ariadne.config.PropertiesManager;
import org.ariadne_eu.utils.config.RepositoryConstants;
import com.ibm.db2.jcc.DB2Xml;
/**
* Created by ben
* Date: 3-mrt-2007
* Time: 15:23:30
* To change this template use File | Settings | File Templates.
*/
public class InsertContentOracleDbImpl extends InsertContentImpl {
private static Logger log = Logger.getLogger(InsertContentOracleDbImpl.class);
private String tableName;
private String columnName;
private String identifierColumnName;
public InsertContentOracleDbImpl() {
initialize();
}
public InsertContentOracleDbImpl(int nb) {
setNumber(nb);
initialize();
}
void initialize() {
super.initialize();
try {
// String driver = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DB_DRIVER + "." + getNumber());
// if (driver == null)
// driver = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DB_DRIVER);
// Class.forName(driver);
Class.forName("oracle.jdbc.driver.OracleDriver");
//TODO: auto generate?
// if(collection == null)
// generateCollection(URI, collectionString, username, password);
tableName = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DB_XMLDB_SQL_TABLENAME);
if (tableName == null)
tableName = "Contentstore";
columnName = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DB_XMLDB_SQL_COLUMNNAME);
if (columnName == null)
columnName = "contentxml";
identifierColumnName = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DB_XMLDB_SQL_IDCOLUMNNAME);
if (identifierColumnName == null)
identifierColumnName = "GLOBAL_IDENTIFIER";
} catch (ClassNotFoundException e) {
log.error("initialize: ", e);
} catch (Throwable t) {
log.error("initialize: ", t);
}
}
// public void insertContent(String identifier, DataHandler dataHandler) {
// try {
// File file = getFileForID(identifier, "", "");
// if (!file.getParentFile().exists()) {
// file.getParentFile().mkdirs();
// }
// FileOutputStream outputStream = new FileOutputStream(file);
// dataHandler.writeTo(outputStream);
// outputStream.flush();
// outputStream.close();
// dataHandler.getInputStream().close();
//// return true;
// log.info("insertContent:identifier:\""+identifier+"\"");
// } catch (IOException e) {
// log.error("insertContent:identifier:\""+identifier+"\" ", e);
//// return false;
// }
// }
public synchronized void insertContent(String identifier, DataHandler dataHandler, String fileName, String fileType) {
try {
File file = getFileForID(identifier, fileName, fileType);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
FileOutputStream outputStream = new FileOutputStream(file);
dataHandler.writeTo(outputStream);
outputStream.flush();
outputStream.close();
dataHandler.getInputStream().close();
// return true;
log.info("insertContent:identifier:\""+identifier+"\"");
} catch (IOException e) {
log.error("insertContent:identifier:\""+identifier+"\" ", e);
// return false;
}
}
// private File getFileForID(String identifier) {
// String metadata = getMetadataForID(identifier);
// if (metadata == null) {
// //identifier doesn't exist yet
// return createUniqueFile(identifier);
// } else {
// return getFileFromMetadata(metadata);
// }
//
// }
private File getFileForID(String identifier, String fileName, String fileType) {
String metadata = getMetadataForID(identifier);
if (metadata == null) {
//identifier doesn't exist yet
return createUniqueFile(identifier, fileName, fileType);
} else {
return getFileFromMetadata(metadata);
}
}
private String getMetadataForID(String identifier) {
PreparedStatement pstmt = null;
Connection con = null;
try {
con = getConnection();
pstmt = con.prepareStatement("SELECT "+columnName+" FROM "+tableName+" WHERE "+identifierColumnName+" = ?");
pstmt.setString(1, identifier);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
DB2Xml xml = (DB2Xml) rs.getObject(1);
return xml.getDB2String();
}
} catch (SQLException e) {
log.error("getMetadataForID:identifier=" + identifier, e);
} finally {
try {
pstmt.close();
con.close();
} catch (Exception e) {
log.error("getMetadataForID:identifier=" + identifier, e);
}
}
return null;
}
private static int counter = 0;
private static Random random = new Random();
private static VMID vmid = new VMID();
// private File createUniqueFile(String identifier) {
// byte[] junk = new byte[16];
//
// random.nextBytes(junk);
//
// String input = new StringBuffer().append(vmid).append(
// new java.util.Date()).append(junk).append(counter++).append(identifier).toString();
//
// byte[] bytes = getMD5Bytes(input.getBytes());
// String name = new BigInteger(bytes).abs().toString();
//
// String basePath = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DR_BASEPATH);
// if (!basePath.endsWith(File.separator))
// basePath += File.separator;
// String fullPath = basePath + name;
// File file = new File(fullPath);
// if (!file.exists()) {
// storeIdentifierPath(identifier, name, file);
// return file;
// }
// else
// return createUniqueFile(identifier); // bad luck, file already exists, retry
// }
private File createUniqueFile(String identifier, String fileName, String fileType) {
byte[] junk = new byte[16];
random.nextBytes(junk);
String input = new StringBuffer().append(vmid).append(
new java.util.Date()).append(junk).append(counter++).append(identifier).toString();
byte[] bytes = getMD5Bytes(input.getBytes());
String relativePath = new BigInteger(bytes).abs().toString();
String basePath = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DR_BASEPATH);
if (!basePath.endsWith(File.separator))
basePath += File.separator;
String fullPath = basePath + relativePath;
File file = new File(fullPath);
if (!file.exists()) {
storeIdentifierPath(identifier, relativePath, fileName, fileType, file);
return file;
}
else
return createUniqueFile(identifier, fileName, fileType); // bad luck, file already exists, retry
}
// private File createUniqueFile(String identifier) {
// String basePath = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DR_BASEPATH);
// if (!basePath.endsWith(File.separator))
// basePath += File.separator;
// String fullPath = basePath + identifier + ".zip";
// File file = new File(fullPath);
// if (!file.exists()) {
// storeIdentifierPath(identifier, identifier + ".zip", file);
// return file;
// }
// else
// return createUniqueFile(identifier); // bad luck, file already exists, retry
// }
// private void storeIdentifierPath(String identifier, String name, File file) {
// String xml = "<content><identifier type=\"ariadneIDv1\">" + identifier + "</identifier><relativepath>" + name + "</relativepath><fullpath>" + file.getAbsolutePath() + "</fullpath></content>";
//
//
// try {
// Connection con = getConnection();
//
// PreparedStatement pstmt = con.prepareStatement("DELETE FROM " + tableName + " WHERE "+identifierColumnName+" = ?");
// pstmt.setString(1, identifier);
// pstmt.execute();
// pstmt.close();
//
// java.sql.Blob blobData = com.ibm.db2.jcc.t2zos.DB2LobFactory.createBlob(xml.getBytes("UTF-8"));
//
// pstmt = con.prepareStatement(
// "INSERT INTO " + tableName + " ("+identifierColumnName+", " + columnName + ") " +
// "VALUES(?, XMLPARSE(document cast(? as Blob) strip whitespace))");
//
// pstmt.setString(1, identifier);
// pstmt.setBlob(2, blobData);
//
// pstmt.execute();
// pstmt.close();
// con.close();
// log.info("insertContent:identifier:\""+identifier+"\"");
// } catch (SQLException e) {
// log.error("insertContent:identifier:\""+identifier+"\" ", e);
// } catch (UnsupportedEncodingException e) {
// log.error("insertContent:identifier:\""+identifier+"\" ", e);
// }
// }
private void storeIdentifierPath(String identifier, String relativePath, String fileName, String fileType, File file) {
String xml = "<content><identifier type=\"ariadneIDv1\">" + identifier
+ "</identifier><relativepath>" + relativePath
+ "</relativepath><fullpath>" + file.getAbsolutePath()
+ "</fullpath><filename>" + fileName + "</filename><filetype>" + fileType
+ "</filetype></content>";
try {
Connection con = getConnection();
PreparedStatement pstmt = con.prepareStatement("DELETE FROM " + tableName + " WHERE "+identifierColumnName+" = ?");
pstmt.setString(1, identifier);
pstmt.execute();
pstmt.close();
java.sql.Clob clobData = getCLOB(xml, con);
pstmt = con.prepareStatement(
"INSERT INTO " + tableName + " ("+identifierColumnName+", " + columnName + ") " +
"VALUES(?, XMLType(?))");
pstmt.setString(1, identifier);
pstmt.setClob(2, clobData);
pstmt.execute();
pstmt.close();
con.close();
log.info("insertContent:identifier:\""+identifier+"\"");
} catch (SQLException e) {
log.error("insertContent:identifier:\""+identifier+"\" ", e);
}
}
private Connection getConnection() throws SQLException {
String URI = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DB_URI);
String username = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DB_USERNAME);
String password = PropertiesManager.getInstance().getProperty(RepositoryConstants.getInstance().CNT_DB_PASSWORD);
return DriverManager.getConnection(URI,username, password);
}
/**
* Return an MD5 checksum for data as a byte array.
*
* @param data
* The data to checksum.
* @return MD5 checksum for the data as a byte array.
*/
private static byte[] getMD5Bytes(byte[] data)
{
try
{
MessageDigest digest = MessageDigest.getInstance("MD5");
return digest.digest(data);
}
catch (NoSuchAlgorithmException nsae)
{
}
// Should never happen
return null;
}
private static File getFileFromMetadata(String metadata) {
int start = metadata.indexOf("<fullpath>") + "<fullpath>".length();
int end = metadata.indexOf("</fullpath>");
String filename = metadata.substring(start, end);
return new File(filename);
}
private static CLOB getCLOB(String xmlData, Connection conn) throws SQLException {
CLOB tempClob = null;
try {
// If the temporary CLOB has not yet been created, create new
tempClob = CLOB.createTemporary(conn, true, CLOB.DURATION_SESSION);
// Open the temporary CLOB in readwrite mode to enable writing
tempClob.open(CLOB.MODE_READWRITE);
// Get the output stream to write
Writer tempClobWriter = tempClob.getCharacterOutputStream();
// Write the data into the temporary CLOB
tempClobWriter.write(xmlData);
// Flush and close the stream
tempClobWriter.flush();
tempClobWriter.close();
// Close the temporary CLOB
tempClob.close();
} catch (SQLException sqlexp) {
tempClob.freeTemporary();
sqlexp.printStackTrace();
} catch (Exception exp) {
tempClob.freeTemporary();
exp.printStackTrace();
}
return tempClob;
}
}