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.autodiscover.configuration.outlook;
025
026import microsoft.exchange.webservices.data.autodiscover.configuration.ConfigurationSettingsBase;
027import microsoft.exchange.webservices.data.autodiscover.enumeration.AutodiscoverErrorCode;
028import microsoft.exchange.webservices.data.autodiscover.enumeration.AutodiscoverResponseType;
029import microsoft.exchange.webservices.data.autodiscover.exception.error.UserSettingError;
030import microsoft.exchange.webservices.data.autodiscover.response.GetUserSettingsResponse;
031import microsoft.exchange.webservices.data.core.EwsUtilities;
032import microsoft.exchange.webservices.data.core.EwsXmlReader;
033import microsoft.exchange.webservices.data.core.ILazyMember;
034import microsoft.exchange.webservices.data.core.LazyMember;
035import microsoft.exchange.webservices.data.core.XmlElementNames;
036import microsoft.exchange.webservices.data.autodiscover.enumeration.UserSettingName;
037
038import java.net.URI;
039import java.util.ArrayList;
040import java.util.List;
041
042/**
043 * Represents Outlook configuration settings.
044 */
045public final class OutlookConfigurationSettings extends ConfigurationSettingsBase {
046
047  /**
048   * All user settings that are available from the Outlook provider.
049   */
050  private static LazyMember<List<UserSettingName>>
051      allOutlookProviderSettings = new LazyMember<List<UserSettingName>>(
052      new ILazyMember<List<UserSettingName>>() {
053        public List<UserSettingName> createInstance() {
054
055          List<UserSettingName> results =
056              new ArrayList<UserSettingName>();
057          for (UserSettingName userSettingName : OutlookUser.getAvailableUserSettings()) {
058            results.add(userSettingName);
059          }
060          results.addAll(OutlookProtocol.getAvailableUserSettings());
061          results.add(UserSettingName.AlternateMailboxes);
062          return results;
063        }
064      });
065
066
067  /**
068   * The user.
069   */
070  private OutlookUser user;
071
072  /**
073   * The account.
074   */
075  private OutlookAccount account;
076
077  /**
078   * Initializes a new instance of the OutlookConfigurationSettings class.
079   */
080  public OutlookConfigurationSettings() {
081    this.user = new OutlookUser();
082    this.account = new OutlookAccount();
083  }
084
085  /**
086   * Determines whether user setting is available in the
087   * OutlookConfiguration or not.
088   *
089   * @param setting The setting.
090   * @return True if user setting is available, otherwise, false.
091   */
092  protected static boolean isAvailableUserSetting(UserSettingName setting) {
093    return allOutlookProviderSettings.getMember().contains(setting);
094  }
095
096  /**
097   * Gets the namespace that defines the settings.
098   *
099   * @return The namespace that defines the settings.
100   */
101  @Override public String getNamespace() {
102    return "http://schemas.microsoft.com/exchange/" +
103        "autodiscover/outlook/responseschema/2006a";
104  }
105
106  /**
107   * Makes this instance a redirection response.
108   *
109   * @param redirectUrl The redirect URL.
110   */
111  @Override public void makeRedirectionResponse(URI redirectUrl) {
112    this.account = new OutlookAccount();
113    this.account.setRedirectTarget(redirectUrl.toString());
114    this.account.setResponseType(AutodiscoverResponseType.RedirectUrl);
115  }
116
117  /**
118   * Tries to read the current XML element.
119   *
120   * @param reader the reader
121   * @return true is the current element was read, false otherwise
122   * @throws Exception the exception
123   */
124  @Override
125  public boolean tryReadCurrentXmlElement(EwsXmlReader reader) throws Exception {
126    if (!super.tryReadCurrentXmlElement(reader)) {
127      if (reader.getLocalName().equals(XmlElementNames.User)) {
128        this.user.loadFromXml(reader);
129        return true;
130      } else if (reader.getLocalName().equals(XmlElementNames.Account)) {
131        this.account.loadFromXml(reader);
132        return true;
133      } else {
134        reader.skipCurrentElement();
135        return false;
136      }
137    } else {
138      return true;
139    }
140  }
141
142  /**
143   * Convert OutlookConfigurationSettings to GetUserSettings response.
144   *
145   * @param smtpAddress       SMTP address requested.
146   * @param requestedSettings The requested settings.
147   * @return GetUserSettingsResponse
148   */
149  @Override public GetUserSettingsResponse convertSettings(String smtpAddress,
150      List<UserSettingName> requestedSettings) {
151    GetUserSettingsResponse response = new GetUserSettingsResponse();
152    response.setSmtpAddress(smtpAddress);
153
154    if (this.getError() != null) {
155      response.setErrorCode(AutodiscoverErrorCode.InternalServerError);
156      response.setErrorMessage(this.getError().getMessage());
157    } else {
158      switch (this.getResponseType()) {
159        case Success:
160          response.setErrorCode(AutodiscoverErrorCode.NoError);
161          response.setErrorMessage("");
162          this.user.convertToUserSettings(requestedSettings, response);
163          this.account.convertToUserSettings(requestedSettings, response);
164          this.reportUnsupportedSettings(requestedSettings, response);
165          break;
166        case Error:
167          response.setErrorCode(AutodiscoverErrorCode.InternalServerError);
168          response.setErrorMessage("The Autodiscover service response was invalid.");
169          break;
170        case RedirectAddress:
171          response.setErrorCode(AutodiscoverErrorCode.RedirectAddress);
172          response.setErrorMessage("");
173          response.setRedirectTarget(this.getRedirectTarget());
174          break;
175        case RedirectUrl:
176          response.setErrorCode(AutodiscoverErrorCode.RedirectUrl);
177          response.setErrorMessage("");
178          response.setRedirectTarget(this.getRedirectTarget());
179          break;
180        default:
181          EwsUtilities.ewsAssert(false, "OutlookConfigurationSettings.ConvertSettings",
182                                 "An unexpected error has occured. "
183                                 + "This code path should never be reached.");
184          break;
185      }
186    }
187    return response;
188  }
189
190  /**
191   * Reports any requested user settings that aren't
192   * supported by the Outlook provider.
193   *
194   * @param requestedSettings The requested settings.
195   * @param response          The response.
196   */
197  private void reportUnsupportedSettings(List<UserSettingName> requestedSettings,
198      GetUserSettingsResponse response) {
199    // In English: find settings listed in requestedSettings that are not supported by the Legacy provider.
200
201    //TODO need to check Iterable
202    List<UserSettingName> invalidSettingQuery =
203        new ArrayList<UserSettingName>();
204    for (UserSettingName userSettingName : requestedSettings) {
205      if (!OutlookConfigurationSettings.isAvailableUserSetting(userSettingName)) {
206        invalidSettingQuery.add(userSettingName);
207      }
208    }
209        /* from setting in requestedSettings
210           where !OutlookConfigurationSettings.IsAvailableUserSetting(setting)
211           select setting;*/
212
213    // Add any unsupported settings to the UserSettingsError collection.
214    for (UserSettingName invalidSetting : invalidSettingQuery) {
215      UserSettingError settingError = new UserSettingError();
216      settingError.setErrorCode(AutodiscoverErrorCode.InvalidSetting);
217      settingError.setSettingName(invalidSetting.toString());
218      settingError.setErrorMessage(String.format(
219          "The requested setting, '%s', isn't supported by this Autodiscover endpoint.",
220          invalidSetting.toString()));
221      response.getUserSettingErrors().add(settingError);
222    }
223  }
224
225  /**
226   * Gets the type of the response.
227   *
228   * @return The type of the response.
229   */
230  @Override public AutodiscoverResponseType getResponseType() {
231    if (this.account != null) {
232      return this.account.getResponseType();
233    } else {
234      return AutodiscoverResponseType.Error;
235    }
236  }
237
238  /**
239   * Gets the redirect target.
240   *
241   * @return String
242   * the redirect target.
243   */
244  @Override public String getRedirectTarget() {
245    return this.account.getRedirectTarget();
246  }
247
248}