1 /* 2 * Copyright 2008-2010 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package de.smartics.maven.issues.bugzilla; 18 19 import java.util.Comparator; 20 import java.util.Iterator; 21 import java.util.List; 22 import java.util.Map; 23 import java.util.TreeMap; 24 25 import org.apache.maven.artifact.versioning.ArtifactVersion; 26 import org.eclipse.mylyn.tasks.core.data.TaskData; 27 28 import de.smartics.maven.issues.util.InverseVersionComparator; 29 30 /** 31 * Contains sections separated by their versions. The versions are not required 32 * to be known in advance. 33 * 34 * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a> 35 * @version $Revision:591 $ 36 */ 37 public class Versions implements Iterable<Versions.VersionedSections> 38 { 39 // ********************************* Fields ********************************* 40 41 // --- constants ------------------------------------------------------------ 42 43 // --- members -------------------------------------------------------------- 44 45 /** 46 * The list of sections to be put to the sections instance. Sections not 47 * mentioned here will be ignored. 48 */ 49 private final List<String> sectionNames; 50 51 /** 52 * The map of versions pointing to the sections with lists of task data. 53 */ 54 private final Map<ArtifactVersion, Sections> versionsMap; 55 56 // ****************************** Initializer ******************************* 57 58 // ****************************** Constructors ****************************** 59 60 /** 61 * Convenience constructor using the {@link InverseVersionComparator} to sort 62 * the version from large to small. 63 * 64 * @param sectionNames the list of sections to be put to the sections 65 * instance. 66 * @throws NullPointerException if the <code>sectionNames</code> list is 67 * <code>null</code>. 68 */ 69 public Versions(final List<String> sectionNames) throws NullPointerException 70 { 71 this(sectionNames, new InverseVersionComparator()); 72 } 73 74 /** 75 * Default constructor. 76 * 77 * @param sectionNames the list of sections to be put to the sections 78 * instance. 79 * @param comparator the comparator to use to sort the versions. If 80 * {@link NullPointerException}, the natural ordering is used. 81 * @throws NullPointerException if the <code>sectionNames</code> list is 82 * <code>null</code>. 83 */ 84 public Versions(final List<String> sectionNames, 85 final Comparator<ArtifactVersion> comparator) throws NullPointerException 86 { 87 if (sectionNames == null) 88 { 89 throw new NullPointerException( 90 "The section name list must not be 'null'."); 91 } 92 this.sectionNames = sectionNames; 93 this.versionsMap = new TreeMap<ArtifactVersion, Sections>(comparator); 94 } 95 96 // ****************************** Inner Classes ***************************** 97 98 /** 99 * A versioned sections information bundle. 100 */ 101 public static final class VersionedSections 102 { 103 // ******************************** Fields ******************************** 104 105 // --- constants ---------------------------------------------------------- 106 107 // --- members ------------------------------------------------------------ 108 109 /** 110 * The version identifier of the sections. 111 */ 112 private final ArtifactVersion version; 113 114 /** 115 * The sections associated with the given version. 116 */ 117 private final Sections sections; 118 119 // ***************************** Initializer ****************************** 120 121 // ***************************** Constructors ***************************** 122 123 /** 124 * Default constructor. 125 * 126 * @param version the version identifier of the sections. 127 * @param sections the sections associated with the given version. 128 */ 129 private VersionedSections(final ArtifactVersion version, 130 final Sections sections) 131 { 132 this.version = version; 133 this.sections = sections; 134 } 135 136 // ***************************** Inner Classes **************************** 137 138 // ******************************** Methods ******************************* 139 140 // --- init --------------------------------------------------------------- 141 142 // --- get&set ------------------------------------------------------------ 143 144 /** 145 * Returns the version identifier of the sections. 146 * 147 * @return the version identifier of the sections. 148 */ 149 public ArtifactVersion getVersion() 150 { 151 return version; 152 } 153 154 /** 155 * Returns the sections associated with the given version. 156 * 157 * @return the sections associated with the given version. 158 */ 159 public Sections getSections() 160 { 161 return sections; 162 } 163 164 // --- business ----------------------------------------------------------- 165 166 // --- object basics ------------------------------------------------------ 167 } 168 169 /** 170 * Implementation of the iterator over sections using the iterator of the 171 * underlying map. 172 */ 173 private final class VersionedSectionsIterator implements 174 Iterator<VersionedSections> 175 { 176 // ******************************** Fields ******************************** 177 178 // --- constants ---------------------------------------------------------- 179 180 // --- members ------------------------------------------------------------ 181 182 /** 183 * The iterator on the map of section information. 184 */ 185 private final Iterator<Map.Entry<ArtifactVersion, Sections>> i = 186 versionsMap.entrySet().iterator(); 187 188 // ***************************** Initializer ****************************** 189 190 // ***************************** Constructors ***************************** 191 192 // ***************************** Inner Classes **************************** 193 194 // ******************************** Methods ******************************* 195 196 // --- init --------------------------------------------------------------- 197 198 // --- get&set ------------------------------------------------------------ 199 200 // --- business ----------------------------------------------------------- 201 202 /** 203 * {@inheritDoc} 204 */ 205 public boolean hasNext() 206 { 207 return i.hasNext(); 208 } 209 210 /** 211 * {@inheritDoc} 212 */ 213 public VersionedSections next() 214 { 215 final Map.Entry<ArtifactVersion, Sections> entry = i.next(); 216 return new VersionedSections(entry.getKey(), entry.getValue()); // NOPMD 217 } 218 219 /** 220 * Not supported. 221 * 222 * @throws UnsupportedOperationException always. 223 */ 224 public void remove() throws UnsupportedOperationException 225 { 226 throw new UnsupportedOperationException( 227 "Removing versioned sections not supported."); 228 } 229 230 // --- object basics ------------------------------------------------------ 231 232 } 233 234 // ********************************* Methods ******************************** 235 236 // --- init ----------------------------------------------------------------- 237 238 // --- get&set -------------------------------------------------------------- 239 240 // --- business ------------------------------------------------------------- 241 242 /** 243 * Adds the task data to the section within the version. If the section is not 244 * managed, the task data is not added. 245 * 246 * @param version the version to select the section. 247 * @param sectionName the name of the section to add the task data to. 248 * @param taskData the task data to add to the given section. 249 * @return <code>true</code> if the task data is added, <code>false</code> if 250 * not. 251 */ 252 public boolean add(final ArtifactVersion version, final String sectionName, 253 final TaskData taskData) 254 { 255 Sections sections = versionsMap.get(version); 256 boolean sectionIsNew = false; 257 if (sections == null) 258 { 259 sections = new Sections(this.sectionNames); 260 sectionIsNew = true; 261 } 262 263 final boolean added = sections.addToSection(sectionName, taskData); 264 265 if (sectionIsNew && added) 266 { 267 versionsMap.put(version, sections); 268 } 269 return added; 270 } 271 272 /** 273 * {@inheritDoc} 274 * 275 * @see java.lang.Iterable#iterator() 276 */ 277 public Iterator<VersionedSections> iterator() 278 { 279 return new VersionedSectionsIterator(); 280 } 281 282 // --- object basics -------------------------------------------------------- 283 284 }