001/** 002 * Copyright 2014 Tampere University of Technology, Pori Department 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package service.tut.pori.fileservice; 017 018 019import java.util.ArrayList; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023import java.util.Map.Entry; 024 025import org.apache.commons.lang3.ArrayUtils; 026import org.apache.log4j.Logger; 027import org.springframework.jdbc.core.simple.SimpleJdbcInsert; 028 029import core.tut.pori.dao.clause.AndClause; 030import core.tut.pori.dao.clause.SQLClause.SQLType; 031import core.tut.pori.dao.SQLDAO; 032import core.tut.pori.dao.SQLDeleteBuilder; 033import core.tut.pori.dao.SQLSelectBuilder; 034import core.tut.pori.http.parameters.Limits; 035import core.tut.pori.users.UserIdentity; 036 037/** 038 * DAO for saving, retrieving and modifying the details of saved files. 039 */ 040public class FileDAO extends SQLDAO { 041 private static final Logger LOGGER = Logger.getLogger(FileDAO.class); 042 /* tables */ 043 private static final String TABLE_FILES = DATABASE+".fs_files"; 044 /* columns */ 045 private static final String COLUMN_FILE_ID = "file_id"; 046 private static final String COLUMN_ORIGINAL_NAME = "original_name"; 047 private static final String COLUMN_SAVED_NAME = "saved_name"; 048 /* sql scripts */ 049 private static final String[] COLUMNS_GET_FILES = {COLUMN_FILE_ID, COLUMN_ORIGINAL_NAME, COLUMN_SAVED_NAME, COLUMN_USER_ID}; 050 private static final String[] COLUMNS_SAVE_FILE = {COLUMN_ORIGINAL_NAME, COLUMN_SAVED_NAME, COLUMN_USER_ID}; 051 052 private static final String SQL_DELETE_FILES_FOR_USER = "DELETE FROM "+TABLE_FILES+" WHERE "+COLUMN_USER_ID+"=?"; 053 private static final int[] SQL_DELETE_FILES_FOR_USER_SQL_TYPES = {SQLType.LONG.toInt()}; 054 055 /** 056 * 057 * @param file 058 */ 059 public void save(File file) { 060 SimpleJdbcInsert insert = new SimpleJdbcInsert(getJdbcTemplate()); 061 insert.withTableName(TABLE_FILES); 062 insert.withoutTableColumnMetaDataAccess(); 063 insert.usingColumns(COLUMNS_SAVE_FILE); 064 insert.setGeneratedKeyName(COLUMN_FILE_ID); 065 066 Map<String, Object> values = new HashMap<>(COLUMNS_SAVE_FILE.length); 067 values.put(COLUMN_ORIGINAL_NAME, file.getName()); 068 values.put(COLUMN_SAVED_NAME, file.getSavedName()); 069 values.put(COLUMN_USER_ID, file.getUserId().getUserId()); 070 file.setFileId((Long) insert.executeAndReturnKey(values)); 071 } 072 073 /** 074 * 075 * @param authenticatedUser 076 * @param fileIds if null or empty, all files for the given user will be deleted 077 * @return list of deleted files or null if nothing was deleted 078 */ 079 public FileList delete(UserIdentity authenticatedUser, long[] fileIds) { 080 FileList files = getFiles(authenticatedUser, fileIds, null); 081 if(FileList.isEmpty(files)){ 082 LOGGER.debug("No files found."); 083 return null; 084 } 085 086 if(ArrayUtils.isEmpty(fileIds)){ 087 Object[] ob = new Object[]{authenticatedUser.getUserId()}; 088 LOGGER.debug("Removed "+getJdbcTemplate().update(SQL_DELETE_FILES_FOR_USER, ob, SQL_DELETE_FILES_FOR_USER_SQL_TYPES)+" files for user, id: "+ob[0]); 089 }else{ 090 List<File> fileList = files.getFiles(); 091 List<Long> fileIdList = new ArrayList<>(fileList.size()); 092 for(File file : fileList){ 093 fileIdList.add(file.getFileId()); 094 } 095 SQLDeleteBuilder sql = new SQLDeleteBuilder(TABLE_FILES); 096 sql.addWhereClause(new AndClause(COLUMN_FILE_ID, fileIdList, SQLType.LONG)); 097 LOGGER.debug("Removed "+sql.execute(getJdbcTemplate())+" files for user, id: "+authenticatedUser.getUserId()); 098 } 099 return files; 100 } 101 102 /** 103 * 104 * @param authenticatedUser 105 * @param fileIds if null or empty, or users files will be returned 106 * @param limits optional limits parameter, if missing, all files will be returned 107 * @return list of files or null if none found 108 */ 109 public FileList getFiles(UserIdentity authenticatedUser, long[] fileIds, Limits limits) { 110 SQLSelectBuilder sql = new SQLSelectBuilder(TABLE_FILES); 111 sql.addSelectColumns(COLUMNS_GET_FILES); 112 sql.addWhereClause(new AndClause(COLUMN_USER_ID, authenticatedUser.getUserId(), SQLType.LONG)); 113 if(!ArrayUtils.isEmpty(fileIds)){ 114 LOGGER.debug("Adding file id filter."); 115 sql.addWhereClause(new AndClause(COLUMN_FILE_ID, fileIds)); 116 } 117 sql.setLimits(limits); 118 List<Map<String, Object>> rows = getJdbcTemplate().queryForList(sql.toSQLString(), sql.getValues(), sql.getValueTypes()); 119 if(rows.isEmpty()){ 120 LOGGER.debug("No files found."); 121 return null; 122 } 123 124 List<File> files = new ArrayList<>(rows.size()); 125 for(Map<String, Object> row : rows){ 126 files.add(extractFile(row)); 127 } 128 129 return FileList.getFileList(files); 130 } 131 132 /** 133 * 134 * @param row 135 * @return file extracted from the given row map 136 */ 137 private File extractFile(Map<String, Object> row){ 138 File file = new File(); 139 for(Entry<String, Object> e : row.entrySet()){ 140 switch(e.getKey()){ 141 case COLUMN_FILE_ID: 142 file.setFileId((Long) e.getValue()); 143 break; 144 case COLUMN_ORIGINAL_NAME: 145 file.setName((String) e.getValue()); 146 break; 147 case COLUMN_SAVED_NAME: 148 file.setSavedName((String) e.getValue()); 149 break; 150 case COLUMN_USER_ID: 151 file.setUserId(new UserIdentity((Long) e.getValue())); 152 break; 153 default: 154 LOGGER.warn("Ignored unknown column: "+e.getKey()); 155 break; 156 } // switch 157 } 158 return file; 159 } 160}