/** * MailArchiver is an application that provides services for storing and managing e-mail messages through a Web Services SOAP interface. * Copyright (C) 2012 Marcio Andre Scholl Levien and Fernando Alberto Reuter Wendt and Jose Ronaldo Nogueira Fonseca Junior * * 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. * * 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 . */ /******************************************************************************\ * * This product was developed by * * SERVIÇO FEDERAL DE PROCESSAMENTO DE DADOS (SERPRO), * * a government company established under Brazilian law (5.615/70), * at Department of Development of Porto Alegre. * \******************************************************************************/ package serpro.mailarchiver.domain.metaarchive; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import javax.jdo.annotations.NotPersistent; import javax.jdo.annotations.PersistenceCapable; import org.apache.james.mime4j.codec.Base64InputStream; import org.apache.james.mime4j.codec.QuotedPrintableInputStream; import org.springframework.beans.factory.annotation.Autowired; import serpro.mailarchiver.domain.metaarchive.UnstructuredField.ContentTransferEncodingField; import serpro.mailarchiver.util.Charsets; import serpro.mailarchiver.util.Environment; import serpro.mailarchiver.util.Logger; import serpro.mailarchiver.util.UserAppConfig; @PersistenceCapable public abstract class SingleBody extends Body { @NotPersistent private static final Logger log = Logger.getLocalLogger(); @Autowired @NotPersistent protected UserAppConfig userAppConfig; @Autowired @NotPersistent protected Environment env; //**** P E R S I S T E N T **** private int offset; private int length; private int size; //***************************** public final int getOffset() { return offset; } public final void setOffset(int offset) { this.offset = offset; } public final int getLength() { return length; } public final void setLength(int length) { this.length = length; } public final int getSize() { return size; } public final void setSize(int size) { this.size = size; } //-------------------------------------------------------------------------- @Override final void dumpTree(StringBuilder sb, String pad) { sb.append(toString(pad + " ")); } //-------------------------------------------------------------------------- public byte[] getRawBytes() throws IOException { Message message = getRootMessage(); if(message != null) { Path path = message.getAbsolutePath(); ByteBuffer byteBuffer = ByteBuffer.allocate(length); FileChannel channel = FileChannel.open(path, StandardOpenOption.READ); channel.read(byteBuffer, offset); channel.close(); return byteBuffer.array(); } throw new IllegalStateException(); } //-------------------------------------------------------------------------- public InputStream getDecoderInputStream() throws IOException { final InputStream is = new ByteArrayInputStream(getRawBytes()); ContentTransferEncodingField contentTransferEncodingField = getEntity().getContentTransferEncoding(); if(contentTransferEncodingField != null) { if(contentTransferEncodingField.isBase64Encoding()) { return new Base64InputStream(is); } else if(contentTransferEncodingField.isQuotedPrintableEncoding()) { return new QuotedPrintableInputStream(is); } } //identity: 7bit, 8bit, binary return is; } //-------------------------------------------------------------------------- public String getRawText() throws IOException { return new String(getRawBytes(), Charsets.Windows_1252); } //-------------------------------------------------------------------------- public String getFileName() { if(getEntity() == null) { return "part_" + getOid(); } String fileName = null; ContentDispositionField contentDispositionField = getEntity().getContentDispositionField(); if(contentDispositionField != null) { fileName = contentDispositionField.getFileName(); if(fileName != null) { return fileName; } } ContentTypeField contentTypeField = getEntity().getContentTypeField(); if(contentTypeField != null) { fileName = contentTypeField.getParameter("name"); if(fileName != null) { return fileName; } } UnstructuredField contentIdField = getEntity().getContentIdField(); if(contentIdField != null) { StringBuilder sb = new StringBuilder(); String text = contentIdField.getText(); int beginIdx = -1; int endIdx = -1; for(int i = 0; i < text.length(); i++) { char c = text.charAt(i); if(Character.isLetterOrDigit(c)) { sb.append(c); if(beginIdx == -1) { beginIdx = i; } endIdx = i; } else { sb.append("-"); } } fileName = sb.substring(beginIdx, endIdx + 1); } else { fileName = "part_" + getOid(); } if(contentTypeField != null) { if(contentTypeField.isImageJpegMimeType()) { fileName += ".jpg"; } else if(contentTypeField.isImageGifMimeType()) { fileName += ".gif"; } else if(contentTypeField.isImagePngMimeType()) { fileName += ".png"; } else if(contentTypeField.isImageBmpMimeType()) { fileName += ".svg"; } else if(contentTypeField.isImageTiffMimeType()) { fileName += ".tif"; } else if(contentTypeField.isImageIconMimeType()) { fileName += ".ico"; } else if(contentTypeField.isImageSvgXmlMimeType()) { fileName += ".svg"; } else { //TODO: acrescentar outros subtipos fileName += "." + contentTypeField.getSubType(); } } return fileName; } public Path getPath() { return userAppConfig.SERVER.getArchiveDir().resolve("temp").resolve(getOid()).resolve(getFileName()); } public URL getURL() { try { return new URL( "http", env.getInternetAddresses()[0].getHostAddress(), userAppConfig.SERVER.getPort(), "/temp/" + getOid() + "/" + getFileName()); } catch(MalformedURLException ex) { log.error(ex); return null; } } public URL getConfidentialURL() { try { return new URL( "https", env.getInternetAddresses()[0].getHostAddress(), userAppConfig.SERVER.getConfidentialPort(), "/temp/" + getOid() + "/" + getFileName()); } catch(MalformedURLException ex) { log.error(ex); return null; } } public void publish() throws IOException { if(Files.exists(getPath())) { //already published return; } log.info("Publishing: %s/%s", getOid(), getFileName()); if(Files.notExists(getPath().getParent())) { Files.createDirectories(getPath().getParent()); } InputStream is = getDecoderInputStream(); Files.copy(is, getPath()); is.close(); } }