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