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 org.apache.commons.mail.DataSourceResolver;
020
021import javax.activation.DataSource;
022import java.io.IOException;
023
024/**
025 * A composite data source resolver. It allows to resolve data sources coming from
026 * multiple locations such as the classpath, the file system or an URL.
027 *
028 * @since 1.3
029 * @version $Id: DataSourceCompositeResolver.html 952467 2015-05-23 18:45:36Z tn $
030 */
031public class DataSourceCompositeResolver extends DataSourceBaseResolver
032{
033    /** the list of resolvers */
034    private final DataSourceResolver[] dataSourceResolvers;
035
036    /**
037     * Constructor.
038     *
039     * @param dataSourceResolvers a list of of resolvers being used
040     */
041    public DataSourceCompositeResolver(final DataSourceResolver[] dataSourceResolvers)
042    {
043        this.dataSourceResolvers = new DataSourceResolver[dataSourceResolvers.length];
044        System.arraycopy(dataSourceResolvers, 0, this.dataSourceResolvers, 0, dataSourceResolvers.length);
045    }
046
047    /**
048     * Constructor.
049     *
050     * @param dataSourceResolvers a list of of resolvers being used
051     * @param isLenient shall we ignore resources not found or throw an exception?
052     */
053    public DataSourceCompositeResolver(final DataSourceResolver[] dataSourceResolvers, final boolean isLenient)
054    {
055        super(isLenient);
056        this.dataSourceResolvers = new DataSourceResolver[dataSourceResolvers.length];
057        System.arraycopy(dataSourceResolvers, 0, this.dataSourceResolvers, 0, dataSourceResolvers.length);
058    }
059
060    /**
061     * Get the underlying data source resolvers.
062     *
063     * @return underlying data source resolvers
064     */
065    public DataSourceResolver[] getDataSourceResolvers()
066    {
067        // clone the internal array to prevent external modification (see EMAIL-116)
068        final DataSourceResolver[] resolvers = new DataSourceResolver[dataSourceResolvers.length];
069        System.arraycopy(dataSourceResolvers, 0, resolvers, 0, dataSourceResolvers.length);
070        return resolvers;
071    }
072
073    /** {@inheritDoc} */
074    public DataSource resolve(final String resourceLocation) throws IOException
075    {
076        final DataSource result = resolve(resourceLocation, true);
077
078        if (isLenient() || result != null)
079        {
080            return result;
081        }
082        throw new IOException("The following resource was not found : " + resourceLocation);
083
084    }
085
086    /** {@inheritDoc} */
087    public DataSource resolve(final String resourceLocation, final boolean isLenient) throws IOException
088    {
089        for (int i = 0; i < getDataSourceResolvers().length; i++)
090        {
091            final DataSourceResolver dataSourceResolver = getDataSourceResolvers()[i];
092            final DataSource dataSource = dataSourceResolver.resolve(resourceLocation, isLenient);
093
094            if (dataSource != null)
095            {
096                return dataSource;
097            }
098        }
099
100        if (isLenient)
101        {
102            return null;
103        }
104        throw new IOException("The following resource was not found : " + resourceLocation);
105    }
106}