/**
* Hudson Serenitec plugin
*
* @author Georges Bossert <gbossert@gmail.com>
* @version $Revision: 1.10 $
* @since $Date: 2008/07/23 12:05:05 ${date}
* @copyright Universit� de Rennes 1
*/
package hudson.plugins.serenitec.util.model;
import hudson.model.AbstractBuild;
import hudson.plugins.serenitec.SerenitecResultAction;
import hudson.plugins.serenitec.parseur.ReportEntry;
import hudson.plugins.serenitec.parseur.ReportFile;
import hudson.plugins.serenitec.parseur.ReportPointeur;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import org.apache.commons.lang.StringUtils;
/**
* A container for annotations.
*
* @author Ulli Hafner
*/
public abstract class EntriesContainer implements EntriesProvider, Serializable
{
/** Unique identifier of this class. */
private static final long serialVersionUID = 855696821788264261L;
/** The hierarchy of a container. */
public enum Hierarchy {
/** Project level. */
PROJECT,
/** Module level. */
MODULE,
/** Package level. */
PACKAGE,
/** File level. */
FILE
}
@SuppressWarnings("Se")
private final List<ReportEntry> rules = new ArrayList<ReportEntry>();
/** The active entries */
private final List<ReportEntry> entries = new ArrayList<ReportEntry>();
/** The entries mapped by severity. */
private transient Map<Integer, ArrayList<ReportEntry>> entriesBySeverity;
/** The entries mapped by name. */
private transient Map<String, ArrayList<ReportEntry>> entriesByName;
/** The not fixed entries */
private transient List<ReportEntry> entriesNotFixed;
/** The fixed entries */
private transient List<ReportEntry> entriesFixed;
/** The new entries */
private transient final List<ReportEntry> newEntries = new ArrayList<ReportEntry>();
/** Entries mapped by number of pointeurs */
private transient List<ReportEntry> entriesOrderByNumberOfPointeurs;
/** The TOP5 entries */
private transient List<ReportEntry> topFiveEntries;
/** The files */
private transient final List<ReportFile> fichiers;
/** The list of pointeurs */
private transient List<ReportPointeur> pointeurs;
/** The files that contain annotations mapped by file name. */
private transient Map<String, Package> packagesByName;
/** The files that contain annotations mapped by file name. */
private transient Map<String, MavenModule> modulesByName;
/** Name of this container. */
private String name;
/** Hierarchy level of this container. */
private Hierarchy hierarchy;
private transient AbstractBuild<?, ?> build;
/**
* Creates a new instance of <code>AnnotationContainer</code>.
*
* @param hierarchy
* the hierarchy of this container
*/
public EntriesContainer(final Hierarchy hierarchy) {
this(StringUtils.EMPTY, hierarchy);
}
/**
* Creates a new instance of <code>AnnotationContainer</code>.
*
* @param name
* the name of this container
* @param hierarchy
* the hierarchy of this container
*/
protected EntriesContainer(final String name, final Hierarchy hierarchy) {
initialize();
this.name = name;
this.hierarchy = hierarchy;
this.fichiers = new ArrayList<ReportFile>();
}
/**
* Adds a new category to this container that will contain the specified annotation. If the category already exists, then the annotation
* is only added to this category.
*
* @param annotation
* the new annotation
*/
private void addCategory(final ReportEntry annotation) { // String category = annotation.getCategory();
// if (!annotationsByCategory.containsKey(category)) {
// annotationsByCategory.put(category, new HashSet<FileAnnotation>());
// }
// annotationsByCategory.get(category).add(annotation);
}
/**
* Adds the specified annotations to this container.
*
* @param newAnnotations
* the annotations to add
*/
public final void addEntries(final Collection<? extends ReportEntry> newentry) {
for (final ReportEntry entry : newentry) {
addEntry(entry);
}
initialize();
}
public final void addEntries(final Collection<? extends ReportEntry> detectedEntries, AbstractBuild<?, ?> build) {
this.build = build;
addEntries(detectedEntries);
}
public void addFiles(final ArrayList<ReportFile> files) {
for (ReportFile fichier : files) {
System.out.println("Ajout du fichier " + fichier.getFilename());
this.addFile(fichier);
}
}
public void addFile(final ReportFile fichier) {
fichier.addPatterns(this.getPointeurs());
this.fichiers.add(fichier);
Collections.sort(this.fichiers);
}
/**
* Adds the specified annotations to this container.
*
* @param newAnnotations
* the annotations to add
*/
public final void addEntries(final ReportEntry[] newAnnotations) {
addEntries(Arrays.asList(newAnnotations));
}
/**
* Adds the specified annotation to this container.
*
* @param annotation
* the annotation to add
*/
public final void addEntry(final ReportEntry entry) {
rules.add(entry);
if (entry.isActive()) {
entries.add(entry);
}
updateMappings(entry);
}
/**
* Adds a new file to this container that will contain the specified annotation. If the file already exists, then the annotation is only
* added to this file.
*
* @param annotation
* the new annotation
*/
private void addFile(final ReportEntry annotation) { // String fileName = annotation.getFileName();
// if (!filesByName.containsKey(fileName)) {
// filesByName.put(fileName, new WorkspaceFile(fileName));
// }
// filesByName.get(fileName).addAnnotation(annotation);
}
/**
* Adds a new module to this container that will contain the specified annotation. If the module already exists, then the annotation is
* only added to this module.
*
* @param annotation
* the new annotation
*/
private void addModule(final ReportEntry annotation) { // String moduleName = annotation.getModuleName();
// if (!modulesByName.containsKey(moduleName)) {
// modulesByName.put(moduleName, new MavenModule(moduleName));
// }
// modulesByName.get(moduleName).addAnnotation(annotation);
}
/**
* Adds a new package to this container that will contain the specified annotation. If the package already exists, then the annotation
* is only added to this package.
*
* @param annotation
* the new annotation
*/
private void addPackage(final ReportEntry annotation) { // String packageName = annotation.getPackageName();
// if (!packagesByName.containsKey(packageName)) {
// packagesByName.put(packageName, new Package(packageName));
// }
// packagesByName.get(packageName).addAnnotation(annotation);
}
/**
* Adds a new type to this container that will contain the specified annotation. If the type already exists, then the annotation is only
* added to this type.
*
* @param annotation
* the new annotation
*/
private void addType(final ReportEntry annotation) { // String type = annotation.getType();
// if (!annotationsByType.containsKey(type)) {
// annotationsByType.put(type, new HashSet<FileAnnotation>());
// }
// annotationsByType.get(type).add(annotation);
}
/**
* Returns whether the maven module with the given name exists.
*
* @param moduleName
* the module to check for
* @return <code>true</code> if the maven module with the given name exists, <code>false</code> otherwise
*/
public boolean containsModule(final String moduleName) {
return modulesByName.containsKey(moduleName);
}
/**
* Returns whether the package with the given name exists.
*
* @param packageName
* the package to check for
* @return <code>true</code> if the package with the given name exists, <code>false</code> otherwise
*/
public boolean containsPackage(final String packageName) {
return packagesByName.containsKey(packageName);
}
/**
* Gets the maximum number of annotations within the elements of the child hierarchy.
*
* @return the maximum number of annotations
*/
public final int getAnnotationBound() {
int maximum = 0;
for (final EntriesContainer subContainer : getChildren()) {
maximum = Math.max(maximum, subContainer.getNumberOfEntry());
}
return maximum;
}
/** {@inheritDoc} */
public final Collection<ReportEntry> getAnnotations() {
return Collections.unmodifiableCollection(rules);
}
/**
* Returns the children containers of this container. If we are already at the leaf level, then an empty collection is returned.
*
* @return the children containers of this container.
*/
protected abstract Collection<? extends EntriesContainer> getChildren();
/**
* Returns this container.
*
* @return this container
*/
public EntriesContainer getContainer() {
return this;
}
/**
* Returns the pointeur identified by its key number
*
* @param key
* @return ReportPointeur
*/
public ReportPointeur getPointeur(int key) {
for (ReportPointeur pointeur : pointeurs) {
if (pointeur.getKey() == key) {
return pointeur;
}
}
return null;
}
public List<String> getModifiedFiles() {
List<String> resultat = new ArrayList<String>();
for (ReportPointeur pointeur : pointeurs) {
if (!resultat.contains(pointeur.getFilename())) {
resultat.add(pointeur.getFilename());
}
}
return resultat;
}
public final List<ReportEntry> getRules() {
return rules;
}
public final List<ReportEntry> getEntries() {
return entries;
}
public final Map<String, ArrayList<ReportEntry>> getEntriesByName() {
return entriesByName;
}
public final Map<Integer, ArrayList<ReportEntry>> getEntriesBySeverity() {
return entriesBySeverity;
}
public final List<ReportEntry> getEntriesFixed() {
return entriesFixed;
}
public List<ReportEntry> getEntriesNotFixed() {
return entriesNotFixed;
}
/**
* @return the hightest severity entry discovered
*/
public int getMaxSeverityDiscovered() {
int resultat = 0;
if (getNumberOfSeverityHighSecurity() > 0) {
resultat = 5;
} else if (getNumberOfSeverityLowSecurity() > 0) {
resultat = 4;
} else if (getNumberOfSeverityDesign() > 0) {
resultat = 3;
} else if (getNumberOfSeverityPerformance() > 0) {
resultat = 2;
} else if (getNumberOfSeverityFormatage() > 0) {
resultat = 1;
}
return resultat;
}
/**
* Gets the module with the given name.
*
* @param moduleName
* the name of the module
* @return the module with the given name
*/
public MavenModule getModule(final String moduleName) {
if (modulesByName.containsKey(moduleName)) {
return modulesByName.get(moduleName);
}
throw new NoSuchElementException("Module not found: " + moduleName);
}
/**
* Gets the modules of this container that have annotations.
*
* @return the modules with annotations
*/
public Collection<MavenModule> getModules() {
return Collections.unmodifiableCollection(modulesByName.values());
}
public final Map<String, MavenModule> getModulesByName() {
return modulesByName;
}
/**
* Returns the name of this container.
*
* @return the name of this container
*/
public final String getName() {
return name;
}
public int getNumberOfRules() {
return rules.size();
}
public int getNumberOfEntry() {
return entries.size();
}
public int getNumberOfNewEntry() {
if (newEntries == null) {
return entries.size();
} else {
return newEntries.size();
}
}
public int getNumberOfFiles() {
if (fichiers == null) {
return 0;
} else {
return fichiers.size();
}
}
public int getNumberOfFilesWithErrors() {
System.out.println("-----------------------------------");
int resultat = 0;
System.out.println("getNumberOfFilesWithErrors");
if (fichiers != null) {
for (ReportFile fichier : fichiers) {
if (fichier.hasPatterns()) {
resultat++;
}
}
}
System.out.println("-----------------------------------");
return resultat;
}
public int getNumberOfFilesWithNoErrors() {
return fichiers.size() - getNumberOfFilesWithErrors();
}
public int getNumberOfFixedEntry() {
return entriesFixed.size();
}
public int getNumberOfNotFixedEntry() {
return entriesNotFixed.size();
}
public int getNumberOfPointeurs() {
System.out.println("EntriesContainer.getNumberOfPointeurs : " + pointeurs.size());
return pointeurs.size();
}
public int getNumberOfSeverityDesignPatterns() {
int resultat = 0;
if (entriesBySeverity.containsKey(3)) {
for (ReportEntry entry : entriesBySeverity.get(3)) {
resultat += entry.getNumberOfPointeurs();
}
}
return resultat;
}
public int getNumberOfSeverityFormatagePatterns() {
int resultat = 0;
if (entriesBySeverity.containsKey(1)) {
for (ReportEntry entry : entriesBySeverity.get(1)) {
resultat += entry.getNumberOfPointeurs();
}
}
return resultat;
}
public int getNumberOfSeverityHighSecurityPatterns() {
int resultat = 0;
if (entriesBySeverity.containsKey(5)) {
for (ReportEntry entry : entriesBySeverity.get(5)) {
resultat += entry.getNumberOfPointeurs();
}
}
return resultat;
}
public int getNumberOfSeverityLowSecurityPatterns() {
int resultat = 0;
if (entriesBySeverity.containsKey(4)) {
for (ReportEntry entry : entriesBySeverity.get(4)) {
resultat += entry.getNumberOfPointeurs();
}
}
return resultat;
}
public int getNumberOfSeverityPerformancePatterns() {
int resultat = 0;
if (entriesBySeverity.containsKey(2)) {
for (ReportEntry entry : entriesBySeverity.get(2)) {
resultat += entry.getNumberOfPointeurs();
}
}
return resultat;
}
public int getNumberOfSeverityDesign() {
if (entriesBySeverity.containsKey(3)) {
return entriesBySeverity.get(3).size();
} else {
return 0;
}
}
public int getNumberOfSeverityFormatage() {
if (entriesBySeverity.containsKey(1)) {
return entriesBySeverity.get(1).size();
} else {
return 0;
}
}
public int getNumberOfSeverityHighSecurity() {
if (entriesBySeverity.containsKey(5)) {
return entriesBySeverity.get(5).size();
} else {
return 0;
}
}
public int getNumberOfSeverityLowSecurity() {
if (entriesBySeverity.containsKey(4)) {
return entriesBySeverity.get(4).size();
} else {
return 0;
}
}
public int getNumberOfSeverityPerformance() {
if (entriesBySeverity.containsKey(2)) {
return entriesBySeverity.get(2).size();
} else {
return 0;
}
}
/**
* Gets the package with the given name.
*
* @param packageName
* the name of the package
* @return the file with the given name
*/
public Package getPackage(final String packageName) {
if (packagesByName.containsKey(packageName)) {
return packagesByName.get(packageName);
}
throw new NoSuchElementException("Package not found: " + packageName);
}
/**
* Returns the package category name for the scanned files. Currently, only java and c# files are supported.
*
* @return the package category name for the scanned files
*/
public final String getPackageCategoryName() {
return "Entete message header getpackageCategoryName";
}
/**
* Gets the packages of this container that have annotations.
*
* @return the packages with annotations
*/
public Collection<Package> getPackages() {
return Collections.unmodifiableCollection(packagesByName.values());
}
public final List<ReportPointeur> getPointeurs() {
return pointeurs;
}
/**
* Returns a tooltip showing the distribution of priorities for this container.
*
* @return a tooltip showing the distribution of priorities
*/
public String getToolTip() {
final StringBuilder message = new StringBuilder();
return StringUtils.removeEnd("repartition selon les priorit�s des entry", " - ");
}
public final List<ReportEntry> getTopFiveEntries() {
return topFiveEntries;
}
/** {@inheritDoc} */
public final boolean hasAnnotations() {
System.out.println("EntriesContainer.HASANNOTATION()**");
return !entries.isEmpty();
}
/**
* Initializes the transient mappings.
*/
private void initialize() {
entriesBySeverity = new Hashtable<Integer, ArrayList<ReportEntry>>();
entriesByName = new Hashtable<String, ArrayList<ReportEntry>>();
entriesNotFixed = new ArrayList<ReportEntry>();
entriesFixed = new ArrayList<ReportEntry>();
topFiveEntries = new ArrayList<ReportEntry>();
entriesOrderByNumberOfPointeurs = new ArrayList<ReportEntry>();
pointeurs = new ArrayList<ReportPointeur>();
/**
* NEW ENTRIES
*/
System.out.println("Execution de EntriesContainer.addEntries() : -------------------------");
boolean doit = true;
if (build != null) {
Object previous = build.getPreviousBuild();
boolean go = true;
while (previous != null && previous instanceof AbstractBuild<?, ?> && go) {
AbstractBuild<?, ?> previousBuild = (AbstractBuild<?, ?>) previous;
SerenitecResultAction previousAction = previousBuild.getAction(SerenitecResultAction.class);
if (previousAction != null) {
List<ReportEntry> prec_entries = previousAction.getResult().getContainer().getEntries();
if (prec_entries != null) {
for (ReportEntry entry : entries) {
System.out.println("Entry : " + entry.getName() + " est nouvelle ?");
for (ReportEntry temp_entry : prec_entries) {
if (temp_entry.equals(entry)) {
doit = false;
}
}
if (doit) {
newEntries.add(entry);
System.out.println("New Entry Found !!");
}
doit = true;
}
go = false;
}
}
previous = previousBuild.getPreviousBuild();
}
}
System.out.println("Fin de execution de EntriesContainer.addEntries() : -------------------------");
boolean etat_pointeur;
for (final ReportEntry entry : entries) {
/**
* ENTRIES BY SEVERITY
*/
if (entriesBySeverity.containsKey(entry.getSeverity())) {
final ArrayList<ReportEntry> temp = entriesBySeverity.get(entry.getSeverity());
temp.add(entry);
entriesBySeverity.put(entry.getSeverity(), temp);
} else {
final ArrayList<ReportEntry> temp = new ArrayList<ReportEntry>();
temp.add(entry);
entriesBySeverity.put(entry.getSeverity(), temp);
}
/**
* ENTRIES BY NAME
*/
if (entriesByName.containsKey(entry.getName())) {
final ArrayList<ReportEntry> temp = entriesByName.get(entry.getName());
temp.add(entry);
entriesByName.put(entry.getName(), temp);
}
/**
* ENTRIES NOT FIXED & ENTRIES FIXED
*/
etat_pointeur = true;
for (final ReportPointeur pointeur : entry.getPointeurs()) {
if (!pointeur.isIsfixed()) {
etat_pointeur = false;
}
/**
* POINTEURS
*/
pointeurs.add(pointeur);
}
if (etat_pointeur) {
entriesFixed.add(entry);
} else {
entriesNotFixed.add(entry);
}
}
/**
* TOP FIVE ENTRIES
*/
entriesOrderByNumberOfPointeurs = rules;
Collections.sort(entriesOrderByNumberOfPointeurs, Collections.reverseOrder());
int i = 0;
while (i < 5 && i < entriesOrderByNumberOfPointeurs.size()) {
topFiveEntries.add(entriesOrderByNumberOfPointeurs.get(i));
i++;
}
packagesByName = new HashMap<String, Package>();
modulesByName = new HashMap<String, MavenModule>();
}
/**
* Return true if all the patterns have been fixed
*/
public final boolean IsFixed() {
return getNumberOfNotFixedEntry() == 0;
}
/**
* Rebuilds the priorities mapping.
*
* @return the created object
*/
private Object readResolve() {
rebuildMappings();
return this;
}
/**
* Rebuilds the priorities and files after deserialization.
*/
protected void rebuildMappings() {
initialize();
for (final ReportEntry entry : getEntries()) {
updateMappings(entry);
}
}
/**
* Sets the hierarchy to the specified value.
*
* @param hierarchy
* the value to set
*/
protected void setHierarchy(final Hierarchy hierarchy) {
this.hierarchy = hierarchy;
}
/**
* Sets the name of this container.
*
* @param name
* the name of this container
*/
public final void setName(final String name) {
this.name = name;
}
/**
* Updates the annotation drill-down mappings (priority, packages, files) with the specified annotation.
*
* @param annotation
* the new annotation
*/
private void updateMappings(final ReportEntry annotation) { // annotationsByPriority.get(annotation.getPriority()).add(annotation);
// if (StringUtils.isNotBlank(annotation.getCategory())) {
// addCategory(annotation);
// }
// if (StringUtils.isNotBlank(annotation.getType())) {
// addType(annotation);
// }
// if (hierarchy == Hierarchy.PROJECT) {
// addModule(annotation);
// }
// if (hierarchy == Hierarchy.PROJECT || hierarchy == Hierarchy.MODULE) {
// addPackage(annotation);
// }
// if (hierarchy == Hierarchy.PROJECT || hierarchy == Hierarchy.MODULE || hierarchy == Hierarchy.PACKAGE) {
// addFile(annotation);
// }
}
public List<ReportEntry> getNewEntries() {
return newEntries;
}
public List<ReportFile> getFichiers() {
return fichiers;
}
}