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.search; 025 026import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter; 027import microsoft.exchange.webservices.data.core.XmlAttributeNames; 028import microsoft.exchange.webservices.data.core.XmlElementNames; 029import microsoft.exchange.webservices.data.core.enumeration.search.SortDirection; 030import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace; 031import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException; 032import microsoft.exchange.webservices.data.core.exception.service.local.ServiceXmlSerializationException; 033import microsoft.exchange.webservices.data.misc.OutParam; 034import microsoft.exchange.webservices.data.property.definition.PropertyDefinitionBase; 035 036import javax.xml.stream.XMLStreamException; 037 038import java.util.ArrayList; 039import java.util.HashMap; 040import java.util.Iterator; 041import java.util.List; 042import java.util.Map; 043 044/** 045 * Represents an ordered collection of property definitions qualified with a 046 * sort direction. 047 */ 048public final class OrderByCollection implements 049 Iterable<Map<PropertyDefinitionBase, SortDirection>> { 050 051 /** 052 * The prop def sort order pair list. 053 */ 054 private List<Map<PropertyDefinitionBase, 055 SortDirection>> propDefSortOrderPairList; 056 057 /** 058 * Initializes a new instance of the OrderByCollection class. 059 */ 060 protected OrderByCollection() { 061 this.propDefSortOrderPairList = new 062 ArrayList<Map<PropertyDefinitionBase, SortDirection>>(); 063 } 064 065 /** 066 * Adds the specified property definition / sort direction pair to the 067 * collection. 068 * 069 * @param propertyDefinition the property definition 070 * @param sortDirection the sort direction 071 * @throws ServiceLocalException the service local exception 072 */ 073 public void add(PropertyDefinitionBase propertyDefinition, 074 SortDirection sortDirection) throws ServiceLocalException { 075 if (this.contains(propertyDefinition)) { 076 throw new ServiceLocalException(String.format("Property %s already exists in OrderByCollection.", 077 propertyDefinition.getPrintableName())); 078 } 079 Map<PropertyDefinitionBase, SortDirection> propertyDefinitionSortDirectionPair = new 080 HashMap<PropertyDefinitionBase, SortDirection>(); 081 propertyDefinitionSortDirectionPair.put(propertyDefinition, 082 sortDirection); 083 this.propDefSortOrderPairList.add(propertyDefinitionSortDirectionPair); 084 } 085 086 /** 087 * Removes all elements from the collection. 088 */ 089 public void clear() { 090 this.propDefSortOrderPairList.clear(); 091 } 092 093 /** 094 * Determines whether the collection contains the specified property 095 * definition. 096 * 097 * @param propertyDefinition the property definition 098 * @return True if the collection contains the specified property 099 * definition; otherwise, false. 100 */ 101 protected boolean contains(PropertyDefinitionBase propertyDefinition) { 102 for (Map<PropertyDefinitionBase, SortDirection> propDefSortOrderPair : propDefSortOrderPairList) { 103 return propDefSortOrderPair.containsKey(propertyDefinition); 104 } 105 return false; 106 } 107 108 /** 109 * Gets the number of elements contained in the collection. 110 * 111 * @return the int 112 */ 113 public int count() { 114 return this.propDefSortOrderPairList.size(); 115 } 116 117 /** 118 * Removes the specified property definition from the collection. 119 * 120 * @param propertyDefinition the property definition 121 * @return True if the property definition is successfully removed; 122 * otherwise, false 123 */ 124 public boolean remove(PropertyDefinitionBase propertyDefinition) { 125 List<Map<PropertyDefinitionBase, SortDirection>> removeList = new 126 ArrayList<Map<PropertyDefinitionBase, SortDirection>>(); 127 for (Map<PropertyDefinitionBase, SortDirection> propDefSortOrderPair : propDefSortOrderPairList) { 128 if (propDefSortOrderPair.containsKey(propertyDefinition)) { 129 removeList.add(propDefSortOrderPair); 130 } 131 } 132 this.propDefSortOrderPairList.removeAll(removeList); 133 return removeList.size() > 0; 134 } 135 136 /** 137 * Removes the element at the specified index from the collection. 138 * 139 * @param index the index 140 */ 141 public void removeAt(int index) { 142 this.propDefSortOrderPairList.remove(index); 143 } 144 145 /** 146 * Tries to get the value for a property definition in the collection. 147 * 148 * @param propertyDefinition the property definition 149 * @param sortDirection the sort direction 150 * @return True if collection contains property definition, otherwise false. 151 */ 152 public boolean tryGetValue(PropertyDefinitionBase propertyDefinition, 153 OutParam<SortDirection> sortDirection) { 154 for (Map<PropertyDefinitionBase, SortDirection> pair : this.propDefSortOrderPairList) { 155 156 if (pair.containsKey(propertyDefinition)) { 157 sortDirection.setParam(pair.get(propertyDefinition)); 158 return true; 159 } 160 } 161 sortDirection.setParam(SortDirection.Ascending); // out parameter has to 162 // be set to some 163 // value. 164 return false; 165 } 166 167 /** 168 * Writes to XML. 169 * 170 * @param writer the writer 171 * @param xmlElementName the xml element name 172 * @throws XMLStreamException the XML stream exception 173 * @throws ServiceXmlSerializationException the service xml serialization exception 174 */ 175 protected void writeToXml(EwsServiceXmlWriter writer, String xmlElementName) 176 throws XMLStreamException, ServiceXmlSerializationException { 177 if (this.count() > 0) { 178 writer.writeStartElement(XmlNamespace.Messages, xmlElementName); 179 180 for (Map<PropertyDefinitionBase, SortDirection> keyValuePair : this.propDefSortOrderPairList) { 181 writer.writeStartElement(XmlNamespace.Types, 182 XmlElementNames.FieldOrder); 183 184 writer.writeAttributeValue(XmlAttributeNames.Order, 185 keyValuePair.values().iterator().next()); 186 keyValuePair.keySet().iterator().next().writeToXml(writer); 187 188 writer.writeEndElement(); // FieldOrder 189 } 190 191 writer.writeEndElement(); 192 } 193 } 194 195 /* 196 * (non-Javadoc) 197 * 198 * @see java.lang.Iterable#iterator() 199 */ 200 @Override 201 public Iterator<Map<PropertyDefinitionBase, SortDirection>> iterator() { 202 return this.propDefSortOrderPairList.iterator(); 203 } 204 205 /** 206 * Gets the element at the specified index from the collection. 207 * 208 * @param index the index 209 * @return the property definition sort direction pair 210 */ 211 public Map<PropertyDefinitionBase, 212 SortDirection> getPropertyDefinitionSortDirectionPair( 213 int index) { 214 return this.propDefSortOrderPairList.get(index); 215 } 216 217 /** 218 * Returns an enumerator that iterates through the collection. 219 * 220 * @return A Iterator that can be used to iterate through the collection. 221 */ 222 public Iterator<Map<PropertyDefinitionBase, 223 SortDirection>> getEnumerator() { 224 return (this.propDefSortOrderPairList.iterator()); 225 } 226 227}