All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wings.template.CachedFileTemplateSource Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2000,2005 wingS development team.
 *
 * This file is part of wingS (http://wingsframework.org).
 *
 * wingS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * Please see COPYING for the complete licence.
 */
package org.wings.template;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Hashtable;

/**
 * A CachedFileDataSource implements a DataSource
 * for a file, but caches small ones.
 *
 * @author Henner Zeller
 */
public class CachedFileTemplateSource extends FileTemplateSource {
    private final  static Logger log = LoggerFactory.getLogger(CachedFileTemplateSource.class);

    private final static class CacheEntry {
        private byte[] filebuffer = null;
        private long lastModified;
        private File file;

        public CacheEntry(File f) throws IOException {
            this.file = f;
            lastModified = -1;
            // we want to throw an IOException here if the file is not found
            if (file != null) {
                lastModified = file.lastModified();
                refresh();
            }
        }

        public CacheEntry(URL url) throws IOException {
            file = null;
            lastModified = System.currentTimeMillis();
            InputStream in = url.openStream();
            /*
             * unfortnunatly, we do not know the length of
             * the data ..
             */
            int totLen = 0;
            int copyLen = 0;
            byte[] tempBuffer = new byte[1024];
            do {
                copyLen = in.read(tempBuffer);
                if (copyLen > 0) {
                    byte[] newFileBuf = new byte[totLen + copyLen];
                    if (filebuffer != null)
                        System.arraycopy(filebuffer, 0, newFileBuf, 0, totLen);
                    System.arraycopy(tempBuffer, 0, newFileBuf, totLen,
                            copyLen);
                    totLen += copyLen;
                    filebuffer = newFileBuf;
                }
            } while (copyLen >= 0);
            in.close();
        }

        public byte[] getBuffer() {
            return filebuffer;
        }

        /**
         * returns the time, this file has been
         * last modified. This checks the Timestamp of
         * the file and initiates a reload to the cache
         * if it changed.
         */
        public long lastModified() {
            checkModified();
            return lastModified;
        }

        private void checkModified() {
            if (file == null)
                return;
            long timestamp = file.lastModified();
            if (lastModified != timestamp) {
                lastModified = timestamp;
                try {
                    refresh();
                } catch (IOException e) {
                    /* ignore currently, file might have been deleted, but is
                     * still in cache.
                     */
                    if (log.isErrorEnabled()) {
                        log.error(file.getAbsolutePath() + " not found. Maybe it has been deleted from the filesystem.");
                    }
                }
            }
        }

        private void refresh() throws IOException {
            int len = (int) file.length();
            filebuffer = new byte[len];
            FileInputStream in = new FileInputStream(file);
            int pos = 0;
            while (pos < len) {
                pos += in.read(filebuffer, pos, len - pos);
            }
            in.close();
        }
    }

    /*
     * we should provide a way to expunge old
     * entries here ...
     */
    private static Hashtable cache = new Hashtable();
    private static final int CACHED_LIMIT = 1024;

    private transient CacheEntry entry;

    public CachedFileTemplateSource(File f) throws IOException {
        super(f);

        entry = (CacheEntry) cache.get(f);
        if (entry == null && f.length() <= CACHED_LIMIT) {
            entry = new CacheEntry(f);
            cache.put(f, entry);
        }
    }

    public CachedFileTemplateSource(URL url)
            throws IOException {
        super(null); // we never read the file directly
        entry = (CacheEntry) cache.get(url);
        if (entry == null) {
            entry = new CacheEntry(url);
            cache.put(url, entry);
        }
        canonicalName = url.toString();
    }

    /**
     * Returns the time the content of this File
     * was last modified.
     * 

* The return value is used to decide whether to reparse a * Source or not. Reparsing is done if the value returned * here differs from the value returned at the last processing * time. * * @return long a modification time */ @Override public long lastModified() { if (entry != null) return entry.lastModified(); else return super.lastModified(); } /** * Gets an InputStream of the File. */ @Override public InputStream getInputStream() throws IOException { if (entry != null) return new ByteArrayInputStream(entry.getBuffer()); else return super.getInputStream(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy