Java tutorial
/** * Copyright (C) 2000 - 2013 Silverpeas * * This program is free software: you can redistribute it and/or modify it 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. * * As a special exception to the terms and conditions of version 3.0 of the GPL, you may * redistribute this Program in connection with Free/Libre Open Source Software ("FLOSS") * applications as described in Silverpeas's FLOSS exception. You should have received a copy of the * text describing the FLOSS exception, and it is also available here: * "http://www.silverpeas.org/docs/core/legal/floss_exception.html" * * 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.silverpeas.util; import com.silverpeas.util.exception.RelativeFileAccessException; import com.stratelia.silverpeas.silvertrace.SilverTrace; import com.stratelia.webactiv.util.FileRepositoryManager; import com.stratelia.webactiv.util.ResourceLocator; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.Properties; import java.util.ResourceBundle; import java.util.StringTokenizer; import javax.activation.MimetypesFileTypeMap; import org.apache.commons.exec.util.StringUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOCase; import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.FalseFileFilter; import org.apache.commons.io.filefilter.IOFileFilter; import org.apache.commons.io.filefilter.SuffixFileFilter; import org.apache.commons.io.filefilter.TrueFileFilter; import org.apache.tika.Tika; import org.silverpeas.util.mail.Mail; public class FileUtil implements MimeTypes { private static final ResourceLocator MIME_TYPES_EXTENSIONS = new ResourceLocator( "org.silverpeas.util.attachment.mime_types", ""); public static final String CONTEXT_TOKEN = ","; public static final String BASE_CONTEXT = "Attachment"; private static final MimetypesFileTypeMap MIME_TYPES = new MimetypesFileTypeMap(); private static final ClassLoader loader = java.security.AccessController .doPrivileged(new java.security.PrivilegedAction<ConfigurationClassLoader>() { @Override public ConfigurationClassLoader run() { return new ConfigurationClassLoader(FileUtil.class.getClassLoader()); } }); /** * Utility method for migration of Silverpeas configuration from : com.silverpeas, * com.stratelia.silverpeas, com.stratelia.webactiv to org.silverpeas * * @param bundle the name of the bundle. * @return the name of the migrated bundle. */ public static String convertBundleName(final String bundle) { return bundle.replace("com.silverpeas", "org.silverpeas") .replace("com.stratelia.silverpeas", "org.silverpeas") .replace("com.stratelia.webactiv", "org.silverpeas"); } /** * Utility method for migration of Silverpeas configuration from : com/silverpeas, * com/stratelia/silverpeas, com/stratelia/webactiv to org/silverpeas * * @param resource the name of the resource. * @return the name of the migrated resource. */ public static String convertResourceName(final String resource) { return resource.replace("com/silverpeas", "org/silverpeas") .replace("com/stratelia/silverpeas", "org/silverpeas") .replace("com/stratelia/webactiv", "org/silverpeas"); } /** * Detects the mime-type of the specified file. * * The mime-type is first extracted from its content. If the detection fails or if the file cannot * be located by its specified name, then the mime-type is detected from the file extension. * * @param fileName the name of the file with its path. * @return the mime-type of the specified file. */ public static String getMimeType(final String fileName) { String mimeType = null; final String fileExtension = FileRepositoryManager.getFileExtension(fileName).toLowerCase(); File file = new File(fileName); if (file.exists()) { try { Tika tika = new Tika(); mimeType = tika.detect(file); } catch (Exception ex) { SilverTrace.warn("attachment", "FileUtil", "attachment.MSG_MISSING_MIME_TYPES_PROPERTIES", ex.getMessage(), ex); } } if (!StringUtil.isDefined(mimeType)) { try { if (MIME_TYPES_EXTENSIONS != null) { mimeType = MIME_TYPES_EXTENSIONS.getString(fileExtension); } } catch (final MissingResourceException e) { SilverTrace.warn("attachment", "FileUtil", "attachment.MSG_MISSING_MIME_TYPES_PROPERTIES", null, e); } } if (!StringUtil.isDefined(mimeType)) { mimeType = MIME_TYPES.getContentType(fileName); } // if the mime type is application/xhml+xml or text/html whereas the file is a JSP or PHP script if (XHTML_MIME_TYPE.equalsIgnoreCase(mimeType) || HTML_MIME_TYPE.equalsIgnoreCase(mimeType)) { if (fileExtension.contains(JSP_EXTENSION)) { mimeType = JSP_MIME_TYPE; } else if (fileExtension.contains(PHP_EXTENSION)) { mimeType = PHP_MIME_TYPE; } // if the mime type refers a ZIP archive, checks if it is an archive of the java platform } else if (ARCHIVE_MIME_TYPE.equalsIgnoreCase(mimeType) || SHORT_ARCHIVE_MIME_TYPE.equalsIgnoreCase(mimeType)) { if (JAR_EXTENSION.equalsIgnoreCase(fileExtension) || WAR_EXTENSION.equalsIgnoreCase(fileExtension) || EAR_EXTENSION.equalsIgnoreCase(fileExtension)) { mimeType = JAVA_ARCHIVE_MIME_TYPE; } else if ("3D".equalsIgnoreCase(fileExtension)) { mimeType = SPINFIRE_MIME_TYPE; } } if (mimeType == null) { mimeType = DEFAULT_MIME_TYPE; } return mimeType; } /** * Create the array of strings this array represents the repertories where the files must be * stored. * * @param context * @return */ public static String[] getAttachmentContext(final String context) { if (!StringUtil.isDefined(context)) { return new String[] { BASE_CONTEXT }; } final StringTokenizer strToken = new StringTokenizer(context, CONTEXT_TOKEN); final List<String> folders = new ArrayList<String>(10); folders.add(BASE_CONTEXT); while (strToken.hasMoreElements()) { folders.add(strToken.nextToken().trim()); } return folders.toArray(new String[folders.size()]); } /** * Read the content of a file in a byte array. * * @param file the file to be read. * @return the bytes array containing the content of the file. * @throws IOException */ public static byte[] readFile(final File file) throws IOException { return FileUtils.readFileToByteArray(file); } /** * Read the content of a file as text (the text is supposed to be in the UTF-8 charset). * * @param file the file to read. * @return the file content as a String. * @throws IOException if an error occurs while reading the file. */ public static String readFileToString(final File file) throws IOException { return FileUtils.readFileToString(file); } /** * Write a stream into a file. * * @param file the file to be written. * @param data the data to be written. * @throws IOException */ public static void writeFile(final File file, final InputStream data) throws IOException { FileOutputStream out = null; try { out = new FileOutputStream(file); IOUtils.copy(data, out); } finally { if (out != null) { out.close(); } } } /** * Write a stream into a file. * * @param file the file to be written. * @param data the data to be written. * @throws IOException */ public static void writeFile(final File file, final Reader data) throws IOException { FileWriter out = new FileWriter(file); try { IOUtils.copy(data, out); } finally { IOUtils.closeQuietly(out); } } /** * Loads a ResourceBundle from the Silverpeas configuration directory. * * @param bundleName the name of the bundle. * @param locale the locale of the bundle. * @return the corresponding ResourceBundle if it exists - null otherwise. */ public static ResourceBundle loadBundle(final String bundleName, final Locale locale) { String name = convertBundleName(bundleName); ResourceBundle bundle; Locale loc = locale; if (loc == null) { loc = Locale.ROOT; } try { bundle = ResourceBundle.getBundle(name, loc, loader, new ConfigurationControl()); if (bundle == null) { bundle = ResourceBundle.getBundle(bundleName, loc, loader, new ConfigurationControl()); } } catch (MissingResourceException mex) { //Let's try with the real name bundle = ResourceBundle.getBundle(bundleName, loc, loader, new ConfigurationControl()); } return bundle; } /** * Loads loads the resource into the specified properties. * * @param properties the properties to be loaded with the resource. * @param resourceName the name of the resource. * @throws IOException */ public static void loadProperties(final Properties properties, final String resourceName) throws IOException { if (StringUtil.isDefined(resourceName) && properties != null) { String name = convertResourceName(resourceName); InputStream in = loader.getResourceAsStream(name); try { properties.load(in); } finally { IOUtils.closeQuietly(in); } } } /** * Indicates if the OS is from the Microsoft Windows familly * * @return true if the OS is from the Microsoft Windows familly - false otherwise. */ public static boolean isWindows() { return OsEnum.getOS().isWindows(); } /** * If 3D document. * * @param filename the name of the file. * @return true or false */ public static boolean isSpinfireDocument(String filename) { return SPINFIRE_MIME_TYPE.equals(getMimeType(filename)); } /** * Indicates if the current file is of type archive. * * @param filename the name of the file. * @return true is the file s of type archive - false otherwise. */ public static boolean isArchive(final String filename) { return ARCHIVE_MIME_TYPES.contains(getMimeType(filename)); } /** * Indicates if the current file is of type image. * * @param filename the name of the file. * @return true is the file is of type image - false otherwise. */ public static boolean isImage(final String filename) { String mimeType = getMimeType(filename); if (DEFAULT_MIME_TYPE.equals(mimeType)) { return FilenameUtils.isExtension(filename.toLowerCase(), ImageUtil.IMAGE_EXTENTIONS); } else { return mimeType.startsWith("image"); } } /** * Indicates if the current file is of type mail. * * @param filename the name of the file. * @return true is the file is of type mail - false otherwise. */ public static boolean isMail(final String filename) { return FilenameUtils.isExtension(filename, Mail.MAIL_EXTENTIONS); } /** * Indicates if the current file is of type PDF. * * @param filename the name of the file. * @return true is the file s of type archive - false otherwise. */ public static boolean isPdf(final String filename) { final String mimeType = getMimeType(filename); return PDF_MIME_TYPE.equals(mimeType); } public static boolean isOpenOfficeCompatible(final String filename) { final String mimeType = getMimeType(filename); return OPEN_OFFICE_MIME_TYPES.contains(mimeType) || isMsOfficeExtension(mimeType); } static boolean isMsOfficeExtension(final String mimeType) { return mimeType.startsWith(WORD_2007_EXTENSION) || mimeType.startsWith(EXCEL_2007_EXTENSION) || mimeType.startsWith(POWERPOINT_2007_EXTENSION); } /** * Checking that the path doesn't contain relative navigation between pathes. * * @param path * @throws RelativeFileAccessException */ public static void checkPathNotRelative(String path) throws RelativeFileAccessException { String unixPath = FilenameUtils.separatorsToUnix(path); if (unixPath != null && (unixPath.contains("../") || unixPath.contains("/.."))) { throw new RelativeFileAccessException(); } } public static Collection<File> listFiles(File directory, String[] extensions, boolean recursive) { return FileUtils.listFiles(directory, extensions, recursive); } public static Collection<File> listFiles(File directory, String[] extensions, boolean caseSensitive, boolean recursive) { if (caseSensitive) { return listFiles(directory, extensions, recursive); } IOFileFilter filter; if (extensions == null) { filter = TrueFileFilter.INSTANCE; } else { String[] suffixes = new String[extensions.length]; for (int i = 0; i < extensions.length; i++) { suffixes[i] = "." + extensions[i]; } filter = new SuffixFileFilter(suffixes, IOCase.INSENSITIVE); } return FileUtils.listFiles(directory, filter, (recursive ? TrueFileFilter.INSTANCE : FalseFileFilter.INSTANCE)); } /** * Forces the deletion of the specified file. If the write property of the file to delete isn't * set, this property is then set before deleting. * * @param fileToDelete file to delete. * @throws IOException if the deletion failed or if the file doesn't exist. */ public static void forceDeletion(File fileToDelete) throws IOException { if (fileToDelete.exists() && !fileToDelete.canWrite()) { fileToDelete.setWritable(true); } FileUtils.forceDelete(fileToDelete); } /** * Moves the specified source file to the specified destination. If the destination exists, it is * then replaced by the source; if the destination is a directory, then it is deleted with all of * its contain. * * @param source the file to move. * @param destination the destination file of the move. * @throws IOException if the source or the destination is invalid or if an error occurs while * moving the file. */ public static void moveFile(File source, File destination) throws IOException { if (destination.exists()) { FileUtils.forceDelete(destination); } FileUtils.moveFile(source, destination); } /** * Copies the specified source file to the specified destination. If the destination exists, it is * then replaced by the source. If the destination can be overwritten, its write property is set * before the copy. * * @param source the file to copy. * @param destination the destination file of the move. * @throws IOException if the source or the destination is invalid or if an error occurs while * copying the file. */ public static void copyFile(File source, File destination) throws IOException { if (destination.exists() && !destination.canWrite()) { destination.setWritable(true); } FileUtils.copyFile(source, destination); } /* * Remove any \ or / from the filename thus avoiding conflicts on the server. * * @param fileName * @return */ public static String getFilename(String fileName) { if (!StringUtil.isDefined(fileName)) { return ""; } return FilenameUtils.getName(fileName); } private FileUtil() { } /** * Convert a path to the current OS path format. * * @param undeterminedOsPath * @return server OS pah. */ public static String convertPathToServerOS(String undeterminedOsPath) { if (undeterminedOsPath == null || !StringUtil.isDefined(undeterminedOsPath)) { return ""; } String localPath = undeterminedOsPath; localPath = localPath.replace('\\', File.separatorChar).replace('/', File.separatorChar); return localPath; } public static String convertFilePath(File file) { if (OsEnum.getOS().isWindows()) { return StringUtils.quoteArgument(file.getAbsolutePath()); } String path = file.getAbsolutePath(); path = path.replaceAll("\\\\", "\\\\\\\\"); path = path.replaceAll("\\s", "\\\\ "); path = path.replaceAll("<", "\\\\<"); path = path.replaceAll(">", "\\\\>"); path = path.replaceAll("'", "\\\\'"); path = path.replaceAll("\"", "\\\\\""); path = path.replaceAll("\\{", "\\\\{"); path = path.replaceAll("}", "\\\\}"); path = path.replaceAll("\\(", "\\\\("); path = path.replaceAll("\\)", "\\\\)"); path = path.replaceAll("\\[", "\\\\["); path = path.replaceAll("\\]", "\\\\]"); path = path.replaceAll("\\&", "\\\\&"); path = path.replaceAll("\\|", "\\\\|"); return path; } public static boolean deleteEmptyDir(File directory) { if (directory.exists() && directory.isDirectory() && directory.list() != null && directory.list().length == 0) { return directory.delete(); } return false; } }