package rtt.core.loader; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; import rtt.core.exceptions.RTTException; import rtt.core.exceptions.RTTException.Type; import rtt.core.utils.RTTLogging; public abstract class ArchiveLoader { public static class NotSupportedArchiveType extends RTTException { private static final long serialVersionUID = -8229231611431198987L; private NotSupportedArchiveType(String message) { super(Type.OPERATION_FAILED, message); } public static NotSupportedArchiveType create(File path) { String message = "Not supported archive type: " + path; return new NotSupportedArchiveType(message); } } private String baseDir = null; private File baseFile; protected ArchiveLoader() {} public static ArchiveLoader create(File path) throws RTTException { if (path == null) { throw new IllegalArgumentException("Give archive file was null."); } boolean supportedArchiveType = path.isDirectory() || path.getPath().endsWith("zip"); if (!supportedArchiveType) { throw NotSupportedArchiveType.create(path); } File aPath = path.getAbsoluteFile(); if (aPath == null) { throw new RTTException(Type.NO_ARCHIVE, "Absolute file of '" + path.getAbsolutePath() + "' returned null."); } return new ZipArchiveLoader(); } public void setBasePath(File base) { this.baseFile = base.getAbsoluteFile(); Path archivePath = Paths.get(base.getPath()); if (Files.isDirectory(archivePath, LinkOption.NOFOLLOW_LINKS)) { baseDir = archivePath.toFile().getAbsolutePath(); } else { Path parent = archivePath.getParent(); while (parent != null && !Files.isDirectory(parent)) { parent = parent.getParent(); } if (parent != null) { baseDir = parent.toFile().getAbsolutePath(); } else { throw new IllegalAccessError("Parent file was null. Base path: " + archivePath); } } } /** * This function returns an {@link InputStream} for the given file name. If * an error occurs during the creation of the stream, this function will * return {@code null}. * <p> * The file will be searched downwards from the base file/base directory. * * @param fileName * the name of the file * @param folders * the path of the folder, containing the given file. * @return an {@link InputStream} or {@code null} * @see #setBasePath(File) */ public InputStream getInputStream(String fileName, String folders) { try { File file = new File(baseFile.getAbsolutePath() + File.separator + folders + File.separator + fileName); return this.doGetInput(file); } catch (Exception e) { RTTLogging.error("Could not retrieve InputStream", e); return null; } } /** * This function returns a {@link OutputStream} for the given file name. If * an error occurs during the creation of the stream, this function will * return {@code null}. * <p> * The file will be searched/created downwards from the base file/base directory. * @param fileName * the name of the file * @param folders * the path of the folder, containing the given file. * @return an {@link OutputStream} or {@code null} * @see #setBasePath(File) */ public OutputStream getOutputStream(String fileName, String folders) { try { File file = new File(baseFile.getAbsolutePath() + File.separator + folders + File.separator + fileName); return this.doGetOutput(file); } catch (Exception e) { RTTLogging.error("Could not retrieve OutputStream", e); return null; } } /** * Returns the current base directory/file. * @return a string with a path to the file/directory */ public String getBasePath() { return baseDir; } protected abstract OutputStream doGetOutput(File file) throws Exception; protected abstract InputStream doGetInput(File file) throws Exception; public void close() {} }