Package com.sun.facelets.impl

Source Code of com.sun.facelets.impl.DefaultFaceletFactory

/**
* Licensed under the Common Development and Distribution License,
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.sun.com/cddl/
*  
* 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 com.sun.facelets.impl;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.el.ELException;
import javax.faces.FacesException;
import javax.faces.context.FacesContext;

import com.sun.facelets.Facelet;
import com.sun.facelets.FaceletException;
import com.sun.facelets.FaceletFactory;
import com.sun.facelets.FaceletHandler;
import com.sun.facelets.compiler.Compiler;
import com.sun.facelets.util.ParameterCheck;
import com.sun.facelets.util.Resource;

/**
* Default FaceletFactory implementation.
*
* @author Jacob Hookom
* @version $Id: DefaultFaceletFactory.java,v 1.10 2007/04/09 01:13:17 youngm Exp $
*/
public final class DefaultFaceletFactory extends FaceletFactory {

    protected final static Logger log = Logger.getLogger("facelets.factory");

    private final Compiler compiler;

    private Map facelets;

    private Map relativeLocations;
   
    private final ResourceResolver resolver;
   
    private final URL baseUrl;

    private final long refreshPeriod;

    public DefaultFaceletFactory(Compiler compiler, ResourceResolver resolver) throws IOException {
        this(compiler, resolver, -1);
    }

    public DefaultFaceletFactory(Compiler compiler, ResourceResolver resolver, long refreshPeriod) {
        ParameterCheck.notNull("compiler", compiler);
        ParameterCheck.notNull("resolver", resolver);
        this.compiler = compiler;
        this.facelets = new HashMap();
        this.relativeLocations = new HashMap();
        this.resolver = resolver;
        this.baseUrl = resolver.resolveUrl("/");
        //this.location = url;
        log.fine("Using ResourceResolver: " + resolver);
        this.refreshPeriod = (refreshPeriod >= 0) ? refreshPeriod * 1000 : -1;
        log.fine("Using Refresh Period: " + this.refreshPeriod);
    }

    /*
     * (non-Javadoc)
     *
     * @see com.sun.facelets.FaceletFactory#getFacelet(java.lang.String)
     */
    public Facelet getFacelet(String uri) throws IOException, FaceletException,
            FacesException, ELException {
        URL url = (URL) this.relativeLocations.get(uri);
        if (url == null) {
            url = this.resolveURL(this.baseUrl, uri);
            if (url != null) {
              Map newLoc = new HashMap(this.relativeLocations);
              newLoc.put(uri, url);
                this.relativeLocations = newLoc;
            } else {
                throw new IOException("'" + uri + "' not found.");
            }
        }
        return this.getFacelet(url);
    }

    /**
     * Resolves a path based on the passed URL. If the path starts with '/',
     * then resolve the path against
     * {@link javax.faces.context.ExternalContext#getResource(java.lang.String) javax.faces.context.ExternalContext#getResource(java.lang.String)}.
     * Otherwise create a new URL via
     * {@link URL#URL(java.net.URL, java.lang.String) URL(URL, String)}.
     *
     * @param source
     *            base to resolve from
     * @param path
     *            relative path to the source
     * @return resolved URL
     * @throws IOException
     */
    public URL resolveURL(URL source, String path) throws IOException {
        if (path.startsWith("/")) {
            URL url = this.resolver.resolveUrl(path);
            if (url == null) {
                throw new FileNotFoundException(path
                        + " Not Found in ExternalContext as a Resource");
            }
            return url;
        } else {
            return new URL(source, path);
        }
    }

    /**
     * Create a Facelet from the passed URL. This method checks if the cached
     * Facelet needs to be refreshed before returning. If so, uses the passed
     * URL to build a new instance;
     *
     * @param url
     *            source url
     * @return Facelet instance
     * @throws IOException
     * @throws FaceletException
     * @throws FacesException
     * @throws ELException
     */
    public Facelet getFacelet(URL url) throws IOException, FaceletException,
            FacesException, ELException {
        ParameterCheck.notNull("url", url);
        String key = url.toString();
        DefaultFacelet f = (DefaultFacelet) this.facelets.get(key);
        if (f == null || this.needsToBeRefreshed(f)) {
            f = this.createFacelet(url);
            Map newLoc = new HashMap(this.facelets);
          newLoc.put(key, f);
            this.facelets = newLoc;
        }
        return f;
    }

    /**
     * Template method for determining if the Facelet needs to be refreshed.
     *
     * @param facelet
     *            Facelet that could have expired
     * @return true if it needs to be refreshed
     */
    protected boolean needsToBeRefreshed(DefaultFacelet facelet) {
        if (this.refreshPeriod != -1) {
            long ttl = facelet.getCreateTime() + this.refreshPeriod;
            if (System.currentTimeMillis() > ttl) {
                try {
                    long atl = facelet.getSource().openConnection()
                            .getLastModified();
                    return atl == 0 || atl > ttl;
                } catch (Exception e) {
                    throw new FaceletException(
                            "Error Checking Last Modified for "
                                    + facelet.getAlias(), e);
                }
            }
        }
        return false;
    }

    /**
     * Uses the internal Compiler reference to build a Facelet given the passed
     * URL.
     *
     * @param url
     *            source
     * @return a Facelet instance
     * @throws IOException
     * @throws FaceletException
     * @throws FacesException
     * @throws ELException
     */
    private DefaultFacelet createFacelet(URL url) throws IOException,
            FaceletException, FacesException, ELException {
        if (log.isLoggable(Level.FINE)) {
            log.fine("Creating Facelet for: " + url);
        }
        String alias = "/"
                + url.getFile().replaceFirst(this.baseUrl.getFile(), "");
        try {
            FaceletHandler h = this.compiler.compile(url, alias);
            DefaultFacelet f = new DefaultFacelet(this, this.compiler
                    .createExpressionFactory(), url, alias, h);
            return f;
        } catch (FileNotFoundException fnfe) {
            if (log.isLoggable(Level.WARNING)) {
                log.warning(alias + " not found at " + url.toExternalForm());
            }
            throw new FileNotFoundException("Facelet Not Found: " + url.toExternalForm());
        }
    }

    /**
     * Compiler this factory uses
     *
     * @return final Compiler instance
     */
    public Compiler getCompiler() {
        return this.compiler;
    }

    public long getRefreshPeriod() {
        return refreshPeriod;
    }
}
TOP

Related Classes of com.sun.facelets.impl.DefaultFaceletFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.