/** * Axelor Business Solutions * * Copyright (C) 2016 Axelor (<http://axelor.com>). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.axelor.apps; import static com.axelor.common.StringUtils.isBlank; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import javax.persistence.PersistenceException; import com.axelor.app.AppSettings; import com.axelor.apps.base.service.administration.GeneralService; import com.axelor.db.Model; import com.axelor.inject.Beans; import com.axelor.meta.db.MetaAttachment; import com.axelor.meta.db.MetaFile; import com.axelor.meta.db.repo.MetaFileRepository; import com.google.common.base.Preconditions; import com.google.inject.Inject; import com.google.inject.persist.Transactional; public class MetaFilesTemp { @Inject protected GeneralService generalService; private static final String DEFAULT_UPLOAD_PATH = "{java.io.tmpdir}/axelor/attachments"; private static final String UPLOAD_PATH = AppSettings.get().getPath("file.upload.dir", DEFAULT_UPLOAD_PATH); public MetaFilesTemp() { } /** * Upload the given file to the file upload directory and create an instance * of {@link MetaFile} for the given file. * * @param file * the given file * @return an instance of {@link MetaFile} * @throws IOException * if unable to read the file * @throws PersistenceException * if unable to save to a {@link MetaFile} instance */ @Transactional public MetaFile upload(File file) throws IOException { return upload(file, new MetaFile()); } /** * Upload the given {@link File} to the upload directory and link it to the * to given {@link MetaFile}. * * <p> * Any existing file linked to the given {@link MetaFile} will be removed * from the upload directory. * </p> * * @param file * the file to upload * @param metaFile * the target {@link MetaFile} instance * @return persisted {@link MetaFile} instance * @throws IOException * if unable to read the file * @throws PersistenceException * if unable to save to {@link MetaFile} instance */ @Transactional public MetaFile upload(File file, MetaFile metaFile) throws IOException { Preconditions.checkNotNull(metaFile); Preconditions.checkNotNull(file); final boolean update = !isBlank(metaFile.getFilePath()); final String targetName = update ? metaFile.getFilePath() : file.getName(); final Path path = Paths.get(UPLOAD_PATH, targetName); final Path tmp = update ? Files.createTempFile(null, null) : null; if (update && Files.exists(path)) { Files.move(path, tmp, StandardCopyOption.REPLACE_EXISTING); } try { // make sure the upload path exists Files.createDirectories(Paths.get(UPLOAD_PATH)); final String mime = Files.probeContentType(file.toPath()); metaFile.setFileName(file.getName()); metaFile.setFileType(mime); metaFile.setFileSize(Files.size(file.toPath())); metaFile.setFilePath(file.getPath()); final MetaFileRepository repo = Beans.get(MetaFileRepository.class); try { return repo.save(metaFile); } catch (Exception e) { // delete the uploaded file throw new PersistenceException(e); } } finally { if (tmp != null) { Files.deleteIfExists(tmp); } } } private Path getNextPath(String fileName) { int dotIndex = fileName.lastIndexOf('.'); int counter = 1; String fileNameBase = fileName.substring(0, dotIndex); String fileNameExt = ""; if (dotIndex > -1) { fileNameExt = fileName.substring(dotIndex); } String targetName = fileName; Path target = Paths.get(UPLOAD_PATH, targetName); while (Files.exists(target)) { targetName = fileNameBase + " (" + counter++ + ")" + fileNameExt; target = Paths.get(UPLOAD_PATH, targetName); } return target; } /** * Attach the given {@link MetaFile} to the given {@link Model} object and * return an instance of a {@link MetaAttachment} that represents the * attachment. * <p> * The {@link MetaAttachment} instance is not persisted. * </p> * * @param file * the given {@link MetaFile} instance * @param entity * the given {@link Model} instance * @return a new instance of {@link MetaAttachment} */ public MetaAttachment attach(MetaFile file, Model entity) { Preconditions.checkNotNull(file); Preconditions.checkNotNull(entity); Preconditions.checkNotNull(entity.getId()); MetaAttachment attachment = new MetaAttachment(); attachment.setMetaFile(file); attachment.setObjectId(entity.getId()); attachment.setObjectName(generalService.getPersistentClass(entity).getCanonicalName()); return attachment; } }