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 */
030public class DataSourceCompositeResolver extends DataSourceBaseResolver
031{
032    /** the list of resolvers */
033    private final DataSourceResolver[] dataSourceResolvers;
034
035    /**
036     * Constructor.
037     *
038     * @param dataSourceResolvers a list of of resolvers being used
039     */
040    public DataSourceCompositeResolver(final DataSourceResolver[] dataSourceResolvers)
041    {
042        this.dataSourceResolvers = new DataSourceResolver[dataSourceResolvers.length];
043        System.arraycopy(dataSourceResolvers, 0, this.dataSourceResolvers, 0, dataSourceResolvers.length);
044    }
045
046    /**
047     * Constructor.
048     *
049     * @param dataSourceResolvers a list of of resolvers being used
050     * @param isLenient shall we ignore resources not found or throw an exception?
051     */
052    public DataSourceCompositeResolver(final DataSourceResolver[] dataSourceResolvers, final boolean isLenient)
053    {
054        super(isLenient);
055        this.dataSourceResolvers = new DataSourceResolver[dataSourceResolvers.length];
056        System.arraycopy(dataSourceResolvers, 0, this.dataSourceResolvers, 0, dataSourceResolvers.length);
057    }
058
059    /**
060     * Get the underlying data source resolvers.
061     *
062     * @return underlying data source resolvers
063     */
064    public DataSourceResolver[] getDataSourceResolvers()
065    {
066        // clone the internal array to prevent external modification (see EMAIL-116)
067        final DataSourceResolver[] resolvers = new DataSourceResolver[dataSourceResolvers.length];
068        System.arraycopy(dataSourceResolvers, 0, resolvers, 0, dataSourceResolvers.length);
069        return resolvers;
070    }
071
072    /** {@inheritDoc} */
073    @Override
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    @Override
088    public DataSource resolve(final String resourceLocation, final boolean isLenient) throws IOException
089    {
090        for (int i = 0; i < getDataSourceResolvers().length; i++)
091        {
092            final DataSourceResolver dataSourceResolver = getDataSourceResolvers()[i];
093            final DataSource dataSource = dataSourceResolver.resolve(resourceLocation, isLenient);
094
095            if (dataSource != null)
096            {
097                return dataSource;
098            }
099        }
100
101        if (isLenient)
102        {
103            return null;
104        }
105        throw new IOException("The following resource was not found : " + resourceLocation);
106    }
107}