001: /* CVS ID: $Id: Storage.java,v 1.1.1.1 2002/10/02 18:42:51 wastl Exp $ */
002: package net.wastl.webmail.server;
003:
004: import net.wastl.webmail.config.*;
005: import net.wastl.webmail.xml.*;
006: import net.wastl.webmail.exceptions.*;
007: import java.io.*;
008: import java.util.*;
009:
010: import javax.xml.transform.Templates;
011: import javax.xml.parsers.ParserConfigurationException;
012:
013: /*
014: * Storage.java
015: *
016: * Created: Feb 1999
017: *
018: * Copyright (C) 1999-2000 Sebastian Schaffert
019: *
020: * This program is free software; you can redistribute it and/or
021: * modify it under the terms of the GNU General Public License
022: * as published by the Free Software Foundation; either version 2
023: * of the License, or (at your option) any later version.
024: *
025: * This program is distributed in the hope that it will be useful,
026: * but WITHOUT ANY WARRANTY; without even the implied warranty of
027: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
028: * GNU General Public License for more details.
029: *
030: * You should have received a copy of the GNU General Public License
031: * along with this program; if not, write to the Free Software
032: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
033: */
034: /**
035: *
036: *
037: * This provides a generic interface for getting and setting stored
038: * data in WebMail.
039: *
040: * @see net.wastl.webmail.storage.simple.SimpleStorage
041: * @author Sebastian Schaffert
042: * @version $Revision: 1.1.1.1 $
043: */
044: /* 9/24/2000 devink - updated for new challenge/response authentication */
045: public abstract class Storage {
046:
047: public static final int LOG_DEBUG = 10;
048: public static final int LOG_INFO = 5;
049: public static final int LOG_WARN = 3;
050: public static final int LOG_ERR = 1;
051: public static final int LOG_CRIT = 0;
052:
053: protected static boolean debug;
054:
055: protected WebMailServer parent;
056:
057: protected ConfigScheme cs;
058:
059: protected XMLSystemData sysdata;
060:
061: protected XMLGenericModel generic_model;
062:
063: public Storage(WebMailServer parent) {
064: debug = WebMailServer.getDebug();
065: this .parent = parent;
066: cs = parent.getConfigScheme();
067: cs
068: .configRegisterYesNoKey("FOLDER TRY LOGIN PASSWORD",
069: "Try to connect folders with the user's login password if authentication fails");
070:
071: }
072:
073: public void initConfigKeys() {
074: // Initialize the configuration file with the default or set parameters
075: // needed to complete the XML file
076: Enumeration enum=cs.getPossibleKeys();
077: while(enum.hasMoreElements()) {
078: String key=(String)enum.nextElement();
079: if(!sysdata.isConfigSet(key)) {
080: // We must use the raw method so the input doesn't get filtered.
081: sysdata.setConfig(key,(String)cs.getDefaultValue(key),false,false);
082: }
083: }
084: saveXMLSysData();
085: }
086:
087: public void setDebug(boolean b) {
088: debug = b;
089: }
090:
091: public boolean getDebug() {
092: return debug;
093: }
094:
095: /**
096: * Fetch all keys of the current configuration.
097: */
098: public Enumeration getConfigKeys() {
099: return cs.getPossibleKeys();
100: }
101:
102: /**
103: * Fetch the configuration associated with the specified key.
104: * @param key Identifier for the configuration
105: */
106: public String getConfig(String key) {
107: return sysdata.getConfig(key);
108: }
109:
110: /**
111: * Set a configuration "key" to the specified value.
112: * @param key Identifier for the configuration
113: * @param value value to set
114: */
115: public void setConfig(String key, String value)
116: throws IllegalArgumentException {
117: // Modified by exce, start
118: /**
119: * Maybe here is a bug.
120: *
121: * Consider that if administrator happens to delete the value of certain
122: * key, that is, the key is an empty tag.
123: * FileStorage.java:272 call ConfigScheme.configRegister???Key() to set
124: * value first, which becomes a default value, then call this function.
125: * However, ConfigStore.getConfig() returns default value
126: * if the key is an empty tag in configuration file that getConfigRaw()
127: * returns null/empty value. That means the value passing in here is always
128: * equals to the value returned by ConfigStore.getConfig().
129: *
130: * The simplest way to enforce saving config data is to comment out the
131: * if statement. However, this may be a performance issue, so I don't
132: * modify the code.
133: */
134: // Modified by exce, end
135: if (!value.equals(getConfig(key))) {
136: log(LOG_DEBUG, "Storage API: Setting configuration for '"
137: + key + "' to '" + value + "'.");
138: sysdata.setConfig(key, value);
139: saveXMLSysData();
140: }
141: }
142:
143: /**
144: * Get the String for key and the specified locale.
145: * @param key Identifier for the String
146: * @param locale locale of the String to fetch
147: */
148: public abstract String getStringResource(String key, Locale locale);
149:
150: /**
151: * Get a xsl stylesheet for the specified locale and theme.
152: * @param key Identifier for the String
153: * @param locale locale of the String to fetch
154: * @param theme theme where to look for the file
155: */
156: public abstract Templates getStylesheet(String name, Locale locale,
157: String theme) throws WebMailException;
158:
159: /**
160: * Get a binary file (most likely an image) for the specified locale and theme.
161: * @param key Identifier for the String
162: * @param locale locale of the String to fetch
163: * @param theme theme where to look for the file
164: */
165: public abstract byte[] getBinaryFile(String name, Locale locale,
166: String theme) throws BinaryNotFoundException;
167:
168: /**
169: * Calculate the document base path for a given locale and theme
170: */
171: public String getBasePath(Locale locale, String theme) {
172: String language_path = (parent
173: .getProperty("webmail.template.path")
174: + System.getProperty("file.separator") + locale
175: .getLanguage());
176: File f = new File(language_path);
177: if (!f.exists()) {
178: language_path = (parent
179: .getProperty("webmail.template.path")
180: + System.getProperty("file.separator") + parent
181: .getDefaultLocale().getLanguage());
182: f = new File(language_path);
183: if (!f.exists()) {
184: System.err
185: .println("Storage::getBasePath: Default Language templates not found \n(tried path: "
186: + language_path + ")");
187: }
188: }
189: String theme_path = language_path
190: + System.getProperty("file.separator") + theme;
191: f = new File(theme_path);
192: if (!f.exists()) {
193: if (parent.getProperty("webmail.default.theme") != null) {
194: theme_path = language_path
195: + System.getProperty("file.separator")
196: + parent.getProperty("webmail.default.theme");
197: } else {
198: theme_path = language_path
199: + System.getProperty("file.separator")
200: + "bibop";
201: }
202: f = new File(theme_path);
203: if (!f.exists()) {
204: System.err
205: .println("Storage::getBasePath: Theme could not be found; probably a problem with your\n installation. Please check the lib/templates/bibop directory and the \nwebmail.default.theme property");
206: }
207: }
208: String basepath = theme_path
209: + System.getProperty("file.separator");
210: return basepath;
211: }
212:
213: public XMLSystemData getSystemData() {
214: return sysdata;
215: }
216:
217: public XMLUserModel createXMLUserModel(XMLUserData data)
218: throws WebMailException {
219: try {
220: return new XMLUserModel(parent, sysdata.getSysData(), data
221: .getUserData());
222: } catch (ParserConfigurationException ex) {
223: throw new WebMailException(
224: "Creating the generic XML model failed. Reason: "
225: + ex.getMessage());
226: }
227: }
228:
229: /**
230: * Return a XML model that contains state and system information for administrator use
231: */
232: public XMLAdminModel createXMLAdminModel() throws WebMailException {
233: try {
234: XMLAdminModel model = new XMLAdminModel(parent, sysdata
235: .getSysData());
236: model.init();
237: model.update();
238: return model;
239: } catch (ParserConfigurationException ex) {
240: throw new WebMailException(
241: "Creating the generic XML model failed. Reason: "
242: + ex.getMessage());
243: }
244: }
245:
246: /**
247: * Return a generic XML model that only contains some state and system information.
248: * This cannot be changed by a single session.
249: */
250: public XMLGenericModel createXMLGenericModel()
251: throws WebMailException {
252: try {
253: XMLGenericModel model = new XMLGenericModel(parent, sysdata
254: .getSysData());
255: model.init();
256: model.update();
257: return model;
258: } catch (ParserConfigurationException ex) {
259: throw new WebMailException(
260: "Creating the generic XML model failed. Reason: "
261: + ex.getMessage());
262: }
263: }
264:
265: /**
266: * Return userlist for a given domain.
267: */
268: public abstract Enumeration getUsers(String domain);
269:
270: /**
271: * @deprecated Use getUsers(String domain) instead
272: */
273: public Enumeration getUsers() {
274: final Enumeration domains=getVirtualDomains();
275: return new Enumeration() {
276: Enumeration enum=null;
277: public boolean hasMoreElements() {
278: return (domains.hasMoreElements() || (enum != null && enum.hasMoreElements()));
279: }
280: public Object nextElement() {
281: if(enum == null || !enum.hasMoreElements()) {
282: if(domains.hasMoreElements()) {
283: enum=getUsers((String)domains.nextElement());
284: } else {
285: return null;
286: }
287: }
288: return enum.nextElement();
289: }
290: };
291: }
292:
293: /**
294: * Get the userdata for the specified user.
295: * @param user Name of the user
296: * @param domain Virtual Domain name of the user
297: * @param passwd Password that the user provided
298: *
299: * devink 7/15/2000 - deprecated, but left in for backwards compat.
300: * devink 9/24/2000 - not deprecated any more
301: * XXX should passwd be a parameter?
302: */
303: public XMLUserData getUserData(String user, String domain,
304: String passwd) throws UserDataException,
305: InvalidPasswordException {
306: return getUserData(user, domain, passwd, false);
307: }
308:
309: /**
310: * get the userdata for the specified user.
311: * Should do some sort of authentication if authentication is set. See
312: * Authenticator class for example.
313: *
314: * devink 7/15/2000 - depreciated, and is no longer abstract, so there is
315: * no requirement to implement it.
316: * devink 9/24/2000 - not depreciated, and is now abstract
317: */
318: public abstract XMLUserData getUserData(String user, String domain,
319: String password, boolean authenticate)
320: throws UserDataException, InvalidPasswordException;
321:
322: /**
323: * Create a userdata for the specified user
324: */
325: public abstract XMLUserData createUserData(String user,
326: String domain, String password)
327: throws CreateUserDataException;
328:
329: /**
330: * Save the userdata for the given user.
331: * @param user Username of this user
332: * @param domain Domain of this user
333: */
334: public abstract void saveUserData(String user, String domain);
335:
336: /**
337: * Set the userdata for the specified user.
338: * @param user Name of the user
339: * @param userdata Data to store
340: * @deprecated use saveUserData instead.
341: */
342: public void setUserData(String user, UserData userdata) {
343: // Call saveUserData, do nothing with "userdata"
344: StringTokenizer tok = new StringTokenizer(user, "@");
345: String login = tok.nextToken();
346: String domain = "nodomain";
347: if (tok.hasMoreTokens()) {
348: domain = tok.nextToken();
349: }
350: saveUserData(login, domain);
351: }
352:
353: /**
354: * Delete a WebMail user
355: * @param user Name of the user to delete
356: * @param domain Domain of that user
357: */
358: public abstract void deleteUserData(String user, String domain);
359:
360: /**
361: * Delete a WebMail user
362: * @param user Name of the user to delete
363: * @deprecated use deleteUserData(String user, String domain) instead.
364: */
365: public void deleteUserData(String user) {
366: StringTokenizer tok = new StringTokenizer(user, "@");
367: String login = tok.nextToken();
368: String domain = "nodomain";
369: if (tok.hasMoreTokens()) {
370: domain = tok.nextToken();
371: }
372: deleteUserData(user, domain);
373: }
374:
375: /**
376: * Set/add a WebMail virtual domain
377: */
378: public void setVirtualDomain(String name, WebMailVirtualDomain v) {
379: sysdata.setVirtualDomain(name, v);
380: saveXMLSysData();
381: }
382:
383: /**
384: * Get a WebMail virtual domain
385: */
386: public WebMailVirtualDomain getVirtualDomain(String name) {
387: return sysdata.getVirtualDomain(name);
388: }
389:
390: public WebMailVirtualDomain createVirtualDomain(String name)
391: throws Exception {
392: sysdata.createVirtualDomain(name);
393: return sysdata.getVirtualDomain(name);
394: }
395:
396: /**
397: * Delete a WebMail virtual domain
398: */
399: public void deleteVirtualDomain(String name) {
400: sysdata.deleteVirtualDomain(name);
401: }
402:
403: /**
404: * Return a list of virtual domains
405: */
406: public Enumeration getVirtualDomains() {
407: return sysdata.getVirtualDomains();
408: }
409:
410: /**
411: * Return this Storage's Authenticator.
412: * This is necessary for changing passwords or re-checking authentication.
413: */
414: public abstract Authenticator getAuthenticator();
415:
416: /**
417: * Send a message to the logging facility.
418: * @param level severity level of the message
419: * @param message the message
420: */
421: public abstract void log(int level, String message);
422:
423: /**
424: * Send an exception to the logging facility.
425: * @param level severity level of the message
426: * @param message the message
427: */
428: public abstract void log(int level, Exception ex);
429:
430: public abstract void shutdown();
431:
432: public void save() {
433: saveXMLSysData();
434: }
435:
436: protected abstract void loadXMLSysData();
437:
438: protected abstract void saveXMLSysData();
439:
440: public String getMimeType(String name) {
441: String content_type;
442: if (name != null
443: && (name.toLowerCase().endsWith("jpg") || name
444: .toLowerCase().endsWith("jpeg"))) {
445: content_type = "IMAGE/JPEG";
446: } else if (name != null && name.toLowerCase().endsWith("gif")) {
447: content_type = "IMAGE/GIF";
448: } else if (name != null && name.toLowerCase().endsWith("png")) {
449: content_type = "IMAGE/PNG";
450: } else if (name != null && name.toLowerCase().endsWith("txt")) {
451: content_type = "TEXT/PLAIN";
452: } else if (name != null
453: && (name.toLowerCase().endsWith("htm") || name
454: .toLowerCase().endsWith("html"))) {
455: content_type = "TEXT/HTML";
456: } else {
457: content_type = "APPLICATION/OCTET-STREAM";
458: }
459: return content_type;
460: }
461:
462: }
|