org.ajax4jsf.resource.InternetResourceBase.java Source code

Java tutorial

Introduction

Here is the source code for org.ajax4jsf.resource.InternetResourceBase.java

Source

/**
 * License Agreement.
 *
 * Rich Faces - Natural Ajax for Java Server Faces (JSF)
 *
 * Copyright (C) 2007 Exadel, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 */

package org.ajax4jsf.resource;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.faces.context.FacesContext;

import org.ajax4jsf.Messages;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Base class for all Html page resources - images, scripts, styles etc. Realise
 * as "brige" pattern - different subclasses for different resource source
 * (static,jar,soft generator ) and customaized with differernt renderers for
 * image, script, style ( linked ir inline ). must operate with different
 * sources - application context, classpath, software generator.
 * 
 * @author shura (latest modification by $Author: nick_belaevski $)
 * @version $Revision: 1.1.2.2 $ $Date: 2007/01/11 16:52:15 $
 * 
 */
public abstract class InternetResourceBase implements InternetResource {

    private static final Log log = LogFactory.getLog(InternetResourceBase.class);

    static final int BUFFER_SIZE = 1024;

    // Hours

    private int contentLength = -1;

    private Date lastModified = new Date(System.currentTimeMillis());

    private long expired = Long.MIN_VALUE;

    private boolean cacheable = true;

    private boolean sessionAware = true;

    private ResourceRenderer renderer = null;

    private Map<Object, Object> customProperties = new HashMap<Object, Object>();

    private String key;

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.chameleon.resource.InternetResource#getContentLength()
     */
    public int getContentLength(ResourceContext resourceContext) {
        return contentLength;
    }

