blob: 574b15b97588ec35d37b7b4a02c13113a7cb2d71 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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$ $Date$
*/
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();
}
}