1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.mail2.jakarta.activation;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.nio.file.Files;
24 import java.nio.file.OpenOption;
25 import java.nio.file.Path;
26 import java.util.Objects;
27
28 import jakarta.activation.DataSource;
29 import jakarta.activation.FileTypeMap;
30 import jakarta.activation.MimetypesFileTypeMap;
31
32 /**
33 * A JavaBeans Activation Framework {@link DataSource} that encapsulates a {@link Path}. It provides data typing services via a {@link FileTypeMap} object.
34 *
35 * @see jakarta.activation.DataSource
36 * @see jakarta.activation.FileTypeMap
37 * @see jakarta.activation.MimetypesFileTypeMap
38 *
39 * @since 1.6.0
40 */
41 public final class PathDataSource implements DataSource {
42
43 /**
44 * The source.
45 */
46 private final Path path;
47
48 /**
49 * Defaults to {@link FileTypeMap#getDefaultFileTypeMap()}.
50 */
51 private final FileTypeMap typeMap;
52
53 /**
54 * NIO options to open the source Path.
55 */
56 private final OpenOption[] options;
57
58 /**
59 * Creates a new instance from a Path.
60 * <p>
61 * The file will not actually be opened until a method is called that requires the path to be opened.
62 * </p>
63 * <p>
64 * The type map defaults to {@link FileTypeMap#getDefaultFileTypeMap()}.
65 *
66 * @param path the path
67 */
68 public PathDataSource(final Path path) {
69 this(path, FileTypeMap.getDefaultFileTypeMap());
70 }
71
72 /**
73 * Creates a new instance from a Path.
74 * <p>
75 * The file will not actually be opened until a method is called that requires the path to be opened.
76 * </p>
77 *
78 * @param path the path, non-null.
79 * @param typeMap the type map, non-null.
80 * @param options options for opening file streams.
81 */
82 public PathDataSource(final Path path, final FileTypeMap typeMap, final OpenOption... options) {
83 this.path = Objects.requireNonNull(path, "path");
84 this.typeMap = Objects.requireNonNull(typeMap, "typeMap");
85 this.options = options;
86 }
87
88 /**
89 * 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
90 * FileDataSource will call the {@link FileTypeMap#getDefaultFileTypeMap} method to acquire a default FileTypeMap.
91 * <p>
92 * By default, the {@link FileTypeMap} used will be a {@link MimetypesFileTypeMap}.
93 * </p>
94 *
95 * @return the MIME Type
96 * @see FileTypeMap#getDefaultFileTypeMap
97 */
98 @Override
99 public String getContentType() {
100 return typeMap.getContentType(getName());
101 }
102
103 /**
104 * 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
105 * with each invocation.
106 *
107 * @return an InputStream
108 */
109 @Override
110 public InputStream getInputStream() throws IOException {
111 return Files.newInputStream(path, options);
112 }
113
114 /**
115 * Gets the <em>name</em> of this object. The FileDataSource will return the file name of the object.
116 *
117 * @return the name of the object or null.
118 * @see jakarta.activation.DataSource
119 */
120 @Override
121 public String getName() {
122 return Objects.toString(path.getFileName(), null);
123 }
124
125 /**
126 * 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
127 * with each invocation.
128 *
129 * @return an OutputStream
130 */
131 @Override
132 public OutputStream getOutputStream() throws IOException {
133 return Files.newOutputStream(path, options);
134 }
135
136 /**
137 * Gets the File object that corresponds to this PathDataSource.
138 *
139 * @return the File object for the file represented by this object.
140 */
141 public Path getPath() {
142 return path;
143 }
144
145 }