    /**
     * @param contentLength
     *            The contentLength to set.
     */
    protected void setContentLength(int contentLength) {
        this.contentLength = contentLength;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.chameleon.resource.InternetResource#getExpired()
     */
    public long getExpired(ResourceContext resourceContext) {
        if (expired == Long.MIN_VALUE) {
            expired = -1;
            String defaultExpireParameter = resourceContext
                    .getInitParameter(InternetResource.DEFAULT_EXPITE_PARAMETER);
            if (null != defaultExpireParameter) {
                expired = Long.parseLong(defaultExpireParameter) * 1000L;
            }
        }
        return expired;
    }

    /**
     * @param expired
     *            The expired to set.
     */
    public void setExpired(long expired) {
        this.expired = expired;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.chameleon.resource.InternetResource#getLastModified()
     */
    public Date getLastModified(ResourceContext resourceContext) {

        if (null != lastModified) {
            return lastModified;
        } else {
            return new Date(System.currentTimeMillis());
        }
    }

    /**
     * @param lastModified
     *            The lastModified to set.
     */
    public void setLastModified(Date lastModified) {
        this.lastModified = lastModified;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.chameleon.resource.InternetResource#isCacheable()
     */
    public boolean isCacheable(ResourceContext resourceContext) {
        return cacheable;
    }

    /**
     * @param cacheable
     *            The cacheable to set.
     */
    public void setCacheable(boolean cacheable) {
        this.cacheable = cacheable;
    }

    /**
     * @return Returns the sessionAware.
     */
    public boolean isSessionAware() {
        return requireFacesContext();
    }

    /**
     * @param sessionAware
     *            The sessionAware to set.
     */
    public void setSessionAware(boolean sessionAware) {
        this.sessionAware = sessionAware;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.chameleon.resource.InternetResource#getContentType()
     */
    public String getContentType(ResourceContext resourceContext) {
        return getRenderer(resourceContext).getContentType();
    }

    /**
     * @return Returns the renderer.
     */
    public ResourceRenderer getRenderer(ResourceContext resourceContext) {
        return renderer;
    }

    /**
     * @param renderer
     *            The renderer to set.
     */
    public void setRenderer(ResourceRenderer renderer) {
        this.renderer = renderer;
    }

    /**
     * Key for wich resource registered in resource builder.
     * 
     * @return Returns the key.
     */
    public String getKey() {
        return key;
    }

    /**
     * Set registration key ( by {@link InternetResourceBuilder} for this
     * resource.
     * 
     * @param key
     *            The key to set.
     */
    public void setKey(String key) {
        this.key = key;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.resource.InternetResource#getUri(javax.faces.context.FacesContext,
     *      java.lang.Object)
     */
    public String getUri(final FacesContext context, Object data) {
        return InternetResourceBuilder.getInstance().getUri(this, context, getDataToStore(context, data));
    }

    /**
     * Template method to construct resource-specific data ( to store in
     * resource URI ). If resource must store any data in session or other
     * cache, it must be done here. Since lightweight realisation, information
     * for restore such data muct be returned by this method.
     * 
     * @param context -
     *            current faces context.
     * @param data -
     *            data for build information, usually current
     *            {@link javax.faces.component.UIComponent}
     * @return - any {@link java.io.Serializable} object, or null.
     */
    protected Object getDataToStore(FacesContext context, Object data) {
        return getRenderer(new FacesResourceContext(context)).getData(this, context, data);
    }

    /**
     * Restore data object from resource URI request parameter ( same object as
     * returned in getDataToStore method )
     * 
     * @param context
     * @return restored data, or null.
     */
    protected Object restoreData(ResourceContext context) {

        Object data = context.getResourceData();
        if (data instanceof byte[]) {
            byte[] objectArray = (byte[]) data;
            data = deserializeData(objectArray);
        }
        return data;

    }

    /**
     * Deserialize parameters object from byte array. By default, used Java
     * de-serialisation from ObjectOutputStream , but implementations can
     * override this method ( togewer with getDataToStore ) for implement short
     * version.
     * 
     * @param objectArray
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    protected Object deserializeData(byte[] objectArray) {
        return objectArray;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.chameleon.resource.InternetResource#getResourceAsStream()
     */
    public InputStream getResourceAsStream(ResourceContext context) {
        throw new UnsupportedOperationException(
                Messages.getMessage(Messages.METHOD_NOT_IMPLEMENTED, "getResourceAsStream"));
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.resource.InternetResource#getProperty(java.lang.Object)
     */
    public Object getProperty(Object key) {
        // TODO Auto-generated method stub
        return customProperties.get(key);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.resource.InternetResource#setProperty(java.lang.Object,
     *      java.lang.Object)
     */
    public void setProperty(Object key, Object value) {
        customProperties.put(key, value);

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.resource.InternetResource#encode(javax.faces.context.FacesContext,
     *      javax.faces.component.UIComponent)
     */
    public void encode(FacesContext context, Object data) throws IOException {
        if (log.isDebugEnabled()) {
            log.debug(Messages.getMessage(Messages.ENCODE_HTML_INFO, getKey()));
        }
        getRenderer(new FacesResourceContext(context)).encode(this, context, data);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.resource.InternetResource#encode(javax.faces.context.FacesContext,
     *      java.lang.Object, java.util.Map)
     */
    public void encode(FacesContext context, Object data, Map<String, Object> attributes) throws IOException {
        if (log.isDebugEnabled()) {
            log.debug(Messages.getMessage(Messages.ENCODE_HTML_INFO_2, getKey(), attributes));
        }
        getRenderer(new FacesResourceContext(context)).encodeBegin(this, context, data, attributes);
        getRenderer(new FacesResourceContext(context)).encodeEnd(this, context, data);

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.resource.InternetResource#encodeBegin(javax.faces.context.FacesContext,
     *      javax.faces.component.UIComponent, java.util.Map)
     */
    public void encodeBegin(FacesContext context, Object component, Map<String, Object> attrs) throws IOException {
        if (log.isDebugEnabled()) {
            log.debug(Messages.getMessage(Messages.ENCODE_BEGIN_HTML_INFO, getKey(), attrs));
        }
        getRenderer(new FacesResourceContext(context)).encodeBegin(this, context, component, attrs);

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.resource.InternetResource#encodeEnd(javax.faces.context.FacesContext,
     *      javax.faces.component.UIComponent, java.util.Map)
     */
    public void encodeEnd(FacesContext context, Object component) throws IOException {
        if (log.isDebugEnabled()) {
            log.debug(Messages.getMessage(Messages.ENCODE_END_HTML_INFO, getKey()));
        }
        getRenderer(new FacesResourceContext(context)).encodeEnd(this, context, component);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.resource.InternetResource#send(javax.faces.context.FacesContext,
     *      java.lang.Object)
     */
    public void send(ResourceContext context) throws IOException {
        if (log.isDebugEnabled()) {
            log.debug(Messages.getMessage(Messages.SEND_CONTENT_INFO, getKey()));
        }
        int total = getRenderer(context).send(this, context);
        // For cacheable resources, store size.
        if (isCacheable(context)) {
            if (context instanceof CachedResourceContext) {
                CachedResourceContext cachedContext = (CachedResourceContext) context;
                cachedContext.getContent().setContentLength(total);
            } else {
                setContentLength(total);
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.chameleon.resource.InternetResource#sendHeaders(javax.servlet.http.HttpServletResponse)
     */
    public void sendHeaders(ResourceContext context) {
        boolean cached = context.isCacheEnabled() && isCacheable(context);
        if (log.isDebugEnabled()) {
            log.debug(Messages.getMessage(Messages.SET_RESPONSE_HEADERS_INFO, getKey()));
        }
        // context.setHeader("Content-Type",getContentType());
        context.setContentType(getContentType(context));
        Date lastModified = getLastModified(context);
        if (lastModified != null) {
            context.setDateHeader("Last-Modified", lastModified.getTime());
        }
        int contentLength = getContentLength(context);
        if (cached) {
            if (contentLength > 0) {
                context.setContentLength(contentLength);
            }
            long expired = getExpired(context);
            if (expired < 0) {
                expired = DEFAULT_EXPIRE;
            }
            context.setDateHeader("Expires", System.currentTimeMillis() + expired);
            context.setHeader("Cache-control", "max-age=" + (expired / 1000L));
        } else {
            if (contentLength > 0) {
                context.setContentLength(contentLength);
                // } else {
                // context.setHeader("Transfer-Encoding", "chunked");
            }
            context.setHeader("Cache-control", "max-age=0, no-store, no-cache");
            context.setHeader("Pragma", "no-cache");
            context.setIntHeader("Expires", 0);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajax4jsf.resource.InternetResource#requireFacesContext()
     */
    public boolean requireFacesContext() {
        // by default, send data in ordinary Http request.
        return getRenderer(null).requireFacesContext();
    }

}