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; 025 026import java.net.URI; 027import java.net.URISyntaxException; 028import java.util.ArrayList; 029import java.util.Arrays; 030import java.util.Collection; 031import java.util.Date; 032import java.util.EnumSet; 033import java.util.Enumeration; 034import java.util.HashMap; 035import java.util.Iterator; 036import java.util.List; 037import java.util.Locale; 038import java.util.Map; 039import java.util.TimeZone; 040 041import microsoft.exchange.webservices.data.autodiscover.AutodiscoverService; 042import microsoft.exchange.webservices.data.autodiscover.IAutodiscoverRedirectionUrl; 043import microsoft.exchange.webservices.data.autodiscover.enumeration.UserSettingName; 044import microsoft.exchange.webservices.data.autodiscover.exception.AutodiscoverLocalException; 045import microsoft.exchange.webservices.data.autodiscover.request.ApplyConversationActionRequest; 046import microsoft.exchange.webservices.data.autodiscover.response.GetUserSettingsResponse; 047import microsoft.exchange.webservices.data.core.enumeration.availability.AvailabilityData; 048import microsoft.exchange.webservices.data.core.enumeration.misc.ConversationActionType; 049import microsoft.exchange.webservices.data.core.enumeration.misc.DateTimePrecision; 050import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion; 051import microsoft.exchange.webservices.data.core.enumeration.misc.IdFormat; 052import microsoft.exchange.webservices.data.core.enumeration.misc.TraceFlags; 053import microsoft.exchange.webservices.data.core.enumeration.misc.UserConfigurationProperties; 054import microsoft.exchange.webservices.data.core.enumeration.notification.EventType; 055import microsoft.exchange.webservices.data.core.enumeration.property.BodyType; 056import microsoft.exchange.webservices.data.core.enumeration.property.WellKnownFolderName; 057import microsoft.exchange.webservices.data.core.enumeration.search.ResolveNameSearchLocation; 058import microsoft.exchange.webservices.data.core.enumeration.service.ConflictResolutionMode; 059import microsoft.exchange.webservices.data.core.enumeration.service.DeleteMode; 060import microsoft.exchange.webservices.data.core.enumeration.service.MeetingRequestsDeliveryScope; 061import microsoft.exchange.webservices.data.core.enumeration.service.MessageDisposition; 062import microsoft.exchange.webservices.data.core.enumeration.service.SendCancellationsMode; 063import microsoft.exchange.webservices.data.core.enumeration.service.SendInvitationsMode; 064import microsoft.exchange.webservices.data.core.enumeration.service.SendInvitationsOrCancellationsMode; 065import microsoft.exchange.webservices.data.core.enumeration.service.SyncFolderItemsScope; 066import microsoft.exchange.webservices.data.core.enumeration.service.calendar.AffectedTaskOccurrence; 067import microsoft.exchange.webservices.data.core.enumeration.service.error.ServiceErrorHandling; 068import microsoft.exchange.webservices.data.core.exception.misc.ArgumentOutOfRangeException; 069import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException; 070import microsoft.exchange.webservices.data.core.exception.service.local.ServiceValidationException; 071import microsoft.exchange.webservices.data.core.exception.service.remote.AccountIsLockedException; 072import microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRemoteException; 073import microsoft.exchange.webservices.data.core.exception.service.remote.ServiceResponseException; 074import microsoft.exchange.webservices.data.core.request.AddDelegateRequest; 075import microsoft.exchange.webservices.data.core.request.ConvertIdRequest; 076import microsoft.exchange.webservices.data.core.request.CopyFolderRequest; 077import microsoft.exchange.webservices.data.core.request.CopyItemRequest; 078import microsoft.exchange.webservices.data.core.request.CreateAttachmentRequest; 079import microsoft.exchange.webservices.data.core.request.CreateFolderRequest; 080import microsoft.exchange.webservices.data.core.request.CreateItemRequest; 081import microsoft.exchange.webservices.data.core.request.CreateResponseObjectRequest; 082import microsoft.exchange.webservices.data.core.request.CreateUserConfigurationRequest; 083import microsoft.exchange.webservices.data.core.request.DeleteAttachmentRequest; 084import microsoft.exchange.webservices.data.core.request.DeleteFolderRequest; 085import microsoft.exchange.webservices.data.core.request.DeleteItemRequest; 086import microsoft.exchange.webservices.data.core.request.DeleteUserConfigurationRequest; 087import microsoft.exchange.webservices.data.core.request.EmptyFolderRequest; 088import microsoft.exchange.webservices.data.core.request.ExecuteDiagnosticMethodRequest; 089import microsoft.exchange.webservices.data.core.request.ExpandGroupRequest; 090import microsoft.exchange.webservices.data.core.request.FindConversationRequest; 091import microsoft.exchange.webservices.data.core.request.FindFolderRequest; 092import microsoft.exchange.webservices.data.core.request.FindItemRequest; 093import microsoft.exchange.webservices.data.core.request.GetAttachmentRequest; 094import microsoft.exchange.webservices.data.core.request.GetDelegateRequest; 095import microsoft.exchange.webservices.data.core.request.GetEventsRequest; 096import microsoft.exchange.webservices.data.core.request.GetFolderRequest; 097import microsoft.exchange.webservices.data.core.request.GetFolderRequestForLoad; 098import microsoft.exchange.webservices.data.core.request.GetInboxRulesRequest; 099import microsoft.exchange.webservices.data.core.request.GetItemRequest; 100import microsoft.exchange.webservices.data.core.request.GetItemRequestForLoad; 101import microsoft.exchange.webservices.data.core.request.GetPasswordExpirationDateRequest; 102import microsoft.exchange.webservices.data.core.request.GetRoomListsRequest; 103import microsoft.exchange.webservices.data.core.request.GetRoomsRequest; 104import microsoft.exchange.webservices.data.core.request.GetServerTimeZonesRequest; 105import microsoft.exchange.webservices.data.core.request.GetUserAvailabilityRequest; 106import microsoft.exchange.webservices.data.core.request.GetUserConfigurationRequest; 107import microsoft.exchange.webservices.data.core.request.GetUserOofSettingsRequest; 108import microsoft.exchange.webservices.data.core.request.HttpWebRequest; 109import microsoft.exchange.webservices.data.core.request.MoveFolderRequest; 110import microsoft.exchange.webservices.data.core.request.MoveItemRequest; 111import microsoft.exchange.webservices.data.core.request.RemoveDelegateRequest; 112import microsoft.exchange.webservices.data.core.request.ResolveNamesRequest; 113import microsoft.exchange.webservices.data.core.request.SendItemRequest; 114import microsoft.exchange.webservices.data.core.request.SetUserOofSettingsRequest; 115import microsoft.exchange.webservices.data.core.request.SubscribeToPullNotificationsRequest; 116import microsoft.exchange.webservices.data.core.request.SubscribeToPushNotificationsRequest; 117import microsoft.exchange.webservices.data.core.request.SubscribeToStreamingNotificationsRequest; 118import microsoft.exchange.webservices.data.core.request.SyncFolderHierarchyRequest; 119import microsoft.exchange.webservices.data.core.request.SyncFolderItemsRequest; 120import microsoft.exchange.webservices.data.core.request.UnsubscribeRequest; 121import microsoft.exchange.webservices.data.core.request.UpdateDelegateRequest; 122import microsoft.exchange.webservices.data.core.request.UpdateFolderRequest; 123import microsoft.exchange.webservices.data.core.request.UpdateInboxRulesRequest; 124import microsoft.exchange.webservices.data.core.request.UpdateItemRequest; 125import microsoft.exchange.webservices.data.core.request.UpdateUserConfigurationRequest; 126import microsoft.exchange.webservices.data.core.response.ConvertIdResponse; 127import microsoft.exchange.webservices.data.core.response.CreateAttachmentResponse; 128import microsoft.exchange.webservices.data.core.response.CreateResponseObjectResponse; 129import microsoft.exchange.webservices.data.core.response.DelegateManagementResponse; 130import microsoft.exchange.webservices.data.core.response.DelegateUserResponse; 131import microsoft.exchange.webservices.data.core.response.DeleteAttachmentResponse; 132import microsoft.exchange.webservices.data.core.response.FindFolderResponse; 133import microsoft.exchange.webservices.data.core.response.FindItemResponse; 134import microsoft.exchange.webservices.data.core.response.GetAttachmentResponse; 135import microsoft.exchange.webservices.data.core.response.GetDelegateResponse; 136import microsoft.exchange.webservices.data.core.response.GetFolderResponse; 137import microsoft.exchange.webservices.data.core.response.GetItemResponse; 138import microsoft.exchange.webservices.data.core.response.GetServerTimeZonesResponse; 139import microsoft.exchange.webservices.data.core.response.MoveCopyFolderResponse; 140import microsoft.exchange.webservices.data.core.response.MoveCopyItemResponse; 141import microsoft.exchange.webservices.data.core.response.ServiceResponse; 142import microsoft.exchange.webservices.data.core.response.ServiceResponseCollection; 143import microsoft.exchange.webservices.data.core.response.UpdateItemResponse; 144import microsoft.exchange.webservices.data.core.service.ServiceObject; 145import microsoft.exchange.webservices.data.core.service.folder.Folder; 146import microsoft.exchange.webservices.data.core.service.item.Appointment; 147import microsoft.exchange.webservices.data.core.service.item.Conversation; 148import microsoft.exchange.webservices.data.core.service.item.Item; 149import microsoft.exchange.webservices.data.messaging.UnifiedMessaging; 150import microsoft.exchange.webservices.data.misc.AsyncCallback; 151import microsoft.exchange.webservices.data.misc.AsyncRequestResult; 152import microsoft.exchange.webservices.data.misc.ConversationAction; 153import microsoft.exchange.webservices.data.misc.DelegateInformation; 154import microsoft.exchange.webservices.data.misc.ExpandGroupResults; 155import microsoft.exchange.webservices.data.misc.FolderIdWrapper; 156import microsoft.exchange.webservices.data.misc.IAsyncResult; 157import microsoft.exchange.webservices.data.misc.ImpersonatedUserId; 158import microsoft.exchange.webservices.data.misc.NameResolutionCollection; 159import microsoft.exchange.webservices.data.misc.OutParam; 160import microsoft.exchange.webservices.data.misc.UserConfiguration; 161import microsoft.exchange.webservices.data.misc.availability.AttendeeInfo; 162import microsoft.exchange.webservices.data.misc.availability.AvailabilityOptions; 163import microsoft.exchange.webservices.data.misc.availability.GetUserAvailabilityResults; 164import microsoft.exchange.webservices.data.misc.availability.TimeWindow; 165import microsoft.exchange.webservices.data.misc.id.AlternateIdBase; 166import microsoft.exchange.webservices.data.notification.GetEventsResults; 167import microsoft.exchange.webservices.data.notification.PullSubscription; 168import microsoft.exchange.webservices.data.notification.PushSubscription; 169import microsoft.exchange.webservices.data.notification.StreamingSubscription; 170import microsoft.exchange.webservices.data.property.complex.Attachment; 171import microsoft.exchange.webservices.data.property.complex.ConversationId; 172import microsoft.exchange.webservices.data.property.complex.DelegateUser; 173import microsoft.exchange.webservices.data.property.complex.EmailAddress; 174import microsoft.exchange.webservices.data.property.complex.EmailAddressCollection; 175import microsoft.exchange.webservices.data.property.complex.FolderId; 176import microsoft.exchange.webservices.data.property.complex.ItemId; 177import microsoft.exchange.webservices.data.property.complex.Mailbox; 178import microsoft.exchange.webservices.data.property.complex.RuleCollection; 179import microsoft.exchange.webservices.data.property.complex.RuleOperation; 180import microsoft.exchange.webservices.data.property.complex.StringList; 181import microsoft.exchange.webservices.data.property.complex.UserId; 182import microsoft.exchange.webservices.data.property.complex.availability.OofSettings; 183import microsoft.exchange.webservices.data.property.complex.time.TimeZoneDefinition; 184import microsoft.exchange.webservices.data.property.definition.PropertyDefinitionBase; 185import microsoft.exchange.webservices.data.search.CalendarView; 186import microsoft.exchange.webservices.data.search.ConversationIndexedItemView; 187import microsoft.exchange.webservices.data.search.FindFoldersResults; 188import microsoft.exchange.webservices.data.search.FindItemsResults; 189import microsoft.exchange.webservices.data.search.FolderView; 190import microsoft.exchange.webservices.data.search.GroupedFindItemsResults; 191import microsoft.exchange.webservices.data.search.Grouping; 192import microsoft.exchange.webservices.data.search.ItemView; 193import microsoft.exchange.webservices.data.search.ViewBase; 194import microsoft.exchange.webservices.data.search.filter.SearchFilter; 195import microsoft.exchange.webservices.data.sync.ChangeCollection; 196import microsoft.exchange.webservices.data.sync.FolderChange; 197import microsoft.exchange.webservices.data.sync.ItemChange; 198 199import org.apache.commons.logging.Log; 200import org.apache.commons.logging.LogFactory; 201import org.w3c.dom.Document; 202import org.w3c.dom.Node; 203 204/** 205 * Represents a binding to the Exchange Web Services. 206 */ 207public class ExchangeService extends ExchangeServiceBase implements IAutodiscoverRedirectionUrl { 208 209 private static final Log LOG = LogFactory.getLog(ExchangeService.class); 210 211 /** 212 * The url. 213 */ 214 private URI url; 215 216 /** 217 * The preferred culture. 218 */ 219 private Locale preferredCulture; 220 221 /** 222 * The DateTimePrecision 223 */ 224 private DateTimePrecision dateTimePrecision = DateTimePrecision.Default; 225 226 /** 227 * The impersonated user id. 228 */ 229 private ImpersonatedUserId impersonatedUserId; 230 // private Iterator<ItemId> Iterator; 231 /** 232 * The file attachment content handler. 233 */ 234 private IFileAttachmentContentHandler fileAttachmentContentHandler; 235 236 /** 237 * The unified messaging. 238 */ 239 private UnifiedMessaging unifiedMessaging; 240 241 private boolean enableScpLookup = true; 242 243 /** 244 * When false, used to indicate that we should use "Exchange2007" as the server version String rather than 245 * Exchange2007_SP1 (@see #getExchange2007CompatibilityMode). 246 * 247 */ 248 private boolean exchange2007CompatibilityMode = false; 249 250 /** 251 * Create response object. 252 * 253 * @param responseObject the response object 254 * @param parentFolderId the parent folder id 255 * @param messageDisposition the message disposition 256 * @return The list of item created or modified as a result of the 257 * "creation" of the response object. 258 * @throws Exception the exception 259 */ 260 public List<Item> internalCreateResponseObject(ServiceObject responseObject, FolderId parentFolderId, 261 MessageDisposition messageDisposition) throws Exception { 262 CreateResponseObjectRequest request = new CreateResponseObjectRequest( 263 this, ServiceErrorHandling.ThrowOnError); 264 Collection<ServiceObject> serviceList = new ArrayList<ServiceObject>(); 265 serviceList.add(responseObject); 266 request.setParentFolderId(parentFolderId); 267 request.setItems(serviceList); 268 request.setMessageDisposition(messageDisposition); 269 270 ServiceResponseCollection<CreateResponseObjectResponse> responses = request 271 .execute(); 272 273 return responses.getResponseAtIndex(0).getItems(); 274 } 275 276 /** 277 * Creates a folder. Calling this method results in a call to EWS. 278 * 279 * @param folder The folder. 280 * @param parentFolderId The parent folder Id 281 * @throws Exception the exception 282 */ 283 public void createFolder(Folder folder, FolderId parentFolderId) 284 throws Exception { 285 CreateFolderRequest request = new CreateFolderRequest(this, 286 ServiceErrorHandling.ThrowOnError); 287 List<Folder> folArry = new ArrayList<Folder>(); 288 folArry.add(folder); 289 request.setFolders(folArry); 290 request.setParentFolderId(parentFolderId); 291 292 request.execute(); 293 } 294 295 /** 296 * Updates a folder. 297 * 298 * @param folder The folder. 299 * @throws Exception the exception 300 */ 301 public void updateFolder(Folder folder) throws Exception { 302 UpdateFolderRequest request = new UpdateFolderRequest(this, 303 ServiceErrorHandling.ThrowOnError); 304 305 request.getFolders().add(folder); 306 307 request.execute(); 308 } 309 310 /** 311 * Copies a folder. Calling this method results in a call to EWS. 312 * 313 * @param folderId The folderId. 314 * @param destinationFolderId The destination folder id. 315 * @return the folder 316 * @throws Exception the exception 317 */ 318 public Folder copyFolder(FolderId folderId, FolderId destinationFolderId) 319 throws Exception { 320 CopyFolderRequest request = new CopyFolderRequest(this, 321 ServiceErrorHandling.ThrowOnError); 322 323 request.setDestinationFolderId(destinationFolderId); 324 request.getFolderIds().add(folderId); 325 326 ServiceResponseCollection<MoveCopyFolderResponse> responses = request 327 .execute(); 328 329 return responses.getResponseAtIndex(0).getFolder(); 330 } 331 332 /** 333 * Move a folder. 334 * 335 * @param folderId The folderId. 336 * @param destinationFolderId The destination folder id. 337 * @return the folder 338 * @throws Exception the exception 339 */ 340 public Folder moveFolder(FolderId folderId, FolderId destinationFolderId) 341 throws Exception { 342 MoveFolderRequest request = new MoveFolderRequest(this, 343 ServiceErrorHandling.ThrowOnError); 344 345 request.setDestinationFolderId(destinationFolderId); 346 request.getFolderIds().add(folderId); 347 348 ServiceResponseCollection<MoveCopyFolderResponse> responses = request 349 .execute(); 350 351 return responses.getResponseAtIndex(0).getFolder(); 352 } 353 354 /** 355 * Finds folder. 356 * 357 * @param parentFolderIds The parent folder ids. 358 * @param searchFilter The search filter. Available search filter classes include 359 * SearchFilter.IsEqualTo, SearchFilter.ContainsSubstring and 360 * SearchFilter.SearchFilterCollection 361 * @param view The view controlling the number of folder returned. 362 * @param errorHandlingMode Indicates the type of error handling should be done. 363 * @return Collection of service response. 364 * @throws Exception the exception 365 */ 366 private ServiceResponseCollection<FindFolderResponse> internalFindFolders( 367 Iterable<FolderId> parentFolderIds, SearchFilter searchFilter, 368 FolderView view, ServiceErrorHandling errorHandlingMode) 369 throws Exception { 370 FindFolderRequest request = new FindFolderRequest(this, 371 errorHandlingMode); 372 373 request.getParentFolderIds().addRangeFolderId(parentFolderIds); 374 request.setSearchFilter(searchFilter); 375 request.setView(view); 376 377 return request.execute(); 378 379 } 380 381 /** 382 * Obtains a list of folder by searching the sub-folder of the specified 383 * folder. 384 * 385 * @param parentFolderId The Id of the folder in which to search for folder. 386 * @param searchFilter The search filter. Available search filter classes include 387 * SearchFilter.IsEqualTo, SearchFilter.ContainsSubstring and 388 * SearchFilter.SearchFilterCollection 389 * @param view The view controlling the number of folder returned. 390 * @return An object representing the results of the search operation. 391 * @throws Exception the exception 392 */ 393 public FindFoldersResults findFolders(FolderId parentFolderId, 394 SearchFilter searchFilter, FolderView view) throws Exception { 395 EwsUtilities.validateParam(parentFolderId, "parentFolderId"); 396 EwsUtilities.validateParam(view, "view"); 397 EwsUtilities.validateParamAllowNull(searchFilter, "searchFilter"); 398 399 List<FolderId> folderIdArray = new ArrayList<FolderId>(); 400 folderIdArray.add(parentFolderId); 401 ServiceResponseCollection<FindFolderResponse> responses = this 402 .internalFindFolders(folderIdArray, searchFilter, view, 403 ServiceErrorHandling.ThrowOnError); 404 405 return responses.getResponseAtIndex(0).getResults(); 406 } 407 408 /** 409 * Obtains a list of folder by searching the sub-folder of the specified 410 * folder. 411 * 412 * @param parentFolderId The Id of the folder in which to search for folder. 413 * @param view The view controlling the number of folder returned. 414 * @return An object representing the results of the search operation. 415 * @throws Exception the exception 416 */ 417 public FindFoldersResults findFolders(FolderId parentFolderId, 418 FolderView view) throws Exception { 419 EwsUtilities.validateParam(parentFolderId, "parentFolderId"); 420 EwsUtilities.validateParam(view, "view"); 421 422 List<FolderId> folderIdArray = new ArrayList<FolderId>(); 423 folderIdArray.add(parentFolderId); 424 425 ServiceResponseCollection<FindFolderResponse> responses = this 426 .internalFindFolders(folderIdArray, null, /* searchFilter */ 427 view, ServiceErrorHandling.ThrowOnError); 428 429 return responses.getResponseAtIndex(0).getResults(); 430 } 431 432 /** 433 * Obtains a list of folder by searching the sub-folder of the specified 434 * folder. 435 * 436 * @param parentFolderName The name of the folder in which to search for folder. 437 * @param searchFilter The search filter. Available search filter classes include 438 * SearchFilter.IsEqualTo, SearchFilter.ContainsSubstring and 439 * SearchFilter.SearchFilterCollection 440 * @param view The view controlling the number of folder returned. 441 * @return An object representing the results of the search operation. 442 * @throws Exception the exception 443 */ 444 public FindFoldersResults findFolders(WellKnownFolderName parentFolderName, 445 SearchFilter searchFilter, FolderView view) throws Exception { 446 return this.findFolders(new FolderId(parentFolderName), searchFilter, 447 view); 448 } 449 450 /** 451 * Obtains a list of folder by searching the sub-folder of the specified 452 * folder. 453 * 454 * @param parentFolderName the parent folder name 455 * @param view the view 456 * @return An object representing the results of the search operation. 457 * @throws Exception the exception 458 */ 459 public FindFoldersResults findFolders(WellKnownFolderName parentFolderName, 460 FolderView view) throws Exception { 461 return this.findFolders(new FolderId(parentFolderName), view); 462 } 463 464 /** 465 * Load specified property for a folder. 466 * 467 * @param folder The folder 468 * @param propertySet The property set 469 * @throws Exception the exception 470 */ 471 public void loadPropertiesForFolder(Folder folder, PropertySet propertySet) throws Exception { 472 EwsUtilities.validateParam(folder, "folder"); 473 EwsUtilities.validateParam(propertySet, "propertySet"); 474 475 GetFolderRequestForLoad request = new GetFolderRequestForLoad(this, 476 ServiceErrorHandling.ThrowOnError); 477 478 request.getFolderIds().add(folder); 479 request.setPropertySet(propertySet); 480 481 request.execute(); 482 } 483 484 /** 485 * Binds to a folder. 486 * 487 * 488 * @param folderId the folder id 489 * @param propertySet the property set 490 * @return Folder 491 * @throws Exception the exception 492 */ 493 public Folder bindToFolder(FolderId folderId, PropertySet propertySet) 494 throws Exception { 495 EwsUtilities.validateParam(folderId, "folderId"); 496 EwsUtilities.validateParam(propertySet, "propertySet"); 497 498 GetFolderRequest request = new GetFolderRequest(this, 499 ServiceErrorHandling.ThrowOnError); 500 501 request.getFolderIds().add(folderId); 502 request.setPropertySet(propertySet); 503 504 ServiceResponseCollection<GetFolderResponse> responses = request 505 .execute(); 506 507 return responses.getResponseAtIndex(0).getFolder(); 508 509 } 510 511 /** 512 * Binds to folder. 513 * 514 * @param <TFolder> The type of the folder. 515 * @param cls Folder class 516 * @param folderId The folder id. 517 * @param propertySet The property set. 518 * @return Folder 519 * @throws Exception the exception 520 */ 521 public <TFolder extends Folder> TFolder bindToFolder(Class<TFolder> cls, FolderId folderId, 522 PropertySet propertySet) throws Exception { 523 Folder result = this.bindToFolder(folderId, propertySet); 524 525 if (cls.isAssignableFrom(result.getClass())) { 526 return (TFolder) result; 527 } else { 528 throw new ServiceLocalException(String.format( 529 "The folder type returned by the service (%s) isn't compatible with the requested folder type (%s).", 530 result.getClass().getName(), cls.getName())); 531 } 532 } 533 534 /** 535 * Deletes a folder. Calling this method results in a call to EWS. 536 * 537 * @param folderId The folder id 538 * @param deleteMode The delete mode 539 * @throws Exception the exception 540 */ 541 public void deleteFolder(FolderId folderId, DeleteMode deleteMode) 542 throws Exception { 543 EwsUtilities.validateParam(folderId, "folderId"); 544 545 DeleteFolderRequest request = new DeleteFolderRequest(this, 546 ServiceErrorHandling.ThrowOnError); 547 548 request.getFolderIds().add(folderId); 549 request.setDeleteMode(deleteMode); 550 551 request.execute(); 552 } 553 554 /** 555 * Empties a folder. Calling this method results in a call to EWS. 556 * 557 * @param folderId The folder id 558 * @param deleteMode The delete mode 559 * @param deleteSubFolders if set to "true" empty folder should also delete sub folder. 560 * @throws Exception the exception 561 */ 562 public void emptyFolder(FolderId folderId, DeleteMode deleteMode, boolean deleteSubFolders) throws Exception { 563 EwsUtilities.validateParam(folderId, "folderId"); 564 565 EmptyFolderRequest request = new EmptyFolderRequest(this, 566 ServiceErrorHandling.ThrowOnError); 567 568 request.getFolderIds().add(folderId); 569 request.setDeleteMode(deleteMode); 570 request.setDeleteSubFolders(deleteSubFolders); 571 request.execute(); 572 } 573 574 /** 575 * Creates multiple item in a single EWS call. Supported item classes are 576 * EmailMessage, Appointment, Contact, PostItem, Task and Item. CreateItems 577 * does not support item that have unsaved attachments. 578 * 579 * @param items the item 580 * @param parentFolderId the parent folder id 581 * @param messageDisposition the message disposition 582 * @param sendInvitationsMode the send invitations mode 583 * @param errorHandling the error handling 584 * @return A ServiceResponseCollection providing creation results for each 585 * of the specified item. 586 * @throws Exception the exception 587 */ 588 private ServiceResponseCollection<ServiceResponse> internalCreateItems( 589 Collection<Item> items, FolderId parentFolderId, 590 MessageDisposition messageDisposition, 591 SendInvitationsMode sendInvitationsMode, 592 ServiceErrorHandling errorHandling) throws Exception { 593 CreateItemRequest request = new CreateItemRequest(this, errorHandling); 594 request.setParentFolderId(parentFolderId); 595 request.setItems(items); 596 request.setMessageDisposition(messageDisposition); 597 request.setSendInvitationsMode(sendInvitationsMode); 598 return request.execute(); 599 } 600 601 /** 602 * Creates multiple item in a single EWS call. Supported item classes are 603 * EmailMessage, Appointment, Contact, PostItem, Task and Item. CreateItems 604 * does not support item that have unsaved attachments. 605 * 606 * @param items the item 607 * @param parentFolderId the parent folder id 608 * @param messageDisposition the message disposition 609 * @param sendInvitationsMode the send invitations mode 610 * @return A ServiceResponseCollection providing creation results for each 611 * of the specified item. 612 * @throws Exception the exception 613 */ 614 public ServiceResponseCollection<ServiceResponse> createItems( 615 Collection<Item> items, FolderId parentFolderId, 616 MessageDisposition messageDisposition, 617 SendInvitationsMode sendInvitationsMode) throws Exception { 618 // All item have to be new. 619 if (!EwsUtilities.trueForAll(items, new IPredicate<Item>() { 620 @Override 621 public boolean predicate(Item obj) throws ServiceLocalException { 622 return obj.isNew(); 623 } 624 })) { 625 throw new ServiceValidationException( 626 "This operation can't be performed because at least one item already has an ID."); 627 } 628 629 // E14:298274 Make sure that all item do *not* have unprocessed 630 // attachments. 631 if (!EwsUtilities.trueForAll(items, new IPredicate<Item>() { 632 @Override 633 public boolean predicate(Item obj) throws ServiceLocalException { 634 return !obj.hasUnprocessedAttachmentChanges(); 635 } 636 })) { 637 throw new ServiceValidationException("This operation doesn't support item that have attachments."); 638 } 639 return this.internalCreateItems(items, parentFolderId, 640 messageDisposition, sendInvitationsMode, 641 ServiceErrorHandling.ReturnErrors); 642 } 643 644 /** 645 * Creates an item. Calling this method results in a call to EWS. 646 * 647 * @param item the item 648 * @param parentFolderId the parent folder id 649 * @param messageDisposition the message disposition 650 * @param sendInvitationsMode the send invitations mode 651 * @throws Exception the exception 652 */ 653 public void createItem(Item item, FolderId parentFolderId, MessageDisposition messageDisposition, 654 SendInvitationsMode sendInvitationsMode) throws Exception { 655 ArrayList<Item> items = new ArrayList<Item>(); 656 items.add(item); 657 internalCreateItems(items, parentFolderId, messageDisposition, sendInvitationsMode, 658 ServiceErrorHandling.ThrowOnError); 659 } 660 661 /** 662 * Updates multiple item in a single EWS call. UpdateItems does not 663 * support item that have unsaved attachments. 664 * 665 * @param items the item 666 * @param savedItemsDestinationFolderId the saved item destination folder id 667 * @param conflictResolution the conflict resolution 668 * @param messageDisposition the message disposition 669 * @param sendInvitationsOrCancellationsMode the send invitations or cancellations mode 670 * @param errorHandling the error handling 671 * @return A ServiceResponseCollection providing update results for each of 672 * the specified item. 673 * @throws Exception the exception 674 */ 675 private ServiceResponseCollection<UpdateItemResponse> internalUpdateItems( 676 Iterable<Item> items, 677 FolderId savedItemsDestinationFolderId, 678 ConflictResolutionMode conflictResolution, 679 MessageDisposition messageDisposition, 680 SendInvitationsOrCancellationsMode sendInvitationsOrCancellationsMode, 681 ServiceErrorHandling errorHandling) throws Exception { 682 UpdateItemRequest request = new UpdateItemRequest(this, errorHandling); 683 684 request.getItems().addAll((Collection<? extends Item>) items); 685 request.setSavedItemsDestinationFolder(savedItemsDestinationFolderId); 686 request.setMessageDisposition(messageDisposition); 687 request.setConflictResolutionMode(conflictResolution); 688 request 689 .setSendInvitationsOrCancellationsMode(sendInvitationsOrCancellationsMode); 690 691 return request.execute(); 692 } 693 694 /** 695 * Updates multiple item in a single EWS call. UpdateItems does not 696 * support item that have unsaved attachments. 697 * 698 * @param items the item 699 * @param savedItemsDestinationFolderId the saved item destination folder id 700 * @param conflictResolution the conflict resolution 701 * @param messageDisposition the message disposition 702 * @param sendInvitationsOrCancellationsMode the send invitations or cancellations mode 703 * @return A ServiceResponseCollection providing update results for each of 704 * the specified item. 705 * @throws Exception the exception 706 */ 707 public ServiceResponseCollection<UpdateItemResponse> updateItems( 708 Iterable<Item> items, 709 FolderId savedItemsDestinationFolderId, 710 ConflictResolutionMode conflictResolution, 711 MessageDisposition messageDisposition, 712 SendInvitationsOrCancellationsMode sendInvitationsOrCancellationsMode) 713 throws Exception { 714 715 // All item have to exist on the server (!new) and modified (dirty) 716 if (!EwsUtilities.trueForAll(items, new IPredicate<Item>() { 717 @Override 718 public boolean predicate(Item obj) throws ServiceLocalException { 719 return (!obj.isNew() && obj.isDirty()); 720 } 721 })) { 722 throw new ServiceValidationException( 723 "This operation can't be performed because one or more item are new or unmodified."); 724 } 725 726 // E14:298274 Make sure that all item do *not* have unprocessed 727 // attachments. 728 if (!EwsUtilities.trueForAll(items, new IPredicate<Item>() { 729 @Override 730 public boolean predicate(Item obj) throws ServiceLocalException { 731 return !obj.hasUnprocessedAttachmentChanges(); 732 } 733 })) { 734 throw new ServiceValidationException( 735 "This operation can't be performed because attachments have been added or deleted for one or more item."); 736 } 737 738 return this.internalUpdateItems(items, savedItemsDestinationFolderId, conflictResolution, 739 messageDisposition, sendInvitationsOrCancellationsMode, 740 ServiceErrorHandling.ReturnErrors); 741 } 742 743 /** 744 * Updates an item. 745 * 746 * @param item the item 747 * @param savedItemsDestinationFolderId the saved item destination folder id 748 * @param conflictResolution the conflict resolution 749 * @param messageDisposition the message disposition 750 * @param sendInvitationsOrCancellationsMode the send invitations or cancellations mode 751 * @return A ServiceResponseCollection providing deletion results for each 752 * of the specified item Ids. 753 * @throws Exception the exception 754 */ 755 public Item updateItem(Item item, FolderId savedItemsDestinationFolderId, 756 ConflictResolutionMode conflictResolution, MessageDisposition messageDisposition, 757 SendInvitationsOrCancellationsMode sendInvitationsOrCancellationsMode) 758 throws Exception { 759 List<Item> itemIdArray = new ArrayList<Item>(); 760 itemIdArray.add(item); 761 762 ServiceResponseCollection<UpdateItemResponse> responses = this 763 .internalUpdateItems(itemIdArray, 764 savedItemsDestinationFolderId, conflictResolution, 765 messageDisposition, sendInvitationsOrCancellationsMode, 766 ServiceErrorHandling.ThrowOnError); 767 768 return responses.getResponseAtIndex(0).getReturnedItem(); 769 } 770 771 /** 772 * Send item. 773 * 774 * @param item the item 775 * @param savedCopyDestinationFolderId the saved copy destination folder id 776 * @throws Exception the exception 777 */ 778 public void sendItem(Item item, FolderId savedCopyDestinationFolderId) 779 throws Exception { 780 SendItemRequest request = new SendItemRequest(this, 781 ServiceErrorHandling.ThrowOnError); 782 783 List<Item> itemIdArray = new ArrayList<Item>(); 784 itemIdArray.add(item); 785 786 request.setItems(itemIdArray); 787 request.setSavedCopyDestinationFolderId(savedCopyDestinationFolderId); 788 789 request.execute(); 790 } 791 792 /** 793 * Copies multiple item in a single call to EWS. 794 * 795 * @param itemIds the item ids 796 * @param destinationFolderId the destination folder id 797 * @param returnNewItemIds Flag indicating whether service should return new ItemIds or 798 * not. 799 * @param errorHandling the error handling 800 * @return A ServiceResponseCollection providing copy results for each of 801 * the specified item Ids. 802 * @throws Exception the exception 803 */ 804 private ServiceResponseCollection<MoveCopyItemResponse> internalCopyItems( 805 Iterable<ItemId> itemIds, FolderId destinationFolderId, 806 Boolean returnNewItemIds, ServiceErrorHandling errorHandling) 807 throws Exception { 808 CopyItemRequest request = new CopyItemRequest(this, errorHandling); 809 request.getItemIds().addRange(itemIds); 810 request.setDestinationFolderId(destinationFolderId); 811 request.setReturnNewItemIds(returnNewItemIds); 812 return request.execute(); 813 814 } 815 816 /** 817 * Copies multiple item in a single call to EWS. 818 * 819 * @param itemIds the item ids 820 * @param destinationFolderId the destination folder id 821 * @return A ServiceResponseCollection providing copy results for each of 822 * the specified item Ids. 823 * @throws Exception the exception 824 */ 825 public ServiceResponseCollection<MoveCopyItemResponse> copyItems( 826 Iterable<ItemId> itemIds, FolderId destinationFolderId) 827 throws Exception { 828 return this.internalCopyItems(itemIds, destinationFolderId, null, 829 ServiceErrorHandling.ReturnErrors); 830 } 831 832 /** 833 * Copies multiple item in a single call to EWS. 834 * 835 * @param itemIds The Ids of the item to copy. 836 * @param destinationFolderId The Id of the folder to copy the item to. 837 * @param returnNewItemIds Flag indicating whether service should return new ItemIds or 838 * not. 839 * @return A ServiceResponseCollection providing copy results for each of 840 * the specified item Ids. 841 * @throws Exception on error 842 */ 843 public ServiceResponseCollection<MoveCopyItemResponse> copyItems( 844 Iterable<ItemId> itemIds, FolderId destinationFolderId, 845 boolean returnNewItemIds) throws Exception { 846 EwsUtilities.validateMethodVersion(this, ExchangeVersion.Exchange2010_SP1, "CopyItems"); 847 848 return this.internalCopyItems(itemIds, destinationFolderId, returnNewItemIds, 849 ServiceErrorHandling.ReturnErrors); 850 } 851 852 /** 853 * Copies an item. Calling this method results in a call to EWS. 854 * 855 * @param itemId The Id of the item to copy. 856 * @param destinationFolderId The folder in which to save sent messages, meeting invitations 857 * or cancellations. If null, the message, meeting invitation or 858 * cancellation is saved in the Sent Items folder 859 * @return The copy of the item. 860 * @throws Exception the exception 861 */ 862 public Item copyItem(ItemId itemId, FolderId destinationFolderId) 863 throws Exception { 864 List<ItemId> itemIdArray = new ArrayList<ItemId>(); 865 itemIdArray.add(itemId); 866 867 return this.internalCopyItems(itemIdArray, destinationFolderId, null, 868 ServiceErrorHandling.ThrowOnError).getResponseAtIndex(0) 869 .getItem(); 870 } 871 872 /** 873 * Moves multiple item in a single call to EWS. 874 * 875 * @param itemIds the item ids 876 * @param destinationFolderId the destination folder id 877 * @param returnNewItemIds Flag indicating whether service should return new ItemIds or 878 * not. 879 * @param errorHandling the error handling 880 * @return A ServiceResponseCollection providing copy results for each of 881 * the specified item Ids. 882 * @throws Exception the exception 883 */ 884 private ServiceResponseCollection<MoveCopyItemResponse> internalMoveItems( 885 Iterable<ItemId> itemIds, FolderId destinationFolderId, 886 Boolean returnNewItemIds, ServiceErrorHandling errorHandling) 887 throws Exception { 888 MoveItemRequest request = new MoveItemRequest(this, errorHandling); 889 890 request.getItemIds().addRange(itemIds); 891 request.setDestinationFolderId(destinationFolderId); 892 request.setReturnNewItemIds(returnNewItemIds); 893 return request.execute(); 894 } 895 896 /** 897 * Moves multiple item in a single call to EWS. 898 * 899 * @param itemIds the item ids 900 * @param destinationFolderId the destination folder id 901 * @return A ServiceResponseCollection providing copy results for each of 902 * the specified item Ids. 903 * @throws Exception the exception 904 */ 905 public ServiceResponseCollection<MoveCopyItemResponse> moveItems( 906 Iterable<ItemId> itemIds, FolderId destinationFolderId) 907 throws Exception { 908 return this.internalMoveItems(itemIds, destinationFolderId, null, 909 ServiceErrorHandling.ReturnErrors); 910 } 911 912 /** 913 * Moves multiple item in a single call to EWS. 914 * 915 * @param itemIds The Ids of the item to move. 916 * @param destinationFolderId The Id of the folder to move the item to. 917 * @param returnNewItemIds Flag indicating whether service should return new ItemIds or 918 * not. 919 * @return A ServiceResponseCollection providing copy results for each of 920 * the specified item Ids. 921 * @throws Exception on error 922 */ 923 public ServiceResponseCollection<MoveCopyItemResponse> moveItems( 924 Iterable<ItemId> itemIds, FolderId destinationFolderId, 925 boolean returnNewItemIds) throws Exception { 926 EwsUtilities.validateMethodVersion(this, ExchangeVersion.Exchange2010_SP1, "MoveItems"); 927 928 return this.internalMoveItems(itemIds, destinationFolderId, returnNewItemIds, 929 ServiceErrorHandling.ReturnErrors); 930 } 931 932 /** 933 * Copies multiple item in a single call to EWS. 934 * 935 * @param itemId the item id 936 * @param destinationFolderId the destination folder id 937 * @return A ServiceResponseCollection providing copy results for each of 938 * the specified item Ids. 939 * @throws Exception the exception 940 */ 941 public Item moveItem(ItemId itemId, FolderId destinationFolderId) 942 throws Exception { 943 List<ItemId> itemIdArray = new ArrayList<ItemId>(); 944 itemIdArray.add(itemId); 945 946 return this.internalMoveItems(itemIdArray, destinationFolderId, null, 947 ServiceErrorHandling.ThrowOnError).getResponseAtIndex(0) 948 .getItem(); 949 } 950 951 /** 952 * Finds item. 953 * 954 * @param <TItem> The type of item 955 * @param parentFolderIds The parent folder ids. 956 * @param searchFilter The search filter. Available search filter classes include 957 * SearchFilter.IsEqualTo, SearchFilter.ContainsSubstring and 958 * SearchFilter.SearchFilterCollection 959 * @param queryString the query string 960 * @param view The view controlling the number of folder returned. 961 * @param groupBy The group by. 962 * @param errorHandlingMode Indicates the type of error handling should be done. 963 * @return Service response collection. 964 * @throws Exception the exception 965 */ 966 public <TItem extends Item> ServiceResponseCollection<FindItemResponse<TItem>> findItems( 967 Iterable<FolderId> parentFolderIds, SearchFilter searchFilter, String queryString, ViewBase view, 968 Grouping groupBy, ServiceErrorHandling errorHandlingMode) throws Exception { 969 EwsUtilities.validateParamCollection(parentFolderIds.iterator(), 970 "parentFolderIds"); 971 EwsUtilities.validateParam(view, "view"); 972 EwsUtilities.validateParamAllowNull(groupBy, "groupBy"); 973 EwsUtilities.validateParamAllowNull(queryString, "queryString"); 974 EwsUtilities.validateParamAllowNull(searchFilter, "searchFilter"); 975 976 FindItemRequest<TItem> request = new FindItemRequest<TItem>(this, 977 errorHandlingMode); 978 979 request.getParentFolderIds().addRangeFolderId(parentFolderIds); 980 request.setSearchFilter(searchFilter); 981 request.setQueryString(queryString); 982 request.setView(view); 983 request.setGroupBy(groupBy); 984 985 return request.execute(); 986 } 987 988 /** 989 * Obtains a list of item by searching the contents of a specific folder. 990 * Calling this method results in a call to EWS. 991 * 992 * @param parentFolderId the parent folder id 993 * @param queryString the query string 994 * @param view the view 995 * @return An object representing the results of the search operation. 996 * @throws Exception the exception 997 */ 998 public FindItemsResults<Item> findItems(FolderId parentFolderId, 999 String queryString, ItemView view) throws Exception { 1000 EwsUtilities.validateParamAllowNull(queryString, "queryString"); 1001 1002 List<FolderId> folderIdArray = new ArrayList<FolderId>(); 1003 folderIdArray.add(parentFolderId); 1004 1005 ServiceResponseCollection<FindItemResponse<Item>> responses = this 1006 .findItems(folderIdArray, null, /* searchFilter */ 1007 queryString, view, null, /* groupBy */ 1008 ServiceErrorHandling.ThrowOnError); 1009 1010 return responses.getResponseAtIndex(0).getResults(); 1011 } 1012 1013 /** 1014 * Obtains a list of item by searching the contents of a specific folder. 1015 * Calling this method results in a call to EWS. 1016 * 1017 * @param parentFolderId the parent folder id 1018 * @param searchFilter the search filter 1019 * @param view the view 1020 * @return An object representing the results of the search operation. 1021 * @throws Exception the exception 1022 */ 1023 public FindItemsResults<Item> findItems(FolderId parentFolderId, 1024 SearchFilter searchFilter, ItemView view) throws Exception { 1025 EwsUtilities.validateParamAllowNull(searchFilter, "searchFilter"); 1026 List<FolderId> folderIdArray = new ArrayList<FolderId>(); 1027 folderIdArray.add(parentFolderId); 1028 ServiceResponseCollection<FindItemResponse<Item>> responses = this 1029 .findItems(folderIdArray, searchFilter, null, /* queryString */ 1030 view, null, /* groupBy */ 1031 ServiceErrorHandling.ThrowOnError); 1032 1033 return responses.getResponseAtIndex(0).getResults(); 1034 } 1035 1036 /** 1037 * Obtains a list of item by searching the contents of a specific folder. 1038 * Calling this method results in a call to EWS. 1039 * 1040 * @param parentFolderId the parent folder id 1041 * @param view the view 1042 * @return An object representing the results of the search operation. 1043 * @throws Exception the exception 1044 */ 1045 public FindItemsResults<Item> findItems(FolderId parentFolderId, 1046 ItemView view) throws Exception { 1047 List<FolderId> folderIdArray = new ArrayList<FolderId>(); 1048 folderIdArray.add(parentFolderId); 1049 ServiceResponseCollection<FindItemResponse<Item>> responses = this 1050 .findItems(folderIdArray, null, /* searchFilter */ 1051 null, /* queryString */ 1052 view, null, /* groupBy */ 1053 ServiceErrorHandling.ThrowOnError); 1054 1055 return responses.getResponseAtIndex(0).getResults(); 1056 } 1057 1058 /** 1059 * Obtains a list of item by searching the contents of a specific folder. 1060 * Calling this method results in a call to EWS. 1061 * 1062 * @param parentFolderName the parent folder name 1063 * @param queryString the query string 1064 * @param view the view 1065 * @return An object representing the results of the search operation. 1066 * @throws Exception the exception 1067 */ 1068 public FindItemsResults<Item> findItems( 1069 WellKnownFolderName parentFolderName, String queryString, 1070 ItemView view) throws Exception { 1071 return this 1072 .findItems(new FolderId(parentFolderName), queryString, view); 1073 } 1074 1075 /** 1076 * Obtains a list of item by searching the contents of a specific folder. 1077 * Calling this method results in a call to EWS. 1078 * 1079 * @param parentFolderName the parent folder name 1080 * @param searchFilter the search filter 1081 * @param view the view 1082 * @return An object representing the results of the search operation. 1083 * @throws Exception the exception 1084 */ 1085 public FindItemsResults<Item> findItems( 1086 WellKnownFolderName parentFolderName, SearchFilter searchFilter, 1087 ItemView view) throws Exception { 1088 return this.findItems(new FolderId(parentFolderName), searchFilter, 1089 view); 1090 } 1091 1092 /** 1093 * Obtains a list of item by searching the contents of a specific folder. 1094 * Calling this method results in a call to EWS. 1095 * 1096 * @param parentFolderName the parent folder name 1097 * @param view the view 1098 * @return An object representing the results of the search operation. 1099 * @throws Exception the exception 1100 */ 1101 public FindItemsResults<Item> findItems( 1102 WellKnownFolderName parentFolderName, ItemView view) 1103 throws Exception { 1104 return this.findItems(new FolderId(parentFolderName), (SearchFilter) null, view); 1105 } 1106 1107 /** 1108 * Obtains a grouped list of item by searching the contents of a specific 1109 * folder. Calling this method results in a call to EWS. 1110 * 1111 * @param parentFolderId the parent folder id 1112 * @param queryString the query string 1113 * @param view the view 1114 * @param groupBy the group by 1115 * @return A list of item containing the contents of the specified folder. 1116 * @throws Exception the exception 1117 */ 1118 public GroupedFindItemsResults<Item> findItems(FolderId parentFolderId, 1119 String queryString, ItemView view, Grouping groupBy) 1120 throws Exception { 1121 EwsUtilities.validateParam(groupBy, "groupBy"); 1122 EwsUtilities.validateParamAllowNull(queryString, "queryString"); 1123 1124 List<FolderId> folderIdArray = new ArrayList<FolderId>(); 1125 folderIdArray.add(parentFolderId); 1126 1127 ServiceResponseCollection<FindItemResponse<Item>> responses = this 1128 .findItems(folderIdArray, null, /* searchFilter */ 1129 queryString, view, groupBy, ServiceErrorHandling.ThrowOnError); 1130 1131 return responses.getResponseAtIndex(0).getGroupedFindResults(); 1132 } 1133 1134 /** 1135 * Obtains a grouped list of item by searching the contents of a specific 1136 * folder. Calling this method results in a call to EWS. 1137 * 1138 * @param parentFolderId the parent folder id 1139 * @param searchFilter the search filter 1140 * @param view the view 1141 * @param groupBy the group by 1142 * @return A list of item containing the contents of the specified folder. 1143 * @throws Exception the exception 1144 */ 1145 public GroupedFindItemsResults<Item> findItems(FolderId parentFolderId, 1146 SearchFilter searchFilter, ItemView view, Grouping groupBy) 1147 throws Exception { 1148 EwsUtilities.validateParam(groupBy, "groupBy"); 1149 EwsUtilities.validateParamAllowNull(searchFilter, "searchFilter"); 1150 1151 List<FolderId> folderIdArray = new ArrayList<FolderId>(); 1152 folderIdArray.add(parentFolderId); 1153 1154 ServiceResponseCollection<FindItemResponse<Item>> responses = this 1155 .findItems(folderIdArray, searchFilter, null, /* queryString */ 1156 view, groupBy, ServiceErrorHandling.ThrowOnError); 1157 1158 return responses.getResponseAtIndex(0).getGroupedFindResults(); 1159 } 1160 1161 /** 1162 * Obtains a grouped list of item by searching the contents of a specific 1163 * folder. Calling this method results in a call to EWS. 1164 * 1165 * @param parentFolderId the parent folder id 1166 * @param view the view 1167 * @param groupBy the group by 1168 * @return A list of item containing the contents of the specified folder. 1169 * @throws Exception the exception 1170 */ 1171 public GroupedFindItemsResults<Item> findItems(FolderId parentFolderId, 1172 ItemView view, Grouping groupBy) throws Exception { 1173 EwsUtilities.validateParam(groupBy, "groupBy"); 1174 1175 List<FolderId> folderIdArray = new ArrayList<FolderId>(); 1176 folderIdArray.add(parentFolderId); 1177 1178 ServiceResponseCollection<FindItemResponse<Item>> responses = this 1179 .findItems(folderIdArray, null, /* searchFilter */ 1180 null, /* queryString */ 1181 view, groupBy, ServiceErrorHandling.ThrowOnError); 1182 1183 return responses.getResponseAtIndex(0).getGroupedFindResults(); 1184 } 1185 1186 /** 1187 * Obtains a grouped list of item by searching the contents of a specific 1188 * folder. Calling this method results in a call to EWS. 1189 * 1190 * @param <TItem> the generic type 1191 * @param cls the cls 1192 * @param parentFolderId the parent folder id 1193 * @param searchFilter the search filter 1194 * @param view the view 1195 * @param groupBy the group by 1196 * @return A list of item containing the contents of the specified folder. 1197 * @throws Exception the exception 1198 */ 1199 protected <TItem extends Item> ServiceResponseCollection<FindItemResponse<TItem>> findItems( 1200 Class<TItem> cls, FolderId parentFolderId, 1201 SearchFilter searchFilter, ViewBase view, Grouping groupBy) 1202 throws Exception { 1203 List<FolderId> folderIdArray = new ArrayList<FolderId>(); 1204 folderIdArray.add(parentFolderId); 1205 1206 return this.findItems(folderIdArray, searchFilter, null, /* queryString */ 1207 view, groupBy, ServiceErrorHandling.ThrowOnError); 1208 } 1209 1210 /** 1211 * Obtains a grouped list of item by searching the contents of a specific 1212 * folder. Calling this method results in a call to EWS. 1213 * 1214 * @param parentFolderName the parent folder name 1215 * @param queryString the query string 1216 * @param view the view 1217 * @param groupBy the group by 1218 * @return A collection of grouped item containing the contents of the 1219 * specified. 1220 * @throws Exception the exception 1221 */ 1222 public GroupedFindItemsResults<Item> findItems( 1223 WellKnownFolderName parentFolderName, String queryString, 1224 ItemView view, Grouping groupBy) throws Exception { 1225 EwsUtilities.validateParam(groupBy, "groupBy"); 1226 return this.findItems(new FolderId(parentFolderName), queryString, 1227 view, groupBy); 1228 } 1229 1230 /** 1231 * Obtains a grouped list of item by searching the contents of a specific 1232 * folder. Calling this method results in a call to EWS. 1233 * 1234 * @param parentFolderName the parent folder name 1235 * @param searchFilter the search filter 1236 * @param view the view 1237 * @param groupBy the group by 1238 * @return A collection of grouped item containing the contents of the 1239 * specified. 1240 * @throws Exception the exception 1241 */ 1242 public GroupedFindItemsResults<Item> findItems( 1243 WellKnownFolderName parentFolderName, SearchFilter searchFilter, 1244 ItemView view, Grouping groupBy) throws Exception { 1245 return this.findItems(new FolderId(parentFolderName), searchFilter, view, groupBy); 1246 } 1247 1248 /** 1249 * Obtains a list of appointments by searching the contents of a specific 1250 * folder. Calling this method results in a call to EWS. 1251 * 1252 * @param parentFolderId the parent folder id 1253 * @param calendarView the calendar view 1254 * @return A collection of appointments representing the contents of the 1255 * specified folder. 1256 * @throws Exception the exception 1257 */ 1258 public FindItemsResults<Appointment> findAppointments( 1259 FolderId parentFolderId, CalendarView calendarView) 1260 throws Exception { 1261 List<FolderId> folderIdArray = new ArrayList<FolderId>(); 1262 folderIdArray.add(parentFolderId); 1263 1264 ServiceResponseCollection<FindItemResponse<Appointment>> response = this 1265 .findItems(folderIdArray, null, /* searchFilter */ 1266 null /* queryString */, calendarView, null, /* groupBy */ 1267 ServiceErrorHandling.ThrowOnError); 1268 1269 return response.getResponseAtIndex(0).getResults(); 1270 } 1271 1272 /** 1273 * Obtains a list of appointments by searching the contents of a specific 1274 * folder. Calling this method results in a call to EWS. 1275 * 1276 * @param parentFolderName the parent folder name 1277 * @param calendarView the calendar view 1278 * @return A collection of appointments representing the contents of the 1279 * specified folder. 1280 * @throws Exception the exception 1281 */ 1282 public FindItemsResults<Appointment> findAppointments( 1283 WellKnownFolderName parentFolderName, CalendarView calendarView) 1284 throws Exception { 1285 return this.findAppointments(new FolderId(parentFolderName), calendarView); 1286 } 1287 1288 /** 1289 * Loads the property of multiple item in a single call to EWS. 1290 * 1291 * @param items the item 1292 * @param propertySet the property set 1293 * @return A ServiceResponseCollection providing results for each of the 1294 * specified item. 1295 * @throws Exception the exception 1296 */ 1297 public ServiceResponseCollection<ServiceResponse> loadPropertiesForItems( 1298 Iterable<Item> items, PropertySet propertySet) throws Exception { 1299 EwsUtilities.validateParamCollection(items.iterator(), "item"); 1300 EwsUtilities.validateParam(propertySet, "propertySet"); 1301 1302 return this.internalLoadPropertiesForItems(items, propertySet, ServiceErrorHandling.ReturnErrors); 1303 } 1304 1305 /** 1306 * Loads the property of multiple item in a single call to EWS. 1307 * 1308 * @param items the item 1309 * @param propertySet the property set 1310 * @param errorHandling the error handling 1311 * @return A ServiceResponseCollection providing results for each of the 1312 * specified item. 1313 * @throws Exception the exception 1314 */ 1315 public ServiceResponseCollection<ServiceResponse> internalLoadPropertiesForItems(Iterable<Item> items, 1316 PropertySet propertySet, ServiceErrorHandling errorHandling) throws Exception { 1317 GetItemRequestForLoad request = new GetItemRequestForLoad(this, 1318 errorHandling); 1319 // return null; 1320 1321 request.getItemIds().addRangeItem(items); 1322 request.setPropertySet(propertySet); 1323 1324 return request.execute(); 1325 } 1326 1327 /** 1328 * Binds to multiple item in a single call to EWS. 1329 * 1330 * @param itemIds the item ids 1331 * @param propertySet the property set 1332 * @param errorHandling the error handling 1333 * @return A ServiceResponseCollection providing results for each of the 1334 * specified item Ids. 1335 * @throws Exception the exception 1336 */ 1337 private ServiceResponseCollection<GetItemResponse> internalBindToItems( 1338 Iterable<ItemId> itemIds, PropertySet propertySet, 1339 ServiceErrorHandling errorHandling) throws Exception { 1340 GetItemRequest request = new GetItemRequest(this, errorHandling); 1341 request.getItemIds().addRange(itemIds); 1342 request.setPropertySet(propertySet); 1343 return request.execute(); 1344 } 1345 1346 /** 1347 * Binds to multiple item in a single call to EWS. 1348 * 1349 * @param itemIds the item ids 1350 * @param propertySet the property set 1351 * @return A ServiceResponseCollection providing results for each of the 1352 * specified item Ids. 1353 * @throws Exception the exception 1354 */ 1355 public ServiceResponseCollection<GetItemResponse> bindToItems( 1356 Iterable<ItemId> itemIds, PropertySet propertySet) throws Exception { 1357 EwsUtilities.validateParamCollection(itemIds.iterator(), "itemIds"); 1358 EwsUtilities.validateParam(propertySet, "propertySet"); 1359 1360 return this.internalBindToItems(itemIds, propertySet, ServiceErrorHandling.ReturnErrors); 1361 } 1362 1363 /** 1364 * Binds to multiple item in a single call to EWS. 1365 * 1366 * @param itemId the item id 1367 * @param propertySet the property set 1368 * @return A ServiceResponseCollection providing results for each of the 1369 * specified item Ids. 1370 * @throws Exception the exception 1371 */ 1372 public Item bindToItem(ItemId itemId, PropertySet propertySet) 1373 throws Exception { 1374 EwsUtilities.validateParam(itemId, "itemId"); 1375 EwsUtilities.validateParam(propertySet, "propertySet"); 1376 List<ItemId> itmLst = new ArrayList<ItemId>(); 1377 itmLst.add(itemId); 1378 ServiceResponseCollection<GetItemResponse> responses = this 1379 .internalBindToItems(itmLst, propertySet, ServiceErrorHandling.ThrowOnError); 1380 1381 return responses.getResponseAtIndex(0).getItem(); 1382 } 1383 1384 /** 1385 * Bind to item. 1386 * 1387 * @param <TItem> The type of the item. 1388 * @param c the c 1389 * @param itemId the item id 1390 * @param propertySet the property set 1391 * @return the t item 1392 * @throws Exception the exception 1393 */ 1394 public <TItem extends Item> TItem bindToItem(Class<TItem> c, ItemId itemId, PropertySet propertySet) throws Exception { 1395 Item result = this.bindToItem(itemId, propertySet); 1396 if (c.isAssignableFrom(result.getClass())) { 1397 return (TItem) result; 1398 } else { 1399 throw new ServiceLocalException(String.format( 1400 "The item type returned by the service (%s) isn't compatible with the requested item type (%s).", result.getClass().getName(), 1401 c.getName())); 1402 } 1403 } 1404 1405 /** 1406 * Deletes multiple item in a single call to EWS. 1407 * 1408 * @param itemIds the item ids 1409 * @param deleteMode the delete mode 1410 * @param sendCancellationsMode the send cancellations mode 1411 * @param affectedTaskOccurrences the affected task occurrences 1412 * @param errorHandling the error handling 1413 * @return A ServiceResponseCollection providing deletion results for each 1414 * of the specified item Ids. 1415 * @throws Exception the exception 1416 */ 1417 private ServiceResponseCollection<ServiceResponse> internalDeleteItems( 1418 Iterable<ItemId> itemIds, DeleteMode deleteMode, 1419 SendCancellationsMode sendCancellationsMode, 1420 AffectedTaskOccurrence affectedTaskOccurrences, 1421 ServiceErrorHandling errorHandling) throws Exception { 1422 DeleteItemRequest request = new DeleteItemRequest(this, errorHandling); 1423 1424 request.getItemIds().addRange(itemIds); 1425 request.setDeleteMode(deleteMode); 1426 request.setSendCancellationsMode(sendCancellationsMode); 1427 request.setAffectedTaskOccurrences(affectedTaskOccurrences); 1428 1429 return request.execute(); 1430 } 1431 1432 /** 1433 * Deletes multiple item in a single call to EWS. 1434 * 1435 * @param itemIds the item ids 1436 * @param deleteMode the delete mode 1437 * @param sendCancellationsMode the send cancellations mode 1438 * @param affectedTaskOccurrences the affected task occurrences 1439 * @return A ServiceResponseCollection providing deletion results for each 1440 * of the specified item Ids. 1441 * @throws Exception the exception 1442 */ 1443 public ServiceResponseCollection<ServiceResponse> deleteItems( 1444 Iterable<ItemId> itemIds, DeleteMode deleteMode, 1445 SendCancellationsMode sendCancellationsMode, 1446 AffectedTaskOccurrence affectedTaskOccurrences) throws Exception { 1447 EwsUtilities.validateParamCollection(itemIds.iterator(), "itemIds"); 1448 1449 return this.internalDeleteItems(itemIds, deleteMode, 1450 sendCancellationsMode, affectedTaskOccurrences, 1451 ServiceErrorHandling.ReturnErrors); 1452 } 1453 1454 /** 1455 * Deletes an item. Calling this method results in a call to EWS. 1456 * 1457 * @param itemId the item id 1458 * @param deleteMode the delete mode 1459 * @param sendCancellationsMode the send cancellations mode 1460 * @param affectedTaskOccurrences the affected task occurrences 1461 * @throws Exception the exception 1462 */ 1463 public void deleteItem(ItemId itemId, DeleteMode deleteMode, SendCancellationsMode sendCancellationsMode, 1464 AffectedTaskOccurrence affectedTaskOccurrences) throws Exception { 1465 List<ItemId> itemIdArray = new ArrayList<ItemId>(); 1466 itemIdArray.add(itemId); 1467 1468 EwsUtilities.validateParam(itemId, "itemId"); 1469 this.internalDeleteItems(itemIdArray, deleteMode, 1470 sendCancellationsMode, affectedTaskOccurrences, 1471 ServiceErrorHandling.ThrowOnError); 1472 } 1473 1474 /** 1475 * Gets an attachment. 1476 * 1477 * @param attachments the attachments 1478 * @param bodyType the body type 1479 * @param additionalProperties the additional property 1480 * @param errorHandling the error handling 1481 * @throws Exception the exception 1482 */ 1483 private ServiceResponseCollection<GetAttachmentResponse> internalGetAttachments( 1484 Iterable<Attachment> attachments, BodyType bodyType, 1485 Iterable<PropertyDefinitionBase> additionalProperties, ServiceErrorHandling errorHandling) 1486 throws Exception { 1487 GetAttachmentRequest request = new GetAttachmentRequest(this, errorHandling); 1488 1489 Iterator<Attachment> it = attachments.iterator(); 1490 while (it.hasNext()) { 1491 request.getAttachments().add(it.next()); 1492 } 1493 request.setBodyType(bodyType); 1494 1495 if (additionalProperties != null) { 1496 List<PropertyDefinitionBase> propsArray = new ArrayList<PropertyDefinitionBase>(); 1497 for (PropertyDefinitionBase propertyDefinitionBase : additionalProperties) { 1498 propsArray.add(propertyDefinitionBase); 1499 } 1500 request.getAdditionalProperties().addAll(propsArray); 1501 } 1502 1503 return request.execute(); 1504 } 1505 1506 /** 1507 * Gets attachments. 1508 * 1509 * @param attachments the attachments 1510 * @param bodyType the body type 1511 * @param additionalProperties the additional property 1512 * @return service response collection 1513 * @throws Exception on error 1514 */ 1515 protected ServiceResponseCollection<GetAttachmentResponse> getAttachments( 1516 Attachment[] attachments, BodyType bodyType, 1517 Iterable<PropertyDefinitionBase> additionalProperties) 1518 throws Exception { 1519 return this.internalGetAttachments(Arrays.asList(attachments), bodyType, 1520 additionalProperties, ServiceErrorHandling.ReturnErrors); 1521 } 1522 1523 /** 1524 * Gets the attachment. 1525 * 1526 * @param attachment the attachment 1527 * @param bodyType the body type 1528 * @param additionalProperties the additional property 1529 * @throws Exception the exception 1530 */ 1531 public void getAttachment(Attachment attachment, BodyType bodyType, 1532 Iterable<PropertyDefinitionBase> additionalProperties) 1533 throws Exception { 1534 1535 List<Attachment> attachmentArray = new ArrayList<Attachment>(); 1536 attachmentArray.add(attachment); 1537 1538 this.internalGetAttachments(attachmentArray, bodyType, additionalProperties, 1539 ServiceErrorHandling.ThrowOnError); 1540 1541 } 1542 1543 /** 1544 * Creates attachments. 1545 * 1546 * @param parentItemId the parent item id 1547 * @param attachments the attachments 1548 * @return Service response collection. 1549 * @throws ServiceResponseException the service response exception 1550 * @throws Exception the exception 1551 */ 1552 public ServiceResponseCollection<CreateAttachmentResponse> createAttachments(String parentItemId, 1553 Iterable<Attachment> attachments) 1554 throws ServiceResponseException, Exception { 1555 CreateAttachmentRequest request = new CreateAttachmentRequest(this, 1556 ServiceErrorHandling.ReturnErrors); 1557 1558 request.setParentItemId(parentItemId); 1559 /* 1560 * if (null != attachments) { while (attachments.hasNext()) { 1561 * request.getAttachments().add(attachments.next()); } } 1562 */ 1563 request.getAttachments().addAll( 1564 (Collection<? extends Attachment>) attachments); 1565 1566 return request.execute(); 1567 } 1568 1569 /** 1570 * Deletes attachments. 1571 * 1572 * @param attachments the attachments 1573 * @return the service response collection 1574 * @throws ServiceResponseException the service response exception 1575 * @throws Exception the exception 1576 */ 1577 public ServiceResponseCollection<DeleteAttachmentResponse> deleteAttachments( 1578 Iterable<Attachment> attachments) throws ServiceResponseException, 1579 Exception { 1580 DeleteAttachmentRequest request = new DeleteAttachmentRequest(this, 1581 ServiceErrorHandling.ReturnErrors); 1582 1583 request.getAttachments().addAll( 1584 (Collection<? extends Attachment>) attachments); 1585 1586 return request.execute(); 1587 } 1588 1589 /** 1590 * Finds contacts in the user's Contacts folder and the Global Address 1591 * List (in that order) that have names that match the one passed as a 1592 * parameter. Calling this method results in a call to EWS. 1593 * 1594 * @param nameToResolve the name to resolve 1595 * @return A collection of name resolutions whose names match the one passed 1596 * as a parameter. 1597 * @throws Exception the exception 1598 */ 1599 public NameResolutionCollection resolveName(String nameToResolve) 1600 throws Exception { 1601 return this.resolveName(nameToResolve, ResolveNameSearchLocation.ContactsThenDirectory, false); 1602 } 1603 1604 /** 1605 * Finds contacts in the user's Contacts folder and the Global Address 1606 * List (in that order) that have names that match the one passed as a 1607 * parameter. Calling this method results in a call to EWS. 1608 * 1609 * @param nameToResolve the name to resolve 1610 * @param parentFolderIds the parent folder ids 1611 * @param searchScope the search scope 1612 * @param returnContactDetails the return contact details 1613 * @return A collection of name resolutions whose names match the one passed 1614 * as a parameter. 1615 * @throws Exception the exception 1616 */ 1617 public NameResolutionCollection resolveName(String nameToResolve, 1618 Iterable<FolderId> parentFolderIds, 1619 ResolveNameSearchLocation searchScope, boolean returnContactDetails) 1620 throws Exception { 1621 return resolveName(nameToResolve, parentFolderIds, searchScope, returnContactDetails, null); 1622 1623 } 1624 1625 /** 1626 * Finds contacts in the Global Address List and/or in specific contact 1627 * folder that have names that match the one passed as a parameter. Calling 1628 * this method results in a call to EWS. 1629 * 1630 * @param nameToResolve The name to resolve. 1631 * @param parentFolderIds The Ids of the contact folder in which to look for matching 1632 * contacts. 1633 * @param searchScope The scope of the search. 1634 * @param returnContactDetails Indicates whether full contact information should be returned 1635 * for each of the found contacts. 1636 * @param contactDataPropertySet The property set for the contact details 1637 * @return a collection of name resolutions whose names match the one passed as a parameter 1638 * @throws Exception on error 1639 */ 1640 public NameResolutionCollection resolveName(String nameToResolve, 1641 Iterable<FolderId> parentFolderIds, 1642 ResolveNameSearchLocation searchScope, 1643 boolean returnContactDetails, PropertySet contactDataPropertySet) 1644 throws Exception { 1645 if (contactDataPropertySet != null) { 1646 EwsUtilities.validateMethodVersion(this, 1647 ExchangeVersion.Exchange2010_SP1, "ResolveName"); 1648 } 1649 1650 EwsUtilities.validateParam(nameToResolve, "nameToResolve"); 1651 1652 if (parentFolderIds != null) { 1653 EwsUtilities.validateParamCollection(parentFolderIds.iterator(), 1654 "parentFolderIds"); 1655 } 1656 ResolveNamesRequest request = new ResolveNamesRequest(this); 1657 1658 request.setNameToResolve(nameToResolve); 1659 request.setReturnFullContactData(returnContactDetails); 1660 request.getParentFolderIds().addRangeFolderId(parentFolderIds); 1661 request.setSearchLocation(searchScope); 1662 request.setContactDataPropertySet(contactDataPropertySet); 1663 1664 return request.execute().getResponseAtIndex(0).getResolutions(); 1665 } 1666 1667 /** 1668 * Finds contacts in the Global Address List that have names that match the 1669 * one passed as a parameter. Calling this method results in a call to EWS. 1670 * 1671 * @param nameToResolve The name to resolve. 1672 * @param searchScope The scope of the search. 1673 * @param returnContactDetails Indicates whether full contact information should be returned 1674 * for each of the found contacts. 1675 * @param contactDataPropertySet The property set for the contact details 1676 * @return A collection of name resolutions whose names match the one 1677 * passed as a parameter. 1678 * @throws Exception on error 1679 */ 1680 public NameResolutionCollection resolveName(String nameToResolve, 1681 ResolveNameSearchLocation searchScope, 1682 boolean returnContactDetails, PropertySet contactDataPropertySet) 1683 throws Exception { 1684 return this.resolveName(nameToResolve, null, searchScope, 1685 returnContactDetails, contactDataPropertySet); 1686 } 1687 1688 /** 1689 * Finds contacts in the user's Contacts folder and the Global Address 1690 * List (in that order) that have names that match the one passed as a 1691 * parameter. Calling this method results in a call to EWS. 1692 * 1693 * @param nameToResolve the name to resolve 1694 * @param searchScope the search scope 1695 * @param returnContactDetails the return contact details 1696 * @return A collection of name resolutions whose names match the one passed 1697 * as a parameter. 1698 * @throws Exception the exception 1699 */ 1700 public NameResolutionCollection resolveName(String nameToResolve, 1701 ResolveNameSearchLocation searchScope, boolean returnContactDetails) 1702 throws Exception { 1703 return this.resolveName(nameToResolve, null, searchScope, returnContactDetails); 1704 } 1705 1706 /** 1707 * Expands a group by retrieving a list of its members. Calling this 1708 * method results in a call to EWS. 1709 * 1710 * @param emailAddress the email address 1711 * @return URL of the Exchange Web Services. 1712 * @throws Exception the exception 1713 */ 1714 public ExpandGroupResults expandGroup(EmailAddress emailAddress) 1715 throws Exception { 1716 EwsUtilities.validateParam(emailAddress, "emailAddress"); 1717 ExpandGroupRequest request = new ExpandGroupRequest(this); 1718 request.setEmailAddress(emailAddress); 1719 return request.execute().getResponseAtIndex(0).getMembers(); 1720 } 1721 1722 /** 1723 * Expands a group by retrieving a list of its members. Calling this 1724 * method results in a call to EWS. 1725 * 1726 * @param groupId the group id 1727 * @return An ExpandGroupResults containing the members of the group. 1728 * @throws Exception the exception 1729 */ 1730 public ExpandGroupResults expandGroup(ItemId groupId) throws Exception { 1731 EwsUtilities.validateParam(groupId, "groupId"); 1732 EmailAddress emailAddress = new EmailAddress(); 1733 emailAddress.setId(groupId); 1734 return this.expandGroup(emailAddress); 1735 } 1736 1737 /** 1738 * Expands a group by retrieving a list of its members. Calling this 1739 * method results in a call to EWS. 1740 * 1741 * @param smtpAddress the smtp address 1742 * @return An ExpandGroupResults containing the members of the group. 1743 * @throws Exception the exception 1744 */ 1745 public ExpandGroupResults expandGroup(String smtpAddress) throws Exception { 1746 EwsUtilities.validateParam(smtpAddress, "smtpAddress"); 1747 return this.expandGroup(new EmailAddress(smtpAddress)); 1748 } 1749 1750 /** 1751 * Expands a group by retrieving a list of its members. Calling this 1752 * method results in a call to EWS. 1753 * 1754 * @param address the address 1755 * @param routingType the routing type 1756 * @return An ExpandGroupResults containing the members of the group. 1757 * @throws Exception the exception 1758 */ 1759 public ExpandGroupResults expandGroup(String address, String routingType) 1760 throws Exception { 1761 EwsUtilities.validateParam(address, "address"); 1762 EwsUtilities.validateParam(routingType, "routingType"); 1763 1764 EmailAddress emailAddress = new EmailAddress(address); 1765 emailAddress.setRoutingType(routingType); 1766 return this.expandGroup(emailAddress); 1767 } 1768 1769 /** 1770 * Get the password expiration date 1771 * 1772 * @param mailboxSmtpAddress The e-mail address of the user. 1773 * @return The password expiration date 1774 * @throws Exception on error 1775 */ 1776 public Date getPasswordExpirationDate(String mailboxSmtpAddress) throws Exception { 1777 GetPasswordExpirationDateRequest request = new GetPasswordExpirationDateRequest(this); 1778 request.setMailboxSmtpAddress(mailboxSmtpAddress); 1779 1780 return request.execute().getPasswordExpirationDate(); 1781 } 1782 1783 /** 1784 * Subscribes to pull notification. Calling this method results in a call 1785 * to EWS. 1786 * 1787 * @param folderIds The Ids of the folder to subscribe to 1788 * @param timeout The timeout, in minutes, after which the subscription expires. 1789 * Timeout must be between 1 and 1440. 1790 * @param watermark An optional watermark representing a previously opened 1791 * subscription. 1792 * @param eventTypes The event types to subscribe to. 1793 * @return A PullSubscription representing the new subscription. 1794 * @throws Exception on error 1795 */ 1796 public PullSubscription subscribeToPullNotifications( 1797 Iterable<FolderId> folderIds, int timeout, String watermark, 1798 EventType... eventTypes) throws Exception { 1799 EwsUtilities.validateParamCollection(folderIds.iterator(), "folderIds"); 1800 1801 return this.buildSubscribeToPullNotificationsRequest(folderIds, 1802 timeout, watermark, eventTypes).execute().getResponseAtIndex(0) 1803 .getSubscription(); 1804 } 1805 1806 /** 1807 * Begins an asynchronous request to subscribes to pull notification. 1808 * Calling this method results in a call to EWS. 1809 * 1810 * @param callback The AsyncCallback delegate. 1811 * @param state An object that contains state information for this request. 1812 * @param folderIds The Ids of the folder to subscribe to. 1813 * @param timeout The timeout, in minutes, after which the subscription expires. 1814 * Timeout must be between 1 and 1440. 1815 * @param watermark An optional watermark representing a previously opened 1816 * subscription. 1817 * @param eventTypes The event types to subscribe to. 1818 * @return An IAsyncResult that references the asynchronous request. 1819 * @throws Exception 1820 */ 1821 public AsyncRequestResult beginSubscribeToPullNotifications( 1822 AsyncCallback callback, Object state, Iterable<FolderId> folderIds, 1823 int timeout, String watermark, EventType... eventTypes) 1824 throws Exception { 1825 EwsUtilities.validateParamCollection(folderIds.iterator(), "folderIds"); 1826 1827 return this.buildSubscribeToPullNotificationsRequest(folderIds, timeout, watermark, 1828 eventTypes).beginExecute(callback); 1829 } 1830 1831 /** 1832 * Subscribes to pull notification on all folder in the authenticated 1833 * user's mailbox. Calling this method results in a call to EWS. 1834 * 1835 * @param timeout the timeout 1836 * @param watermark the watermark 1837 * @param eventTypes the event types 1838 * @return A PullSubscription representing the new subscription. 1839 * @throws Exception the exception 1840 */ 1841 public PullSubscription subscribeToPullNotificationsOnAllFolders( 1842 int timeout, String watermark, EventType... eventTypes) 1843 throws Exception { 1844 EwsUtilities.validateMethodVersion(this, ExchangeVersion.Exchange2010, 1845 "SubscribeToPullNotificationsOnAllFolders"); 1846 1847 return this.buildSubscribeToPullNotificationsRequest(null, timeout, 1848 watermark, eventTypes).execute().getResponseAtIndex(0) 1849 .getSubscription(); 1850 } 1851 1852 /** 1853 * Begins an asynchronous request to subscribe to pull notification on all 1854 * folder in the authenticated user's mailbox. Calling this method results 1855 * in a call to EWS. 1856 * 1857 * @param callback The AsyncCallback delegate. 1858 * @param state An object that contains state information for this request. 1859 * @param timeout The timeout, in minutes, after which the subscription expires. 1860 * Timeout must be between 1 and 1440. 1861 * @param watermark An optional watermark representing a previously opened 1862 * subscription. 1863 * @param eventTypes The event types to subscribe to. 1864 * @return An IAsyncResult that references the asynchronous request. 1865 * @throws Exception 1866 */ 1867 public IAsyncResult beginSubscribeToPullNotificationsOnAllFolders(AsyncCallback callback, Object state, 1868 int timeout, 1869 String watermark, EventType... eventTypes) throws Exception { 1870 EwsUtilities.validateMethodVersion(this, ExchangeVersion.Exchange2010, 1871 "BeginSubscribeToPullNotificationsOnAllFolders"); 1872 1873 return this.buildSubscribeToPullNotificationsRequest(null, timeout, watermark, eventTypes).beginExecute( 1874 null); 1875 } 1876 1877 /** 1878 * Ends an asynchronous request to subscribe to pull notification in the 1879 * authenticated user's mailbox. 1880 * 1881 * @param asyncResult An IAsyncResult that references the asynchronous request. 1882 * @return A PullSubscription representing the new subscription. 1883 * @throws Exception 1884 */ 1885 public PullSubscription endSubscribeToPullNotifications( 1886 IAsyncResult asyncResult) throws Exception { 1887 SubscribeToPullNotificationsRequest request = AsyncRequestResult 1888 .extractServiceRequest(this, asyncResult); 1889 1890 return request.endExecute(asyncResult).getResponseAtIndex(0) 1891 .getSubscription(); 1892 } 1893 1894 /** 1895 * Builds a request to subscribe to pull notification in the 1896 * authenticated user's mailbox. 1897 * 1898 * @param folderIds The Ids of the folder to subscribe to. 1899 * @param timeout The timeout, in minutes, after which the subscription expires. 1900 * Timeout must be between 1 and 1440 1901 * @param watermark An optional watermark representing a previously opened 1902 * subscription 1903 * @param eventTypes The event types to subscribe to 1904 * @return A request to subscribe to pull notification in the authenticated 1905 * user's mailbox 1906 * @throws Exception the exception 1907 */ 1908 private SubscribeToPullNotificationsRequest buildSubscribeToPullNotificationsRequest( 1909 Iterable<FolderId> folderIds, int timeout, String watermark, 1910 EventType... eventTypes) throws Exception { 1911 if (timeout < 1 || timeout > 1440) { 1912 throw new IllegalArgumentException("timeout", new Throwable( 1913 "Timeout must be a value between 1 and 1440.")); 1914 } 1915 1916 EwsUtilities.validateParamCollection(eventTypes, "eventTypes"); 1917 1918 SubscribeToPullNotificationsRequest request = new SubscribeToPullNotificationsRequest( 1919 this); 1920 1921 if (folderIds != null) { 1922 request.getFolderIds().addRangeFolderId(folderIds); 1923 } 1924 1925 request.setTimeOut(timeout); 1926 1927 for (EventType event : eventTypes) { 1928 request.getEventTypes().add(event); 1929 } 1930 1931 request.setWatermark(watermark); 1932 1933 return request; 1934 } 1935 1936 /** 1937 * Unsubscribes from a pull subscription. Calling this method results in a 1938 * call to EWS. 1939 * 1940 * @param subscriptionId the subscription id 1941 * @throws Exception the exception 1942 */ 1943 public void unsubscribe(String subscriptionId) throws Exception { 1944 1945 this.buildUnsubscribeRequest(subscriptionId).execute(); 1946 } 1947 1948 /** 1949 * Begins an asynchronous request to unsubscribe from a subscription. 1950 * Calling this method results in a call to EWS. 1951 * 1952 * @param callback The AsyncCallback delegate. 1953 * @param state An object that contains state information for this request. 1954 * @param subscriptionId The Id of the pull subscription to unsubscribe from. 1955 * @return An IAsyncResult that references the asynchronous request. 1956 * @throws Exception 1957 */ 1958 public IAsyncResult beginUnsubscribe(AsyncCallback callback, Object state, String subscriptionId) 1959 throws Exception { 1960 return this.buildUnsubscribeRequest(subscriptionId).beginExecute(callback); 1961 } 1962 1963 /** 1964 * Ends an asynchronous request to unsubscribe from a subscription. 1965 * 1966 * @param asyncResult An IAsyncResult that references the asynchronous request. 1967 * @throws Exception 1968 */ 1969 public void endUnsubscribe(IAsyncResult asyncResult) throws Exception { 1970 UnsubscribeRequest request = AsyncRequestResult.extractServiceRequest(this, asyncResult); 1971 1972 request.endExecute(asyncResult); 1973 } 1974 1975 /** 1976 * Buids a request to unsubscribe from a subscription. 1977 * 1978 * @param subscriptionId The id of the subscription for which to get the events 1979 * @return A request to unsubscripbe from a subscription 1980 * @throws Exception 1981 */ 1982 private UnsubscribeRequest buildUnsubscribeRequest(String subscriptionId) 1983 throws Exception { 1984 EwsUtilities.validateParam(subscriptionId, "subscriptionId"); 1985 1986 UnsubscribeRequest request = new UnsubscribeRequest(this); 1987 1988 request.setSubscriptionId(subscriptionId); 1989 1990 return request; 1991 } 1992 1993 /** 1994 * Retrieves the latests events associated with a pull subscription. 1995 * Calling this method results in a call to EWS. 1996 * 1997 * @param subscriptionId the subscription id 1998 * @param waterMark the water mark 1999 * @return A GetEventsResults containing a list of events associated with 2000 * the subscription. 2001 * @throws Exception the exception 2002 */ 2003 public GetEventsResults getEvents(String subscriptionId, String waterMark) 2004 throws Exception { 2005 2006 return this.buildGetEventsRequest(subscriptionId, waterMark).execute() 2007 .getResponseAtIndex(0).getResults(); 2008 } 2009 2010 /** 2011 * Begins an asynchronous request to retrieve the latest events associated 2012 * with a pull subscription. Calling this method results in a call to EWS. 2013 * 2014 * @param callback The AsyncCallback delegate. 2015 * @param state An object that contains state information for this request. 2016 * @param subscriptionId The id of the pull subscription for which to get the events 2017 * @param watermark The watermark representing the point in time where to start 2018 * receiving events 2019 * @return An IAsynResult that references the asynchronous request 2020 * @throws Exception 2021 */ 2022 public IAsyncResult beginGetEvents(AsyncCallback callback, Object state, String subscriptionId, 2023 String watermark) throws Exception { 2024 return this.buildGetEventsRequest(subscriptionId, watermark) 2025 .beginExecute(callback); 2026 } 2027 2028 /** 2029 * Ends an asynchronous request to retrieve the latest events associated 2030 * with a pull subscription. 2031 * 2032 * @param asyncResult An IAsyncResult that references the asynchronous request. 2033 * @return A GetEventsResults containing a list of events associated with 2034 * the subscription. 2035 * @throws Exception 2036 */ 2037 public GetEventsResults endGetEvents(IAsyncResult asyncResult) throws Exception { 2038 GetEventsRequest request = AsyncRequestResult.extractServiceRequest(this, asyncResult); 2039 2040 return request.endExecute(asyncResult).getResponseAtIndex(0).getResults(); 2041 } 2042 2043 /** 2044 * Builds a request to retrieve the letest events associated with a pull 2045 * subscription 2046 * 2047 * @param subscriptionId The Id of the pull subscription for which to get the events 2048 * @param watermark The watermark representing the point in time where to start 2049 * receiving events 2050 * @return An request to retrieve the latest events associated with a pull 2051 * subscription 2052 * @throws Exception 2053 */ 2054 private GetEventsRequest buildGetEventsRequest(String subscriptionId, 2055 String watermark) throws Exception { 2056 EwsUtilities.validateParam(subscriptionId, "subscriptionId"); 2057 EwsUtilities.validateParam(watermark, "watermark"); 2058 2059 GetEventsRequest request = new GetEventsRequest(this); 2060 2061 request.setSubscriptionId(subscriptionId); 2062 request.setWatermark(watermark); 2063 2064 return request; 2065 } 2066 2067 /** 2068 * Subscribes to push notification. Calling this method results in a call 2069 * to EWS. 2070 * 2071 * @param folderIds the folder ids 2072 * @param url the url 2073 * @param frequency the frequency 2074 * @param watermark the watermark 2075 * @param eventTypes the event types 2076 * @return A PushSubscription representing the new subscription. 2077 * @throws Exception the exception 2078 */ 2079 public PushSubscription subscribeToPushNotifications( 2080 Iterable<FolderId> folderIds, URI url, int frequency, 2081 String watermark, EventType... eventTypes) throws Exception { 2082 EwsUtilities.validateParamCollection(folderIds.iterator(), "folderIds"); 2083 2084 return this.buildSubscribeToPushNotificationsRequest(folderIds, url, 2085 frequency, watermark, eventTypes).execute().getResponseAtIndex(0).getSubscription(); 2086 } 2087 2088 /** 2089 * Begins an asynchronous request to subscribe to push notification. 2090 * Calling this method results in a call to EWS. 2091 * 2092 * @param callback The asynccallback delegate 2093 * @param state An object that contains state information for this request 2094 * @param folderIds The ids of the folder to subscribe 2095 * @param url the url of web service endpoint the exchange server should 2096 * @param frequency the frequency,in minutes at which the exchange server should 2097 * contact the web Service endpoint. Frequency must be between 1 2098 * and 1440. 2099 * @param watermark An optional watermark representing a previously opened 2100 * subscription 2101 * @param eventTypes The event types to subscribe to. 2102 * @return An IAsyncResult that references the asynchronous request. 2103 * @throws Exception 2104 */ 2105 public IAsyncResult beginSubscribeToPushNotifications( 2106 AsyncCallback callback, Object state, Iterable<FolderId> folderIds, 2107 URI url, int frequency, String watermark, EventType... eventTypes) 2108 throws Exception { 2109 EwsUtilities.validateParamCollection(folderIds.iterator(), "folderIds"); 2110 2111 return this.buildSubscribeToPushNotificationsRequest(folderIds, url, frequency, watermark, 2112 eventTypes).beginExecute(callback); 2113 } 2114 2115 /** 2116 * Subscribes to push notification on all folder in the authenticated 2117 * user's mailbox. Calling this method results in a call to EWS. 2118 * 2119 * @param url the url 2120 * @param frequency the frequency 2121 * @param watermark the watermark 2122 * @param eventTypes the event types 2123 * @return A PushSubscription representing the new subscription. 2124 * @throws Exception the exception 2125 */ 2126 public PushSubscription subscribeToPushNotificationsOnAllFolders(URI url, 2127 int frequency, String watermark, EventType... eventTypes) 2128 throws Exception { 2129 EwsUtilities.validateMethodVersion(this, ExchangeVersion.Exchange2010, 2130 "SubscribeToPushNotificationsOnAllFolders"); 2131 2132 return this.buildSubscribeToPushNotificationsRequest(null, url, 2133 frequency, watermark, eventTypes).execute().getResponseAtIndex(0).getSubscription(); 2134 } 2135 2136 /** 2137 * Begins an asynchronous request to subscribe to push notification on all 2138 * folder in the authenticated user's mailbox. Calling this method results 2139 * in a call to EWS. 2140 * 2141 * @param callback The asynccallback delegate 2142 * @param state An object that contains state inforamtion for this request 2143 * @param url the url 2144 * @param frequency the frequency,in minutes at which the exchange server should 2145 * contact the web Service endpoint. Frequency must be between 1 2146 * and 1440. 2147 * @param watermark An optional watermark representing a previously opened 2148 * subscription 2149 * @param eventTypes The event types to subscribe to. 2150 * @return An IAsyncResult that references the asynchronous request. 2151 * @throws Exception 2152 */ 2153 public IAsyncResult beginSubscribeToPushNotificationsOnAllFolders( 2154 AsyncCallback callback, Object state, URI url, int frequency, 2155 String watermark, EventType... eventTypes) throws Exception { 2156 EwsUtilities.validateMethodVersion(this, ExchangeVersion.Exchange2010, 2157 "BeginSubscribeToPushNotificationsOnAllFolders"); 2158 2159 return this.buildSubscribeToPushNotificationsRequest(null, url, frequency, watermark, 2160 eventTypes).beginExecute(callback); 2161 } 2162 2163 2164 /** 2165 * Ends an asynchronous request to subscribe to push notification in the 2166 * authenticated user's mailbox. 2167 * 2168 * @param asyncResult An IAsyncResult that references the asynchronous request. 2169 * @return A PushSubscription representing the new subscription 2170 * @throws Exception 2171 */ 2172 public PushSubscription endSubscribeToPushNotifications( 2173 IAsyncResult asyncResult) throws Exception { 2174 SubscribeToPushNotificationsRequest request = AsyncRequestResult 2175 .extractServiceRequest(this, asyncResult); 2176 2177 return request.endExecute(asyncResult).getResponseAtIndex(0) 2178 .getSubscription(); 2179 } 2180 2181 /** 2182 * Builds an request to request to subscribe to push notification in the 2183 * authenticated user's mailbox. 2184 * 2185 * @param folderIds the folder ids 2186 * @param url the url 2187 * @param frequency the frequency 2188 * @param watermark the watermark 2189 * @param eventTypes the event types 2190 * @return A request to request to subscribe to push notification in the 2191 * authenticated user's mailbox. 2192 * @throws Exception the exception 2193 */ 2194 private SubscribeToPushNotificationsRequest buildSubscribeToPushNotificationsRequest( 2195 Iterable<FolderId> folderIds, URI url, int frequency, 2196 String watermark, EventType[] eventTypes) throws Exception { 2197 EwsUtilities.validateParam(url, "url"); 2198 if (frequency < 1 || frequency > 1440) { 2199 throw new ArgumentOutOfRangeException("frequency", "The frequency must be a value between 1 and 1440."); 2200 } 2201 2202 EwsUtilities.validateParamCollection(eventTypes, "eventTypes"); 2203 SubscribeToPushNotificationsRequest request = new SubscribeToPushNotificationsRequest(this); 2204 2205 if (folderIds != null) { 2206 request.getFolderIds().addRangeFolderId(folderIds); 2207 } 2208 2209 request.setUrl(url); 2210 request.setFrequency(frequency); 2211 2212 for (EventType event : eventTypes) { 2213 request.getEventTypes().add(event); 2214 } 2215 2216 request.setWatermark(watermark); 2217 2218 return request; 2219 } 2220 2221 /** 2222 * Subscribes to streaming notification. Calling this method results in a 2223 * call to EWS. 2224 * 2225 * @param folderIds The Ids of the folder to subscribe to. 2226 * @param eventTypes The event types to subscribe to. 2227 * @return A StreamingSubscription representing the new subscription 2228 * @throws Exception 2229 */ 2230 public StreamingSubscription subscribeToStreamingNotifications( 2231 Iterable<FolderId> folderIds, EventType... eventTypes) 2232 throws Exception { 2233 EwsUtilities.validateMethodVersion(this, 2234 ExchangeVersion.Exchange2010_SP1, 2235 "SubscribeToStreamingNotifications"); 2236 2237 EwsUtilities.validateParamCollection(folderIds.iterator(), "folderIds"); 2238 2239 return this.buildSubscribeToStreamingNotificationsRequest(folderIds, 2240 eventTypes).execute().getResponseAtIndex(0).getSubscription(); 2241 } 2242 2243 /** 2244 * Subscribes to streaming notification on all folder in the authenticated 2245 * user's mailbox. Calling this method results in a call to EWS. 2246 * 2247 * @param eventTypes The event types to subscribe to. 2248 * @return A StreamingSubscription representing the new subscription. 2249 * @throws Exception 2250 */ 2251 public StreamingSubscription subscribeToStreamingNotificationsOnAllFolders( 2252 EventType... eventTypes) throws Exception { 2253 EwsUtilities.validateMethodVersion(this, ExchangeVersion.Exchange2010_SP1, 2254 "SubscribeToStreamingNotificationsOnAllFolders"); 2255 2256 return this.buildSubscribeToStreamingNotificationsRequest(null, 2257 eventTypes).execute().getResponseAtIndex(0).getSubscription(); 2258 } 2259 2260 /** 2261 * Begins an asynchronous request to subscribe to streaming notification. 2262 * Calling this method results in a call to EWS. 2263 * 2264 * @param callback The AsyncCallback delegate 2265 * @param state An object that contains state information for this request. 2266 * @param folderIds The Ids of the folder to subscribe to. 2267 * @param eventTypes The event types to subscribe to. 2268 * @return An IAsyncResult that references the asynchronous request 2269 * @throws Exception 2270 */ 2271 public IAsyncResult beginSubscribeToStreamingNotifications(AsyncCallback callback, Object state, 2272 Iterable<FolderId> folderIds, 2273 EventType... eventTypes) throws Exception { 2274 EwsUtilities.validateMethodVersion(this, 2275 ExchangeVersion.Exchange2010_SP1, 2276 "BeginSubscribeToStreamingNotifications"); 2277 2278 EwsUtilities.validateParamCollection(folderIds.iterator(), "folderIds"); 2279 2280 return this.buildSubscribeToStreamingNotificationsRequest(folderIds, 2281 eventTypes).beginExecute(callback); 2282 } 2283 2284 /** 2285 * Begins an asynchronous request to subscribe to streaming notification on 2286 * all folder in the authenticated user's mailbox. Calling this method 2287 * results in a call to EWS. 2288 * 2289 * @param callback The AsyncCallback delegate 2290 * @param state An object that contains state information for this request. 2291 * @return An IAsyncResult that references the asynchronous request. 2292 * @throws Exception 2293 */ 2294 public IAsyncResult beginSubscribeToStreamingNotificationsOnAllFolders(AsyncCallback callback, Object state, 2295 EventType... eventTypes) throws Exception { 2296 EwsUtilities.validateMethodVersion(this, 2297 ExchangeVersion.Exchange2010_SP1, 2298 "BeginSubscribeToStreamingNotificationsOnAllFolders"); 2299 2300 return this.buildSubscribeToStreamingNotificationsRequest(null, 2301 eventTypes).beginExecute(callback); 2302 } 2303 2304 /** 2305 * Ends an asynchronous request to subscribe to push notification in the 2306 * authenticated user's mailbox. 2307 * 2308 * @param asyncResult An IAsyncResult that references the asynchronous request. 2309 * @return A streamingSubscription representing the new subscription 2310 * @throws Exception 2311 * @throws IndexOutOfBoundsException 2312 */ 2313 public StreamingSubscription endSubscribeToStreamingNotifications(IAsyncResult asyncResult) 2314 throws IndexOutOfBoundsException, Exception { 2315 EwsUtilities.validateMethodVersion( 2316 this, 2317 ExchangeVersion.Exchange2010_SP1, 2318 "EndSubscribeToStreamingNotifications"); 2319 2320 SubscribeToStreamingNotificationsRequest request = 2321 AsyncRequestResult.extractServiceRequest(this, asyncResult); 2322 // SubscribeToStreamingNotificationsRequest request = AsyncRequestResult.extractServiceRequest<SubscribeToStreamingNotificationsRequest>(this, asyncResult); 2323 return request.endExecute(asyncResult).getResponseAtIndex(0).getSubscription(); 2324 } 2325 2326 /** 2327 * Builds request to subscribe to streaming notification in the 2328 * authenticated user's mailbox. 2329 * 2330 * @param folderIds The Ids of the folder to subscribe to. 2331 * @param eventTypes The event types to subscribe to. 2332 * @return A request to subscribe to streaming notification in the 2333 * authenticated user's mailbox 2334 * @throws Exception 2335 */ 2336 private SubscribeToStreamingNotificationsRequest buildSubscribeToStreamingNotificationsRequest( 2337 Iterable<FolderId> folderIds, EventType[] eventTypes) throws Exception { 2338 EwsUtilities.validateParamCollection(eventTypes, "eventTypes"); 2339 2340 SubscribeToStreamingNotificationsRequest request = new SubscribeToStreamingNotificationsRequest( 2341 this); 2342 2343 if (folderIds != null) { 2344 request.getFolderIds().addRangeFolderId(folderIds); 2345 } 2346 2347 for (EventType event : eventTypes) { 2348 request.getEventTypes().add(event); 2349 } 2350 2351 return request; 2352 } 2353 2354 2355 2356 /** 2357 * Synchronizes the item of a specific folder. Calling this method 2358 * results in a call to EWS. 2359 * 2360 * @param syncFolderId The Id of the folder containing the item to synchronize with. 2361 * @param propertySet The set of property to retrieve for synchronized item. 2362 * @param ignoredItemIds The optional list of item Ids that should be ignored. 2363 * @param maxChangesReturned The maximum number of changes that should be returned. 2364 * @param syncScope The sync scope identifying item to include in the 2365 * ChangeCollection. 2366 * @param syncState The optional sync state representing the point in time when to 2367 * start the synchronization. 2368 * @return A ChangeCollection containing a list of changes that occurred in 2369 * the specified folder. 2370 * @throws Exception the exception 2371 */ 2372 public ChangeCollection<ItemChange> syncFolderItems(FolderId syncFolderId, 2373 PropertySet propertySet, Iterable<ItemId> ignoredItemIds, 2374 int maxChangesReturned, SyncFolderItemsScope syncScope, 2375 String syncState) throws Exception { 2376 return this.buildSyncFolderItemsRequest(syncFolderId, propertySet, 2377 ignoredItemIds, maxChangesReturned, syncScope, syncState) 2378 .execute().getResponseAtIndex(0).getChanges(); 2379 } 2380 2381 /** 2382 * Begins an asynchronous request to synchronize the item of a specific 2383 * folder. Calling this method results in a call to EWS. 2384 * 2385 * @param callback The AsyncCallback delegate 2386 * @param state An object that contains state information for this request 2387 * @param syncFolderId The Id of the folder containing the item to synchronize with 2388 * @param propertySet The set of property to retrieve for synchronized item. 2389 * @param ignoredItemIds The optional list of item Ids that should be ignored. 2390 * @param maxChangesReturned The maximum number of changes that should be returned. 2391 * @param syncScope The sync scope identifying item to include in the 2392 * ChangeCollection 2393 * @param syncState The optional sync state representing the point in time when to 2394 * start the synchronization 2395 * @return An IAsyncResult that references the asynchronous request. 2396 * @throws Exception 2397 */ 2398 public IAsyncResult beginSyncFolderItems(AsyncCallback callback, Object state, FolderId syncFolderId, 2399 PropertySet propertySet, 2400 Iterable<ItemId> ignoredItemIds, int maxChangesReturned, 2401 SyncFolderItemsScope syncScope, String syncState) throws Exception { 2402 return this.buildSyncFolderItemsRequest(syncFolderId, propertySet, 2403 ignoredItemIds, maxChangesReturned, syncScope, syncState) 2404 .beginExecute(callback); 2405 } 2406 2407 /** 2408 * Ends an asynchronous request to synchronize the item of a specific 2409 * folder. 2410 * 2411 * @param asyncResult An IAsyncResult that references the asynchronous request. 2412 * @return A ChangeCollection containing a list of changes that occurred in 2413 * the specified folder. 2414 * @throws Exception 2415 */ 2416 public ChangeCollection<ItemChange> endSyncFolderItems(IAsyncResult asyncResult) throws Exception { 2417 SyncFolderItemsRequest request = AsyncRequestResult.extractServiceRequest(this, asyncResult); 2418 2419 return request.endExecute(asyncResult).getResponseAtIndex(0).getChanges(); 2420 } 2421 2422 /** 2423 * Builds a request to synchronize the item of a specific folder. 2424 * 2425 * @param syncFolderId The Id of the folder containing the item to synchronize with 2426 * @param propertySet The set of property to retrieve for synchronized item. 2427 * @param ignoredItemIds The optional list of item Ids that should be ignored 2428 * @param maxChangesReturned The maximum number of changes that should be returned. 2429 * @param syncScope The sync scope identifying item to include in the 2430 * ChangeCollection. 2431 * @param syncState The optional sync state representing the point in time when to 2432 * start the synchronization. 2433 * @return A request to synchronize the item of a specific folder. 2434 * @throws Exception 2435 */ 2436 private SyncFolderItemsRequest buildSyncFolderItemsRequest( 2437 FolderId syncFolderId, PropertySet propertySet, 2438 Iterable<ItemId> ignoredItemIds, int maxChangesReturned, 2439 SyncFolderItemsScope syncScope, String syncState) throws Exception { 2440 EwsUtilities.validateParam(syncFolderId, "syncFolderId"); 2441 EwsUtilities.validateParam(propertySet, "propertySet"); 2442 2443 SyncFolderItemsRequest request = new SyncFolderItemsRequest(this); 2444 2445 request.setSyncFolderId(syncFolderId); 2446 request.setPropertySet(propertySet); 2447 if (ignoredItemIds != null) { 2448 request.getIgnoredItemIds().addRange(ignoredItemIds); 2449 } 2450 request.setMaxChangesReturned(maxChangesReturned); 2451 request.setSyncScope(syncScope); 2452 request.setSyncState(syncState); 2453 2454 return request; 2455 } 2456 2457 /** 2458 * Synchronizes the sub-folder of a specific folder. Calling this method 2459 * results in a call to EWS. 2460 * 2461 * @param syncFolderId the sync folder id 2462 * @param propertySet the property set 2463 * @param syncState the sync state 2464 * @return A ChangeCollection containing a list of changes that occurred in 2465 * the specified folder. 2466 * @throws Exception the exception 2467 */ 2468 public ChangeCollection<FolderChange> syncFolderHierarchy( 2469 FolderId syncFolderId, PropertySet propertySet, String syncState) 2470 throws Exception { 2471 return this.buildSyncFolderHierarchyRequest(syncFolderId, propertySet, 2472 syncState).execute().getResponseAtIndex(0).getChanges(); 2473 } 2474 2475 /** 2476 * Begins an asynchronous request to synchronize the sub-folder of a 2477 * specific folder. Calling this method results in a call to EWS. 2478 * 2479 * @param callback The AsyncCallback delegate 2480 * @param state An object that contains state information for this request. 2481 * @param syncFolderId The Id of the folder containing the item to synchronize with. 2482 * A null value indicates the root folder of the mailbox. 2483 * @param propertySet The set of property to retrieve for synchronized item. 2484 * @param syncState The optional sync state representing the point in time when to 2485 * start the synchronization. 2486 * @return An IAsyncResult that references the asynchronous request 2487 * @throws Exception 2488 */ 2489 public IAsyncResult beginSyncFolderHierarchy(AsyncCallback callback, Object state, FolderId syncFolderId, 2490 PropertySet propertySet, 2491 String syncState) throws Exception { 2492 return this.buildSyncFolderHierarchyRequest(syncFolderId, propertySet, 2493 syncState).beginExecute(callback); 2494 } 2495 2496 /** 2497 * Synchronizes the entire folder hierarchy of the mailbox this Service is 2498 * connected to. Calling this method results in a call to EWS. 2499 * 2500 * @param propertySet The set of property to retrieve for synchronized item. 2501 * @param syncState The optional sync state representing the point in time when to 2502 * start the synchronization. 2503 * @return A ChangeCollection containing a list of changes that occurred in 2504 * the specified folder. 2505 * @throws Exception 2506 */ 2507 public ChangeCollection<FolderChange> syncFolderHierarchy( 2508 PropertySet propertySet, String syncState) 2509 throws Exception { 2510 return this.syncFolderHierarchy(null, propertySet, syncState); 2511 } 2512 2513 /* 2514 * Begins an asynchronous request to synchronize the entire folder hierarchy 2515 * of the mailbox this Service is connected to. Calling this method results 2516 * in a call to EWS 2517 * 2518 * @param callback 2519 * The AsyncCallback delegate 2520 * @param state 2521 * An object that contains state information for this request. 2522 * @param propertySet 2523 * The set of property to retrieve for synchronized item. 2524 * @param syncState 2525 * The optional sync state representing the point in time when to 2526 * start the synchronization. 2527 * @return An IAsyncResult that references the asynchronous request 2528 * @throws Exception 2529 public IAsyncResult beginSyncFolderHierarchy(FolderId syncFolderId, PropertySet propertySet, String syncState) throws Exception { 2530 return this.beginSyncFolderHierarchy(null,null, null, 2531 propertySet, syncState); 2532 }*/ 2533 2534 /** 2535 * Ends an asynchronous request to synchronize the specified folder 2536 * hierarchy of the mailbox this Service is connected to. 2537 * 2538 * @param asyncResult An IAsyncResult that references the asynchronous request. 2539 * @return A ChangeCollection containing a list of changes that occurred in 2540 * the specified folder. 2541 * @throws Exception 2542 */ 2543 public ChangeCollection<FolderChange> endSyncFolderHierarchy(IAsyncResult asyncResult) throws Exception { 2544 SyncFolderHierarchyRequest request = AsyncRequestResult.extractServiceRequest(this, asyncResult); 2545 2546 return request.endExecute(asyncResult).getResponseAtIndex(0).getChanges(); 2547 } 2548 2549 /** 2550 * Builds a request to synchronize the specified folder hierarchy of the 2551 * mailbox this Service is connected to. 2552 * 2553 * @param syncFolderId The Id of the folder containing the item to synchronize with. 2554 * A null value indicates the root folder of the mailbox. 2555 * @param propertySet The set of property to retrieve for synchronized item. 2556 * @param syncState The optional sync state representing the point in time when to 2557 * start the synchronization. 2558 * @return A request to synchronize the specified folder hierarchy of the 2559 * mailbox this Service is connected to 2560 * @throws Exception 2561 */ 2562 private SyncFolderHierarchyRequest buildSyncFolderHierarchyRequest( 2563 FolderId syncFolderId, PropertySet propertySet, String syncState) 2564 throws Exception { 2565 EwsUtilities.validateParamAllowNull(syncFolderId, "syncFolderId"); // Null 2566 // syncFolderId 2567 // is 2568 // allowed 2569 EwsUtilities.validateParam(propertySet, "propertySet"); 2570 2571 SyncFolderHierarchyRequest request = new SyncFolderHierarchyRequest(this); 2572 2573 request.setPropertySet(propertySet); 2574 request.setSyncFolderId(syncFolderId); 2575 request.setSyncState(syncState); 2576 2577 return request; 2578 } 2579 2580 // Availability operations 2581 2582 /** 2583 * Gets Out of Office (OOF) settings for a specific user. Calling this 2584 * method results in a call to EWS. 2585 * 2586 * @param smtpAddress the smtp address 2587 * @return An OofSettings instance containing OOF information for the 2588 * specified user. 2589 * @throws Exception the exception 2590 */ 2591 public OofSettings getUserOofSettings(String smtpAddress) throws Exception { 2592 EwsUtilities.validateParam(smtpAddress, "smtpAddress"); 2593 GetUserOofSettingsRequest request = new GetUserOofSettingsRequest(this); 2594 request.setSmtpAddress(smtpAddress); 2595 2596 return request.execute().getOofSettings(); 2597 } 2598 2599 /** 2600 * Sets Out of Office (OOF) settings for a specific user. Calling this 2601 * method results in a call to EWS. 2602 * 2603 * @param smtpAddress the smtp address 2604 * @param oofSettings the oof settings 2605 * @throws Exception the exception 2606 */ 2607 public void setUserOofSettings(String smtpAddress, OofSettings oofSettings) 2608 throws Exception { 2609 EwsUtilities.validateParam(smtpAddress, "smtpAddress"); 2610 EwsUtilities.validateParam(oofSettings, "oofSettings"); 2611 2612 SetUserOofSettingsRequest request = new SetUserOofSettingsRequest(this); 2613 2614 request.setSmtpAddress(smtpAddress); 2615 request.setOofSettings(oofSettings); 2616 2617 request.execute(); 2618 } 2619 2620 /** 2621 * Gets detailed information about the availability of a set of users, 2622 * rooms, and resources within a specified time window. 2623 * 2624 * @param attendees the attendees 2625 * @param timeWindow the time window 2626 * @param requestedData the requested data 2627 * @param options the options 2628 * @return The availability information for each user appears in a unique 2629 * FreeBusyResponse object. The order of users in the request 2630 * determines the order of availability data for each user in the 2631 * response. 2632 * @throws Exception the exception 2633 */ 2634 public GetUserAvailabilityResults getUserAvailability( 2635 Iterable<AttendeeInfo> attendees, TimeWindow timeWindow, 2636 AvailabilityData requestedData, AvailabilityOptions options) 2637 throws Exception { 2638 EwsUtilities.validateParamCollection(attendees.iterator(), "attendees"); 2639 EwsUtilities.validateParam(timeWindow, "timeWindow"); 2640 EwsUtilities.validateParam(options, "options"); 2641 2642 GetUserAvailabilityRequest request = new GetUserAvailabilityRequest(this); 2643 2644 request.setAttendees(attendees); 2645 request.setTimeWindow(timeWindow); 2646 request.setRequestedData(requestedData); 2647 request.setOptions(options); 2648 2649 return request.execute(); 2650 } 2651 2652 /** 2653 * Gets detailed information about the availability of a set of users, 2654 * rooms, and resources within a specified time window. 2655 * 2656 * @param attendees the attendees 2657 * @param timeWindow the time window 2658 * @param requestedData the requested data 2659 * @return The availability information for each user appears in a unique 2660 * FreeBusyResponse object. The order of users in the request 2661 * determines the order of availability data for each user in the 2662 * response. 2663 * @throws Exception the exception 2664 */ 2665 public GetUserAvailabilityResults getUserAvailability( 2666 Iterable<AttendeeInfo> attendees, TimeWindow timeWindow, 2667 AvailabilityData requestedData) throws Exception { 2668 return this.getUserAvailability(attendees, timeWindow, requestedData, 2669 new AvailabilityOptions()); 2670 } 2671 2672 /** 2673 * Retrieves a collection of all room lists in the organization. 2674 * 2675 * @return An EmailAddressCollection containing all the room lists in the 2676 * organization 2677 * @throws Exception the exception 2678 */ 2679 public EmailAddressCollection getRoomLists() throws Exception { 2680 GetRoomListsRequest request = new GetRoomListsRequest(this); 2681 return request.execute().getRoomLists(); 2682 } 2683 2684 /** 2685 * Retrieves a collection of all room lists in the specified room list in 2686 * the organization. 2687 * 2688 * @param emailAddress the email address 2689 * @return A collection of EmailAddress objects representing all the rooms 2690 * within the specifed room list. 2691 * @throws Exception the exception 2692 */ 2693 public Collection<EmailAddress> getRooms(EmailAddress emailAddress) 2694 throws Exception { 2695 EwsUtilities.validateParam(emailAddress, "emailAddress"); 2696 GetRoomsRequest request = new GetRoomsRequest(this); 2697 request.setRoomList(emailAddress); 2698 2699 return request.execute().getRooms(); 2700 } 2701 2702 // region Conversation 2703 2704 /** 2705 * Retrieves a collection of all Conversations in the specified Folder. 2706 * 2707 * @param view The view controlling the number of conversations returned. 2708 * @param filter The search filter. Only search filter class supported 2709 * SearchFilter.IsEqualTo 2710 * @param folderId The Id of the folder in which to search for conversations. 2711 * @throws Exception 2712 */ 2713 private Collection<Conversation> findConversation( 2714 ConversationIndexedItemView view, SearchFilter.IsEqualTo filter, 2715 FolderId folderId) throws Exception { 2716 EwsUtilities.validateParam(view, "view"); 2717 EwsUtilities.validateParamAllowNull(filter, "filter"); 2718 EwsUtilities.validateParam(folderId, "folderId"); 2719 EwsUtilities.validateMethodVersion(this, 2720 ExchangeVersion.Exchange2010_SP1, "FindConversation"); 2721 2722 FindConversationRequest request = new FindConversationRequest(this); 2723 request.setIndexedItemView(view); 2724 request.setConversationViewFilter(filter); 2725 request.setFolderId(new FolderIdWrapper(folderId)); 2726 2727 return request.execute().getConversations(); 2728 } 2729 2730 /** 2731 * Retrieves a collection of all Conversations in the specified Folder. 2732 * 2733 * @param view The view controlling the number of conversations returned. 2734 * @param folderId The Id of the folder in which to search for conversations. 2735 * @throws Exception 2736 */ 2737 public Collection<Conversation> findConversation( 2738 ConversationIndexedItemView view, FolderId folderId) 2739 throws Exception { 2740 return this.findConversation(view, null, folderId); 2741 } 2742 2743 /** 2744 * Applies ConversationAction on the specified conversation. 2745 * 2746 * @param actionType ConversationAction 2747 * @param conversationIds The conversation ids. 2748 * @param processRightAway True to process at once . This is blocking and false to let 2749 * the Assitant process it in the back ground 2750 * @param categories Catgories that need to be stamped can be null or empty 2751 * @param enableAlwaysDelete True moves every current and future messages in the 2752 * conversation to deleted item folder. False stops the alwasy 2753 * delete action. This is applicable only if the action is 2754 * AlwaysDelete 2755 * @param destinationFolderId Applicable if the action is AlwaysMove. This moves every 2756 * current message and future message in the conversation to the 2757 * specified folder. Can be null if tis is then it stops the 2758 * always move action 2759 * @param errorHandlingMode The error handling mode. 2760 * @throws Exception 2761 */ 2762 private ServiceResponseCollection<ServiceResponse> applyConversationAction( 2763 ConversationActionType actionType, 2764 Iterable<ConversationId> conversationIds, boolean processRightAway, 2765 StringList categories, boolean enableAlwaysDelete, 2766 FolderId destinationFolderId, ServiceErrorHandling errorHandlingMode) 2767 throws Exception { 2768 EwsUtilities.ewsAssert(actionType == ConversationActionType.AlwaysCategorize 2769 || actionType == ConversationActionType.AlwaysMove 2770 || actionType == ConversationActionType.AlwaysDelete, "ApplyConversationAction", 2771 "Invalic actionType"); 2772 2773 EwsUtilities.validateParam(conversationIds, "conversationId"); 2774 EwsUtilities.validateMethodVersion(this, 2775 ExchangeVersion.Exchange2010_SP1, "ApplyConversationAction"); 2776 2777 ApplyConversationActionRequest request = new ApplyConversationActionRequest( 2778 this, errorHandlingMode); 2779 ConversationAction action = new ConversationAction(); 2780 2781 for (ConversationId conversationId : conversationIds) { 2782 action.setAction(actionType); 2783 action.setConversationId(conversationId); 2784 action.setProcessRightAway(processRightAway); 2785 action.setCategories(categories); 2786 action.setEnableAlwaysDelete(enableAlwaysDelete); 2787 action 2788 .setDestinationFolderId(destinationFolderId != null ? new FolderIdWrapper( 2789 destinationFolderId) 2790 : null); 2791 request.getConversationActions().add(action); 2792 } 2793 2794 return request.execute(); 2795 } 2796 2797 /** 2798 * Applies one time conversation action on item in specified folder inside 2799 * the conversation. 2800 * 2801 * @param actionType The action 2802 * @param idTimePairs The id time pairs. 2803 * @param contextFolderId The context folder id. 2804 * @param destinationFolderId The destination folder id. 2805 * @param deleteType Type of the delete. 2806 * @param isRead The is read. 2807 * @param errorHandlingMode The error handling mode. 2808 * @throws Exception 2809 */ 2810 private ServiceResponseCollection<ServiceResponse> applyConversationOneTimeAction( 2811 ConversationActionType actionType, 2812 Iterable<HashMap<ConversationId, Date>> idTimePairs, 2813 FolderId contextFolderId, FolderId destinationFolderId, 2814 DeleteMode deleteType, Boolean isRead, 2815 ServiceErrorHandling errorHandlingMode) throws Exception { 2816 EwsUtilities.ewsAssert( 2817 actionType == ConversationActionType.Move || actionType == ConversationActionType.Delete 2818 || actionType == ConversationActionType.SetReadState || actionType == ConversationActionType.Copy, 2819 "ApplyConversationOneTimeAction", "Invalid actionType"); 2820 2821 EwsUtilities.validateParamCollection(idTimePairs.iterator(), 2822 "idTimePairs"); 2823 EwsUtilities.validateMethodVersion(this, 2824 ExchangeVersion.Exchange2010_SP1, "ApplyConversationAction"); 2825 2826 ApplyConversationActionRequest request = new ApplyConversationActionRequest( 2827 this, errorHandlingMode); 2828 2829 for (HashMap<ConversationId, Date> idTimePair : idTimePairs) { 2830 ConversationAction action = new ConversationAction(); 2831 2832 action.setAction(actionType); 2833 action.setConversationId(idTimePair.keySet().iterator().next()); 2834 action 2835 .setContextFolderId(contextFolderId != null ? new FolderIdWrapper( 2836 contextFolderId) 2837 : null); 2838 action 2839 .setDestinationFolderId(destinationFolderId != null ? new FolderIdWrapper( 2840 destinationFolderId) 2841 : null); 2842 action.setConversationLastSyncTime(idTimePair.values().iterator() 2843 .next()); 2844 action.setIsRead(isRead); 2845 action.setDeleteType(deleteType); 2846 2847 request.getConversationActions().add(action); 2848 } 2849 2850 return request.execute(); 2851 } 2852 2853 /** 2854 * Sets up a conversation so that any item received within that conversation 2855 * is always categorized. Calling this method results in a call to EWS. 2856 * 2857 * @param conversationId The id of the conversation. 2858 * @param categories The categories that should be stamped on item in the 2859 * conversation. 2860 * @param processSynchronously Indicates whether the method should return only once enabling 2861 * this rule and stamping existing item in the conversation is 2862 * completely done. If processSynchronously is false, the method 2863 * returns immediately. 2864 * @throws Exception 2865 */ 2866 public ServiceResponseCollection<ServiceResponse> enableAlwaysCategorizeItemsInConversations( 2867 Iterable<ConversationId> conversationId, 2868 Iterable<String> categories, boolean processSynchronously) 2869 throws Exception { 2870 EwsUtilities.validateParamCollection(categories.iterator(), 2871 "categories"); 2872 return this.applyConversationAction( 2873 ConversationActionType.AlwaysCategorize, conversationId, 2874 processSynchronously, new StringList(categories), false, null, 2875 ServiceErrorHandling.ReturnErrors); 2876 } 2877 2878 /** 2879 * Sets up a conversation so that any item received within that conversation 2880 * is no longer categorized. Calling this method results in a call to EWS. 2881 * 2882 * @param conversationId The id of the conversation. 2883 * @param processSynchronously Indicates whether the method should return only once enabling 2884 * this rule and stamping existing item in the conversation is 2885 * completely done. If processSynchronously is false, the method 2886 * returns immediately. 2887 * @throws Exception 2888 */ 2889 public ServiceResponseCollection<ServiceResponse> disableAlwaysCategorizeItemsInConversations( 2890 Iterable<ConversationId> conversationId, 2891 boolean processSynchronously) throws Exception { 2892 return this.applyConversationAction( 2893 ConversationActionType.AlwaysCategorize, conversationId, 2894 processSynchronously, null, false, null, 2895 ServiceErrorHandling.ReturnErrors); 2896 } 2897 2898 /** 2899 * Sets up a conversation so that any item received within that conversation 2900 * is always moved to Deleted Items folder. Calling this method results in a 2901 * call to EWS. 2902 * 2903 * @param conversationId The id of the conversation. 2904 * @param processSynchronously Indicates whether the method should return only once enabling 2905 * this rule and stamping existing item in the conversation is 2906 * completely done. If processSynchronously is false, the method 2907 * returns immediately. 2908 * @throws Exception 2909 */ 2910 public ServiceResponseCollection<ServiceResponse> enableAlwaysDeleteItemsInConversations( 2911 Iterable<ConversationId> conversationId, 2912 boolean processSynchronously) throws Exception { 2913 return this.applyConversationAction( 2914 ConversationActionType.AlwaysDelete, conversationId, 2915 processSynchronously, null, true, null, 2916 ServiceErrorHandling.ReturnErrors); 2917 } 2918 2919 /** 2920 * Sets up a conversation so that any item received within that conversation 2921 * is no longer moved to Deleted Items folder. Calling this method results 2922 * in a call to EWS. 2923 * 2924 * @param conversationId The id of the conversation. 2925 * @param processSynchronously Indicates whether the method should return only once enabling 2926 * this rule and stamping existing item in the conversation is 2927 * completely done. If processSynchronously is false, the method 2928 * returns immediately. 2929 * @throws Exception 2930 */ 2931 public ServiceResponseCollection<ServiceResponse> disableAlwaysDeleteItemsInConversations( 2932 Iterable<ConversationId> conversationId, 2933 boolean processSynchronously) throws Exception { 2934 return this.applyConversationAction( 2935 ConversationActionType.AlwaysDelete, conversationId, 2936 processSynchronously, null, false, null, 2937 ServiceErrorHandling.ReturnErrors); 2938 } 2939 2940 /** 2941 * Sets up a conversation so that any item received within that conversation 2942 * is always moved to a specific folder. Calling this method results in a 2943 * call to EWS. 2944 * 2945 * @param conversationId The Id of the folder to which conversation item should be 2946 * moved. 2947 * @param destinationFolderId The Id of the destination folder. 2948 * @param processSynchronously Indicates whether the method should return only once enabling 2949 * this rule and stamping existing item in the conversation is 2950 * completely done. If processSynchronously is false, the method 2951 * returns immediately. 2952 * @throws Exception 2953 */ 2954 public ServiceResponseCollection<ServiceResponse> enableAlwaysMoveItemsInConversations( 2955 Iterable<ConversationId> conversationId, 2956 FolderId destinationFolderId, boolean processSynchronously) 2957 throws Exception { 2958 EwsUtilities.validateParam(destinationFolderId, "destinationFolderId"); 2959 return this.applyConversationAction(ConversationActionType.AlwaysMove, 2960 conversationId, processSynchronously, null, false, 2961 destinationFolderId, ServiceErrorHandling.ReturnErrors); 2962 } 2963 2964 /** 2965 * Sets up a conversation so that any item received within that conversation 2966 * is no longer moved to a specific folder. Calling this method results in a 2967 * call to EWS. 2968 * 2969 * @param conversationIds The conversation ids. 2970 * @param processSynchronously Indicates whether the method should return only once disabling 2971 * this rule is completely done. If processSynchronously is 2972 * false, the method returns immediately. 2973 * @throws Exception 2974 */ 2975 public ServiceResponseCollection<ServiceResponse> disableAlwaysMoveItemsInConversations( 2976 Iterable<ConversationId> conversationIds, 2977 boolean processSynchronously) throws Exception { 2978 return this.applyConversationAction(ConversationActionType.AlwaysMove, 2979 conversationIds, processSynchronously, null, false, null, 2980 ServiceErrorHandling.ReturnErrors); 2981 } 2982 2983 /** 2984 * Moves the item in the specified conversation to the specified 2985 * destination folder. Calling this method results in a call to EWS. 2986 * 2987 * @param idLastSyncTimePairs The pairs of Id of conversation whose item should be moved 2988 * and the dateTime conversation was last synced (Items received 2989 * after that dateTime will not be moved). 2990 * @param contextFolderId The Id of the folder that contains the conversation. 2991 * @param destinationFolderId The Id of the destination folder. 2992 * @throws Exception 2993 */ 2994 public ServiceResponseCollection<ServiceResponse> moveItemsInConversations( 2995 Iterable<HashMap<ConversationId, Date>> idLastSyncTimePairs, 2996 FolderId contextFolderId, FolderId destinationFolderId) 2997 throws Exception { 2998 EwsUtilities.validateParam(destinationFolderId, "destinationFolderId"); 2999 return this.applyConversationOneTimeAction(ConversationActionType.Move, 3000 idLastSyncTimePairs, contextFolderId, destinationFolderId, 3001 null, null, ServiceErrorHandling.ReturnErrors); 3002 } 3003 3004 /** 3005 * Copies the item in the specified conversation to the specified 3006 * destination folder. Calling this method results in a call to EWS. 3007 * 3008 * @param idLastSyncTimePairs The pairs of Id of conversation whose item should be copied 3009 * and the dateTime conversation was last synced (Items received 3010 * after that dateTime will not be copied). 3011 * @param contextFolderId The context folder id. 3012 * @param destinationFolderId The destination folder id. 3013 * @throws Exception 3014 */ 3015 public ServiceResponseCollection<ServiceResponse> copyItemsInConversations( 3016 Iterable<HashMap<ConversationId, Date>> idLastSyncTimePairs, 3017 FolderId contextFolderId, FolderId destinationFolderId) 3018 throws Exception { 3019 EwsUtilities.validateParam(destinationFolderId, "destinationFolderId"); 3020 return this.applyConversationOneTimeAction(ConversationActionType.Copy, 3021 idLastSyncTimePairs, contextFolderId, destinationFolderId, 3022 null, null, ServiceErrorHandling.ReturnErrors); 3023 } 3024 3025 /** 3026 * Deletes the item in the specified conversation. Calling this method 3027 * results in a call to EWS. 3028 * 3029 * @param idLastSyncTimePairs The pairs of Id of conversation whose item should be deleted 3030 * and the date and time conversation was last synced (Items 3031 * received after that date will not be deleted). conversation 3032 * was last synced (Items received after that dateTime will not 3033 * be copied). 3034 * @param contextFolderId The Id of the folder that contains the conversation. 3035 * @param deleteMode The deletion mode 3036 * @throws Exception 3037 */ 3038 public ServiceResponseCollection<ServiceResponse> deleteItemsInConversations( 3039 Iterable<HashMap<ConversationId, Date>> idLastSyncTimePairs, 3040 FolderId contextFolderId, DeleteMode deleteMode) throws Exception { 3041 return this.applyConversationOneTimeAction( 3042 ConversationActionType.Delete, idLastSyncTimePairs, 3043 contextFolderId, null, deleteMode, null, 3044 ServiceErrorHandling.ReturnErrors); 3045 } 3046 3047 /** 3048 * Sets the read state for item in conversation. Calling this mehtod would 3049 * result in call to EWS. 3050 * 3051 * @param idLastSyncTimePairs The pairs of Id of conversation whose item should read state 3052 * set and the date and time conversation was last synced (Items 3053 * received after that date will not have their read state set). 3054 * was last synced (Items received after that date will not be 3055 * deleted). conversation was last synced (Items received after 3056 * that dateTime will not be copied). 3057 * @param contextFolderId The Id of the folder that contains the conversation. 3058 * @param isRead if set to <c>true</c>, conversation item are marked as read; 3059 * otherwise they are marked as unread. 3060 * @throws Exception 3061 */ 3062 public ServiceResponseCollection<ServiceResponse> setReadStateForItemsInConversations( 3063 Iterable<HashMap<ConversationId, Date>> idLastSyncTimePairs, 3064 FolderId contextFolderId, boolean isRead) throws Exception { 3065 return this.applyConversationOneTimeAction( 3066 ConversationActionType.SetReadState, idLastSyncTimePairs, 3067 contextFolderId, null, null, isRead, 3068 ServiceErrorHandling.ReturnErrors); 3069 } 3070 3071 // Id conversion operations 3072 3073 /** 3074 * Converts multiple Ids from one format to another in a single call to 3075 * EWS. 3076 * 3077 * @param ids the ids 3078 * @param destinationFormat the destination format 3079 * @param errorHandling the error handling 3080 * @return A ServiceResponseCollection providing conversion results for each 3081 * specified Ids. 3082 * @throws Exception the exception 3083 */ 3084 private ServiceResponseCollection<ConvertIdResponse> internalConvertIds( 3085 Iterable<AlternateIdBase> ids, IdFormat destinationFormat, 3086 ServiceErrorHandling errorHandling) throws Exception { 3087 EwsUtilities.validateParamCollection(ids.iterator(), "ids"); 3088 3089 ConvertIdRequest request = new ConvertIdRequest(this, errorHandling); 3090 3091 request.getIds().addAll((Collection<? extends AlternateIdBase>) ids); 3092 request.setDestinationFormat(destinationFormat); 3093 3094 return request.execute(); 3095 } 3096 3097 /** 3098 * Converts multiple Ids from one format to another in a single call to 3099 * EWS. 3100 * 3101 * @param ids the ids 3102 * @param destinationFormat the destination format 3103 * @return A ServiceResponseCollection providing conversion results for each 3104 * specified Ids. 3105 * @throws Exception the exception 3106 */ 3107 public ServiceResponseCollection<ConvertIdResponse> convertIds( 3108 Iterable<AlternateIdBase> ids, IdFormat destinationFormat) 3109 throws Exception { 3110 EwsUtilities.validateParamCollection(ids.iterator(), "ids"); 3111 3112 return this.internalConvertIds(ids, destinationFormat, 3113 ServiceErrorHandling.ReturnErrors); 3114 } 3115 3116 /** 3117 * Converts Id from one format to another in a single call to EWS. 3118 * 3119 * @param id the id 3120 * @param destinationFormat the destination format 3121 * @return The converted Id. 3122 * @throws Exception the exception 3123 */ 3124 public AlternateIdBase convertId(AlternateIdBase id, 3125 IdFormat destinationFormat) throws Exception { 3126 EwsUtilities.validateParam(id, "id"); 3127 3128 List<AlternateIdBase> alternateIdBaseArray = new ArrayList<AlternateIdBase>(); 3129 alternateIdBaseArray.add(id); 3130 3131 ServiceResponseCollection<ConvertIdResponse> responses = this 3132 .internalConvertIds(alternateIdBaseArray, destinationFormat, 3133 ServiceErrorHandling.ThrowOnError); 3134 3135 return responses.getResponseAtIndex(0).getConvertedId(); 3136 } 3137 3138 /** 3139 * Adds delegates to a specific mailbox. Calling this method results in a 3140 * call to EWS. 3141 * 3142 * @param mailbox the mailbox 3143 * @param meetingRequestsDeliveryScope the meeting request delivery scope 3144 * @param delegateUsers the delegate users 3145 * @return A collection of DelegateUserResponse objects providing the 3146 * results of the operation. 3147 * @throws Exception the exception 3148 */ 3149 public Collection<DelegateUserResponse> addDelegates(Mailbox mailbox, 3150 MeetingRequestsDeliveryScope meetingRequestsDeliveryScope, 3151 DelegateUser... delegateUsers) throws Exception { 3152 return addDelegates(mailbox, meetingRequestsDeliveryScope, 3153 Arrays.asList(delegateUsers)); 3154 } 3155 3156 /** 3157 * Adds delegates to a specific mailbox. Calling this method results in a 3158 * call to EWS. 3159 * 3160 * @param mailbox the mailbox 3161 * @param meetingRequestsDeliveryScope the meeting request delivery scope 3162 * @param delegateUsers the delegate users 3163 * @return A collection of DelegateUserResponse objects providing the 3164 * results of the operation. 3165 * @throws Exception the exception 3166 */ 3167 public Collection<DelegateUserResponse> addDelegates(Mailbox mailbox, 3168 MeetingRequestsDeliveryScope meetingRequestsDeliveryScope, 3169 Iterable<DelegateUser> delegateUsers) throws Exception { 3170 EwsUtilities.validateParam(mailbox, "mailbox"); 3171 EwsUtilities.validateParamCollection(delegateUsers.iterator(), 3172 "delegateUsers"); 3173 3174 AddDelegateRequest request = new AddDelegateRequest(this); 3175 request.setMailbox(mailbox); 3176 3177 for (DelegateUser user : delegateUsers) { 3178 request.getDelegateUsers().add(user); 3179 } 3180 3181 request.setMeetingRequestsDeliveryScope(meetingRequestsDeliveryScope); 3182 3183 DelegateManagementResponse response = request.execute(); 3184 return response.getDelegateUserResponses(); 3185 } 3186 3187 /** 3188 * Updates delegates on a specific mailbox. Calling this method results in 3189 * a call to EWS. 3190 * 3191 * @param mailbox the mailbox 3192 * @param meetingRequestsDeliveryScope the meeting request delivery scope 3193 * @param delegateUsers the delegate users 3194 * @return A collection of DelegateUserResponse objects providing the 3195 * results of the operation. 3196 * @throws Exception the exception 3197 */ 3198 public Collection<DelegateUserResponse> updateDelegates(Mailbox mailbox, 3199 MeetingRequestsDeliveryScope meetingRequestsDeliveryScope, 3200 DelegateUser... delegateUsers) throws Exception { 3201 return this.updateDelegates(mailbox, meetingRequestsDeliveryScope, 3202 Arrays.asList(delegateUsers)); 3203 } 3204 3205 /** 3206 * Updates delegates on a specific mailbox. Calling this method results in 3207 * a call to EWS. 3208 * 3209 * @param mailbox the mailbox 3210 * @param meetingRequestsDeliveryScope the meeting request delivery scope 3211 * @param delegateUsers the delegate users 3212 * @return A collection of DelegateUserResponse objects providing the 3213 * results of the operation. 3214 * @throws Exception the exception 3215 */ 3216 public Collection<DelegateUserResponse> updateDelegates(Mailbox mailbox, 3217 MeetingRequestsDeliveryScope meetingRequestsDeliveryScope, 3218 Iterable<DelegateUser> delegateUsers) throws Exception { 3219 EwsUtilities.validateParam(mailbox, "mailbox"); 3220 EwsUtilities.validateParamCollection(delegateUsers.iterator(), 3221 "delegateUsers"); 3222 3223 UpdateDelegateRequest request = new UpdateDelegateRequest(this); 3224 3225 request.setMailbox(mailbox); 3226 3227 ArrayList<DelegateUser> delUser = new ArrayList<DelegateUser>(); 3228 for (DelegateUser user : delegateUsers) { 3229 delUser.add(user); 3230 } 3231 request.getDelegateUsers().addAll(delUser); 3232 request.setMeetingRequestsDeliveryScope(meetingRequestsDeliveryScope); 3233 3234 DelegateManagementResponse response = request.execute(); 3235 return response.getDelegateUserResponses(); 3236 } 3237 3238 /** 3239 * Removes delegates on a specific mailbox. Calling this method results in 3240 * a call to EWS. 3241 * 3242 * @param mailbox the mailbox 3243 * @param userIds the user ids 3244 * @return A collection of DelegateUserResponse objects providing the 3245 * results of the operation. 3246 * @throws Exception the exception 3247 */ 3248 public Collection<DelegateUserResponse> removeDelegates(Mailbox mailbox, 3249 UserId... userIds) throws Exception { 3250 return removeDelegates(mailbox, Arrays.asList(userIds)); 3251 } 3252 3253 /** 3254 * Removes delegates on a specific mailbox. Calling this method results in 3255 * a call to EWS. 3256 * 3257 * @param mailbox the mailbox 3258 * @param userIds the user ids 3259 * @return A collection of DelegateUserResponse objects providing the 3260 * results of the operation. 3261 * @throws Exception the exception 3262 */ 3263 public Collection<DelegateUserResponse> removeDelegates(Mailbox mailbox, 3264 Iterable<UserId> userIds) throws Exception { 3265 EwsUtilities.validateParam(mailbox, "mailbox"); 3266 EwsUtilities.validateParamCollection(userIds.iterator(), "userIds"); 3267 3268 RemoveDelegateRequest request = new RemoveDelegateRequest(this); 3269 request.setMailbox(mailbox); 3270 3271 ArrayList<UserId> delUser = new ArrayList<UserId>(); 3272 for (UserId user : userIds) { 3273 delUser.add(user); 3274 } 3275 request.getUserIds().addAll(delUser); 3276 3277 DelegateManagementResponse response = request.execute(); 3278 return response.getDelegateUserResponses(); 3279 } 3280 3281 /** 3282 * Retrieves the delegates of a specific mailbox. Calling this method 3283 * results in a call to EWS. 3284 * 3285 * @param mailbox the mailbox 3286 * @param includePermissions the include permissions 3287 * @param userIds the user ids 3288 * @return A GetDelegateResponse providing the results of the operation. 3289 * @throws Exception the exception 3290 */ 3291 public DelegateInformation getDelegates(Mailbox mailbox, 3292 boolean includePermissions, UserId... userIds) throws Exception { 3293 return this.getDelegates(mailbox, includePermissions, Arrays.asList(userIds)); 3294 } 3295 3296 /** 3297 * Retrieves the delegates of a specific mailbox. Calling this method 3298 * results in a call to EWS. 3299 * 3300 * @param mailbox the mailbox 3301 * @param includePermissions the include permissions 3302 * @param userIds the user ids 3303 * @return A GetDelegateResponse providing the results of the operation. 3304 * @throws Exception the exception 3305 */ 3306 public DelegateInformation getDelegates(Mailbox mailbox, 3307 boolean includePermissions, Iterable<UserId> userIds) 3308 throws Exception { 3309 EwsUtilities.validateParam(mailbox, "mailbox"); 3310 3311 GetDelegateRequest request = new GetDelegateRequest(this); 3312 3313 request.setMailbox(mailbox); 3314 3315 ArrayList<UserId> delUser = new ArrayList<UserId>(); 3316 for (UserId user : userIds) { 3317 delUser.add(user); 3318 } 3319 request.getUserIds().addAll(delUser); 3320 request.setIncludePermissions(includePermissions); 3321 3322 GetDelegateResponse response = request.execute(); 3323 DelegateInformation delegateInformation = new DelegateInformation( 3324 (List<DelegateUserResponse>) response 3325 .getDelegateUserResponses(), response 3326 .getMeetingRequestsDeliveryScope()); 3327 3328 return delegateInformation; 3329 } 3330 3331 /** 3332 * Creates the user configuration. 3333 * 3334 * @param userConfiguration the user configuration 3335 * @throws Exception the exception 3336 */ 3337 public void createUserConfiguration(UserConfiguration userConfiguration) 3338 throws Exception { 3339 EwsUtilities.validateParam(userConfiguration, "userConfiguration"); 3340 3341 CreateUserConfigurationRequest request = new CreateUserConfigurationRequest( 3342 this); 3343 3344 request.setUserConfiguration(userConfiguration); 3345 3346 request.execute(); 3347 } 3348 3349 /** 3350 * Creates a UserConfiguration. 3351 * 3352 * @param name the name 3353 * @param parentFolderId the parent folder id 3354 * @throws Exception the exception 3355 */ 3356 public void deleteUserConfiguration(String name, FolderId parentFolderId) 3357 throws Exception { 3358 EwsUtilities.validateParam(name, "name"); 3359 EwsUtilities.validateParam(parentFolderId, "parentFolderId"); 3360 3361 DeleteUserConfigurationRequest request = new DeleteUserConfigurationRequest( 3362 this); 3363 3364 request.setName(name); 3365 request.setParentFolderId(parentFolderId); 3366 request.execute(); 3367 } 3368 3369 /** 3370 * Creates a UserConfiguration. 3371 * 3372 * @param name the name 3373 * @param parentFolderId the parent folder id 3374 * @param properties the property 3375 * @return the user configuration 3376 * @throws Exception the exception 3377 */ 3378 public UserConfiguration getUserConfiguration(String name, FolderId parentFolderId, 3379 UserConfigurationProperties properties) 3380 throws Exception { 3381 EwsUtilities.validateParam(name, "name"); 3382 EwsUtilities.validateParam(parentFolderId, "parentFolderId"); 3383 3384 GetUserConfigurationRequest request = new GetUserConfigurationRequest(this); 3385 3386 request.setName(name); 3387 request.setParentFolderId(parentFolderId); 3388 request.setProperties(EnumSet.of(properties)); 3389 3390 return request.execute().getResponseAtIndex(0).getUserConfiguration(); 3391 } 3392 3393 /** 3394 * Loads the property of the specified userConfiguration. 3395 * 3396 * @param userConfiguration the user configuration 3397 * @param properties the property 3398 * @throws Exception the exception 3399 */ 3400 public void loadPropertiesForUserConfiguration(UserConfiguration userConfiguration, 3401 UserConfigurationProperties properties) throws Exception { 3402 EwsUtilities.ewsAssert(userConfiguration != null, "ExchangeService.LoadPropertiesForUserConfiguration", 3403 "userConfiguration is null"); 3404 3405 GetUserConfigurationRequest request = new GetUserConfigurationRequest( 3406 this); 3407 3408 request.setUserConfiguration(userConfiguration); 3409 request.setProperties(EnumSet.of(properties)); 3410 3411 request.execute(); 3412 } 3413 3414 /** 3415 * Updates a UserConfiguration. 3416 * 3417 * @param userConfiguration the user configuration 3418 * @throws Exception the exception 3419 */ 3420 public void updateUserConfiguration(UserConfiguration userConfiguration) 3421 throws Exception { 3422 EwsUtilities.validateParam(userConfiguration, "userConfiguration"); 3423 UpdateUserConfigurationRequest request = new UpdateUserConfigurationRequest(this); 3424 3425 request.setUserConfiguration(userConfiguration); 3426 3427 request.execute(); 3428 } 3429 3430 // region InboxRule operations 3431 3432 /** 3433 * Retrieves inbox rules of the authenticated user. 3434 * 3435 * @return A RuleCollection object containing the authenticated users inbox 3436 * rules. 3437 * @throws Exception 3438 */ 3439 public RuleCollection getInboxRules() throws Exception { 3440 GetInboxRulesRequest request = new GetInboxRulesRequest(this); 3441 return request.execute().getRules(); 3442 } 3443 3444 /** 3445 * Retrieves the inbox rules of the specified user. 3446 * 3447 * @param mailboxSmtpAddress The SMTP address of the user whose inbox rules should be 3448 * retrieved 3449 * @return A RuleCollection object containing the inbox rules of the 3450 * specified user. 3451 * @throws Exception 3452 */ 3453 public RuleCollection getInboxRules(String mailboxSmtpAddress) 3454 throws Exception { 3455 EwsUtilities.validateParam(mailboxSmtpAddress, "MailboxSmtpAddress"); 3456 3457 GetInboxRulesRequest request = new GetInboxRulesRequest(this); 3458 request.setmailboxSmtpAddress(mailboxSmtpAddress); 3459 return request.execute().getRules(); 3460 } 3461 3462 /** 3463 * Updates the authenticated user's inbox rules by applying the specified 3464 * operations. 3465 * 3466 * @param operations The operations that should be applied to the user's inbox 3467 * rules. 3468 * @param removeOutlookRuleBlob Indicate whether or not to remove Outlook Rule Blob. 3469 * @throws Exception 3470 */ 3471 public void updateInboxRules(Iterable<RuleOperation> operations, 3472 boolean removeOutlookRuleBlob) throws Exception { 3473 UpdateInboxRulesRequest request = new UpdateInboxRulesRequest(this); 3474 request.setInboxRuleOperations(operations); 3475 request.setRemoveOutlookRuleBlob(removeOutlookRuleBlob); 3476 request.execute(); 3477 } 3478 3479 /** 3480 * Updates the authenticated user's inbox rules by applying the specified 3481 * operations. 3482 * 3483 * @param operations The operations that should be applied to the user's inbox 3484 * rules. 3485 * @param removeOutlookRuleBlob Indicate whether or not to remove Outlook Rule Blob. 3486 * @param mailboxSmtpAddress The SMTP address of the user whose inbox rules should be 3487 * retrieved 3488 * @throws Exception 3489 */ 3490 public void updateInboxRules(Iterable<RuleOperation> operations, 3491 boolean removeOutlookRuleBlob, String mailboxSmtpAddress) 3492 throws Exception { 3493 UpdateInboxRulesRequest request = new UpdateInboxRulesRequest(this); 3494 request.setInboxRuleOperations(operations); 3495 request.setRemoveOutlookRuleBlob(removeOutlookRuleBlob); 3496 request.setMailboxSmtpAddress(mailboxSmtpAddress); 3497 request.execute(); 3498 } 3499 3500 /** 3501 * Default implementation of AutodiscoverRedirectionUrlValidationCallback. 3502 * Always returns true indicating that the URL can be used. 3503 * 3504 * @param redirectionUrl the redirection url 3505 * @return Returns true. 3506 * @throws AutodiscoverLocalException the autodiscover local exception 3507 */ 3508 private boolean defaultAutodiscoverRedirectionUrlValidationCallback( 3509 String redirectionUrl) throws AutodiscoverLocalException { 3510 throw new AutodiscoverLocalException(String.format( 3511 "Autodiscover blocked a potentially insecure redirection to %s. To allow Autodiscover to follow the redirection, use the AutodiscoverUrl(string, AutodiscoverRedirectionUrlValidationCallback) overload.", redirectionUrl)); 3512 } 3513 3514 /** 3515 * Initializes the Url property to the Exchange Web Services URL for the 3516 * specified e-mail address by calling the Autodiscover service. 3517 * 3518 * @param emailAddress the email address 3519 * @throws Exception the exception 3520 */ 3521 public void autodiscoverUrl(String emailAddress) throws Exception { 3522 this.autodiscoverUrl(emailAddress, this); 3523 } 3524 3525 /** 3526 * Initializes the Url property to the Exchange Web Services URL for the 3527 * specified e-mail address by calling the Autodiscover service. 3528 * 3529 * @param emailAddress the email address to use. 3530 * @param validateRedirectionUrlCallback The callback used to validate redirection URL 3531 * @throws Exception the exception 3532 */ 3533 public void autodiscoverUrl(String emailAddress, 3534 IAutodiscoverRedirectionUrl validateRedirectionUrlCallback) 3535 throws Exception { 3536 URI exchangeServiceUrl = null; 3537 3538 if (this.getRequestedServerVersion().ordinal() > ExchangeVersion.Exchange2007_SP1 3539 .ordinal()) { 3540 try { 3541 exchangeServiceUrl = this.getAutodiscoverUrl(emailAddress, this 3542 .getRequestedServerVersion(), 3543 validateRedirectionUrlCallback); 3544 this.setUrl(this 3545 .adjustServiceUriFromCredentials(exchangeServiceUrl)); 3546 return; 3547 } catch (AutodiscoverLocalException ex) { 3548 3549 this.traceMessage(TraceFlags.AutodiscoverResponse, String 3550 .format("Autodiscover service call " 3551 + "failed with error '%s'. " 3552 + "Will try legacy service", ex.getMessage())); 3553 3554 } catch (ServiceRemoteException ex) { 3555 // E14:321785 -- Special case: if 3556 // the caller's account is locked 3557 // we want to return this exception, not continue. 3558 if (ex instanceof AccountIsLockedException) { 3559 throw new AccountIsLockedException(ex.getMessage(), 3560 exchangeServiceUrl, ex); 3561 } 3562 3563 this.traceMessage(TraceFlags.AutodiscoverResponse, String 3564 .format("Autodiscover service call " 3565 + "failed with error '%s'. " 3566 + "Will try legacy service", ex.getMessage())); 3567 } 3568 } 3569 3570 // Try legacy Autodiscover provider 3571 3572 exchangeServiceUrl = this.getAutodiscoverUrl(emailAddress, 3573 ExchangeVersion.Exchange2007_SP1, 3574 validateRedirectionUrlCallback); 3575 3576 this.setUrl(this.adjustServiceUriFromCredentials(exchangeServiceUrl)); 3577 } 3578 3579 /** 3580 * Autodiscover will always return the "plain" EWS endpoint URL but if the 3581 * client is using WindowsLive credential, ExchangeService needs to use the 3582 * WS-Security endpoint. 3583 * 3584 * @param uri the uri 3585 * @return Adjusted URL. 3586 * @throws Exception 3587 */ 3588 private URI adjustServiceUriFromCredentials(URI uri) 3589 throws Exception { 3590 return (this.getCredentials() != null) ? this.getCredentials() 3591 .adjustUrl(uri) : uri; 3592 } 3593 3594 /** 3595 * Gets the autodiscover url. 3596 * 3597 * @param emailAddress the email address 3598 * @param requestedServerVersion the Exchange version 3599 * @param validateRedirectionUrlCallback the validate redirection url callback 3600 * @return the autodiscover url 3601 * @throws Exception the exception 3602 */ 3603 private URI getAutodiscoverUrl(String emailAddress, 3604 ExchangeVersion requestedServerVersion, 3605 IAutodiscoverRedirectionUrl validateRedirectionUrlCallback) 3606 throws Exception { 3607 3608 AutodiscoverService autodiscoverService = new AutodiscoverService(this, requestedServerVersion); 3609 autodiscoverService.setWebProxy(getWebProxy()); 3610 3611 autodiscoverService 3612 .setRedirectionUrlValidationCallback(validateRedirectionUrlCallback); 3613 autodiscoverService.setEnableScpLookup(this.getEnableScpLookup()); 3614 3615 GetUserSettingsResponse response = autodiscoverService.getUserSettings( 3616 emailAddress, UserSettingName.InternalEwsUrl, 3617 UserSettingName.ExternalEwsUrl); 3618 3619 switch (response.getErrorCode()) { 3620 case NoError: 3621 return this.getEwsUrlFromResponse(response, autodiscoverService 3622 .isExternal().TRUE); 3623 3624 case InvalidUser: 3625 throw new ServiceRemoteException(String.format("Invalid user: '%s'", 3626 emailAddress)); 3627 3628 case InvalidRequest: 3629 throw new ServiceRemoteException(String.format("Invalid Autodiscover request: '%s'", response 3630 .getErrorMessage())); 3631 3632 default: 3633 this.traceMessage(TraceFlags.AutodiscoverConfiguration, String 3634 .format("No EWS Url returned for user %s, " 3635 + "error code is %s", emailAddress, response 3636 .getErrorCode())); 3637 3638 throw new ServiceRemoteException(response.getErrorMessage()); 3639 } 3640 } 3641 3642 private URI getEwsUrlFromResponse(GetUserSettingsResponse response, 3643 boolean isExternal) throws URISyntaxException, AutodiscoverLocalException { 3644 String uriString; 3645 3646 // Bug E14:59063 -- Figure out which URL to use: Internal or External. 3647 // Bug E14:67646 -- AutoDiscover may not return an external protocol. 3648 // First try external, then internal. 3649 // Bug E14:82650 -- Either protocol 3650 // may be returned without a configured URL. 3651 OutParam<String> outParam = new OutParam<String>(); 3652 if ((isExternal && response.tryGetSettingValue(String.class, 3653 UserSettingName.ExternalEwsUrl, outParam))) { 3654 uriString = outParam.getParam(); 3655 if (!(uriString == null || uriString.isEmpty())) { 3656 return new URI(uriString); 3657 } 3658 } 3659 if ((response.tryGetSettingValue(String.class, 3660 UserSettingName.InternalEwsUrl, outParam) || response 3661 .tryGetSettingValue(String.class, 3662 UserSettingName.ExternalEwsUrl, outParam))) { 3663 uriString = outParam.getParam(); 3664 if (!(uriString == null || uriString.isEmpty())) { 3665 return new URI(uriString); 3666 } 3667 } 3668 3669 // If Autodiscover doesn't return an 3670 // internal or external EWS URL, throw an exception. 3671 throw new AutodiscoverLocalException( 3672 "The Autodiscover service didn't return an appropriate URL that can be used for the ExchangeService Autodiscover URL."); 3673 } 3674 3675 // region Diagnostic Method -- Only used by test 3676 3677 /** 3678 * Executes the diagnostic method. 3679 * 3680 * @param verb The verb. 3681 * @param parameter The parameter. 3682 * @throws Exception 3683 */ 3684 protected Document executeDiagnosticMethod(String verb, Node parameter) 3685 throws Exception { 3686 ExecuteDiagnosticMethodRequest request = new ExecuteDiagnosticMethodRequest(this); 3687 request.setVerb(verb); 3688 request.setParameter(parameter); 3689 3690 return request.execute().getResponseAtIndex(0).getReturnValue(); 3691 3692 } 3693 3694 // endregion 3695 3696 // region Validation 3697 3698 /** 3699 * Validates this instance. 3700 * 3701 * @throws ServiceLocalException the service local exception 3702 */ 3703 @Override public void validate() throws ServiceLocalException { 3704 super.validate(); 3705 if (this.getUrl() == null) { 3706 throw new ServiceLocalException("The Url property on the ExchangeService object must be set."); 3707 } 3708 } 3709 3710 // region Constructors 3711 3712 /** 3713 * Initializes a new instance of the <see cref="ExchangeService"/> class, 3714 * targeting the specified version of EWS and scoped to the to the system's 3715 * current time zone. 3716 */ 3717 public ExchangeService() { 3718 super(); 3719 } 3720 3721 /** 3722 * Initializes a new instance of the <see cref="ExchangeService"/> class, 3723 * targeting the specified version of EWS and scoped to the system's current 3724 * time zone. 3725 * 3726 * @param requestedServerVersion the requested server version 3727 */ 3728 public ExchangeService(ExchangeVersion requestedServerVersion) { 3729 super(requestedServerVersion); 3730 } 3731 3732 // Utilities 3733 3734 /** 3735 * Prepare http web request. 3736 * 3737 * @return the http web request 3738 * @throws ServiceLocalException the service local exception 3739 * @throws java.net.URISyntaxException the uRI syntax exception 3740 */ 3741 public HttpWebRequest prepareHttpWebRequest() 3742 throws ServiceLocalException, URISyntaxException { 3743 try { 3744 this.url = this.adjustServiceUriFromCredentials(this.getUrl()); 3745 } catch (Exception e) { 3746 LOG.error(e); 3747 } 3748 return this.prepareHttpWebRequestForUrl(url, this 3749 .getAcceptGzipEncoding(), true); 3750 } 3751 3752 /** 3753 * Prepares a http web request from a pooling connection manager, used for subscriptions. 3754 * 3755 * @return A http web request 3756 * @throws ServiceLocalException The service local exception 3757 * @throws java.net.URISyntaxException the uRI syntax exception 3758 */ 3759 public HttpWebRequest prepareHttpPoolingWebRequest() 3760 throws ServiceLocalException, URISyntaxException { 3761 try { 3762 this.url = this.adjustServiceUriFromCredentials(this.getUrl()); 3763 } catch (Exception e) { 3764 LOG.error(e); 3765 } 3766 return this.prepareHttpPoolingWebRequestForUrl(url, this 3767 .getAcceptGzipEncoding(), true); 3768 } 3769 3770 /** 3771 * Processes an HTTP error response. 3772 * 3773 * @param httpWebResponse The HTTP web response. 3774 * @param webException The web exception 3775 * @throws Exception 3776 */ 3777 @Override public void processHttpErrorResponse(HttpWebRequest httpWebResponse, Exception webException) throws Exception { 3778 this.internalProcessHttpErrorResponse(httpWebResponse, webException, 3779 TraceFlags.EwsResponseHttpHeaders, TraceFlags.EwsResponse); 3780 } 3781 3782 // Properties 3783 3784 /** 3785 * Gets the URL of the Exchange Web Services. 3786 * 3787 * @return URL of the Exchange Web Services. 3788 */ 3789 public URI getUrl() { 3790 return url; 3791 } 3792 3793 /** 3794 * Sets the URL of the Exchange Web Services. 3795 * 3796 * @param url URL of the Exchange Web Services. 3797 */ 3798 public void setUrl(URI url) { 3799 this.url = url; 3800 } 3801 3802 /** 3803 * Gets the impersonated user id. 3804 * 3805 * @return the impersonated user id 3806 */ 3807 public ImpersonatedUserId getImpersonatedUserId() { 3808 return impersonatedUserId; 3809 } 3810 3811 /** 3812 * Sets the impersonated user id. 3813 * 3814 * @param impersonatedUserId the new impersonated user id 3815 */ 3816 public void setImpersonatedUserId(ImpersonatedUserId impersonatedUserId) { 3817 this.impersonatedUserId = impersonatedUserId; 3818 } 3819 3820 /** 3821 * Gets the preferred culture. 3822 * 3823 * @return the preferred culture 3824 */ 3825 public Locale getPreferredCulture() { 3826 return preferredCulture; 3827 } 3828 3829 /** 3830 * Sets the preferred culture. 3831 * 3832 * @param preferredCulture the new preferred culture 3833 */ 3834 public void setPreferredCulture(Locale preferredCulture) { 3835 this.preferredCulture = preferredCulture; 3836 } 3837 3838 /** 3839 * Gets the DateTime precision for DateTime values returned from Exchange 3840 * Web Services. 3841 * 3842 * @return the DateTimePrecision 3843 */ 3844 public DateTimePrecision getDateTimePrecision() { 3845 return this.dateTimePrecision; 3846 } 3847 3848 /** 3849 * Sets the DateTime precision for DateTime values Web Services. 3850 * @param d date time precision 3851 */ 3852 public void setDateTimePrecision(DateTimePrecision d) { 3853 this.dateTimePrecision = d; 3854 } 3855 3856 /** 3857 * Sets the DateTime precision for DateTime values returned from Exchange 3858 * Web Services. 3859 * 3860 * @param dateTimePrecision the new DateTimePrecision 3861 */ 3862 public void setPreferredCulture(DateTimePrecision dateTimePrecision) { 3863 this.dateTimePrecision = dateTimePrecision; 3864 } 3865 3866 /** 3867 * Gets the file attachment content handler. 3868 * 3869 * @return the file attachment content handler 3870 */ 3871 public IFileAttachmentContentHandler getFileAttachmentContentHandler() { 3872 return this.fileAttachmentContentHandler; 3873 } 3874 3875 /** 3876 * Sets the file attachment content handler. 3877 * 3878 * @param fileAttachmentContentHandler the new file attachment content handler 3879 */ 3880 public void setFileAttachmentContentHandler( 3881 IFileAttachmentContentHandler fileAttachmentContentHandler) { 3882 this.fileAttachmentContentHandler = fileAttachmentContentHandler; 3883 } 3884 3885 /** 3886 * Provides access to the Unified Messaging functionalities. 3887 * 3888 * @return the unified messaging 3889 */ 3890 public UnifiedMessaging getUnifiedMessaging() { 3891 if (this.unifiedMessaging == null) { 3892 this.unifiedMessaging = new UnifiedMessaging(this); 3893 } 3894 3895 return this.unifiedMessaging; 3896 } 3897 3898 /** 3899 * Gets or sets a value indicating whether the AutodiscoverUrl method should 3900 * perform SCP (Service Connection Point) record lookup when determining the 3901 * Autodiscover service URL. 3902 * 3903 * @return enable scp lookup flag. 3904 */ 3905 public boolean getEnableScpLookup() { 3906 return this.enableScpLookup; 3907 } 3908 3909 3910 public void setEnableScpLookup(boolean value) { 3911 this.enableScpLookup = value; 3912 } 3913 3914 /** 3915 * Returns true whether Exchange2007 compatibility mode is enabled, false otherwise. 3916 */ 3917 public boolean getExchange2007CompatibilityMode() { 3918 return this.exchange2007CompatibilityMode; 3919 } 3920 3921 /** 3922 * Set the flag indicating if the Exchange2007 compatibility mode is enabled. 3923 * 3924 * <remarks> 3925 * In order to support E12 servers, the <code>exchange2007CompatibilityMode</code> property, 3926 * set to true, can be used to indicate that we should use "Exchange2007" as the server version String 3927 * rather than Exchange2007_SP1. 3928 * </remarks> 3929 * 3930 * @param value true if the Exchange2007 compatibility mode is enabled. 3931 */ 3932 public void setExchange2007CompatibilityMode(boolean value) { 3933 this.exchange2007CompatibilityMode = value; 3934 } 3935 3936 /** 3937 * Retrieves the definitions of the specified server-side time zones. 3938 * 3939 * @param timeZoneIds the time zone ids 3940 * @return A Collection containing the definitions of the specified time 3941 * zones. 3942 * @throws Exception 3943 */ 3944 public Collection<TimeZoneDefinition> getServerTimeZones( 3945 Iterable<String> timeZoneIds) throws Exception { 3946 Map<String, TimeZoneDefinition> timeZoneMap = new HashMap<String, TimeZoneDefinition>(); 3947 3948 GetServerTimeZonesRequest request = new GetServerTimeZonesRequest(this); 3949 ServiceResponseCollection<GetServerTimeZonesResponse> responses = request.execute(); 3950 for (GetServerTimeZonesResponse response : responses) { 3951 for (TimeZoneDefinition tzd : response.getTimeZones()) { 3952 timeZoneMap.put(tzd.getId(), tzd); 3953 } 3954 } 3955 3956 Collection<TimeZoneDefinition> timeZoneList = new ArrayList<TimeZoneDefinition>(); 3957 3958 for (String timeZoneId : timeZoneIds) { 3959 timeZoneList.add(timeZoneMap.get(timeZoneId)); 3960 } 3961 3962 return timeZoneList; 3963 } 3964 3965 /** 3966 * Retrieves the definitions of all server-side time zones. 3967 * 3968 * @return A Collection containing the definitions of the specified time 3969 * zones. 3970 * @throws Exception 3971 */ 3972 public Collection<TimeZoneDefinition> getServerTimeZones() throws Exception { 3973 GetServerTimeZonesRequest request = new GetServerTimeZonesRequest(this); 3974 Collection<TimeZoneDefinition> timeZoneList = new ArrayList<TimeZoneDefinition>(); 3975 ServiceResponseCollection<GetServerTimeZonesResponse> responses = request.execute(); 3976 for (GetServerTimeZonesResponse response : responses) { 3977 timeZoneList.addAll(response.getTimeZones()); 3978 } 3979 3980 return timeZoneList; 3981 } 3982 3983 /* 3984 * (non-Javadoc) 3985 * 3986 * @seemicrosoft.exchange.webservices.AutodiscoverRedirectionUrlInterface# 3987 * autodiscoverRedirectionUrlValidationCallback(java.lang.String) 3988 */ 3989 public boolean autodiscoverRedirectionUrlValidationCallback( 3990 String redirectionUrl) throws AutodiscoverLocalException { 3991 return defaultAutodiscoverRedirectionUrlValidationCallback(redirectionUrl); 3992 3993 } 3994 3995}