view src/main/java/de/mpiwg/gazetteer/utils/DataProvider.java @ 49:7c2e1b14b77d

new: load existing full text searching result into searching table
author Zoe Hong <zhong@mpiwg-berlin.mpg.de>
date Tue, 26 Jan 2016 11:46:10 +0100
parents 13555aff1f88
children a00efd5d9e77
line wrap: on
line source

package de.mpiwg.gazetteer.utils;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Session;

import cl.maps.duplex.DuplexKey;
import de.mpiwg.gazetteer.bo.LGBranch;
import de.mpiwg.gazetteer.bo.LGFile;
import de.mpiwg.gazetteer.bo.LGFullTextSearchFile;
import de.mpiwg.gazetteer.bo.LGTopic;
import de.mpiwg.gazetteer.bo.LGTopicSectionRelation;
import de.mpiwg.gazetteer.db.DBContents;
import de.mpiwg.gazetteer.db.DBSection;
import de.mpiwg.gazetteer.utils.exceptions.NoAuthorizedException;
import de.mpiwg.gazetteer.utils.exceptions.VersioningException;

public class DataProvider extends AbstractDataProvider{
	
	private static Logger logger = Logger.getLogger(DataProvider.class);
	private static DataProvider instance;
	
	public static DataProvider getInstance(){
		if(instance == null)
			instance = new DataProvider();
		return instance;
	}
	
	public static void resetInstance() {
		instance = null;
	}
	
	public DataProvider(){
		logger.info("##### Starting DataProvider #####");
	}
	
	

	/* --- branch --- */
	
	public LGFile getFile(Long fileId){
		return getFileMap().getValuesByOwnKey(fileId);
	}
	
	public List<LGFile> getAllFiles(Long branchId){
		List<LGFile> list = getFileMap().getValuesByAKey(branchId);
		Collections.sort(list);
		Collections.reverse(list);
		return list;
	}
	
	public List<LGTopicSectionRelation> getAllExistingTopicSectionRelation() {
		List<LGTopicSectionRelation> list = new ArrayList<LGTopicSectionRelation>();
		for (LGTopicSectionRelation relation : getTopicSectionRelationMap().values()) {
			list.add(relation);
		}
		return list;
	}
	
	public List<LGBranch> getAllExistingBranches(){
		List<LGBranch> list = new ArrayList<LGBranch>();
		for(LGBranch branch : getBranchMap().values()){	
			list.add(branch);
		}
		return list;
	}
	
	public List<LGBranch> getBranches(Long userId){
		List<LGBranch> list = new ArrayList<LGBranch>();
		for(LGBranch branch : getBranchMap().values()){
			if(branch.hasContributor(userId)){
				list.add(branch);
			}
		}
		return list;
	}
	
	
	public LGBranch getBranch(Long branchId){
		return getBranchMap().getValuesByOwnKey(branchId);
	}
	
	public void deleteFile(LGFile file) throws Exception{
	
		LGBranch branch = getBranch(file.getBranchId());
		
		if(branch == null){
			throw new Exception("There is any Branch for " + file);
		}
		
		List<LGFile> files = getAllFiles(file.getBranchId());
		
		if(files.size() == 1){
			throw new Exception("This file could not be deleted, because it is part of a branch that has only one file. A Branch without files is a inconsistency.");
		}
		
		// if the file is the last version of a branch, we must replace the current file with the penultimate file.
		if(branch.getCurrentLastFileId().equals(file.getId())){
			LGFile penultimateFile = getPenultimateFile(files);
			
			penultimateFile.setLastVersion(true);
			branch.setCurrentLastFileId(penultimateFile.getId());
			
			this.updateBranch(branch);
			this.updateFile(penultimateFile);
			
		}
		
		//deleting file from DB and cache
		int modifiedFiles = DBService.deleteFileFromDB(file.getId());
		getFileMap().remove(file.getKey());
		
		logger.info(modifiedFiles + " items deleted by removing file " + file);
	}
	
