/*
 * 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.sling.jcr.classloader.internal;

import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessControlException;

import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.sling.jcr.classloader.internal.net.URLFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The <code>ClassPathEntry</code> class encapsulates entries in the class path
 * of the {@link DynamicRepositoryClassLoader}. The main task is to retrieve
 * {@link ClassLoaderResource} instances for classes or resources to load from it.
 * <p>
 * This implementation is not currently integrated with Java security. That is
 * protection domains and security managers are not supported yet.
 * <p>
 * This class is not intended to be subclassed or instantiated by clients.
 */
public final class ClassPathEntry {

    /** default logging */
    private static final Logger log = LoggerFactory.getLogger(ClassPathEntry.class);

    /** The session assigned to this class path entry */
    protected final Session session;

    /** The path to the item of this class path entry */
    protected final String path;

    /** The base URL for the class path entry to later construct resource URLs */
    protected URL baseURL;

    //---------- construction --------------------------------------------------

    /**
     * Creates an instance of the <code>ClassPathEntry</code> assigning the
     * session and path.
     *
     * @param session The <code>Session</code> to access the Repository.
     * @param path The path of the class path entry, this is either the
     *      path of a node containing a jar archive or is the path
     *      of the root of a hierarchy to look up resources in.
     */
    protected ClassPathEntry(Session session, String path) {
        this.path = path;
        this.session = session;
    }

    /**
     * Clones this instance of the <code>ClassPathEntry</code> setting the
     * path and session to the same value as the base instance.
     * <p>
     * Note that this constructor does not duplicate the session from the base
     * instance.
     *
     * @param base The <code>ClassPathEntry</code> from which to copy the path
     *      and the session.
     */
    protected ClassPathEntry(ClassPathEntry base) {
        this.path = base.path;
        this.session = base.session;
        this.baseURL = base.baseURL;
    }

    /**
     * Returns an instance of the <code>ClassPathEntry</code> class. This
     * instance will be a subclass correctly handling the type (directory or
     * jar archive) of class path entry is to be created.
     * <p>
     * If the path given has a trailing slash, it is taken as a directory root
     * else the path is first tested, whether it contains an archive. If not
     * the path is treated as a directory.
     *
     * @param session The <code>Session</code> to access the Repository.
     * @param path The path of the class path entry, this is either the
     *      path of a node containing a jar archive or is the path
     *      of the root of a hierharchy to look up resources in.
     *
     * @return An initialized <code>ClassPathEntry</code> instance for the
     *      path or <code>null</code> if an error occurred creating the
     *      instance.
     */
    static ClassPathEntry getInstance(Session session, String path) {

        // check we can access the path, don't care about content now
        try {
            session.checkPermission(path, "read");
        } catch (AccessControlException ace) {
            log.warn(
                "getInstance: Access denied reading from {}, ignoring entry",
                path);
            return null;
        } catch (RepositoryException re) {
            log.error("getInstance: Cannot check permission to " + path, re);
        }

        if (!path.endsWith("/")) {
            // assume the path designates a directory
            // append trailing slash now
            path += "/";
        }

        // we assume a directory class path entry, but we might have to check
        // whether the path refers to a node or not. On the other hande, this
        // class path entry will not be usable anyway if not, user beware :-)

        return new ClassPathEntry(session, path);
    }

    /**
     * Returns the path on which this <code>ClassPathEntry</code> is based.
     */
    public String getPath() {
        return path;
    }

    /**
     * Returns this <code>ClassPathEntry</code> represented as an URL to be
     * used in a list of URLs to further work on. If there is a problem creating
     * the URL for this instance, <code>null</code> is returned instead.
     */
    public URL toURL() {
        if (baseURL == null) {
            try {
                baseURL = URLFactory.createURL(session, path);
            } catch (MalformedURLException mue) {
                log.warn("DirectoryClassPathEntry: Creating baseURl for " +
                    path, mue);
            }
        }

        return baseURL;
    }

    /**
     * Returns a {@link ClassLoaderResource} for the named resource if it
     * can befound below this directory root identified by the path given
     * at construction time. Note that if the page would exist but does
     * either not contain content or is not readable by the current session,
     * no resource is returned.
     *
     * @param name The name of the resource to return. If the resource would
     *      be a class the name must already be modified to denote a valid
     *      path, that is dots replaced by dashes and the <code>.class</code>
     *      extension attached.
     *
     * @return The {@link ClassLoaderResource} identified by the name or
     *      <code>null</code> if no resource is found for that name.
     */
    public ClassLoaderResource getResource(final String name) {

        try {
            final Property prop = Util.getProperty(session.getItem(path + name));
            if (prop != null) {
                return new ClassLoaderResource(this, name, prop);
            }

            log.debug("getResource: resource {} not found below {} ", name,
                path);

        } catch (PathNotFoundException pnfe) {

            log.debug("getResource: Classpath entry {} does not have resource {}",
                path, name);

        } catch (RepositoryException cbe) {

            log.warn("getResource: problem accessing the resource {} below {}",
                new Object[] { name, path }, cbe);

        }
        // invariant : no page or problem accessing the page

        return null;
    }

    /**
     * @see Object#toString()
     */
    public String toString() {
        StringBuilder buf = new StringBuilder(super.toString());
        buf.append(": path: ");
        buf.append(path);
        buf.append(", user: ");
        buf.append(session.getUserID());
        return buf.toString();
    }

    //----------- internal helper ----------------------------------------------

}
