Package net.wastl.webmail.storage.simple

Source Code of net.wastl.webmail.storage.simple.SimpleStorage

/*
* @(#)$Id: SimpleStorage.java 111 2008-10-29 23:09:35Z unsaved $
*
* Copyright 2008 by the JWebMail Development Team and Sebastian Schaffert.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 net.wastl.webmail.storage.simple;

import java.io.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import javax.servlet.UnavailableException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.wastl.webmail.storage.*;
import net.wastl.webmail.server.*;
import net.wastl.webmail.config.*;
import net.wastl.webmail.misc.*;
import net.wastl.webmail.xml.*;
import net.wastl.webmail.exceptions.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import org.xml.sax.InputSource;

/**
* This is the SimpleStorage class for the non-enterprise edition of WebMail.
* It provides means of getting and storing data in ZIPFiles and
* ResourceBundles.
*
* @see net.wastl.webmail.server.Storage
* @author Sebastian Schaffert
* @versin $Revision: 111 $
*/
public class SimpleStorage extends FileStorage {
    private static Log log = LogFactory.getLog(FileStorage.class);

    public static final String user_domain_separator="|";

    protected Hashtable resources;

    protected Hashtable vdoms;

    protected ExpireableCache user_cache;

    protected int user_cache_size=100;

    /**
     * Initialize SimpleStorage.
     * Fetch Configuration Information etc.
     */
    public SimpleStorage(WebMailServer parent)
        throws UnavailableException {
        super(parent);
        saveXMLSysData();
    }

    protected void initConfig() throws UnavailableException {
        log.info("Configuration ... ");

        loadXMLSysData();

        log.info("successfully parsed XML configuration file.");
    }

    protected void loadXMLSysData()
        throws UnavailableException {
        String datapath=parent.getProperty("webmail.data.path");
        String file="file://"+datapath+System.getProperty("file.separator")+"webmail.xml";
        // String file=datapath+System.getProperty("file.separator")+"webmail.xml";
        // bug fixed by Christian Senet
        Document root;
        try {
            DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            root=parser.parse(file);
            log.debug("Configuration file parsed, document: "+root);
            sysdata=new XMLSystemData(root,cs);
            log.debug( "SimpleStorage: WebMail configuration loaded.");
        } catch(Exception ex) {
            log.error("SimpleStorage: Failed to load WebMail configuration file",
                    ex);
            throw new UnavailableException(ex.getMessage());
        }
    }

    protected void saveXMLSysData() {
        try {
            Document d=sysdata.getRoot();
            OutputStream cfg_out=new FileOutputStream(parent.getProperty("webmail.data.path")+
                                                      System.getProperty("file.separator")+
                                                      "webmail.xml");

            XMLCommon.writeXML(d,cfg_out,"file://"+parent.getProperty("webmail.xml.path")+
                               System.getProperty("file.separator")+"sysdata.dtd");

//          XMLCommon.writeXML(d,cfg_out,parent.getProperty("webmail.xml.path")+
//                             System.getProperty("file.separator")+"sysdata.dtd");
            cfg_out.flush();
            cfg_out.close();
            sysdata.setLoadTime(System.currentTimeMillis());
            log.debug("SimpleStorage: WebMail configuration saved.");
        } catch(Exception ex) {
            log.error("SimpleStorage: Error while trying to save WebMail configuration",
                    ex);
        }
    }


    protected void initCache() {
        // Initialize the file cache from FileStorage
        super.initCache();

        // Now initialize the user cache
        cs.configRegisterIntegerKey(this,"CACHE SIZE USER","100","Size of the user cache");
        try {
            // Default value 100, if parsing fails.
            user_cache_size=100;
            user_cache_size=Integer.parseInt(getConfig("CACHE SIZE USER"));
        } catch(NumberFormatException e) {}
        if(user_cache==null) {
            user_cache=new ExpireableCache(user_cache_size);
        } else {
            user_cache.setCapacity(user_cache_size);
        }
    }


