Project: * Clean-up (Eclipse cruft, unused files, etc...) * Git-specific changes * Maven POMs clean-up and changes for the build system * Version set to 1.0.0-0 in the development branches * Maven plug-ins updated to latest versions * Very partial dev. documentation added
This commit is contained in:
parent
c74e30d5ba
commit
0665a760de
1439 changed files with 1020 additions and 1649 deletions
legacyworlds-server-beans-mailer
pom.xml
src
main
java/com/deepclone/lw/beans/mailer
MailDataImpl.javaMailQueueHandler.javaMailQueueItem.javaMailQueueTask.javaMailQueueTerminator.javaMailerBean.javaQueuedMail.java
resources/configuration
test
30
legacyworlds-server-beans-mailer/pom.xml
Normal file
30
legacyworlds-server-beans-mailer/pom.xml
Normal file
|
@ -0,0 +1,30 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>legacyworlds-server-beans</artifactId>
|
||||
<groupId>com.deepclone.lw</groupId>
|
||||
<version>1.0.0</version>
|
||||
<relativePath>../legacyworlds-server-beans/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>legacyworlds-server-beans-mailer</artifactId>
|
||||
<name>Legacy Worlds - Server - Components - Mailer</name>
|
||||
<version>${legacyworlds.version.main}.${legacyworlds.version.release}-${legacyworlds.version.build}</version>
|
||||
<description>This package contains the mailer component, which uses LW's i18n system and Spring's mail sending interfaces.
|
||||
It is capable of sending mails synchronously or asynchronously.</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,170 @@
|
|||
package com.deepclone.lw.beans.mailer;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.deepclone.lw.interfaces.mailer.AlreadySentException;
|
||||
import com.deepclone.lw.interfaces.mailer.MailData;
|
||||
import com.deepclone.lw.interfaces.mailer.MissingDataException;
|
||||
import com.deepclone.lw.interfaces.mailer.NotSentException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The mail data implementation consists in a single-use message sender that includes templating
|
||||
* capabilities.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
class MailDataImpl
|
||||
implements MailData
|
||||
{
|
||||
|
||||
/* Regular expressions used to identify template variables */
|
||||
private static final String camelCase = "[a-z]+([A-Z][a-z]*)*";
|
||||
private static final String fieldName = camelCase + "(\\." + camelCase + ")*";
|
||||
private static final String field = "\\$\\{(" + fieldName + ")\\}";
|
||||
private static final Pattern fPattern = Pattern.compile( field );
|
||||
|
||||
/** Queue-handling task */
|
||||
private final MailQueueHandler mailQueueTask;
|
||||
|
||||
/** Address of the message's recipient */
|
||||
private final String mailTo;
|
||||
|
||||
/** Template string of the message */
|
||||
private final String template;
|
||||
|
||||
/** Field values to use when replacing */
|
||||
private Map< String , Object > fields = new HashMap< String , Object >( );
|
||||
|
||||
/** Flag indicating whether the message has already been sent */
|
||||
private Boolean sent = false;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the instance's data then extract variable names from the template string.f
|
||||
*
|
||||
* @param task
|
||||
* the queue-handling task
|
||||
* @param target
|
||||
* the address of the message's recipient
|
||||
* @param template
|
||||
* the message's template
|
||||
*/
|
||||
MailDataImpl( MailQueueHandler task , String target , String template )
|
||||
{
|
||||
this.mailQueueTask = task;
|
||||
this.mailTo = target;
|
||||
this.template = template;
|
||||
this.parseTemplate( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extracts variable names from the template.
|
||||
*/
|
||||
private void parseTemplate( )
|
||||
{
|
||||
Matcher m = fPattern.matcher( this.template );
|
||||
while ( m.find( ) ) {
|
||||
this.fields.put( m.group( 1 ) , null );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Makes sure a message is never sent twice.
|
||||
*
|
||||
* @throws AlreadySentException
|
||||
* if the message had already been sent.
|
||||
*/
|
||||
private void checkSent( )
|
||||
throws AlreadySentException
|
||||
{
|
||||
synchronized ( this.sent ) {
|
||||
if ( this.sent ) {
|
||||
throw new AlreadySentException( );
|
||||
}
|
||||
this.sent = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepares the message's data.
|
||||
*
|
||||
* This method will check that the message has not been sent, then start replacing variables by
|
||||
* their assigned values in the template. It will return the fully-substituted message text.
|
||||
*
|
||||
* @return the message's text after variable substitution
|
||||
* @throws AlreadySentException
|
||||
* if the message has already been sent
|
||||
* @throws MissingDataException
|
||||
* if one of the variables has no value
|
||||
*/
|
||||
private String prepareMail( )
|
||||
throws AlreadySentException , MissingDataException
|
||||
{
|
||||
this.checkSent( );
|
||||
|
||||
String message = this.template;
|
||||
for ( String fName : this.fields.keySet( ) ) {
|
||||
Object value = this.fields.get( fName );
|
||||
if ( value == null ) {
|
||||
synchronized ( this.sent ) {
|
||||
this.sent = false;
|
||||
}
|
||||
throw new MissingDataException( fName );
|
||||
}
|
||||
|
||||
String regexp = "\\$\\{";
|
||||
regexp += fName.replace( (CharSequence) "." , (CharSequence) "\\." );
|
||||
regexp += "\\}";
|
||||
|
||||
Pattern p = Pattern.compile( regexp );
|
||||
message = p.matcher( message ).replaceAll( value.toString( ).replace( "$" , "\\$" ) );
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
/* Documented in MailData interface */
|
||||
@Override
|
||||
public void queue( )
|
||||
throws AlreadySentException , MissingDataException
|
||||
{
|
||||
this.mailQueueTask.queueMessage( this.mailTo , this.prepareMail( ) );
|
||||
}
|
||||
|
||||
|
||||
/* Documented in MailData interface */
|
||||
@Override
|
||||
public void sendNow( )
|
||||
throws AlreadySentException , NotSentException , MissingDataException
|
||||
{
|
||||
this.mailQueueTask.sendMessage( this.mailTo , this.prepareMail( ) );
|
||||
}
|
||||
|
||||
|
||||
/* Documented in MailData interface */
|
||||
@Override
|
||||
public void setData( String identifier , Object value )
|
||||
{
|
||||
if ( !this.fields.containsKey( identifier ) ) {
|
||||
throw new IllegalArgumentException( "unknown field '" + identifier + "'" );
|
||||
}
|
||||
if ( this.fields.get( identifier ) != null ) {
|
||||
throw new IllegalArgumentException( "field '" + identifier + "' already set" );
|
||||
}
|
||||
if ( value == null ) {
|
||||
throw new IllegalArgumentException( "field value may not be null" );
|
||||
}
|
||||
this.fields.put( identifier , value );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.deepclone.lw.beans.mailer;
|
||||
|
||||
|
||||
import com.deepclone.lw.interfaces.mailer.NotSentException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Mail queue handler interface
|
||||
*
|
||||
* This interface is normally implemented by the mail queue task. However, it is required in order
|
||||
* to test the MailData implementation separately.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
interface MailQueueHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Stops the queue-handling task.
|
||||
*
|
||||
* This method inserts a terminator into the queue, then waits for the queue to be
|
||||
* de-initialised (which indicates that the main loop ended).
|
||||
*/
|
||||
public void stop( );
|
||||
|
||||
|
||||
/**
|
||||
* Adds a message to the queue.
|
||||
*
|
||||
* @param mailTo
|
||||
* the address of the email's recipient.
|
||||
* @param message
|
||||
* the contents of the email
|
||||
*/
|
||||
public void queueMessage( String mailTo , String message );
|
||||
|
||||
|
||||
/**
|
||||
* Sends a message.
|
||||
*
|
||||
* @param mailTo
|
||||
* address of the email's recipient
|
||||
* @param message
|
||||
* contents of the message
|
||||
* @throws NotSentException
|
||||
* if the mail could not be sent for some reason
|
||||
*/
|
||||
public void sendMessage( String mailTo , String message )
|
||||
throws NotSentException;
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.deepclone.lw.beans.mailer;
|
||||
|
||||
|
||||
/**
|
||||
* This empty abstract class is used as the base class for both queued mails and termination
|
||||
* signals.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
abstract class MailQueueItem
|
||||
{
|
||||
// EMPTY
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
package com.deepclone.lw.beans.mailer;
|
||||
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.springframework.mail.MailException;
|
||||
import org.springframework.mail.MailSender;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
|
||||
import com.deepclone.lw.cmd.admin.logs.LogLevel;
|
||||
import com.deepclone.lw.interfaces.eventlog.SystemLogger;
|
||||
import com.deepclone.lw.interfaces.mailer.NotSentException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements the queue-handling task of the mailer bean. This task is responsible for
|
||||
* sending mail asynchronously, but it also provides a method allowing mails to be sent
|
||||
* synchronously by {@link MailData} instances.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
class MailQueueTask
|
||||
implements Runnable , MailQueueHandler
|
||||
{
|
||||
|
||||
/** The bean's system logger */
|
||||
private final SystemLogger logger;
|
||||
|
||||
/** The From: address */
|
||||
private final String mailFrom;
|
||||
|
||||
/** The mail sender bean */
|
||||
private final MailSender mailSender;
|
||||
|
||||
/** The mail queue */
|
||||
private LinkedBlockingQueue< MailQueueItem > queue;
|
||||
|
||||
|
||||
/** Copies the various data and references */
|
||||
MailQueueTask( SystemLogger logger , String mailFrom , LinkedBlockingQueue< MailQueueItem > queue ,
|
||||
MailSender mailSender )
|
||||
{
|
||||
this.logger = logger;
|
||||
this.mailFrom = mailFrom;
|
||||
this.queue = queue;
|
||||
this.mailSender = mailSender;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stops the queue-handling task.
|
||||
*
|
||||
* This method inserts a terminator into the queue, then waits for the queue to be
|
||||
* de-initialised (which indicates that the main loop ended).
|
||||
*/
|
||||
@Override
|
||||
public void stop( )
|
||||
{
|
||||
this.queue.add( new MailQueueTerminator( ) );
|
||||
while ( this.queue != null ) {
|
||||
Thread.yield( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a message to the queue.
|
||||
*
|
||||
* This method adds a new {@link QueuedMail} instance to the queue, initialising it using the
|
||||
* specified parameters. Should the queueing fail for some reason, the error is logged.
|
||||
*
|
||||
* @param mailTo
|
||||
* the address of the email's recipient.
|
||||
* @param message
|
||||
* the contents of the email
|
||||
*/
|
||||
@Override
|
||||
public void queueMessage( String mailTo , String message )
|
||||
{
|
||||
try {
|
||||
this.queue.put( new QueuedMail( mailTo , message ) );
|
||||
this.logger.log( LogLevel.DEBUG , "queued mail to " + mailTo );
|
||||
} catch ( InterruptedException e ) {
|
||||
// This should never happen, as the queue is non-blocking on this end
|
||||
this.logger.log( LogLevel.ERROR , "could not queue mail to " + mailTo , e );
|
||||
}
|
||||
this.logger.flush( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a message.
|
||||
*
|
||||
* This method splits the message into two parts (subject and body), then initialises the
|
||||
* {@link SimpleMailMessage} instance corresponding to the mail, before finally trying to send
|
||||
* it through the mail sender bean.
|
||||
*
|
||||
* @param mailTo
|
||||
* address of the email's recipient
|
||||
* @param message
|
||||
* contents of the message
|
||||
* @throws NotSentException
|
||||
* if the mail could not be sent for some reason
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage( String mailTo , String message )
|
||||
throws NotSentException
|
||||
{
|
||||
// Extract title and body from message
|
||||
// FIXME: there are better ways to do this
|
||||
String title = "";
|
||||
int i = 0;
|
||||
while ( i < message.length( ) && message.charAt( i ) != '\n' ) {
|
||||
title += message.charAt( i );
|
||||
i++;
|
||||
}
|
||||
while ( i < message.length( ) && message.charAt( i ) == '\n' ) {
|
||||
i++;
|
||||
}
|
||||
String body = ( i == message.length( ) ) ? "" : message.substring( i );
|
||||
|
||||
// Write log if the title or the body are empty
|
||||
if ( title.equals( "" ) ) {
|
||||
this.logger.log( LogLevel.WARNING , "sending email with no title" );
|
||||
}
|
||||
if ( body.equals( "" ) ) {
|
||||
this.logger.log( LogLevel.WARNING , "sending email with empty body" );
|
||||
}
|
||||
this.logger.flush( );
|
||||
|
||||
// Create actual mail data
|
||||
SimpleMailMessage smm = new SimpleMailMessage( );
|
||||
smm.setFrom( this.mailFrom );
|
||||
smm.setTo( mailTo );
|
||||
smm.setSubject( title );
|
||||
smm.setText( body );
|
||||
|
||||
// Try to send it
|
||||
synchronized ( this.mailSender ) {
|
||||
try {
|
||||
this.mailSender.send( smm );
|
||||
} catch ( MailException e ) {
|
||||
this.logger.log( LogLevel.INFO , "could not send mail to " + mailTo , e ).flush( );
|
||||
throw new NotSentException( e );
|
||||
}
|
||||
}
|
||||
this.logger.log( LogLevel.DEBUG , "sent mail to " + mailTo ).flush( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main queue-handling loop.
|
||||
*
|
||||
* This method contains the task's main loop. It constantly polls the queue for incoming
|
||||
* information, sending queued email. All errors while sending messages are ignored. When a
|
||||
* terminator is found on the queue, all remaining messages will be flushed and the main loop
|
||||
* will exit.
|
||||
*/
|
||||
@Override
|
||||
public void run( )
|
||||
{
|
||||
boolean keepRunning = true;
|
||||
LinkedBlockingQueue< MailQueueItem > queue = this.queue;
|
||||
while ( keepRunning ) {
|
||||
MailQueueItem item;
|
||||
|
||||
// Wait for items to send
|
||||
try {
|
||||
item = queue.take( );
|
||||
} catch ( InterruptedException e ) {
|
||||
this.logger.log( LogLevel.WARNING , "mail queue consumer interrupted" ).flush( );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle terminators
|
||||
if ( item instanceof MailQueueTerminator ) {
|
||||
keepRunning = false;
|
||||
this.logger.log( LogLevel.INFO , "termination order received" ).flush( );
|
||||
}
|
||||
|
||||
do {
|
||||
// Send mail
|
||||
if ( item instanceof QueuedMail ) {
|
||||
QueuedMail mail = (QueuedMail) item;
|
||||
try {
|
||||
this.sendMessage( mail.mailTo , mail.message );
|
||||
} catch ( NotSentException e ) {
|
||||
// Unable to send; it's been logged, so we ignore it
|
||||
}
|
||||
}
|
||||
// If we're terminating, flush the queue
|
||||
if ( ! ( keepRunning || queue.isEmpty( ) ) ) {
|
||||
boolean fail;
|
||||
do {
|
||||
try {
|
||||
item = queue.take( );
|
||||
fail = false;
|
||||
} catch ( InterruptedException e ) {
|
||||
fail = true;
|
||||
}
|
||||
} while ( fail );
|
||||
}
|
||||
} while ( !keepRunning && !queue.isEmpty( ) );
|
||||
}
|
||||
|
||||
// Kill the queue
|
||||
this.queue = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.deepclone.lw.beans.mailer;
|
||||
|
||||
|
||||
/**
|
||||
* This empty class is a mail queue item which indicates that the mail queue handling task should
|
||||
* terminate.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
class MailQueueTerminator
|
||||
extends MailQueueItem
|
||||
{
|
||||
// EMPTY
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package com.deepclone.lw.beans.mailer;
|
||||
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mail.MailSender;
|
||||
|
||||
import com.deepclone.lw.cmd.admin.logs.LogLevel;
|
||||
import com.deepclone.lw.interfaces.eventlog.*;
|
||||
import com.deepclone.lw.interfaces.i18n.*;
|
||||
import com.deepclone.lw.interfaces.mailer.*;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The mailer bean spawns a queue-handling task on initialisation. It is responsible for
|
||||
* initialising mail data instances, giving them access to the queue-handling task. When the
|
||||
* container destroys the bean, it inserts a terminator in the mail queue then waits for the task to
|
||||
* end.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
public class MailerBean
|
||||
implements Mailer , InitializingBean , DisposableBean
|
||||
{
|
||||
/** The default From: address for mails sent by the bean */
|
||||
private final static String defaultSender = "webmaster@legacyworlds.com";
|
||||
|
||||
/** Translator bean */
|
||||
private Translator translator;
|
||||
|
||||
/** Spring mail sender bean */
|
||||
private MailSender mailSender;
|
||||
|
||||
/** System logger for the mailer bean */
|
||||
private SystemLogger logger;
|
||||
|
||||
/** From: address to use when sending mails */
|
||||
private String mailFrom = defaultSender;
|
||||
|
||||
/** Mail queue */
|
||||
private LinkedBlockingQueue< MailQueueItem > queue;
|
||||
|
||||
/** Queue-handling task */
|
||||
private MailQueueTask task;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the translator bean (DI)
|
||||
*
|
||||
* @param translator
|
||||
* the translator bean
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setTranslator( Translator translator )
|
||||
{
|
||||
this.translator = translator;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the mail sender bean (DI)
|
||||
*
|
||||
* @param mailSender
|
||||
* the mail sender bean
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setMailSender( MailSender mailSender )
|
||||
{
|
||||
this.mailSender = mailSender;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialises the system logger (DI)
|
||||
*
|
||||
* @param logger
|
||||
* the logger bean
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setLogger( Logger logger )
|
||||
{
|
||||
this.logger = logger.getSystemLogger( "Mailer" );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes the From: address.
|
||||
*
|
||||
* @param mailFrom
|
||||
* the new From: address
|
||||
*/
|
||||
public void setMailFrom( String mailFrom )
|
||||
{
|
||||
this.mailFrom = mailFrom;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates the mail queue and spawns the queue-handling task when the bean is initialised.
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet( )
|
||||
{
|
||||
this.logger.log( LogLevel.INFO , "mailer task initialising" ).flush( );
|
||||
|
||||
this.queue = new LinkedBlockingQueue< MailQueueItem >( );
|
||||
this.task = new MailQueueTask( this.logger , this.mailFrom , this.queue , this.mailSender );
|
||||
|
||||
Thread t = new Thread( this.task );
|
||||
t.start( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Terminates and waits for the queue-handling task when the bean is destroyed.
|
||||
*/
|
||||
@Override
|
||||
public void destroy( )
|
||||
{
|
||||
this.task.stop( );
|
||||
this.task = null;
|
||||
this.queue = null;
|
||||
}
|
||||
|
||||
|
||||
/* Documentation in Mailer interface */
|
||||
@Override
|
||||
public MailData createMail( String language , String contentsDef , String target )
|
||||
throws TranslationException
|
||||
{
|
||||
|
||||
String template = this.translator.translate( language , contentsDef );
|
||||
return new MailDataImpl( this.task , target , template );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.deepclone.lw.beans.mailer;
|
||||
|
||||
|
||||
/**
|
||||
* This class represents a queued mail on the mail task's queue. It carries both the target address
|
||||
* and the message's contents.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
class QueuedMail
|
||||
extends MailQueueItem
|
||||
{
|
||||
/** The target mail address */
|
||||
final String mailTo;
|
||||
|
||||
/** The contents of the email */
|
||||
final String message;
|
||||
|
||||
|
||||
/** Initialises the queued mail */
|
||||
QueuedMail( String mailTo , String message )
|
||||
{
|
||||
this.mailTo = mailTo;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||
|
||||
<import resource="mailer/mailer-bean.xml" />
|
||||
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
|
||||
<property name="host" value="127.0.0.1" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||
|
||||
<!-- Mailer bean - all properties autowired or defaulted -->
|
||||
<bean id="mailer" class="com.deepclone.lw.beans.mailer.MailerBean" />
|
||||
|
||||
</beans>
|
0
legacyworlds-server-beans-mailer/src/test/java/.empty
Normal file
0
legacyworlds-server-beans-mailer/src/test/java/.empty
Normal file
Reference in a new issue