	private LGFile getPenultimateFile(List<LGFile> files){
		LGFile penultimateFile = null;
		LGFile lastFile = null;
		
		for(LGFile file : files){
			if(lastFile == null){
				lastFile = file;
			}else if(penultimateFile == null){
				lastFile = (lastFile.getVersion() > file.getVersion()) ? lastFile : file;
				penultimateFile = (lastFile.getVersion() < file.getVersion()) ? lastFile : file;
			}else{
				if(file.getVersion() > lastFile.getVersion()){
					penultimateFile = lastFile;
					lastFile = file;
				}else if(file.getVersion() > penultimateFile.getVersion()){
					penultimateFile = file;
				}
			}
		}
		
		return penultimateFile;
	}
	
	public void deleteBranch(LGBranch branch){
		
		int modifiedFiles = DBService.deleteBranchFromDB(branch.getId());
		List<LGFile> fileToDelete = getFileMap().getValuesByAKey(branch.getId());
		
		for(LGFile file : new ArrayList<LGFile>(fileToDelete)){
			getFileMap().remove(file.getKey());
		}
		getBranchMap().remove(branch.getKey());

		logger.info(modifiedFiles + " items deleted by removing branch " + branch.toString());
	}
	
	public void updateFile(LGFile file) throws Exception{
		if(!file.isPersistent()){
			throw new Exception("Trying to update a file that it is not persistent!");
		}
		
		Date date = new Date();
		DBService.saveDBEntry(file, date);
		this.getFileMap().put(file.getKey(), file);
	}
	
	public void updateBranch(LGBranch branch) throws Exception{
		if(!branch.isPersistent()){
			throw new Exception("Trying to update a branch that it is not persistent!");
		}
		
		Date date = new Date();
		DBService.saveDBEntry(branch, date);
		this.getBranchMap().put(branch.getKey(), branch);
	}
	
	public LGFile saveFile(Long branchId, String text, Long userId, Long userPreviousFileId) throws Exception{
		
		
		
		Date date = new Date();
		
		LGBranch branch = getBranchMap().getValuesByOwnKey(branchId);
		
		if(!branch.hasContributor(userId)){
			throw new NoAuthorizedException(userId, branchId);
		}
		
		if(!branch.getCurrentLastFileId().equals(userPreviousFileId)){
			LGFile userPreviousFile = getFileMap().getValuesByOwnKey(userPreviousFileId);
			LGFile currentLastFile = getFileMap().getValuesByOwnKey(branch.getCurrentLastFileId());
			
			throw new VersioningException(userPreviousFile, currentLastFile);
		}
		
		LGFile previousFile = getFileMap().getValuesByOwnKey(branch.getCurrentLastFileId());
		
		LGFile file = new LGFile();
		file.setBranchId(branchId);
		file.setVersion(previousFile.getVersion() + 1);
		file.setUserId(userId);
		file.setContent(text);
		
		//Saving into DB
		//##################################
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();
		
		
		file.setBranchId(branch.getId());
		DBService.saveDBEntry0(session, file, date);
		
		previousFile.setLastVersion(false);
		DBService.saveDBEntry0(session, previousFile, date);
		
		branch.setCurrentLastFileId(file.getId());
		DBService.saveDBEntry0(session, branch, date);
		
		//Saving physical file in the operating system
		String fileName = FileManager.saveFile(branch, file, date, userId);
		file.setFileName(fileName);
		DBService.saveDBEntry0(session, file, date);
		
		session.getTransaction().commit();
		//##################################
		
		
		//Saving into Cache
		getBranchMap().put(branch.getKey(), branch);
		getFileMap().put(file.getKey(), file);
		getFileMap().put(previousFile.getKey(), previousFile);
		
		return file;
	}
	
