/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2009 Jason Mehrens. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.*;
import java.security.*;
import java.util.logging.*;
/**
* An error manager used to store mime messages from the <tt>MailHandler</tt>
* to the file system when the email server is unavailable or unreachable.
* The code to manually setup this error manager can be as simple as the
* following:
* <tt><pre>
* File dir = new File("path to dir");
* FileErrorManager em = new FileErrorManager(dir);
* </pre></tt>
*
* <p>
* <b>Configuration:</b>
* The code to setup this error manager via the logging properties
* can be as simple as the following:
* <tt><pre>
* #Default FileErrorManager settings.
* com.sun.mail.util.logging.FileErrorManager.pattern = path to directory
* </pre></tt>
*
* If properties are not defined, or contain invalid values, then the specified
* default values are used.
* <ul>
* <li>com.sun.mail.util.logging.FileErrorManager.pattern the absolute file path
* to the directory which will store any failed email messages. (defaults
* to the value of the system property <tt>java.io.tmpdir</tt>)
* </ul>
*
* @author Jason Mehrens
*/
/**
* Stores the LogManager.
*/
/**
* Used to report internal errors.
*/
/**
* Directory of the email store.
*/
private final File emailStore
;
/**
* Creates a new error manager. Files are stored in the users temp
* directory.
* @exception SecurityException if unable to access system properties or
* if a security manager is present and unable to read or write to users
* temp directory.
*/
public FileErrorManager() {
this.emailStore = getEmailStore();
init();
}
/**
* Creates a new error manager.
* @param dir a directory to store the email files.
* @throws NullPointerException if <tt>dir</tt> is <tt>null</tt>
* @throws IllegalArgumentException if <tt>dir</tt> is a
* <tt>java.io.File</tt> subclass, not a directory, or is not an absolute
* path.
* @throws SecurityException if a security manager is present and unable
* to read or write to a given directory.
*/
public FileErrorManager
(File dir
) {
this.emailStore = dir;
init();
}
/**
* If the message parameter is a raw email, and passes the store term, then
* this method will store the email to the file system. If the message
* parameter is not a raw email then the message is forwarded to the super
* class. If an email is written to the filesystem without error, then the
* orignal reported error is ignored.
* @param msg String raw email or plain error message.
* @param ex Exception that occured in the mail handler.
* @param code int error manager code.
*/
if (isRawEmail(msg, ex, code)) {
try {
storeEmail(msg);
super.error(msg, ex, code);
internal.
error(emailStore.
toString(), IOE,
ErrorManager.
WRITE_FAILURE);
super.error(msg, ex, code);
internal.
error(emailStore.
toString(), RE,
ErrorManager.
WRITE_FAILURE);
}
} else {
super.error(msg, ex, code);
}
}
private void init() {
File dir =
this.
emailStore;
if (dir.
getClass() !=
File.
class) { //for security.
}
if (!dir.isDirectory()) {
}
//For now, only absolute paths are allowed.
if (!dir.isAbsolute()) {
}
if (!dir.canRead()) { //Can throw under a security manager.
internal.error(dir.getAbsolutePath(),
}
if (!dir.canWrite()) { //Can throw under a security manager.
internal.error(dir.getAbsolutePath(),
}
}
return "FileErrorManager";
}
return ".eml";
}
if (msg != null && msg.length() > 0) {
return !msg.
startsWith(Level.
SEVERE.
getName());
}
return false;
}
for (;;) {
tmp =
File.
createTempFile(prefixName
(), suffixName
(), emailStore
);
try {
break;
if (!tmp.exists()) { //retry if file is locked
throw FNFE;
}
}
}
try {
ps.print(email);
ps.flush();
tmp = null; //Don't delete 'tmp' if all bytes were written.
ps.close();
} finally {
close(out);
delete(tmp); //Only deletes if not null.
}
}
if (out != null) {
try {
out.close();
internal.
error(out.
toString(), IOE,
ErrorManager.
CLOSE_FAILURE);
}
}
}
private void delete
(File tmp
) {
if (tmp != null) {
try {
if (!tmp.delete() && tmp.exists()) {
try {
tmp.deleteOnExit();
if (!tmp.delete()) {
internal.
error(tmp.
getAbsolutePath(), shutdown,
ErrorManager.
CLOSE_FAILURE);
}
}
}
internal.
error(tmp.
toString(), SE,
ErrorManager.
CLOSE_FAILURE);
}
}
}
/**
* Gets the location of the email store.
* @return the File location.
*/
private File getEmailStore
() {
String dir = manager.
getProperty(
getClass().getName().concat(".pattern"));
if (dir == null) {
return System.
getProperty("java.io.tmpdir",
"");
}
});
}
}
}