3939import static java .nio .charset .StandardCharsets .UTF_8 ;
4040import static java .util .Arrays .asList ;
4141import static java .util .regex .Pattern .compile ;
42- import static java .util .regex .Pattern .quote ;
4342import static org .simplejavamail .internal .util .Preconditions .assumeTrue ;
4443import static org .simplejavamail .internal .util .Preconditions .checkNonEmptyArgument ;
45- import static org .simplejavamail .internal .util .SimpleOptional .ofNullable ;
4644
4745public final class MiscUtil {
4846
@@ -52,8 +50,6 @@ public final class MiscUtil {
5250 private static final Pattern TRAILING_TOKEN_DELIMITER_PATTERN = compile ("<\\ |>$" );
5351 private static final Pattern TOKEN_DELIMITER_PATTERN = compile ("\\ s*<\\ |>\\ s*" );
5452
55- private static final Pattern ABSOLUTE_URL_PATTERN = compile (format ("^(%s|%s|%s).*" , quote ("http://" ), quote ("https://" ), quote ("file:/" )));
56-
5753 private static final Random RANDOM = new Random ();
5854
5955 @ SuppressFBWarnings (value = "NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE" )
@@ -277,38 +273,97 @@ public static ByteArrayInputStream copyInputstream(InputStream input) {
277273 }
278274
279275 @ Nullable
280- public static DataSource tryResolveImageFileDataSource (@ Nullable final String baseDir , @ Nullable final String baseClassPath , @ NotNull final String srcLocation )
276+ public static DataSource tryResolveImageFileDataSourceFromDisk (final @ Nullable String baseDir , final boolean allowOutsideBaseDir , final @ NotNull String srcLocation ) {
277+ DataSource dataSource ;
278+
279+ if (baseDir == null ) {
280+ dataSource = tryLoadingFromDisk (new File (srcLocation ));
281+ if (dataSource == null ) {
282+ dataSource = tryLoadingFromDisk (new File ("." , srcLocation ));
283+ }
284+ } else {
285+ if (srcLocation .startsWith (baseDir )) {
286+ dataSource = tryLoadingFromDisk (new File (srcLocation ));
287+ } else {
288+ dataSource = tryLoadingFromDisk (new File (baseDir , srcLocation ));
289+ if (dataSource == null && allowOutsideBaseDir ) {
290+ dataSource = tryLoadingFromDisk (new File ("." , srcLocation ));
291+ if (dataSource == null ) {
292+ dataSource = tryLoadingFromDisk (new File (srcLocation ));
293+ }
294+ }
295+ }
296+ }
297+ return dataSource ;
298+ }
299+
300+ @ Nullable
301+ public static DataSource tryResolveFileDataSourceFromClassPath (final @ Nullable String baseClassPath , final boolean allowOutsideBaseClassPath , final @ NotNull String srcLocation )
281302 throws IOException {
282- DataSource fileSource = tryResolveImageFileDataSourceFromDisk (baseDir , srcLocation );
283- return (fileSource != null ) ? fileSource : tryResolveFileDataSourceFromClassPath (baseClassPath , srcLocation );
303+ DataSource dataSource ;
304+
305+ if (baseClassPath == null ) {
306+ dataSource = tryLoadingFromClassPath (srcLocation );
307+ } else {
308+ if (srcLocation .startsWith (baseClassPath )) {
309+ dataSource = tryLoadingFromClassPath (srcLocation );
310+ } else {
311+ dataSource = tryLoadingFromClassPath (baseClassPath + srcLocation );
312+ if (dataSource == null && allowOutsideBaseClassPath ) {
313+ dataSource = tryLoadingFromClassPath (srcLocation );
314+ }
315+ }
316+ }
317+ return dataSource ;
284318 }
285319
286320 @ Nullable
287- private static DataSource tryResolveImageFileDataSourceFromDisk (final @ Nullable String baseDir , final @ NotNull String srcLocation ) {
288- File file = new File (srcLocation );
289- if (!file .exists () && !file .isAbsolute ()) {
290- file = new File (ofNullable (baseDir ).orElse ("." ), srcLocation );
321+ public static DataSource tryResolveUrlDataSource (@ Nullable final URL baseUrl , final boolean allowOutsideBaseUrl , @ NotNull final String srcLocation )
322+ throws IOException {
323+ DataSource dataSource ;
324+
325+ if (baseUrl == null ) {
326+ dataSource = tryLoadingFromUrl (srcLocation );
327+ } else {
328+ if (isCorrectlyFormattedUrl (srcLocation ) && new URL (srcLocation ).getPath ().startsWith (baseUrl .getPath ())) {
329+ dataSource = tryLoadingFromUrl (srcLocation );
330+ } else {
331+ final String urlPath = (baseUrl .getAuthority () + baseUrl .getPath () + "/" + srcLocation )
332+ .replaceAll ("/\\ \\ " , "/" )
333+ .replaceAll ("//" , "/" );
334+ final String url = format ("%s://%s" , baseUrl .getProtocol (), urlPath );
335+
336+ dataSource = tryLoadingFromUrl (url );
337+ if (dataSource == null && allowOutsideBaseUrl ) {
338+ dataSource = tryLoadingFromUrl (srcLocation );
339+ }
340+ }
291341 }
292- if (file .exists ()) {
293- final FileDataSource fileDataSource = new FileDataSource (file );
342+ return dataSource ;
343+ }
344+
345+ @ Nullable
346+ private static DataSource tryLoadingFromDisk (@ NotNull final File srcLocation ) {
347+ if (srcLocation .exists ()) {
348+ final FileDataSource fileDataSource = new FileDataSource (srcLocation );
294349 fileDataSource .setFileTypeMap (ImageMimeType .IMAGE_MIMETYPES_FILE_TYPE_MAP );
295350 return fileDataSource ;
296351 }
297352 return null ;
298353 }
299354
300355 @ Nullable
301- private static DataSource tryResolveFileDataSourceFromClassPath (final @ Nullable String baseClassPath , final @ NotNull String srcLocation )
356+ private static DataSource tryLoadingFromClassPath (final @ NotNull String resourceName )
302357 throws IOException {
303- final String resourceName = ( ofNullable ( baseClassPath ). orElse ( "" ) + srcLocation ) .replaceAll ("//" , "/" );
304- final InputStream is = MiscUtil .class .getResourceAsStream (resourceName );
358+ final String cleanResourceName = resourceName .replaceAll ("//" , "/" );
359+ final InputStream is = MiscUtil .class .getResourceAsStream (cleanResourceName );
305360
306361 if (is != null ) {
307362 try {
308- final String mimeType = ImageMimeType .getContentType (srcLocation );
363+ final String mimeType = ImageMimeType .getContentType (resourceName );
309364 final ByteArrayDataSource ds = new ByteArrayDataSource (is , mimeType );
310365 // EMAIL-125: set the name of the DataSource to the normalized resource URL similar to other DataSource implementations, e.g. FileDataSource, URLDataSource
311- ds .setName (MiscUtil .class .getResource (resourceName ).toString ());
366+ ds .setName (MiscUtil .class .getResource (cleanResourceName ).toString ());
312367 return ds ;
313368 } finally {
314369 is .close ();
@@ -317,16 +372,24 @@ private static DataSource tryResolveFileDataSourceFromClassPath(final @Nullable
317372 return null ;
318373 }
319374
320- @ NotNull
321- public static DataSource resolveUrlDataSource (@ Nullable final URL baseUrl , @ NotNull final String srcLocation )
322- throws IOException {
323- final URL url = (valueNullOrEmpty (baseUrl ) || ABSOLUTE_URL_PATTERN .matcher (srcLocation ).matches ())
324- ? new URL (srcLocation )
325- : new URL (baseUrl , srcLocation .replaceAll ("&" , "&" ));
375+ @ Nullable
376+ private static DataSource tryLoadingFromUrl (final String url ) {
377+ try {
378+ final DataSource result = new URLDataSource (new URL (url ));
379+ result .getInputStream ();
380+ return result ;
381+ } catch (IOException e ) {
382+ return null ;
383+ }
384+ }
326385
327- DataSource result = new URLDataSource (url );
328- result .getInputStream ();
329- return result ;
386+ public static boolean isCorrectlyFormattedUrl (final String srcLocation ) {
387+ try {
388+ new URL (srcLocation );
389+ return true ;
390+ } catch (IOException e ) {
391+ return false ;
392+ }
330393 }
331394
332395 public static String randomCid10 () {
0 commit comments