	public Long saveNewFile(String text, String label, Long sectionId, Long userId) throws Exception{
		
		Date date = new Date();
		
		LGBranch branch = new LGBranch();				
		branch.setSectionId(sectionId);
		branch.setUserId(userId);
		branch.setLabel(label);
		branch.addContributor(userId);
		branch.loadTransientData();
		
		LGFile file = new LGFile();
		file.setUserId(userId);
		file.setContent(text);
		
		//Saving into DB
		//##################################
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();
		
		DBService.saveDBEntry0(session, branch, date);
		file.setBranchId(branch.getId());
		
		DBService.saveDBEntry0(session, file, date);
		branch.setCurrentLastFileId(file.getId());

		//Saving physical file in the operating system
		String fileName = FileManager.saveFile(branch, file, date, userId);
		file.setFileName(fileName);
		DBService.saveDBEntry0(session, file, date);
		
		session.getTransaction().commit();
		//##################################
		
		
		//Saving into Cache
		getBranchMap().put(branch.getKey(), branch);
		getFileMap().put(file.getKey(), file);
		
		return branch.getId();
		
	}

	/* --- end branch --- */
	
	
	
	/* --- full text search --- */
	
	public List<LGFullTextSearchFile> getSearchFileList4User(Long userId) {
	
		List<LGFullTextSearchFile> list = new ArrayList<LGFullTextSearchFile>();
		
		for(LGFullTextSearchFile searchFile : getFullTextSearchFileMap().values()){
			if(searchFile.getUserId() == userId){
				list.add(searchFile);
			}
		}
		
		return list;
	}

	
	public LGFullTextSearchFile saveLGFullTextSearchFile(List<DBContents> list, Long userId, LGFullTextSearchFile searchFile) throws Exception {	
		// save as csv and html file in filesystem, and records in db `FullTextSearchFile
		// List<DBContents> list is the filteredList of searching result with isRemoved field
	
		Date date = new Date();
		
		//Saving into DB
		//##################################
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();
		
		DBService.saveDBEntry0(session, searchFile, date);
		
		//Saving physical file in the operating system
		FileManager.saveFullTextSearchFileAsCsv(searchFile, userId, list);	// save csv file to LGMap's datasets folder
		FileManager.saveFullTextSearchFileAsHtml(searchFile, userId, list);	// save html file to LGMap's datasets folder
		
		session.getTransaction().commit();
		//##################################
		
		return searchFile;
	}

	public LGFullTextSearchFile getFullTextSearchFile(Long fileId) {

		LGFullTextSearchFile file = getFullTextSearchFileMap().getValuesByOwnKey(fileId);
		
		return file;
	}

	/* --- end full text search --- */

	/* --- topic --- */
	
	public List<LGTopic> getTopics(Long userId){
		List<LGTopic> list = new ArrayList<LGTopic>();
		for(LGTopic topic : getTopicMap().values()){
			/*
			if(topic.hasContributor(userId)){
				list.add(topic);
			}
			*/
			
			// add topic into list anyway, without checking the contributor role.
			list.add(topic);
		}
		
		return list;
	}
	
	public LGTopic getTopic(Long topicId){
		return getTopicMap().getValuesByOwnKey(topicId);
	}
	
	
	public void deleteTopic(LGTopic topic){
			
		int modifiedRelation = DBService.deleteTopicFromDB(topic.getId());
		getTopicMap().remove(topic.getKey());
		
		logger.info("removing " + modifiedRelation + " records in topicSectionRelation of topic " + topic.toString());
		
		this.setTopicSectionRelationMap(null);	// clear topicSectionRelationMap cache
		

	}

	public void createTopic(String nameEn, String nameCh,String namePinyin, String description, Long userId) {
		Date date = new Date();
		
		LGTopic topic = new LGTopic();
		topic.setNameEn(nameEn);
		topic.setNameCh(nameCh);
		topic.setNamePinyin(namePinyin);
		topic.setDescription(description);
		topic.setUserId(userId);
		topic.setContributors("[" + userId.toString() + "]");
		
		//Saving into DB
		//##################################
		// For Topic table
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();
		
		DBService.saveDBEntry0(session, topic, date);
			
		session.getTransaction().commit();
		//##################################
		
	}

