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    
024    package microsoft.exchange.webservices.data.autodiscover.configuration.outlook;
025    
026    import microsoft.exchange.webservices.data.autodiscover.configuration.ConfigurationSettingsBase;
027    import microsoft.exchange.webservices.data.autodiscover.enumeration.AutodiscoverErrorCode;
028    import microsoft.exchange.webservices.data.autodiscover.enumeration.AutodiscoverResponseType;
029    import microsoft.exchange.webservices.data.autodiscover.exception.error.UserSettingError;
030    import microsoft.exchange.webservices.data.autodiscover.response.GetUserSettingsResponse;
031    import microsoft.exchange.webservices.data.core.EwsUtilities;
032    import microsoft.exchange.webservices.data.core.EwsXmlReader;
033    import microsoft.exchange.webservices.data.core.ILazyMember;
034    import microsoft.exchange.webservices.data.core.LazyMember;
035    import microsoft.exchange.webservices.data.core.XmlElementNames;
036    import microsoft.exchange.webservices.data.autodiscover.enumeration.UserSettingName;
037    
038    import java.net.URI;
039    import java.util.ArrayList;
040    import java.util.List;
041    
042    /**
043     * Represents Outlook configuration settings.
044     */
045    public 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    }