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 */ 017package org.apache.commons.mail2.jakarta.resolver; 018 019import java.io.IOException; 020import java.io.InputStream; 021import java.net.URL; 022 023import jakarta.activation.DataSource; 024import jakarta.activation.FileTypeMap; 025import jakarta.mail.util.ByteArrayDataSource; 026 027/** 028 * Creates a {@code DataSource} based on an class path. 029 * 030 * @since 1.3 031 */ 032public class DataSourceClassPathResolver extends DataSourceBaseResolver { 033 /** The base string of the resource relative to the classpath when resolving relative paths */ 034 private final String classPathBase; 035 036 /** 037 * Constructs a new instance. 038 */ 039 public DataSourceClassPathResolver() { 040 this("/"); 041 } 042 043 /** 044 * Constructs a new instance. 045 * 046 * @param classPathBase a base class path 047 */ 048 public DataSourceClassPathResolver(final String classPathBase) { 049 this(classPathBase, false); 050 } 051 052 /** 053 * Constructs a new instance. 054 * 055 * @param classPathBase a base class path 056 * @param lenient shall we ignore resources not found or throw an exception? 057 */ 058 public DataSourceClassPathResolver(final String classPathBase, final boolean lenient) { 059 super(lenient); 060 this.classPathBase = classPathBase.endsWith("/") ? classPathBase : classPathBase + "/"; 061 } 062 063 /** 064 * Gets the class path base. 065 * 066 * @return the classPathBase 067 */ 068 public String getClassPathBase() { 069 return classPathBase; 070 } 071 072 /** 073 * Returns the resource name for a given resource location. 074 * 075 * @param resourceLocation the resource location 076 * @return {@link #getClassPathBase()} + {@code resourceLocation} 077 * @see #getClassPathBase() 078 */ 079 private String getResourceName(final String resourceLocation) { 080 return (getClassPathBase() + resourceLocation).replace("//", "/"); 081 } 082 083 /** {@inheritDoc} */ 084 @Override 085 public DataSource resolve(final String resourceLocation) throws IOException { 086 return resolve(resourceLocation, isLenient()); 087 } 088 089 /** {@inheritDoc} */ 090 @Override 091 public DataSource resolve(final String resourceLocation, final boolean isLenient) throws IOException { 092 try { 093 if (!isCid(resourceLocation) && !isHttpUrl(resourceLocation)) { 094 final String mimeType = FileTypeMap.getDefaultFileTypeMap().getContentType(resourceLocation); 095 final String resourceName = getResourceName(resourceLocation); 096 try (InputStream inputStream = DataSourceClassPathResolver.class.getResourceAsStream(resourceName)) { 097 if (inputStream == null) { 098 if (isLenient) { 099 return null; 100 } 101 throw new IOException("The following class path resource was not found : " + resourceLocation); 102 } 103 final ByteArrayDataSource ds = new ByteArrayDataSource(inputStream, mimeType); 104 // EMAIL-125: set the name of the DataSource to the normalized resource URL 105 // similar to other DataSource implementations, e.g. FileDataSource, URLDataSource 106 final URL resource = DataSourceClassPathResolver.class.getResource(resourceName); 107 if (resource != null) { 108 ds.setName(resource.toString()); 109 } else if (isLenient) { 110 return null; 111 } else { 112 throw new IOException("The following class path resource was not found : " + resourceName); 113 } 114 return ds; 115 } 116 } 117 return null; 118 } catch (final IOException e) { 119 if (isLenient) { 120 return null; 121 } 122 throw e; 123 } 124 } 125}