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.mail2.jakarta.resolver;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.net.MalformedURLException;
22  import java.net.URL;
23  
24  import org.apache.commons.mail2.core.EmailUtils;
25  
26  import jakarta.activation.DataSource;
27  import jakarta.activation.URLDataSource;
28  
29  /**
30   * Creates a {@code DataSource} based on an URL.
31   *
32   * @since 1.3
33   */
34  public class DataSourceUrlResolver extends DataSourceBaseResolver {
35  
36      /** The base url of the resource when resolving relative paths */
37      private final URL baseUrl;
38  
39      /**
40       * Constructs a new instance.
41       *
42       * @param baseUrl the base URL used for resolving relative resource locations
43       */
44      public DataSourceUrlResolver(final URL baseUrl) {
45          this.baseUrl = baseUrl;
46      }
47  
48      /**
49       * Constructs a new instance.
50       *
51       * @param baseUrl the base URL used for resolving relative resource locations
52       * @param lenient shall we ignore resources not found or complain with an exception
53       */
54      public DataSourceUrlResolver(final URL baseUrl, final boolean lenient) {
55          super(lenient);
56          this.baseUrl = baseUrl;
57      }
58  
59      /**
60       * Create an URL based on a base URL and a resource location suitable for loading the resource.
61       *
62       * @param resourceLocation a resource location
63       * @return the corresponding URL
64       * @throws java.net.MalformedURLException creating the URL failed
65       */
66      protected URL createUrl(final String resourceLocation) throws MalformedURLException {
67          // if we get an non-existing base url than the resource can
68          // be directly used to create an URL
69          if (baseUrl == null) {
70              return new URL(resourceLocation);
71          }
72          // if we get an non-existing location what we shall do?
73          if (EmailUtils.isEmpty(resourceLocation)) {
74              throw new IllegalArgumentException("No resource defined");
75          }
76          // if we get a stand-alone resource than ignore the base url
77          if (isFileUrl(resourceLocation) || isHttpUrl(resourceLocation)) {
78              return new URL(resourceLocation);
79          }
80          return new URL(getBaseUrl(), resourceLocation.replace("&", "&"));
81      }
82  
83      /**
84       * Gets the base URL used for resolving relative resource locations.
85       *
86       * @return the baseUrl
87       */
88      public URL getBaseUrl() {
89          return baseUrl;
90      }
91  
92      /** {@inheritDoc} */
93      @Override
94      public DataSource resolve(final String resourceLocation) throws IOException {
95          return resolve(resourceLocation, isLenient());
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     public DataSource resolve(final String resourceLocation, final boolean isLenient) throws IOException {
101         DataSource result = null;
102         try {
103             if (!isCid(resourceLocation)) {
104                 result = new URLDataSource(createUrl(resourceLocation));
105                 // validate we can read.
106                 try (InputStream inputStream = result.getInputStream()) {
107                     inputStream.read();
108                 }
109             }
110             return result;
111         } catch (final IOException e) {
112             if (isLenient) {
113                 return null;
114             }
115             throw e;
116         }
117     }
118 }