    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *     http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.mail.activation;
    019
    020import java.io.IOException;
    021import java.io.InputStream;
    022import java.io.OutputStream;
    023import java.nio.file.Files;
    024import java.nio.file.OpenOption;
    025import java.nio.file.Path;
    026import java.util.Objects;
    027
    028import javax.activation.DataSource;
    029import javax.activation.FileTypeMap;
    030import javax.activation.MimetypesFileTypeMap;
    031
    032/**
    033 * A JavaBeans Activation Framework {@link DataSource} that encapsulates a {@link Path}. It provides data typing services via a {@link FileTypeMap} object.
    034 *
    035 * @see javax.activation.DataSource
    036 * @see javax.activation.FileTypeMap
    037 * @see javax.activation.MimetypesFileTypeMap
    038 *
    039 * @since 1.6.0
    040 */
    041public final class PathDataSource implements DataSource {
    042
    043    private final Path path;
    044    private final FileTypeMap typeMap;
    045    private final OpenOption[] options;
    046
    047    /**
    048     * Creates a new instance from a Path.
    049     * <p>
    050     * The file will not actually be opened until a method is called that requires the path to be opened.
    051     * </p>
    052     * <p>
    053     * The type map defaults to {@link FileTypeMap#getDefaultFileTypeMap()}.
    054     *
    055     * @param path the path
    056     */
    057    public PathDataSource(final Path path) {
    058        this(path, FileTypeMap.getDefaultFileTypeMap());
    059    }
    060
    061    /**
    062     * Creates a new instance from a Path.
    063     * <p>
    064     * The file will not actually be opened until a method is called that requires the path to be opened.
    065     * </p>
    066     *
    067     * @param path    the path, non-null.
    068     * @param typeMap the type map, non-null.
    069     * @param options options for opening file streams.
    070     */
    071    public PathDataSource(final Path path, final FileTypeMap typeMap, final OpenOption... options) {
    072        this.path = Objects.requireNonNull(path, "path");
    073        this.typeMap = Objects.requireNonNull(typeMap, "typeMap");
    074        this.options = options;
    075    }
    076
    077    /**
    078     * Gets the MIME type of the data as a String. This method uses the currently installed FileTypeMap. If there is no FileTypeMap explicitly set, the
    079     * FileDataSource will call the {@link FileTypeMap#getDefaultFileTypeMap} method to acquire a default FileTypeMap.
    080     * <p>
    081     * By default, the {@link FileTypeMap} used will be a {@link MimetypesFileTypeMap}.
    082     * </p>
    083     *
    084     * @return the MIME Type
    085     * @see FileTypeMap#getDefaultFileTypeMap
    086     */
    087    @Override
    088    public String getContentType() {
    089        return typeMap.getContentType(getName());
    090    }
    091
    092    /**
    093     * Gets an InputStream representing the the data and will throw an IOException if it can not do so. This method will return a new instance of InputStream
    094     * with each invocation.
    095     *
    096     * @return an InputStream
    097     */
    098    @Override
    099    public InputStream getInputStream() throws IOException {
    100        return Files.newInputStream(path, options);
    101    }
    102
    103    /**
    104     * Gets the <em>name</em> of this object. The FileDataSource will return the file name of the object.
    105     *
    106     * @return the name of the object or null.
    107     * @see javax.activation.DataSource
    108     */
    109    @Override
    110    public String getName() {
    111        return Objects.toString(path.getFileName(), null);
    112    }
    113
    114    /**
    115     * Gets an OutputStream representing the the data and will throw an IOException if it can not do so. This method will return a new instance of OutputStream
    116     * with each invocation.
    117     *
    118     * @return an OutputStream
    119     */
    120    @Override
    121    public OutputStream getOutputStream() throws IOException {
    122        return Files.newOutputStream(path, options);
    123    }
    124
    125    /**
    126     * Gets the File object that corresponds to this PathDataSource.
    127     *
    128     * @return the File object for the file represented by this object.
    129     */
    130    public Path getPath() {
    131        return path;
    132    }
    133
    134}