/* * Copyright 2015-Present Entando S.r.l. (http://www.entando.com) 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 2.1 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. */ package org.entando.entando.aps.system.services.storage; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.agiletec.aps.system.exception.ApsSystemException; import java.util.Arrays; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.CharEncoding; /** * @author E.Santoboni */ public class LocalStorageManager implements IStorageManager { private static final Logger _logger = LoggerFactory.getLogger(LocalStorageManager.class); public void init() throws Exception { _logger.debug("{} ready", this.getClass().getName()); } @Override public void saveFile(String subPath, boolean isProtectedResource, InputStream is) throws ApsSystemException { subPath = (null == subPath)? "" : subPath; String fullPath = this.createFullPath(subPath, isProtectedResource); try { File dir = new File(fullPath).getParentFile(); if (!dir.exists()) { dir.mkdirs(); } byte[] buffer = new byte[1024]; int length = -1; FileOutputStream outStream = new FileOutputStream(fullPath); while ((length = is.read(buffer)) != -1) { outStream.write(buffer, 0, length); outStream.flush(); } outStream.close(); is.close(); } catch (Throwable t) { _logger.error("Error on saving file", t); throw new ApsSystemException("Error on saving file", t); } } @Override public boolean deleteFile(String subPath, boolean isProtectedResource) throws ApsSystemException { subPath = (null == subPath)? "" : subPath; String fullPath = this.createFullPath(subPath, isProtectedResource); File file = new File(fullPath); if (file.exists()) { return file.delete(); } return false; } @Override public void createDirectory(String subPath, boolean isProtectedResource) throws ApsSystemException { subPath = (null == subPath)? "" : subPath; String fullPath = this.createFullPath(subPath, isProtectedResource); File dir = new File(fullPath); if (!dir.exists() || !dir.isDirectory()) { dir.mkdirs(); } } @Override public void deleteDirectory(String subPath, boolean isProtectedResource) throws ApsSystemException { subPath = (null == subPath)? "" : subPath; String fullPath = this.createFullPath(subPath, isProtectedResource); File dir = new File(fullPath); this.delete(dir); } private boolean delete(File file) throws ApsSystemException { if (file.exists()) { if (file.isDirectory()) { String[] filesName = file.list(); for (int i = 0; i < filesName.length; i++) { File fileToDelete = new File(file.getAbsoluteFile() + File.separator + filesName[i]); this.delete(fileToDelete); } file.delete(); } else { return file.delete(); } } return false; } @Override public InputStream getStream(String subPath, boolean isProtectedResource) throws ApsSystemException { try { subPath = (null == subPath)? "" : subPath; String fullPath = this.createFullPath(subPath, isProtectedResource); File file = new File(fullPath); if (file.exists() && !file.isDirectory()) { return new FileInputStream(file); } } catch (Throwable t) { _logger.error("Error extracting stream", t); throw new ApsSystemException("Error extracting stream", t); } return null; } @Override public boolean exists(String subPath, boolean isProtectedResource) throws ApsSystemException { File file = this.getFile(subPath, isProtectedResource); return file.exists(); } protected File getFile(String subPath, boolean isProtectedResource) throws ApsSystemException { subPath = (null == subPath)? "" : subPath; String fullPath = this.createFullPath(subPath, isProtectedResource); return new File(fullPath); } @Override public String getResourceUrl(String subPath, boolean isProtectedResource) { subPath = (null == subPath)? "" : subPath; String baseUrl = (!isProtectedResource) ? this.getBaseURL() : this.getProtectedBaseURL(); return this.createPath(baseUrl, subPath, true); } @Override public String readFile(String subPath, boolean isProtectedResource) throws ApsSystemException { subPath = (null == subPath)? "" : subPath; String fullPath = this.createFullPath(subPath, isProtectedResource); File file = new File(fullPath); try { return FileUtils.readFileToString(file, CharEncoding.UTF_8); } catch (Throwable t) { _logger.error("Error reading File with path {}", subPath, t); throw new ApsSystemException("Error reading file", t); } } @Override public void editFile(String subPath, boolean isProtectedResource, InputStream is) throws ApsSystemException { subPath = (null == subPath)? "" : subPath; String fullPath = this.createFullPath(subPath, isProtectedResource); String tempFilePath = null; try { File oldFile = new File(fullPath); if (oldFile.exists()) { String tempDir = System.getProperty("java.io.tmpdir"); tempFilePath = tempDir + File.separator + subPath; FileUtils.moveFile(oldFile, new File(tempFilePath)); } this.saveFile(subPath, isProtectedResource, is); } catch (Throwable t) { try { if (null != tempFilePath) { FileUtils.moveFile(new File(tempFilePath), new File(fullPath)); } } catch (Throwable tr) { _logger.error("Error restoring File from path {} to path", tempFilePath, fullPath, tr); } _logger.error("Error writing File with path {}", subPath, t); throw new ApsSystemException("Error editing file", t); } finally { if (null != tempFilePath) { new File(tempFilePath).delete(); } } } @Override public String[] list(String subPath, boolean isProtectedResource) throws ApsSystemException { return this.list(subPath, isProtectedResource, null); } @Override public String[] listDirectory(String subPath, boolean isProtectedResource) throws ApsSystemException { return this.list(subPath, isProtectedResource, true); } @Override public String[] listFile(String subPath, boolean isProtectedResource) throws ApsSystemException { return this.list(subPath, isProtectedResource, false); } private String[] list(String subPath, boolean isProtectedResource, Boolean searchDirectory) throws ApsSystemException { subPath = (null == subPath)? "" : subPath; String fullPath = this.createFullPath(subPath, isProtectedResource); File directory = new File(fullPath); if (directory.exists() && directory.isDirectory()) { String[] objects = new String[]{}; String folder = fullPath; if (!folder.endsWith("/")) { folder += "/"; } String[] contents = directory.list(); if (null == searchDirectory) { objects = contents; } else { for (int i = 0; i < contents.length; i++) { String string = contents[i]; File file = new File(folder + string); if ((file.isDirectory() && searchDirectory) || (!file.isDirectory() && !searchDirectory)) { objects = this.addChild(string, objects); } } } Arrays.sort(objects); return objects; } return null; } protected String[] addChild(String stringToAdd, String[] objects) { int len = objects.length; String[] newArray = new String[len + 1]; for (int i = 0; i < len; i++) { newArray[i] = objects[i]; } newArray[len] = stringToAdd; return newArray; } private String createFullPath(String subPath, boolean isProtectedResource) { subPath = (null == subPath)? "" : subPath; String diskRoot = (!isProtectedResource) ? this.getBaseDiskRoot() : this.getProtectedBaseDiskRoot(); return this.createPath(diskRoot, subPath, false); } private String createPath(String basePath, String subPath, boolean isUrlPath) { subPath = (null == subPath)? "" : subPath; String separator = (isUrlPath) ? "/" : File.separator; boolean baseEndWithSlash = basePath.endsWith(separator); boolean subPathStartWithSlash = subPath.startsWith(separator); if ((baseEndWithSlash && !subPathStartWithSlash) || (!baseEndWithSlash && subPathStartWithSlash)) { return basePath + subPath; } else if (!baseEndWithSlash && !subPathStartWithSlash) { return basePath + separator + subPath; } else { String base = basePath.substring(0, basePath.length() - File.separator.length()); return base + subPath; } } @Override public BasicFileAttributeView[] listAttributes(String subPath, boolean isProtectedResource) throws ApsSystemException { return this.listAttributes(subPath, isProtectedResource, null); } @Override public BasicFileAttributeView[] listDirectoryAttributes(String subPath, boolean isProtectedResource) throws ApsSystemException { return this.listAttributes(subPath, isProtectedResource, true); } @Override public BasicFileAttributeView[] listFileAttributes(String subPath, boolean isProtectedResource) throws ApsSystemException { return this.listAttributes(subPath, isProtectedResource, false); } private BasicFileAttributeView[] listAttributes(String subPath, boolean isProtectedResource, Boolean searchDirectory) throws ApsSystemException { subPath = (null == subPath)? "" : subPath; String fullPath = this.createFullPath(subPath, isProtectedResource); File directory = new File(fullPath); if (directory.exists() && directory.isDirectory()) { BasicFileAttributeView[] objects = new BasicFileAttributeView[]{}; String folder = fullPath; if (!folder.endsWith("/")) { folder += "/"; } String[] contents = directory.list(); for (int i = 0; i < contents.length; i++) { String string = contents[i]; File file = new File(folder + string); if (null == searchDirectory || (file.isDirectory() && searchDirectory) || (!file.isDirectory() && !searchDirectory)) { BasicFileAttributeView bfav = new BasicFileAttributeView(file); objects = this.addChild(bfav, objects); } } Arrays.sort(objects); return objects; } return null; } protected BasicFileAttributeView[] addChild(BasicFileAttributeView elementToAdd, BasicFileAttributeView[] objects) { int len = objects.length; BasicFileAttributeView[] newArray = new BasicFileAttributeView[len + 1]; for (int i = 0; i < len; i++) { newArray[i] = objects[i]; } newArray[len] = elementToAdd; return newArray; } @Override public BasicFileAttributeView getAttributes(String subPath, boolean isProtectedResource) throws ApsSystemException { File file = this.getFile(subPath, isProtectedResource); if (!file.exists()) { return null; } else { return new BasicFileAttributeView(file); } } protected String getBaseURL() { return _baseURL; } public void setBaseURL(String baseURL) { this._baseURL = baseURL; } protected String getBaseDiskRoot() { return _baseDiskRoot; } public void setBaseDiskRoot(String baseDiskRoot) { this._baseDiskRoot = baseDiskRoot; } protected String getProtectedBaseDiskRoot() { return _protectedBaseDiskRoot; } public void setProtectedBaseDiskRoot(String protBaseDiskRoot) { this._protectedBaseDiskRoot = protBaseDiskRoot; } protected String getProtectedBaseURL() { return _protectedBaseURL; } public void setProtectedBaseURL(String protBaseURL) { this._protectedBaseURL = protBaseURL; } public void setAllowedEditExtensions(String allowedEditExtensions) { this._allowedEditExtensions = allowedEditExtensions; } public String getAllowedEditExtensions() { return _allowedEditExtensions; } private String _baseURL; private String _baseDiskRoot; private String _protectedBaseDiskRoot; private String _protectedBaseURL; private String _allowedEditExtensions; }