/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.mail.resolver;

import javax.activation.DataSource;
import javax.activation.FileDataSource;
import java.io.File;
import java.io.IOException;

/**
 * Creates a <code>DataSource</code> based on an URL. The implementation
 * also resolves file resources.
 *
 * @since 1.3
 */
public class DataSourceFileResolver extends DataSourceBaseResolver
{
    /** the base directory of the resource when resolving relative paths */
    private final File baseDir;

    /**
     * Constructor.
     */
    public DataSourceFileResolver()
    {
        baseDir = new File(".");
    }

    /**
     * Constructor.
     *
     * @param baseDir the base directory of the resource when resolving relative paths
     */
    public DataSourceFileResolver(final File baseDir)
    {
        this.baseDir = baseDir;
    }

    /**
     * Constructor.
     *
     * @param baseDir the base directory of the resource when resolving relative paths
     * @param lenient shall we ignore resources not found or complain with an exception
     */
    public DataSourceFileResolver(final File baseDir, final boolean lenient)
    {
        super(lenient);
        this.baseDir = baseDir;
    }

    /**
     * Get the base directory used for resolving relative resource locations.
     *
     * @return the baseUrl
     */
    public File getBaseDir()
    {
        return baseDir;
    }

    /** {@inheritDoc} */
    @Override
    public DataSource resolve(final String resourceLocation) throws IOException
    {
        return resolve(resourceLocation, isLenient());
    }

    /** {@inheritDoc} */
    @Override
    public DataSource resolve(final String resourceLocation, final boolean isLenient) throws IOException
    {
        File file;
        DataSource result = null;

        if (!isCid(resourceLocation))
        {
            file = new File(resourceLocation);

            if (!file.isAbsolute())
            {
                file = getBaseDir() != null ? new File(getBaseDir(), resourceLocation) : new File(resourceLocation);
            }

            if (file.exists())
            {
                result = new FileDataSource(file);
            }
            else
            {
                if (!isLenient)
                {
                    throw new IOException("Cant resolve the following file resource :" + file.getAbsolutePath());
                }
            }
        }

        return result;
    }
}
