--- /dev/null
+/*******************************************************************************
+ * Copyright � Igor Barma, Alexandre Desoubeaux, Christian Martel, Eric Brun, Mathieu Amblard, Gwenael Gevet, Pierre Guillot, 2012
+ * Copyright Alexandre Desoubeaux, Christian Martel, Cedric Lecarpentier, Alexandre Lefevre, Marc Salvat 2014-2016
+ * Copyright Alexandre Desoubeaux, Christian Martel, Cedric Lecarpentier, Marc Salvat, Marc Suarez, Harifetra Ramamonjy 2017
+ *
+ * This file is part of the work and learning management system Pentila Nero.
+ *
+ * Pentila Nero is free software. You can redistribute it and/or modify since
+ * you respect the terms of either (at least one of the both license) :
+ * - under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * - the CeCILL-C as published by CeCILL-C; either version 1 of the
+ * License, or any later version
+ * - the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the license,
+ * or (at your option) any later version.
+ *
+ * There are special exceptions to the terms and conditions of the
+ * licenses as they are applied to this software. View the full text of
+ * the exception in file LICENSE-PROJECT.txt in the directory of this software
+ * distribution.
+ *
+ * Pentila Nero 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
+ * Licenses for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * and the CeCILL-C and the GNU Lesser General Public License along with
+ * Pentila Nero. If not, see :
+ * <http://www.gnu.org/licenses/> and
+ * <http://www.cecill.info/licences.fr.html>.
+ ******************************************************************************/
+package com.pentila.entSavoie.utils;
+
+import java.awt.image.RenderedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.NumberFormat;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
+import javax.imageio.stream.ImageOutputStream;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.DocumentType;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.jsoup.select.Elements;
+
+import com.liferay.portal.kernel.dao.orm.QueryUtil;
+import com.liferay.portal.kernel.exception.PortalException;
+import com.liferay.portal.kernel.exception.SystemException;
+import com.liferay.portal.kernel.image.ImageToolUtil;
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
+import com.liferay.portal.kernel.repository.model.FileEntry;
+import com.liferay.portal.kernel.repository.model.Folder;
+import com.liferay.portal.kernel.search.Indexer;
+import com.liferay.portal.kernel.search.IndexerRegistryUtil;
+import com.liferay.portal.kernel.util.Base64;
+import com.liferay.portal.kernel.util.FileUtil;
+import com.liferay.portal.kernel.workflow.WorkflowConstants;
+import com.liferay.portal.model.User;
+import com.liferay.portal.service.ServiceContext;
+import com.liferay.portal.service.UserLocalServiceUtil;
+import com.liferay.portlet.documentlibrary.model.DLFileEntry;
+import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
+import com.liferay.portlet.documentlibrary.model.DLFolder;
+import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
+import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
+import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
+import com.liferay.portlet.documentlibrary.service.DLFileShortcutLocalServiceUtil;
+import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
+import com.pentila.entSavoie.cartable.model.DlLink;
+import com.pentila.entSavoie.cartable.service.CasierEntryLocalServiceUtil;
+import com.pentila.entSavoie.cartable.service.DlLinkLocalServiceUtil;
+
+public class DLEntryUtil {
+
+ private static Log logger = LogFactoryUtil.getLog(DLEntryUtil.class);
+
+ public static void deleteFolder(long folderId) throws PortalException, SystemException {
+ //supprime effectivement le fichier
+ DLAppLocalServiceUtil.deleteFolder(folderId);
+ }
+
+ public static void deleteFile(long fileId) throws PortalException, SystemException {
+ final FileEntry file = DLAppLocalServiceUtil.getFileEntry(fileId);
+ try {
+ CasierEntryLocalServiceUtil.deleteBuC_G_Id(file.getCompanyId(), file.getGroupId(), file.getFileEntryId());
+ } catch (PortalException e){}
+ DLAppLocalServiceUtil.deleteFileEntry(fileId);
+ }
+
+ public static void deleteDLFileShortcut(long shId) throws PortalException, SystemException {
+ try {
+ final DLFileShortcut file = DLFileShortcutLocalServiceUtil.getDLFileShortcut(shId);
+ CasierEntryLocalServiceUtil.deleteBuC_G_Id(file.getCompanyId(), file.getGroupId(), file.getFileShortcutId());
+ } catch (PortalException e){}
+ DLFileShortcutLocalServiceUtil.deleteDLFileShortcut(shId);
+ }
+
+ public static DLFileShortcut copyDLFileShortcut(long userId, long shortCutId, long destFolderId) throws PortalException, SystemException {
+ final User user = UserLocalServiceUtil.getUser(userId);
+ final DLFileShortcut originShortcut = DLFileShortcutLocalServiceUtil.getFileShortcut(shortCutId);
+ final Folder destFolder = DLAppLocalServiceUtil.getFolder(destFolderId);
+
+ ServiceContext serviceContext = new ServiceContext();
+ serviceContext.setAddGroupPermissions(true);
+ serviceContext.setAddGuestPermissions(true);
+
+ DLFileShortcut ret = DLFileShortcutLocalServiceUtil.addFileShortcut(
+ user.getUserId(),
+ destFolder.getGroupId(),
+ destFolder.getFolderId(),
+ originShortcut.getToFileEntryId(),
+ serviceContext);
+ return ret;
+ }
+
+ public static FileEntry moveFileEntry(long userId, long fileId, long destFolderId) throws PortalException, SystemException {
+ final User user = UserLocalServiceUtil.getUser(userId);
+
+ // Ajout des permissions
+ ServiceContext serviceContext = new ServiceContext();
+ serviceContext.setAddGroupPermissions(true);
+ serviceContext.setAddGuestPermissions(true);
+ FileEntry ret = null;
+
+ try {
+
+ DlLink dll = null;
+ // if we have link copy the source dans delete the link file
+ dll = DlLinkLocalServiceUtil.fetchDlLinkByTargetType(fileId, "file");
+ if( (dll != null) && (dll.getSourceId() != 0) ){
+ FileEntry sourceLinkedFile = DLAppLocalServiceUtil.getFileEntry(dll.getSourceId());
+ FileEntry targetLinkedFile = DLAppLocalServiceUtil.getFileEntry(dll.getTargetId());
+
+ ret = DLEntryUtil.copyFileEntry(user.getUserId(), dll.getSourceId(), destFolderId, true);
+
+ // in case it change user change the title, get it
+ if(!sourceLinkedFile.getTitle().equals(targetLinkedFile.getTitle())){
+
+ ret = DLAppLocalServiceUtil.updateFileEntry(ret.getUserId(),
+ ret.getFileEntryId(),
+ ret.getMimeType(),
+ ret.getTitle(),
+ targetLinkedFile.getTitle(),
+ ret.getDescription(),
+ "",
+ true,
+ ret.getContentStream(),
+ ret.getSize(),
+ serviceContext);
+ }
+
+
+ // verification
+ if (sourceLinkedFile !=null) {
+ // we have a link so we delete it
+ DlLinkLocalServiceUtil.removeDlFileLinkByTarget(dll.getTargetId());
+ int linkLeft = DlLinkLocalServiceUtil.countDlFileLinkBySourceId(sourceLinkedFile.getFileEntryId());
+ if (linkLeft==0) {
+ // plus de lien donc on supprime la source
+ DLAppLocalServiceUtil.deleteFileEntry(sourceLinkedFile.getFileEntryId());
+ // on verifie le dossier contenant pour suppression le cas echeant en recurssif
+ removeLinkedFileContainer(sourceLinkedFile.getFolderId());
+ }
+ }
+ DLAppLocalServiceUtil.deleteFileEntry(fileId);
+ }
+ else{
+ // no dll link just move the file
+ ret = DLAppLocalServiceUtil.moveFileEntry(
+ user.getUserId(),
+ fileId,
+ destFolderId,
+ serviceContext);
+ }
+ // update file permission to get the new parent folder permission
+ PermissionsUtils.setParentPermissionToFile(ret);
+ } catch (SystemException se) {
+ logger.error(se);
+ } catch (IOException ioe) {
+ logger.error(ioe);
+ }
+ return ret;
+ }
+
+ /***
+ * this method move a pFolderToMove in pTargetFolderIf the file inside are links, this method get the reals file and write them into folder instead of links
+ * @param pFolderToMove The Folder object you will move
+ * @param pTargetFolder the folder id of target folder
+ * @throws PortalException
+ * @throws SystemException
+ */
+ public static Folder moveFolder(Folder pFolderToMove, long pTargetFolder) throws PortalException, SystemException{
+ Folder targetFolder = DLAppLocalServiceUtil.getFolder(pTargetFolder);
+ Folder newFolder = DLAppUtil.addFolder(targetFolder.getUserId(), targetFolder.getGroupId(), pTargetFolder, pFolderToMove.getName());
+ List<FileEntry> files = DLAppLocalServiceUtil.getFileEntries(pFolderToMove.getGroupId(), pFolderToMove.getFolderId());
+ List<Folder> folders = DLAppLocalServiceUtil.getFolders(pFolderToMove.getGroupId(), pFolderToMove.getFolderId());
+
+ for (Folder aFolder: folders) {
+ moveFolder(aFolder, newFolder.getFolderId());
+ }
+
+ for (FileEntry aFile: files) {
+ moveFileEntry(targetFolder.getUserId(), aFile.getFileEntryId(), newFolder.getFolderId());
+ }
+
+ DLAppLocalServiceUtil.deleteFolder(pFolderToMove.getFolderId());
+
+ return newFolder;
+ }
+
+ public static FileEntry copyFileEntry(long userId, long fileId, long destFolderId) throws PortalException, SystemException, IOException {
+ return copyFileEntry(userId, fileId, destFolderId, true);
+ }
+
+ /**
+ * Copy a file as a link (without it's content)
+ * @param pUserId long which represent the receiver0
+ * @param pFileId file id (as long) which represent the file to copy and create the link
+ * @param pDestFolderId the folder id where the file will be copy (as long)
+ * @param pSourcePortlet a String representing the orgin protlet. It's specifically for quota
+ * @return The linked file entry (FileEntry object)
+ */
+ public static FileEntry copyLinkedFileEntry(long pUserId, long pFileId, long pDestFolderId, String pSourcePortlet) throws PortalException, SystemException, IOException {
+ // copy the file without content
+ FileEntry linkedDLFE = copyFileEntry(pUserId, pFileId, pDestFolderId, false);
+
+ // generate the link
+ DlLinkLocalServiceUtil.addDlFileLink(pFileId, linkedDLFE.getFileEntryId(), pSourcePortlet);
+
+ // reindex the target file due test of link inside documentLibrary.util.indexer.java
+ Indexer indexer = IndexerRegistryUtil.getIndexer(DLFileEntry.class);
+
+ try {
+ indexer.reindex(linkedDLFE);
+ } catch (Exception e) {
+ logger.error("Error during reindexing file "+linkedDLFE.getFileEntryId());
+ }
+ return linkedDLFE;
+ }
+
+ public static FileEntry copyFileEntry(long userId, long fileId, long destFolderId, boolean copyFileContent) throws PortalException, SystemException, IOException {
+ final User user = UserLocalServiceUtil.getUser(userId);
+ final FileEntry originFile = DLAppLocalServiceUtil.getFileEntry(fileId);
+ final Folder destFolder = DLAppLocalServiceUtil.getFolder(destFolderId);
+
+ // Ajout des permissions
+ ServiceContext serviceContext = new ServiceContext();
+ serviceContext.setAddGroupPermissions(true);
+ serviceContext.setAddGuestPermissions(true);
+
+ FileEntry ret = null;
+
+ InputStream is = null;
+ if (copyFileContent) {
+ // on prend le contenu du fichier a copier
+ /*
+ * We are using the getContentStream from FileEntryUtil because the same methods on FileEntry check the permission, in some case this throw and error
+ */
+ is = DLFileEntryLocalServiceUtil.getFileAsStream(originFile.getUserId(), originFile.getFileEntryId(), originFile.getVersion());
+ }
+ else {
+ // on sauve un fichier vide!!!
+ is = new ByteArrayInputStream("".getBytes());
+ }
+
+
+ ret = DLAppUtil.addFileEntry(user, destFolder, originFile.getTitle(), is);
+
+ return ret;
+ }
+
+ /**
+ * Copy a folder as a link (with it's content)
+ * @param pUserId long which represent the receiver0
+ * @param pFolderId folder id (as long) which represent the folder to copy and create the link
+ * @param pDestFolderId the folder id where the file will be copy (as long)
+ * @param pSourcePortlet a String representing the origin portlet. It's specifically for quota
+ * @return The folder copied (Folder object)
+ */
+ public static Folder copyFolder(long pUserId, long pFolderId, long pDestFolderId) throws PortalException, SystemException, IOException {
+ return copyFolder(pUserId, pFolderId, pDestFolderId, true, null);
+ }
+
+ /**
+ * Copy a folder as a link (without it's content)
+ * @param pUserId long which represent the receiver0
+ * @param pFolderId folder id (as long) which represent the folder to copy and create the link
+ * @param pDestFolderId the folder id where the file will be copy (as long)
+ * @param pSourcePortlet a String representing the origin portlet. It's specifically for quota
+ * @return The folder copied (Folder object)
+ */
+ public static Folder copyLinkedFolder(long pUserId, long pFolderId, long pDestFolderId, String pOriginPortlet) throws PortalException, SystemException, IOException {
+ return copyFolder(pUserId, pFolderId, pDestFolderId, false, pOriginPortlet);
+ }
+
+ /**
+ * Copy a folder (with or without it's content)
+ * @param pUserId long which represent the receiver0
+ * @param pFolderId folder id (as long) which represent the folder to copy and create the link
+ * @param pDestFolderId the folder id where the file will be copy (as long)
+ * @param pCopyFileContent boolean which represent if it's necessary to sopy the file content or juste create a link
+ * @param pSourcePortlet a String representing the origin portlet. It's specifically for quota
+ * @return The folder copied (Folder object)
+ */
+ public static Folder copyFolder(long pUserId, long pFolderId, long pDestFolderId, boolean pCopyFileContent, String pOriginPortlet) throws PortalException, SystemException, IOException {
+ final User user = UserLocalServiceUtil.getUser(pUserId);
+ final Folder folder = DLAppLocalServiceUtil.getFolder(pFolderId);
+ final Folder destFolder = DLAppLocalServiceUtil.getFolder(pDestFolderId);
+ //Verifie que le dossier de destination n'es pas un sous dossier du dossier a copier.
+ long currFolderId = destFolder.getFolderId();
+ while (currFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
+ if (currFolderId == pFolderId)
+ return null;
+ currFolderId = DLAppLocalServiceUtil.getFolder(currFolderId).getParentFolderId();
+ }
+ // Ajout des permissions
+ ServiceContext serviceContext = new ServiceContext();
+ serviceContext.setAddGroupPermissions(true);
+ serviceContext.setAddGuestPermissions(true);
+
+ Folder newFolder = DLAppUtil.addFolder(user.getUserId(), destFolder.getGroupId(), destFolder.getFolderId(), folder.getName());
+
+ //si pas de probleme de nom (qui auraient leve une DuplicateFolderNameException)
+ //copie les contenus
+ for (Object entry : DLAppLocalServiceUtil.getFoldersAndFileEntriesAndFileShortcuts(folder.getGroupId(), folder.getFolderId(), WorkflowConstants.STATUS_ANY, true, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null)) {
+ if (entry instanceof Folder) {
+ final Folder currFolder = (Folder) entry;
+ copyFolder(user.getUserId(), currFolder.getFolderId(), newFolder.getFolderId(), pCopyFileContent, pOriginPortlet);
+ } else if (entry instanceof FileEntry) {
+ final FileEntry currFe = (FileEntry) entry;
+
+ if (pCopyFileContent) {
+ copyFileEntry(user.getUserId(), currFe.getFileEntryId(), newFolder.getFolderId());
+ }
+ else {
+ copyLinkedFileEntry(user.getUserId(), currFe.getFileEntryId(), newFolder.getFolderId(), pOriginPortlet);
+ }
+
+ } else if (entry instanceof DLFileShortcut) {
+ continue;
+ }
+ }
+ return newFolder;
+ }
+
+ public static boolean isSignetFile(InputStream is){
+ File file = null;
+ try{
+ file = FileUtil.createTempFile();
+ FileUtil.write(file, is);
+ is.close();
+ Document doc = Jsoup.parse(file, null);
+ List<Node>nodes = doc.childNodes();
+ Elements dts = doc.select("DT");
+ for (Node node : nodes) {
+ if (node instanceof DocumentType) {
+ DocumentType documentType = (DocumentType)node;
+ return documentType.toString().toLowerCase().contains("bookmark") && (dts.size() == 1);
+ }
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+ } finally {
+ if (file != null) {
+ file.delete();
+ }
+ }
+ return false;
+ }
+
+ public static boolean isSignetFile(DLFileEntry dlFileEntry){
+ try{
+ InputStream is = DLFileEntryLocalServiceUtil.getFileAsStream(dlFileEntry.getUserId(), dlFileEntry.getFileEntryId(), dlFileEntry.getVersion());
+ return isSignetFile(is);
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public static boolean isSignetFile(FileEntry fileEntry){
+ try{
+ InputStream is = DLFileEntryLocalServiceUtil.getFileAsStream(fileEntry.getUserId(), fileEntry.getFileEntryId(), fileEntry.getVersion());
+ return isSignetFile(is);
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public static String getUrlSignet(InputStream is){
+ File file = null;
+ try{
+ file = FileUtil.createTempFile();
+ FileUtil.write(file, is);
+ is.close();
+ Document doc = Jsoup.parse(file, null);
+ Element a = doc.select("A").first();
+ return a.attr("HREF");
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ } finally {
+ if (file != null) {
+ file.delete();
+ }
+ }
+ return "";
+ }
+
+ public static String getUrlSignet(FileEntry fileEntry) throws IOException{
+ InputStream is = null;
+ try{
+ is = DLFileEntryLocalServiceUtil.getFileAsStream(fileEntry.getUserId(), fileEntry.getFileEntryId(), fileEntry.getVersion());
+ return getUrlSignet(is);
+ } catch (Exception e) {
+ e.printStackTrace();
+ is.close();
+ }
+ return "";
+ }
+
+ public static String[] splitFileName(String fname) {
+ // retourne le nom du fichier et l'extension du fichier "String" en se basant sur le dernier '.' du nom
+ // --> retourne chaine vide si pas de point dans le nom !!!!!
+ String[] result = new String[2];
+ int dotIndex = fname.lastIndexOf(".");
+ if (dotIndex != -1) {
+ result[0] = fname.substring(0, dotIndex);
+ result[1] = fname.substring(dotIndex+1);
+ }
+ else {
+ result[0] = fname;
+ result[1] = "___";
+ }
+ return result;
+ }
+
+ /**
+ * Convert an image as a file into a base 64 string by compressing and resizing it
+ * @param file
+ * @param extension
+ * @param compress
+ * @param maxWidth
+ * @return String
+ * @throws PortalException
+ * @throws SystemException
+ * @throws IOException
+ */
+ public static String convertImageToBase64(File file, String extension, boolean compress, double maxWidth, double maxHeight) throws PortalException, SystemException, IOException {
+ byte[] fileArray = reduceImageSize(file, extension, compress, maxWidth, maxHeight);
+ String fileBase64 = Base64.encode(fileArray);
+ return fileBase64;
+ }
+
+ /**
+ * Convert an image as a byte array into a base 64 string by compressing and resizing it
+ * @param file
+ * @param extension
+ * @param compress
+ * @param maxWidth
+ * @return String
+ * @throws PortalException
+ * @throws SystemException
+ * @throws IOException
+ */
+ public static String convertImageToBase64(byte[] byteArray, String extension, boolean compress, double maxWidth, double maxHeight) throws PortalException, SystemException, IOException {
+ byte[] fileArray = reduceImageSize(byteArray, extension, compress, maxWidth, maxHeight);
+ String fileBase64 = Base64.encode(fileArray);
+ return fileBase64;
+ }
+
+ /**
+ * Reduces the size of an image by compressing and resizing it
+ * Doesn't work for tiff files
+ * @param file
+ * @param extension
+ * @param compress
+ * @param maxWidth
+ * @return byte[]
+ * @throws IOException
+ */
+ public static byte[] reduceImageSize(File file, String extension, boolean compress, double maxWidth, double maxHeight) throws IOException {
+
+ // Le format tiff n'est pas supporte
+ if(extension.equals("tiff") || extension.equals("tif")){
+ return FileUtil.getBytes(file);
+ }
+
+ byte[] fileArray = null;
+ RenderedImage renderedImage = ImageToolUtil.read(file).getRenderedImage();
+
+ maxWidth = maxWidth==0?renderedImage.getWidth():maxWidth;
+ maxHeight = maxHeight==0?renderedImage.getHeight():maxHeight;
+
+ /*
+ * Redimensionne l'image + compression
+ */
+ if((renderedImage.getWidth()>maxWidth || renderedImage.getHeight()>maxHeight)){
+ double widthScale = maxWidth/renderedImage.getWidth();
+ double heightScale = maxHeight/renderedImage.getHeight();
+ double scale = Math.min(widthScale, heightScale);
+
+ double width = renderedImage.getWidth() * scale;
+ double height = renderedImage.getHeight() * scale;
+
+ RenderedImage thumbnail = ImageToolUtil.scale(renderedImage, (int) height, (int) width);
+
+ if(compress){
+ fileArray = compressImage(thumbnail, extension);
+ }
+
+ if(!compress || fileArray == null){
+ ByteArrayOutputStream bam = new ByteArrayOutputStream();
+ ImageIO.write(thumbnail, extension, bam);
+ fileArray = bam.toByteArray();
+ bam.close();
+ }
+ }
+ /*
+ * Compression uniquement
+ */
+ else if(compress) {
+ fileArray = compressImage(renderedImage, extension);
+ if(fileArray == null){
+ fileArray = FileUtil.getBytes(file);
+ }
+ }
+ /*
+ * Aucun traitement sur l'image
+ */
+ else {
+ fileArray = FileUtil.getBytes(file);
+ }
+
+ return fileArray;
+ }
+
+
+ /**
+ * Reduces the size of an image by compressing and resizing it
+ * Doesn't work for tiff files
+ * @param file
+ * @param extension
+ * @param compress
+ * @param maxWidth
+ * @return byte[]
+ * @throws IOException
+ */
+ public static byte[] reduceImageSize(byte[] byteArray, String extension, boolean compress, double maxWidth, double maxHeight) throws IOException {
+
+ // Le format tiff n'est pas supporte
+ if(extension.equals("tiff") || extension.equals("tif")){
+ return byteArray;
+ }
+
+ byte[] fileArray = null;
+ RenderedImage renderedImage = ImageToolUtil.read(byteArray).getRenderedImage();
+
+ maxWidth = maxWidth==0?renderedImage.getWidth():maxWidth;
+ maxHeight = maxHeight==0?renderedImage.getHeight():maxHeight;
+
+ /*
+ * Redimensionne l'image + compression
+ */
+ if((renderedImage.getWidth()>maxWidth || renderedImage.getHeight()>maxHeight)){
+ double widthScale = maxWidth/renderedImage.getWidth();
+ double heightScale = maxHeight/renderedImage.getHeight();
+ double scale = Math.min(widthScale, heightScale);
+
+ double width = renderedImage.getWidth() * scale;
+ double height = renderedImage.getHeight() * scale;
+
+ RenderedImage thumbnail = ImageToolUtil.scale(renderedImage, (int) height, (int) width);
+
+ if(compress){
+ fileArray = compressImage(thumbnail, extension);
+ }
+
+ if(!compress || fileArray == null){
+ ByteArrayOutputStream bam = new ByteArrayOutputStream();
+ ImageIO.write(thumbnail, extension, bam);
+ fileArray = bam.toByteArray();
+ bam.close();
+ }
+ }
+ /*
+ * Compression uniquement
+ */
+ else if(compress) {
+ fileArray = compressImage(renderedImage, extension);
+ if(fileArray == null){
+ fileArray = byteArray;
+ }
+ }
+ /*
+ * Aucun traitement sur l'image
+ */
+ else {
+ fileArray = byteArray;
+ }
+
+ return fileArray;
+ }
+
+ /**
+ * Compress an image (only for JPEG)
+ * See lib jai_imageio-1.1.jar for other formats
+ * @param image
+ * @param extension
+ * @return byte[]
+ * @throws IOException
+ */
+ public static byte[] compressImage(RenderedImage image, String extension) throws IOException {
+
+ Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName(extension);
+
+ if(iter.hasNext()){
+ ImageWriter writer = (ImageWriter) iter.next();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ImageOutputStream ios = ImageIO.createImageOutputStream(bos);
+ writer.setOutput(ios);
+
+ ImageWriteParam iwparam = writer.getDefaultWriteParam();
+ if(extension.equals("jpg") || extension.equals("jpeg")){
+ iwparam = new JPEGImageWriteParam(Locale.getDefault());
+ iwparam.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
+ iwparam.setCompressionQuality(0.7F);
+ }
+
+ writer.write(null, new IIOImage(image, null, null), iwparam);
+
+ ios.flush();
+ writer.dispose();
+ ios.close();
+
+ return bos.toByteArray();
+ } else {
+ return null;
+ }
+
+ }
+
+ /*
+ * On gere les links
+ */
+ public static void updateLinkedFolderContent(long groupId, long folderId) throws PortalException, SystemException {
+ // check a folder and its content to reintegrate all file linked content
+ List<Folder> folders = DLAppLocalServiceUtil.getFolders(groupId, folderId);
+ for (Folder dlf: folders) {
+ updateLinkedFolderContent(groupId, dlf.getFolderId());
+ }
+ List<FileEntry> files = DLAppLocalServiceUtil.getFileEntries(groupId, folderId);
+ for (FileEntry dlfe: files) {
+ updateLinkedFileContent(dlfe.getFileEntryId());
+ }
+ }
+
+ public static void updateLinkedFileContent(long oldFileId, long newFileId) throws PortalException, SystemException {
+ // update file content after a move of it so new file....
+ DlLink dll = null;
+ try {
+ dll = DlLinkLocalServiceUtil.getDlFileLinkByTarget(oldFileId);
+ dll.setTargetId(newFileId);
+ DlLinkLocalServiceUtil.updateDlLink(dll);
+ updateLinkedFileContent(newFileId);
+ }
+ catch(Exception exc) {
+ logger.error(exc);
+ }
+ }
+
+ public static void updateLinkedFileContent(long fileId) throws PortalException, SystemException {
+ // check for a link
+ InputStream is = null;
+ FileEntry sourceLinkedFile = null;
+ DlLink dll = null;
+ try {
+ dll = DlLinkLocalServiceUtil.getDlFileLinkByTarget(fileId);
+ sourceLinkedFile = DLAppLocalServiceUtil.getFileEntry(dll.getSourceId());
+ is = sourceLinkedFile.getContentStream();
+ } catch (Exception e1) {
+ String stackString = "";
+ for(int iterator = 0 ; iterator < e1.getStackTrace().length ; iterator++){
+ stackString += e1.getStackTrace()[iterator].toString() + "\n";
+ }
+ logger.warn(stackString);
+ try {
+ is.close();
+ }
+ catch (IOException e) {
+ // no is to close
+ logger.error(e);
+ }
+ return;
+ }
+
+ if (is!=null) {
+ try {
+ // on met a jour le file!!!!!
+ FileEntry f = DLAppLocalServiceUtil.getFileEntry(fileId);
+ DLStoreUtil.updateFile(
+ f.getCompanyId(),
+ f.getFolderId(),
+ f.getTitle(),
+ f.getExtension(),
+ true,
+ f.getVersion(),
+ f.getTitle(),
+ is);
+ // set new permission to file
+ PermissionsUtils.setParentPermissionToFile(f);
+
+ }
+ catch (Exception e) {
+ logger.error(e);
+ }
+ finally{
+ try {
+ is.close();
+ }
+ catch (IOException e){
+ logger.error(e);
+ }
+ }
+ }
+
+ // verification
+ if (sourceLinkedFile!=null) {
+ // we have a link so we delete it
+ DlLinkLocalServiceUtil.removeDlFileLinkByTarget(dll.getTargetId());
+ int linkLeft = DlLinkLocalServiceUtil.countDlFileLinkBySourceId(sourceLinkedFile.getFileEntryId());
+ if (linkLeft==0) {
+ // plus de lien donc on supprime la source
+ DLAppLocalServiceUtil.deleteFileEntry(sourceLinkedFile.getFileEntryId());
+ // on verifie le dossier contenant pour suppression le cas echeant en recurssif
+ removeLinkedFileContainer(sourceLinkedFile.getFolderId());
+ }
+ }
+ }
+
+ public static void removeLinkedFileContainer(long folderId) throws SystemException, PortalException {
+ // on verifie le nombre de fichier dans le dossier pour le supprimer si besoin
+ Folder folder = DLAppLocalServiceUtil.getFolder(folderId);
+ if (folder.getParentFolderId() == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
+ // on est au niveau de sending box donc on arrete
+ return;
+ }
+ // on supprime les dossiers vers le bas!
+ List<Folder> childFolders = DLAppLocalServiceUtil.getFolders(folder.getGroupId(), folderId);
+ for (Folder child: childFolders) {
+ removeEmptyChildsFolders(child.getFolderId());
+ }
+
+ if (DLAppLocalServiceUtil.getFoldersAndFileEntriesAndFileShortcutsCount(folder.getGroupId(), folderId, WorkflowConstants.STATUS_ANY, true)==0) {
+ // on supprime le dossier et on remonte
+ DLAppLocalServiceUtil.deleteFolder(folderId);
+ removeLinkedFileContainer(folder.getParentFolderId());
+ }
+ }
+
+ public static void removeEmptyChildsFolders(long folderId) throws PortalException, SystemException {
+ Folder folder = DLAppLocalServiceUtil.getFolder(folderId);
+ List<Folder> childFolders = DLAppLocalServiceUtil.getFolders(folder.getGroupId(), folderId);
+ for (Folder child: childFolders) {
+ removeEmptyChildsFolders(child.getFolderId());
+ }
+ // dossier vide
+ if (DLAppLocalServiceUtil.getFoldersAndFileEntriesAndFileShortcutsCount(folder.getGroupId(), folderId, WorkflowConstants.STATUS_ANY, true)==0) {
+ // on supprime le dossier et on remonte
+ DLAppLocalServiceUtil.deleteFolder(folderId);
+ }
+ }
+
+ public static String formatFileSize(double size, Locale locale) {
+ NumberFormat nf = NumberFormat.getInstance(locale);
+ nf.setMaximumFractionDigits(1);
+ nf.setMinimumFractionDigits(1);
+
+ double koSize = size / 1024.0;
+ double moSize = koSize / 1024.0;
+ double goSize = moSize / 1024.0;
+ double toSize = goSize / 1024.0;
+ if (goSize > 1024.0) {
+ return nf.format(toSize) + " To";
+ } else if (moSize > 1024.0) {
+ return nf.format(goSize) + " Go";
+ } else if (koSize > 1024.0) {
+ return nf.format(moSize) + " Mo";
+ } else if (size > 1024.0) {
+ return nf.format(koSize) + " Ko";
+ } else {
+ return nf.format(size) + " o";
+ }
+ }
+
+ public static String formatFileSizeToKo(double size, Locale locale) {
+ NumberFormat nf = NumberFormat.getInstance(locale);
+ nf.setMaximumFractionDigits(1);
+ nf.setMinimumFractionDigits(1);
+
+ double koSize = size / 1024.0;
+ return nf.format(koSize) + " Ko";
+ }
+
+ /**
+ * This method return the size of the folder in parameter
+ * @param folderId the folder id, this is the id of folder you want to define the size
+ * @return long which contain the size in octet of the folder
+ * @throws PortalException liferay exception
+ * @throws SystemException liferay exception
+ */
+ public static long getFolderTotalSize(long folderId) throws PortalException, SystemException{
+ long totalSize = 0;
+
+ Folder folder = DLAppLocalServiceUtil.getFolder(folderId);
+
+ // get the size of sub-folder
+ for (DLFolder subFolder : FoldersUtil.getSubFolders(folder)) {
+ totalSize += getFolderTotalSize (subFolder.getFolderId());
+ }
+ // get file
+ for (DLFileEntry file : FoldersUtil.getFilesEntriesInFolder(folder)) {
+ totalSize += file.getSize();
+ }
+ return totalSize;
+ }
+}