    public Enumeration getUsers(String domain) {
        String path=parent.getProperty("webmail.data.path")+System.getProperty("file.separator")+
            domain+System.getProperty("file.separator");

        File f=new File(path);
        if(f.canRead() && f.isDirectory()) {
            final String[] files=f.list(new FilenameFilter() {
                    public boolean accept(File file, String s) {
                        if(s.endsWith(".xml")) {
                            return true;
                        } else {
                            return false;
                        }
                    }
                } );
            return new Enumeration() {
                    int i=0;
                    public boolean hasMoreElements() {
                        return i<files.length;
                    }
                    public Object nextElement() {
                        int cur=i++;
                        return files[cur].substring(0,files[cur].length()-4);
                    }
                };
        } else {
            log.warn("SimpleStorage: Could not list files in directory "+path);
            return new Enumeration() {
                    public boolean hasMoreElements() { return false; }
                    public Object nextElement() { return null; }
                };
        }
    }


    public XMLUserData createUserData(String user, String domain, String password) throws CreateUserDataException {
        XMLUserData data;
        String template=parent.getProperty("webmail.xml.path")+
            System.getProperty("file.separator")+"userdata.xml";

        File f=new File(template);
        if(!f.exists()) {
            log.warn("SimpleStorage: User configuration template ("+template+") doesn't exist!");
            throw new CreateUserDataException("User configuration template ("+template+") doesn't exist!",user,domain);
        } else if(!f.canRead()) {
            log.warn("SimpleStorage: User configuration template ("+template+") is not readable!");
            throw new CreateUserDataException("User configuration template ("+template+") is not readable!",user,domain);
        }

        Document root;
        try {
            DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            root=parser.parse("file://"+template);
            data=new XMLUserData(root);
            data.init(user,domain,password);
            if(getConfig("SHOW ADVERTISEMENTS").toUpperCase().equals("YES")) {
                if(user.indexOf("@")!=-1) {
                  data.setSignature(user+"\n\n"+
                                    getConfig("ADVERTISEMENT MESSAGE"));
                } else {
                  data.setSignature(user+"@"+domain+"\n\n"+
                                    getConfig("ADVERTISEMENT MESSAGE"));
                }
            } else {
                if(user.indexOf("@")!=-1) {
                  data.setSignature(user);
                } else {
                  data.setSignature(user+"@"+domain);
                }
            }
            data.setTheme(parent.getDefaultTheme());
            WebMailVirtualDomain vdom=getVirtualDomain(domain);
            data.addMailHost("Default",getConfig("DEFAULT PROTOCOL")+"://"+
                             vdom.getDefaultServer(),user,password,
                             vdom.getImapBasedir());

        } catch(Exception ex) {
            log.warn("SimpleStorage: User configuration template ("+template+") exists but could not be parsed", ex);
            throw new CreateUserDataException("User configuration template ("+template+") exists but could not be parsed",user,domain);
        }
        return data;
    }


