/** * Copyright © 2001 The JA-SIG Collaborative. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *u * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the JA-SIG Collaborative * (http://www.jasig.org/)." * * THIS SOFTWARE IS PROVIDED BY THE JA-SIG COLLABORATIVE "AS IS" AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JA-SIG COLLABORATIVE OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ package org.jasig.portal; import org.jasig.portal.security.IPerson; import org.jasig.portal.ChannelStatistics; import org.jasig.portal.ChannelUser; import org.jasig.portal.RDBMStatisticsStore; import org.jasig.portal.services.EntityCachingService; import java.io.BufferedReader; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Hashtable; import java.util.Enumeration; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jasig.portal.RDBMServices; /** *
A class that saves and retrieves usage statistics to/from the portal database.
* * @author rtwigg@uccs.edu */ public class RDBMChannelStatisticsStore implements IChannelStatisticsStore{ private static final Log log = LogFactory.getLog(RDBMChannelStatisticsStore.class); /** * Get channel statistics. * @param channelPublishId a channel publish ID * @return channelStatistics, statistics for the channel ornull
* if no matching channel statistics are found
* @throws java.sql.SQLException
*/
public ChannelStatistics getChannelStatistics(int channelPublishId) throws SQLException {
ChannelStatistics channelStats = null;
// Check the cache
try {
channelStats = (ChannelStatistics)EntityCachingService.instance().get(ChannelStatistics.class, String.valueOf(channelPublishId));
} catch (Exception e) {
log.error("Error checking cache for channel statistics with publish id "
+ channelPublishId, e);
}
// If not found in cache, get it from the store and cache it, otherwise return it
if (channelStats == null) {
Connection conn = null;
RDBMServices.PreparedStatement pstmtChannelStats = null;
RDBMServices.PreparedStatement pstmtChannelName = null;
ResultSet rs = null;
ResultSet rst = null;
try {
conn = RDBMServices.getConnection();
pstmtChannelStats = getChannelStatsPstmt(conn);
pstmtChannelName = getChannelNamePstmt(conn);
pstmtChannelStats.clearParameters();
pstmtChannelStats.setInt(1, channelPublishId);
log.debug("RDBMChannelStatisticsStore.getChannelStatistics(): " + pstmtChannelStats);
rs = pstmtChannelStats.executeQuery();
if (rs.next()) {
do {
if (channelStats==null) {
channelStats = new ChannelStatistics(channelPublishId);
}
String userName = rs.getString(1);
ChannelUser channelUser = new ChannelUser(channelPublishId, userName);
channelUser.setDateAdded(rs.getDate(2));
channelUser.setDateInstantiated(rs.getDate(3));
int totInst = rs.getInt(4);
channelUser.setDateTargeted(rs.getDate(5));
int totTarg = rs.getInt(6);
channelUser.setTotInstantiated(totInst);
channelUser.setTotTargeted(totTarg);
channelStats.addUser(channelUser);
} while (rs.next());
int dbOffset = 0;
rs.close();
pstmtChannelName.clearParameters();
pstmtChannelName.setInt(1, channelPublishId);
log.debug("RDBMChannelStatisticsStore.getChannelStatistics(): " + pstmtChannelStats);
rs = pstmtChannelName.executeQuery();
if (rs.next()) {
String name = rs.getString(dbOffset + 1);
if (name != null) {
channelStats.setName(name);
}
}
log.debug("RDBMChannelStatisticsStore.getChannelStatistics(): Read channel " + channelPublishId + " from the store");
// Add the channel definition to the cache
try {
EntityCachingService.instance().add(channelStats);
} catch (Exception e) {
log.error("Error caching channel statistics " + channelStats, e);
}
} // end if (rs.next())
} finally {
try { rs.close(); } catch (Exception e) {}
try { pstmtChannelStats.close(); } catch (Exception e) {}
try { pstmtChannelName.close(); } catch (Exception e) {}
try { RDBMServices.releaseConnection(conn); } catch (Exception e) {}
} // end try/finally
} // end if channelStats==null
return channelStats;
}
public void putChannelStatistics(IPerson person, Hashtable channelSet) throws SQLException {
RDBMServices.PreparedStatement pstmtChannelUser = null;
RDBMServices.PreparedStatement pstmtChannelUserInsert = null;
RDBMServices.PreparedStatement pstmtChannelUserUpdate = null;
ResultSet rs = null;
String sqlUserName;
java.sql.Date sqlDateAdded;
java.sql.Date sqlDateInstantiated;
java.sql.Date sqlDateTargeted;
int sqlTotInstantiated=0;
int sqlTotTargeted=0;
RDBMServices rdbm = new RDBMServices();
Connection conn = RDBMServices.getConnection();
pstmtChannelUser = getChannelUserPstmt(conn);
try
{
// Set autocommit false for the connection
RDBMServices.setAutoCommit(conn, false);
Enumeration en = channelSet.keys();
while (en.hasMoreElements())
{
String channelId = (String)en.nextElement();
int channelIdInt = Integer.parseInt(channelId);
ChannelUser cUser = (ChannelUser)channelSet.get(channelId);
String userName = cUser.getUserName();
try
{
pstmtChannelUser.clearParameters();
pstmtChannelUser.setInt(1, Integer.parseInt(channelId));
sqlUserName = RDBMServices.sqlEscape(userName);
pstmtChannelUser.setString(2, sqlUserName);
rs = pstmtChannelUser.executeQuery();
log.info("RDBMChannelStatisticsStore.putChannelStatistics(): " + pstmtChannelUser);
// If channel stats is already there, do an update, otherwise do an insert
if (rs.next())
{
java.sql.Date oldDateAdded = rs.getDate(3);
java.sql.Date oldDateInstantiated = rs.getDate(4);
int oldTotInstantiated = rs.getInt(5);
java.sql.Date oldDateTargeted = rs.getDate(6);
int oldTotTargeted = rs.getInt(7);
if (oldDateAdded.after(cUser.getDateAdded()))
sqlDateAdded = oldDateAdded;
else
sqlDateAdded = cUser.getDateAdded();
if (oldDateInstantiated.after(cUser.getDateInstantiated()))
sqlDateInstantiated = oldDateInstantiated;
else
sqlDateInstantiated = cUser.getDateInstantiated();
if (oldDateTargeted.after(cUser.getDateTargeted()))
sqlDateTargeted = oldDateTargeted;
else
sqlDateTargeted = cUser.getDateTargeted();
sqlTotInstantiated = oldTotInstantiated + cUser.getTotInstantiated();
sqlTotTargeted = oldTotTargeted + cUser.getTotTargeted();
pstmtChannelUserUpdate = getChannelUserUpdatePstmt(conn);
pstmtChannelUserUpdate.clearParameters();
pstmtChannelUserUpdate.setDate(1, sqlDateAdded);
pstmtChannelUserUpdate.setDate(2, sqlDateInstantiated);
pstmtChannelUserUpdate.setInt(3, sqlTotInstantiated);
pstmtChannelUserUpdate.setDate(4, sqlDateTargeted);
pstmtChannelUserUpdate.setInt(5, sqlTotTargeted);
pstmtChannelUserUpdate.setInt(6, channelIdInt);
pstmtChannelUserUpdate.setString(7, sqlUserName);
pstmtChannelUserUpdate.executeUpdate();
}
else
{
pstmtChannelUserInsert = getChannelUserInsertPstmt(conn);
pstmtChannelUserInsert.clearParameters();
pstmtChannelUserInsert.setInt(1, Integer.parseInt(channelId));
pstmtChannelUserInsert.setString(2, sqlUserName);
pstmtChannelUserInsert.setDate(3, cUser.getDateAdded());
pstmtChannelUserInsert.setDate(4, cUser.getDateInstantiated());
pstmtChannelUserInsert.setInt(5, sqlTotInstantiated);
pstmtChannelUserInsert.setDate(6, cUser.getDateTargeted());
pstmtChannelUserInsert.setInt(7, sqlTotTargeted);
log.info("RDBMChannelStatisticsStore.putChannelStatistics(): " + pstmtChannelUserInsert);
pstmtChannelUserInsert.executeUpdate();
}
// Commit the transaction
RDBMServices.commit(conn);
} // end try
catch (SQLException sqle)
{
log.error("Exception saving channel statistics for user" + userName, sqle);
RDBMServices.rollback(conn);
throw sqle;
}
} // end while
} finally {
try { rs.close(); } catch (Exception e) {}
try { pstmtChannelUser.close(); } catch (Exception e) {}
try { pstmtChannelUserUpdate.close(); } catch (Exception e) {}
try { pstmtChannelUserInsert.close(); } catch (Exception e) {}
try { RDBMServices.releaseConnection(conn); } catch (Exception e) {}
} // end try/finally
}
protected static final RDBMServices.PreparedStatement getChannelStatsPstmt(Connection conn) throws SQLException {
String sql = "SELECT USER_NAME, CHAN_ADDED, CHAN_LAST_INSTANTIATED, CHAN_TOTAL_INSTANTIATED, " +
"CHAN_LAST_TARGETED, CHAN_TOTAL_TARGETED FROM UP_CHANNEL_USER WHERE CHAN_ID=?";
return new RDBMServices.PreparedStatement(conn, sql);
}
protected static final RDBMServices.PreparedStatement getChannelNamePstmt(Connection conn) throws SQLException {
return new RDBMServices.PreparedStatement(conn, "SELECT CHAN_NAME FROM UP_CHANNEL WHERE CHAN_ID=?");
}
protected static final RDBMServices.PreparedStatement getChannelUserPstmt(Connection conn) throws SQLException {
String sql = "SELECT * FROM UP_CHANNEL_USER WHERE CHAN_ID=? AND USER_NAME=?";
return new RDBMServices.PreparedStatement(conn, sql);
}
protected static final RDBMServices.PreparedStatement getChannelUserUpdatePstmt(Connection conn) throws SQLException {
String sql = "UPDATE UP_CHANNEL_USER SET CHAN_ADDED = ?, CHAN_LAST_INSTANTIATED = ?, " +
"CHAN_TOTAL_INSTANTIATED = ?, CHAN_LAST_TARGETED = ?, CHAN_TOTAL_TARGETED = ? " +
"WHERE CHAN_ID = ? AND USER_NAME = ?";
return new RDBMServices.PreparedStatement(conn, sql);
}
protected static final RDBMServices.PreparedStatement getChannelUserInsertPstmt(Connection conn) throws SQLException {
String sql = "INSERT INTO UP_CHANNEL_USER (CHAN_ID, USER_NAME, CHAN_ADDED, " +
"CHAN_LAST_INSTANTIATED, CHAN_TOTAL_INSTANTIATED, CHAN_LAST_TARGETED, " +
"CHAN_TOTAL_TARGETED) VALUES (?, ?, ?, ?, ?, ?, ?)";
return new RDBMServices.PreparedStatement(conn, sql);
}
}