Sergiu Dumitriu wrote:
Lilianne E. Blaze wrote:
Sergiu Dumitriu wrote:
Lilianne E. Blaze wrote:
Hello,
Here's the newest version.
Basically it bridges XWiki.sendMessage to MailSenderPlugin.
It uses Reflection, so no circulars, but it's not exactly pretty.
The patch
cannot be applied yet, since it introduces a regression I'd
like to fix first.
The old sendMessage allowed indeed to set a Subject inside the content
(as a mail header), which is extracted (when found) and passed to the
plugin's sendTextMessage method.
The old sendMessage passed headers+body as-is
to SMTPClient.
The problem is that ALL kinds of headers were
allowed inside the text
content, not just the subject, and with this patch these headers are
discarded.
Ok.
Here's what I'm thinking - remove subject extraction from the patch,
instead add a new method to MailSender plugin, like
sendRawMessage(String from, String to, String rawData), which acts more
like old SMTPClient, and add header extraction/handling logic there.
Would that be ok?
Yes, that would work.
What the parser needs to do is find try to determine if the content
starts with headers (keyword: some value), and while a completely blank
line isn't found (and for failsafe, while the line still matches this
pattern) add each header to the contructed Mail object.
Done for 1.9m1 core and 1.7 mailsender, attaching.
I had no time to test it extensively, but it works in a couple basic
scenarios (like adding Priority header). Also logging is debug-type,
you'll probably want to change all/most to trace. Note it is still not
100% compatible, in old version you could in theory compose a multipart
message, or even multipart with attachments, line-by-line from the
template fields, but as the old type was direct text-to-smtp, and the
new one isn't (temporary XWiki-Mail objects), it's impossible to write
something like that without rewriting it from scratch. This patch should
take care of all except the most unusual cases.
Also you need to change the line:
#set($params.server = ['smtp_server'])
To
#set($params.server = ['smtp_server', 'smtp_server_username',
'smtp_server_password', 'javamail_extra_props'])
In XWiki.AdminGeneralSheet
Greetings, Lilianne
Index: main/java/com/xpn/xwiki/XWiki.java
===================================================================
--- main/java/com/xpn/xwiki/XWiki.java (revision 18814)
+++ main/java/com/xpn/xwiki/XWiki.java (working copy)
@@ -30,7 +30,6 @@
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
@@ -69,8 +68,6 @@
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.commons.net.smtp.SMTPClient;
-import org.apache.commons.net.smtp.SMTPReply;
import org.apache.ecs.Filter;
import org.apache.ecs.filter.CharacterFilter;
import org.apache.ecs.xhtml.textarea;
@@ -2877,9 +2874,13 @@
needsUpdate |= bclass.addTextAreaField("meta", "HTTP Meta
Info", 60, 8);
needsUpdate |= bclass.addTextField("dateformat", "Date
Format", 30);
+ // mail
needsUpdate |= bclass.addBooleanField("use_email_verification",
"Use eMail Verification", "yesno");
- needsUpdate |= bclass.addTextField("smtp_server", "SMTP
Server", 30);
needsUpdate |= bclass.addTextField("admin_email", "Admin
eMail", 30);
+ needsUpdate |= bclass.addTextField("smtp_server", "SMTP
Server", 30);
+ needsUpdate |= bclass.addTextField("smtp_server_username", "SMTP
Server username (optional)", 30);
+ needsUpdate |= bclass.addTextField("smtp_server_password", "SMTP
Server password (optional)", 30);
+ needsUpdate |= bclass.addTextAreaField("javamail_extra_props",
"Additional JavaMail properties", 60, 6);
needsUpdate |= bclass.addTextAreaField("validation_email_content",
"Validation eMail Content", 72, 10);
needsUpdate |= bclass.addTextAreaField("confirmation_email_content",
"Confirmation eMail Content", 72, 10);
needsUpdate |= bclass.addTextAreaField("invitation_email_content",
"Invitation eMail Content", 72, 10);
@@ -3353,74 +3354,66 @@
* @deprecated replaced by the <a
href="http://code.xwiki.org/xwiki/bin/view/Plugins/MailSenderPlugin&qu…
Sender
* Plugin</a>
*/
+ // DEVNOTE: this is the main sendMessage, other variants delegate to this one
@Deprecated
- public void sendMessage(String sender, String[] recipient, String message,
XWikiContext context)
+ public void sendMessage(String sender, String[] recipients, String rawMessage,
XWikiContext context)
throws XWikiException
{
- SMTPClient smtpc = null;
- try {
- String server = getXWikiPreference("smtp_server", context);
- String port = getXWikiPreference("smtp_port", context);
- String login = getXWikiPreference("smtp_login", context);
+ LOG.info("Entering sendMessage(...)...");
- if (context.get("debugMail") != null) {
- StringBuffer msg = new StringBuffer(message);
- msg.append("\n Recipient: ");
- msg.append(recipient);
- recipient = ((String)
context.get("debugMail")).split(",");
- message = msg.toString();
- }
+ Object mailSender;
+ Class mailSenderClass;
+ Method mailSenderSendRaw;
- if ((server == null) || server.equals("")) {
- server = "127.0.0.1";
- }
- if ((port == null) || (port.equals(""))) {
- port = "25";
- }
- if ((login == null) || login.equals("")) {
- login = InetAddress.getLocalHost().getHostName();
- }
+ try
+ {
+ mailSender = getPluginApi("mailsender", context);
+ mailSenderClass =
Class.forName("com.xpn.xwiki.plugin.mailsender.MailSenderPluginApi");
- smtpc = new SMTPClient();
- smtpc.connect(server, Integer.parseInt(port));
- int reply = smtpc.getReplyCode();
- if (!SMTPReply.isPositiveCompletion(reply)) {
- Object[] args = {server, port, new Integer(reply),
smtpc.getReplyString()};
- throw new XWikiException(XWikiException.MODULE_XWIKI_EMAIL,
- XWikiException.ERROR_XWIKI_EMAIL_CONNECT_FAILED,
- "Could not connect to server {0} port {1} error code {2}
({3})", null, args);
- }
+ // public int sendRawMessage(String from, String to, String rawMessage)
+ mailSenderSendRaw = mailSenderClass.getMethod("sendRawMessage",
+ new Class[]{String.class, String.class, String.class});
+ }
+ catch(Exception e)
+ {
+ String eMsg = "Problem getting MailSender via Reflection: " + e;
+ LOG.error(eMsg);
+ throw new XWikiException(XWikiException.MODULE_XWIKI_EMAIL,
+ XWikiException.ERROR_XWIKI_EMAIL_ERROR_SENDING_EMAIL, eMsg);
+ }
- if (smtpc.login(login) == false) {
- reply = smtpc.getReplyCode();
- Object[] args = {server, port, new Integer(reply),
smtpc.getReplyString()};
- throw new XWikiException(XWikiException.MODULE_XWIKI_EMAIL,
- XWikiException.ERROR_XWIKI_EMAIL_LOGIN_FAILED,
- "Could not login to mail server {0} port {1} error code {2}
({3})", null, args);
- }
+ LOG.trace("Message = \"" + rawMessage + "\"");
- if (smtpc.sendSimpleMessage(sender, recipient, message) == false) {
- reply = smtpc.getReplyCode();
- Object[] args = {server, port, new Integer(reply),
smtpc.getReplyString()};
- throw new XWikiException(XWikiException.MODULE_XWIKI_EMAIL,
- XWikiException.ERROR_XWIKI_EMAIL_SEND_FAILED,
- "Could not send mail to server {0} port {1} error code {2}
({3})", null, args);
- }
+ String messageRecipients = recipients[0];
+ for( int i = 1; i < recipients.length; i++)
+ {
+ messageRecipients = messageRecipients + "," + recipients[i];
+ }
- } catch (IOException e) {
- Object[] args = {sender, recipient};
- throw new XWikiException(XWikiException.MODULE_XWIKI_EMAIL,
- XWikiException.ERROR_XWIKI_EMAIL_ERROR_SENDING_EMAIL, "Exception
while sending email from {0} to {1}",
- e, args);
- } finally {
- if ((smtpc != null) && (smtpc.isConnected())) {
- try {
- smtpc.disconnect();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
+ try
+ {
+ mailSenderSendRaw.invoke(mailSender, sender, messageRecipients, rawMessage);
}
+ catch(InvocationTargetException ite)
+ {
+ Throwable cause = ite.getCause();
+ if( cause instanceof XWikiException )
+ {
+ throw (XWikiException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ catch(Exception e)
+ {
+ // probably either IllegalAccessException or IllegalArgumentException
+ // shouldn't happen unless there were an incompatible code change
+ throw new RuntimeException(e);
+ }
+
+ LOG.info("Exiting sendMessage(...). It seems everything went ok.");
}
/**
Index: main/resources/ApplicationResources.properties
===================================================================
--- main/resources/ApplicationResources.properties (revision 18814)
+++ main/resources/ApplicationResources.properties (working copy)
@@ -181,6 +181,9 @@
use_email_verification=Use email verification
admin_email=Admin email
smtp_server=Outgoing SMTP Server
+smtp_server_username=SMTP Server Username (optional)
+smtp_server_password=SMTP Server Password (optional)
+javamail_extra_props=Additional JavaMail properties
validation_email_content=Validation e-Mail Content
confirmation_email_content=Confirmation e-Mail Content
preferences=Preferences
Index: main/java/com/xpn/xwiki/plugin/mailsender/MailSender.java
===================================================================
--- main/java/com/xpn/xwiki/plugin/mailsender/MailSender.java (revision 18814)
+++ main/java/com/xpn/xwiki/plugin/mailsender/MailSender.java (working copy)
@@ -121,6 +121,16 @@
List<Attachment> attachments);
/**
+ * Sends a raw message.
+ *
+ * @param from
+ * @param to
+ * @param rawMessage
+ * @return
+ */
+ int sendRawMessage(String from, String to, String rawMessage);
+
+ /**
* Uses an XWiki document to build the message subject and context, based on
variables stored in the
* VelocityContext. Sends the email.
*
Index: main/java/com/xpn/xwiki/plugin/mailsender/MailSenderPluginApi.java
===================================================================
--- main/java/com/xpn/xwiki/plugin/mailsender/MailSenderPluginApi.java (revision 18814)
+++ main/java/com/xpn/xwiki/plugin/mailsender/MailSenderPluginApi.java (working copy)
@@ -29,6 +29,11 @@
import com.xpn.xwiki.api.Attachment;
import com.xpn.xwiki.api.XWiki;
import com.xpn.xwiki.plugin.PluginApi;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
/**
* Plugin that brings powerful mailing capabilities. This is the wrapper accessible from
in-document scripts.
@@ -109,6 +114,93 @@
return sendMail(email);
}
+ public int sendRawMessage(String from, String to, String rawMessage)
+ {
+ LOG.error("sendRawMessage(...)...");
+ LOG.error("from = " + from);
+ LOG.error("to = " + to);
+ LOG.error("rawMessage = >>>" + rawMessage +
"<<<");
+
+ Mail email = new Mail();
+ email.setFrom(from);
+ email.setTo(to);
+
+ // TODO: do we want a default here?
+ //email.setSubject("XWiki message");
+
+ parseRawMessage(email, rawMessage);
+ return sendMail(email);
+ }
+
+ protected void parseRawMessage(Mail toMail, String rawMessage)
+ {
+ String SUBJECT = "Subject";
+ String COLON_SPACE = ": ";
+
+ // sanity check
+ if( rawMessage == null )
+ {
+ throw new IllegalArgumentException("rawMessage can't be null");
+ }
+ else if( rawMessage.trim().equals("") )
+ {
+ throw new IllegalArgumentException("rawMessage can't be empty");
+ }
+
+ try
+ {
+ StringReader sr = new StringReader(rawMessage);
+ BufferedReader br = new BufferedReader(sr);
+ String line;
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+
+ // skip whitespace at beginning, just in case
+ // (there should be no empty lines here)
+ do
+ {
+ line = br.readLine();
+ }
+ while( line.trim().equals("") );
+
+ int pos;
+ while( (pos = line.indexOf(COLON_SPACE)) != -1 )
+ {
+ String header = line.substring(0, pos);
+ String value = line.substring(pos + COLON_SPACE.length());
+ if( header.equals(SUBJECT) )
+ {
+ toMail.setSubject(value);
+ }
+ else
+ {
+ toMail.setHeader(header, value);
+ }
+
+ line = br.readLine();
+ }
+
+ // skip whitespace. there should be zero or one empty line here
+ while( line.trim().equals("") )
+ {
+ line = br.readLine();
+ }
+
+ do
+ {
+ pw.print(line + "\r\n");
+ }
+ while( (line = br.readLine()) != null );
+
+ toMail.setTextPart(sw.toString());
+ }
+ catch(IOException ioe)
+ {
+ // can't happen here
+ }
+ }
+
/**
* {@inheritDoc}
*