diff --git a/pom.xml b/pom.xml index cc32d2d4e2..ea6fff7958 100644 --- a/pom.xml +++ b/pom.xml @@ -417,14 +417,16 @@ - org.codehaus.mojo - versions-maven-plugin + ${project.groupId} + ${project.artifactId} + ${project.version} dependency-updates-report plugin-updates-report property-updates-report + parent-updates-report diff --git a/src/it/it-abstract-versions-report-001/verify.groovy b/src/it/it-abstract-versions-report-001/verify.groovy index da937db0ce..c0633c5e32 100644 --- a/src/it/it-abstract-versions-report-001/verify.groovy +++ b/src/it/it-abstract-versions-report-001/verify.groovy @@ -1,15 +1,17 @@ -dependencyUpdatesReport = new File( basedir, "target/site/dependency-updates-report.html" ) - -assert dependencyUpdatesReport.exists( ) +dependencyUpdatesReport = new File( basedir, "target/site/dependency-updates-report.html" ).text + .replaceAll( '<[^>]+>', ' ' ) + .replaceAll( '&[^;]+;', ' ' ) + .replaceAll( '\\s+', ' ' ) // some basic (=not comprehensive) checks on the contents of the dependency report -assert dependencyUpdatesReport.text =~ /\b1\.1\.0-2\b/ // current version of the dependency -assert dependencyUpdatesReport.text =~ /\b3\.0\b/ // latest major available version - -pluginUpdatesReport = new File( basedir, "target/site/plugin-updates-report.html" ) +assert dependencyUpdatesReport =~ /\b1\.1\.0-2\b/ // current version of the dependency +assert dependencyUpdatesReport =~ /\b3\.0\b/ // latest major available version -assert pluginUpdatesReport.exists( ) +pluginUpdatesReport = new File( basedir, "target/site/plugin-updates-report.html" ).text + .replaceAll( '<[^>]+>', ' ' ) + .replaceAll( '&[^;]+;', ' ' ) + .replaceAll( '\\s+', ' ' ) // some basic (=not comprehensive) checks on the contents of the plugin report -assert pluginUpdatesReport.text =~ /\b1\.0\b/ // current version of the plugin -assert pluginUpdatesReport.text =~ /\b3\.1\b/ // latest major available version \ No newline at end of file +assert pluginUpdatesReport =~ /\b1\.0\b/ // current version of the plugin +assert pluginUpdatesReport =~ /\b3\.1\b/ // latest major available version \ No newline at end of file diff --git a/src/it/it-parent-updates-report-001/invoker.properties b/src/it/it-parent-updates-report-001/invoker.properties index c01f7db0e4..d89b80b302 100644 --- a/src/it/it-parent-updates-report-001/invoker.properties +++ b/src/it/it-parent-updates-report-001/invoker.properties @@ -1 +1 @@ -invoker.goals=site +invoker.goals = site diff --git a/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java b/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java index 5fa98541ab..336febe831 100644 --- a/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java +++ b/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java @@ -19,8 +19,6 @@ * under the License. */ -import javax.inject.Inject; - import java.io.File; import java.util.List; import java.util.Locale; @@ -49,15 +47,17 @@ import org.codehaus.mojo.versions.api.DefaultVersionsHelper; import org.codehaus.mojo.versions.api.VersionsHelper; import org.codehaus.mojo.versions.model.RuleSet; +import org.codehaus.mojo.versions.reporting.ReportRendererFactory; import org.codehaus.plexus.i18n.I18N; /** * Base class for all versions reports. * + * @param modelled report object * @author Stephen Connolly * @since 1.0-alpha-3 */ -public abstract class AbstractVersionsReport +public abstract class AbstractVersionsReport extends AbstractMavenReport { /** @@ -99,7 +99,7 @@ public abstract class AbstractVersionsReport /** * @since 1.0-alpha-3 */ - private WagonManager wagonManager; + private final WagonManager wagonManager; /** * @since 1.0-alpha-3 @@ -188,17 +188,25 @@ public abstract class AbstractVersionsReport @Parameter( property = "maven.version.ignore" ) protected Set ignoredVersions; + /** + * Renderer factory + * + * @since 2.13.0 + */ + protected ReportRendererFactory rendererFactory; + // --------------------- GETTER / SETTER METHODS --------------------- - @Inject protected AbstractVersionsReport( I18N i18n, RepositorySystem repositorySystem, ArtifactResolver artifactResolver, - ArtifactMetadataSource artifactMetadataSource, WagonManager wagonManager ) + ArtifactMetadataSource artifactMetadataSource, WagonManager wagonManager, + ReportRendererFactory rendererFactory ) { this.i18n = i18n; this.repositorySystem = repositorySystem; this.artifactResolver = artifactResolver; this.artifactMetadataSource = artifactMetadataSource; this.wagonManager = wagonManager; + this.rendererFactory = rendererFactory; } public VersionsHelper getHelper() diff --git a/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReportRenderer.java b/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReportRenderer.java deleted file mode 100644 index b61ffa0e36..0000000000 --- a/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReportRenderer.java +++ /dev/null @@ -1,826 +0,0 @@ -package org.codehaus.mojo.versions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.util.HashSet; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import org.apache.maven.artifact.ArtifactUtils; -import org.apache.maven.artifact.versioning.ArtifactVersion; -import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; -import org.apache.maven.artifact.versioning.VersionRange; -import org.apache.maven.doxia.sink.Sink; -import org.apache.maven.doxia.sink.SinkEventAttributes; -import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; -import org.apache.maven.model.Dependency; -import org.apache.maven.reporting.AbstractMavenReportRenderer; -import org.codehaus.mojo.versions.api.AbstractVersionDetails; -import org.codehaus.mojo.versions.api.ArtifactAssociation; -import org.codehaus.mojo.versions.api.ArtifactVersions; -import org.codehaus.mojo.versions.api.PropertyVersions; -import org.codehaus.plexus.i18n.I18N; -import org.codehaus.plexus.util.StringUtils; - -import static java.util.Optional.empty; -import static java.util.Optional.of; -import static org.codehaus.mojo.versions.api.Segment.INCREMENTAL; -import static org.codehaus.mojo.versions.api.Segment.MAJOR; -import static org.codehaus.mojo.versions.api.Segment.MINOR; -import static org.codehaus.mojo.versions.api.Segment.SUBINCREMENTAL; - -/** - * Base class for report renderers. - * - * @author Stephen Connolly - * @since 1.0-beta-1 - */ -public abstract class AbstractVersionsReportRenderer - extends AbstractMavenReportRenderer -{ - /** - * Internationalization component. - * - * @since 1.0-beta-1 - */ - protected final I18N i18n; - - /** - * The locale we are rendering for. - * - * @since 1.0-beta-1 - */ - protected final Locale locale; - - /** - * The name of the bundle containing our I18n resources. - * - * @since 1.0-beta-1 - */ - protected final String bundleName; - - public AbstractVersionsReportRenderer( org.apache.maven.doxia.sink.Sink sink, String bundleName, I18N i18n, - Locale locale ) - { - super( sink ); - this.bundleName = bundleName; - this.i18n = i18n; - this.locale = locale; - } - - public String getTitle() - { - return getText( "report.title" ); - } - - /** - * Gets the localized message for this report. - * - * @param key the message key. - * @return the message. - */ - public String getText( String key ) - { - return i18n.getString( bundleName, locale, key ); - } - - protected void renderWarningIcon() - { - sink.figureGraphics( "images/icon_warning_sml.gif" ); - } - - protected void renderSuccessIcon() - { - sink.figureGraphics( "images/icon_success_sml.gif" ); - } - - protected boolean equals( ArtifactVersion v1, ArtifactVersion v2 ) - { - return v1 == v2 || ( v1 != null && v1.equals( v2 ) ) - || ( v1 != null && v2 != null && v1.toString().equals( v2.toString() ) ); - } - - protected void renderDependencySummaryTableRow( Dependency dependency, ArtifactVersions details ) - { - renderDependencySummaryTableRow( dependency, details, true, true, true ); - } - - protected void renderDependencySummaryTableRow( Dependency dependency, ArtifactVersions details, - boolean includeScope, boolean includeClassifier, - boolean includeType ) - { - sink.tableRow(); - sink.tableCell(); - ArtifactVersion[] allUpdates = details.getAllUpdates( empty() ); - if ( allUpdates == null || allUpdates.length == 0 ) - { - renderSuccessIcon(); - } - else - { - renderWarningIcon(); - } - sink.tableCell_(); - sink.tableCell(); - sink.text( dependency.getGroupId() ); - sink.tableCell_(); - sink.tableCell(); - sink.text( dependency.getArtifactId() ); - sink.tableCell_(); - sink.tableCell(); - sink.text( dependency.getVersion() ); - sink.tableCell_(); - if ( includeScope ) - { - sink.tableCell(); - sink.text( dependency.getScope() ); - sink.tableCell_(); - } - if ( includeClassifier ) - { - sink.tableCell(); - sink.text( dependency.getClassifier() ); - sink.tableCell_(); - } - if ( includeType ) - { - sink.tableCell(); - sink.text( dependency.getType() ); - sink.tableCell_(); - } - - sink.tableCell(); - if ( details.getNewestUpdate( of( SUBINCREMENTAL ) ) != null ) - { - safeBold(); - sink.text( details.getNewestUpdate( of( SUBINCREMENTAL ) ).toString() ); - safeBold_(); - } - sink.tableCell_(); - - sink.tableCell(); - if ( details.getNewestUpdate( of( INCREMENTAL ) ) != null ) - { - safeBold(); - sink.text( details.getNewestUpdate( of( INCREMENTAL ) ).toString() ); - safeBold_(); - } - sink.tableCell_(); - - sink.tableCell(); - if ( details.getNewestUpdate( of( MINOR ) ) != null ) - { - safeBold(); - sink.text( details.getNewestUpdate( of( MINOR ) ).toString() ); - safeBold_(); - } - sink.tableCell_(); - - sink.tableCell(); - if ( details.getNewestUpdate( of( MAJOR ) ) != null ) - { - safeBold(); - sink.text( details.getNewestUpdate( of( MAJOR ) ).toString() ); - safeBold_(); - } - sink.tableCell_(); - - sink.tableRow_(); - } - - protected void safeBold() - { - try - { - sink.bold(); - } - catch ( NoSuchMethodError e ) - { - // ignore Maven 2.1.0 - } - } - - @SuppressWarnings( "checkstyle:MethodName" ) - protected void safeBold_() - { - try - { - sink.bold_(); - } - catch ( NoSuchMethodError e ) - { - // ignore Maven 2.1.0 - } - } - - protected void safeItalic() - { - try - { - sink.italic(); - } - catch ( NoSuchMethodError e ) - { - // ignore Maven 2.1.0 - } - } - - @SuppressWarnings( "checkstyle:MethodName" ) - protected void safeItalic_() - { - try - { - sink.italic_(); - } - catch ( NoSuchMethodError e ) - { - // ignore Maven 2.1.0 - } - } - - protected void renderDependencySummaryTableHeader() - { - renderDependencySummaryTableHeader( true, true, true ); - } - - protected void renderDependencySummaryTableHeader( boolean includeScope, boolean includeClassifier, - boolean includeType ) - { - sink.tableRow(); - sink.tableHeaderCell(); - sink.text( getText( "report.status" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.groupId" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.artifactId" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.currentVersion" ) ); - sink.tableHeaderCell_(); - if ( includeScope ) - { - sink.tableHeaderCell(); - sink.text( getText( "report.scope" ) ); - sink.tableHeaderCell_(); - } - if ( includeClassifier ) - { - sink.tableHeaderCell(); - sink.text( getText( "report.classifier" ) ); - sink.tableHeaderCell_(); - } - if ( includeType ) - { - sink.tableHeaderCell(); - sink.text( getText( "report.type" ) ); - sink.tableHeaderCell_(); - } - sink.tableHeaderCell(); - sink.text( getText( "report.latestSubIncremental" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestIncremental" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestMinor" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestMajor" ) ); - sink.tableHeaderCell_(); - sink.tableRow_(); - } - - protected void renderDependencyDetailTable( Dependency dependency, ArtifactVersions details ) - { - renderDependencyDetailTable( dependency, details, true, true, true ); - } - - @SuppressWarnings( "checkstyle:MethodLength" ) - protected void renderDependencyDetailTable( Dependency dependency, ArtifactVersions details, boolean includeScope, - boolean includeClassifier, boolean includeType ) - { - final SinkEventAttributes headerAttributes = new SinkEventAttributeSet(); - headerAttributes.addAttribute( SinkEventAttributes.WIDTH, "20%" ); - final SinkEventAttributes cellAttributes = new SinkEventAttributeSet(); - headerAttributes.addAttribute( SinkEventAttributes.WIDTH, "80%" ); - sink.table(); - sink.tableRows( new int[] { Sink.JUSTIFY_RIGHT, Sink.JUSTIFY_LEFT }, false ); - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.status" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - ArtifactVersion[] versions = details.getAllUpdates( empty() ); - if ( details.getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) - { - renderWarningIcon(); - sink.nonBreakingSpace(); - sink.text( getText( "report.otherUpdatesAvailable" ) ); - } - else if ( details.getOldestUpdate( of( INCREMENTAL ) ) != null ) - { - renderWarningIcon(); - sink.nonBreakingSpace(); - sink.text( getText( "report.incrementalUpdatesAvailable" ) ); - } - else if ( details.getOldestUpdate( of( MINOR ) ) != null ) - { - renderWarningIcon(); - sink.nonBreakingSpace(); - sink.text( getText( "report.minorUpdatesAvailable" ) ); - } - else if ( details.getOldestUpdate( of( MAJOR ) ) != null ) - { - renderWarningIcon(); - sink.nonBreakingSpace(); - sink.text( getText( "report.majorUpdatesAvailable" ) ); - } - else - { - renderSuccessIcon(); - sink.nonBreakingSpace(); - sink.text( getText( "report.noUpdatesAvailable" ) ); - } - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.groupId" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( dependency.getGroupId() ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.artifactId" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( dependency.getArtifactId() ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.currentVersion" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( dependency.getVersion() ); - sink.tableCell_(); - sink.tableRow_(); - if ( includeScope ) - { - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.scope" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( dependency.getScope() ); - sink.tableCell_(); - sink.tableRow_(); - } - if ( includeClassifier ) - { - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.classifier" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( dependency.getClassifier() ); - sink.tableCell_(); - sink.tableRow_(); - } - if ( includeType ) - { - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.type" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( dependency.getType() ); - sink.tableCell_(); - sink.tableRow_(); - } - if ( versions != null && versions.length > 0 ) - { - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.updateVersions" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - for ( int i = 0; i < versions.length; i++ ) - { - if ( i > 0 ) - { - sink.lineBreak(); - } - String label = getLabel( versions[i], details ); - if ( label != null ) - { - safeBold(); - } - sink.text( versions[i].toString() ); - if ( label != null ) - { - safeBold_(); - sink.nonBreakingSpace(); - safeItalic(); - sink.text( label ); - safeItalic_(); - } - } - sink.tableCell_(); - sink.tableRow_(); - } - sink.tableRows_(); - sink.table_(); - } - - protected void renderDependencySummaryTable( Map map ) - { - renderDependencySummaryTable( map, true, true, true ); - } - - protected void renderDependencySummaryTable( Map map, boolean includeScope, - boolean includeClassifier, boolean includeType ) - { - sink.table(); - renderDependencySummaryTableHeader( includeScope, includeClassifier, includeType ); - for ( Map.Entry entry : map.entrySet() ) - { - renderDependencySummaryTableRow( entry.getKey(), entry.getValue(), includeScope, includeClassifier, - includeType ); - } - renderDependencySummaryTableHeader( includeScope, includeClassifier, includeType ); - sink.table_(); - } - - protected void renderPropertySummaryTable( Map map ) - { - sink.table(); - renderPropertySummaryTableHeader(); - for ( Map.Entry entry : map.entrySet() ) - { - renderPropertySummaryTableRow( entry.getKey(), entry.getValue() ); - } - renderPropertySummaryTableHeader(); - sink.table_(); - } - - protected void renderPropertySummaryTableRow( Property property, PropertyVersions versions ) - { - sink.tableRow(); - sink.tableCell(); - if ( versions.getAllUpdates( empty() ).length == 0 ) - { - renderSuccessIcon(); - } - else - { - renderWarningIcon(); - } - sink.tableCell_(); - sink.tableCell(); - sink.text( "${" + property.getName() + "}" ); - sink.tableCell_(); - sink.tableCell(); - sink.text( versions.getCurrentVersion().toString() ); - sink.tableCell_(); - - sink.tableCell(); - if ( versions.getNewestUpdate( of( SUBINCREMENTAL ) ) != null ) - { - safeBold(); - sink.text( versions.getNewestUpdate( of( SUBINCREMENTAL ) ).toString() ); - safeBold_(); - } - sink.tableCell_(); - - sink.tableCell(); - if ( versions.getNewestUpdate( of( INCREMENTAL ) ) != null ) - { - safeBold(); - sink.text( versions.getNewestUpdate( of( INCREMENTAL ) ).toString() ); - safeBold_(); - } - sink.tableCell_(); - - sink.tableCell(); - if ( versions.getNewestUpdate( of( MINOR ) ) != null ) - { - safeBold(); - sink.text( versions.getNewestUpdate( of( MINOR ) ).toString() ); - safeBold_(); - } - sink.tableCell_(); - - sink.tableCell(); - if ( versions.getNewestUpdate( of( MAJOR ) ) != null ) - { - safeBold(); - sink.text( versions.getNewestUpdate( of( MAJOR ) ).toString() ); - safeBold_(); - } - sink.tableCell_(); - - sink.tableRow_(); - } - - protected void renderPropertySummaryTableHeader() - { - sink.tableRow(); - sink.tableHeaderCell(); - sink.text( getText( "report.status" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.property" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.currentVersion" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestSubIncremental" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestIncremental" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestMinor" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestMajor" ) ); - sink.tableHeaderCell_(); - sink.tableRow_(); - } - - @SuppressWarnings( "checkstyle:MethodLength" ) - protected void renderPropertyDetailTable( Property property, PropertyVersions versions ) - { - final SinkEventAttributes headerAttributes = new SinkEventAttributeSet(); - headerAttributes.addAttribute( SinkEventAttributes.WIDTH, "20%" ); - final SinkEventAttributes cellAttributes = new SinkEventAttributeSet(); - headerAttributes.addAttribute( SinkEventAttributes.WIDTH, "80%" ); - sink.table(); - sink.tableRows( new int[] { Sink.JUSTIFY_RIGHT, Sink.JUSTIFY_LEFT }, false ); - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.status" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - ArtifactVersion[] artifactVersions = versions.getAllUpdates( empty() ); - Set rangeVersions = getVersionsInRange( property, versions, artifactVersions ); - if ( versions.getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) - { - renderWarningIcon(); - sink.nonBreakingSpace(); - sink.text( getText( "report.otherUpdatesAvailable" ) ); - } - else if ( versions.getOldestUpdate( of( INCREMENTAL ) ) != null ) - { - renderWarningIcon(); - sink.nonBreakingSpace(); - sink.text( getText( "report.incrementalUpdatesAvailable" ) ); - } - else if ( versions.getOldestUpdate( of( MINOR ) ) != null ) - { - renderWarningIcon(); - sink.nonBreakingSpace(); - sink.text( getText( "report.minorUpdatesAvailable" ) ); - } - else if ( versions.getOldestUpdate( of( MAJOR ) ) != null ) - { - renderWarningIcon(); - sink.nonBreakingSpace(); - sink.text( getText( "report.majorUpdatesAvailable" ) ); - } - else - { - renderSuccessIcon(); - sink.nonBreakingSpace(); - sink.text( getText( "report.noUpdatesAvailable" ) ); - } - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.property" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( "${" + property.getName() + "}" ); - sink.tableCell_(); - sink.tableRow_(); - - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.associations" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - ArtifactAssociation[] associations = versions.getAssociations(); - for ( int i = 0; i < associations.length; i++ ) - { - if ( i > 0 ) - { - sink.lineBreak(); - } - sink.text( ArtifactUtils.versionlessKey( associations[i].getArtifact() ) ); - } - sink.tableCell_(); - sink.tableRow_(); - - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.currentVersion" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( versions.getCurrentVersion().toString() ); - sink.tableCell_(); - sink.tableRow_(); - if ( artifactVersions.length > 0 ) - { - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.updateVersions" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - boolean someNotAllowed = false; - for ( int i = 0; i < artifactVersions.length; i++ ) - { - if ( i > 0 ) - { - sink.lineBreak(); - } - boolean allowed = ( rangeVersions.contains( artifactVersions[i].toString() ) ); - String label = getLabel( artifactVersions[i], versions ); - if ( !allowed ) - { - sink.text( "* " ); - someNotAllowed = true; - } - if ( allowed && label != null ) - { - safeBold(); - } - sink.text( artifactVersions[i].toString() ); - if ( label != null ) - { - if ( allowed ) - { - safeBold_(); - } - sink.nonBreakingSpace(); - safeItalic(); - sink.text( label ); - safeItalic_(); - } - } - if ( someNotAllowed ) - { - sink.lineBreak(); - sink.lineBreak(); - sink.text( "* " ); - safeItalic(); - sink.text( getText( "report.excludedVersion" ) ); - safeItalic_(); - } - sink.tableCell_(); - sink.tableRow_(); - } - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.versionRange" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( StringUtils.isEmpty( property.getVersion() ) ? "[,)" : property.getVersion() ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.autoLinkDependencies" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( property.isAutoLinkDependencies() ? getText( "report.yes" ) : getText( "report.no" ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.banSnapshots" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( property.isBanSnapshots() ? getText( "report.yes" ) : getText( "report.no" ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.searchReactor" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( property.isSearchReactor() ? getText( "report.yes" ) : getText( "report.no" ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableHeaderCell( headerAttributes ); - sink.text( getText( "report.preferReactor" ) ); - sink.tableHeaderCell_(); - sink.tableCell( cellAttributes ); - sink.text( property.isPreferReactor() ? getText( "report.yes" ) : getText( "report.no" ) ); - sink.tableCell_(); - sink.tableRow_(); - - sink.tableRows_(); - sink.table_(); - } - - private Set getVersionsInRange( Property property, PropertyVersions versions, - ArtifactVersion[] artifactVersions ) - { - VersionRange range; - Set rangeVersions = new HashSet<>(); - ArtifactVersion[] tmp; - if ( property.getVersion() != null ) - { - try - { - range = VersionRange.createFromVersionSpec( property.getVersion() ); - tmp = versions.getAllUpdates( range ); - } - catch ( InvalidVersionSpecificationException e ) - { - tmp = artifactVersions; - } - } - else - { - tmp = artifactVersions; - } - for ( ArtifactVersion artifactVersion : tmp ) - { - rangeVersions.add( artifactVersion.toString() ); - } - return rangeVersions; - } - - protected String getLabel( ArtifactVersion version, AbstractVersionDetails versions ) - { - if ( equals( version, versions.getNewestUpdate( of( SUBINCREMENTAL ) ) ) ) - { - return getText( "report.latestSubIncremental" ); - } - - if ( equals( version, versions.getOldestUpdate( of( SUBINCREMENTAL ) ) ) ) - { - return getText( "report.nextVersion" ); - } - - if ( equals( version, versions.getOldestUpdate( of( INCREMENTAL ) ) ) ) - { - return getText( "report.nextIncremental" ); - } - - if ( equals( version, versions.getNewestUpdate( of( INCREMENTAL ) ) ) ) - { - return getText( "report.latestIncremental" ); - } - - if ( equals( version, versions.getOldestUpdate( of( MINOR ) ) ) ) - { - return getText( "report.nextMinor" ); - } - - if ( equals( version, versions.getNewestUpdate( of( MINOR ) ) ) ) - { - return getText( "report.latestMinor" ); - } - - if ( equals( version, versions.getOldestUpdate( of( MAJOR ) ) ) ) - { - return getText( "report.nextMajor" ); - } - - if ( equals( version, versions.getNewestUpdate( of( MAJOR ) ) ) ) - { - return getText( "report.latestMajor" ); - } - - return ""; - } - -} diff --git a/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesRenderer.java b/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesRenderer.java deleted file mode 100644 index d1d6b807af..0000000000 --- a/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesRenderer.java +++ /dev/null @@ -1,226 +0,0 @@ -package org.codehaus.mojo.versions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.util.Locale; -import java.util.Map; -import java.util.TreeMap; - -import org.apache.maven.artifact.ArtifactUtils; -import org.apache.maven.doxia.sink.Sink; -import org.apache.maven.model.Dependency; -import org.codehaus.mojo.versions.api.ArtifactVersions; -import org.codehaus.mojo.versions.utils.DependencyComparator; -import org.codehaus.plexus.i18n.I18N; - -import static java.util.Optional.of; -import static org.codehaus.mojo.versions.api.Segment.INCREMENTAL; -import static org.codehaus.mojo.versions.api.Segment.MAJOR; -import static org.codehaus.mojo.versions.api.Segment.MINOR; -import static org.codehaus.mojo.versions.api.Segment.SUBINCREMENTAL; - -/** - * @since 1.0-beta-1 - */ -public class DependencyUpdatesRenderer - extends AbstractVersionsReportRenderer -{ - - private final Map dependencyUpdates; - - private final Map dependencyManagementUpdates; - - public DependencyUpdatesRenderer( Sink sink, I18N i18n, String bundleName, Locale locale, - Map dependencyUpdates, - Map dependencyManagementUpdates ) - { - super( sink, bundleName, i18n, locale ); - this.dependencyUpdates = dependencyUpdates; - this.dependencyManagementUpdates = dependencyManagementUpdates; - } - - protected void renderBody() - { - Map allUpdates = new TreeMap<>( new DependencyComparator() ); - allUpdates.putAll( dependencyManagementUpdates ); - allUpdates.putAll( dependencyUpdates ); - - sink.section1(); - sink.sectionTitle1(); - sink.text( getText( "report.overview.title" ) ); - sink.sectionTitle1_(); - sink.paragraph(); - sink.text( getText( "report.overview.text" ) ); - sink.paragraph_(); - - renderSummaryTotalsTable( allUpdates ); - - renderDependencyManagementSummary(); - - renderDependencySummary(); - - sink.section1_(); - - sink.section1(); - sink.sectionTitle1(); - sink.text( getText( "report.detail.title" ) ); - sink.sectionTitle1_(); - sink.paragraph(); - sink.text( getText( "report.detail.text" ) ); - sink.paragraph_(); - - for ( Map.Entry entry : allUpdates.entrySet() ) - { - renderDependencyDetail( entry.getKey(), entry.getValue() ); - } - sink.section1_(); - } - - protected void renderDependencySummary() - { - renderSummaryTable( "report.overview.dependency", dependencyUpdates, "report.overview.noDependency" ); - } - - protected void renderDependencyManagementSummary() - { - renderSummaryTable( "report.overview.dependencyManagement", dependencyManagementUpdates, - "report.overview.noDependencyManagement" ); - } - - protected void renderSummaryTable( String titleKey, Map contents, String emptyKey ) - { - sink.section2(); - sink.sectionTitle2(); - sink.text( getText( titleKey ) ); - sink.sectionTitle2_(); - - if ( contents.isEmpty() ) - { - sink.paragraph(); - sink.text( getText( emptyKey ) ); - sink.paragraph_(); - } - else - { - renderDependencySummaryTable( contents ); - } - sink.section2_(); - } - - protected void renderSummaryTotalsTable( Map allUpdates ) - { - int numInc = 0; - int numMin = 0; - int numMaj = 0; - int numAny = 0; - int numCur = 0; - for ( ArtifactVersions details : allUpdates.values() ) - { - if ( details.getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) - { - numAny++; - } - else if ( details.getOldestUpdate( of( INCREMENTAL ) ) != null ) - { - numInc++; - } - else if ( details.getOldestUpdate( of( MINOR ) ) != null ) - { - numMin++; - } - else if ( details.getOldestUpdate( of( MAJOR ) ) != null ) - { - numMaj++; - } - else - { - numCur++; - } - } - sink.table(); - sink.tableRow(); - sink.tableCell(); - renderSuccessIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numUpToDate" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numCur ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerVersionAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numAny ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerIncrementalAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numInc ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerMinorAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numMin ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerMajorAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numMaj ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.table_(); - } - - protected void renderDependencyDetail( Dependency dependency, ArtifactVersions details ) - { - sink.section2(); - sink.sectionTitle2(); - sink.text( ArtifactUtils.versionlessKey( dependency.getGroupId(), dependency.getArtifactId() ) ); - sink.sectionTitle2_(); - renderDependencyDetailTable( dependency, details ); - sink.section2_(); - } - -} diff --git a/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesReport.java b/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesReportMojo.java similarity index 89% rename from src/main/java/org/codehaus/mojo/versions/DependencyUpdatesReport.java rename to src/main/java/org/codehaus/mojo/versions/DependencyUpdatesReportMojo.java index 80b66a0607..e38a2285e7 100644 --- a/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesReport.java +++ b/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesReportMojo.java @@ -39,6 +39,9 @@ import org.apache.maven.reporting.MavenReportException; import org.apache.maven.repository.RepositorySystem; import org.codehaus.mojo.versions.api.ArtifactVersions; +import org.codehaus.mojo.versions.xml.DependencyUpdatesXmlRenderer; +import org.codehaus.mojo.versions.reporting.ReportRendererFactory; +import org.codehaus.mojo.versions.reporting.model.DependencyUpdatesModel; import org.codehaus.mojo.versions.utils.DependencyComparator; import org.codehaus.plexus.i18n.I18N; @@ -52,8 +55,8 @@ * @since 1.0-beta-1 */ @Mojo( name = "dependency-updates-report", - requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true ) -public class DependencyUpdatesReport extends AbstractVersionsReport + requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = false ) +public class DependencyUpdatesReportMojo extends AbstractVersionsReport { /** @@ -101,10 +104,12 @@ public class DependencyUpdatesReport extends AbstractVersionsReport protected boolean onlyUpgradable; @Inject - protected DependencyUpdatesReport( I18N i18n, RepositorySystem repositorySystem, ArtifactResolver artifactResolver, - ArtifactMetadataSource artifactMetadataSource, WagonManager wagonManager ) + protected DependencyUpdatesReportMojo( I18N i18n, RepositorySystem repositorySystem, + ArtifactResolver artifactResolver, + ArtifactMetadataSource artifactMetadataSource, WagonManager wagonManager, + ReportRendererFactory rendererFactory ) { - super( i18n, repositorySystem, artifactResolver, artifactMetadataSource, wagonManager ); + super( i18n, repositorySystem, artifactResolver, artifactMetadataSource, wagonManager, rendererFactory ); } /** @@ -132,10 +137,10 @@ public boolean canGenerateReport() @SuppressWarnings( "deprecation" ) protected void doGenerateReport( Locale locale, Sink sink ) throws MavenReportException { - Set dependencies = new TreeSet<>( new DependencyComparator() ); + Set dependencies = new TreeSet<>( DependencyComparator.INSTANCE ); dependencies.addAll( getProject().getDependencies() ); - Set dependencyManagement = new TreeSet<>( new DependencyComparator() ); + Set dependencyManagement = new TreeSet<>( DependencyComparator.INSTANCE ); if ( processDependencyManagement ) { @@ -202,11 +207,9 @@ && getProject().getOriginalModel().getDependencyManagement().getDependencies() ! { if ( "html".equals( format ) ) { - DependencyUpdatesRenderer renderer = - new DependencyUpdatesRenderer( sink, getI18n(), getOutputName(), locale, dependencyUpdates, - dependencyManagementUpdates ); - renderer.render(); - + rendererFactory.createReportRenderer( getOutputName(), sink, locale, + new DependencyUpdatesModel( dependencyUpdates, dependencyManagementUpdates ) ) + .render(); } else if ( "xml".equals( format ) ) { @@ -254,5 +257,5 @@ public String getOutputName() { return "dependency-updates-report"; } - } + diff --git a/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java b/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java index a34235cfa5..5227465810 100644 --- a/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java +++ b/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java @@ -355,7 +355,7 @@ public DisplayDependencyUpdatesMojo( RepositorySystem repositorySystem, private static Set extractPluginDependenciesFromPluginsInPluginManagement( Build build ) { - Set result = new TreeSet<>( new DependencyComparator() ); + Set result = new TreeSet<>( DependencyComparator.INSTANCE ); if ( build.getPluginManagement() != null ) { for ( Plugin plugin : build.getPluginManagement().getPlugins() ) @@ -371,7 +371,7 @@ private static Set extractPluginDependenciesFromPluginsInPluginManag private static Set extractDependenciesFromPlugins( List plugins ) { - Set result = new TreeSet<>( new DependencyComparator() ); + Set result = new TreeSet<>( DependencyComparator.INSTANCE ); for ( Plugin plugin : plugins ) { if ( plugin.getDependencies() != null && !plugin.getDependencies().isEmpty() ) @@ -395,7 +395,7 @@ private static Set extractDependenciesFromPlugins( List plug private static Set removeDependencyManagment( Set dependencies, Set dependencyManagement ) { - Set result = new TreeSet<>( new DependencyComparator() ); + Set result = new TreeSet<>( DependencyComparator.INSTANCE ); for ( Dependency dependency : dependencies ) { boolean matched = false; @@ -488,7 +488,7 @@ public void execute() validateInput(); - Set dependencyManagement = new TreeSet<>( new DependencyComparator() ); + Set dependencyManagement = new TreeSet<>( DependencyComparator.INSTANCE ); DependencyManagement projectDependencyManagement = getProjectDependencyManagement( getProject() ); if ( projectDependencyManagement != null ) { @@ -537,7 +537,7 @@ public void execute() } } - Set dependencies = new TreeSet<>( new DependencyComparator() ); + Set dependencies = new TreeSet<>( DependencyComparator.INSTANCE ); dependencies.addAll( getProject().getDependencies() ); if ( isProcessingDependencyManagement() ) @@ -545,14 +545,14 @@ public void execute() dependencies = removeDependencyManagment( dependencies, dependencyManagement ); } - Set pluginDependencies = new TreeSet<>( new DependencyComparator() ); + Set pluginDependencies = new TreeSet<>( DependencyComparator.INSTANCE ); if ( isProcessingPluginDependencies() ) { pluginDependencies = extractDependenciesFromPlugins( getProject().getBuildPlugins() ); } - Set pluginDependenciesInPluginManagement = new TreeSet<>( new DependencyComparator() ); + Set pluginDependenciesInPluginManagement = new TreeSet<>( DependencyComparator.INSTANCE ); if ( isProcessPluginDependenciesInDependencyManagement() ) { pluginDependenciesInPluginManagement = diff --git a/src/main/java/org/codehaus/mojo/versions/DisplayPluginUpdatesMojo.java b/src/main/java/org/codehaus/mojo/versions/DisplayPluginUpdatesMojo.java index 78c08f721c..fe15039f7c 100644 --- a/src/main/java/org/codehaus/mojo/versions/DisplayPluginUpdatesMojo.java +++ b/src/main/java/org/codehaus/mojo/versions/DisplayPluginUpdatesMojo.java @@ -1645,7 +1645,7 @@ private Set getProjectPlugins( Map superPomPluginManagem } debugPluginMap( "after adding reporting plugins for profile " + profile.getId(), plugins ); } - Set result = new TreeSet<>( new PluginComparator() ); + Set result = new TreeSet<>( PluginComparator.INSTANCE ); result.addAll( plugins.values() ); return result; } @@ -1702,7 +1702,7 @@ private void debugPluginMap( String description, Map plugins ) { if ( getLog().isDebugEnabled() ) { - Set sorted = new TreeSet<>( new PluginComparator() ); + Set sorted = new TreeSet<>( PluginComparator.INSTANCE ); sorted.addAll( plugins.values() ); StringBuilder buf = new StringBuilder( description ); for ( Plugin plugin : sorted ) diff --git a/src/main/java/org/codehaus/mojo/versions/ParentUpdatesReport.java b/src/main/java/org/codehaus/mojo/versions/ParentUpdatesReportMojo.java similarity index 70% rename from src/main/java/org/codehaus/mojo/versions/ParentUpdatesReport.java rename to src/main/java/org/codehaus/mojo/versions/ParentUpdatesReportMojo.java index cbc99740f3..f625217fdc 100644 --- a/src/main/java/org/codehaus/mojo/versions/ParentUpdatesReport.java +++ b/src/main/java/org/codehaus/mojo/versions/ParentUpdatesReportMojo.java @@ -23,14 +23,12 @@ import java.util.List; import java.util.Locale; -import java.util.Map; import org.apache.maven.artifact.manager.WagonManager; import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.doxia.sink.Sink; -import org.apache.maven.model.Dependency; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; @@ -38,12 +36,11 @@ import org.apache.maven.reporting.MavenReportException; import org.apache.maven.repository.RepositorySystem; import org.codehaus.mojo.versions.api.ArtifactVersions; +import org.codehaus.mojo.versions.reporting.ReportRendererFactory; +import org.codehaus.mojo.versions.reporting.model.ParentUpdatesModel; import org.codehaus.mojo.versions.utils.DependencyBuilder; import org.codehaus.plexus.i18n.I18N; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; - /** * Generates a report on available updates for parent artifacts * @@ -52,16 +49,17 @@ */ @Mojo( name = "parent-updates-report", requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = false ) -public class ParentUpdatesReport extends AbstractVersionsReport +public class ParentUpdatesReportMojo extends AbstractVersionsReport { @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true ) protected List reactorProjects; @Inject - protected ParentUpdatesReport( I18N i18n, RepositorySystem repositorySystem, ArtifactResolver artifactResolver, - ArtifactMetadataSource artifactMetadataSource, WagonManager wagonManager ) + protected ParentUpdatesReportMojo( I18N i18n, RepositorySystem repositorySystem, ArtifactResolver artifactResolver, + ArtifactMetadataSource artifactMetadataSource, WagonManager wagonManager, + ReportRendererFactory rendererFactory ) { - super( i18n, repositorySystem, artifactResolver, artifactMetadataSource, wagonManager ); + super( i18n, repositorySystem, artifactResolver, artifactMetadataSource, wagonManager, rendererFactory ); } /** @@ -106,28 +104,16 @@ protected void doGenerateReport( Locale locale, Sink sink ) throws MavenReportEx ArtifactVersions artifactVersions = getHelper().lookupArtifactVersions( project.getParentArtifact(), false ); artifactVersions.setIncludeSnapshots( allowSnapshots ); - Dependency parent = DependencyBuilder.newBuilder() - .withGroupId( artifactVersions.getGroupId() ) - .withArtifactId( artifactVersions.getArtifactId() ) - .withVersion( artifactVersions.getArtifact().getVersion() ) - .withScope( artifactVersions.getArtifact().getScope() ) - .withType( artifactVersions.getArtifact().getType() ) - .withClassifier( artifactVersions.getArtifact().getClassifier() ) - .build(); - new DependencyUpdatesRenderer( sink, getI18n(), getOutputName(), locale, - singletonMap( parent, artifactVersions ), emptyMap() ) - { - @Override - protected void renderSummaryTotalsTable( Map allUpdates ) - { - } - - @Override - protected void renderDependencyManagementSummary() - { - } - } - .renderBody(); + rendererFactory.createReportRenderer( getOutputName(), sink, locale, + new ParentUpdatesModel( DependencyBuilder.newBuilder() + .withGroupId( artifactVersions.getGroupId() ) + .withArtifactId( artifactVersions.getArtifactId() ) + .withVersion( artifactVersions.getArtifact().getVersion() ) + .withScope( artifactVersions.getArtifact().getScope() ) + .withType( artifactVersions.getArtifact().getType() ) + .withClassifier( artifactVersions.getArtifact().getClassifier() ) + .build(), artifactVersions ) ) + .render(); } catch ( ArtifactMetadataRetrievalException e ) { diff --git a/src/main/java/org/codehaus/mojo/versions/PluginUpdatesDetails.java b/src/main/java/org/codehaus/mojo/versions/PluginUpdatesDetails.java index a4fd2db234..84842b57ef 100644 --- a/src/main/java/org/codehaus/mojo/versions/PluginUpdatesDetails.java +++ b/src/main/java/org/codehaus/mojo/versions/PluginUpdatesDetails.java @@ -31,10 +31,8 @@ /** * Details of a plugin's updates. */ -public class PluginUpdatesDetails +public class PluginUpdatesDetails extends ArtifactVersions { - private final ArtifactVersions artifactVersions; - private final Map dependencyVersions; private final boolean includeSnapshots; @@ -42,18 +40,14 @@ public class PluginUpdatesDetails public PluginUpdatesDetails( ArtifactVersions artifactVersions, Map dependencyVersions, boolean includeSnapshots ) { + super( artifactVersions ); Objects.requireNonNull( artifactVersions ); Objects.requireNonNull( dependencyVersions ); - this.artifactVersions = artifactVersions; + this.dependencyVersions = dependencyVersions; this.includeSnapshots = includeSnapshots; } - public ArtifactVersions getArtifactVersions() - { - return artifactVersions; - } - public Map getDependencyVersions() { return dependencyVersions; @@ -66,7 +60,8 @@ public Map getDependencyVersions() */ public boolean isArtifactUpdateAvailable() { - return artifactVersions.getAllUpdates( empty(), includeSnapshots ).length > 0; + ArtifactVersion[] updates = getAllUpdates( empty(), includeSnapshots ); + return updates != null && updates.length > 0; } /** @@ -76,15 +71,11 @@ public boolean isArtifactUpdateAvailable() */ public boolean isDependencyUpdateAvailable() { - for ( ArtifactVersions versions : dependencyVersions.values() ) + return dependencyVersions.values().stream().anyMatch( versions -> { ArtifactVersion[] dependencyUpdates = versions.getAllUpdates( empty(), includeSnapshots ); - if ( dependencyUpdates != null && dependencyUpdates.length > 0 ) - { - return true; - } - } - return false; + return dependencyUpdates != null && dependencyUpdates.length > 0; + } ); } /** diff --git a/src/main/java/org/codehaus/mojo/versions/PluginUpdatesReport.java b/src/main/java/org/codehaus/mojo/versions/PluginUpdatesReportMojo.java similarity index 85% rename from src/main/java/org/codehaus/mojo/versions/PluginUpdatesReport.java rename to src/main/java/org/codehaus/mojo/versions/PluginUpdatesReportMojo.java index 01c6409218..71b8524029 100644 --- a/src/main/java/org/codehaus/mojo/versions/PluginUpdatesReport.java +++ b/src/main/java/org/codehaus/mojo/versions/PluginUpdatesReportMojo.java @@ -38,6 +38,9 @@ import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.reporting.MavenReportException; import org.apache.maven.repository.RepositorySystem; +import org.codehaus.mojo.versions.xml.PluginUpdatesXmlRenderer; +import org.codehaus.mojo.versions.reporting.ReportRendererFactory; +import org.codehaus.mojo.versions.reporting.model.PluginUpdatesModel; import org.codehaus.mojo.versions.utils.PluginComparator; import org.codehaus.plexus.i18n.I18N; @@ -50,8 +53,8 @@ * @since 1.0-beta-1 */ @Mojo( name = "plugin-updates-report", requiresDependencyResolution = ResolutionScope.RUNTIME, - threadSafe = true ) -public class PluginUpdatesReport extends AbstractVersionsReport + threadSafe = false ) +public class PluginUpdatesReportMojo extends AbstractVersionsReport { /** @@ -78,10 +81,11 @@ public class PluginUpdatesReport extends AbstractVersionsReport protected boolean onlyUpgradable; @Inject - protected PluginUpdatesReport( I18N i18n, RepositorySystem repositorySystem, ArtifactResolver artifactResolver, - ArtifactMetadataSource artifactMetadataSource, WagonManager wagonManager ) + protected PluginUpdatesReportMojo( I18N i18n, RepositorySystem repositorySystem, ArtifactResolver artifactResolver, + ArtifactMetadataSource artifactMetadataSource, WagonManager wagonManager, + ReportRendererFactory rendererFactory ) { - super( i18n, repositorySystem, artifactResolver, artifactMetadataSource, wagonManager ); + super( i18n, repositorySystem, artifactResolver, artifactMetadataSource, wagonManager, rendererFactory ); } /** @@ -121,19 +125,19 @@ private boolean haveBuildPlugins() */ protected void doGenerateReport( Locale locale, Sink sink ) throws MavenReportException { - Set pluginManagement = new TreeSet<>( new PluginComparator() ); + Set pluginManagement = new TreeSet<>( PluginComparator.INSTANCE ); if ( haveBuildPluginManagementPlugins() ) { pluginManagement.addAll( getProject().getBuild().getPluginManagement().getPlugins() ); } - Set plugins = new TreeSet<>( new PluginComparator() ); + Set plugins = new TreeSet<>( PluginComparator.INSTANCE ); if ( haveBuildPlugins() ) { plugins.addAll( getProject().getBuild().getPlugins() ); } - PluginComparator comparator = new PluginComparator(); + PluginComparator comparator = PluginComparator.INSTANCE; if ( !onlyProjectPlugins ) { // Retains only plugins not present in pluginManagement @@ -157,19 +161,18 @@ protected void doGenerateReport( Locale locale, Sink sink ) throws MavenReportEx if ( onlyUpgradable ) { pluginUpdates = - filter( pluginUpdates, plugin -> plugin.getArtifactVersions().getVersions().length > 1 ); + filter( pluginUpdates, plugin -> plugin.getVersions().length > 1 ); pluginManagementUpdates = filter( pluginManagementUpdates, - plugin -> plugin.getArtifactVersions().getVersions().length > 1 ); + plugin -> plugin.getVersions().length > 1 ); } for ( String format : formats ) { if ( "html".equals( format ) ) { - PluginUpdatesRenderer renderer = - new PluginUpdatesRenderer( sink, getI18n(), getOutputName(), locale, pluginUpdates, - pluginManagementUpdates ); - renderer.render(); + rendererFactory.createReportRenderer( getOutputName(), getSink(), locale, + new PluginUpdatesModel( pluginUpdates, pluginManagementUpdates ) ) + .render(); } else if ( "xml".equals( format ) ) { @@ -201,5 +204,5 @@ public String getOutputName() { return "plugin-updates-report"; } - } + diff --git a/src/main/java/org/codehaus/mojo/versions/PropertyUpdatesRenderer.java b/src/main/java/org/codehaus/mojo/versions/PropertyUpdatesRenderer.java deleted file mode 100644 index b3d4686bb6..0000000000 --- a/src/main/java/org/codehaus/mojo/versions/PropertyUpdatesRenderer.java +++ /dev/null @@ -1,206 +0,0 @@ -package org.codehaus.mojo.versions; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.util.Locale; -import java.util.Map; -import java.util.TreeMap; - -import org.apache.maven.doxia.sink.Sink; -import org.codehaus.mojo.versions.api.PropertyVersions; -import org.codehaus.mojo.versions.utils.PropertyComparator; -import org.codehaus.plexus.i18n.I18N; - -import static java.util.Optional.of; -import static org.codehaus.mojo.versions.api.Segment.INCREMENTAL; -import static org.codehaus.mojo.versions.api.Segment.MAJOR; -import static org.codehaus.mojo.versions.api.Segment.MINOR; -import static org.codehaus.mojo.versions.api.Segment.SUBINCREMENTAL; - -/** - * @since 1.0-beta-1 - */ -public class PropertyUpdatesRenderer - extends AbstractVersionsReportRenderer -{ - - private final Map propertyUpdates; - - public PropertyUpdatesRenderer( Sink sink, I18N i18n, String bundleName, Locale locale, - Map propertyUpdates ) - { - super( sink, bundleName, i18n, locale ); - this.propertyUpdates = propertyUpdates; - } - - protected void renderBody() - { - Map allUpdates = new TreeMap<>( new PropertyComparator() ); - allUpdates.putAll( propertyUpdates ); - - sink.section1(); - sink.sectionTitle1(); - sink.text( getText( "report.overview.title" ) ); - sink.sectionTitle1_(); - sink.paragraph(); - sink.text( getText( "report.overview.text" ) ); - sink.paragraph_(); - - renderSummaryTotalsTable( allUpdates ); - - renderSummaryTable( "report.overview.property", propertyUpdates, "report.overview.noProperty" ); - - sink.section1_(); - - sink.section1(); - sink.sectionTitle1(); - sink.text( getText( "report.detail.title" ) ); - sink.sectionTitle1_(); - sink.paragraph(); - sink.text( getText( "report.detail.text" ) ); - sink.paragraph_(); - - for ( final Map.Entry entry : allUpdates.entrySet() ) - { - renderPropertyDetail( entry.getKey(), entry.getValue() ); - } - sink.section1_(); - } - - private void renderSummaryTable( String titleKey, Map contents, String emptyKey ) - { - sink.section2(); - sink.sectionTitle2(); - sink.text( getText( titleKey ) ); - sink.sectionTitle2_(); - - if ( contents.isEmpty() ) - { - sink.paragraph(); - sink.text( getText( emptyKey ) ); - sink.paragraph_(); - } - else - { - renderPropertySummaryTable( contents ); - } - sink.section2_(); - } - - private void renderSummaryTotalsTable( Map allUpdates ) - { - int numInc = 0; - int numMin = 0; - int numMaj = 0; - int numAny = 0; - int numCur = 0; - for ( PropertyVersions details : allUpdates.values() ) - { - if ( details.getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) - { - numAny++; - } - else if ( details.getOldestUpdate( of( INCREMENTAL ) ) != null ) - { - numInc++; - } - else if ( details.getOldestUpdate( of( MINOR ) ) != null ) - { - numMin++; - } - else if ( details.getOldestUpdate( of( MAJOR ) ) != null ) - { - numMaj++; - } - else - { - numCur++; - } - } - sink.table(); - sink.tableRow(); - sink.tableCell(); - renderSuccessIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numUpToDate" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numCur ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerVersionAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numAny ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerIncrementalAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numInc ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerMinorAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numMin ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerMajorAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numMaj ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.table_(); - } - - private void renderPropertyDetail( Property property, PropertyVersions versions ) - { - sink.section2(); - sink.sectionTitle2(); - sink.text( "${" + property.getName() + "" ); - sink.sectionTitle2_(); - renderPropertyDetailTable( property, versions ); - sink.section2_(); - } - -} diff --git a/src/main/java/org/codehaus/mojo/versions/PropertyUpdatesReport.java b/src/main/java/org/codehaus/mojo/versions/PropertyUpdatesReportMojo.java similarity index 82% rename from src/main/java/org/codehaus/mojo/versions/PropertyUpdatesReport.java rename to src/main/java/org/codehaus/mojo/versions/PropertyUpdatesReportMojo.java index 4093b70c3e..18bb30e001 100644 --- a/src/main/java/org/codehaus/mojo/versions/PropertyUpdatesReport.java +++ b/src/main/java/org/codehaus/mojo/versions/PropertyUpdatesReportMojo.java @@ -36,6 +36,8 @@ import org.apache.maven.reporting.MavenReportException; import org.apache.maven.repository.RepositorySystem; import org.codehaus.mojo.versions.api.PropertyVersions; +import org.codehaus.mojo.versions.reporting.ReportRendererFactory; +import org.codehaus.mojo.versions.reporting.model.PropertyUpdatesModel; import org.codehaus.mojo.versions.utils.PropertyComparator; import org.codehaus.plexus.i18n.I18N; @@ -47,11 +49,9 @@ * @since 1.0-beta-1 */ @Mojo( name = "property-updates-report", requiresDependencyResolution = ResolutionScope.RUNTIME, - threadSafe = true ) -public class PropertyUpdatesReport - extends AbstractVersionsReport + threadSafe = false ) +public class PropertyUpdatesReportMojo extends AbstractVersionsReport { - /** * Any restrictions that apply to specific properties. * @@ -85,10 +85,12 @@ public class PropertyUpdatesReport private boolean autoLinkItems; @Inject - protected PropertyUpdatesReport( I18N i18n, RepositorySystem repositorySystem, ArtifactResolver artifactResolver, - ArtifactMetadataSource artifactMetadataSource, WagonManager wagonManager ) + protected PropertyUpdatesReportMojo( I18N i18n, RepositorySystem repositorySystem, + ArtifactResolver artifactResolver, + ArtifactMetadataSource artifactMetadataSource, WagonManager wagonManager, + ReportRendererFactory rendererFactory ) { - super( i18n, repositorySystem, artifactResolver, artifactMetadataSource, wagonManager ); + super( i18n, repositorySystem, artifactResolver, artifactMetadataSource, wagonManager, rendererFactory ); } /** @@ -115,7 +117,7 @@ private boolean haveBuildProperties() protected void doGenerateReport( Locale locale, Sink sink ) throws MavenReportException { - final Map updateSet = new TreeMap<>( new PropertyComparator() ); + final Map updateSet = new TreeMap<>( PropertyComparator.INSTANCE ); try { updateSet.putAll( getHelper().getVersionPropertiesMap( getProject(), properties, includeProperties, @@ -125,9 +127,8 @@ protected void doGenerateReport( Locale locale, Sink sink ) { throw new MavenReportException( e.getMessage(), e ); } - PropertyUpdatesRenderer renderer = - new PropertyUpdatesRenderer( sink, getI18n(), getOutputName(), locale, updateSet ); - renderer.render(); + rendererFactory.createReportRenderer( getOutputName(), getSink(), locale, + new PropertyUpdatesModel( updateSet ) ).render(); } /** @@ -138,3 +139,4 @@ public String getOutputName() return "property-updates-report"; } } + diff --git a/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java b/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java index e5d9df192a..db28d1e990 100644 --- a/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java +++ b/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java @@ -30,6 +30,8 @@ import org.apache.maven.artifact.versioning.VersionRange; import org.codehaus.mojo.versions.ordering.VersionComparator; +import static org.apache.commons.lang3.StringUtils.compare; + /** * Holds the results of a search for versions of an artifact. * @@ -37,7 +39,7 @@ * @since 1.0-alpha-3 */ public class ArtifactVersions - extends AbstractVersionDetails + extends AbstractVersionDetails implements Comparable { /** * The artifact that who's versions we hold details of. @@ -80,6 +82,36 @@ public ArtifactVersions( Artifact artifact, List versions, Vers } } + /** + * Creates a new {@link ArtifactVersions} instance as shallow copy of the other + * + * @param other other object to be linked to + * @since 2.13.0 + */ + public ArtifactVersions( ArtifactVersions other ) + { + artifact = other.artifact; + versionComparator = other.versionComparator; + versions = other.versions; + setCurrentVersion( other.getCurrentVersion() ); + setIncludeSnapshots( other.isIncludeSnapshots() ); + } + + @SuppressWarnings( "checkstyle:InnerAssignment" ) + public int compareTo( ArtifactVersions that ) + { + int rv; + return this == that + ? 0 + : that == null || getClass() != that.getClass() + ? 1 + : ( rv = compare( getGroupId(), that.getGroupId() ) ) != 0 + ? rv + : ( rv = compare( getArtifactId(), that.getArtifactId() ) ) != 0 + ? rv + : compare( getVersion(), that.getVersion() ); + } + /** * Checks if the version is in the range (and ensures that the range respects the -! syntax to rule out * any qualifiers from range boundaries). @@ -134,7 +166,7 @@ public Artifact getArtifact() } /** - * Returns the groupId of the artifact who's versions we are holding. + * Returns the groupId of the artifact which versions we are holding. * * @return the groupId. * @since 1.0-alpha-3 @@ -145,7 +177,7 @@ public String getGroupId() } /** - * Returns the artifactId of the artifact who's versions we are holding. + * Returns the artifactId of the artifact which versions we are holding. * * @return the artifactId. * @since 1.0-alpha-3 @@ -155,6 +187,17 @@ public String getArtifactId() return getArtifact().getArtifactId(); } + /** + * Returns the artifactId of the artifact which versions we are holding. + * + * @return current version + * @since 2.13.0 + */ + public String getVersion() + { + return getArtifact().getVersion(); + } + public ArtifactVersion[] getVersions( boolean includeSnapshots ) { return includeSnapshots diff --git a/src/main/java/org/codehaus/mojo/versions/api/DefaultArtifactAssociation.java b/src/main/java/org/codehaus/mojo/versions/api/DefaultArtifactAssociation.java index f612462f07..e75ee3525b 100644 --- a/src/main/java/org/codehaus/mojo/versions/api/DefaultArtifactAssociation.java +++ b/src/main/java/org/codehaus/mojo/versions/api/DefaultArtifactAssociation.java @@ -54,6 +54,7 @@ public String getArtifactId() return artifact.getArtifactId(); } + public Artifact getArtifact() { return artifact; diff --git a/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java b/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java index a7685eeccf..947333b60b 100644 --- a/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java +++ b/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java @@ -311,7 +311,7 @@ private static RuleSet getRulesViaWagon( String rulesUri, Log logger, String ser WagonManager wagonManager, Settings settings ) throws MojoExecutionException { - RuleSet loadedRules = new RuleSet(); + RuleSet loadedRules; int split = rulesUri.lastIndexOf( '/' ); String baseUri = rulesUri; @@ -681,7 +681,7 @@ public Map lookupDependenciesUpdates( Set dependencyUpdates = new TreeMap<>( new DependencyComparator() ); + final Map dependencyUpdates = new TreeMap<>( DependencyComparator.INSTANCE ); // Lookup details in parallel... final ExecutorService executor = Executors.newFixedThreadPool( LOOKUP_PARALLEL_THREADS ); @@ -731,7 +731,7 @@ public Map lookupPluginsUpdates( Set plugi requestsForDetails.add( new PluginLookup( plugin, allowSnapshots ) ); } - Map pluginUpdates = new TreeMap<>( new PluginComparator() ); + Map pluginUpdates = new TreeMap<>( PluginComparator.INSTANCE ); // Lookup details in parallel... ExecutorService executor = Executors.newFixedThreadPool( LOOKUP_PARALLEL_THREADS ); @@ -768,13 +768,11 @@ public PluginUpdatesDetails lookupPluginUpdates( Plugin plugin, boolean allowSna getLog().debug( "Checking " + ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() ) + " for updates newer than " + version ); - boolean includeSnapshots = allowSnapshots; - final ArtifactVersions pluginArtifactVersions = lookupArtifactVersions( createPluginArtifact( plugin.getGroupId(), plugin.getArtifactId(), version ), true ); - Set pluginDependencies = new TreeSet<>( new DependencyComparator() ); + Set pluginDependencies = new TreeSet<>( DependencyComparator.INSTANCE ); if ( plugin.getDependencies() != null ) { pluginDependencies.addAll( plugin.getDependencies() ); @@ -782,7 +780,7 @@ public PluginUpdatesDetails lookupPluginUpdates( Plugin plugin, boolean allowSna Map pluginDependencyDetails = lookupDependenciesUpdates( pluginDependencies, false ); - return new PluginUpdatesDetails( pluginArtifactVersions, pluginDependencyDetails, includeSnapshots ); + return new PluginUpdatesDetails( pluginArtifactVersions, pluginDependencyDetails, allowSnapshots ); } @Override diff --git a/src/main/java/org/codehaus/mojo/versions/api/ReportRenderer.java b/src/main/java/org/codehaus/mojo/versions/api/ReportRenderer.java new file mode 100644 index 0000000000..376985ef93 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/api/ReportRenderer.java @@ -0,0 +1,31 @@ +package org.codehaus.mojo.versions.api; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Common interface for reporting components + */ +public interface ReportRenderer +{ + /** + * Renders the report + */ + void render(); +} diff --git a/src/main/java/org/codehaus/mojo/versions/filtering/DependencyFilter.java b/src/main/java/org/codehaus/mojo/versions/filtering/DependencyFilter.java index af021add5f..07bf61617e 100644 --- a/src/main/java/org/codehaus/mojo/versions/filtering/DependencyFilter.java +++ b/src/main/java/org/codehaus/mojo/versions/filtering/DependencyFilter.java @@ -62,6 +62,6 @@ private TreeSet filterBy( Set dependencies, Predicate new TreeSet<>( new DependencyComparator() ) ) ); + .collect( Collectors.toCollection( () -> new TreeSet<>( DependencyComparator.INSTANCE ) ) ); } } diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/AbstractVersionsReportRenderer.java b/src/main/java/org/codehaus/mojo/versions/reporting/AbstractVersionsReportRenderer.java new file mode 100644 index 0000000000..2d52e0565a --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/AbstractVersionsReportRenderer.java @@ -0,0 +1,457 @@ +package org.codehaus.mojo.versions.reporting; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Arrays; +import java.util.Locale; +import java.util.Map; + +import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.doxia.sink.Sink; +import org.apache.maven.doxia.sink.SinkEventAttributes; +import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; +import org.apache.maven.model.Dependency; +import org.codehaus.mojo.versions.api.ArtifactVersions; +import org.codehaus.mojo.versions.api.ReportRenderer; +import org.codehaus.plexus.i18n.I18N; + +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.codehaus.mojo.versions.api.Segment.INCREMENTAL; +import static org.codehaus.mojo.versions.api.Segment.MAJOR; +import static org.codehaus.mojo.versions.api.Segment.MINOR; +import static org.codehaus.mojo.versions.api.Segment.SUBINCREMENTAL; + +/** + * Base class for report renderers. + * @param modelled report object + * + * @author Stephen Connolly + * @since 1.0-beta-1 + */ +public abstract class AbstractVersionsReportRenderer extends VersionsReportRendererBase implements ReportRenderer +{ + + /** + * Model of the object being rendered + * + * @since 2.13.0 + */ + protected T model; + + /** + * Constructor to be called by the dependency injection framework + * @param i18n i18n object to be injected + */ + protected AbstractVersionsReportRenderer( I18N i18n, Sink sink, Locale locale, String bundleName, T model ) + { + super( sink, i18n, locale, bundleName ); + this.model = model; + } + + /** + * {@inheritDoc} + */ + protected void renderBody() + { + sink.section1(); + sink.sectionTitle1(); + sink.text( getText( "report.overview.title" ) ); + sink.sectionTitle1_(); + sink.paragraph(); + sink.text( getText( "report.overview.text" ) ); + sink.paragraph_(); + + renderOverview(); + + renderManagementSummaryTable(); + renderSummaryTable(); + + sink.section1_(); + + sink.section1(); + sink.sectionTitle1(); + sink.text( getText( "report.detail.title" ) ); + sink.sectionTitle1_(); + sink.paragraph(); + sink.text( getText( "report.detail.text" ) ); + sink.paragraph_(); + + renderDetails(); + + sink.section1_(); + } + + /** + * Renders the "Overview" table + */ + protected void renderOverview() + { + sink.table(); + sink.tableRow(); + renderOverviewTableRow( computeOverviewStats() ); + sink.tableRow_(); + sink.table_(); + } + + /** + * Renders the "management" (dependencyManagement, pluginManagement, etc.) summary table + */ + protected abstract void renderManagementSummaryTable(); + + /** + * Renders the regular ("dependencies", "plugins", etc.) summary table + */ + protected abstract void renderSummaryTable(); + + /** + * Renders the singular summary table row + * @param stats summary statistics object to render + * @param concrete {@linkplain OverviewStats} class + */ + protected void renderOverviewTableRow( Q stats ) + { + sink.tableCell(); + renderSuccessIcon(); + sink.tableCell_(); + sink.tableCell(); + sink.text( getText( "report.overview.numUpToDate" ) ); + sink.tableCell_(); + sink.tableCell(); + sink.text( Integer.toString( stats.getUpToDate() ) ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableCell(); + renderWarningIcon(); + sink.tableCell_(); + sink.tableCell(); + sink.text( getText( "report.overview.numNewerVersionAvailable" ) ); + sink.tableCell_(); + sink.tableCell(); + sink.text( Integer.toString( stats.getAny() ) ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableCell(); + renderWarningIcon(); + sink.tableCell_(); + sink.tableCell(); + sink.text( getText( "report.overview.numNewerIncrementalAvailable" ) ); + sink.tableCell_(); + sink.tableCell(); + sink.text( Integer.toString( stats.getIncremental() ) ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableCell(); + renderWarningIcon(); + sink.tableCell_(); + sink.tableCell(); + sink.text( getText( "report.overview.numNewerMinorAvailable" ) ); + sink.tableCell_(); + sink.tableCell(); + sink.text( Integer.toString( stats.getMinor() ) ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableCell(); + renderWarningIcon(); + sink.tableCell_(); + sink.tableCell(); + sink.text( getText( "report.overview.numNewerMajorAvailable" ) ); + sink.tableCell_(); + sink.tableCell(); + sink.text( Integer.toString( stats.getMajor() ) ); + sink.tableCell_(); + } + + /** + * Computes the {@linkplain OverviewStats} object needed to render the summary table row + * @param concrete {@linkplain OverviewStats} class + * @return stats object + */ + protected abstract Q computeOverviewStats(); + + /** + * Renders the details table + */ + protected abstract void renderDetails(); + + protected void renderSummaryTable( Map contents, boolean hasScope ) + { + sink.table(); + + sink.tableRow(); + renderSummaryTableHeader( hasScope, true ); + sink.tableRow_(); + + contents.forEach( ( artifact, artifactVersions ) -> + renderSummaryTableRow( artifact, artifactVersions, hasScope ) ); + + sink.tableRow(); + renderSummaryTableHeader( hasScope, true ); + sink.tableRow_(); + + sink.table_(); + } + + protected void renderSummaryTableHeader( boolean hasScope, boolean hasType ) + { + renderTableHeaderCells( "report.status", "report.groupId", "report.artifactId", + "report.currentVersion" ); + if ( hasScope ) + { + renderTableHeaderCells( "report.scope" ); + } + if ( hasType ) + { + renderTableHeaderCells( "report.classifier", "report.type" ); + } + renderTableHeaderCells( "report.latestSubIncremental", + "report.latestIncremental", "report.latestMinor", "report.latestMajor" ); + } + + protected void renderSummaryTableRow( Dependency artifact, ArtifactVersions artifactVersions, + boolean includeScope ) + { + sink.tableRow(); + sink.tableCell(); + ArtifactVersion[] allUpdates = artifactVersions.getAllUpdates( empty() ); + if ( allUpdates == null || allUpdates.length == 0 ) + { + renderSuccessIcon(); + } + else + { + renderWarningIcon(); + } + sink.tableCell_(); + sink.tableCell(); + sink.text( artifact.getGroupId() ); + sink.tableCell_(); + sink.tableCell(); + sink.text( artifact.getArtifactId() ); + sink.tableCell_(); + sink.tableCell(); + sink.text( artifact.getVersion() ); + sink.tableCell_(); + if ( includeScope ) + { + sink.tableCell(); + sink.text( artifact.getScope() ); + sink.tableCell_(); + } + sink.tableCell(); + sink.text( artifact.getClassifier() ); + sink.tableCell_(); + sink.tableCell(); + sink.text( artifact.getType() ); + sink.tableCell_(); + + sink.tableCell(); + if ( artifactVersions.getNewestUpdate( of( SUBINCREMENTAL ) ) != null ) + { + safeBold(); + sink.text( artifactVersions.getNewestUpdate( of( SUBINCREMENTAL ) ).toString() ); + safeBold_(); + } + sink.tableCell_(); + + sink.tableCell(); + if ( artifactVersions.getNewestUpdate( of( INCREMENTAL ) ) != null ) + { + safeBold(); + sink.text( artifactVersions.getNewestUpdate( of( INCREMENTAL ) ).toString() ); + safeBold_(); + } + sink.tableCell_(); + + sink.tableCell(); + if ( artifactVersions.getNewestUpdate( of( MINOR ) ) != null ) + { + safeBold(); + sink.text( artifactVersions.getNewestUpdate( of( MINOR ) ).toString() ); + safeBold_(); + } + sink.tableCell_(); + + sink.tableCell(); + if ( artifactVersions.getNewestUpdate( of( MAJOR ) ) != null ) + { + safeBold(); + sink.text( artifactVersions.getNewestUpdate( of( MAJOR ) ).toString() ); + safeBold_(); + } + sink.tableCell_(); + + sink.tableRow_(); + } + + @SuppressWarnings( "checkstyle:MethodLength" ) + protected void renderDependencyDetailTable( Dependency artifact, ArtifactVersions details, boolean includeScope ) + { + final SinkEventAttributes headerAttributes = new SinkEventAttributeSet(); + headerAttributes.addAttribute( SinkEventAttributes.WIDTH, "20%" ); + final SinkEventAttributes cellAttributes = new SinkEventAttributeSet(); + headerAttributes.addAttribute( SinkEventAttributes.WIDTH, "80%" ); + sink.table(); + sink.tableRows( new int[] { Sink.JUSTIFY_RIGHT, Sink.JUSTIFY_LEFT }, false ); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.status" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + ArtifactVersion[] versions = details.getAllUpdates( empty() ); + if ( details.getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) + { + renderWarningIcon(); + sink.nonBreakingSpace(); + sink.text( getText( "report.otherUpdatesAvailable" ) ); + } + else if ( details.getOldestUpdate( of( INCREMENTAL ) ) != null ) + { + renderWarningIcon(); + sink.nonBreakingSpace(); + sink.text( getText( "report.incrementalUpdatesAvailable" ) ); + } + else if ( details.getOldestUpdate( of( MINOR ) ) != null ) + { + renderWarningIcon(); + sink.nonBreakingSpace(); + sink.text( getText( "report.minorUpdatesAvailable" ) ); + } + else if ( details.getOldestUpdate( of( MAJOR ) ) != null ) + { + renderWarningIcon(); + sink.nonBreakingSpace(); + sink.text( getText( "report.majorUpdatesAvailable" ) ); + } + else + { + renderSuccessIcon(); + sink.nonBreakingSpace(); + sink.text( getText( "report.noUpdatesAvailable" ) ); + } + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.groupId" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( artifact.getGroupId() ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.artifactId" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( artifact.getArtifactId() ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.currentVersion" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( artifact.getVersion() ); + sink.tableCell_(); + sink.tableRow_(); + if ( includeScope ) + { + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.scope" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( artifact.getScope() ); + sink.tableCell_(); + sink.tableRow_(); + } + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.classifier" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( artifact.getClassifier() ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.type" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( artifact.getType() ); + sink.tableCell_(); + sink.tableRow_(); + if ( versions != null && versions.length > 0 ) + { + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.updateVersions" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + for ( int i = 0; i < versions.length; i++ ) + { + if ( i > 0 ) + { + sink.lineBreak(); + } + String label = getLabel( versions[i], details ); + if ( label != null ) + { + safeBold(); + } + sink.text( versions[i].toString() ); + if ( label != null ) + { + safeBold_(); + sink.nonBreakingSpace(); + safeItalic(); + sink.text( label ); + safeItalic_(); + } + } + sink.tableCell_(); + sink.tableRow_(); + } + sink.tableRows_(); + sink.table_(); + } + + /** + * Renders a table header containing elements denoted by the given keys + * @param keys variable argument list containing keys of the property file to retrieve the + * headers from + */ + protected void renderTableHeaderCells( String... keys ) + { + Arrays.stream( keys ) + .map( this::getText ) + .forEachOrdered( str -> + { + sink.tableHeaderCell(); + sink.text( str ); + sink.tableHeaderCell_(); + } ); + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/DependencyUpdatesReportRenderer.java b/src/main/java/org/codehaus/mojo/versions/reporting/DependencyUpdatesReportRenderer.java new file mode 100644 index 0000000000..c92b2bd10b --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/DependencyUpdatesReportRenderer.java @@ -0,0 +1,134 @@ +package org.codehaus.mojo.versions.reporting; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Locale; +import java.util.Map; + +import org.apache.http.annotation.Contract; +import org.apache.maven.artifact.ArtifactUtils; +import org.apache.maven.doxia.sink.Sink; +import org.apache.maven.model.Dependency; +import org.codehaus.mojo.versions.api.ArtifactVersions; +import org.codehaus.mojo.versions.reporting.model.DependencyUpdatesModel; +import org.codehaus.plexus.i18n.I18N; + +import static java.util.Optional.of; +import static org.apache.http.annotation.ThreadingBehavior.SAFE; +import static org.codehaus.mojo.versions.api.Segment.INCREMENTAL; +import static org.codehaus.mojo.versions.api.Segment.MAJOR; +import static org.codehaus.mojo.versions.api.Segment.MINOR; +import static org.codehaus.mojo.versions.api.Segment.SUBINCREMENTAL; + +/** + * @param type of the model + * @since 1.0-beta-1 + */ +@Contract( threading = SAFE ) +public class DependencyUpdatesReportRenderer extends AbstractVersionsReportRenderer +{ + public DependencyUpdatesReportRenderer( I18N i18n, Sink sink, Locale locale, String bundleName, K model ) + { + super( i18n, sink, locale, bundleName, model ); + } + + /** + * {@inheritDoc} + */ + @Override + protected void renderDetails() + { + model.getAllUpdates().forEach( this::renderDependencyDetail ); + } + + @Override + protected void renderSummaryTable() + { + renderTable( "report.overview.dependency", model.getArtifactUpdates(), + "report.overview.noDependency" ); + } + + @Override + protected void renderManagementSummaryTable() + { + renderTable( "report.overview.dependencyManagement", + model.getArtifactManagementUpdates(), "report.overview.noDependencyManagement" ); + } + + protected void renderTable( String titleKey, Map contents, String emptyKey ) + { + sink.section2(); + sink.sectionTitle2(); + sink.text( getText( titleKey ) ); + sink.sectionTitle2_(); + + if ( contents.isEmpty() ) + { + sink.paragraph(); + sink.text( getText( emptyKey ) ); + sink.paragraph_(); + } + else + { + renderSummaryTable( contents, true ); + } + sink.section2_(); + } + + @Override + protected OverviewStats computeOverviewStats() + { + OverviewStats stats = new OverviewStats(); + model.getAllUpdates().values().forEach( details -> + { + if ( details.getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) + { + stats.incrementAny(); + } + else if ( details.getOldestUpdate( of( INCREMENTAL ) ) != null ) + { + stats.incrementIncremental(); + } + else if ( details.getOldestUpdate( of( MINOR ) ) != null ) + { + stats.incrementMinor(); + } + else if ( details.getOldestUpdate( of( MAJOR ) ) != null ) + { + stats.incrementMajor(); + } + else + { + stats.incrementUpToDate(); + } + } ); + return stats; + } + + protected void renderDependencyDetail( Dependency artifact, ArtifactVersions details ) + { + sink.section2(); + sink.sectionTitle2(); + sink.text( ArtifactUtils.versionlessKey( artifact.getGroupId(), artifact.getArtifactId() ) ); + sink.sectionTitle2_(); + renderDependencyDetailTable( artifact, details, true ); + sink.section2_(); + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/OverviewStats.java b/src/main/java/org/codehaus/mojo/versions/reporting/OverviewStats.java new file mode 100644 index 0000000000..b2612d2ecf --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/OverviewStats.java @@ -0,0 +1,89 @@ +package org.codehaus.mojo.versions.reporting; + + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Represents summary stats + * + * @author Andrzej Jarmoniuk + */ +class OverviewStats +{ + private int major; + + private int minor; + + private int incremental; + + private int any; + + private int upToDate; + + public int getMajor() + { + return major; + } + + public void incrementMajor() + { + major++; + } + + public int getMinor() + { + return minor; + } + + public void incrementMinor() + { + minor++; + } + + public int getIncremental() + { + return incremental; + } + + public void incrementIncremental() + { + incremental++; + } + + public int getAny() + { + return any; + } + + public void incrementAny() + { + any++; + } + + public int getUpToDate() + { + return upToDate; + } + + public void incrementUpToDate() + { + upToDate++; + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/ParentUpdatesReportRenderer.java b/src/main/java/org/codehaus/mojo/versions/reporting/ParentUpdatesReportRenderer.java new file mode 100644 index 0000000000..f89139a249 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/ParentUpdatesReportRenderer.java @@ -0,0 +1,52 @@ +package org.codehaus.mojo.versions.reporting; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Locale; + +import org.apache.http.annotation.Contract; +import org.apache.maven.doxia.sink.Sink; +import org.codehaus.mojo.versions.reporting.model.ParentUpdatesModel; +import org.codehaus.plexus.i18n.I18N; + +import static org.apache.http.annotation.ThreadingBehavior.SAFE; + +/** + * @since 1.0-beta-1 + */ +@Contract( threading = SAFE ) +public class ParentUpdatesReportRenderer extends DependencyUpdatesReportRenderer +{ + public ParentUpdatesReportRenderer( I18N i18n, Sink sink, Locale locale, String bundleName, + ParentUpdatesModel model ) + { + super( i18n, sink, locale, bundleName, model ); + } + + @Override + protected void renderOverview() + { + } + + @Override + protected void renderManagementSummaryTable() + { + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/PluginUpdatesRenderer.java b/src/main/java/org/codehaus/mojo/versions/reporting/PluginUpdatesReportRenderer.java similarity index 51% rename from src/main/java/org/codehaus/mojo/versions/PluginUpdatesRenderer.java rename to src/main/java/org/codehaus/mojo/versions/reporting/PluginUpdatesReportRenderer.java index de7b3677d7..2d46646321 100644 --- a/src/main/java/org/codehaus/mojo/versions/PluginUpdatesRenderer.java +++ b/src/main/java/org/codehaus/mojo/versions/reporting/PluginUpdatesReportRenderer.java @@ -1,4 +1,4 @@ -package org.codehaus.mojo.versions; +package org.codehaus.mojo.versions.reporting; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -9,7 +9,7 @@ * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an @@ -22,21 +22,22 @@ import java.text.MessageFormat; import java.util.Locale; import java.util.Map; -import java.util.TreeMap; +import org.apache.http.annotation.Contract; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.sink.SinkEventAttributes; import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; import org.apache.maven.model.Dependency; -import org.apache.maven.model.Plugin; +import org.codehaus.mojo.versions.PluginUpdatesDetails; import org.codehaus.mojo.versions.api.ArtifactVersions; -import org.codehaus.mojo.versions.utils.PluginComparator; +import org.codehaus.mojo.versions.reporting.model.PluginUpdatesModel; import org.codehaus.plexus.i18n.I18N; import static java.util.Optional.empty; import static java.util.Optional.of; +import static org.apache.http.annotation.ThreadingBehavior.SAFE; import static org.codehaus.mojo.versions.api.Segment.INCREMENTAL; import static org.codehaus.mojo.versions.api.Segment.MAJOR; import static org.codehaus.mojo.versions.api.Segment.MINOR; @@ -45,228 +46,160 @@ /** * @since 1.0-beta-1 */ -public class PluginUpdatesRenderer - extends AbstractVersionsReportRenderer +@Contract( threading = SAFE ) +public class PluginUpdatesReportRenderer extends AbstractVersionsReportRenderer { - private final Map pluginUpdates; + public PluginUpdatesReportRenderer( I18N i18n, Sink sink, Locale locale, String bundleName, + PluginUpdatesModel model ) + { + super( i18n, sink, locale, bundleName, model ); + } - private final Map pluginManagementUpdates; + @Override + protected void renderSummaryTable() + { + renderTable( "report.overview.plugin", model.getArtifactUpdates(), + "report.overview.noPlugin" ); + } - public PluginUpdatesRenderer( Sink sink, I18N i18n, String bundleName, Locale locale, - Map pluginUpdates, - Map pluginManagementUpdates ) + protected void renderManagementSummaryTable() { - super( sink, bundleName, i18n, locale ); - this.pluginUpdates = pluginUpdates; - this.pluginManagementUpdates = pluginManagementUpdates; + renderTable( "report.overview.pluginManagement", model.getArtifactManagementUpdates(), + "report.overview.noPluginManagement" ); } - protected void renderBody() + /** + * {@inheritDoc} + */ + @Override + protected void renderDetails() { - Map allUpdates = new TreeMap<>( new PluginComparator() ); - allUpdates.putAll( pluginManagementUpdates ); - allUpdates.putAll( pluginUpdates ); + model.getAllUpdates().forEach( this::renderPluginDetail ); + } - sink.section1(); - sink.sectionTitle1(); - sink.text( getText( "report.overview.title" ) ); - sink.sectionTitle1_(); - sink.paragraph(); - sink.text( getText( "report.overview.text" ) ); - sink.paragraph_(); + private void renderDependencyDetail( Dependency dependency, ArtifactVersions details ) + { + sink.section3(); + sink.sectionTitle3(); + sink.text( MessageFormat.format( getText( "report.pluginDependency" ), + ArtifactUtils.versionlessKey( dependency.getGroupId(), dependency.getArtifactId() ) ) ); + sink.sectionTitle3_(); + renderDependencyDetailTable( dependency, details, false ); + sink.section3_(); + } - renderSummaryTotalsTable( allUpdates ); + private void renderTable( String titleKey, Map contents, String emptyKey ) + { + sink.section2(); + sink.sectionTitle2(); + sink.text( getText( titleKey ) ); + sink.sectionTitle2_(); + + if ( contents.isEmpty() ) + { + sink.paragraph(); + sink.text( getText( emptyKey ) ); + sink.paragraph_(); + } + else + { + renderSummaryTable( contents ); + } + sink.section2_(); + } + + protected void renderSummaryTable( Map contents ) + { + sink.table(); + + sink.tableRow(); + renderSummaryTableHeader( false, false ); + sink.tableRow_(); - renderSummaryTable( "report.overview.pluginManagement", pluginManagementUpdates, - "report.overview.noPluginManagement" ); + contents.forEach( this::renderSummaryTableRow ); - renderSummaryTable( "report.overview.plugin", pluginUpdates, "report.overview.noPlugin" ); + sink.tableRow(); + renderSummaryTableHeader( false, false ); + sink.tableRow_(); - sink.section1_(); + sink.table_(); + } - sink.section1(); - sink.sectionTitle1(); - sink.text( getText( "report.detail.title" ) ); - sink.sectionTitle1_(); - sink.paragraph(); - sink.text( getText( "report.detail.text" ) ); - sink.paragraph_(); + /** + * Extension of the {@linkplain OverviewStats} adding dependency stats + */ + static class PluginOverviewStats extends OverviewStats + { + private int dependencies; - for ( final Map.Entry entry : allUpdates.entrySet() ) + public int getDependencies() { - renderPluginDetail( entry.getKey(), entry.getValue() ); + return dependencies; } - sink.section1_(); + public void incrementDependencies() + { + dependencies++; + } } - private void renderSummaryTotalsTable( Map allUpdates ) + /** + * {@inheritDoc} + */ + @Override + protected PluginOverviewStats computeOverviewStats() { - int numInc = 0; - int numMin = 0; - int numMaj = 0; - int numAny = 0; - int numCur = 0; - int numDep = 0; - for ( PluginUpdatesDetails pluginDetails : allUpdates.values() ) + PluginOverviewStats stats = new PluginOverviewStats(); + model.getAllUpdates().values().forEach( details -> { - ArtifactVersions details = pluginDetails.getArtifactVersions(); if ( details.getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) { - numAny++; + stats.incrementAny(); } else if ( details.getOldestUpdate( of( INCREMENTAL ) ) != null ) { - numInc++; + stats.incrementIncremental(); } else if ( details.getOldestUpdate( of( MINOR ) ) != null ) { - numMin++; + stats.incrementMinor(); } else if ( details.getOldestUpdate( of( MAJOR ) ) != null ) { - numMaj++; + stats.incrementMajor(); } else { - numCur++; + stats.incrementUpToDate(); } - if ( pluginDetails.isDependencyUpdateAvailable() ) + if ( details.isDependencyUpdateAvailable() ) { - numDep++; + stats.incrementDependencies(); } - } - sink.table(); - sink.tableRow(); - sink.tableCell(); - renderSuccessIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numUpToDate" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numCur ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerVersionAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numAny ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerIncrementalAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numInc ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerMinorAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numMin ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerMajorAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numMaj ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.tableRow(); - sink.tableCell(); - renderWarningIcon(); - sink.tableCell_(); - sink.tableCell(); - sink.text( getText( "report.overview.numNewerDependenciesAvailable" ) ); - sink.tableCell_(); - sink.tableCell(); - sink.text( Integer.toString( numDep ) ); - sink.tableCell_(); - sink.tableRow_(); - sink.table_(); + } ); + return stats; } - private void renderSummaryTable( String titleKey, Map contents, String emptyKey ) + @Override + protected void renderSummaryTableHeader( boolean hasScope, boolean hasType ) { - sink.section2(); - sink.sectionTitle2(); - sink.text( getText( titleKey ) ); - sink.sectionTitle2_(); - - if ( contents.isEmpty() ) - { - sink.paragraph(); - sink.text( getText( emptyKey ) ); - sink.paragraph_(); - } - else - { - sink.table(); - renderSummaryTableHeader(); - for ( final Map.Entry entry : contents.entrySet() ) - { - renderPluginSummary( entry.getKey(), entry.getValue() ); - } - renderSummaryTableHeader(); - sink.table_(); - } - sink.section2_(); + super.renderSummaryTableHeader( hasScope, hasType ); + renderTableHeaderCells( "report.dependencyStatus" ); } - private void renderSummaryTableHeader() + @Override + protected void renderOverviewTableRow( T stats ) { - sink.tableRow(); - sink.tableHeaderCell(); - sink.text( getText( "report.status" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.groupId" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.artifactId" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.currentVersion" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestSubIncremental" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestIncremental" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestMinor" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.latestMajor" ) ); - sink.tableHeaderCell_(); - sink.tableHeaderCell(); - sink.text( getText( "report.dependencyStatus" ) ); - sink.tableHeaderCell_(); - sink.tableRow_(); + super.renderOverviewTableRow( stats ); + sink.tableCell(); + sink.text( getText( "report.overview.numNewerDependenciesAvailable" ) ); + sink.tableCell_(); + sink.tableCell(); + sink.text( Integer.toString( ( (PluginOverviewStats) stats ).getDependencies() ) ); + sink.tableCell_(); } - private void renderPluginSummary( Plugin plugin, PluginUpdatesDetails details ) + protected void renderSummaryTableRow( Dependency artifact, PluginUpdatesDetails details ) { sink.tableRow(); sink.tableCell(); @@ -280,17 +213,17 @@ private void renderPluginSummary( Plugin plugin, PluginUpdatesDetails details ) } sink.tableCell_(); sink.tableCell(); - sink.text( plugin.getGroupId() ); + sink.text( artifact.getGroupId() ); sink.tableCell_(); sink.tableCell(); - sink.text( plugin.getArtifactId() ); + sink.text( artifact.getArtifactId() ); sink.tableCell_(); sink.tableCell(); if ( !details.isArtifactUpdateAvailable() ) { safeBold(); } - sink.text( plugin.getVersion() ); + sink.text( artifact.getVersion() ); if ( !details.isArtifactUpdateAvailable() ) { safeBold_(); @@ -298,37 +231,37 @@ private void renderPluginSummary( Plugin plugin, PluginUpdatesDetails details ) sink.tableCell_(); sink.tableCell(); - if ( details.getArtifactVersions().getNewestUpdate( of( SUBINCREMENTAL ) ) != null ) + if ( details.getNewestUpdate( of( SUBINCREMENTAL ) ) != null ) { safeBold(); - sink.text( details.getArtifactVersions().getNewestUpdate( of( SUBINCREMENTAL ) ).toString() ); + sink.text( details.getNewestUpdate( of( SUBINCREMENTAL ) ).toString() ); safeBold_(); } sink.tableCell_(); sink.tableCell(); - if ( details.getArtifactVersions().getNewestUpdate( of( INCREMENTAL ) ) != null ) + if ( details.getNewestUpdate( of( INCREMENTAL ) ) != null ) { safeBold(); - sink.text( details.getArtifactVersions().getNewestUpdate( of( INCREMENTAL ) ).toString() ); + sink.text( details.getNewestUpdate( of( INCREMENTAL ) ).toString() ); safeBold_(); } sink.tableCell_(); sink.tableCell(); - if ( details.getArtifactVersions().getNewestUpdate( of( MINOR ) ) != null ) + if ( details.getNewestUpdate( of( MINOR ) ) != null ) { safeBold(); - sink.text( details.getArtifactVersions().getNewestUpdate( of( MINOR ) ).toString() ); + sink.text( details.getNewestUpdate( of( MINOR ) ).toString() ); safeBold_(); } sink.tableCell_(); sink.tableCell(); - if ( details.getArtifactVersions().getNewestUpdate( of( MAJOR ) ) != null ) + if ( details.getNewestUpdate( of( MAJOR ) ) != null ) { safeBold(); - sink.text( details.getArtifactVersions().getNewestUpdate( of( MAJOR ) ).toString() ); + sink.text( details.getNewestUpdate( of( MAJOR ) ).toString() ); safeBold_(); } sink.tableCell_(); @@ -348,7 +281,7 @@ private void renderPluginSummary( Plugin plugin, PluginUpdatesDetails details ) } @SuppressWarnings( "checkstyle:MethodLength" ) - private void renderPluginDetail( Plugin plugin, PluginUpdatesDetails details ) + private void renderPluginDetail( Dependency artifact, PluginUpdatesDetails plugin ) { final SinkEventAttributes headerAttributes = new SinkEventAttributeSet(); headerAttributes.addAttribute( SinkEventAttributes.WIDTH, "20%" ); @@ -366,26 +299,26 @@ private void renderPluginDetail( Plugin plugin, PluginUpdatesDetails details ) sink.text( getText( "report.status" ) ); sink.tableHeaderCell_(); sink.tableCell( cellAttributes ); - ArtifactVersion[] versions = details.getArtifactVersions().getAllUpdates( empty() ); - if ( details.getArtifactVersions().getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) + ArtifactVersion[] versions = plugin.getAllUpdates( empty() ); + if ( plugin.getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) { renderWarningIcon(); sink.nonBreakingSpace(); sink.text( getText( "report.otherUpdatesAvailable" ) ); } - else if ( details.getArtifactVersions().getOldestUpdate( of( INCREMENTAL ) ) != null ) + else if ( plugin.getOldestUpdate( of( INCREMENTAL ) ) != null ) { renderWarningIcon(); sink.nonBreakingSpace(); sink.text( getText( "report.incrementalUpdatesAvailable" ) ); } - else if ( details.getArtifactVersions().getOldestUpdate( of( MINOR ) ) != null ) + else if ( plugin.getOldestUpdate( of( MINOR ) ) != null ) { renderWarningIcon(); sink.nonBreakingSpace(); sink.text( getText( "report.minorUpdatesAvailable" ) ); } - else if ( details.getArtifactVersions().getOldestUpdate( of( MAJOR ) ) != null ) + else if ( plugin.getOldestUpdate( of( MAJOR ) ) != null ) { renderWarningIcon(); sink.nonBreakingSpace(); @@ -423,7 +356,7 @@ else if ( details.getArtifactVersions().getOldestUpdate( of( MAJOR ) ) != null ) sink.text( plugin.getVersion() ); sink.tableCell_(); sink.tableRow_(); - if ( versions.length > 0 ) + if ( versions != null && versions.length > 0 ) { sink.tableRow(); sink.tableHeaderCell( headerAttributes ); @@ -436,7 +369,7 @@ else if ( details.getArtifactVersions().getOldestUpdate( of( MAJOR ) ) != null ) { sink.lineBreak(); } - String label = getLabel( versions[i], details.getArtifactVersions() ); + String label = getLabel( versions[i], plugin ); if ( label != null ) { safeBold(); @@ -457,7 +390,7 @@ else if ( details.getArtifactVersions().getOldestUpdate( of( MAJOR ) ) != null ) sink.tableRows_(); sink.table_(); - if ( !details.getDependencyVersions().isEmpty() ) + if ( !plugin.getDependencyVersions().isEmpty() ) { sink.section3(); sink.sectionTitle3(); @@ -465,25 +398,13 @@ else if ( details.getArtifactVersions().getOldestUpdate( of( MAJOR ) ) != null ) ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() ) ) ); sink.sectionTitle3_(); - renderDependencySummaryTable( details.getDependencyVersions(), false, true, true ); + renderSummaryTable( plugin.getDependencyVersions(), false ); sink.section3_(); - details.getDependencyVersions() - .forEach( this::renderDependencyDetail ); + plugin.getDependencyVersions().forEach( this::renderDependencyDetail ); } sink.section2_(); } - - private void renderDependencyDetail( Dependency dependency, ArtifactVersions details ) - { - sink.section3(); - sink.sectionTitle3(); - sink.text( MessageFormat.format( getText( "report.pluginDependency" ), - ArtifactUtils.versionlessKey( dependency.getGroupId(), dependency.getArtifactId() ) ) ); - sink.sectionTitle3_(); - renderDependencyDetailTable( dependency, details, false, true, true ); - sink.section3_(); - } - } + diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/PropertyUpdatesReportRenderer.java b/src/main/java/org/codehaus/mojo/versions/reporting/PropertyUpdatesReportRenderer.java new file mode 100644 index 0000000000..8f1559c5a3 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/PropertyUpdatesReportRenderer.java @@ -0,0 +1,434 @@ +package org.codehaus.mojo.versions.reporting; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.http.annotation.Contract; +import org.apache.maven.artifact.ArtifactUtils; +import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.artifact.versioning.VersionRange; +import org.apache.maven.doxia.sink.Sink; +import org.apache.maven.doxia.sink.SinkEventAttributes; +import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; +import org.codehaus.mojo.versions.Property; +import org.codehaus.mojo.versions.api.ArtifactAssociation; +import org.codehaus.mojo.versions.api.PropertyVersions; +import org.codehaus.mojo.versions.reporting.model.PropertyUpdatesModel; +import org.codehaus.plexus.i18n.I18N; +import org.codehaus.plexus.util.StringUtils; + +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.apache.http.annotation.ThreadingBehavior.SAFE; +import static org.codehaus.mojo.versions.api.Segment.INCREMENTAL; +import static org.codehaus.mojo.versions.api.Segment.MAJOR; +import static org.codehaus.mojo.versions.api.Segment.MINOR; +import static org.codehaus.mojo.versions.api.Segment.SUBINCREMENTAL; + +/** + * @since 1.0-beta-1 + */ +@Contract( threading = SAFE ) +public class PropertyUpdatesReportRenderer extends AbstractVersionsReportRenderer +{ + public PropertyUpdatesReportRenderer( I18N i18n, Sink sink, Locale locale, String bundleName, + PropertyUpdatesModel model ) + { + super( i18n, sink, locale, bundleName, model ); + } + + @Override + protected void renderManagementSummaryTable() + { + } + + @Override + protected void renderSummaryTable() + { + renderTable( "report.overview.property", model.getAllUpdates(), + "report.overview.noProperty" ); + } + + /** + * {@inheritDoc} + */ + @Override + protected void renderDetails() + { + model.getAllUpdates().forEach( this::renderPropertyDetail ); + } + + protected void renderTable( String titleKey, Map contents, String emptyKey ) + { + sink.section2(); + sink.sectionTitle2(); + sink.text( getText( titleKey ) ); + sink.sectionTitle2_(); + + if ( contents.isEmpty() ) + { + sink.paragraph(); + sink.text( getText( emptyKey ) ); + sink.paragraph_(); + } + else + { + renderSummaryTable( contents ); + } + sink.section2_(); + } + + protected void renderSummaryTable( Map contents ) + { + sink.table(); + + sink.tableRow(); + renderSummaryTableHeader( false, false ); + sink.tableRow_(); + + contents.forEach( this::renderPropertySummaryTableRow ); + + sink.tableRow(); + renderSummaryTableHeader( false, false ); + sink.tableRow_(); + + sink.table_(); + } + + private void renderPropertySummaryTableRow( Property property, PropertyVersions versions ) + { + sink.tableRow(); + sink.tableCell(); + if ( versions.getAllUpdates( empty() ).length == 0 ) + { + renderSuccessIcon(); + } + else + { + renderWarningIcon(); + } + sink.tableCell_(); + sink.tableCell(); + sink.text( "${" + property.getName() + "}" ); + sink.tableCell_(); + sink.tableCell(); + sink.text( versions.getCurrentVersion().toString() ); + sink.tableCell_(); + + sink.tableCell(); + if ( versions.getNewestUpdate( of( SUBINCREMENTAL ) ) != null ) + { + safeBold(); + sink.text( versions.getNewestUpdate( of( SUBINCREMENTAL ) ).toString() ); + safeBold_(); + } + sink.tableCell_(); + + sink.tableCell(); + if ( versions.getNewestUpdate( of( INCREMENTAL ) ) != null ) + { + safeBold(); + sink.text( versions.getNewestUpdate( of( INCREMENTAL ) ).toString() ); + safeBold_(); + } + sink.tableCell_(); + + sink.tableCell(); + if ( versions.getNewestUpdate( of( MINOR ) ) != null ) + { + safeBold(); + sink.text( versions.getNewestUpdate( of( MINOR ) ).toString() ); + safeBold_(); + } + sink.tableCell_(); + + sink.tableCell(); + if ( versions.getNewestUpdate( of( MAJOR ) ) != null ) + { + safeBold(); + sink.text( versions.getNewestUpdate( of( MAJOR ) ).toString() ); + safeBold_(); + } + sink.tableCell_(); + + sink.tableRow_(); + } + + @SuppressWarnings( "checkstyle:MethodLength" ) + protected void renderPropertyDetailTable( Property property, PropertyVersions versions ) + { + final SinkEventAttributes headerAttributes = new SinkEventAttributeSet(); + headerAttributes.addAttribute( SinkEventAttributes.WIDTH, "20%" ); + final SinkEventAttributes cellAttributes = new SinkEventAttributeSet(); + headerAttributes.addAttribute( SinkEventAttributes.WIDTH, "80%" ); + sink.table(); + sink.tableRows( new int[] { Sink.JUSTIFY_RIGHT, Sink.JUSTIFY_LEFT }, false ); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.status" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + ArtifactVersion[] artifactVersions = versions.getAllUpdates( empty() ); + Set rangeVersions = getVersionsInRange( property, versions, artifactVersions ); + if ( versions.getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) + { + renderWarningIcon(); + sink.nonBreakingSpace(); + sink.text( getText( "report.otherUpdatesAvailable" ) ); + } + else if ( versions.getOldestUpdate( of( INCREMENTAL ) ) != null ) + { + renderWarningIcon(); + sink.nonBreakingSpace(); + sink.text( getText( "report.incrementalUpdatesAvailable" ) ); + } + else if ( versions.getOldestUpdate( of( MINOR ) ) != null ) + { + renderWarningIcon(); + sink.nonBreakingSpace(); + sink.text( getText( "report.minorUpdatesAvailable" ) ); + } + else if ( versions.getOldestUpdate( of( MAJOR ) ) != null ) + { + renderWarningIcon(); + sink.nonBreakingSpace(); + sink.text( getText( "report.majorUpdatesAvailable" ) ); + } + else + { + renderSuccessIcon(); + sink.nonBreakingSpace(); + sink.text( getText( "report.noUpdatesAvailable" ) ); + } + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.property" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( "${" + property.getName() + "}" ); + sink.tableCell_(); + sink.tableRow_(); + + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.associations" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + ArtifactAssociation[] associations = versions.getAssociations(); + for ( int i = 0; i < associations.length; i++ ) + { + if ( i > 0 ) + { + sink.lineBreak(); + } + sink.text( ArtifactUtils.versionlessKey( associations[i].getArtifact() ) ); + } + sink.tableCell_(); + sink.tableRow_(); + + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.currentVersion" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( versions.getCurrentVersion().toString() ); + sink.tableCell_(); + sink.tableRow_(); + if ( artifactVersions.length > 0 ) + { + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.updateVersions" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + boolean someNotAllowed = false; + for ( int i = 0; i < artifactVersions.length; i++ ) + { + if ( i > 0 ) + { + sink.lineBreak(); + } + boolean allowed = ( rangeVersions.contains( artifactVersions[i].toString() ) ); + String label = getLabel( artifactVersions[i], versions ); + if ( !allowed ) + { + sink.text( "* " ); + someNotAllowed = true; + } + if ( allowed && label != null ) + { + safeBold(); + } + sink.text( artifactVersions[i].toString() ); + if ( label != null ) + { + if ( allowed ) + { + safeBold_(); + } + sink.nonBreakingSpace(); + safeItalic(); + sink.text( label ); + safeItalic_(); + } + } + if ( someNotAllowed ) + { + sink.lineBreak(); + sink.lineBreak(); + sink.text( "* " ); + safeItalic(); + sink.text( getText( "report.excludedVersion" ) ); + safeItalic_(); + } + sink.tableCell_(); + sink.tableRow_(); + } + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.versionRange" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( StringUtils.isEmpty( property.getVersion() ) ? "[,)" : property.getVersion() ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.autoLinkDependencies" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( property.isAutoLinkDependencies() ? getText( "report.yes" ) : getText( "report.no" ) ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.banSnapshots" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( property.isBanSnapshots() ? getText( "report.yes" ) : getText( "report.no" ) ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.searchReactor" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( property.isSearchReactor() ? getText( "report.yes" ) : getText( "report.no" ) ); + sink.tableCell_(); + sink.tableRow_(); + sink.tableRow(); + sink.tableHeaderCell( headerAttributes ); + sink.text( getText( "report.preferReactor" ) ); + sink.tableHeaderCell_(); + sink.tableCell( cellAttributes ); + sink.text( property.isPreferReactor() ? getText( "report.yes" ) : getText( "report.no" ) ); + sink.tableCell_(); + sink.tableRow_(); + + sink.tableRows_(); + sink.table_(); + } + + @SuppressWarnings( "checkstyle:MethodLength" ) + protected Set getVersionsInRange( Property property, PropertyVersions versions, + ArtifactVersion[] artifactVersions ) + { + VersionRange range; + Set rangeVersions = new HashSet<>(); + ArtifactVersion[] tmp; + if ( property.getVersion() != null ) + { + try + { + range = VersionRange.createFromVersionSpec( property.getVersion() ); + tmp = versions.getAllUpdates( range ); + } + catch ( InvalidVersionSpecificationException e ) + { + tmp = artifactVersions; + } + } + else + { + tmp = artifactVersions; + } + for ( ArtifactVersion artifactVersion : tmp ) + { + rangeVersions.add( artifactVersion.toString() ); + } + return rangeVersions; + } + + @Override + protected void renderSummaryTableHeader( boolean hasScope, boolean hasType ) + { + renderTableHeaderCells( "report.status", "report.property", "report.currentVersion", + "report.latestSubIncremental", "report.latestIncremental", "report.latestMinor", + "report.latestMajor" ); + } + + @Override + protected OverviewStats computeOverviewStats() + { + OverviewStats stats = new OverviewStats(); + model.getAllUpdates().values().forEach( details -> + { + if ( details.getOldestUpdate( of( SUBINCREMENTAL ) ) != null ) + { + stats.incrementAny(); + } + else if ( details.getOldestUpdate( of( INCREMENTAL ) ) != null ) + { + stats.incrementIncremental(); + } + else if ( details.getOldestUpdate( of( MINOR ) ) != null ) + { + stats.incrementMinor(); + } + else if ( details.getOldestUpdate( of( MAJOR ) ) != null ) + { + stats.incrementMajor(); + } + else + { + stats.incrementUpToDate(); + } + } ); + return stats; + } + + private void renderPropertyDetail( Property property, PropertyVersions versions ) + { + sink.section2(); + sink.sectionTitle2(); + sink.text( "${" + property.getName() + "}" ); + sink.sectionTitle2_(); + renderPropertyDetailTable( property, versions ); + sink.section2_(); + } + +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/ReportRendererFactory.java b/src/main/java/org/codehaus/mojo/versions/reporting/ReportRendererFactory.java new file mode 100644 index 0000000000..53d65790d9 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/ReportRendererFactory.java @@ -0,0 +1,45 @@ +package org.codehaus.mojo.versions.reporting; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Locale; + +import org.apache.maven.doxia.sink.Sink; +import org.codehaus.mojo.versions.api.ReportRenderer; + +/** + * Factory for report renderers + */ +public interface ReportRendererFactory +{ + /** + * Creates a new {@linkplain ReportRenderer} instance for the given report renderer name. + * + * @param concrete class of the report renderer + * @param reportName name of the report to generate + * @param sink sink to use for rendering + * @param locale locale to use for rendering + * @param model data to render + * @return new report renderer + * @throws IllegalArgumentException thrown if the report with the given name could not be found + */ + T createReportRenderer( String reportName, Sink sink, Locale locale, U model ) + throws IllegalArgumentException; +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/ReportRendererFactoryImpl.java b/src/main/java/org/codehaus/mojo/versions/reporting/ReportRendererFactoryImpl.java new file mode 100644 index 0000000000..faeb4f5b71 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/ReportRendererFactoryImpl.java @@ -0,0 +1,83 @@ +package org.codehaus.mojo.versions.reporting; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import javax.inject.Inject; +import javax.inject.Named; + +import java.util.Locale; + +import org.apache.maven.doxia.sink.Sink; +import org.codehaus.mojo.versions.api.ReportRenderer; +import org.codehaus.mojo.versions.reporting.model.DependencyUpdatesModel; +import org.codehaus.mojo.versions.reporting.model.ParentUpdatesModel; +import org.codehaus.mojo.versions.reporting.model.PluginUpdatesModel; +import org.codehaus.mojo.versions.reporting.model.PropertyUpdatesModel; +import org.codehaus.plexus.i18n.I18N; + +/** + * Factory for report renderers + */ +@Named +public class ReportRendererFactoryImpl implements ReportRendererFactory +{ + public static final String DEPENDENCY_UPDATES_REPORT = "dependency-updates-report"; + public static final String PLUGIN_UPDATES_REPORT = "plugin-updates-report"; + public static final String PROPERTY_UPDATES_REPORT = "property-updates-report"; + public static final String PARENT_UPDATES_REPORT = "parent-updates-report"; + private final I18N i18N; + + @Inject + public ReportRendererFactoryImpl( I18N i18N ) + { + this.i18N = i18N; + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings( "unchecked" ) + public T createReportRenderer( String reportName, Sink sink, Locale locale, U model ) + throws IllegalArgumentException + { + if ( DEPENDENCY_UPDATES_REPORT.equals( reportName ) ) + { + return (T) new DependencyUpdatesReportRenderer<>( i18N, sink, locale, reportName, + (DependencyUpdatesModel) model ); + } + if ( PLUGIN_UPDATES_REPORT.equals( reportName ) ) + { + return (T) new PluginUpdatesReportRenderer( i18N, sink, locale, reportName, + (PluginUpdatesModel) model ); + } + if ( PROPERTY_UPDATES_REPORT.equals( reportName ) ) + { + return (T) new PropertyUpdatesReportRenderer( i18N, sink, locale, reportName, + (PropertyUpdatesModel) model ); + } + if ( PARENT_UPDATES_REPORT.equals( reportName ) ) + { + return (T) new ParentUpdatesReportRenderer( i18N, sink, locale, reportName, + (ParentUpdatesModel) model ); + } + throw new IllegalArgumentException( "Invalid report name: " + reportName ); + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/VersionsReportRendererBase.java b/src/main/java/org/codehaus/mojo/versions/reporting/VersionsReportRendererBase.java new file mode 100644 index 0000000000..79ea8fc87b --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/VersionsReportRendererBase.java @@ -0,0 +1,172 @@ +package org.codehaus.mojo.versions.reporting; + + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Locale; + +import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.doxia.sink.Sink; +import org.apache.maven.reporting.AbstractMavenReportRenderer; +import org.codehaus.mojo.versions.api.AbstractVersionDetails; +import org.codehaus.plexus.i18n.I18N; + +import static java.util.Optional.of; +import static org.codehaus.mojo.versions.api.Segment.INCREMENTAL; +import static org.codehaus.mojo.versions.api.Segment.MAJOR; +import static org.codehaus.mojo.versions.api.Segment.MINOR; +import static org.codehaus.mojo.versions.api.Segment.SUBINCREMENTAL; + +/** + * Base class over the {@linkplain AbstractVersionsReportRenderer} providing base + * utility methods + */ +public abstract class VersionsReportRendererBase extends AbstractMavenReportRenderer +{ + /** + * Internationalization component. + * + * @since 1.0-beta-1 + */ + protected final I18N i18n; + /** + * The locale we are rendering for. + * + * @since 1.0-beta-1 + */ + protected Locale locale; + /** + * The name of the bundle containing our I18n resources. + * + * @since 1.0-beta-1 + */ + protected String bundleName; + + public VersionsReportRendererBase( Sink sink, I18N i18n, Locale locale, String bundleName ) + { + super( sink ); + this.i18n = i18n; + this.locale = locale; + this.bundleName = bundleName; + } + + public String getTitle() + { + return getText( "report.title" ); + } + + /** + * Gets the localized message for this report. + * + * @param key the message key. + * @return the message. + */ + public String getText( String key ) + { + return i18n.getString( bundleName, locale, key ); + } + + protected void renderWarningIcon() + { + sink.figureGraphics( "images/icon_warning_sml.gif" ); + } + + protected void renderSuccessIcon() + { + sink.figureGraphics( "images/icon_success_sml.gif" ); + } + + protected boolean equals( ArtifactVersion v1, ArtifactVersion v2 ) + { + return v1 == v2 || ( v1 != null && v1.equals( v2 ) ) + || ( v1 != null && v2 != null && v1.toString().equals( v2.toString() ) ); + } + + protected void safeBold() + { + try + { + sink.bold(); + } + catch ( NoSuchMethodError e ) + { + // ignore Maven 2.1.0 + } + } + + @SuppressWarnings( "checkstyle:MethodName" ) + protected void safeBold_() + { + try + { + sink.bold_(); + } + catch ( NoSuchMethodError e ) + { + // ignore Maven 2.1.0 + } + } + + protected void safeItalic() + { + try + { + sink.italic(); + } + catch ( NoSuchMethodError e ) + { + // ignore Maven 2.1.0 + } + } + + @SuppressWarnings( "checkstyle:MethodName" ) + protected void safeItalic_() + { + try + { + sink.italic_(); + } + catch ( NoSuchMethodError e ) + { + // ignore Maven 2.1.0 + } + } + + protected String getLabel( ArtifactVersion version, AbstractVersionDetails versions ) + { + return equals( version, versions.getNewestUpdate( of( MAJOR ) ) ) + ? getText( "report.latestMajor" ) + : equals( version, versions.getOldestUpdate( of( MAJOR ) ) ) + ? getText( "report.nextMajor" ) + : equals( version, versions.getNewestUpdate( of( MINOR ) ) ) + ? getText( "report.latestMinor" ) + : equals( version, versions.getOldestUpdate( of( MINOR ) ) ) + ? getText( "report.nextMinor" ) + : equals( version, versions.getNewestUpdate( of( INCREMENTAL ) ) ) + ? getText( "report.latestIncremental" ) + : equals( version, versions.getOldestUpdate( of( INCREMENTAL ) ) ) + ? getText( "report.nextIncremental" ) + : equals( version, versions.getNewestUpdate( of( SUBINCREMENTAL ) ) ) + ? getText( "report.latestSubIncremental" ) + : equals( version, versions.getOldestUpdate( of( SUBINCREMENTAL ) ) ) + ? getText( "report.nextVersion" ) + : null; + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/model/AbstractUpdatesModel.java b/src/main/java/org/codehaus/mojo/versions/reporting/model/AbstractUpdatesModel.java new file mode 100644 index 0000000000..5802b8b9eb --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/model/AbstractUpdatesModel.java @@ -0,0 +1,72 @@ +package org.codehaus.mojo.versions.reporting.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Map; +import java.util.TreeMap; +import java.util.function.Function; + +import org.apache.maven.model.Dependency; +import org.codehaus.mojo.versions.api.ArtifactVersions; +import org.codehaus.mojo.versions.utils.DependencyComparator; + +/** + * Base class for using with the {@linkplain org.codehaus.mojo.versions.api.ReportRenderer} API + * @param class extending ArtifactVersion in the constructor + */ +public abstract class AbstractUpdatesModel +{ + private final Map artifactUpdates; + private final Map artifactManagementUpdates; + private final Map allUpdates; + + public AbstractUpdatesModel( Map artifactUpdates, + Map artifactManagementUpdates, + Function supplier ) + { + this.artifactUpdates = artifactUpdates.entrySet().stream().collect( + () -> new TreeMap<>( DependencyComparator.INSTANCE ), + ( map, entry ) -> map.put( supplier.apply( entry.getKey() ), entry.getValue() ), + Map::putAll ); + this.artifactManagementUpdates = artifactManagementUpdates.entrySet().stream().collect( + () -> new TreeMap<>( DependencyComparator.INSTANCE ), + ( map, entry ) -> map.put( supplier.apply( entry.getKey() ), entry.getValue() ), + Map::putAll ); + allUpdates = new TreeMap<>( DependencyComparator.INSTANCE ); + // overriding entries from dependencyManagementUpdates with dependencyUpdates + allUpdates.putAll( this.artifactManagementUpdates ); + allUpdates.putAll( this.artifactUpdates ); + } + + public Map getArtifactUpdates() + { + return artifactUpdates; + } + + public Map getArtifactManagementUpdates() + { + return artifactManagementUpdates; + } + + public Map getAllUpdates() + { + return allUpdates; + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/model/DependencyUpdatesModel.java b/src/main/java/org/codehaus/mojo/versions/reporting/model/DependencyUpdatesModel.java new file mode 100644 index 0000000000..5fb2dbb04b --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/model/DependencyUpdatesModel.java @@ -0,0 +1,37 @@ +package org.codehaus.mojo.versions.reporting.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Map; + +import org.apache.maven.model.Dependency; +import org.codehaus.mojo.versions.api.ArtifactVersions; + +/** + * Model class for using with the {@linkplain org.codehaus.mojo.versions.api.ReportRenderer} API + */ +public class DependencyUpdatesModel extends AbstractUpdatesModel +{ + public DependencyUpdatesModel( Map dependencyUpdates, + Map dependencyManagementUpdates ) + { + super( dependencyUpdates, dependencyManagementUpdates, id -> id ); + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/model/ParentUpdatesModel.java b/src/main/java/org/codehaus/mojo/versions/reporting/model/ParentUpdatesModel.java new file mode 100644 index 0000000000..347ed9559c --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/model/ParentUpdatesModel.java @@ -0,0 +1,37 @@ +package org.codehaus.mojo.versions.reporting.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.model.Dependency; +import org.codehaus.mojo.versions.api.ArtifactVersions; + +import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; + +/** + * Model class for using with the {@linkplain org.codehaus.mojo.versions.api.ReportRenderer} API + */ +public class ParentUpdatesModel extends DependencyUpdatesModel +{ + public ParentUpdatesModel( Dependency parent, ArtifactVersions dependencyUpdates ) + { + super( singletonMap( parent, dependencyUpdates ), emptyMap() ); + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/model/PluginUpdatesModel.java b/src/main/java/org/codehaus/mojo/versions/reporting/model/PluginUpdatesModel.java new file mode 100644 index 0000000000..9a4bbc6663 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/model/PluginUpdatesModel.java @@ -0,0 +1,42 @@ +package org.codehaus.mojo.versions.reporting.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Map; + +import org.apache.maven.model.Plugin; +import org.codehaus.mojo.versions.PluginUpdatesDetails; +import org.codehaus.mojo.versions.utils.DependencyBuilder; + +/** + * Model class for using with the {@linkplain org.codehaus.mojo.versions.api.ReportRenderer} API + */ +public class PluginUpdatesModel extends AbstractUpdatesModel +{ + public PluginUpdatesModel( Map pluginUpdates, + Map pluginManagementUpdates ) + { + super( pluginUpdates, pluginManagementUpdates, p -> DependencyBuilder.newBuilder() + .withGroupId( p.getGroupId() ) + .withArtifactId( p.getArtifactId() ) + .withVersion( p.getVersion() ) + .build() ); + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/reporting/model/PropertyUpdatesModel.java b/src/main/java/org/codehaus/mojo/versions/reporting/model/PropertyUpdatesModel.java new file mode 100644 index 0000000000..c329dc5a61 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/reporting/model/PropertyUpdatesModel.java @@ -0,0 +1,46 @@ +package org.codehaus.mojo.versions.reporting.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Map; +import java.util.TreeMap; + +import org.codehaus.mojo.versions.Property; +import org.codehaus.mojo.versions.api.PropertyVersions; +import org.codehaus.mojo.versions.utils.PropertyComparator; + +/** + * Model class for using with the {@linkplain org.codehaus.mojo.versions.api.ReportRenderer} API + */ +public class PropertyUpdatesModel +{ + private final Map allUpdates; + + public PropertyUpdatesModel( Map propertyUpdates ) + { + this.allUpdates = new TreeMap<>( PropertyComparator.INSTANCE ); + this.allUpdates.putAll( propertyUpdates ); + } + + public Map getAllUpdates() + { + return allUpdates; + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/utils/DependencyComparator.java b/src/main/java/org/codehaus/mojo/versions/utils/DependencyComparator.java index 20be1ad5f3..8330fc4b28 100644 --- a/src/main/java/org/codehaus/mojo/versions/utils/DependencyComparator.java +++ b/src/main/java/org/codehaus/mojo/versions/utils/DependencyComparator.java @@ -21,6 +21,7 @@ import java.util.Comparator; +import org.apache.commons.lang3.StringUtils; import org.apache.maven.model.Dependency; /** @@ -28,9 +29,9 @@ * * @since 1.0-alpha-1 */ -public class DependencyComparator - implements Comparator +public enum DependencyComparator implements Comparator { + INSTANCE; /** * @param d1 the first dependency @@ -39,29 +40,21 @@ public class DependencyComparator * @see java.util.Comparator#compare(Object, Object) * @since 1.0-alpha-1 */ + @SuppressWarnings( "checkstyle:InnerAssignment" ) public int compare( Dependency d1, Dependency d2 ) { - int r = d1.getGroupId().compareTo( d2.getGroupId() ); - if ( r == 0 ) - { - r = d1.getArtifactId().compareTo( d2.getArtifactId() ); - } - if ( r == 0 ) - { - String v1 = d1.getVersion(); - String v2 = d2.getVersion(); - if ( v1 == null ) - { - // hope I got the +1/-1 the right way around - return v2 == null ? 0 : -1; - } - if ( v2 == null ) - { - return 1; - } - r = v1.compareTo( v2 ); - } - return r; + int r; + return d1 == d2 + ? 0 + : d1 == null + ? 1 + : d2 == null + ? -1 + : ( r = StringUtils.compare( d1.getGroupId(), d2.getGroupId() ) ) != 0 + ? r + : ( r = StringUtils.compare( d1.getArtifactId(), d2.getArtifactId() ) ) != 0 + ? r + : StringUtils.compare( d1.getVersion(), d2.getVersion() ); } } diff --git a/src/main/java/org/codehaus/mojo/versions/utils/PluginComparator.java b/src/main/java/org/codehaus/mojo/versions/utils/PluginComparator.java index b62a06ec08..d4efe84646 100644 --- a/src/main/java/org/codehaus/mojo/versions/utils/PluginComparator.java +++ b/src/main/java/org/codehaus/mojo/versions/utils/PluginComparator.java @@ -29,9 +29,9 @@ * * @since 1.0-beta-1 */ -public class PluginComparator - implements Comparator +public enum PluginComparator implements Comparator { + INSTANCE; /** * Compares to {@link Plugin} or {@link ReportPlugin} instances. diff --git a/src/main/java/org/codehaus/mojo/versions/utils/PropertyComparator.java b/src/main/java/org/codehaus/mojo/versions/utils/PropertyComparator.java index a00af7d2b0..676df82494 100644 --- a/src/main/java/org/codehaus/mojo/versions/utils/PropertyComparator.java +++ b/src/main/java/org/codehaus/mojo/versions/utils/PropertyComparator.java @@ -21,6 +21,7 @@ import java.util.Comparator; +import org.apache.commons.lang3.StringUtils; import org.codehaus.mojo.versions.Property; /** @@ -28,9 +29,10 @@ * * @since 1.0-beta-1 */ -public class PropertyComparator - implements Comparator +public enum PropertyComparator implements Comparator { + INSTANCE; + /** * Compares to {@link Property} instances. * @@ -42,6 +44,12 @@ public class PropertyComparator */ public int compare( Property p1, Property p2 ) { - return p1.getName().compareTo( p2.getName() ); + return p1 == p2 + ? 0 + : p1 == null + ? 1 + : p2 == null + ? -1 + : StringUtils.compare( p1.getName(), p2.getName() ); } } diff --git a/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesXmlRenderer.java b/src/main/java/org/codehaus/mojo/versions/xml/DependencyUpdatesXmlRenderer.java similarity index 91% rename from src/main/java/org/codehaus/mojo/versions/DependencyUpdatesXmlRenderer.java rename to src/main/java/org/codehaus/mojo/versions/xml/DependencyUpdatesXmlRenderer.java index ec9aa2db38..ed3f596aa4 100644 --- a/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesXmlRenderer.java +++ b/src/main/java/org/codehaus/mojo/versions/xml/DependencyUpdatesXmlRenderer.java @@ -1,4 +1,4 @@ -package org.codehaus.mojo.versions; +package org.codehaus.mojo.versions.xml; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -9,7 +9,7 @@ * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an @@ -23,7 +23,6 @@ import java.io.PrintWriter; import java.util.Collection; import java.util.Map; -import java.util.Map.Entry; import java.util.Optional; import java.util.TreeMap; @@ -77,11 +76,11 @@ public class DependencyUpdatesXmlRenderer private static final String TAB = "\t"; - private Map dependencyUpdates; + private final Map dependencyUpdates; - private Map dependencyManagementUpdates; + private final Map dependencyManagementUpdates; - private String outputFileName; + private final String outputFileName; public DependencyUpdatesXmlRenderer( Map dependencyUpdates, Map dependencyManagementUpdates, @@ -102,7 +101,7 @@ public void render() { StringBuilder sb = new StringBuilder(); sb.append( "" ).append( NL ); - Map allUpdates = new TreeMap<>( new DependencyComparator() ); + Map allUpdates = new TreeMap<>( DependencyComparator.INSTANCE ); allUpdates.putAll( dependencyManagementUpdates ); allUpdates.putAll( dependencyUpdates ); sb.append( getSummaryBlock( allUpdates.values() ) ); @@ -144,7 +143,7 @@ public static String wrapElement( String value, String tag ) * @param allUpdates all dependencies versions * @return summary in xml format */ - public static String getSummaryBlock( Collection allUpdates ) + public static String getSummaryBlock( Collection allUpdates ) { int numInc = 0; int numMin = 0; @@ -241,28 +240,27 @@ private static String getDependencyInfoBlock( Map { StringBuilder sBuilder = new StringBuilder(); sBuilder.append( TAB ).append( OPEN_TAG ).append( blockName ).append( CLOSE_TAG ).append( NL ); - for ( Entry entry : dependencyUpdates.entrySet() ) + dependencyUpdates.forEach( ( dep, value ) -> { sBuilder.append( TAB ).append( TAB ).append( OPEN_TAG ).append( subblockName ).append( CLOSE_TAG ) - .append( NL ); + .append( NL ); - Dependency dep = entry.getKey(); sBuilder.append( TAB ).append( TAB ).append( TAB ).append( wrapElement( dep.getGroupId(), - GROUP_ID ) ).append( NL ); + GROUP_ID ) ).append( NL ); sBuilder.append( TAB ).append( TAB ).append( TAB ).append( wrapElement( dep.getArtifactId(), - ARTIFACT_ID ) ).append( NL ); + ARTIFACT_ID ) ).append( NL ); sBuilder.append( TAB ).append( TAB ).append( TAB ).append( wrapElement( dep.getScope(), - SCOPE ) ).append( NL ); + SCOPE ) ).append( NL ); sBuilder.append( TAB ).append( TAB ).append( TAB ).append( wrapElement( dep.getClassifier(), - CLASSIFIER ) ).append( NL ); + CLASSIFIER ) ).append( NL ); sBuilder.append( TAB ).append( TAB ).append( TAB ).append( wrapElement( dep.getType(), - TYPE ) ).append( NL ); + TYPE ) ).append( NL ); - sBuilder.append( getVersionsBlocks( entry.getValue() ) ); + sBuilder.append( getVersionsBlocks( value ) ); sBuilder.append( TAB ).append( TAB ).append( OPEN_CLOSING_TAG ).append( subblockName ).append( CLOSE_TAG ) - .append( NL ); - } + .append( NL ); + } ); sBuilder.append( TAB ).append( OPEN_CLOSING_TAG ).append( blockName ).append( CLOSE_TAG ).append( NL ); return sBuilder.toString(); } diff --git a/src/main/java/org/codehaus/mojo/versions/PluginUpdatesXmlRenderer.java b/src/main/java/org/codehaus/mojo/versions/xml/PluginUpdatesXmlRenderer.java similarity index 80% rename from src/main/java/org/codehaus/mojo/versions/PluginUpdatesXmlRenderer.java rename to src/main/java/org/codehaus/mojo/versions/xml/PluginUpdatesXmlRenderer.java index e19a98e3e6..1a0ad812ba 100644 --- a/src/main/java/org/codehaus/mojo/versions/PluginUpdatesXmlRenderer.java +++ b/src/main/java/org/codehaus/mojo/versions/xml/PluginUpdatesXmlRenderer.java @@ -1,4 +1,4 @@ -package org.codehaus.mojo.versions; +package org.codehaus.mojo.versions.xml; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -9,7 +9,7 @@ * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an @@ -21,19 +21,16 @@ import java.io.IOException; import java.io.PrintWriter; -import java.util.Collection; import java.util.Map; -import java.util.Map.Entry; import java.util.TreeMap; -import java.util.stream.Collectors; import org.apache.maven.model.Plugin; import org.apache.maven.reporting.MavenReportException; -import org.codehaus.mojo.versions.api.ArtifactVersions; +import org.codehaus.mojo.versions.PluginUpdatesDetails; import org.codehaus.mojo.versions.utils.PluginComparator; -import static org.codehaus.mojo.versions.DependencyUpdatesXmlRenderer.getVersionsBlocks; -import static org.codehaus.mojo.versions.DependencyUpdatesXmlRenderer.wrapElement; +import static org.codehaus.mojo.versions.xml.DependencyUpdatesXmlRenderer.getVersionsBlocks; +import static org.codehaus.mojo.versions.xml.DependencyUpdatesXmlRenderer.wrapElement; /** * XML renderer for PluginUpdatesReport creates an xml file in target directory and writes report about available @@ -83,7 +80,7 @@ public void render() { StringBuilder sb = new StringBuilder(); sb.append( "" ).append( NL ); - Map allUpdates = new TreeMap<>( new PluginComparator() ); + Map allUpdates = new TreeMap<>( PluginComparator.INSTANCE ); allUpdates.putAll( pluginManagementUpdates ); allUpdates.putAll( pluginUpdates ); sb.append( getSummaryBlock( allUpdates ) ); @@ -105,10 +102,7 @@ public void render() private static String getSummaryBlock( Map allUpdates ) { - Collection allVersions = allUpdates.values().stream() - .map( PluginUpdatesDetails::getArtifactVersions ) - .collect( Collectors.toList() ); - return DependencyUpdatesXmlRenderer.getSummaryBlock( allVersions ); + return DependencyUpdatesXmlRenderer.getSummaryBlock( allUpdates.values() ); } private static String getPluginsInfoBlock( Map pluginUpdates, String blockName, @@ -116,22 +110,21 @@ private static String getPluginsInfoBlock( Map plu { StringBuilder sBuilder = new StringBuilder(); sBuilder.append( TAB ).append( OPEN_TAG ).append( blockName ).append( CLOSE_TAG ).append( NL ); - for ( Entry entry : pluginUpdates.entrySet() ) + pluginUpdates.forEach( ( plugin, value ) -> { sBuilder.append( TAB ).append( TAB ).append( OPEN_TAG ).append( subblockName ).append( CLOSE_TAG ) - .append( NL ); + .append( NL ); - Plugin plugin = entry.getKey(); sBuilder.append( TAB ).append( TAB ).append( TAB ).append( wrapElement( plugin.getGroupId(), - GROUP_ID ) ).append( NL ); + GROUP_ID ) ).append( NL ); sBuilder.append( TAB ).append( TAB ).append( TAB ).append( wrapElement( plugin.getArtifactId(), - ARTIFACT_ID ) ).append( NL ); + ARTIFACT_ID ) ).append( NL ); - sBuilder.append( getVersionsBlocks( entry.getValue().getArtifactVersions() ) ); + sBuilder.append( getVersionsBlocks( value ) ); sBuilder.append( TAB ).append( TAB ).append( OPEN_CLOSING_TAG ).append( subblockName ).append( CLOSE_TAG ) - .append( NL ); - } + .append( NL ); + } ); sBuilder.append( TAB ).append( OPEN_CLOSING_TAG ).append( blockName ).append( CLOSE_TAG ).append( NL ); return sBuilder.toString(); } diff --git a/src/main/resources/parent-updates-report.properties b/src/main/resources/parent-updates-report.properties index 632d111778..2ddf8b1650 100644 --- a/src/main/resources/parent-updates-report.properties +++ b/src/main/resources/parent-updates-report.properties @@ -6,7 +6,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an diff --git a/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesReportTest.java b/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesReportMojoTest.java similarity index 63% rename from src/test/java/org/codehaus/mojo/versions/DependencyUpdatesReportTest.java rename to src/test/java/org/codehaus/mojo/versions/DependencyUpdatesReportMojoTest.java index cd99c1d250..7403e2610f 100644 --- a/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesReportTest.java +++ b/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesReportMojoTest.java @@ -24,10 +24,11 @@ import java.io.OutputStream; import java.util.Arrays; import java.util.Collections; -import java.util.LinkedHashMap; +import java.util.HashMap; import java.util.Locale; import java.util.Set; +import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.doxia.module.xhtml5.Xhtml5SinkFactory; import org.apache.maven.doxia.sink.SinkFactory; @@ -36,9 +37,13 @@ import org.apache.maven.model.Model; import org.apache.maven.project.MavenProject; import org.apache.maven.reporting.MavenReportException; +import org.apache.maven.repository.RepositorySystem; import org.codehaus.mojo.versions.model.RuleSet; +import org.codehaus.mojo.versions.reporting.ReportRendererFactoryImpl; import org.codehaus.mojo.versions.utils.DependencyBuilder; import org.codehaus.mojo.versions.utils.MockUtils; +import org.codehaus.plexus.i18n.I18N; +import org.hamcrest.Matchers; import org.junit.Test; import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE; @@ -49,21 +54,25 @@ import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.anyOf; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** - * Basic tests for {@linkplain DependencyUpdatesReport}. + * Basic tests for {@linkplain DependencyUpdatesReportMojo}. * * @author Andrzej Jarmoniuk */ -public class DependencyUpdatesReportTest +public class DependencyUpdatesReportMojoTest { - - private static class TestDependencyUpdatesReport extends DependencyUpdatesReport + private static class TestDependencyUpdatesReportMojo extends DependencyUpdatesReportMojo { - @SuppressWarnings( "deprecation" ) - TestDependencyUpdatesReport() + private static final I18N MOCK_I18N = mockI18N(); + + TestDependencyUpdatesReportMojo() { - super( mockI18N(), MockUtils.mockRepositorySystem(), null, mockArtifactMetadataSource(), null ); + super( MOCK_I18N, mockRepositorySystem(), null, mockArtifactMetadataSource(), + null, new ReportRendererFactoryImpl( MOCK_I18N ) ); siteTool = MockUtils.mockSiteTool(); project = new MavenProject(); @@ -72,13 +81,20 @@ private static class TestDependencyUpdatesReport extends DependencyUpdatesReport project.getModel().setDependencyManagement( new DependencyManagement() ); } - public TestDependencyUpdatesReport withDependencies( Dependency... dependencies ) + public TestDependencyUpdatesReportMojo withDependencies( Dependency... dependencies ) { project.setDependencies( Arrays.asList( dependencies ) ); return this; } - public TestDependencyUpdatesReport withOriginalDependencyManagement( + public TestDependencyUpdatesReportMojo withArtifactMetadataSource( + ArtifactMetadataSource artifactMetadataSource ) + { + this.artifactMetadataSource = artifactMetadataSource; + return this; + } + + public TestDependencyUpdatesReportMojo withOriginalDependencyManagement( Dependency... originalDependencyManagement ) { project.getOriginalModel().getDependencyManagement() @@ -86,62 +102,77 @@ public TestDependencyUpdatesReport withOriginalDependencyManagement( return this; } - public TestDependencyUpdatesReport withDependencyManagement( Dependency... dependencyManagement ) + public TestDependencyUpdatesReportMojo withDependencyManagement( Dependency... dependencyManagement ) { project.getModel().getDependencyManagement().setDependencies( Arrays.asList( dependencyManagement ) ); return this; } - public TestDependencyUpdatesReport withOnlyUpgradable( boolean onlyUpgradable ) + public TestDependencyUpdatesReportMojo withOnlyUpgradable( boolean onlyUpgradable ) { this.onlyUpgradable = onlyUpgradable; return this; } - public TestDependencyUpdatesReport withProcessDependencyManagement( boolean processDependencyManagement ) + public TestDependencyUpdatesReportMojo withProcessDependencyManagement( boolean processDependencyManagement ) { this.processDependencyManagement = processDependencyManagement; return this; } - public TestDependencyUpdatesReport withProcessDependencyManagementTransitive( + public TestDependencyUpdatesReportMojo withProcessDependencyManagementTransitive( boolean processDependencyManagementTransitive ) { this.processDependencyManagementTransitive = processDependencyManagementTransitive; return this; } - public TestDependencyUpdatesReport withOnlyProjectDependencies( + public TestDependencyUpdatesReportMojo withOnlyProjectDependencies( boolean onlyProjectDependencies ) { this.onlyProjectDependencies = onlyProjectDependencies; return this; } - public TestDependencyUpdatesReport withRuleSet( + public TestDependencyUpdatesReportMojo withRuleSet( RuleSet ruleSet ) { this.ruleSet = ruleSet; return this; } - public TestDependencyUpdatesReport withIgnoredVersions( + public TestDependencyUpdatesReportMojo withIgnoredVersions( Set ignoredVersions ) { this.ignoredVersions = ignoredVersions; return this; } - public TestDependencyUpdatesReport withArtifactMetadataSource( ArtifactMetadataSource artifactMetadataSource ) + private static RepositorySystem mockRepositorySystem() { - this.artifactMetadataSource = artifactMetadataSource; - return this; + RepositorySystem repositorySystem = mock( RepositorySystem.class ); + when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( + invocation -> + { + Dependency dependency = invocation.getArgument( 0 ); + return new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), + dependency.getVersion(), dependency.getScope(), dependency.getType(), + dependency.getClassifier(), null ); + } ); + return repositorySystem; } } private static Dependency dependencyOf( String artifactId ) { - return DependencyBuilder.dependencyWith( "groupA", artifactId, "1.0.0", "default", "pom", SCOPE_COMPILE ); + return DependencyBuilder.dependencyWith( "groupA", artifactId, "1.0.0", + "default", "pom", SCOPE_COMPILE ); + } + + private static Dependency dependencyOf( String artifactId, String version ) + { + return DependencyBuilder.dependencyWith( "groupA", artifactId, version, + "default", "pom", SCOPE_COMPILE ); } @Test @@ -149,7 +180,7 @@ public void testOnlyUpgradableDependencies() throws IOException, MavenReportExce { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new TestDependencyUpdatesReport() + new TestDependencyUpdatesReportMojo() .withOnlyUpgradable( true ) .withDependencies( dependencyOf( "artifactA" ), dependencyOf( "artifactB" ), @@ -166,7 +197,7 @@ public void testOnlyUpgradableWithOriginalDependencyManagement() throws IOExcept { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new TestDependencyUpdatesReport() + new TestDependencyUpdatesReportMojo() .withOriginalDependencyManagement( dependencyOf( "artifactA" ), dependencyOf( "artifactB" ), dependencyOf( "artifactC" ) ) .withProcessDependencyManagement( true ) @@ -183,7 +214,7 @@ public void testOnlyUpgradableWithTransitiveDependencyManagement() throws IOExce { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new TestDependencyUpdatesReport() + new TestDependencyUpdatesReportMojo() .withDependencyManagement( dependencyOf( "artifactA" ), dependencyOf( "artifactB" ), dependencyOf( "artifactC" ) ) @@ -202,7 +233,7 @@ public void testOnlyProjectDependencies() throws IOException, MavenReportExcepti { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new TestDependencyUpdatesReport() + new TestDependencyUpdatesReportMojo() .withDependencies( dependencyOf( "artifactA" ) ) .withDependencyManagement( dependencyOf( "artifactA" ), dependencyOf( "artifactB" ), dependencyOf( "artifactC" ) ) @@ -220,7 +251,7 @@ public void testOnlyProjectDependenciesWithIgnoredVersions() throws IOException, { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new TestDependencyUpdatesReport() + new TestDependencyUpdatesReportMojo() .withDependencies( dependencyOf( "artifactA" ) ) .withDependencyManagement( dependencyOf( "artifactA" ), dependencyOf( "artifactB" ), dependencyOf( "artifactC" ) ) @@ -233,42 +264,47 @@ public void testOnlyProjectDependenciesWithIgnoredVersions() throws IOException, assertThat( output, containsString( "report.noUpdatesAvailable" ) ); } - + /** + * Dependencies should be rendered in alphabetical order + */ @Test - public void testSubincrementalUpdates() - throws IOException, MavenReportException + public void testDependenciesInAlphabeticalOrder() throws IOException, MavenReportException { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new TestDependencyUpdatesReport() - .withDependencies( DependencyBuilder.newBuilder() - .withGroupId( "localhost" ) - .withArtifactId( "dummy-api" ) - .withVersion( "1.1" ) - .withScope( SCOPE_COMPILE ) - .withType( "jar" ) - .build() ) - .withArtifactMetadataSource( mockArtifactMetadataSource( new LinkedHashMap() + new TestDependencyUpdatesReportMojo() + .withArtifactMetadataSource( mockArtifactMetadataSource( new HashMap() {{ - put( "dummy-api", new String[] { "1.0.1", "1.0", "1.1.0-2", "1.1.1", "1.1.1-2", "1.1.2", - "1.1.2-SNAPSHOT", "1.1.3", "1.1", "1.1-SNAPSHOT", "1.2.1", "1.2.2", "1.2", "1.3", - "1.9.1-SNAPSHOT", "2.0", "2.1.1-SNAPSHOT", "2.1", "3.0", "3.1.1-SNAPSHOT", - "3.1.5-SNAPSHOT", "3.4.0-SNAPSHOT"} ); + put( "amstrad", new String[] {"1.0.0", "2.0.0"} ); + put( "atari", new String[] {"1.0.0", "2.0.0"} ); + put( "commodore", new String[] {"1.0.0", "2.0.0"} ); + put( "spectrum", new String[] {"1.0.0", "2.0.0"} ); }} ) ) + .withDependencies( dependencyOf( "spectrum" ), dependencyOf( "atari" ), + dependencyOf( "amstrad" ), dependencyOf( "commodore" ) ) .generate( sinkFactory.createSink( os ), sinkFactory, Locale.getDefault() ); - String output = os.toString() - .replaceAll( "<[^>]+>", " " ) - .replaceAll( "&[^;]+;", " " ) - .replaceAll( "\\s+", " " ); - assertThat( output, containsString( "localhost dummy-api 1.1 compile jar 1.1.0-2 1.1.3 1.3 3.0" ) ); - assertThat( output, containsString( "1.1.0-2 report.latestSubIncremental" ) ); - assertThat( output, containsString( "1.1.1 report.nextIncremental" ) ); - assertThat( output, containsString( "1.1.3 report.latestIncremental" ) ); - assertThat( output, containsString( "1.2 report.nextMinor" ) ); - assertThat( output, containsString( "1.3 report.latestMinor" ) ); - assertThat( output, containsString( "2.0 report.nextMajor" ) ); - assertThat( output, containsString( "3.0 report.latestMajor" ) ); + String output = os.toString().replaceAll( "\n", "" ); + assertThat( output, Matchers.stringContainsInOrder( "amstrad", "atari", "commodore", "spectrum" ) ); } + /** + * Dependency updates for dependency should override those for dependency management + */ + @Test + public void testDependenciesShouldOverrideDependencyManagement() throws IOException, MavenReportException + { + OutputStream os = new ByteArrayOutputStream(); + SinkFactory sinkFactory = new Xhtml5SinkFactory(); + new TestDependencyUpdatesReportMojo() + .withProcessDependencyManagement( true ) + .withProcessDependencyManagementTransitive( true ) + .withDependencies( dependencyOf( "artifactA", "2.0.0" ), + dependencyOf( "artifactB" ) ) + .withDependencyManagement( dependencyOf( "artifactA" ) ) + .generate( sinkFactory.createSink( os ), sinkFactory, Locale.getDefault() ); + + String output = os.toString().replaceAll( "\n", "" ); + assertThat( output, Matchers.stringContainsInOrder( "artifactB" ) ); + } } diff --git a/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesXmlRendererTest.java b/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesXmlRendererTest.java index 6f890a8f7b..69889a7e91 100644 --- a/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesXmlRendererTest.java +++ b/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesXmlRendererTest.java @@ -30,6 +30,7 @@ import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; import org.codehaus.mojo.versions.api.ArtifactVersions; +import org.codehaus.mojo.versions.xml.DependencyUpdatesXmlRenderer; import org.hamcrest.core.Is; import org.junit.Test; diff --git a/src/test/java/org/codehaus/mojo/versions/ParentUpdatesReportTest.java b/src/test/java/org/codehaus/mojo/versions/ParentUpdatesReportMojoTest.java similarity index 89% rename from src/test/java/org/codehaus/mojo/versions/ParentUpdatesReportTest.java rename to src/test/java/org/codehaus/mojo/versions/ParentUpdatesReportMojoTest.java index 95c81c19be..7854a027f1 100644 --- a/src/test/java/org/codehaus/mojo/versions/ParentUpdatesReportTest.java +++ b/src/test/java/org/codehaus/mojo/versions/ParentUpdatesReportMojoTest.java @@ -33,6 +33,8 @@ import org.apache.maven.model.Model; import org.apache.maven.project.MavenProject; import org.apache.maven.reporting.MavenReportException; +import org.codehaus.mojo.versions.reporting.ReportRendererFactoryImpl; +import org.codehaus.plexus.i18n.I18N; import org.junit.Test; import static org.codehaus.mojo.versions.utils.MockUtils.mockArtifactMetadataSource; @@ -43,22 +45,23 @@ import static org.hamcrest.Matchers.allOf; /** - * Basic tests for {@linkplain ParentUpdatesReport}. + * Basic tests for {@linkplain ParentUpdatesReportMojo}. * * @author Andrzej Jarmoniuk */ -public class ParentUpdatesReportTest +public class ParentUpdatesReportMojoTest { + private static final I18N MOCK_I18N = mockI18N(); @Test public void testAllowSnapshots() throws IOException, MavenReportException { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new ParentUpdatesReport( mockI18N(), mockRepositorySystem(), null, + new ParentUpdatesReportMojo( MOCK_I18N, mockRepositorySystem(), null, mockArtifactMetadataSource( new HashMap() {{ put( "default-artifact", new String[] {"1.0.0", "1.0.1", "1.1.0", "2.0.0", "2.0.1-SNAPSHOT"} ); - }} ), null ) + }} ), null, new ReportRendererFactoryImpl( MOCK_I18N ) ) {{ allowSnapshots = true; project = new MavenProject( new Model() diff --git a/src/test/java/org/codehaus/mojo/versions/PluginUpdatesReportTest.java b/src/test/java/org/codehaus/mojo/versions/PluginUpdatesReportMojoTest.java similarity index 86% rename from src/test/java/org/codehaus/mojo/versions/PluginUpdatesReportTest.java rename to src/test/java/org/codehaus/mojo/versions/PluginUpdatesReportMojoTest.java index a8fad70d7f..25f2ea781a 100644 --- a/src/test/java/org/codehaus/mojo/versions/PluginUpdatesReportTest.java +++ b/src/test/java/org/codehaus/mojo/versions/PluginUpdatesReportMojoTest.java @@ -37,7 +37,9 @@ import org.apache.maven.reporting.MavenReportException; import org.apache.maven.repository.RepositorySystem; import org.codehaus.mojo.versions.model.RuleSet; +import org.codehaus.mojo.versions.reporting.ReportRendererFactoryImpl; import org.codehaus.mojo.versions.utils.MockUtils; +import org.codehaus.plexus.i18n.I18N; import org.junit.Test; import static org.apache.maven.artifact.Artifact.SCOPE_RUNTIME; @@ -54,17 +56,19 @@ import static org.mockito.Mockito.when; /** - * Basic tests for {@linkplain PluginUpdatesReport}. + * Basic tests for {@linkplain PluginUpdatesReportMojo}. * * @author Andrzej Jarmoniuk */ -public class PluginUpdatesReportTest +public class PluginUpdatesReportMojoTest { - private static class TestPluginUpdatesReport extends PluginUpdatesReport + private static class TestPluginUpdatesReportMojo extends PluginUpdatesReportMojo { - TestPluginUpdatesReport() + static final I18N MOCK_I18N = mockI18N(); + TestPluginUpdatesReportMojo() { - super( mockI18N(), mockRepositorySystem(), null, mockArtifactMetadataSource(), null ); + super( MOCK_I18N, mockRepositorySystem(), null, mockArtifactMetadataSource(), + null, new ReportRendererFactoryImpl( MOCK_I18N ) ); siteTool = MockUtils.mockSiteTool(); project = new MavenProject(); @@ -74,38 +78,38 @@ private static class TestPluginUpdatesReport extends PluginUpdatesReport artifactMetadataSource = mockArtifactMetadataSource(); } - public TestPluginUpdatesReport withPlugins( Plugin... plugins ) + public TestPluginUpdatesReportMojo withPlugins( Plugin... plugins ) { project.getBuild().setPlugins( Arrays.asList( plugins ) ); return this; } - public TestPluginUpdatesReport withPluginManagement( Plugin... pluginManagement ) + public TestPluginUpdatesReportMojo withPluginManagement( Plugin... pluginManagement ) { project.getBuild().getPluginManagement().setPlugins( Arrays.asList( pluginManagement ) ); return this; } - public TestPluginUpdatesReport withOnlyUpgradable( boolean onlyUpgradable ) + public TestPluginUpdatesReportMojo withOnlyUpgradable( boolean onlyUpgradable ) { this.onlyUpgradable = onlyUpgradable; return this; } - public TestPluginUpdatesReport withOnlyProjectPlugins( boolean onlyProjectPlugins ) + public TestPluginUpdatesReportMojo withOnlyProjectPlugins( boolean onlyProjectPlugins ) { this.onlyProjectPlugins = onlyProjectPlugins; return this; } - public TestPluginUpdatesReport withRuleSet( + public TestPluginUpdatesReportMojo withRuleSet( RuleSet ruleSet ) { this.ruleSet = ruleSet; return this; } - public TestPluginUpdatesReport withIgnoredVersions( + public TestPluginUpdatesReportMojo withIgnoredVersions( Set ignoredVersions ) { this.ignoredVersions = ignoredVersions; @@ -143,7 +147,7 @@ public void testOnlyUpgradablePlugins() throws IOException, MavenReportException { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new TestPluginUpdatesReport() + new TestPluginUpdatesReportMojo() .withPlugins( pluginOf( "artifactA" ), pluginOf( "artifactB" ), pluginOf( "artifactC" ) ) .withOnlyUpgradable( true ) @@ -159,7 +163,7 @@ public void testOnlyUpgradableWithPluginManagement() throws IOException, MavenRe { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new TestPluginUpdatesReport() + new TestPluginUpdatesReportMojo() .withPluginManagement( pluginOf( "artifactA" ), pluginOf( "artifactB" ), pluginOf( "artifactC" ) ) .withOnlyUpgradable( true ) @@ -175,7 +179,7 @@ public void testOnlyProjectPlugins() throws IOException, MavenReportException { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new TestPluginUpdatesReport() + new TestPluginUpdatesReportMojo() .withPlugins( pluginOf( "artifactA" ) ) .withPluginManagement( pluginOf( "artifactA" ), pluginOf( "artifactB" ), pluginOf( "artifactC" ) ) @@ -193,7 +197,7 @@ public void testOnlyProjectPluginsWithIgnoredVersions() throws IOException, Mave { OutputStream os = new ByteArrayOutputStream(); SinkFactory sinkFactory = new Xhtml5SinkFactory(); - new TestPluginUpdatesReport() + new TestPluginUpdatesReportMojo() .withPlugins( pluginOf( "artifactA" ) ) .withPluginManagement( pluginOf( "artifactA" ), pluginOf( "artifactB" ), pluginOf( "artifactC" ) ) diff --git a/src/test/java/org/codehaus/mojo/versions/api/DefaultVersionsHelperTest.java b/src/test/java/org/codehaus/mojo/versions/api/DefaultVersionsHelperTest.java index ada1bf7294..89fcc92b49 100644 --- a/src/test/java/org/codehaus/mojo/versions/api/DefaultVersionsHelperTest.java +++ b/src/test/java/org/codehaus/mojo/versions/api/DefaultVersionsHelperTest.java @@ -287,4 +287,5 @@ public void testIgnoredVersionsShouldExtendTheRuleSet() throws MojoExecutionExce assertThat( ruleSet.getIgnoreVersions().stream().map( IgnoreVersion::getVersion ) .collect( Collectors.toList() ), containsInAnyOrder( ".*-M.", ".*-SNAPSHOT", "1.0.0" ) ); } + }