001package ball.activation;
002/*-
003 * ##########################################################################
004 * Utilities
005 * %%
006 * Copyright (C) 2008 - 2022 Allen D. Ball
007 * %%
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *      http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 * ##########################################################################
020 */
021import java.beans.ConstructorProperties;
022import java.io.File;
023import java.io.FileInputStream;
024import java.io.FileOutputStream;
025import java.io.IOException;
026import lombok.ToString;
027
028import static org.apache.commons.lang3.StringUtils.EMPTY;
029
030/**
031 * {@link javax.activation.DataSource} backed by a temporary {@link File}
032 * and based on {@link FileInputStream} and {@link FileOutputStream}.
033 *
034 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
035 */
036@ToString
037public class TempFileDataSource extends AbstractDataSource {
038    private final String prefix;
039    private final String suffix;
040    private final File parent;
041    private volatile File file = null;
042
043    /**
044     * @param   prefix          The file name prefix.
045     * @param   suffix          The file name suffix.
046     * @param   parent          The parent {@link File}.
047     * @param   type            Initial {@code "ContentType"} attribute
048     *                          value.
049     *
050     * @see File#createTempFile(String,String,File)
051     */
052    @ConstructorProperties({ EMPTY, EMPTY, EMPTY, "contentType" })
053    public TempFileDataSource(String prefix, String suffix, File parent, String type) {
054        super();
055
056        if (prefix != null) {
057            this.prefix = prefix;
058        } else {
059            this.prefix = TempFileDataSource.class.getSimpleName();
060        }
061
062        this.suffix = suffix;
063        this.parent = parent;
064
065        if (type != null) {
066            setContentType(type);
067        }
068    }
069
070    /**
071     * @param   type            Initial {@code "ContentType"} attribute
072     *                          value.
073     */
074    @ConstructorProperties({ "contentType" })
075    public TempFileDataSource(String type) { this(null, null, null, type); }
076
077    {
078        try {
079            clear();
080        } catch (Exception exception) {
081            throw new ExceptionInInitializerError(exception);
082        }
083    }
084
085    @Override
086    public long length() { return file.length(); }
087
088    @Override
089    public FileInputStream getInputStream() throws IOException {
090        return new FileInputStream(file);
091    }
092
093    @Override
094    public FileOutputStream getOutputStream() throws IOException {
095        FileOutputStream out = null;
096        File old = file;
097
098        if (old != null) {
099            old.delete();
100        }
101
102        file = File.createTempFile(prefix, suffix, parent);
103        file.deleteOnExit();
104
105        out = new FileOutputStream(file);
106
107        return out;
108    }
109}