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