    /**
     * @see net.wastl.webmail.server.Storage.getUserData()
     */
    public XMLUserData getUserData(String user, String domain, String password, boolean authenticate)
         throws UserDataException, InvalidPasswordException
    {
        if(authenticate) {
            auth.authenticatePreUserData(user,domain,password);
        }

        if(user.equals("")) {
            return null;
        }

        XMLUserData data=(XMLUserData)user_cache.get(user+user_domain_separator+domain);
        if(data == null) {
            user_cache.miss();
            String filename=parent.getProperty("webmail.data.path")+
                System.getProperty("file.separator")+domain+
                System.getProperty("file.separator")+user+".xml";
            boolean error=true;
            File f=new File(filename);
            if(f.exists() && f.canRead()) {
                log.info("SimpleStorage: Reading user configuration ("+f.getAbsolutePath()+") for "+user);

                long t_start=System.currentTimeMillis();
                try {
                    DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                    Document root = parser.parse(new InputSource(new InputStreamReader(new FileInputStream(filename), "UTF-8")));
//                  Document root = parser.parse(new InputSource(new InputStreamReader(new FileInputStream(f.getAbsolutePath()), "UTF-8")));

                    data=new XMLUserData(root);
                    log.debug("SimpleStorage: Parsed Document "+root);
                    error=false;
                } catch(Exception ex) {
                    log.warn("SimpleStorage: User configuration for "+user+
                        " exists but could not be parsed ("+ex.getMessage()+")", ex);
                    error=true;
                }
                long t_end=System.currentTimeMillis();
                log.debug("SimpleStorage: Parsing of XML userdata for "+user+", domain "
                    +domain+" took "+(t_end-t_start)+"ms.");

                if(authenticate) {
                    auth.authenticatePostUserData(data,domain,password);
                }
            }

            if(error && !f.exists()) {
                log.info("UserConfig: Creating user configuration for "+user);

                data=createUserData(user,domain,password);

                error=false;

                if(authenticate) {
                    auth.authenticatePostUserData(data,domain,password);
                }
            }
            if(error) {
                log.error("UserConfig: Could not read userdata for "+user+"!");
                throw new UserDataException("Could not read userdata!",user,domain);
            }
            user_cache.put(user+user_domain_separator+domain,data);
        } else {
            user_cache.hit();
            if(authenticate) {
                auth.authenticatePostUserData(data,domain,password);
            }
        }

        return data;
    }


    public void saveUserData(String user, String domain) {
        try {
            String path=parent.getProperty("webmail.data.path")+
                System.getProperty("file.separator")+domain;
            File p=new File(path);
            if((p.exists() && p.isDirectory()) || p.mkdirs()) {
                File f=new File(path+System.getProperty("file.separator")+user+".xml");
                if((!f.exists() && p.canWrite()) || f.canWrite()) {
                    XMLUserData userdata=getUserData(user,domain,"",false);
                    Document d=userdata.getRoot();

                    long t_start=System.currentTimeMillis();

                    FileOutputStream out=new FileOutputStream(f);
//                  XMLCommon.writeXML(d,out,parent.getProperty("webmail.xml.path")+
//                                     System.getProperty("file.separator")+"userdata.dtd");

                    XMLCommon.writeXML(d,out,"file://"+parent.getProperty("webmail.xml.path")+
                                       System.getProperty("file.separator")+"userdata.dtd");
                    out.flush();
                    out.close();
                    long t_end=System.currentTimeMillis();
                    log.debug("SimpleStorage: Serializing userdata for "+user+
                        ", domain "+domain+" took "+(t_end-t_start)+"ms.");
                } else {
                    log.warn("SimpleStorage: Could not write userdata ("+f.getAbsolutePath()+") for user "+user);
                }
            } else {
                log.error("SimpleStorage: Could not create path "+path+
                    ". Aborting with user "+user);
            }
        } catch(Exception ex) {
            log.error("SimpleStorage: Unexpected error while trying to save user configuration "+
                "for user "+user+"("+ex.getMessage()+").", ex);
        }
    }


    /**
     * Delete a WebMail user
     * @param user Name of the user to delete
     */
    public void deleteUserData(String user, String domain) {
        String path=parent.getProperty("webmail.data.path")+System.getProperty("file.separator")+
            domain+System.getProperty("file.separator")+user+".xml";
        File f=new File(path);
        if(!f.canWrite() || !f.delete()) {
            log.error("SimpleStorage: Could not delete user "+user+" ("+path+")!");
        } else {
            log.info("SimpleStorage: Deleted user "+user+"!");
        }
        user_cache.remove(user+user_domain_separator+domain);
    }

    public String toString() {
        String s="SimpleStorage:\n"+super.toString();
        s+=" - user cache:  Capacity "+user_cache.getCapacity()+", Usage "+user_cache.getUsage();
        s+=", "+user_cache.getHits()+" hits, "+user_cache.getMisses()+" misses\n";
        return s;
    }
}
TOP

Related Classes of net.wastl.webmail.storage.simple.SimpleStorage

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.