001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.enforcer.rules;
020
021import javax.inject.Inject;
022import javax.inject.Named;
023
024import java.util.List;
025import java.util.Objects;
026
027import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
028import org.apache.maven.artifact.versioning.VersionRange;
029import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
030import org.apache.maven.model.Prerequisites;
031import org.apache.maven.project.MavenProject;
032
033/**
034 * @author Robert Scholte
035 * @since 1.3
036 */
037@Named("requirePrerequisite")
038public final class RequirePrerequisite extends AbstractStandardEnforcerRule {
039    /**
040     * Only the projects with one of these packagings will be enforced to have the correct prerequisite.
041     *
042     * @since 1.4
043     */
044    private List<String> packagings;
045
046    /**
047     * Can either be version or a range, e.g. {@code 2.2.1} or {@code [2.2.1,)}
048     */
049    private String mavenVersion;
050
051    private final MavenProject project;
052
053    @Inject
054    public RequirePrerequisite(MavenProject project) {
055        this.project = Objects.requireNonNull(project);
056    }
057
058    /**
059     * Set the mavenVersion Can either be version or a range, e.g. {@code 2.2.1} or {@code [2.2.1,)}
060     *
061     * @param mavenVersion the version or {@code null}
062     */
063    public void setMavenVersion(String mavenVersion) {
064        this.mavenVersion = mavenVersion;
065    }
066
067    /**
068     * Only the projects with one of these packagings will be enforced to have the correct prerequisite.
069     *
070     * @since 1.4
071     * @param packagings the list of packagings
072     */
073    public void setPackagings(List<String> packagings) {
074        this.packagings = packagings;
075    }
076
077    @Override
078    public void execute() throws EnforcerRuleException {
079        try {
080
081            if ("pom".equals(project.getPackaging())) {
082                getLog().debug("Packaging is pom, skipping requirePrerequisite rule");
083                return;
084            }
085
086            if (packagings != null && !packagings.contains(project.getPackaging())) {
087                getLog().debug("Packaging is " + project.getPackaging() + ", skipping requirePrerequisite rule");
088                return;
089            }
090
091            Prerequisites prerequisites = project.getPrerequisites();
092
093            if (prerequisites == null) {
094                throw new EnforcerRuleException("Requires prerequisite not set");
095            }
096
097            if (mavenVersion != null) {
098
099                VersionRange requiredVersionRange = VersionRange.createFromVersionSpec(mavenVersion);
100
101                if (!requiredVersionRange.hasRestrictions()) {
102                    requiredVersionRange = VersionRange.createFromVersionSpec("[" + mavenVersion + ",)");
103                }
104
105                VersionRange specifiedVersion = VersionRange.createFromVersionSpec(prerequisites.getMaven());
106
107                VersionRange restrictedVersionRange = requiredVersionRange.restrict(specifiedVersion);
108
109                if (restrictedVersionRange.getRecommendedVersion() == null) {
110                    throw new EnforcerRuleException("The specified Maven prerequisite( " + specifiedVersion
111                            + " ) doesn't match the required version: " + mavenVersion);
112                }
113            }
114        } catch (InvalidVersionSpecificationException e) {
115            throw new EnforcerRuleException(e.getMessage(), e);
116        }
117    }
118
119    @Override
120    public String toString() {
121        return String.format("RequirePrerequisite[packagings=%s, mavenVersion=%s]", packagings, mavenVersion);
122    }
123}