001/* 002 * The MIT License 003 * Copyright (c) 2012 Microsoft Corporation 004 * 005 * Permission is hereby granted, free of charge, to any person obtaining a copy 006 * of this software and associated documentation files (the "Software"), to deal 007 * in the Software without restriction, including without limitation the rights 008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 009 * copies of the Software, and to permit persons to whom the Software is 010 * furnished to do so, subject to the following conditions: 011 * 012 * The above copyright notice and this permission notice shall be included in 013 * all copies or substantial portions of the Software. 014 * 015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 021 * THE SOFTWARE. 022 */ 023 024package microsoft.exchange.webservices.data.core.service.item; 025 026import microsoft.exchange.webservices.data.attribute.Attachable; 027import microsoft.exchange.webservices.data.attribute.ServiceObjectDefinition; 028import microsoft.exchange.webservices.data.core.EwsUtilities; 029import microsoft.exchange.webservices.data.core.ExchangeService; 030import microsoft.exchange.webservices.data.core.PropertySet; 031import microsoft.exchange.webservices.data.core.XmlElementNames; 032import microsoft.exchange.webservices.data.core.service.response.ResponseMessage; 033import microsoft.exchange.webservices.data.core.service.response.SuppressReadReceipt; 034import microsoft.exchange.webservices.data.core.service.schema.EmailMessageSchema; 035import microsoft.exchange.webservices.data.core.service.schema.ServiceObjectSchema; 036import microsoft.exchange.webservices.data.core.enumeration.service.ConflictResolutionMode; 037import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion; 038import microsoft.exchange.webservices.data.core.enumeration.service.MessageDisposition; 039import microsoft.exchange.webservices.data.core.enumeration.service.ResponseMessageType; 040import microsoft.exchange.webservices.data.core.enumeration.property.WellKnownFolderName; 041import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException; 042import microsoft.exchange.webservices.data.property.complex.EmailAddress; 043import microsoft.exchange.webservices.data.property.complex.EmailAddressCollection; 044import microsoft.exchange.webservices.data.property.complex.FolderId; 045import microsoft.exchange.webservices.data.property.complex.ItemAttachment; 046import microsoft.exchange.webservices.data.property.complex.ItemId; 047import microsoft.exchange.webservices.data.property.complex.MessageBody; 048 049import java.util.Arrays; 050 051/** 052 * Represents an e-mail message. Properties available on e-mail messages are 053 * defined in the EmailMessageSchema class. 054 */ 055@Attachable 056@ServiceObjectDefinition(xmlElementName = XmlElementNames.Message) 057public class EmailMessage extends Item { 058 059 /** 060 * Initializes an unsaved local instance of EmailMessage. To bind to an 061 * existing e-mail message, use EmailMessage.Bind() instead. 062 * 063 * @param service The ExchangeService object to which the e-mail message will be 064 * bound. 065 * @throws Exception the exception 066 */ 067 public EmailMessage(ExchangeService service) throws Exception { 068 super(service); 069 } 070 071 public EmailMessage(ExchangeService service, ItemId itemId) throws Exception { 072 super(service, itemId); 073 } 074 075 /** 076 * Initializes a new instance of the "EmailMessage" class. 077 * 078 * @param parentAttachment The parent attachment. 079 * @throws Exception the exception 080 */ 081 public EmailMessage(ItemAttachment parentAttachment) throws Exception { 082 super(parentAttachment); 083 } 084 085 /** 086 * Binds to an existing e-mail message and loads the specified set of 087 * property.Calling this method results in a call to EWS. 088 * 089 * @param service the service 090 * @param id the id 091 * @param propertySet the property set 092 * @return An EmailMessage instance representing the e-mail message 093 * corresponding to the specified Id 094 * @throws Exception the exception 095 */ 096 public static EmailMessage bind(ExchangeService service, ItemId id, 097 PropertySet propertySet) throws Exception { 098 return service.bindToItem(EmailMessage.class, id, propertySet); 099 100 } 101 102 /** 103 * Binds to an existing e-mail message and loads its first class 104 * property.Calling this method results in a call to EWS. 105 * 106 * @param service the service 107 * @param id the id 108 * @return An EmailMessage instance representing the e-mail message 109 * corresponding to the specified Id 110 * @throws Exception the exception 111 */ 112 public static EmailMessage bind(ExchangeService service, ItemId id) 113 throws Exception { 114 return EmailMessage.bind(service, id, PropertySet 115 .getFirstClassProperties()); 116 } 117 118 /** 119 * Method to return the schema associated with this type of object. 120 * 121 * @return The schema associated with this type of object. 122 */ 123 @Override public ServiceObjectSchema getSchema() { 124 return EmailMessageSchema.Instance; 125 } 126 127 /** 128 * Gets the minimum required server version. 129 * 130 * @return Earliest Exchange version in which this service object type is 131 * supported. 132 */ 133 @Override public ExchangeVersion getMinimumRequiredServerVersion() { 134 return ExchangeVersion.Exchange2007_SP1; 135 } 136 137 /** 138 * Send message. 139 * 140 * @param parentFolderId The parent folder id. 141 * @param messageDisposition The message disposition. 142 * @throws Exception the exception 143 */ 144 private void internalSend(FolderId parentFolderId, 145 MessageDisposition messageDisposition) throws Exception { 146 this.throwIfThisIsAttachment(); 147 148 if (this.isNew()) { 149 if ((this.getAttachments().getCount() == 0) || 150 (messageDisposition == MessageDisposition.SaveOnly)) { 151 this.internalCreate(parentFolderId, messageDisposition, null); 152 } else { 153 // Bug E14:80316 -- If the message has attachments, save as a 154 // draft (and add attachments) before sending. 155 this.internalCreate(null, // null means use the Drafts folder in 156 // the mailbox of the authenticated 157 // user. 158 MessageDisposition.SaveOnly, null); 159 160 this.getService().sendItem(this, parentFolderId); 161 } 162 } else if (this.isDirty()) { 163 // Validate and save attachments before sending. 164 this.getAttachments().validate(); 165 this.getAttachments().save(); 166 167 if (this.getPropertyBag().getIsUpdateCallNecessary()) { 168 this.internalUpdate(parentFolderId, 169 ConflictResolutionMode.AutoResolve, messageDisposition, 170 null); 171 } else { 172 this.getService().sendItem(this, parentFolderId); 173 } 174 } else { 175 this.getService().sendItem(this, parentFolderId); 176 } 177 178 // this.internalCreate(parentFolderId, messageDisposition, null); 179 } 180 181 /** 182 * Creates a reply response to the message. 183 * 184 * @param replyAll the reply all 185 * @return A ResponseMessage representing the reply response that can 186 * subsequently be modified and sent. 187 * @throws Exception the exception 188 */ 189 public ResponseMessage createReply(boolean replyAll) throws Exception { 190 this.throwIfThisIsNew(); 191 192 return new ResponseMessage(this, 193 replyAll ? ResponseMessageType.ReplyAll : 194 ResponseMessageType.Reply); 195 } 196 197 /** 198 * Creates a forward response to the message. 199 * 200 * @return A ResponseMessage representing the forward response that can 201 * subsequently be modified and sent. 202 * @throws Exception the exception 203 */ 204 public ResponseMessage createForward() throws Exception { 205 this.throwIfThisIsNew(); 206 return new ResponseMessage(this, ResponseMessageType.Forward); 207 } 208 209 /** 210 * Replies to the message. Calling this method results in a call to EWS. 211 * 212 * @param bodyPrefix the body prefix 213 * @param replyAll the reply all 214 * @throws Exception the exception 215 */ 216 public void reply(MessageBody bodyPrefix, boolean replyAll) 217 throws Exception { 218 ResponseMessage responseMessage = this.createReply(replyAll); 219 responseMessage.setBodyPrefix(bodyPrefix); 220 responseMessage.sendAndSaveCopy(); 221 } 222 223 /** 224 * Forwards the message. Calling this method results in a call to EWS. 225 * 226 * @param bodyPrefix the body prefix 227 * @param toRecipients the to recipients 228 * @throws Exception the exception 229 */ 230 public void forward(MessageBody bodyPrefix, EmailAddress... toRecipients) 231 throws Exception { 232 if (null != toRecipients) { 233 forward(bodyPrefix, Arrays.asList(toRecipients)); 234 } 235 } 236 237 /** 238 * Forwards the message. Calling this method results in a call to EWS. 239 * 240 * @param bodyPrefix the body prefix 241 * @param toRecipients the to recipients 242 * @throws Exception the exception 243 */ 244 public void forward(MessageBody bodyPrefix, 245 Iterable<EmailAddress> toRecipients) throws Exception { 246 ResponseMessage responseMessage = this.createForward(); 247 248 responseMessage.setBodyPrefix(bodyPrefix); 249 responseMessage.getToRecipients() 250 .addEmailRange(toRecipients.iterator()); 251 252 responseMessage.sendAndSaveCopy(); 253 } 254 255 /** 256 * Sends this e-mail message. Calling this method results in at least one 257 * call to EWS. 258 * 259 * @throws Exception the exception 260 */ 261 public void send() throws Exception { 262 internalSend(null, MessageDisposition.SendOnly); 263 } 264 265 /** 266 * Sends this e-mail message and saves a copy of it in the specified 267 * folder. SendAndSaveCopy does not work if the message has unsaved 268 * attachments. In that case, the message must first be saved and then sent. 269 * Calling this method results in a call to EWS. 270 * 271 * @param destinationFolderId the destination folder id 272 * @throws Exception the exception 273 */ 274 public void sendAndSaveCopy(FolderId destinationFolderId) throws Exception { 275 EwsUtilities.validateParam(destinationFolderId, "destinationFolderId"); 276 this.internalSend(destinationFolderId, 277 MessageDisposition.SendAndSaveCopy); 278 } 279 280 /** 281 * Sends this e-mail message and saves a copy of it in the specified 282 * folder. SendAndSaveCopy does not work if the message has unsaved 283 * attachments. In that case, the message must first be saved and then sent. 284 * Calling this method results in a call to EWS. 285 * 286 * @param destinationFolderName the destination folder name 287 * @throws Exception the exception 288 */ 289 public void sendAndSaveCopy(WellKnownFolderName destinationFolderName) 290 throws Exception { 291 this.internalSend(new FolderId(destinationFolderName), 292 MessageDisposition.SendAndSaveCopy); 293 } 294 295 /** 296 * Sends this e-mail message and saves a copy of it in the Sent Items 297 * folder. SendAndSaveCopy does not work if the message has unsaved 298 * attachments. In that case, the message must first be saved and then sent. 299 * Calling this method results in a call to EWS. 300 * 301 * @throws Exception the exception 302 */ 303 public void sendAndSaveCopy() throws Exception { 304 this.internalSend(new FolderId(WellKnownFolderName.SentItems), 305 MessageDisposition.SendAndSaveCopy); 306 } 307 308 /** 309 * Suppresses the read receipt on the message. Calling this method results 310 * in a call to EWS. 311 * 312 * @throws Exception the exception 313 */ 314 public void suppressReadReceipt() throws Exception { 315 this.throwIfThisIsNew(); 316 new SuppressReadReceipt(this).internalCreate(null, null); 317 } 318 319 /** 320 * Gets the list of To recipients for the e-mail message. 321 * 322 * @return The list of To recipients for the e-mail message. 323 * @throws ServiceLocalException the service local exception 324 */ 325 public EmailAddressCollection getToRecipients() 326 throws ServiceLocalException { 327 return getPropertyBag().getObjectFromPropertyDefinition( 328 EmailMessageSchema.ToRecipients); 329 } 330 331 /** 332 * Gets the list of Bcc recipients for the e-mail message. 333 * 334 * @return the bcc recipients 335 * @throws ServiceLocalException the service local exception 336 */ 337 public EmailAddressCollection getBccRecipients() 338 throws ServiceLocalException { 339 return getPropertyBag().getObjectFromPropertyDefinition( 340 EmailMessageSchema.BccRecipients); 341 } 342 343 /** 344 * Gets the list of Cc recipients for the e-mail message. 345 * 346 * @return the cc recipients 347 * @throws ServiceLocalException the service local exception 348 */ 349 public EmailAddressCollection getCcRecipients() 350 throws ServiceLocalException { 351 return getPropertyBag().getObjectFromPropertyDefinition( 352 EmailMessageSchema.CcRecipients); 353 } 354 355 /** 356 * Gets the conversation topic of the e-mail message. 357 * 358 * @return the conversation topic 359 * @throws ServiceLocalException the service local exception 360 */ 361 public String getConversationTopic() throws ServiceLocalException { 362 return getPropertyBag().getObjectFromPropertyDefinition( 363 EmailMessageSchema.ConversationTopic); 364 } 365 366 /** 367 * Gets the conversation index of the e-mail message. 368 * 369 * @return the conversation index 370 * @throws ServiceLocalException the service local exception 371 */ 372 public byte[] getConversationIndex() throws ServiceLocalException { 373 return getPropertyBag().getObjectFromPropertyDefinition( 374 EmailMessageSchema.ConversationIndex); 375 } 376 377 /** 378 * Gets the "on behalf" sender of the e-mail message. 379 * 380 * @return the from 381 * @throws ServiceLocalException the service local exception 382 */ 383 public EmailAddress getFrom() throws ServiceLocalException { 384 return getPropertyBag().getObjectFromPropertyDefinition( 385 EmailMessageSchema.From); 386 } 387 388 /** 389 * Sets the from. 390 * 391 * @param value the new from 392 * @throws Exception the exception 393 */ 394 public void setFrom(EmailAddress value) throws Exception { 395 this.getPropertyBag().setObjectFromPropertyDefinition( 396 EmailMessageSchema.From, value); 397 } 398 399 /** 400 * Gets a value indicating whether this is an associated message. 401 * 402 * @return the checks if is associated 403 * @throws ServiceLocalException the service local exception 404 */ 405 @Override 406 public boolean getIsAssociated() throws ServiceLocalException { 407 return super.getIsAssociated(); 408 } 409 410 // The "new" keyword is used to expose the setter only on Message types, 411 // because 412 // EWS only supports creation of FAI Message types. IsAssociated is a 413 // readonly 414 // property of the Item type but it is used by the CreateItem web method for 415 // creating 416 // associated messages. 417 418 /** 419 * Sets the checks if is associated. 420 * 421 * @param value the new checks if is associated 422 * @throws Exception the exception 423 */ 424 public void setIsAssociated(boolean value) throws Exception { 425 this.getPropertyBag().setObjectFromPropertyDefinition( 426 EmailMessageSchema.IsAssociated, value); 427 } 428 429 /** 430 * Gets a value indicating whether a read receipt is requested for 431 * the e-mail message. 432 * 433 * @return the checks if is delivery receipt requested 434 * @throws ServiceLocalException the service local exception 435 */ 436 public Boolean getIsDeliveryReceiptRequested() 437 throws ServiceLocalException { 438 return getPropertyBag().getObjectFromPropertyDefinition( 439 EmailMessageSchema.IsDeliveryReceiptRequested); 440 } 441 442 /** 443 * Sets the checks if is delivery receipt requested. 444 * 445 * @param value the new checks if is delivery receipt requested 446 * @throws Exception the exception 447 */ 448 public void setIsDeliveryReceiptRequested(Boolean value) throws Exception { 449 this.getPropertyBag().setObjectFromPropertyDefinition( 450 EmailMessageSchema.IsDeliveryReceiptRequested, value); 451 } 452 453 /** 454 * Gets a value indicating whether the e-mail message is read. 455 * 456 * @return the checks if is read 457 * @throws ServiceLocalException the service local exception 458 */ 459 public Boolean getIsRead() throws ServiceLocalException { 460 return getPropertyBag().getObjectFromPropertyDefinition( 461 EmailMessageSchema.IsRead); 462 } 463 464 /** 465 * Sets the checks if is read. 466 * 467 * @param value the new checks if is read 468 * @throws Exception the exception 469 */ 470 public void setIsRead(Boolean value) throws Exception { 471 this.getPropertyBag().setObjectFromPropertyDefinition( 472 EmailMessageSchema.IsRead, value); 473 } 474 475 /** 476 * Gets a value indicating whether a read receipt is requested for 477 * the e-mail message. 478 * 479 * @return the checks if is read receipt requested 480 * @throws ServiceLocalException the service local exception 481 */ 482 public Boolean getIsReadReceiptRequested() throws ServiceLocalException { 483 return getPropertyBag().getObjectFromPropertyDefinition( 484 EmailMessageSchema.IsReadReceiptRequested); 485 } 486 487 /** 488 * Sets the checks if is read receipt requested. 489 * 490 * @param value the new checks if is read receipt requested 491 * @throws Exception the exception 492 */ 493 public void setIsReadReceiptRequested(Boolean value) throws Exception { 494 this.getPropertyBag().setObjectFromPropertyDefinition( 495 EmailMessageSchema.IsReadReceiptRequested, value); 496 } 497 498 /** 499 * Gets a value indicating whether a response is requested for the 500 * e-mail message. 501 * 502 * @return the checks if is response requested 503 * @throws ServiceLocalException the service local exception 504 */ 505 public Boolean getIsResponseRequested() throws ServiceLocalException { 506 return getPropertyBag().getObjectFromPropertyDefinition( 507 EmailMessageSchema.IsResponseRequested); 508 } 509 510 /** 511 * Sets the checks if is response requested. 512 * 513 * @param value the new checks if is response requested 514 * @throws Exception the exception 515 */ 516 public void setIsResponseRequested(Boolean value) throws Exception { 517 this.getPropertyBag().setObjectFromPropertyDefinition( 518 EmailMessageSchema.IsResponseRequested, value); 519 } 520 521 /** 522 * Gets the Internat Message Id of the e-mail message. 523 * 524 * @return the internet message id 525 * @throws ServiceLocalException the service local exception 526 */ 527 public String getInternetMessageId() throws ServiceLocalException { 528 return getPropertyBag().getObjectFromPropertyDefinition( 529 EmailMessageSchema.InternetMessageId); 530 } 531 532 /** 533 * Gets the references of the e-mail message. 534 * 535 * @return the references 536 * @throws ServiceLocalException the service local exception 537 */ 538 public String getReferences() throws ServiceLocalException { 539 return getPropertyBag().getObjectFromPropertyDefinition( 540 EmailMessageSchema.References); 541 } 542 543 /** 544 * Sets the references. 545 * 546 * @param value the new references 547 * @throws Exception the exception 548 */ 549 public void setReferences(String value) throws Exception { 550 this.getPropertyBag().setObjectFromPropertyDefinition( 551 EmailMessageSchema.References, value); 552 } 553 554 /** 555 * Gets a list of e-mail addresses to which replies should be addressed. 556 * 557 * @return the reply to 558 * @throws ServiceLocalException the service local exception 559 */ 560 public EmailAddressCollection getReplyTo() throws ServiceLocalException { 561 return getPropertyBag().getObjectFromPropertyDefinition( 562 EmailMessageSchema.ReplyTo); 563 } 564 565 /** 566 * Gets the sender of the e-mail message. 567 * 568 * @return the sender 569 * @throws ServiceLocalException the service local exception 570 */ 571 public EmailAddress getSender() throws ServiceLocalException { 572 return getPropertyBag().getObjectFromPropertyDefinition( 573 EmailMessageSchema.Sender); 574 } 575 576 /** 577 * Sets the sender. 578 * 579 * @param value the new sender 580 * @throws Exception the exception 581 */ 582 public void setSender(EmailAddress value) throws Exception { 583 this.getPropertyBag().setObjectFromPropertyDefinition( 584 EmailMessageSchema.Sender, value); 585 } 586 587 /** 588 * Gets the ReceivedBy property of the e-mail message. 589 * 590 * @return the received by 591 * @throws ServiceLocalException the service local exception 592 */ 593 public EmailAddress getReceivedBy() throws ServiceLocalException { 594 return getPropertyBag().getObjectFromPropertyDefinition( 595 EmailMessageSchema.ReceivedBy); 596 } 597 598 /** 599 * Gets the ReceivedRepresenting property of the e-mail message. 600 * 601 * @return the received representing 602 * @throws ServiceLocalException the service local exception 603 */ 604 public EmailAddress getReceivedRepresenting() throws ServiceLocalException { 605 return getPropertyBag().getObjectFromPropertyDefinition( 606 EmailMessageSchema.ReceivedRepresenting); 607 } 608}