	public void updateTopic(LGTopic topic) throws Exception {
		if(!topic.isPersistent()){
			throw new Exception("Trying to update a topic that it is not persistent!");
		}
		
		Date date = new Date();
		DBService.saveDBEntry(topic, date);
		this.getTopicMap().put(topic.getKey(), topic);
		
	}
	
	
	
	public List<DBSection> getAllSectionsInTopic(Long topicId) throws SQLException{
		
		List<LGTopicSectionRelation> topicSectionRelationList = getTopicSectionRelationMap().getValuesByAKey(topicId);

		// get sections from topicSecionRelation list
		List<DBSection> list = new ArrayList<DBSection>();
		for (LGTopicSectionRelation aRelation : topicSectionRelationList) {
			//logger.debug(aRelation.getInfo() );
			
			DBSection section = DBService.getSectionWithContent(aRelation.getSectionId());
			list.add(section);
			
		}
		
		
		Collections.sort(list);
		Collections.reverse(list);
		return list;
	}




	public void deleteTopicSectionRelation(Long topicId, String bookId) throws Exception{
		// delete record with topicId, bookId in topicSectionRelation
		// this means the sectionId = 0, there is no corresponding section in the book for this topic
		
		// TODO
		
	}

	public void deleteTopicSectionRelation(Long topicId, Long sectionId) throws Exception{
		if (sectionId == 0) {
			throw new Exception("sectionId cannot be 0");
		}
		
		DuplexKey<Long, Long> key = new DuplexKey<Long, Long>(topicId, sectionId);
		LGTopicSectionRelation topicSectionRelation = this.getTopicSectionRelationMap().get(key);

		LGTopic topic = getTopic(topicId);
		
		if(topic == null){
			throw new Exception("There is no topic of " + topicSectionRelation);
		}
		
		//deleting topicSectionRelation from DB and cache
		int modifiedRelation = DBService.deleteTopicSectionRelationFromDB(topicSectionRelation.getId());
		getTopicSectionRelationMap().remove(topicSectionRelation.getKey());
		
		logger.info(modifiedRelation + " items deleted by removing topicSectionRelation " + topicSectionRelation.toString());

		
	}

	public String updateTopicSectionRelation(Long sectionId, Long topicId) throws Exception {
		DuplexKey<Long, Long> key = new DuplexKey<Long, Long>(topicId, sectionId);
		LGTopicSectionRelation topicSectionRelation = this.getTopicSectionRelationMap().get(key);

		if (topicSectionRelation != null) {
			// the relation already existed
			// would this possibly need any modification to the existing record in the topicSectionRelation table?
			
			return "updated";
			
		} else {
			createTopicSectionRelation(sectionId, topicId);

			return "added";
		}
		
	
		
	}
	
	
	public void createTopicSectionRelation(Long sectionId, Long topicId) throws Exception {
		
		Date date = new Date();
		
		LGTopicSectionRelation topicSectionRelation = new LGTopicSectionRelation();
		topicSectionRelation.setTopicId(topicId);
		topicSectionRelation.setSectionId(sectionId);
		
		DBService.getInstance();
		DBSection section = DBService.getSectionWithContent(sectionId);
		topicSectionRelation.setBookId(section.getBookId());
		
		//Saving into DB
		//##################################
		// For Topic table
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();
		
		DBService.saveDBEntry0(session, topicSectionRelation, date);
			
		session.getTransaction().commit();
		//##################################
		
		// update cache
		this.loadTopicSectionRelations();
	
	}

	public Integer getNumberOfSectionInTopic(Long topicId) {
		List<LGTopicSectionRelation> topicSectionRelationList = getTopicSectionRelationMap().getValuesByAKey(topicId);
	
		return topicSectionRelationList.size();
	}

	
	
	/* --- end topic --- */
	
}