|
What this is
Other links
The source code
/* CVS ID: $Id: FileStorage.java,v 1.1.1.1 2002/10/02 18:42:53 wastl Exp $ */
package net.wastl.webmail.storage;
import java.io.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import net.wastl.webmail.exceptions.*;
import net.wastl.webmail.server.*;
import net.wastl.webmail.config.*;
import net.wastl.webmail.misc.*;
import net.wastl.webmail.xml.*;
import net.wastl.webmail.logger.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
/**
* FileStorage.java
*
* Created: Jan 2000
*
* Copyright (C) 2000 Sebastian Schaffert
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/**
* This is the FileStorage class is common to all other storage classes in WebMail
* It provides means of getting and storing data in ZIPFiles and ResourceBundles,
* for example HTML-templates, binary files and MIME-types
*
* @see Storage
* @author Sebastian Schaffert
* @versin $Revision: 1.1.1.1 $
*/
public abstract class FileStorage extends Storage implements ConfigurationListener {
protected Hashtable resources;
protected Hashtable file_resources;
protected Hashtable stylesheet_cache;
protected Hashtable binary_cache;
/** Stores Locale/ExpireableCache pairs */
//protected Hashtable file_cache;;
protected Authenticator auth;
protected static Hashtable mime_types;
protected Logger logger;
protected static DateFormat df=null;
private boolean init_complete=false;
protected int file_cache_size=40;
/**
* Initialize SimpleStorage.
* Fetch Configuration Information etc.
*/
public FileStorage(WebMailServer parent) {
super(parent);
initConfig();
cs.addConfigurationListener("AUTH",this);
cs.configRegisterStringKey(this,"MIME TYPES",parent.getProperty("webmail.lib.path")+
System.getProperty("file.separator")+"mime.types",
"File with mime type information.");
cs.configRegisterYesNoKey("SHOW ADVERTISEMENTS","Whether or not to include the WebMail advertisement "+
"messages in default user signatures and HTTP response headers");
cs.configRegisterStringKey("ADVERTISEMENT MESSAGE","JWebMail "+parent.getVersion()+" WWW to Mail Gateway", "Advertisement to attach to user signatures");
resources=new Hashtable();
file_resources=new Hashtable();
initCache();
initLog();
// Now included in configuration:
// initVirtualDomains();
initMIME();
initAuth();
initLanguages();
init_complete=true;
}
/**
* initialize XMLSystemData sysdata
*/
protected abstract void initConfig();
protected void initCache() {
// Initialize the file cache
cs.configRegisterIntegerKey(this,"CACHE SIZE FILE","40","Size for the file system cache for every locale");
try {
file_cache_size=Integer.parseInt("CACHE SIZE FILE");
} catch(NumberFormatException e) {}
// Now the same for the stylesheet cache
if(stylesheet_cache == null) {
stylesheet_cache = new Hashtable(10);
}
Enumeration enum2=stylesheet_cache.keys();
while(enum2.hasMoreElements()) {
ExpireableCache ec=(ExpireableCache)stylesheet_cache.get(enum2.nextElement());
ec.setCapacity(file_cache_size);
}
// And for binary files
if(binary_cache == null) {
binary_cache = new Hashtable(10);
}
Enumeration enum3=binary_cache.keys();
while(enum3.hasMoreElements()) {
ExpireableCache ec=(ExpireableCache)binary_cache.get(enum3.nextElement());
ec.setCapacity(file_cache_size);
}
}
protected void initLog() {
if(false) {
try {
Class logger_class=Class.forName(parent.getProperty("webmail.log.facility"));
Class[] argtypes={Class.forName("net.wastl.webmail.server.WebMailServer"),
Class.forName("net.wastl.webmail.server.Storage")};
Object[] args={parent,this};
logger=(Logger)logger_class.getConstructor(argtypes).newInstance(args);
} catch(Exception ex) {
// Print a warning!
logger=new FileLogger(parent,this);
}
} else {
try {
logger=new ServletLogger(parent,this);
} catch(Exception ex) {
// Print a warning!
logger=new FileLogger(parent,this);
}
}
}
protected void initAuth() {
System.err.print(" * Authenticator ... ");
Authenticator a=parent.getAuthenticatorHandler().getAuthenticator(getConfig("AUTH"));
if(a!=null) {
// IMAP level authentication
auth=a;
auth.init(this);
System.err.println("ok. Using "+auth.getClass().getName()+" (v"+auth.getVersion()+") for authentication.");
} else {
System.err.println("error. Could not initalize any authenticator. Users will not be able to log on.");
auth=null;
}
}
protected void initMIME() {
System.err.print(" * MIME types ... ");
if(getConfig("mime types") != null) {
try {
File f=new File(getConfig("mime types"));
if(f.exists() && f.canRead()) {
mime_types=new Hashtable();
BufferedReader in=new BufferedReader(new InputStreamReader(new FileInputStream(f)));
String line=in.readLine();
while(line != null) {
if(!line.startsWith("#")) {
StringTokenizer tok=new StringTokenizer(line);
if(tok.hasMoreTokens()) {
String type=tok.nextToken();
while(tok.hasMoreTokens()) {
String key=tok.nextToken();
mime_types.put(key,type);
//System.err.println(key+" -> "+type);
}
}
}
line=in.readLine();
}
in.close();
System.err.println(" loaded from "+getConfig("mime types")+".");
} else {
System.err.println(" could not find "+getConfig("mime types")+". Will use standard MIME types.");
}
} catch(IOException ex) {
System.err.println(" could not find "+getConfig("mime types")+". Will use standard MIME types.");
}
} else {
System.err.println(" not configured. Will use standard MIME types.");
}
}
protected void initLanguages() {
System.err.print(" * Available languages ... ");
File f=new File(parent.getProperty("webmail.template.path")+System.getProperty("file.separator"));
String[] flist=f.list(new FilenameFilter() {
public boolean accept(File myf, String s) {
if(myf.isDirectory() && s.equals(s.toLowerCase()) && (s.length()==2 || s.equals("default"))) {
return true;
} else {
return false;
}
}
});
File cached=new File(parent.getProperty("webmail.data.path")+System.getProperty("file.separator")+"locales.cache");
Locale[] available1=null;
/* Now we try to cache the Locale list since it takes really long to gather it! */
boolean exists=cached.exists();
if(exists) {
try {
ObjectInputStream in=new ObjectInputStream(new FileInputStream(cached));
available1=(Locale[])in.readObject();
in.close();
System.err.print(" using disk cache ... ");
} catch(Exception ex) {
exists=false;
}
}
if(!exists) {
// We should cache this on disk since it is so slow!
available1=Collator.getAvailableLocales();
try {
ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream(cached));
os.writeObject(available1);
os.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
// Do this manually, as it is not JDK 1.1 compatible ...
//Vector available=new Vector(Arrays.asList(available1));
Vector available=new Vector(available1.length);
for(int i=0; i<available1.length; i++) {
available.addElement(available1[i]);
}
String s="";
int count=0;
for(int i=0;i<flist.length;i++) {
String cur_lang=flist[i];
Locale loc=new Locale(cur_lang,"","");
Enumeration enum=available.elements();
boolean added=false;
while(enum.hasMoreElements()) {
Locale l=(Locale)enum.nextElement();
if(l.getLanguage().equals(loc.getLanguage())) {
s+=l.toString()+" ";
count++;
added=true;
}
}
if(!added) {
s+=loc.toString()+" ";
count++;
}
}
System.err.println(count+" languages initialized.");
cs.configRegisterStringKey(this,"LANGUAGES",s,"Languages available in WebMail");
setConfig("LANGUAGES",s);
/*
Setup list of themes for each language
*/
for(int j=0;j<flist.length;j++) {
File themes=new File(parent.getProperty("webmail.template.path")+System.getProperty("file.separator")
+flist[j]+System.getProperty("file.separator"));
String[] themelist=themes.list(new FilenameFilter() {
public boolean accept(File myf, String s3) {
if(myf.isDirectory() && !s3.equals("CVS")) {
return true;
} else {
return false;
}
}
});
String s2="";
for(int k=0;k<themelist.length;k++) {
s2+=themelist[k]+" ";
}
cs.configRegisterStringKey(this,"THEMES_"+flist[j].toUpperCase(),s2,"Themes for language "+flist[j]);
setConfig("THEMES_"+flist[j].toUpperCase(),s2);
}
}
/**
* Get the String for key and the specified locale.
* @param key Identifier for the String
* @param locale locale of the String to fetch
*/
public String getStringResource(String key, Locale locale) {
if(resources.get(locale.getLanguage()) != null) {
String s = ((ResourceBundle)resources.get(locale.getLanguage())).getString(key);
return ((ResourceBundle)resources.get(locale.getLanguage())).getString(key);
} else {
try {
// Modified by exce, start.
// ResourceBundle rc=XMLResourceBundle.getBundle("resources",locale,null);
System.err.println("Loading locale");
ResourceBundle rc = ResourceBundle.getBundle("org.bulbul.webmail.xmlresource.Resources", locale);
// Modified by exce, end.
resources.put(locale.getLanguage(),rc);
return rc.getString(key);
} catch(Exception e) {
e.printStackTrace();
return "";
}
}
}
/**
* Return the requested Stylesheet, precompiled and fitting to the locale and theme
*/
public Templates getStylesheet(String name, Locale locale, String theme) throws WebMailException {
String key = locale.getLanguage()+"/"+theme;
AttributedExpireableCache cache=(AttributedExpireableCache)stylesheet_cache.get(key);
if(cache == null) {
cache=new AttributedExpireableCache(file_cache_size);
stylesheet_cache.put(key,cache);
}
Templates stylesheet=null;
String basepath=getBasePath(locale,theme);
File f=new File(basepath+name);
if(!f.exists()) {
throw new StylesheetNotFoundException("The requested stylesheet "+name+" could not be found (path tried: "+basepath+".");
}
if(cache.get(name) != null && ((Long)cache.getAttributes(name)).longValue() >= f.lastModified()) {
// Keep statistics :-)
cache.hit();
return (Templates)cache.get(name);
} else {
try {
StreamSource msg_xsl=new StreamSource("file://"+basepath+name);
TransformerFactory factory=TransformerFactory.newInstance();
stylesheet=factory.newTemplates(msg_xsl);
cache.put(name,stylesheet, new Long(f.lastModified()));
cache.miss();
} catch(Exception ex) {
//System.err.println("Error while compiling stylesheet "+name+", language="+locale.getLanguage()+", theme="+theme+".");
throw new WebMailException("Error while compiling stylesheet "+name+", language="+locale.getLanguage()+", theme="+theme+":\n"+ex.toString());
}
return stylesheet;
}
}
/**
* Get a binary file for the specified locale.
* @param key Identifier for the String
* @param locale locale of the String to fetch
*/
public synchronized byte[] getBinaryFile(String name, Locale locale, String theme) throws BinaryNotFoundException {
String key = locale.getLanguage()+"/"+theme;
AttributedExpireableCache cache=(AttributedExpireableCache)binary_cache.get(key);
if(cache == null) {
cache=new AttributedExpireableCache(file_cache_size);
binary_cache.put(key,cache);
}
ByteStore bs=null;
String basepath=getBasePath(locale,theme);
File f=new File(basepath+name);
if(!f.exists()) {
throw new BinaryNotFoundException("The file "+name+" could not be found!");
}
if(cache.get(name) != null && ((Long)cache.getAttributes(name)).longValue() >= f.lastModified()) {
// Keep statistics :-)
cache.hit();
return ((ByteStore)cache.get(name)).getBytes();
} else {
try {
bs=ByteStore.getBinaryFromIS(new FileInputStream(f),(int)f.length());
} catch(IOException ex) { ex.printStackTrace(); }
cache.put(name,bs,new Long(f.lastModified()));
if(bs != null) {
return bs.getBytes();
} else {
return new byte[1];
}
}
}
public Authenticator getAuthenticator() {
return auth;
}
/**
* Send a message to the logging facility.
* @param level severity level of the message
* @param message the message
*/
public synchronized void log(int level, String message) {
if(logger != null) {
logger.log(level,message);
} else {
System.err.println("LOG("+level+"): "+message);
}
}
/**
* Send a message to the logging facility.
* @param level severity level of the message
* @param message the message
*/
public synchronized void log(int level, Exception ex) {
if(logger != null) {
logger.log(level,ex);
} else {
System.err.println("LOG("+level+"): ");
ex.printStackTrace();
}
}
protected String formatDate(long date) {
if(df==null) {
TimeZone tz=TimeZone.getDefault();
df=DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.DEFAULT, Locale.getDefault());
df.setTimeZone(tz);
}
String now=df.format(new Date(date));
return now;
}
public void shutdown() {
logger.shutdown();
}
public String getMimeType(String name) {
if(mime_types == null) {
return super.getMimeType(name);
} else {
if(name != null) {
String type="application/unknown";
Enumeration enum=mime_types.keys();
while(enum.hasMoreElements()) {
String s=(String)enum.nextElement();
if(name.toLowerCase().endsWith(s)) {
type= (String)mime_types.get(s);
}
}
return type;
} else {
return "UNKNOWN";
}
}
}
public void notifyConfigurationChange(String key) {
log(Storage.LOG_DEBUG,"FileStorage: Configuration change notify for key "+key+".");
System.err.println("- Configuration changed: ");
if(key.toUpperCase().startsWith("AUTH")) {
initAuth();
} else if(key.toUpperCase().startsWith("MIME")) {
initMIME();
}
}
public String toString() {
String s="";
Enumeration enum=stylesheet_cache.keys();
while(enum.hasMoreElements()) {
String name=(String)enum.nextElement();
ExpireableCache cache=(ExpireableCache)stylesheet_cache.get(name);
s+=" - stylesheet cache for "+name+": Capacity "+cache.getCapacity()+", Usage "+cache.getUsage();
s+=", "+cache.getHits()+" hits, "+cache.getMisses()+" misses\n";
}
enum=binary_cache.keys();
while(enum.hasMoreElements()) {
String name=(String)enum.nextElement();
ExpireableCache cache=(ExpireableCache)binary_cache.get(name);
s+=" - binary cache for "+name+": Capacity "+cache.getCapacity()+", Usage "+cache.getUsage();
s+=", "+cache.getHits()+" hits, "+cache.getMisses()+" misses\n";
}
return s;
}
}
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.