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