From aedf15a2a90f9643fed5257c9582d79a774c0e11 Mon Sep 17 00:00:00 2001 From: fcamblor Date: Thu, 23 Sep 2010 21:19:31 +0000 Subject: [PATCH] refactored BuildStatConfiguration filters and BuildHistorySearchCriteria.jobFilter to BuildSearchCriteria, allowing to share job build result eligibility (in job filtering) --- .../FromRequestObjectFactory.java | 47 ++++ .../GlobalBuildStatsPlugin.java | 46 ++-- .../business/GlobalBuildStatsBusiness.java | 19 +- .../AbstractBuildStatChartDimension.java | 10 +- .../model/BuildHistorySearchCriteria.java | 14 +- .../model/BuildSearchCriteria.java | 109 +++++++++ .../model/BuildStatConfiguration.java | 209 ++++++++++-------- .../GlobalBuildStatsXStreamConverter.java | 13 +- .../xstream/migration/v6/V5ToV6Migrator.java | 44 ++++ .../migration/v6/V6GlobalBuildStatsPOJO.java | 23 ++ .../xstream/migration/v6/V6XStreamReader.java | 57 +++++ .../GlobalBuildStatsPlugin/index.jelly | 16 +- 12 files changed, 445 insertions(+), 162 deletions(-) create mode 100644 src/main/java/hudson/plugins/global_build_stats/FromRequestObjectFactory.java create mode 100644 src/main/java/hudson/plugins/global_build_stats/model/BuildSearchCriteria.java create mode 100644 src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V5ToV6Migrator.java create mode 100644 src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V6GlobalBuildStatsPOJO.java create mode 100644 src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V6XStreamReader.java diff --git a/src/main/java/hudson/plugins/global_build_stats/FromRequestObjectFactory.java b/src/main/java/hudson/plugins/global_build_stats/FromRequestObjectFactory.java new file mode 100644 index 0000000..fd55dc3 --- /dev/null +++ b/src/main/java/hudson/plugins/global_build_stats/FromRequestObjectFactory.java @@ -0,0 +1,47 @@ +package hudson.plugins.global_build_stats; + +import hudson.plugins.global_build_stats.model.BuildHistorySearchCriteria; +import hudson.plugins.global_build_stats.model.BuildSearchCriteria; +import hudson.plugins.global_build_stats.model.BuildStatConfiguration; +import hudson.plugins.global_build_stats.model.HistoricScale; +import hudson.plugins.global_build_stats.model.YAxisChartType; + +import org.kohsuke.stapler.StaplerRequest; + +public class FromRequestObjectFactory { + + public static BuildHistorySearchCriteria createBuildHistorySearchCriteria(StaplerRequest req){ + BuildSearchCriteria criteria = createBuildSearchCriteria(req); + return new BuildHistorySearchCriteria( + Long.parseLong(req.getParameter("start")), + Long.parseLong(req.getParameter("end")), + criteria); + } + + public static BuildStatConfiguration createBuildStatConfiguration(String id, StaplerRequest req){ + BuildSearchCriteria criteria = createBuildSearchCriteria(req); + return new BuildStatConfiguration( + id, + req.getParameter("title"), + Integer.parseInt(req.getParameter("buildStatWidth")), + Integer.parseInt(req.getParameter("buildStatHeight")), + Integer.parseInt(req.getParameter("historicLength")), + HistoricScale.valueOf(req.getParameter("historicScale")), + YAxisChartType.valueOf(req.getParameter("yAxisChartType")), + Boolean.parseBoolean(req.getParameter("buildStatusesShown")), + Boolean.parseBoolean(req.getParameter("totalBuildTimeShown")), + Boolean.parseBoolean(req.getParameter("averageBuildTimeShown")), + criteria); + } + + public static BuildSearchCriteria createBuildSearchCriteria(StaplerRequest req){ + BuildSearchCriteria criteria = new BuildSearchCriteria(req.getParameter("jobFilter"), + req.getParameter("nodeFilter"), + Boolean.parseBoolean(req.getParameter("successShown")), + Boolean.parseBoolean(req.getParameter("failuresShown")), + Boolean.parseBoolean(req.getParameter("unstablesShown")), + Boolean.parseBoolean(req.getParameter("abortedShown")), + Boolean.parseBoolean(req.getParameter("notBuildsShown"))); + return criteria; + } +} diff --git a/src/main/java/hudson/plugins/global_build_stats/GlobalBuildStatsPlugin.java b/src/main/java/hudson/plugins/global_build_stats/GlobalBuildStatsPlugin.java index c6769ec..1d765aa 100644 --- a/src/main/java/hudson/plugins/global_build_stats/GlobalBuildStatsPlugin.java +++ b/src/main/java/hudson/plugins/global_build_stats/GlobalBuildStatsPlugin.java @@ -12,6 +12,7 @@ import hudson.plugins.global_build_stats.business.GlobalBuildStatsBusiness; import hudson.plugins.global_build_stats.model.AbstractBuildStatChartDimension; import hudson.plugins.global_build_stats.model.BuildHistorySearchCriteria; +import hudson.plugins.global_build_stats.model.BuildSearchCriteria; import hudson.plugins.global_build_stats.model.BuildStatChartData; import hudson.plugins.global_build_stats.model.BuildStatConfiguration; import hudson.plugins.global_build_stats.model.HistoricScale; @@ -87,6 +88,7 @@ public void start() throws Exception { // XStream compacting aliases... Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.JOB_BUILD_RESULT_CLASS_ALIAS, JobBuildResult.class); Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.BUILD_STAT_CONFIG_CLASS_ALIAS, BuildStatConfiguration.class); + Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.BUILD_SEARCH_CRITERIA_CLASS_ALIAS, BuildSearchCriteria.class); Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.HISTORIC_SCALE_CLASS_ALIAS, HistoricScale.class); Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.YAXIS_CHART_TYPE_CLASS_ALIAS, YAxisChartType.class); Hudson.XSTREAM.alias(GlobalBuildStatsXStreamConverter.YAXIS_CHART_DIMENSION_CLASS_ALIAS, YAxisChartDimension.class); @@ -96,11 +98,17 @@ public void start() throws Exception { Hudson.XSTREAM.aliasField("h", BuildStatConfiguration.class, "buildStatHeight"); Hudson.XSTREAM.aliasField("l", BuildStatConfiguration.class, "historicLength"); Hudson.XSTREAM.aliasField("s", BuildStatConfiguration.class, "historicScale"); - Hudson.XSTREAM.aliasField("jf", BuildStatConfiguration.class, "jobFilter"); - Hudson.XSTREAM.aliasField("sbr", BuildStatConfiguration.class, "shownBuildResults"); Hudson.XSTREAM.aliasField("yact", BuildStatConfiguration.class, "yAxisChartType"); Hudson.XSTREAM.aliasField("ds", BuildStatConfiguration.class, "dimensionsShown"); + Hudson.XSTREAM.aliasField("f", BuildStatConfiguration.class, "buildFilters"); + // Deprecated ! Just here for old formats + Hudson.XSTREAM.aliasField("jf", BuildStatConfiguration.class, "jobFilter"); + Hudson.XSTREAM.aliasField("sbr", BuildStatConfiguration.class, "shownBuildResults"); + Hudson.XSTREAM.aliasField("jf", BuildSearchCriteria.class, "jobFilter"); + Hudson.XSTREAM.aliasField("nf", BuildSearchCriteria.class, "nodeFilter"); + Hudson.XSTREAM.aliasField("sbr", BuildSearchCriteria.class, "shownBuildResults"); + Hudson.XSTREAM.aliasField("r", JobBuildResult.class, "result"); Hudson.XSTREAM.aliasField("n", JobBuildResult.class, "jobName"); Hudson.XSTREAM.aliasField("nb", JobBuildResult.class, "buildNumber"); @@ -302,7 +310,7 @@ public void doCreateChart(StaplerRequest req, StaplerResponse res) throws Servle Hudson.getInstance().checkPermission(getRequiredPermission()); // Passing null id since this is a not persisted BuildStatConfiguration - BuildStatConfiguration config = createBuildStatConfig(null, req); + BuildStatConfiguration config = FromRequestObjectFactory.createBuildStatConfiguration(null, req); JFreeChart chart = business.createChart(config); ChartUtil.generateGraph(req, res, chart, config.getBuildStatWidth(), config.getBuildStatHeight()); @@ -317,7 +325,7 @@ public void doCreateChartMap(StaplerRequest req, StaplerResponse res) throws Ser config = business.searchBuildStatConfigById(buildStatId); } else { // Passing null id since this is a not persisted BuildStatConfiguration - config = createBuildStatConfig(null, req); + config = FromRequestObjectFactory.createBuildStatConfiguration(null, req); } JFreeChart chart = business.createChart(config); @@ -327,8 +335,7 @@ public void doCreateChartMap(StaplerRequest req, StaplerResponse res) throws Ser public void doBuildHistory(StaplerRequest req, StaplerResponse res) throws ServletException, IOException { Hudson.getInstance().checkPermission(getRequiredPermission()); - BuildHistorySearchCriteria searchCriteria = new BuildHistorySearchCriteria(); - req.bindParameters(searchCriteria); + BuildHistorySearchCriteria searchCriteria = FromRequestObjectFactory.createBuildHistorySearchCriteria(req); List filteredJobBuildResults = business.searchBuilds(searchCriteria); @@ -342,7 +349,7 @@ public void doUpdateBuildStatConfiguration(StaplerRequest req, StaplerResponse r boolean regenerateId = Boolean.valueOf(req.getParameter("regenerateId")).booleanValue(); - BuildStatConfiguration config = createBuildStatConfig(req.getParameter("buildStatId"), req); + BuildStatConfiguration config = FromRequestObjectFactory.createBuildStatConfiguration(req.getParameter("buildStatId"), req); business.updateBuildStatConfiguration(req.getParameter("buildStatId"), config, regenerateId); String json = JSONObject.fromObject(config).toString(); @@ -352,7 +359,7 @@ public void doUpdateBuildStatConfiguration(StaplerRequest req, StaplerResponse r public void doAddBuildStatConfiguration(StaplerRequest req, StaplerResponse res) throws ServletException, IOException { Hudson.getInstance().checkPermission(getRequiredPermission()); - BuildStatConfiguration config = createBuildStatConfig(ModelIdGenerator.INSTANCE.generateIdForClass(BuildStatConfiguration.class), req); + BuildStatConfiguration config = FromRequestObjectFactory.createBuildStatConfiguration(ModelIdGenerator.INSTANCE.generateIdForClass(BuildStatConfiguration.class), req); business.addBuildStatConfiguration(config); String json = JSONObject.fromObject(config).toString(); @@ -411,29 +418,6 @@ public static String getFieldFilterRegex(){ return FieldFilterFactory.REGEX_FIELD_FILTER_LABEL; } - private BuildStatConfiguration createBuildStatConfig(String id, StaplerRequest req){ - // TODO: refactor this using StaplerRequest.bindParameters() with introspection ! - return new BuildStatConfiguration( - id, - req.getParameter("title"), - Integer.parseInt(req.getParameter("buildStatWidth")), - Integer.parseInt(req.getParameter("buildStatHeight")), - Integer.parseInt(req.getParameter("historicLength")), - HistoricScale.valueOf(req.getParameter("historicScale")), - req.getParameter("jobFilter"), - req.getParameter("nodeFilter"), - Boolean.parseBoolean(req.getParameter("successShown")), - Boolean.parseBoolean(req.getParameter("failuresShown")), - Boolean.parseBoolean(req.getParameter("unstablesShown")), - Boolean.parseBoolean(req.getParameter("abortedShown")), - Boolean.parseBoolean(req.getParameter("notBuildsShown")), - YAxisChartType.valueOf(req.getParameter("yAxisChartType")), - Boolean.parseBoolean(req.getParameter("buildStatusesShown")), - Boolean.parseBoolean(req.getParameter("totalBuildTimeShown")), - Boolean.parseBoolean(req.getParameter("averageBuildTimeShown")) - ); - } - public BuildStatConfiguration[] getBuildStatConfigsArrayed() { return buildStatConfigs.toArray(new BuildStatConfiguration[]{}); } diff --git a/src/main/java/hudson/plugins/global_build_stats/business/GlobalBuildStatsBusiness.java b/src/main/java/hudson/plugins/global_build_stats/business/GlobalBuildStatsBusiness.java index 3cdcc94..cbcd65c 100644 --- a/src/main/java/hudson/plugins/global_build_stats/business/GlobalBuildStatsBusiness.java +++ b/src/main/java/hudson/plugins/global_build_stats/business/GlobalBuildStatsBusiness.java @@ -7,12 +7,9 @@ import hudson.model.Job; import hudson.plugins.global_build_stats.GlobalBuildStatsPlugin; import hudson.plugins.global_build_stats.JobBuildResultFactory; -import hudson.plugins.global_build_stats.FieldFilter; -import hudson.plugins.global_build_stats.FieldFilterFactory; import hudson.plugins.global_build_stats.model.AbstractBuildStatChartDimension; import hudson.plugins.global_build_stats.model.AbstractBuildStatChartDimension.LegendItemData; import hudson.plugins.global_build_stats.model.BuildHistorySearchCriteria; -import hudson.plugins.global_build_stats.model.BuildResult; import hudson.plugins.global_build_stats.model.BuildStatConfiguration; import hudson.plugins.global_build_stats.model.DateRange; import hudson.plugins.global_build_stats.model.JobBuildResult; @@ -118,12 +115,8 @@ public JFreeChart createChart(BuildStatConfiguration config){ public List searchBuilds(BuildHistorySearchCriteria searchCriteria){ List filteredJobBuildResults = new ArrayList(); - FieldFilter jobFilter = FieldFilterFactory.createFieldFilter(searchCriteria.jobFilter); for(JobBuildResult r : plugin.getJobBuildResults()){ - if(r.getBuildDate().getTimeInMillis() >= searchCriteria.start - && r.getBuildDate().getTimeInMillis() < searchCriteria.end - && jobResultStatusMatchesWith(r.getResult(), searchCriteria) - && jobFilter.isFieldValueValid(r.getJobName())){ + if(searchCriteria.isJobResultEligible(r)){ boolean isJobAccessible = false; boolean isBuildAccessible = false; @@ -220,14 +213,6 @@ public static String escapeAntiSlashes(String value){ } } - protected static boolean jobResultStatusMatchesWith(BuildResult r, BuildHistorySearchCriteria c){ - return (BuildResult.ABORTED.equals(r) && c.abortedShown) - || (BuildResult.FAILURE.equals(r) && c.failuresShown) - || (BuildResult.NOT_BUILD.equals(r) && c.notBuildShown) - || (BuildResult.SUCCESS.equals(r) && c.successShown) - || (BuildResult.UNSTABLE.equals(r) && c.unstablesShown); - } - private JFreeChart createChart(final BuildStatConfiguration config, List dimensions, String title) { final JFreeChart chart = ChartFactory.createStackedAreaChart(title, null, "", @@ -324,7 +309,7 @@ public List createDataSetBuilder(BuildStatConfi // If no range found : stop the iteration ! if(tickCount != config.getHistoricLength() && currentBuild != null){ - if(config.isJobResultEligible(currentBuild)){ + if(config.getBuildFilters().isJobResultEligible(currentBuild)){ for(AbstractBuildStatChartDimension dimension : dimensions){ dimension.saveDataForBuild(currentBuild); } diff --git a/src/main/java/hudson/plugins/global_build_stats/model/AbstractBuildStatChartDimension.java b/src/main/java/hudson/plugins/global_build_stats/model/AbstractBuildStatChartDimension.java index 4f07c24..f0244871 100644 --- a/src/main/java/hudson/plugins/global_build_stats/model/AbstractBuildStatChartDimension.java +++ b/src/main/java/hudson/plugins/global_build_stats/model/AbstractBuildStatChartDimension.java @@ -95,15 +95,19 @@ public String generateURL(CategoryDataset dataset, int row, int column) { boolean abortedShown=Messages.Build_Results_Statuses_ABORTED().equals(status); boolean notBuildShown=Messages.Build_Results_Statuses_NOT_BUILD().equals(status); - return new StringBuilder() - .append("buildHistory?jobFilter=").append(config.getJobFilter()) + StringBuilder sb = new StringBuilder() + .append("buildHistory?jobFilter=").append(config.getBuildFilters().getJobFilter()) .append("&start=").append(range.getStart().getTimeInMillis()) .append("&end=").append(range.getEnd().getTimeInMillis()) .append("&successShown=").append(successShown) .append("&failuresShown=").append(failuresShown) .append("&unstablesShown=").append(unstablesShown) .append("&abortedShown=").append(abortedShown) - .append("¬BuildShown=").append(notBuildShown).toString(); + .append("¬BuildShown=").append(notBuildShown); + if(config.getBuildFilters().getNodeFilter() != null){ + sb.append("&nodeFilter=").append(config.getBuildFilters().getNodeFilter()); + } + return sb.toString(); } /* TODO: add tooltip diff --git a/src/main/java/hudson/plugins/global_build_stats/model/BuildHistorySearchCriteria.java b/src/main/java/hudson/plugins/global_build_stats/model/BuildHistorySearchCriteria.java index 3bc1e9c..3c7ba42 100644 --- a/src/main/java/hudson/plugins/global_build_stats/model/BuildHistorySearchCriteria.java +++ b/src/main/java/hudson/plugins/global_build_stats/model/BuildHistorySearchCriteria.java @@ -2,8 +2,18 @@ public class BuildHistorySearchCriteria { - public String jobFilter; public long start, end; - public boolean successShown, failuresShown, unstablesShown, abortedShown, notBuildShown; + public BuildSearchCriteria buildFilters; + public BuildHistorySearchCriteria(long _start, long _end, BuildSearchCriteria _buildFilters){ + this.start = _start; + this.end = _end; + this.buildFilters = _buildFilters; + } + + public boolean isJobResultEligible(JobBuildResult result){ + return buildFilters.isJobResultEligible(result) + && (result.getBuildDate().getTimeInMillis() >= this.start) + && (result.getBuildDate().getTimeInMillis() < this.end); + } } diff --git a/src/main/java/hudson/plugins/global_build_stats/model/BuildSearchCriteria.java b/src/main/java/hudson/plugins/global_build_stats/model/BuildSearchCriteria.java new file mode 100644 index 0000000..269a89e --- /dev/null +++ b/src/main/java/hudson/plugins/global_build_stats/model/BuildSearchCriteria.java @@ -0,0 +1,109 @@ +package hudson.plugins.global_build_stats.model; + +import hudson.plugins.global_build_stats.FieldFilter; +import hudson.plugins.global_build_stats.FieldFilterFactory; + +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; + +@ExportedBean +public class BuildSearchCriteria { + + private String jobFilter = FieldFilterFactory.ALL_VALUES_FILTER_LABEL; + transient FieldFilter calculatedJobFilter = null; // For calcul optimizations only + private String nodeFilter = FieldFilterFactory.ALL_VALUES_FILTER_LABEL; + transient FieldFilter calculatedNodeFilter = null; // For calcul optimizations only + private short shownBuildResults; + + public BuildSearchCriteria(String _jobFilter, String _nodeFilter, + boolean _successShown, boolean _failuresShown, boolean _unstablesShown, + boolean _abortedShown, boolean _notBuildsShown){ + + this.setJobFilter(_jobFilter); + this.setNodeFilter(_nodeFilter); + + this.shownBuildResults = 0; + this.shownBuildResults |= _successShown?BuildResult.SUCCESS.code:0; + this.shownBuildResults |= _failuresShown?BuildResult.FAILURE.code:0; + this.shownBuildResults |= _unstablesShown?BuildResult.UNSTABLE.code:0; + this.shownBuildResults |= _abortedShown?BuildResult.ABORTED.code:0; + this.shownBuildResults |= _notBuildsShown?BuildResult.NOT_BUILD.code:0; + } + + public boolean isJobResultEligible(JobBuildResult result){ + boolean jobBuildEligible = true; + + jobBuildEligible &= getCalculatedJobFilter().isFieldValueValid(result.getJobName()); + jobBuildEligible &= getCalculatedNodeFilter().isFieldValueValid(result.getNodeName()); + jobBuildEligible &= isAbortedShown() || result.getResult().getAbortedCount()!=1; + jobBuildEligible &= isFailuresShown() || result.getResult().getFailureCount()!=1; + jobBuildEligible &= isNotBuildShown() || result.getResult().getNotBuildCount()!=1; + jobBuildEligible &= isSuccessShown() || result.getResult().getSuccessCount()!=1; + jobBuildEligible &= isUnstablesShown() || result.getResult().getUnstableCount()!=1; + + return jobBuildEligible; + } + + public void setJobFilter(String jobFilter) { + this.jobFilter = jobFilter; + this.calculatedJobFilter = FieldFilterFactory.createFieldFilter(jobFilter); + } + + public void setNodeFilter(String nodeFilter) { + this.nodeFilter = nodeFilter; + this.calculatedNodeFilter = FieldFilterFactory.createFieldFilter(nodeFilter); + } + + protected FieldFilter getCalculatedJobFilter(){ + // When BuildStatConfiguration is XStream deserialized, the transient calculatedJobFilter field + // will be null ! + if(calculatedJobFilter == null){ calculatedJobFilter = FieldFilterFactory.createFieldFilter(jobFilter); } + return this.calculatedJobFilter; + } + + protected FieldFilter getCalculatedNodeFilter(){ + // When BuildStatConfiguration is XStream deserialized, the transient calculatedNodeFilter field + // will be null ! + if(calculatedNodeFilter == null){ calculatedNodeFilter = FieldFilterFactory.createFieldFilter(nodeFilter); } + return this.calculatedNodeFilter; + } + + @Exported + public boolean isSuccessShown(){ + return (shownBuildResults & BuildResult.SUCCESS.code) != 0; + } + + @Exported + public boolean isFailuresShown(){ + return (shownBuildResults & BuildResult.FAILURE.code) != 0; + } + + @Exported + public boolean isUnstablesShown(){ + return (shownBuildResults & BuildResult.UNSTABLE.code) != 0; + } + + @Exported + public boolean isAbortedShown(){ + return (shownBuildResults & BuildResult.ABORTED.code) != 0; + } + + @Exported + public boolean isNotBuildShown(){ + return (shownBuildResults & BuildResult.NOT_BUILD.code) != 0; + } + + @Exported + public String getJobFilter() { + return jobFilter; + } + + @Exported + public String getNodeFilter() { + return nodeFilter; + } + + public void setShownBuildResults(short shownBuildResults) { + this.shownBuildResults = shownBuildResults; + } +} diff --git a/src/main/java/hudson/plugins/global_build_stats/model/BuildStatConfiguration.java b/src/main/java/hudson/plugins/global_build_stats/model/BuildStatConfiguration.java index 468f61e..c66c793 100644 --- a/src/main/java/hudson/plugins/global_build_stats/model/BuildStatConfiguration.java +++ b/src/main/java/hudson/plugins/global_build_stats/model/BuildStatConfiguration.java @@ -34,20 +34,32 @@ public class BuildStatConfiguration implements Serializable { private YAxisChartDimension[] dimensionsShown; // Filters on jobs - private String jobFilter = FieldFilterFactory.ALL_VALUES_FILTER_LABEL; + private BuildSearchCriteria buildFilters; + /** + * @deprecated Use buildFilters.jobFilter instead ! + */ + @Deprecated + transient private String jobFilter = FieldFilterFactory.ALL_VALUES_FILTER_LABEL; transient FieldFilter calculatedJobFilter = null; // For calcul optimizations only - private String nodeFilter = FieldFilterFactory.ALL_VALUES_FILTER_LABEL; + /** + * @deprecated Use buildFilters.nodeFilter instead ! + */ + @Deprecated + transient private String nodeFilter = FieldFilterFactory.ALL_VALUES_FILTER_LABEL; transient FieldFilter calculatedNodeFilter = null; // For calcul optimizations only - private short shownBuildResults; + /** + * @deprecated Use buildFilters.shownBuildResults instead ! + */ + @Deprecated + transient private short shownBuildResults; public BuildStatConfiguration(){ } public BuildStatConfiguration(String _id, String _buildStatTitle, int _buildStatWidth, int _buildStatHeight, - int _historicLength, HistoricScale _historicScale, String _jobFilter, String _nodeFilter, - boolean _successShown, boolean _failuresShown, boolean _unstablesShown, - boolean _abortedShown, boolean _notBuildsShown, YAxisChartType _yAxisChartType, - boolean _buildCountsShown, boolean _totalBuildTimeShown, boolean _averageBuildTimeShown){ + int _historicLength, HistoricScale _historicScale, YAxisChartType _yAxisChartType, + boolean _buildCountsShown, boolean _totalBuildTimeShown, boolean _averageBuildTimeShown, + BuildSearchCriteria _buildFilters){ this.id = _id; this.buildStatTitle = _buildStatTitle; @@ -56,17 +68,8 @@ public BuildStatConfiguration(String _id, String _buildStatTitle, int _buildStat this.historicLength = _historicLength; this.historicScale = _historicScale; - this.setJobFilter(_jobFilter); - this.setNodeFilter(_nodeFilter); - - this.shownBuildResults = 0; - this.shownBuildResults |= _successShown?BuildResult.SUCCESS.code:0; - this.shownBuildResults |= _failuresShown?BuildResult.FAILURE.code:0; - this.shownBuildResults |= _unstablesShown?BuildResult.UNSTABLE.code:0; - this.shownBuildResults |= _abortedShown?BuildResult.ABORTED.code:0; - this.shownBuildResults |= _notBuildsShown?BuildResult.NOT_BUILD.code:0; - this.yAxisChartType = _yAxisChartType; + this.buildFilters = _buildFilters; List dimensionsList = new ArrayList(); if(_buildCountsShown){ dimensionsList.add(YAxisChartDimension.BUILD_COUNTER); } @@ -75,45 +78,6 @@ public BuildStatConfiguration(String _id, String _buildStatTitle, int _buildStat this.dimensionsShown = dimensionsList.toArray(new YAxisChartDimension[]{}); } - public boolean isJobResultEligible(JobBuildResult result){ - boolean jobBuildEligible = true; - - jobBuildEligible &= getCalculatedJobFilter().isFieldValueValid(result.getJobName()); - jobBuildEligible &= getCalculatedNodeFilter().isFieldValueValid(result.getNodeName()); - jobBuildEligible &= isAbortedShown() || result.getResult().getAbortedCount()!=1; - jobBuildEligible &= isFailuresShown() || result.getResult().getFailureCount()!=1; - jobBuildEligible &= isNotBuildShown() || result.getResult().getNotBuildCount()!=1; - jobBuildEligible &= isSuccessShown() || result.getResult().getSuccessCount()!=1; - jobBuildEligible &= isUnstablesShown() || result.getResult().getUnstableCount()!=1; - - return jobBuildEligible; - } - - @Exported - public boolean isSuccessShown(){ - return (shownBuildResults & BuildResult.SUCCESS.code) != 0; - } - - @Exported - public boolean isFailuresShown(){ - return (shownBuildResults & BuildResult.FAILURE.code) != 0; - } - - @Exported - public boolean isUnstablesShown(){ - return (shownBuildResults & BuildResult.UNSTABLE.code) != 0; - } - - @Exported - public boolean isAbortedShown(){ - return (shownBuildResults & BuildResult.ABORTED.code) != 0; - } - - @Exported - public boolean isNotBuildShown(){ - return (shownBuildResults & BuildResult.NOT_BUILD.code) != 0; - } - @Exported public String getBuildStatTitle() { return buildStatTitle; @@ -129,10 +93,6 @@ public HistoricScale getHistoricScale() { return historicScale; } - public short getShownBuildResults() { - return shownBuildResults; - } - @Exported public int getBuildStatWidth() { return buildStatWidth; @@ -143,16 +103,6 @@ public int getBuildStatHeight() { return buildStatHeight; } - @Exported - public String getJobFilter() { - return jobFilter; - } - - @Exported - public String getNodeFilter() { - return nodeFilter; - } - @Exported public String getId() { return id; @@ -183,16 +133,6 @@ public void setHistoricScale(String historicScale) { this.historicScale = HistoricScale.valueOf(historicScale); } - public void setJobFilter(String jobFilter) { - this.jobFilter = jobFilter; - this.calculatedJobFilter = FieldFilterFactory.createFieldFilter(jobFilter); - } - - public void setNodeFilter(String nodeFilter) { - this.nodeFilter = nodeFilter; - this.calculatedNodeFilter = FieldFilterFactory.createFieldFilter(nodeFilter); - } - public void setId(String id) { this.id = id; } @@ -201,10 +141,6 @@ public void setyAxisChartType(YAxisChartType yAxisChartType) { this.yAxisChartType = yAxisChartType; } - public void setShownBuildResults(short shownBuildResults) { - this.shownBuildResults = shownBuildResults; - } - @Exported public YAxisChartDimension[] getDimensionsShown() { return dimensionsShown; @@ -214,20 +150,6 @@ public void setDimensionsShown(YAxisChartDimension[] dimensionsShown) { this.dimensionsShown = dimensionsShown; } - protected FieldFilter getCalculatedJobFilter(){ - // When BuildStatConfiguration is XStream deserialized, the transient calculatedJobFilter field - // will be null ! - if(calculatedJobFilter == null){ calculatedJobFilter = FieldFilterFactory.createFieldFilter(jobFilter); } - return this.calculatedJobFilter; - } - - protected FieldFilter getCalculatedNodeFilter(){ - // When BuildStatConfiguration is XStream deserialized, the transient calculatedNodeFilter field - // will be null ! - if(calculatedNodeFilter == null){ calculatedNodeFilter = FieldFilterFactory.createFieldFilter(nodeFilter); } - return this.calculatedNodeFilter; - } - @Exported public boolean isBuildStatusesShown(){ return Arrays.binarySearch(this.dimensionsShown, YAxisChartDimension.BUILD_COUNTER)>=0; @@ -242,4 +164,95 @@ public boolean isTotalBuildTimeShown (){ public boolean isAverageBuildTimeShown(){ return Arrays.binarySearch(this.dimensionsShown, YAxisChartDimension.BUILD_AVERAGE_DURATION)>=0; } + + @Exported + public BuildSearchCriteria getBuildFilters() { + return buildFilters; + } + + public void setBuildFilters(BuildSearchCriteria buildFilters) { + this.buildFilters = buildFilters; + } + + /** + * Use getBuildFilters().isSuccessShown() instead + */ + @Deprecated + public boolean isSuccessShown(){ + return (shownBuildResults & BuildResult.SUCCESS.code) != 0; + } + + /** + * Use getBuildFilters().isFailuresShown() instead + */ + @Deprecated + public boolean isFailuresShown(){ + return (shownBuildResults & BuildResult.FAILURE.code) != 0; + } + + /** + * Use getBuildFilters().isUnstablesShown() instead + */ + @Deprecated + public boolean isUnstablesShown(){ + return (shownBuildResults & BuildResult.UNSTABLE.code) != 0; + } + + /** + * Use getBuildFilters().isAbortedShown() instead + */ + @Deprecated + public boolean isAbortedShown(){ + return (shownBuildResults & BuildResult.ABORTED.code) != 0; + } + + /** + * Use getBuildFilters().isNotBuildShown() instead + */ + @Deprecated + public boolean isNotBuildShown(){ + return (shownBuildResults & BuildResult.NOT_BUILD.code) != 0; + } + + /** + * Use getBuildFilters().getJobFilter() instead + */ + @Deprecated + public String getJobFilter() { + return jobFilter; + } + + /** + * Use getBuildFilters().getNodeFilter() instead + */ + @Deprecated + public String getNodeFilter() { + return nodeFilter; + } + + /** + * Use getBuildFilters().setJobFilter(jobFilter) instead + */ + @Deprecated + public void setJobFilter(String jobFilter) { + this.jobFilter = jobFilter; + this.calculatedJobFilter = FieldFilterFactory.createFieldFilter(jobFilter); + } + + /** + * Use getBuildFilters().setNodeFilter(nodeFilter) instead + */ + @Deprecated + public void setNodeFilter(String nodeFilter) { + this.nodeFilter = nodeFilter; + this.calculatedNodeFilter = FieldFilterFactory.createFieldFilter(nodeFilter); + } + + /** + * Use getBuildFilters().setShownBuildResults(shownBuildResults) instead + */ + @Deprecated + public void setShownBuildResults(short shownBuildResults) { + this.shownBuildResults = shownBuildResults; + } } diff --git a/src/main/java/hudson/plugins/global_build_stats/xstream/GlobalBuildStatsXStreamConverter.java b/src/main/java/hudson/plugins/global_build_stats/xstream/GlobalBuildStatsXStreamConverter.java index 30c02df..8b05b4d 100644 --- a/src/main/java/hudson/plugins/global_build_stats/xstream/GlobalBuildStatsXStreamConverter.java +++ b/src/main/java/hudson/plugins/global_build_stats/xstream/GlobalBuildStatsXStreamConverter.java @@ -16,8 +16,10 @@ import hudson.plugins.global_build_stats.xstream.migration.v4.V3ToV4Migrator; import hudson.plugins.global_build_stats.xstream.migration.v4.V4XStreamReader; import hudson.plugins.global_build_stats.xstream.migration.v5.V4ToV5Migrator; -import hudson.plugins.global_build_stats.xstream.migration.v5.V5GlobalBuildStatsPOJO; import hudson.plugins.global_build_stats.xstream.migration.v5.V5XStreamReader; +import hudson.plugins.global_build_stats.xstream.migration.v6.V5ToV6Migrator; +import hudson.plugins.global_build_stats.xstream.migration.v6.V6GlobalBuildStatsPOJO; +import hudson.plugins.global_build_stats.xstream.migration.v6.V6XStreamReader; import java.util.logging.Logger; @@ -48,6 +50,7 @@ public class GlobalBuildStatsXStreamConverter implements Converter { public static final String BUILD_STAT_CONFIG_CLASS_ALIAS = "bsc"; public static final String JOB_BUILD_RESULT_CLASS_ALIAS = "jbr"; + public static final String BUILD_SEARCH_CRITERIA_CLASS_ALIAS = "bscr"; public static final String HISTORIC_SCALE_CLASS_ALIAS = "GBS_HS"; public static final String YAXIS_CHART_TYPE_CLASS_ALIAS = "GBS_YACT"; public static final String YAXIS_CHART_DIMENSION_CLASS_ALIAS = "GBS_YACD"; @@ -62,7 +65,8 @@ public class GlobalBuildStatsXStreamConverter implements Converter { new V2XStreamReader(), new V3XStreamReader(), new V4XStreamReader(), - new V5XStreamReader() + new V5XStreamReader(), + new V6XStreamReader() }; /** @@ -73,7 +77,8 @@ public class GlobalBuildStatsXStreamConverter implements Converter { new V1ToV2Migrator(), new V2ToV3Migrator(), new V3ToV4Migrator(), - new V4ToV5Migrator() + new V4ToV5Migrator(), + new V5ToV6Migrator() }; /** @@ -169,7 +174,7 @@ public Object unmarshal(HierarchicalStreamReader reader, protected void populateGlobalBuildStatsPlugin(GlobalBuildStatsPlugin plugin, GlobalBuildStatsPOJO pojo){ // Latest POJO is v5 // Update this line every time you add a new migrator ! - V5GlobalBuildStatsPOJO versionedPojo = (V5GlobalBuildStatsPOJO)pojo; + V6GlobalBuildStatsPOJO versionedPojo = (V6GlobalBuildStatsPOJO)pojo; plugin.getBuildStatConfigs().clear(); plugin.getBuildStatConfigs().addAll(versionedPojo.buildStatConfigs); diff --git a/src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V5ToV6Migrator.java b/src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V5ToV6Migrator.java new file mode 100644 index 0000000..5a1b997 --- /dev/null +++ b/src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V5ToV6Migrator.java @@ -0,0 +1,44 @@ +package hudson.plugins.global_build_stats.xstream.migration.v6; + +import hudson.plugins.global_build_stats.model.BuildSearchCriteria; +import hudson.plugins.global_build_stats.model.BuildStatConfiguration; +import hudson.plugins.global_build_stats.model.JobBuildResult; +import hudson.plugins.global_build_stats.xstream.migration.GlobalBuildStatsDataMigrator; +import hudson.plugins.global_build_stats.xstream.migration.v5.V5GlobalBuildStatsPOJO; + +import java.util.ArrayList; + +/** + * V6 Evolutions : + * - Creation of BuildStatConfiguration.buildFilters and move of jobFilter, nodeFilter and shownBuildResults into this encapsulated class + * @author fcamblor + */ +public class V5ToV6Migrator implements GlobalBuildStatsDataMigrator { + + public V6GlobalBuildStatsPOJO migrate(V5GlobalBuildStatsPOJO pojo) { + V6GlobalBuildStatsPOJO migratedPojo = new V6GlobalBuildStatsPOJO(); + + migratedPojo.buildStatConfigs = new ArrayList(); + migratedPojo.jobBuildResults = new ArrayList(); + + for(BuildStatConfiguration cfg : pojo.buildStatConfigs){ + // Migrating old data into new BuildSearchCriteria which will be persisted ! + BuildSearchCriteria criteria = new BuildSearchCriteria( + cfg.getJobFilter(), + cfg.getNodeFilter(), + cfg.isSuccessShown(), + cfg.isFailuresShown(), + cfg.isUnstablesShown(), + cfg.isAbortedShown(), + cfg.isNotBuildShown()); + + cfg.setBuildFilters(criteria); + + migratedPojo.buildStatConfigs.add(cfg); + } + migratedPojo.jobBuildResults.addAll(pojo.jobBuildResults); + + return migratedPojo; + } + +} diff --git a/src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V6GlobalBuildStatsPOJO.java b/src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V6GlobalBuildStatsPOJO.java new file mode 100644 index 0000000..f96bd55 --- /dev/null +++ b/src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V6GlobalBuildStatsPOJO.java @@ -0,0 +1,23 @@ +package hudson.plugins.global_build_stats.xstream.migration.v6; + +import java.util.List; + +import hudson.plugins.global_build_stats.model.BuildStatConfiguration; +import hudson.plugins.global_build_stats.model.JobBuildResult; +import hudson.plugins.global_build_stats.xstream.migration.GlobalBuildStatsPOJO; + +public class V6GlobalBuildStatsPOJO implements GlobalBuildStatsPOJO { + + /** + * List of aggregated job build results + * This list will grow over time + */ + public List jobBuildResults; + + /** + * List of persisted build statistics configurations used on the + * global build stats screen + */ + public List buildStatConfigs; + +} diff --git a/src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V6XStreamReader.java b/src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V6XStreamReader.java new file mode 100644 index 0000000..af58134 --- /dev/null +++ b/src/main/java/hudson/plugins/global_build_stats/xstream/migration/v6/V6XStreamReader.java @@ -0,0 +1,57 @@ +package hudson.plugins.global_build_stats.xstream.migration.v6; + +import hudson.plugins.global_build_stats.model.BuildStatConfiguration; +import hudson.plugins.global_build_stats.model.JobBuildResult; +import hudson.plugins.global_build_stats.model.ModelIdGenerator; +import hudson.plugins.global_build_stats.xstream.migration.GlobalBuildStatsXStreamReader; + +import java.util.ArrayList; +import java.util.List; + +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +/** + * Reader for GlobalBuildStats v6 XStream representation + * @author fcamblor + */ +public class V6XStreamReader implements GlobalBuildStatsXStreamReader{ + + public V6GlobalBuildStatsPOJO readGlobalBuildStatsPOJO( + HierarchicalStreamReader reader, UnmarshallingContext context) { + + V6GlobalBuildStatsPOJO pojo = new V6GlobalBuildStatsPOJO(); + + reader.moveDown(); + List jobBuildResults = new ArrayList(); + while(reader.hasMoreChildren()){ + reader.moveDown(); + + JobBuildResult jbr = (JobBuildResult)context.convertAnother(pojo, JobBuildResult.class); + jobBuildResults.add(jbr); + + reader.moveUp(); + } + reader.moveUp(); + + reader.moveDown(); + List buildStatConfigs = new ArrayList(); + while(reader.hasMoreChildren()){ + reader.moveDown(); + + BuildStatConfiguration bsc = (BuildStatConfiguration)context.convertAnother(pojo, BuildStatConfiguration.class); + buildStatConfigs.add(bsc); + + // Registering BuildStatConfiguration's id in the ModelIdGenerator + ModelIdGenerator.INSTANCE.registerIdForClass(BuildStatConfiguration.class, bsc.getId()); + + reader.moveUp(); + } + reader.moveUp(); + + pojo.jobBuildResults = jobBuildResults; + pojo.buildStatConfigs = buildStatConfigs; + + return pojo; + } +} diff --git a/src/main/resources/hudson/plugins/global_build_stats/GlobalBuildStatsPlugin/index.jelly b/src/main/resources/hudson/plugins/global_build_stats/GlobalBuildStatsPlugin/index.jelly index 4364ea8..1611a88 100644 --- a/src/main/resources/hudson/plugins/global_build_stats/GlobalBuildStatsPlugin/index.jelly +++ b/src/main/resources/hudson/plugins/global_build_stats/GlobalBuildStatsPlugin/index.jelly @@ -266,7 +266,7 @@ } if($(this.buildStatConfId+'_jobFilter').value.indexOf(FIELD_FILTER_REGEX) != -1){ $(this.buildStatConfId+'_jobFilteringType_REGEX').checked = 'checked'; - initializeRegexField(this.buildStatConfId+'_jobNameRegex', this.buildStatConf.jobFilter); + initializeRegexField(this.buildStatConfId+'_jobNameRegex', this.buildStatConf.buildFilters.jobFilter); $(this.buildStatConfId+'_jobFilteringType_REGEX').onchange(); $(this.buildStatConfId+'_jobNameRegex').disabled = false; } else if($(this.buildStatConfId+'_jobFilter').value.indexOf(FIELD_FILTER_ALL) != -1){ @@ -280,7 +280,7 @@ } if($(this.buildStatConfId+'_nodeFilter').value.indexOf(FIELD_FILTER_REGEX) != -1){ $(this.buildStatConfId+'_nodeFilteringType_REGEX').checked = 'checked'; - initializeRegexField(this.buildStatConfId+'_nodeNameRegex', this.buildStatConf.nodeFilter); + initializeRegexField(this.buildStatConfId+'_nodeNameRegex', this.buildStatConf.buildFilters.nodeFilter); $(this.buildStatConfId+'_nodeFilteringType_REGEX').onchange(); $(this.buildStatConfId+'_nodeNameRegex').disabled = false; } else if($(this.buildStatConfId+'_nodeFilter').value.indexOf(FIELD_FILTER_ALL) != -1){ @@ -290,11 +290,11 @@ // Changing default values... if(this.buildStatConf != null){ - if(this.buildStatConf.successShown == false) { $(this.buildStatConfId+'_successShown').checked = false; } - if(this.buildStatConf.failuresShown == false) { $(this.buildStatConfId+'_failuresShown').checked = false; } - if(this.buildStatConf.unstablesShown == false) { $(this.buildStatConfId+'_unstablesShown').checked = false; } - if(this.buildStatConf.abortedShown == false) { $(this.buildStatConfId+'_abortedShown').checked = false; } - if(this.buildStatConf.notBuildsShown == true) { $(this.buildStatConfId+'_notBuildsShown').checked = true; } + if(this.buildStatConf.buildFilters.successShown == false) { $(this.buildStatConfId+'_successShown').checked = false; } + if(this.buildStatConf.buildFilters.failuresShown == false) { $(this.buildStatConfId+'_failuresShown').checked = false; } + if(this.buildStatConf.buildFilters.unstablesShown == false) { $(this.buildStatConfId+'_unstablesShown').checked = false; } + if(this.buildStatConf.buildFilters.abortedShown == false) { $(this.buildStatConfId+'_abortedShown').checked = false; } + if(this.buildStatConf.buildFilters.notBuildsShown == true) { $(this.buildStatConfId+'_notBuildsShown').checked = true; } if(this.buildStatConf.buildStatusesShown == false) { $(this.buildStatConfId+'_buildStatusesShown').checked = false; } if(this.buildStatConf.totalBuildTimeShown == true) { $(this.buildStatConfId+'_totalBuildTimeShown').checked = true; } if(this.buildStatConf.averageBuildTimeShown == true) { $(this.buildStatConfId+'_averageBuildTimeShown').checked = true; } @@ -564,6 +564,8 @@ } else { // Creating context for update var currentContext = jsonConcat(buildStatConfiguration, { + jobFilter: buildStatConfiguration.buildFilters.jobFilter, + nodeFilter: buildStatConfiguration.buildFilters.nodeFilter, rootURL: rootURL, formAction: "updateBuildStatConfiguration", buildStatId: getBuildStatConfigId(buildStatConfiguration.id),