1
0
mirror of https://github.com/moparisthebest/davmail synced 2025-01-13 22:48:07 -05:00

Caldav: id 2900599, implement optional attendees in notifications

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@897 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2009-12-24 15:33:26 +00:00
parent fa7ed285b1
commit 3b92c1978b
3 changed files with 162 additions and 79 deletions

View File

@ -55,7 +55,6 @@ import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimePart;
import javax.mail.internet.MimeUtility;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.NoRouteToHostException;
@ -2183,6 +2182,7 @@ public class ExchangeSession {
class Participants {
String attendees;
String optionalAttendees;
String organizer;
}
@ -2196,6 +2196,7 @@ public class ExchangeSession {
*/
protected Participants getParticipants(boolean isNotification) throws IOException {
HashSet<String> attendees = new HashSet<String>();
HashSet<String> optionalAttendees = new HashSet<String>();
String organizer = null;
BufferedReader reader = null;
try {
@ -2224,7 +2225,11 @@ public class ExchangeSession {
&& (!isNotification
|| line.indexOf("RSVP=TRUE") >= 0
|| line.indexOf("PARTSTAT=NEEDS-ACTION") >= 0)) {
attendees.add(value);
if (line.indexOf("ROLE=OPT-PARTICIPANT") >= 0) {
optionalAttendees.add(value);
} else {
attendees.add(value);
}
}
}
}
@ -2235,16 +2240,8 @@ public class ExchangeSession {
}
}
Participants participants = new Participants();
if (!attendees.isEmpty()) {
StringBuilder result = new StringBuilder();
for (String recipient : attendees) {
if (result.length() > 0) {
result.append(", ");
}
result.append(recipient);
}
participants.attendees = result.toString();
}
participants.attendees = StringUtil.join(attendees, ", ");
participants.optionalAttendees = StringUtil.join(optionalAttendees, ", ");
participants.organizer = organizer;
return participants;
}
@ -2261,7 +2258,7 @@ public class ExchangeSession {
protected EventResult createOrUpdate() throws IOException {
String boundary = UUID.randomUUID().toString();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(baos, "ASCII");
MimeOutputStreamWriter writer = new MimeOutputStreamWriter(baos);
int status = 0;
PutMethod putmethod = new PutMethod(URIUtil.encodePath(href));
putmethod.setRequestHeader("Translate", "f");
@ -2275,60 +2272,51 @@ public class ExchangeSession {
putmethod.setRequestHeader("Content-Type", "message/rfc822");
String method = getICSMethod(icsBody);
writer.write("Content-Transfer-Encoding: 7bit\r\n" +
"Content-class: ");
writer.write(contentClass);
writer.write("\r\n");
writer.writeHeader("Content-Transfer-Encoding", "7bit");
writer.writeHeader("Content-class", contentClass);
// append date
SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss Z", Locale.ENGLISH);
writer.write("Date: ");
writer.write(formatter.format(new Date()));
writer.write("\r\n");
writer.writeHeader("Date", new Date());
// Make sure invites have a proper subject line
writer.writeHeader("Subject", getICSSummary(icsBody));
if ("urn:content-classes:calendarmessage".equals(contentClass)) {
// need to parse attendees and organizer to build recipients
Participants participants = getParticipants(true);
String recipients;
if (email.equalsIgnoreCase(participants.organizer)) {
// current user is organizer => notify all
recipients = participants.attendees;
writer.writeHeader("To", participants.attendees);
writer.writeHeader("Cc", participants.optionalAttendees);
// do not send notification if no recipients found
if (participants.attendees == null && participants.optionalAttendees == null) {
status = HttpStatus.SC_NO_CONTENT;
}
} else {
// notify only organizer
recipients = participants.organizer;
writer.writeHeader("To", participants.organizer);
// do not send notification if no recipients found
if (participants.organizer == null) {
status = HttpStatus.SC_NO_CONTENT;
}
}
// Make sure invites have a proper subject line
writer.write("Subject: " + MimeUtility.encodeText(getICSSummary(icsBody), "UTF-8", null) + "\r\n");
// do not send notification if no recipients found
if (recipients != null && recipients.length() > 0) {
writer.write("To: ");
writer.write(recipients);
writer.write("\r\n");
} else {
status = HttpStatus.SC_NO_CONTENT;
}
} else {
// Make sure invites have a proper subject line
writer.write("Subject: " + MimeUtility.encodeText(getICSSummary(icsBody), "UTF-8", null) + "\r\n");
// need to parse attendees and organizer to build recipients
Participants participants = getParticipants(false);
// storing appointment, full recipients header
writer.write("To: ");
if (participants.attendees != null) {
writer.write(participants.attendees);
writer.writeHeader("To", participants.attendees);
} else {
writer.write(email);
// use current user as attendee
writer.writeHeader("To", email);
}
writer.writeHeader("Cc", participants.optionalAttendees);
writer.write("\r\n");
writer.write("From: ");
if (participants.organizer != null) {
writer.write(participants.organizer);
writer.writeHeader("From", participants.organizer);
} else {
writer.write(email);
writer.writeHeader("From", email);
}
writer.write("\r\n");
// if not organizer, set REPLYTIME to force Outlook in attendee mode
if (participants.organizer != null && !email.equalsIgnoreCase(participants.organizer)) {
if (icsBody.indexOf("METHOD:") < 0) {
@ -2340,50 +2328,39 @@ public class ExchangeSession {
}
}
}
writer.write("MIME-Version: 1.0\r\n" +
"Content-Type: multipart/alternative;\r\n" +
"\tboundary=\"----=_NextPart_");
writer.write(boundary);
writer.write("\"\r\n" +
"\r\n" +
"This is a multi-part message in MIME format.\r\n" +
"\r\n" +
"------=_NextPart_");
writer.write(boundary);
writer.writeHeader("MIME-Version", "1.0");
writer.writeHeader("Content-Type", "multipart/alternative;\r\n"+
"\tboundary=\"----=_NextPart_"+boundary+"\"");
writer.writeLn();
writer.writeLn("This is a multi-part message in MIME format.");
writer.writeLn();
writer.writeLn("------=_NextPart_"+boundary);
// Write a part of the message that contains the
// ICS description so that invites contain the description text
String description = getICSDescription(icsBody).replaceAll("\\\\[Nn]", "\r\n");
if (description.length() > 0) {
writer.write("\r\n" +
"Content-Type: text/plain;\r\n" +
"\tcharset=\"utf-8\"\r\n" +
"content-transfer-encoding: 8bit\r\n" +
"\r\n");
writer.writeHeader("Content-Type", "text/plain;\r\n" +
"\tcharset=\"utf-8\"");
writer.writeHeader("content-transfer-encoding", "8bit");
writer.writeLn();
writer.flush();
baos.write(description.getBytes("UTF-8"));
writer.write("\r\n" +
"------=_NextPart_" +
boundary);
writer.writeLn();
writer.writeLn("------=_NextPart_"+boundary);
}
writer.write("\r\n" +
"Content-class: ");
writer.write(contentClass);
writer.write("\r\n" +
"Content-Type: text/calendar;\r\n" +
"\tmethod=");
writer.write(method);
writer.write(";\r\n" +
"\tcharset=\"utf-8\"\r\n" +
"Content-Transfer-Encoding: 8bit\r\n\r\n");
writer.writeHeader("Content-class", contentClass);
writer.writeHeader("Content-Type", "text/calendar;\r\n"+
"\tmethod="+method+";\r\n"+
"\tcharset=\"utf-8\""
);
writer.writeHeader("Content-Transfer-Encoding", "8bit");
writer.writeLn();
writer.flush();
baos.write(fixICS(icsBody, false).getBytes("UTF-8"));
writer.write("\r\n------=_NextPart_");
writer.write(boundary);
writer.write("--\r\n");
writer.writeLn();
writer.writeLn("------=_NextPart_"+boundary+"--");
writer.close();
putmethod.setRequestEntity(new ByteArrayRequestEntity(baos.toByteArray(), "message/rfc822"));
try {

View File

@ -0,0 +1,82 @@
/*
* DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
* Copyright (C) 2009 Mickael Guessant
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package davmail.exchange;
import javax.mail.internet.MimeUtility;
import java.io.*;
import java.util.Date;
import java.util.Locale;
import java.text.SimpleDateFormat;
/**
* Mime OutputStreamWriter to build in memory Mime message.
*/
public class MimeOutputStreamWriter extends OutputStreamWriter {
public MimeOutputStreamWriter(OutputStream out) throws UnsupportedEncodingException {
super(out,"ASCII");
}
/**
* Write MIME header
* @param header header name
* @param value header value
* @throws IOException on error
*/
public void writeHeader(String header, String value) throws IOException {
// do not write empty headers
if (value != null && value.length() > 0) {
write(header);
write(": ");
write(MimeUtility.encodeText(value, "UTF-8", null));
writeLn();
}
}
/**
* Write MIME header
* @param header header name
* @param value header value
* @throws IOException on error
*/
public void writeHeader(String header, Date value) throws IOException {
SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss Z", Locale.ENGLISH);
writeHeader(header, formatter.format(value));
}
/**
* Write line.
*
* @param line line content
* @throws IOException on error
*/
public void writeLn(String line) throws IOException {
write(line);
write("\r\n");
}
/**
* Write CRLF.
*
* @throws IOException on error
*/
public void writeLn() throws IOException {
write("\r\n");
}
}

View File

@ -18,6 +18,8 @@
*/
package davmail.util;
import java.util.Set;
/**
* Various string handling methods
*/
@ -95,4 +97,26 @@ public final class StringUtil {
}
return result;
}
/**
* Join values with given separator.
*
* @param values value set
* @param separator separator
* @return joined values
*/
public static String join(Set<String> values, String separator) {
if (values != null && !values.isEmpty()) {
StringBuilder result = new StringBuilder();
for (String value : values) {
if (result.length() > 0) {
result.append(separator);
}
result.append(value);
}
return result.toString();
} else {
return null;
}
}
}