/*! * Copyright 2010 - 2013 Pentaho Corporation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.vfs.provider.mime; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Map; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Part; import javax.mail.internet.MimeMultipart; import org.apache.commons.vfs.FileContentInfoFactory; import org.apache.commons.vfs.FileName; import org.apache.commons.vfs.FileObject; import org.apache.commons.vfs.FileSystemException; import org.apache.commons.vfs.FileType; import org.apache.commons.vfs.NameScope; import org.apache.commons.vfs.provider.AbstractFileObject; import org.apache.commons.vfs.provider.AbstractFileSystem; import org.apache.commons.vfs.provider.UriParser; import org.apache.commons.vfs.util.FileObjectUtils; /** * A part of a MIME message. * * @author <a href="mailto:imario@apache.org">imario@apache.org</a> * @version $Revision: 755096 $ $Date: 2009-03-16 22:48:32 -0400 (Mon, 16 Mar 2009) $ */ public class MimeFileObject extends AbstractFileObject implements FileObject { private Part part; private Map attributeMap; protected MimeFileObject(final FileName name, final Part part, final AbstractFileSystem fileSystem) throws FileSystemException { super(name, fileSystem); setPart(part); } /** * Attaches this file object to its file resource. */ protected void doAttach() throws Exception { if (part == null) { if (!getName().equals(getFileSystem().getRootName())) { MimeFileObject foParent = (MimeFileObject) FileObjectUtils.getAbstractFileObject(getParent()); setPart(foParent.findPart(getName().getBaseName())); return; } setPart(((MimeFileSystem) getFileSystem()).createCommunicationLink()); } } private Part findPart(String partName) throws Exception { if (getType() == FileType.IMAGINARY) { // not existent return null; } if (isMultipart()) { Multipart multipart = (Multipart) part.getContent(); if (partName.startsWith(MimeFileSystem.NULL_BP_NAME)) { int partNumber = Integer.parseInt(partName.substring(MimeFileSystem.NULL_BP_NAME.length()), 10); if (partNumber < 0 || partNumber+1 > multipart.getCount()) { // non existent return null; } return multipart.getBodyPart(partNumber); } for (int i = 0; i<multipart.getCount(); i++) { Part childPart = multipart.getBodyPart(i); if (partName.equals(childPart.getFileName())) { return childPart; } } } return null; } protected void doDetach() throws Exception { } /** * Determines the type of the file, returns null if the file does not * exist. */ protected FileType doGetType() throws Exception { if (part == null) { return FileType.IMAGINARY; } if (isMultipart()) { // we cant have children ... return FileType.FILE_OR_FOLDER; } return FileType.FILE; } protected String[] doListChildren() throws Exception { return null; } /** * Lists the children of the file. Is only called if {@link #doGetType} * returns {@link org.apache.commons.vfs.FileType#FOLDER}. */ protected FileObject[] doListChildrenResolved() throws Exception { if (part == null) { return null; } List vfs = new ArrayList(); if (isMultipart()) { Object container = part.getContent(); if (container instanceof Multipart) { Multipart multipart = (Multipart) container; for (int i = 0; i<multipart.getCount(); i++) { Part part = multipart.getBodyPart(i); String filename = UriParser.encode(part.getFileName()); if (filename == null) { filename = MimeFileSystem.NULL_BP_NAME + i; } MimeFileObject fo = (MimeFileObject) FileObjectUtils.getAbstractFileObject(getFileSystem().resolveFile( getFileSystem().getFileSystemManager().resolveName( getName(), filename, NameScope.CHILD))); fo.setPart(part); vfs.add(fo); } } } return (MimeFileObject[]) vfs.toArray(new MimeFileObject[vfs.size()]); } private void setPart(Part part) { this.part = part; this.attributeMap = null; } /** * Returns the size of the file content (in bytes). */ protected long doGetContentSize() throws Exception { return part.getSize(); } /** * Returns the last modified time of this file. */ protected long doGetLastModifiedTime() throws Exception { Message mm = getMessage(); if (mm == null) { return -1; } if (mm.getSentDate() != null) { return mm.getSentDate().getTime(); } if (mm.getReceivedDate() != null) { mm.getReceivedDate(); } return 0; } private Message getMessage() throws FileSystemException { if (part instanceof Message) { return (Message) part; } return ((MimeFileObject) FileObjectUtils.getAbstractFileObject(getParent())).getMessage(); } /** * Creates an input stream to read the file content from. */ protected InputStream doGetInputStream() throws Exception { if (isMultipart()) { // deliver the preamble as the only content String preamble = ((MimeMultipart) part.getContent()).getPreamble(); if (preamble == null) { return new ByteArrayInputStream(new byte[]{}); } return new ByteArrayInputStream(preamble.getBytes(MimeFileSystem.PREAMBLE_CHARSET)); } return part.getInputStream(); } boolean isMultipart() throws MessagingException { return part.getContentType() != null && part.getContentType().startsWith("multipart/"); } protected FileContentInfoFactory getFileContentInfoFactory() { return new MimeFileContentInfoFactory(); } protected Part getPart() { return part; } /** * Returns all headers of this part.<br /> * The map key is a java.lang.String and the value is a:<br /> * <ul> * <li>java.lang.Strings for single entries</li> * or a * <li>java.utils.List of java.lang.Strings for entries with multiple values</li> * </ul> */ protected Map doGetAttributes() throws Exception { if (attributeMap == null) { if (part != null) { attributeMap = new MimeAttributesMap(part); } else { attributeMap = Collections.EMPTY_MAP; } } return attributeMap; } protected Enumeration getAllHeaders() throws MessagingException { return part.getAllHeaders(); } }