Java tutorial
/* * Aloha Open Source SIP Application Server- https://trac.osmosoft.com/Aloha * * Copyright (c) 2008, British Telecommunications plc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free Software * Foundation; either version 3.0 of the License, or (at your option) any later * version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along * with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.bt.aloha.dao; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.List; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.support.SqlLobValue; import com.bt.aloha.media.conference.state.ConferenceInfo; import com.bt.aloha.media.conference.state.ConferenceState; import com.bt.aloha.media.conference.state.ConferenceTerminationCause; import com.bt.aloha.media.conference.state.ParticipantState; import com.bt.aloha.util.ConcurrentUpdateException; public class ConferenceInfoDaoImpl extends DaoBase implements ConferenceInfoDao { private static final String NO_CONFERENCE_FOUND_FOR_CALL_S_RETURNING_NULL = "no conference found for call %s, returning null"; private static final String PERCENT = "%"; private static final String INFO_S_ALREADY_EXISTS_IN_DATABASE_USE_REPLACE_DIALOG_INSTEAD = "Info %s already exists in database, use replaceDialog instead"; private static final String COUNT_SQL = "select count(conferenceId) from conferenceInfo"; private static final int V_ID_POS = 3; private static final String COLUMNS = "conferenceId, " + "simpleSipBeanId ," + "createTime ," + "object_version ," + "last_use_time, " + "startTime, " + "endTime, " + "mediaServerAddress, " + "conferenceState, " + "conferenceTerminationCause, " + "maxNumberOfParticipants, " + "maxDurationInMinutes, " + "housekeepingForced, " + "participants"; private static final String UPDATE_SQL = "update conferenceinfo set " + "simpleSipBeanId=?," + "createTime=?," + "object_version=?," + "last_use_time=?," + "startTime=?," + "endTime=?," + "mediaServerAddress=?," + "conferenceState=?," + "conferenceTerminationCause=?," + "maxNumberOfParticipants=?," + "maxDurationInMinutes=?," + "housekeepingForced=?," + "participants=?" + " where conferenceId=? and object_version=?"; private static final String INSERT_SQL = "insert into conferenceInfo (" + COLUMNS + ") " + "values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; private static final String SELECT_COLUMNS = "select " + COLUMNS + " from conferenceInfo"; private static final String SELECT_BY_ID_SQL = SELECT_COLUMNS + " where conferenceId=?"; private static final String SELECT_WHERE_CALL_ID_SQL = SELECT_COLUMNS + " where (participants like ?) and createTime = (select max(createTime) from conferenceInfo where participants like ?)"; private static final String DELETE_SQL = "delete from conferenceinfo where conferenceid = ?"; private static final int[] INSERT_TYPES = new int[] { Types.VARCHAR, Types.VARCHAR, Types.BIGINT, Types.VARCHAR, Types.BIGINT, Types.BIGINT, Types.BIGINT, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.BIGINT, Types.BIGINT, Types.BOOLEAN, Types.CLOB, }; private static final int[] UPDATE_TYPES = new int[] { Types.VARCHAR, Types.BIGINT, Types.VARCHAR, Types.BIGINT, Types.BIGINT, Types.BIGINT, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.BIGINT, Types.BIGINT, Types.BOOLEAN, Types.CLOB, Types.VARCHAR, Types.VARCHAR, }; private static final String CONFERENCEINFO_DELETE_BY_HOUSEKEEPER_FLAGS_SQL = "delete from conferenceinfo where (conferencestate = 'Ended' or housekeepingForced = 'True') and last_use_time < ?"; private static final String CONFERENCEINFO_FIND_BY_HOUSEKEEPER_FLAGS_SQL = "select conferenceId from conferenceinfo where (conferencestate = 'Ended' or housekeepingForced = 'True') and last_use_time < ?"; private static final String CONFERENCEINFO_UPDATE_BY_HOUSEKEEPER_FLAGS_SQL = SELECT_COLUMNS + " where conferencestate != 'Ended' and last_use_time < ?"; private static final String SELECT_CONNECTED_MAX_DURATION_CONFERENCES_SQL = SELECT_COLUMNS + " where conferencestate = 'Active' and maxDurationInMinutes > 0"; private static final String SELECT_ALL_SQL = "select * from conferenceinfo"; private Log log = LogFactory.getLog(ConferenceInfoDaoImpl.class); public ConferenceInfoDaoImpl(DataSource aDataSource) { super(aDataSource); } public void create(final ConferenceInfo conferenceInfo) { log.debug(String.format("create(%s)", conferenceInfo.getId())); try { List<Object> paramList1 = createParams(conferenceInfo); Object[] params1 = paramList1.toArray(); getJdbcTemplate().update(INSERT_SQL, params1, INSERT_TYPES); } catch (DataIntegrityViolationException e) { throw new IllegalArgumentException(String.format( INFO_S_ALREADY_EXISTS_IN_DATABASE_USE_REPLACE_DIALOG_INSTEAD, conferenceInfo.getId()), e); } } private List<Object> createParams(ConferenceInfo conferenceInfo) { List<Object> result = new Vector<Object>(); result.add(conferenceInfo.getId()); result.add(conferenceInfo.getSimpleSipBeanId()); result.add(conferenceInfo.getCreateTime()); result.add(conferenceInfo.getVersionId()); result.add(conferenceInfo.getLastUsedTime()); result.add(conferenceInfo.getStartTime()); result.add(conferenceInfo.getEndTime()); result.add(conferenceInfo.getMediaServerAddress()); result.add(readEnum(conferenceInfo.getConferenceState())); result.add(readEnum(conferenceInfo.getConferenceTerminationCause())); result.add(conferenceInfo.getMaxNumberOfParticipants()); result.add(conferenceInfo.getMaxDurationInMinutes()); result.add(conferenceInfo.isHousekeepForced()); result.add(new SqlLobValue(conferenceInfo.getParticipants().toString())); return result; } private String readEnum(Object e) { if (null == e) return null; return e.toString(); } class ConferenceInfoRowMapper implements RowMapper { public ConferenceInfoRowMapper() { } public Object mapRow(ResultSet rs, int rowNum) throws SQLException { String creatingBeanName = rs.getString("simpleSipBeanId"); String aMediaServerAddress = rs.getString("mediaServerAddress"); int theMaxNumberOfParticipants = rs.getInt("maxNumberOfParticipants"); long theMaxDurationInMinutes = rs.getLong("maxDurationInMinutes"); ConferenceInfo info = new ConferenceInfo(creatingBeanName, aMediaServerAddress, theMaxNumberOfParticipants, theMaxDurationInMinutes); String aConferenceId = rs.getString("conferenceId"); info.setId(aConferenceId); long startTime = rs.getLong("startTime"); info.setStartTime(startTime); String conferenceStateString = rs.getString("conferenceState"); info.updateConferenceState( conferenceStateString == null ? null : ConferenceState.valueOf(conferenceStateString)); info.setVersionId(rs.getString("object_version")); info.setLastUsedTime(rs.getLong("last_use_time")); long createTime = rs.getLong("createTime"); info.setCreateTime(createTime); long endTime = rs.getLong("endTime"); info.setEndTime(endTime); String conferenceTerminationCause = rs.getString("conferenceTerminationCause"); info.setConferenceTerminationCause(conferenceTerminationCause == null ? null : ConferenceTerminationCause.valueOf(conferenceTerminationCause)); String participants = rs.getString("participants"); loadParticipants(info, participants); info.setHousekeepForced(rs.getBoolean("housekeepingForced")); return info; } private void loadParticipants(ConferenceInfo info, final String participants) { log.debug(String.format("loadParticipants(%s, %s)", info, participants)); String p1 = participants.replaceAll(" ", ""); String p2 = p1.startsWith("{") ? p1.substring(1) : p1; String p3 = p2.endsWith("}") ? p2.substring(0, p2.length() - 1) : p2; if (p3.length() < 1) return; String[] participantsArray = p3.split(","); for (String participant : participantsArray) { String[] parts = participant.split("="); info.getParticipants().put(parts[0], ParticipantState.valueOf(parts[1])); } } } public ConferenceInfo read(String callId) { ConferenceInfo conferenceInfo = (ConferenceInfo) getJdbcTemplate().queryForObject(SELECT_BY_ID_SQL, new Object[] { callId }, new ConferenceInfoRowMapper()); return conferenceInfo; } public void delete(String conferenceId) { Object[] params = new Object[] { conferenceId }; int[] types = new int[] { Types.VARCHAR }; getJdbcTemplate().update(DELETE_SQL, params, types); } public void update(final ConferenceInfo conferenceInfo) { List<Object> paramList = createParams(conferenceInfo); // replace version id with new one paramList.set(V_ID_POS, conferenceInfo.generateNewVersionId()); // remove ID paramList.remove(0); // add the ID at the end of the list paramList.add(conferenceInfo.getId()); // add old version ID String oldVersionId = conferenceInfo.getVersionId(); paramList.add(oldVersionId); Object[] params = paramList.toArray(); int rowsUpdated = getJdbcTemplate().update(UPDATE_SQL, params, UPDATE_TYPES); if (1 != rowsUpdated) throw new ConcurrentUpdateException(conferenceInfo.getId(), String.format("Info %s modified in database, try again", conferenceInfo.getId())); } public int size() { return getJdbcTemplate().queryForInt(COUNT_SQL); } @SuppressWarnings("unchecked") public ConferenceInfo findConferenceForCallId(String callId) { log.debug(String.format("findConferenceForCallId(%s)", callId)); if (null == callId) return null; String like = PERCENT + callId + PERCENT; List result = getJdbcTemplate().query(SELECT_WHERE_CALL_ID_SQL, new Object[] { like, like }, new ConferenceInfoRowMapper()); if (result.size() < 1) { log.debug(String.format(NO_CONFERENCE_FOUND_FOR_CALL_S_RETURNING_NULL, callId)); return null; } return (ConferenceInfo) result.get(0); } public ConcurrentMap<String, ConferenceInfo> getAll() { return getSelectedConferences(SELECT_ALL_SQL); } public ConcurrentMap<String, ConferenceInfo> findConnectedMaxDurationConferences() { return getSelectedConferences(SELECT_CONNECTED_MAX_DURATION_CONFERENCES_SQL); } @SuppressWarnings("unchecked") private ConcurrentMap<String, ConferenceInfo> getSelectedConferences(String sql) { ConcurrentMap<String, ConferenceInfo> result = new ConcurrentHashMap<String, ConferenceInfo>(); List records = getJdbcTemplate().query(sql, new ConferenceInfoRowMapper()); for (int i = 0; i < records.size(); i++) { ConferenceInfo conferenceInfo = (ConferenceInfo) records.get(i); result.put(conferenceInfo.getId(), conferenceInfo); } return result; } @Override public String getDeleteByHouseKeeperFlagsSql() { return CONFERENCEINFO_DELETE_BY_HOUSEKEEPER_FLAGS_SQL; } @Override public String getUpdateByHouseKeeperFlagsSql() { return CONFERENCEINFO_UPDATE_BY_HOUSEKEEPER_FLAGS_SQL; } @Override public String getFindByHouseKeeperFlagsSql() { return CONFERENCEINFO_FIND_BY_HOUSEKEEPER_FLAGS_SQL; } }