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 package org.apache.commons.mail.resolver;
18
19 import org.apache.commons.mail.ByteArrayDataSource;
20
21 import javax.activation.DataSource;
22 import javax.activation.FileTypeMap;
23 import java.io.IOException;
24 import java.io.InputStream;
25
26 /**
27 * Creates a <code>DataSource</code> based on an class path.
28 *
29 * @since 1.3
30 * @version $Id: DataSourceClassPathResolver.java 1448981 2013-02-22 10:40:34Z tn $
31 */
32 public class DataSourceClassPathResolver extends DataSourceBaseResolver
33 {
34 /** the base string of the resource relative to the classpath when resolving relative paths */
35 private final String classPathBase;
36
37 /**
38 * Constructor
39 */
40 public DataSourceClassPathResolver()
41 {
42 this.classPathBase = "/";
43 }
44
45 /**
46 * Constructor.
47 *
48 * @param classPathBase a base class path
49 */
50 public DataSourceClassPathResolver(final String classPathBase)
51 {
52 this.classPathBase = classPathBase.endsWith("/") ? classPathBase : classPathBase + "/";
53 }
54
55 /**
56 * Constructor.
57 *
58 * @param classPathBase a base class path
59 * @param lenient shall we ignore resources not found or throw an exception?
60 */
61 public DataSourceClassPathResolver(final String classPathBase, final boolean lenient)
62 {
63 super(lenient);
64 this.classPathBase = classPathBase.endsWith("/") ? classPathBase : classPathBase + "/";
65 }
66
67 /**
68 * @return the classPathBase
69 */
70 public String getClassPathBase()
71 {
72 return classPathBase;
73 }
74
75 /** {@inheritDoc} */
76 public DataSource resolve(String resourceLocation) throws IOException
77 {
78 return resolve(resourceLocation, isLenient());
79 }
80
81 /** {@inheritDoc} */
82 public DataSource resolve(final String resourceLocation, final boolean isLenient) throws IOException
83 {
84 DataSource result = null;
85
86 try
87 {
88 if (!isCid(resourceLocation) && !isHttpUrl(resourceLocation))
89 {
90 String mimeType = FileTypeMap.getDefaultFileTypeMap().getContentType(resourceLocation);
91 String resourceName = getResourceName(resourceLocation);
92 InputStream is = DataSourceClassPathResolver.class.getResourceAsStream(resourceName);
93
94 if (is != null)
95 {
96 ByteArrayDataSource ds = new ByteArrayDataSource(is, mimeType);
97 // EMAIL-125: set the name of the DataSource to the normalized resource URL
98 // similar to other DataSource implementations, e.g. FileDataSource, URLDataSource
99 ds.setName(DataSourceClassPathResolver.class.getResource(resourceName).toString());
100 result = ds;
101 }
102 else
103 {
104 if (isLenient)
105 {
106 return null;
107 }
108 else
109 {
110 throw new IOException("The following class path resource was not found : " + resourceLocation);
111 }
112 }
113 }
114
115
116 return result;
117 }
118 catch (IOException e)
119 {
120 if (isLenient)
121 {
122 return null;
123 }
124 else
125 {
126 throw e;
127 }
128 }
129 }
130
131 /**
132 * Returns the resource name for a given resource location.
133 *
134 * @param resourceLocation the resource location
135 * @return {@link #getClassPathBase()} + {@code resourceLocation}
136 * @see #getClassPathBase()
137 */
138 private String getResourceName(final String resourceLocation)
139 {
140 return (getClassPathBase() + resourceLocation).replaceAll("//", "/");
141 }
142 }