001    /**
002     * Created by IntelliJ IDEA.
003     * User: DanH
004     * Date: Aug 9, 2005
005     * Time: 6:50:28 PM
006     */
007    package net.sf.jolene.factories;
008    
009    import net.sf.jolene.constants.Prefs;
010    import net.sf.jolene.dom.Document;
011    import org.apache.log4j.LogManager;
012    import org.apache.log4j.Logger;
013    
014    import java.io.IOException;
015    import java.io.File;
016    import java.io.FileNotFoundException;
017    import java.util.HashMap;
018    import java.util.Map;
019    
020    
021    /**
022     * DocumentFactory is a Singleton used to perform cacheing of documents. Documents added to the cache
023     * are not parsed again. Instead they are cloned which is faster.
024     *
025     * @author Dan Howard
026     */
027    public class DocumentFactory {
028    
029        private static final Logger log = LogManager.getLogger(DocumentFactory.class);
030    
031        private static final int DEFAULT_CACHE_SIZE = 32;
032    
033        private static DocumentFactory instance = new DocumentFactory();
034    
035        private Map<String, Document> documents;
036    
037        /**
038         * Gets the factory instance.
039         *
040         * @return DocumentFactory instance.
041         */
042        public static DocumentFactory getInstance() {
043            return instance;
044        }
045    
046        private DocumentFactory() {
047            int cacheSize;
048            try {
049                cacheSize = Integer.parseInt(Prefs.CacheSize.getValue());
050            } catch (NumberFormatException e) {
051                cacheSize = DEFAULT_CACHE_SIZE;
052                log.warn("NumberFormatException : " + e.getMessage() + " cache size set to 32");
053            }
054            documents = new HashMap<String, Document>(cacheSize);
055        }
056    
057        /**
058         * Returns a new document instance using the full filename + timestamp as the factory key.
059         *
060         * @param docFileName full path and name to the file to get.
061         * @return Document the document object from the cache.
062         * @throws IOException if any IOException occurs.
063         */
064        public Document getDocument(String docFileName) throws IOException {
065            log.debug("getDocument: " + docFileName);
066    
067            boolean cacheEnabled = Boolean.parseBoolean(Prefs.DocumentCaching.getValue());
068    
069            log.debug("getDocument: filename: Cache enabled? " + cacheEnabled);
070    
071            if (cacheEnabled) {
072                File file = new File(docFileName);
073                if (! file.exists()) {
074                    throw new FileNotFoundException(docFileName + " not found!");
075                }
076                String key = docFileName + " - " + file.lastModified();
077                if (!documents.containsKey(key)) {
078                    documents.put(key, new Document(docFileName));
079                }
080                return documents.get(key).clone();
081            }
082    
083            return new Document(docFileName);
084        }
085    
086        /**
087         * Returns a new document instance using the full filename + timestamp as the factory key.
088         *
089         * @param docFileName full path and name to the file to get.
090         * @param contextPath aids in finding the document's real path from the uri.
091         * @param uri         uri to the document.
092         * @return Document   the document object from the cache.
093         * @throws IOException if ever an IOException occurs.
094         */
095        public Document getDocument(String docFileName, String contextPath, String uri) throws IOException {
096            log.debug("getDocument (with cp): " + docFileName + " cp: " + contextPath);
097    
098            boolean cacheEnabled = Boolean.parseBoolean(Prefs.DocumentCaching.getValue());
099            log.debug("getDocument: filename, contextPath, uri: Cache enabled? " + cacheEnabled);
100    
101            if (cacheEnabled) {
102                File file = new File(docFileName);
103                if (! file.exists()) {
104                    throw new FileNotFoundException(docFileName + " not found!");
105                }
106                String key = docFileName + " - " + file.lastModified();
107                if (!documents.containsKey(key)) {
108                    documents.put(key, new Document(docFileName, contextPath, uri));
109                }
110                return documents.get(key).clone();
111    
112            }
113            return new Document(docFileName, contextPath, uri);
114        }
115    
116    
117    }