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.property.complex;
025    
026    import microsoft.exchange.webservices.data.core.EwsServiceXmlReader;
027    import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter;
028    import microsoft.exchange.webservices.data.core.XmlAttributeNames;
029    import microsoft.exchange.webservices.data.core.XmlElementNames;
030    import microsoft.exchange.webservices.data.core.enumeration.search.SearchFolderTraversal;
031    import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace;
032    import microsoft.exchange.webservices.data.core.exception.service.local.ServiceValidationException;
033    import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException;
034    import microsoft.exchange.webservices.data.search.filter.SearchFilter;
035    
036    /**
037     * Represents the parameters associated with a search folder.
038     */
039    public final class SearchFolderParameters extends ComplexProperty implements IComplexPropertyChangedDelegate {
040    
041      /**
042       * The traversal.
043       */
044      private SearchFolderTraversal traversal;
045    
046      /**
047       * The root folder ids.
048       */
049      private FolderIdCollection rootFolderIds = new FolderIdCollection();
050    
051      /**
052       * The search filter.
053       */
054      private SearchFilter searchFilter;
055    
056      /**
057       * Initializes a new instance of the SearchFolderParameters class.
058       */
059      public SearchFolderParameters() {
060        super();
061        this.rootFolderIds.addOnChangeEvent(this);
062      }
063    
064      /**
065       * Complex property changed.
066       *
067       * @param complexProperty the complex property
068       */
069      @Override
070      public void complexPropertyChanged(ComplexProperty complexProperty) {
071        this.propertyChanged(complexProperty);
072      }
073    
074      /**
075       * Property changed.
076       *
077       * @param complexProperty the complex property
078       */
079      private void propertyChanged(ComplexProperty complexProperty) {
080        this.changed();
081      }
082    
083      /**
084       * Tries to read element from XML.
085       *
086       * @param reader the reader
087       * @return True if element was read.
088       * @throws Exception the exception
089       */
090      @Override
091      public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
092          throws Exception {
093        if (reader.getLocalName().equalsIgnoreCase(
094            XmlElementNames.BaseFolderIds)) {
095          this.rootFolderIds.internalClear();
096          this.rootFolderIds.loadFromXml(reader, reader.getLocalName());
097          return true;
098        } else if (reader.getLocalName().equalsIgnoreCase(
099            XmlElementNames.Restriction)) {
100          reader.read();
101          this.searchFilter = SearchFilter.loadFromXml(reader);
102          return true;
103        } else {
104          return false;
105        }
106      }
107    
108      /**
109       * Reads the attribute from XML.
110       *
111       * @param reader the reader
112       * @throws Exception the exception
113       */
114      @Override
115      public void readAttributesFromXml(EwsServiceXmlReader reader)
116          throws Exception {
117        this.traversal = reader.readAttributeValue(SearchFolderTraversal.class,
118            XmlAttributeNames.Traversal);
119      }
120    
121      /**
122       * Writes the attribute to XML.
123       *
124       * @param writer the writer
125       * @throws ServiceXmlSerializationException the service xml serialization exception
126       */
127      @Override
128      public void writeAttributesToXml(EwsServiceXmlWriter writer)
129          throws ServiceXmlSerializationException {
130        writer.writeAttributeValue(XmlAttributeNames.Traversal, this.traversal);
131      }
132    
133      /**
134       * Writes elements to XML.
135       *
136       * @param writer the writer
137       * @throws Exception the exception
138       */
139      @Override
140      public void writeElementsToXml(EwsServiceXmlWriter writer)
141          throws Exception {
142        if (this.searchFilter != null) {
143          writer.writeStartElement(XmlNamespace.Types,
144              XmlElementNames.Restriction);
145          this.searchFilter.writeToXml(writer);
146          writer.writeEndElement(); // Restriction
147        }
148    
149        this.rootFolderIds.writeToXml(writer, XmlElementNames.BaseFolderIds);
150      }
151    
152      /**
153       * Validates this instance.
154       *
155       * @throws Exception
156       */
157      public void validate() throws Exception {
158        // Search folder must have at least one root folder id.
159        if (this.rootFolderIds.getCount() == 0) {
160          throw new ServiceValidationException("SearchParameters must contain at least one folder id.");
161        }
162    
163        // Validate the search filter
164        if (this.searchFilter != null) {
165          this.searchFilter.internalValidate();
166        }
167      }
168    
169      /**
170       * Gets the traversal mode for the search folder.
171       *
172       * @return the traversal
173       */
174      public SearchFolderTraversal getTraversal() {
175        return traversal;
176      }
177    
178      /**
179       * Sets the traversal.
180       *
181       * @param traversal the new traversal
182       */
183      public void setTraversal(SearchFolderTraversal traversal) {
184        if (this.canSetFieldValue(this.traversal, traversal)) {
185          this.traversal = traversal;
186          this.changed();
187        }
188      }
189    
190      /**
191       * Gets the list of root folder the search folder searches in.
192       *
193       * @return the root folder ids
194       */
195      public FolderIdCollection getRootFolderIds() {
196        return rootFolderIds;
197      }
198    
199      /**
200       * Gets the search filter associated with the search folder.
201       * Available search filter classes include SearchFilter.IsEqualTo,
202       * SearchFilter.ContainsSubstring and SearchFilter.SearchFilterCollection.
203       *
204       * @return the search filter
205       */
206      public SearchFilter getSearchFilter() {
207        return searchFilter;
208      }
209    
210      /**
211       * Sets the search filter.
212       *
213       * @param searchFilter the new search filter
214       */
215      public void setSearchFilter(SearchFilter searchFilter) {
216    
217        if (this.searchFilter != null) {
218          this.searchFilter.removeChangeEvent(this);
219        }
220    
221        if (this.canSetFieldValue(this.searchFilter, searchFilter)) {
222          this.searchFilter = searchFilter;
223          this.changed();
224        }
225        if (this.searchFilter != null) {
226          this.searchFilter.addOnChangeEvent(this);
227        }
228      }
229    
230    }