package db.support; import java.io.File; import java.io.FileInputStream; import java.io.Serializable; import java.text.DateFormat; import java.text.MessageFormat; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.dom4j.Document; import org.dom4j.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import db.Constants; import db.DBBackupRecord; import db.DBBackupRecordService; import db.map.CacheMap; import db.util.ConfigUtils; import db.util.HandleXML; import db.util.IOUtil; import kernel.util.DateUtils; public class DBBackupRecordServiceImpl implements DBBackupRecordService { /** * LOG */ private Logger logger = LoggerFactory.getLogger(DBBackupRecordServiceImpl.class); /** * 备份信息XML存储路径 */ private final static String BACKUP_RECORD_XML_PATH = ConfigUtils.getBackupRecordXMLPath(); /** * 文件锁 */ private ReadWriteLock lock = new ReentrantReadWriteLock(); /** * 备份信息缓存 */ private static CacheMap BKRECORD_CACHE = new CacheMap(); /** * 备份文件保存个数最大限值 */ private static Integer MAX_LIMIT_NUM; /** * 默认备份文件个数最大限值 */ private static Integer DEFAULT_MAX_LIMITNUM = 20; @Override public Integer getMaxLimitNum() { if (MAX_LIMIT_NUM == null) { MAX_LIMIT_NUM = DEFAULT_MAX_LIMITNUM; } return MAX_LIMIT_NUM; } @Override public void setMaxLimitNum(Integer limitNum) { if (limitNum == null) { throw new RuntimeException("database_maxLimitNum_setting_null"); } MAX_LIMIT_NUM = limitNum; lock.writeLock().lock(); FileInputStream fis = null; try { File file = new File(BACKUP_RECORD_XML_PATH); if (!file.exists()) { file.createNewFile(); } fis = new FileInputStream(BACKUP_RECORD_XML_PATH); Document document = HandleXML.getDocument(fis, "DbBackupRecordList"); Element maxLimitNumE = (Element) document.selectSingleNode("/DbBackupRecordList/maxLimitNum"); if (maxLimitNumE == null) { maxLimitNumE = document.getRootElement().addElement("maxLimitNum"); } maxLimitNumE.setText(String.valueOf(MAX_LIMIT_NUM)); HandleXML.writeToXML(document, BACKUP_RECORD_XML_PATH); } catch (Exception e) { logger.error("error", e); } finally { IOUtil.closeQuietly(fis); lock.writeLock().unlock(); } } @Override public Collection findAll() { return BKRECORD_CACHE.values(); } @Override public DBBackupRecord findByUuid(Serializable uuid) { if (uuid == null) { throw new RuntimeException("database_backuprecord_uuid_null"); // throw new FastFailException(MessageFormat.format("database_backuprecord_uuid_null")); } return BKRECORD_CACHE.get(uuid); } @Override public void add(DBBackupRecord record) { if (record == null) { throw new RuntimeException("database_backuprecord_add_null"); // throw new FastFailException(MessageFormat.format("database_backuprecord_add_null")); } lock.writeLock().lock(); FileInputStream fis = null; try { fis = new FileInputStream(BACKUP_RECORD_XML_PATH); Document document = HandleXML.getDocument(fis, "DbBackupRecordList"); Element root = document.getRootElement(); Element recordNode = root.addElement("DbBackupRecord"); String uuid = record.getUuid(); recordNode.addAttribute("uuid", uuid != null ? uuid : ""); Element nameNode = recordNode.addElement("name"); nameNode.setText(record.getName() != null ? record.getName() : ""); Element filePathNode = recordNode.addElement("filePath"); filePathNode.setText(record.getFilePath() != null ? record.getFilePath() : ""); DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT); Element timePathNode = recordNode.addElement("backupTime"); timePathNode.setText(record.getBackupTime() != null ? sdf.format(record.getBackupTime()) : ""); Element fileSizeNode = recordNode.addElement("fileSize"); fileSizeNode.setText(String.valueOf(record.getFileSize())); Element descriptionNode = recordNode.addElement("description"); String description = record.getDescription(); descriptionNode.setText(description == null ? "" : description); // 超过最大限制值,去除旧备份 if (BKRECORD_CACHE.size() >= getMaxLimitNum()) { HandleXML.deleteFirstNode("/DbBackupRecordList/DbBackupRecord", document); } HandleXML.writeToXML(document, BACKUP_RECORD_XML_PATH); } catch (Exception e) { logger.error("error", e); } finally { IOUtil.closeQuietly(fis); lock.writeLock().unlock(); } putBackupRecordCache(record); } @Override public void delete(Serializable uuid) { if (uuid == null) { throw new RuntimeException("database_backuprecord_delete_null"); // throw new FastFailException(MessageFormat.format("database_backuprecord_delete_null")); } DBBackupRecord record = BKRECORD_CACHE.get(uuid); if (record == null) { throw new RuntimeException("database_backuprecord_delete_null"); // throw new FastFailException(MessageFormat.format("database_backuprecord_delete_null")); } // 删除备份文件 File file = new File(record.getFilePath()); if (file.exists()) { if (file.delete()) { String msg = MessageFormat.format("database_backuprecord_delete_file_failed", file.getAbsoluteFile()); throw new RuntimeException(msg); // throw new FastFailException(msg); } } lock.writeLock().lock(); FileInputStream fis = null; try { fis = new FileInputStream(BACKUP_RECORD_XML_PATH); Document document = HandleXML.getDocument(fis, "DbBackupRecordList"); String xpathExpression = "/DbBackupRecordList/DbBackupRecord[@uuid=\"" + uuid + "\"]"; Element ele = (Element) document.selectSingleNode(xpathExpression); if (ele != null) { ele.getParent().remove(ele); } HandleXML.writeToXML(document, BACKUP_RECORD_XML_PATH); } catch (Exception e) { logger.error("error", e); } finally { IOUtil.closeQuietly(fis); lock.writeLock().unlock(); } removeBackupRecordCache(uuid); } @Override public int deleteByIds(Serializable[] ids) { int count = 0; for (Serializable id : ids) { delete(id); count++; } return count; } /** *

Description: 存入缓存

*

Create Time: 2013-2-5

* @author weiminghua * @param record 备份记录 */ private void putBackupRecordCache(DBBackupRecord record) { BKRECORD_CACHE.put(record.getUuid(), record); } /** *

Description: 从缓存中删除数据

*

Create Time: 2013-2-5

* @author weiminghua * @param uuid 备份记录ID */ private void removeBackupRecordCache(Serializable uuid) { BKRECORD_CACHE.remove(uuid); } @Override public void initialize() { lock.readLock().lock(); FileInputStream fis = null; try { File file = new File(BACKUP_RECORD_XML_PATH); if (!file.exists()) { file.createNewFile(); } fis = new FileInputStream(BACKUP_RECORD_XML_PATH); Document document = HandleXML.getDocument(fis, "DbBackupRecordList"); Element maxLimitNumE = (Element) document.selectSingleNode("/DbBackupRecordList/maxLimitNum"); if (maxLimitNumE != null) { MAX_LIMIT_NUM = Integer.parseInt(maxLimitNumE.getText()); } // 读取已有备份信息 List list = document.selectNodes("/DbBackupRecordList/DbBackupRecord"); Iterator iter = list.iterator(); DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT); while (iter.hasNext()) { Element e = (Element) iter.next(); DBBackupRecord record = new DBBackupRecord(); record.setUuid(e.attribute("uuid").getValue()); Element nameE = e.element("name"); if (nameE != null) { record.setName(nameE.getText()); } Element backupTimeE = e.element("backupTime"); if (backupTimeE != null) { record.setBackupTime(sdf.parse(backupTimeE.getText())); } Element filePathE = e.element("filePath"); if (filePathE != null) { record.setFilePath(filePathE.getText()); } Element fileSizeE = e.element("fileSize"); if (fileSizeE != null) { record.setFileSize(Long.valueOf(fileSizeE.getText())); } Element descriptionE = e.element("description"); if (descriptionE != null) { record.setDescription(descriptionE.getText()); } putBackupRecordCache(record); // 加入缓存 } } catch (Exception e) { logger.error("error", e); } finally { IOUtil.closeQuietly(fis); lock.readLock().unlock(); } } }